gzjzss 7 роки тому
батько
коміт
8e2f4fa2db
100 змінених файлів з 19923 додано та 0 видалено
  1. 8 0
      .htaccess
  2. 22 0
      .vscode/launch.json
  3. 6 0
      application/.htaccess
  4. 1 0
      application/cache/branchs
  5. 11 0
      application/cache/index.html
  6. 1 0
      application/cache/setting
  7. 135 0
      application/config/autoload.php
  8. 94 0
      application/config/config.json
  9. 527 0
      application/config/config.php
  10. 85 0
      application/config/constants.php
  11. 96 0
      application/config/database.php
  12. 24 0
      application/config/doctypes.php
  13. 103 0
      application/config/foreign_chars.php
  14. 13 0
      application/config/hooks.php
  15. 11 0
      application/config/index.html
  16. 19 0
      application/config/memcached.php
  17. 84 0
      application/config/migration.php
  18. 183 0
      application/config/mimes.php
  19. 39 0
      application/config/mongo_db.php
  20. 14 0
      application/config/profiler.php
  21. 606 0
      application/config/rest.php
  22. 72 0
      application/config/routes.php
  23. 14 0
      application/config/smarty.php
  24. 64 0
      application/config/smileys.php
  25. 214 0
      application/config/user_agents.php
  26. 10 0
      application/config/workorder.php
  27. 280 0
      application/controllers/Appauth.php
  28. 74 0
      application/controllers/Index.php
  29. 14 0
      application/controllers/Main.php
  30. 351 0
      application/controllers/Report.php
  31. 156 0
      application/controllers/Setting.php
  32. 121 0
      application/controllers/Template.php
  33. 71 0
      application/controllers/Ueditor.php
  34. 498 0
      application/controllers/User.php
  35. 191 0
      application/controllers/Warning.php
  36. 578 0
      application/controllers/Workorder.php
  37. 11 0
      application/controllers/index.html
  38. 237 0
      application/controllers/v1/Api.php
  39. 199 0
      application/core/MY_Controller.php
  40. 11 0
      application/core/index.html
  41. 11 0
      application/helpers/index.html
  42. 108 0
      application/helpers/sms_helper.php
  43. 11 0
      application/hooks/index.html
  44. 11 0
      application/index.html
  45. 11 0
      application/language/bulgarian/index.html
  46. 18 0
      application/language/bulgarian/rest_controller_lang.php
  47. 11 0
      application/language/dutch/index.html
  48. 16 0
      application/language/dutch/rest_controller_lang.php
  49. 18 0
      application/language/english/rest_controller_lang.php
  50. 11 0
      application/language/french/index.html
  51. 18 0
      application/language/french/rest_controller_lang.php
  52. 11 0
      application/language/german/index.html
  53. 18 0
      application/language/german/rest_controller_lang.php
  54. 18 0
      application/language/greek/rest_controller_lang.php
  55. 11 0
      application/language/index.html
  56. 11 0
      application/language/indonesia/index.html
  57. 18 0
      application/language/indonesia/rest_controller_lang.php
  58. 11 0
      application/language/italian/index.html
  59. 16 0
      application/language/italian/rest_controller_lang.php
  60. 11 0
      application/language/korean/index.html
  61. 16 0
      application/language/korean/rest_controller_lang.php
  62. 11 0
      application/language/portuguese-brazilian/index.html
  63. 18 0
      application/language/portuguese-brazilian/rest_controller_lang.php
  64. 11 0
      application/language/romanian/index.html
  65. 18 0
      application/language/romanian/rest_controller_lang.php
  66. 11 0
      application/language/serbian_cyr/index.html
  67. 18 0
      application/language/serbian_cyr/rest_controller_lang.php
  68. 11 0
      application/language/serbian_lat/index.html
  69. 18 0
      application/language/serbian_lat/rest_controller_lang.php
  70. 11 0
      application/language/simplified-chinese/index.html
  71. 18 0
      application/language/simplified-chinese/rest_controller_lang.php
  72. 11 0
      application/language/spanish/index.html
  73. 18 0
      application/language/spanish/rest_controller_lang.php
  74. 11 0
      application/language/traditional-chinese/index.html
  75. 18 0
      application/language/traditional-chinese/rest_controller_lang.php
  76. 11 0
      application/language/turkish/index.html
  77. 18 0
      application/language/turkish/rest_controller_lang.php
  78. 85 0
      application/libraries/Aliyunsms.php
  79. 25 0
      application/libraries/Ci_smarty.php
  80. 291 0
      application/libraries/MY_pagination.php
  81. 69 0
      application/libraries/Mailer.php
  82. 1064 0
      application/libraries/Mongo_db.php
  83. 620 0
      application/libraries/Notices.php
  84. 502 0
      application/libraries/PHPMail/LICENSE
  85. 49 0
      application/libraries/PHPMail/PHPMailerAutoload.php
  86. 1 0
      application/libraries/PHPMail/VERSION
  87. 4044 0
      application/libraries/PHPMail/class.phpmailer.php
  88. 197 0
      application/libraries/PHPMail/class.phpmaileroauth.php
  89. 77 0
      application/libraries/PHPMail/class.phpmaileroauthgoogle.php
  90. 407 0
      application/libraries/PHPMail/class.pop3.php
  91. 1276 0
      application/libraries/PHPMail/class.smtp.php
  92. 61 0
      application/libraries/PHPMail/composer.json
  93. 3593 0
      application/libraries/PHPMail/composer.lock
  94. 148 0
      application/libraries/PHPMail/extras/EasyPeasyICS.php
  95. 17 0
      application/libraries/PHPMail/extras/README.md
  96. 1159 0
      application/libraries/PHPMail/extras/htmlfilter.php
  97. 185 0
      application/libraries/PHPMail/extras/ntlm_sasl_client.php
  98. 162 0
      application/libraries/PHPMail/get_oauth_token.php
  99. 26 0
      application/libraries/PHPMail/language/phpmailer.lang-am.php
  100. 0 0
      application/libraries/PHPMail/language/phpmailer.lang-ar.php

+ 8 - 0
.htaccess

@@ -0,0 +1,8 @@
+<IfModule mod_rewrite.c>
+Options +FollowSymlinks -Multiviews
+RewriteEngine on
+
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteRule ^(.*)$ index.php?s=$1 [QSA,PT,L]
+</IfModule>

+ 22 - 0
.vscode/launch.json

@@ -0,0 +1,22 @@
+{
+    // 使用 IntelliSense 了解相关属性。 
+    // 悬停以查看现有属性的描述。
+    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Listen for XDebug",
+            "type": "php",
+            "request": "launch",
+            "port": 9000
+        },
+        {
+            "name": "Launch currently open script",
+            "type": "php",
+            "request": "launch",
+            "program": "${file}",
+            "cwd": "${fileDirname}",
+            "port": 9000
+        }
+    ]
+}

+ 6 - 0
application/.htaccess

@@ -0,0 +1,6 @@
+<IfModule authz_core_module>
+    Require all denied
+</IfModule>
+<IfModule !authz_core_module>
+    Deny from all
+</IfModule>

Різницю між файлами не показано, бо вона завелика
+ 1 - 0
application/cache/branchs


+ 11 - 0
application/cache/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

Різницю між файлами не показано, бо вона завелика
+ 1 - 0
application/cache/setting


+ 135 - 0
application/config/autoload.php

@@ -0,0 +1,135 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------
+| AUTO-LOADER
+| -------------------------------------------------------------------
+| This file specifies which systems should be loaded by default.
+|
+| In order to keep the framework as light-weight as possible only the
+| absolute minimal resources are loaded by default. For example,
+| the database is not connected to automatically since no assumption
+| is made regarding whether you intend to use it.  This file lets
+| you globally define which systems you would like loaded with every
+| request.
+|
+| -------------------------------------------------------------------
+| Instructions
+| -------------------------------------------------------------------
+|
+| These are the things you can load automatically:
+|
+| 1. Packages
+| 2. Libraries
+| 3. Drivers
+| 4. Helper files
+| 5. Custom config files
+| 6. Language files
+| 7. Models
+|
+*/
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Packages
+| -------------------------------------------------------------------
+| Prototype:
+|
+|  $autoload['packages'] = array(APPPATH.'third_party', '/usr/local/shared');
+|
+*/
+$autoload['packages'] = array();
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Libraries
+| -------------------------------------------------------------------
+| These are the classes located in system/libraries/ or your
+| application/libraries/ directory, with the addition of the
+| 'database' library, which is somewhat of a special case.
+|
+| Prototype:
+|
+|	$autoload['libraries'] = array('database', 'email', 'session');
+|
+| You can also supply an alternative library name to be assigned
+| in the controller:
+|
+|	$autoload['libraries'] = array('user_agent' => 'ua');
+*/
+$autoload['libraries'] = array("mongo_db", "session","ci_smarty","serial");
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Drivers
+| -------------------------------------------------------------------
+| These classes are located in system/libraries/ or in your
+| application/libraries/ directory, but are also placed inside their
+| own subdirectory and they extend the CI_Driver_Library class. They
+| offer multiple interchangeable driver options.
+|
+| Prototype:
+|
+|	$autoload['drivers'] = array('cache');
+|
+| You can also supply an alternative property name to be assigned in
+| the controller:
+|
+|	$autoload['drivers'] = array('cache' => 'cch');
+|
+*/
+$autoload['drivers'] = array();
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Helper Files
+| -------------------------------------------------------------------
+| Prototype:
+|
+|	$autoload['helper'] = array('url', 'file');
+*/
+$autoload['helper'] = array('url');
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Config files
+| -------------------------------------------------------------------
+| Prototype:
+|
+|	$autoload['config'] = array('config1', 'config2');
+|
+| NOTE: This item is intended for use ONLY if you have created custom
+| config files.  Otherwise, leave it blank.
+|
+*/
+$autoload['config'] = array('workorder');
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Language files
+| -------------------------------------------------------------------
+| Prototype:
+|
+|	$autoload['language'] = array('lang1', 'lang2');
+|
+| NOTE: Do not include the "_lang" part of your file.  For example
+| "codeigniter_lang.php" would be referenced as array('codeigniter');
+|
+*/
+$autoload['language'] = array();
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Models
+| -------------------------------------------------------------------
+| Prototype:
+|
+|	$autoload['model'] = array('first_model', 'second_model');
+|
+| You can also supply an alternative model name to be assigned
+| in the controller:
+|
+|	$autoload['model'] = array('first_model' => 'first');
+*/
+$autoload['model'] = array();

+ 94 - 0
application/config/config.json

@@ -0,0 +1,94 @@
+/* 前后端通信相关的配置,注释只允许使用多行方式 */
+{
+    /* 上传图片配置项 */
+    "imageActionName": "uploadimage", /* 执行上传图片的action名称 */
+    "imageFieldName": "upfile", /* 提交的图片表单名称 */
+    "imageMaxSize": 2048000, /* 上传大小限制,单位B */
+    "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
+    "imageCompressEnable": true, /* 是否压缩图片,默认是true */
+    "imageCompressBorder": 1600, /* 图片压缩最长边限制 */
+    "imageInsertAlign": "none", /* 插入的图片浮动方式 */
+    "imageUrlPrefix": "", /* 图片访问路径前缀 */
+    "imagePathFormat": "static/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+                                /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
+                                /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
+                                /* {time} 会替换成时间戳 */
+                                /* {yyyy} 会替换成四位年份 */
+                                /* {yy} 会替换成两位年份 */
+                                /* {mm} 会替换成两位月份 */
+                                /* {dd} 会替换成两位日期 */
+                                /* {hh} 会替换成两位小时 */
+                                /* {ii} 会替换成两位分钟 */
+                                /* {ss} 会替换成两位秒 */
+                                /* 非法字符 \ : * ? " < > | */
+                                /* 具请体看线上文档: fex.baidu.com/neditor/#use-format_upload_filename */
+
+    /* 涂鸦图片上传配置项 */
+    "scrawlActionName": "uploadscrawl", /* 执行上传涂鸦的action名称 */
+    "scrawlFieldName": "upfile", /* 提交的图片表单名称 */
+    "scrawlPathFormat": "static/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+    "scrawlMaxSize": 2048000, /* 上传大小限制,单位B */
+    "scrawlUrlPrefix": "", /* 图片访问路径前缀 */
+    "scrawlInsertAlign": "none",
+
+    /* 截图工具上传 */
+    "snapscreenActionName": "uploadimage", /* 执行上传截图的action名称 */
+    "snapscreenPathFormat": "static/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+    "snapscreenUrlPrefix": "", /* 图片访问路径前缀 */
+    "snapscreenInsertAlign": "none", /* 插入的图片浮动方式 */
+
+    /* 抓取远程图片配置 */
+    "catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
+    "catcherActionName": "catchimage", /* 执行抓取远程图片的action名称 */
+    "catcherFieldName": "source", /* 提交的图片列表表单名称 */
+    "catcherPathFormat": "static/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+    "catcherUrlPrefix": "", /* 图片访问路径前缀 */
+    "catcherMaxSize": 2048000, /* 上传大小限制,单位B */
+    "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取图片格式显示 */
+
+    /* 上传视频配置 */
+    "videoActionName": "uploadvideo", /* 执行上传视频的action名称 */
+    "videoFieldName": "upfile", /* 提交的视频表单名称 */
+    "videoPathFormat": "static/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+    "videoUrlPrefix": "", /* 视频访问路径前缀 */
+    "videoMaxSize": 102400000, /* 上传大小限制,单位B,默认100MB */
+    "videoAllowFiles": [
+        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
+        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"], /* 上传视频格式显示 */
+
+    /* 上传文件配置 */
+    "fileActionName": "uploadfile", /* controller里,执行上传视频的action名称 */
+    "fileFieldName": "upfile", /* 提交的文件表单名称 */
+    "filePathFormat": "static/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+    "fileUrlPrefix": "", /* 文件访问路径前缀 */
+    "fileMaxSize": 51200000, /* 上传大小限制,单位B,默认50MB */
+    "fileAllowFiles": [
+        ".png", ".jpg", ".jpeg", ".gif", ".bmp",
+        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
+        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
+        ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
+        ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
+    ], /* 上传文件格式显示 */
+
+    /* 列出指定目录下的图片 */
+    "imageManagerActionName": "listimage", /* 执行图片管理的action名称 */
+    "imageManagerListPath": "static/upload/image/", /* 指定要列出图片的目录 */
+    "imageManagerListSize": 20, /* 每次列出文件数量 */
+    "imageManagerUrlPrefix": "", /* 图片访问路径前缀 */
+    "imageManagerInsertAlign": "none", /* 插入的图片浮动方式 */
+    "imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 列出的文件类型 */
+
+    /* 列出指定目录下的文件 */
+    "fileManagerActionName": "listfile", /* 执行文件管理的action名称 */
+    "fileManagerListPath": "static/upload/file/", /* 指定要列出文件的目录 */
+    "fileManagerUrlPrefix": "", /* 文件访问路径前缀 */
+    "fileManagerListSize": 20, /* 每次列出文件数量 */
+    "fileManagerAllowFiles": [
+        ".png", ".jpg", ".jpeg", ".gif", ".bmp",
+        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
+        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
+        ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
+        ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
+    ] /* 列出的文件类型 */
+
+}

+ 527 - 0
application/config/config.php

@@ -0,0 +1,527 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+|--------------------------------------------------------------------------
+| Base Site URL
+|--------------------------------------------------------------------------
+|
+| URL to your CodeIgniter root. Typically this will be your base URL,
+| WITH a trailing slash:
+|
+|	http://example.com/
+|
+| WARNING: You MUST set this value!
+|
+| If it is not set, then CodeIgniter will try guess the protocol and path
+| your installation, but due to security concerns the hostname will be set
+| to $_SERVER['SERVER_ADDR'] if available, or localhost otherwise.
+| The auto-detection mechanism exists only for convenience during
+| development and MUST NOT be used in production!
+|
+| If you need to allow multiple domains, remember that this file is still
+| a PHP script and you can easily do that on your own.
+|
+*/
+$config['base_url'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Index File
+|--------------------------------------------------------------------------
+|
+| Typically this will be your index.php file, unless you've renamed it to
+| something else. If you are using mod_rewrite to remove the page set this
+| variable so that it is blank.
+|
+*/
+$config['index_page'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| URI PROTOCOL
+|--------------------------------------------------------------------------
+|
+| This item determines which server global should be used to retrieve the
+| URI string.  The default setting of 'REQUEST_URI' works for most servers.
+| If your links do not seem to work, try one of the other delicious flavors:
+|
+| 'REQUEST_URI'    Uses $_SERVER['REQUEST_URI']
+| 'QUERY_STRING'   Uses $_SERVER['QUERY_STRING']
+| 'PATH_INFO'      Uses $_SERVER['PATH_INFO']
+|
+| WARNING: If you set this to 'PATH_INFO', URIs will always be URL-decoded!
+*/
+$config['uri_protocol']	= 'REQUEST_URI';
+
+/*
+|--------------------------------------------------------------------------
+| URL suffix
+|--------------------------------------------------------------------------
+|
+| This option allows you to add a suffix to all URLs generated by CodeIgniter.
+| For more information please see the user guide:
+|
+| https://codeigniter.com/user_guide/general/urls.html
+*/
+$config['url_suffix'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Default Language
+|--------------------------------------------------------------------------
+|
+| This determines which set of language files should be used. Make sure
+| there is an available translation if you intend to use something other
+| than english.
+|
+*/
+$config['language']	= 'english';
+
+/*
+|--------------------------------------------------------------------------
+| Default Character Set
+|--------------------------------------------------------------------------
+|
+| This determines which character set is used by default in various methods
+| that require a character set to be provided.
+|
+| See http://php.net/htmlspecialchars for a list of supported charsets.
+|
+*/
+$config['charset'] = 'UTF-8';
+
+/*
+|--------------------------------------------------------------------------
+| Enable/Disable System Hooks
+|--------------------------------------------------------------------------
+|
+| If you would like to use the 'hooks' feature you must enable it by
+| setting this variable to TRUE (boolean).  See the user guide for details.
+|
+*/
+$config['enable_hooks'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Class Extension Prefix
+|--------------------------------------------------------------------------
+|
+| This item allows you to set the filename/classname prefix when extending
+| native libraries.  For more information please see the user guide:
+|
+| https://codeigniter.com/user_guide/general/core_classes.html
+| https://codeigniter.com/user_guide/general/creating_libraries.html
+|
+*/
+$config['subclass_prefix'] = 'MY_';
+
+/*
+|--------------------------------------------------------------------------
+| Composer auto-loading
+|--------------------------------------------------------------------------
+|
+| Enabling this setting will tell CodeIgniter to look for a Composer
+| package auto-loader script in application/vendor/autoload.php.
+|
+|	$config['composer_autoload'] = TRUE;
+|
+| Or if you have your vendor/ directory located somewhere else, you
+| can opt to set a specific path as well:
+|
+|	$config['composer_autoload'] = '/path/to/vendor/autoload.php';
+|
+| For more information about Composer, please visit http://getcomposer.org/
+|
+| Note: This will NOT disable or override the CodeIgniter-specific
+|	autoloading (application/config/autoload.php)
+*/
+$config['composer_autoload'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Allowed URL Characters
+|--------------------------------------------------------------------------
+|
+| This lets you specify which characters are permitted within your URLs.
+| When someone tries to submit a URL with disallowed characters they will
+| get a warning message.
+|
+| As a security measure you are STRONGLY encouraged to restrict URLs to
+| as few characters as possible.  By default only these are allowed: a-z 0-9~%.:_-
+|
+| Leave blank to allow all characters -- but only if you are insane.
+|
+| The configured value is actually a regular expression character group
+| and it will be executed as: ! preg_match('/^[<permitted_uri_chars>]+$/i
+|
+| DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!!
+|
+*/
+$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';
+
+/*
+|--------------------------------------------------------------------------
+| Enable Query Strings
+|--------------------------------------------------------------------------
+|
+| By default CodeIgniter uses search-engine friendly segment based URLs:
+| example.com/who/what/where/
+|
+| You can optionally enable standard query string based URLs:
+| example.com?who=me&what=something&where=here
+|
+| Options are: TRUE or FALSE (boolean)
+|
+| The other items let you set the query string 'words' that will
+| invoke your controllers and its functions:
+| example.com/index.php?c=controller&m=function
+|
+| Please note that some of the helpers won't work as expected when
+| this feature is enabled, since CodeIgniter is designed primarily to
+| use segment based URLs.
+|
+*/
+$config['enable_query_strings'] = FALSE;
+$config['controller_trigger'] = 'c';
+$config['function_trigger'] = 'm';
+$config['directory_trigger'] = 'd';
+
+/*
+|--------------------------------------------------------------------------
+| Allow $_GET array
+|--------------------------------------------------------------------------
+|
+| By default CodeIgniter enables access to the $_GET array.  If for some
+| reason you would like to disable it, set 'allow_get_array' to FALSE.
+|
+| WARNING: This feature is DEPRECATED and currently available only
+|          for backwards compatibility purposes!
+|
+*/
+$config['allow_get_array'] = TRUE;
+
+/*
+|--------------------------------------------------------------------------
+| Error Logging Threshold
+|--------------------------------------------------------------------------
+|
+| You can enable error logging by setting a threshold over zero. The
+| threshold determines what gets logged. Threshold options are:
+|
+|	0 = Disables logging, Error logging TURNED OFF
+|	1 = Error Messages (including PHP errors)
+|	2 = Debug Messages
+|	3 = Informational Messages
+|	4 = All Messages
+|
+| You can also pass an array with threshold levels to show individual error types
+|
+| 	array(2) = Debug Messages, without Error Messages
+|
+| For a live site you'll usually only enable Errors (1) to be logged otherwise
+| your log files will fill up very fast.
+|
+*/
+$config['log_threshold'] = 0;
+
+/*
+|--------------------------------------------------------------------------
+| Error Logging Directory Path
+|--------------------------------------------------------------------------
+|
+| Leave this BLANK unless you would like to set something other than the default
+| application/logs/ directory. Use a full server path with trailing slash.
+|
+*/
+$config['log_path'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Log File Extension
+|--------------------------------------------------------------------------
+|
+| The default filename extension for log files. The default 'php' allows for
+| protecting the log files via basic scripting, when they are to be stored
+| under a publicly accessible directory.
+|
+| Note: Leaving it blank will default to 'php'.
+|
+*/
+$config['log_file_extension'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Log File Permissions
+|--------------------------------------------------------------------------
+|
+| The file system permissions to be applied on newly created log files.
+|
+| IMPORTANT: This MUST be an integer (no quotes) and you MUST use octal
+|            integer notation (i.e. 0700, 0644, etc.)
+*/
+$config['log_file_permissions'] = 0644;
+
+/*
+|--------------------------------------------------------------------------
+| Date Format for Logs
+|--------------------------------------------------------------------------
+|
+| Each item that is logged has an associated date. You can use PHP date
+| codes to set your own date formatting
+|
+*/
+$config['log_date_format'] = 'Y-m-d H:i:s';
+
+/*
+|--------------------------------------------------------------------------
+| Error Views Directory Path
+|--------------------------------------------------------------------------
+|
+| Leave this BLANK unless you would like to set something other than the default
+| application/views/errors/ directory.  Use a full server path with trailing slash.
+|
+*/
+$config['error_views_path'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Cache Directory Path
+|--------------------------------------------------------------------------
+|
+| Leave this BLANK unless you would like to set something other than the default
+| application/cache/ directory.  Use a full server path with trailing slash.
+|
+*/
+$config['cache_path'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Cache Include Query String
+|--------------------------------------------------------------------------
+|
+| Whether to take the URL query string into consideration when generating
+| output cache files. Valid options are:
+|
+|	FALSE      = Disabled
+|	TRUE       = Enabled, take all query parameters into account.
+|	             Please be aware that this may result in numerous cache
+|	             files generated for the same page over and over again.
+|	array('q') = Enabled, but only take into account the specified list
+|	             of query parameters.
+|
+*/
+$config['cache_query_string'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Encryption Key
+|--------------------------------------------------------------------------
+|
+| If you use the Encryption class, you must set an encryption key.
+| See the user guide for more info.
+|
+| https://codeigniter.com/user_guide/libraries/encryption.html
+|
+*/
+$config['encryption_key'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Session Variables
+|--------------------------------------------------------------------------
+|
+| 'sess_driver'
+|
+|	The storage driver to use: files, database, redis, memcached
+|
+| 'sess_cookie_name'
+|
+|	The session cookie name, must contain only [0-9a-z_-] characters
+|
+| 'sess_expiration'
+|
+|	The number of SECONDS you want the session to last.
+|	Setting to 0 (zero) means expire when the browser is closed.
+|
+| 'sess_save_path'
+|
+|	The location to save sessions to, driver dependent.
+|
+|	For the 'files' driver, it's a path to a writable directory.
+|	WARNING: Only absolute paths are supported!
+|
+|	For the 'database' driver, it's a table name.
+|	Please read up the manual for the format with other session drivers.
+|
+|	IMPORTANT: You are REQUIRED to set a valid save path!
+|
+| 'sess_match_ip'
+|
+|	Whether to match the user's IP address when reading the session data.
+|
+|	WARNING: If you're using the database driver, don't forget to update
+|	         your session table's PRIMARY KEY when changing this setting.
+|
+| 'sess_time_to_update'
+|
+|	How many seconds between CI regenerating the session ID.
+|
+| 'sess_regenerate_destroy'
+|
+|	Whether to destroy session data associated with the old session ID
+|	when auto-regenerating the session ID. When set to FALSE, the data
+|	will be later deleted by the garbage collector.
+|
+| Other session cookie settings are shared with the rest of the application,
+| except for 'cookie_prefix' and 'cookie_httponly', which are ignored here.
+|
+*/
+$config['sess_driver'] = 'files';
+$config['sess_cookie_name'] = 'ci_session';
+$config['sess_expiration'] = 7200;
+$config['sess_save_path'] = NULL;
+$config['sess_match_ip'] = FALSE;
+$config['sess_time_to_update'] = 300;
+$config['sess_regenerate_destroy'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Cookie Related Variables
+|--------------------------------------------------------------------------
+|
+| 'cookie_prefix'   = Set a cookie name prefix if you need to avoid collisions
+| 'cookie_domain'   = Set to .your-domain.com for site-wide cookies
+| 'cookie_path'     = Typically will be a forward slash
+| 'cookie_secure'   = Cookie will only be set if a secure HTTPS connection exists.
+| 'cookie_httponly' = Cookie will only be accessible via HTTP(S) (no javascript)
+|
+| Note: These settings (with the exception of 'cookie_prefix' and
+|       'cookie_httponly') will also affect sessions.
+|
+*/
+$config['cookie_prefix']	= '';
+$config['cookie_domain']	= '';
+$config['cookie_path']		= '/';
+$config['cookie_secure']	= FALSE;
+$config['cookie_httponly'] 	= FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Standardize newlines
+|--------------------------------------------------------------------------
+|
+| Determines whether to standardize newline characters in input data,
+| meaning to replace \r\n, \r, \n occurrences with the PHP_EOL value.
+|
+| WARNING: This feature is DEPRECATED and currently available only
+|          for backwards compatibility purposes!
+|
+*/
+$config['standardize_newlines'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Global XSS Filtering
+|--------------------------------------------------------------------------
+|
+| Determines whether the XSS filter is always active when GET, POST or
+| COOKIE data is encountered
+|
+| WARNING: This feature is DEPRECATED and currently available only
+|          for backwards compatibility purposes!
+|
+*/
+$config['global_xss_filtering'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Cross Site Request Forgery
+|--------------------------------------------------------------------------
+| Enables a CSRF cookie token to be set. When set to TRUE, token will be
+| checked on a submitted form. If you are accepting user data, it is strongly
+| recommended CSRF protection be enabled.
+|
+| 'csrf_token_name' = The token name
+| 'csrf_cookie_name' = The cookie name
+| 'csrf_expire' = The number in seconds the token should expire.
+| 'csrf_regenerate' = Regenerate token on every submission
+| 'csrf_exclude_uris' = Array of URIs which ignore CSRF checks
+*/
+$config['csrf_protection'] = FALSE;
+$config['csrf_token_name'] = 'csrf_token_name';
+$config['csrf_cookie_name'] = 'csrf_cookie_name';
+$config['csrf_expire'] = 7200;
+$config['csrf_regenerate'] = TRUE;
+$config['csrf_exclude_uris'] = array();
+
+/*
+|--------------------------------------------------------------------------
+| Output Compression
+|--------------------------------------------------------------------------
+|
+| Enables Gzip output compression for faster page loads.  When enabled,
+| the output class will test whether your server supports Gzip.
+| Even if it does, however, not all browsers support compression
+| so enable only if you are reasonably sure your visitors can handle it.
+|
+| Only used if zlib.output_compression is turned off in your php.ini.
+| Please do not use it together with httpd-level output compression.
+|
+| VERY IMPORTANT:  If you are getting a blank page when compression is enabled it
+| means you are prematurely outputting something to your browser. It could
+| even be a line of whitespace at the end of one of your scripts.  For
+| compression to work, nothing can be sent before the output buffer is called
+| by the output class.  Do not 'echo' any values with compression enabled.
+|
+*/
+$config['compress_output'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Master Time Reference
+|--------------------------------------------------------------------------
+|
+| Options are 'local' or any PHP supported timezone. This preference tells
+| the system whether to use your server's local time as the master 'now'
+| reference, or convert it to the configured one timezone. See the 'date
+| helper' page of the user guide for information regarding date handling.
+|
+*/
+$config['time_reference'] = 'local';
+
+/*
+|--------------------------------------------------------------------------
+| Rewrite PHP Short Tags
+|--------------------------------------------------------------------------
+|
+| If your PHP installation does not have short tag support enabled CI
+| can rewrite the tags on-the-fly, enabling you to utilize that syntax
+| in your view files.  Options are TRUE or FALSE (boolean)
+|
+| Note: You need to have eval() enabled for this to work.
+|
+*/
+$config['rewrite_short_tags'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Reverse Proxy IPs
+|--------------------------------------------------------------------------
+|
+| If your server is behind a reverse proxy, you must whitelist the proxy
+| IP addresses from which CodeIgniter should trust headers such as
+| HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify
+| the visitor's IP address.
+|
+| You can use both an array or a comma-separated list of proxy addresses,
+| as well as specifying whole subnets. Here are a few examples:
+|
+| Comma-separated:	'10.0.1.200,192.168.5.0/24'
+| Array:		array('10.0.1.200', '192.168.5.0/24')
+*/
+$config['proxy_ips'] = '';
+
+$config['page_size'] = 10;
+
+$config['secret_key'] = "work_order";

+ 85 - 0
application/config/constants.php

@@ -0,0 +1,85 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+|--------------------------------------------------------------------------
+| Display Debug backtrace
+|--------------------------------------------------------------------------
+|
+| If set to TRUE, a backtrace will be displayed along with php errors. If
+| error_reporting is disabled, the backtrace will not display, regardless
+| of this setting
+|
+*/
+defined('SHOW_DEBUG_BACKTRACE') OR define('SHOW_DEBUG_BACKTRACE', TRUE);
+
+/*
+|--------------------------------------------------------------------------
+| File and Directory Modes
+|--------------------------------------------------------------------------
+|
+| These prefs are used when checking and setting modes when working
+| with the file system.  The defaults are fine on servers with proper
+| security, but you may wish (or even need) to change the values in
+| certain environments (Apache running a separate process for each
+| user, PHP under CGI with Apache suEXEC, etc.).  Octal values should
+| always be used to set the mode correctly.
+|
+*/
+defined('FILE_READ_MODE')  OR define('FILE_READ_MODE', 0644);
+defined('FILE_WRITE_MODE') OR define('FILE_WRITE_MODE', 0666);
+defined('DIR_READ_MODE')   OR define('DIR_READ_MODE', 0755);
+defined('DIR_WRITE_MODE')  OR define('DIR_WRITE_MODE', 0755);
+
+/*
+|--------------------------------------------------------------------------
+| File Stream Modes
+|--------------------------------------------------------------------------
+|
+| These modes are used when working with fopen()/popen()
+|
+*/
+defined('FOPEN_READ')                           OR define('FOPEN_READ', 'rb');
+defined('FOPEN_READ_WRITE')                     OR define('FOPEN_READ_WRITE', 'r+b');
+defined('FOPEN_WRITE_CREATE_DESTRUCTIVE')       OR define('FOPEN_WRITE_CREATE_DESTRUCTIVE', 'wb'); // truncates existing file data, use with care
+defined('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE')  OR define('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE', 'w+b'); // truncates existing file data, use with care
+defined('FOPEN_WRITE_CREATE')                   OR define('FOPEN_WRITE_CREATE', 'ab');
+defined('FOPEN_READ_WRITE_CREATE')              OR define('FOPEN_READ_WRITE_CREATE', 'a+b');
+defined('FOPEN_WRITE_CREATE_STRICT')            OR define('FOPEN_WRITE_CREATE_STRICT', 'xb');
+defined('FOPEN_READ_WRITE_CREATE_STRICT')       OR define('FOPEN_READ_WRITE_CREATE_STRICT', 'x+b');
+
+/*
+|--------------------------------------------------------------------------
+| Exit Status Codes
+|--------------------------------------------------------------------------
+|
+| Used to indicate the conditions under which the script is exit()ing.
+| While there is no universal standard for error codes, there are some
+| broad conventions.  Three such conventions are mentioned below, for
+| those who wish to make use of them.  The CodeIgniter defaults were
+| chosen for the least overlap with these conventions, while still
+| leaving room for others to be defined in future versions and user
+| applications.
+|
+| The three main conventions used for determining exit status codes
+| are as follows:
+|
+|    Standard C/C++ Library (stdlibc):
+|       http://www.gnu.org/software/libc/manual/html_node/Exit-Status.html
+|       (This link also contains other GNU-specific conventions)
+|    BSD sysexits.h:
+|       http://www.gsp.com/cgi-bin/man.cgi?section=3&topic=sysexits
+|    Bash scripting:
+|       http://tldp.org/LDP/abs/html/exitcodes.html
+|
+*/
+defined('EXIT_SUCCESS')        OR define('EXIT_SUCCESS', 0); // no errors
+defined('EXIT_ERROR')          OR define('EXIT_ERROR', 1); // generic error
+defined('EXIT_CONFIG')         OR define('EXIT_CONFIG', 3); // configuration error
+defined('EXIT_UNKNOWN_FILE')   OR define('EXIT_UNKNOWN_FILE', 4); // file not found
+defined('EXIT_UNKNOWN_CLASS')  OR define('EXIT_UNKNOWN_CLASS', 5); // unknown class
+defined('EXIT_UNKNOWN_METHOD') OR define('EXIT_UNKNOWN_METHOD', 6); // unknown class member
+defined('EXIT_USER_INPUT')     OR define('EXIT_USER_INPUT', 7); // invalid user input
+defined('EXIT_DATABASE')       OR define('EXIT_DATABASE', 8); // database error
+defined('EXIT__AUTO_MIN')      OR define('EXIT__AUTO_MIN', 9); // lowest automatically-assigned error code
+defined('EXIT__AUTO_MAX')      OR define('EXIT__AUTO_MAX', 125); // highest automatically-assigned error code

+ 96 - 0
application/config/database.php

@@ -0,0 +1,96 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------
+| DATABASE CONNECTIVITY SETTINGS
+| -------------------------------------------------------------------
+| This file will contain the settings needed to access your database.
+|
+| For complete instructions please consult the 'Database Connection'
+| page of the User Guide.
+|
+| -------------------------------------------------------------------
+| EXPLANATION OF VARIABLES
+| -------------------------------------------------------------------
+|
+|	['dsn']      The full DSN string describe a connection to the database.
+|	['hostname'] The hostname of your database server.
+|	['username'] The username used to connect to the database
+|	['password'] The password used to connect to the database
+|	['database'] The name of the database you want to connect to
+|	['dbdriver'] The database driver. e.g.: mysqli.
+|			Currently supported:
+|				 cubrid, ibase, mssql, mysql, mysqli, oci8,
+|				 odbc, pdo, postgre, sqlite, sqlite3, sqlsrv
+|	['dbprefix'] You can add an optional prefix, which will be added
+|				 to the table name when using the  Query Builder class
+|	['pconnect'] TRUE/FALSE - Whether to use a persistent connection
+|	['db_debug'] TRUE/FALSE - Whether database errors should be displayed.
+|	['cache_on'] TRUE/FALSE - Enables/disables query caching
+|	['cachedir'] The path to the folder where cache files should be stored
+|	['char_set'] The character set used in communicating with the database
+|	['dbcollat'] The character collation used in communicating with the database
+|				 NOTE: For MySQL and MySQLi databases, this setting is only used
+| 				 as a backup if your server is running PHP < 5.2.3 or MySQL < 5.0.7
+|				 (and in table creation queries made with DB Forge).
+| 				 There is an incompatibility in PHP with mysql_real_escape_string() which
+| 				 can make your site vulnerable to SQL injection if you are using a
+| 				 multi-byte character set and are running versions lower than these.
+| 				 Sites using Latin-1 or UTF-8 database character set and collation are unaffected.
+|	['swap_pre'] A default table prefix that should be swapped with the dbprefix
+|	['encrypt']  Whether or not to use an encrypted connection.
+|
+|			'mysql' (deprecated), 'sqlsrv' and 'pdo/sqlsrv' drivers accept TRUE/FALSE
+|			'mysqli' and 'pdo/mysql' drivers accept an array with the following options:
+|
+|				'ssl_key'    - Path to the private key file
+|				'ssl_cert'   - Path to the public key certificate file
+|				'ssl_ca'     - Path to the certificate authority file
+|				'ssl_capath' - Path to a directory containing trusted CA certificates in PEM format
+|				'ssl_cipher' - List of *allowed* ciphers to be used for the encryption, separated by colons (':')
+|				'ssl_verify' - TRUE/FALSE; Whether verify the server certificate or not ('mysqli' only)
+|
+|	['compress'] Whether or not to use client compression (MySQL only)
+|	['stricton'] TRUE/FALSE - forces 'Strict Mode' connections
+|							- good for ensuring strict SQL while developing
+|	['ssl_options']	Used to set various SSL options that can be used when making SSL connections.
+|	['failover'] array - A array with 0 or more data for connections if the main should fail.
+|	['save_queries'] TRUE/FALSE - Whether to "save" all executed queries.
+| 				NOTE: Disabling this will also effectively disable both
+| 				$this->db->last_query() and profiling of DB queries.
+| 				When you run a query, with this setting set to TRUE (default),
+| 				CodeIgniter will store the SQL statement for debugging purposes.
+| 				However, this may cause high memory usage, especially if you run
+| 				a lot of SQL queries ... disable this to avoid that problem.
+|
+| The $active_group variable lets you choose which connection group to
+| make active.  By default there is only one group (the 'default' group).
+|
+| The $query_builder variables lets you determine whether or not to load
+| the query builder class.
+*/
+$active_group = 'default';
+$query_builder = TRUE;
+
+$db['default'] = array(
+	'dsn'	=> '',
+	'hostname' => 'localhost',
+	'username' => '',
+	'password' => '',
+	'database' => '',
+	'dbdriver' => 'mysqli',
+	'dbprefix' => '',
+	'pconnect' => FALSE,
+	'db_debug' => (ENVIRONMENT !== 'production'),
+	'cache_on' => FALSE,
+	'cachedir' => '',
+	'char_set' => 'utf8',
+	'dbcollat' => 'utf8_general_ci',
+	'swap_pre' => '',
+	'encrypt' => FALSE,
+	'compress' => FALSE,
+	'stricton' => FALSE,
+	'failover' => array(),
+	'save_queries' => TRUE
+);

+ 24 - 0
application/config/doctypes.php

@@ -0,0 +1,24 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+$_doctypes = array(
+	'xhtml11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
+	'xhtml1-strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
+	'xhtml1-trans' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
+	'xhtml1-frame' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
+	'xhtml-basic11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',
+	'html5' => '<!DOCTYPE html>',
+	'html4-strict' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
+	'html4-trans' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
+	'html4-frame' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">',
+	'mathml1' => '<!DOCTYPE math SYSTEM "http://www.w3.org/Math/DTD/mathml1/mathml.dtd">',
+	'mathml2' => '<!DOCTYPE math PUBLIC "-//W3C//DTD MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/mathml2.dtd">',
+	'svg10' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">',
+	'svg11' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">',
+	'svg11-basic' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">',
+	'svg11-tiny' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">',
+	'xhtml-math-svg-xh' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">',
+	'xhtml-math-svg-sh' => '<!DOCTYPE svg:svg PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">',
+	'xhtml-rdfa-1' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">',
+	'xhtml-rdfa-2' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.1//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd">'
+);

+ 103 - 0
application/config/foreign_chars.php

@@ -0,0 +1,103 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------
+| Foreign Characters
+| -------------------------------------------------------------------
+| This file contains an array of foreign characters for transliteration
+| conversion used by the Text helper
+|
+*/
+$foreign_characters = array(
+	'/ä|æ|ǽ/' => 'ae',
+	'/ö|œ/' => 'oe',
+	'/ü/' => 'ue',
+	'/Ä/' => 'Ae',
+	'/Ü/' => 'Ue',
+	'/Ö/' => 'Oe',
+	'/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ|Α|Ά|Ả|Ạ|Ầ|Ẫ|Ẩ|Ậ|Ằ|Ắ|Ẵ|Ẳ|Ặ|А/' => 'A',
+	'/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª|α|ά|ả|ạ|ầ|ấ|ẫ|ẩ|ậ|ằ|ắ|ẵ|ẳ|ặ|а/' => 'a',
+	'/Б/' => 'B',
+	'/б/' => 'b',
+	'/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
+	'/ç|ć|ĉ|ċ|č/' => 'c',
+	'/Д/' => 'D',
+	'/д/' => 'd',
+	'/Ð|Ď|Đ|Δ/' => 'Dj',
+	'/ð|ď|đ|δ/' => 'dj',
+	'/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Ε|Έ|Ẽ|Ẻ|Ẹ|Ề|Ế|Ễ|Ể|Ệ|Е|Э/' => 'E',
+	'/è|é|ê|ë|ē|ĕ|ė|ę|ě|έ|ε|ẽ|ẻ|ẹ|ề|ế|ễ|ể|ệ|е|э/' => 'e',
+	'/Ф/' => 'F',
+	'/ф/' => 'f',
+	'/Ĝ|Ğ|Ġ|Ģ|Γ|Г|Ґ/' => 'G',
+	'/ĝ|ğ|ġ|ģ|γ|г|ґ/' => 'g',
+	'/Ĥ|Ħ/' => 'H',
+	'/ĥ|ħ/' => 'h',
+	'/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|Η|Ή|Ί|Ι|Ϊ|Ỉ|Ị|И|Ы/' => 'I',
+	'/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|η|ή|ί|ι|ϊ|ỉ|ị|и|ы|ї/' => 'i',
+	'/Ĵ/' => 'J',
+	'/ĵ/' => 'j',
+	'/Ķ|Κ|К/' => 'K',
+	'/ķ|κ|к/' => 'k',
+	'/Ĺ|Ļ|Ľ|Ŀ|Ł|Λ|Л/' => 'L',
+	'/ĺ|ļ|ľ|ŀ|ł|λ|л/' => 'l',
+	'/М/' => 'M',
+	'/м/' => 'm',
+	'/Ñ|Ń|Ņ|Ň|Ν|Н/' => 'N',
+	'/ñ|ń|ņ|ň|ʼn|ν|н/' => 'n',
+	'/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ|Ο|Ό|Ω|Ώ|Ỏ|Ọ|Ồ|Ố|Ỗ|Ổ|Ộ|Ờ|Ớ|Ỡ|Ở|Ợ|О/' => 'O',
+	'/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º|ο|ό|ω|ώ|ỏ|ọ|ồ|ố|ỗ|ổ|ộ|ờ|ớ|ỡ|ở|ợ|о/' => 'o',
+	'/П/' => 'P',
+	'/п/' => 'p',
+	'/Ŕ|Ŗ|Ř|Ρ|Р/' => 'R',
+	'/ŕ|ŗ|ř|ρ|р/' => 'r',
+	'/Ś|Ŝ|Ş|Ș|Š|Σ|С/' => 'S',
+	'/ś|ŝ|ş|ș|š|ſ|σ|ς|с/' => 's',
+	'/Ț|Ţ|Ť|Ŧ|τ|Т/' => 'T',
+	'/ț|ţ|ť|ŧ|т/' => 't',
+	'/Þ|þ/' => 'th',
+	'/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|Ũ|Ủ|Ụ|Ừ|Ứ|Ữ|Ử|Ự|У/' => 'U',
+	'/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|υ|ύ|ϋ|ủ|ụ|ừ|ứ|ữ|ử|ự|у/' => 'u',
+	'/Ƴ|Ɏ|Ỵ|Ẏ|Ӳ|Ӯ|Ў|Ý|Ÿ|Ŷ|Υ|Ύ|Ϋ|Ỳ|Ỹ|Ỷ|Ỵ|Й/' => 'Y',
+	'/ẙ|ʏ|ƴ|ɏ|ỵ|ẏ|ӳ|ӯ|ў|ý|ÿ|ŷ|ỳ|ỹ|ỷ|ỵ|й/' => 'y',
+	'/В/' => 'V',
+	'/в/' => 'v',
+	'/Ŵ/' => 'W',
+	'/ŵ/' => 'w',
+	'/Ź|Ż|Ž|Ζ|З/' => 'Z',
+	'/ź|ż|ž|ζ|з/' => 'z',
+	'/Æ|Ǽ/' => 'AE',
+	'/ß/' => 'ss',
+	'/IJ/' => 'IJ',
+	'/ij/' => 'ij',
+	'/Œ/' => 'OE',
+	'/ƒ/' => 'f',
+	'/ξ/' => 'ks',
+	'/π/' => 'p',
+	'/β/' => 'v',
+	'/μ/' => 'm',
+	'/ψ/' => 'ps',
+	'/Ё/' => 'Yo',
+	'/ё/' => 'yo',
+	'/Є/' => 'Ye',
+	'/є/' => 'ye',
+	'/Ї/' => 'Yi',
+	'/Ж/' => 'Zh',
+	'/ж/' => 'zh',
+	'/Х/' => 'Kh',
+	'/х/' => 'kh',
+	'/Ц/' => 'Ts',
+	'/ц/' => 'ts',
+	'/Ч/' => 'Ch',
+	'/ч/' => 'ch',
+	'/Ш/' => 'Sh',
+	'/ш/' => 'sh',
+	'/Щ/' => 'Shch',
+	'/щ/' => 'shch',
+	'/Ъ|ъ|Ь|ь/' => '',
+	'/Ю/' => 'Yu',
+	'/ю/' => 'yu',
+	'/Я/' => 'Ya',
+	'/я/' => 'ya'
+);

+ 13 - 0
application/config/hooks.php

@@ -0,0 +1,13 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------------
+| Hooks
+| -------------------------------------------------------------------------
+| This file lets you define "hooks" to extend CI without hacking the core
+| files.  Please see the user guide for info:
+|
+|	https://codeigniter.com/user_guide/general/hooks.html
+|
+*/

+ 11 - 0
application/config/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 19 - 0
application/config/memcached.php

@@ -0,0 +1,19 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------------
+| Memcached settings
+| -------------------------------------------------------------------------
+| Your Memcached servers can be specified below.
+|
+|	See: https://codeigniter.com/user_guide/libraries/caching.html#memcached
+|
+*/
+$config = array(
+	'default' => array(
+		'hostname' => '127.0.0.1',
+		'port'     => '11211',
+		'weight'   => '1',
+	),
+);

+ 84 - 0
application/config/migration.php

@@ -0,0 +1,84 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+|--------------------------------------------------------------------------
+| Enable/Disable Migrations
+|--------------------------------------------------------------------------
+|
+| Migrations are disabled by default for security reasons.
+| You should enable migrations whenever you intend to do a schema migration
+| and disable it back when you're done.
+|
+*/
+$config['migration_enabled'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Migration Type
+|--------------------------------------------------------------------------
+|
+| Migration file names may be based on a sequential identifier or on
+| a timestamp. Options are:
+|
+|   'sequential' = Sequential migration naming (001_add_blog.php)
+|   'timestamp'  = Timestamp migration naming (20121031104401_add_blog.php)
+|                  Use timestamp format YYYYMMDDHHIISS.
+|
+| Note: If this configuration value is missing the Migration library
+|       defaults to 'sequential' for backward compatibility with CI2.
+|
+*/
+$config['migration_type'] = 'timestamp';
+
+/*
+|--------------------------------------------------------------------------
+| Migrations table
+|--------------------------------------------------------------------------
+|
+| This is the name of the table that will store the current migrations state.
+| When migrations runs it will store in a database table which migration
+| level the system is at. It then compares the migration level in this
+| table to the $config['migration_version'] if they are not the same it
+| will migrate up. This must be set.
+|
+*/
+$config['migration_table'] = 'migrations';
+
+/*
+|--------------------------------------------------------------------------
+| Auto Migrate To Latest
+|--------------------------------------------------------------------------
+|
+| If this is set to TRUE when you load the migrations class and have
+| $config['migration_enabled'] set to TRUE the system will auto migrate
+| to your latest migration (whatever $config['migration_version'] is
+| set to). This way you do not have to call migrations anywhere else
+| in your code to have the latest migration.
+|
+*/
+$config['migration_auto_latest'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Migrations version
+|--------------------------------------------------------------------------
+|
+| This is used to set migration version that the file system should be on.
+| If you run $this->migration->current() this is the version that schema will
+| be upgraded / downgraded to.
+|
+*/
+$config['migration_version'] = 0;
+
+/*
+|--------------------------------------------------------------------------
+| Migrations Path
+|--------------------------------------------------------------------------
+|
+| Path to your migrations folder.
+| Typically, it will be within your application path.
+| Also, writing permission is required within the migrations path.
+|
+*/
+$config['migration_path'] = APPPATH.'migrations/';

+ 183 - 0
application/config/mimes.php

@@ -0,0 +1,183 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------
+| MIME TYPES
+| -------------------------------------------------------------------
+| This file contains an array of mime types.  It is used by the
+| Upload class to help identify allowed file types.
+|
+*/
+return array(
+	'hqx'	=>	array('application/mac-binhex40', 'application/mac-binhex', 'application/x-binhex40', 'application/x-mac-binhex40'),
+	'cpt'	=>	'application/mac-compactpro',
+	'csv'	=>	array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain'),
+	'bin'	=>	array('application/macbinary', 'application/mac-binary', 'application/octet-stream', 'application/x-binary', 'application/x-macbinary'),
+	'dms'	=>	'application/octet-stream',
+	'lha'	=>	'application/octet-stream',
+	'lzh'	=>	'application/octet-stream',
+	'exe'	=>	array('application/octet-stream', 'application/x-msdownload'),
+	'class'	=>	'application/octet-stream',
+	'psd'	=>	array('application/x-photoshop', 'image/vnd.adobe.photoshop'),
+	'so'	=>	'application/octet-stream',
+	'sea'	=>	'application/octet-stream',
+	'dll'	=>	'application/octet-stream',
+	'oda'	=>	'application/oda',
+	'pdf'	=>	array('application/pdf', 'application/force-download', 'application/x-download', 'binary/octet-stream'),
+	'ai'	=>	array('application/pdf', 'application/postscript'),
+	'eps'	=>	'application/postscript',
+	'ps'	=>	'application/postscript',
+	'smi'	=>	'application/smil',
+	'smil'	=>	'application/smil',
+	'mif'	=>	'application/vnd.mif',
+	'xls'	=>	array('application/vnd.ms-excel', 'application/msexcel', 'application/x-msexcel', 'application/x-ms-excel', 'application/x-excel', 'application/x-dos_ms_excel', 'application/xls', 'application/x-xls', 'application/excel', 'application/download', 'application/vnd.ms-office', 'application/msword'),
+	'ppt'	=>	array('application/powerpoint', 'application/vnd.ms-powerpoint', 'application/vnd.ms-office', 'application/msword'),
+	'pptx'	=> 	array('application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/x-zip', 'application/zip'),
+	'wbxml'	=>	'application/wbxml',
+	'wmlc'	=>	'application/wmlc',
+	'dcr'	=>	'application/x-director',
+	'dir'	=>	'application/x-director',
+	'dxr'	=>	'application/x-director',
+	'dvi'	=>	'application/x-dvi',
+	'gtar'	=>	'application/x-gtar',
+	'gz'	=>	'application/x-gzip',
+	'gzip'  =>	'application/x-gzip',
+	'php'	=>	array('application/x-httpd-php', 'application/php', 'application/x-php', 'text/php', 'text/x-php', 'application/x-httpd-php-source'),
+	'php4'	=>	'application/x-httpd-php',
+	'php3'	=>	'application/x-httpd-php',
+	'phtml'	=>	'application/x-httpd-php',
+	'phps'	=>	'application/x-httpd-php-source',
+	'js'	=>	array('application/x-javascript', 'text/plain'),
+	'swf'	=>	'application/x-shockwave-flash',
+	'sit'	=>	'application/x-stuffit',
+	'tar'	=>	'application/x-tar',
+	'tgz'	=>	array('application/x-tar', 'application/x-gzip-compressed'),
+	'z'	=>	'application/x-compress',
+	'xhtml'	=>	'application/xhtml+xml',
+	'xht'	=>	'application/xhtml+xml',
+	'zip'	=>	array('application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/s-compressed', 'multipart/x-zip'),
+	'rar'	=>	array('application/x-rar', 'application/rar', 'application/x-rar-compressed'),
+	'mid'	=>	'audio/midi',
+	'midi'	=>	'audio/midi',
+	'mpga'	=>	'audio/mpeg',
+	'mp2'	=>	'audio/mpeg',
+	'mp3'	=>	array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'),
+	'aif'	=>	array('audio/x-aiff', 'audio/aiff'),
+	'aiff'	=>	array('audio/x-aiff', 'audio/aiff'),
+	'aifc'	=>	'audio/x-aiff',
+	'ram'	=>	'audio/x-pn-realaudio',
+	'rm'	=>	'audio/x-pn-realaudio',
+	'rpm'	=>	'audio/x-pn-realaudio-plugin',
+	'ra'	=>	'audio/x-realaudio',
+	'rv'	=>	'video/vnd.rn-realvideo',
+	'wav'	=>	array('audio/x-wav', 'audio/wave', 'audio/wav'),
+	'bmp'	=>	array('image/bmp', 'image/x-bmp', 'image/x-bitmap', 'image/x-xbitmap', 'image/x-win-bitmap', 'image/x-windows-bmp', 'image/ms-bmp', 'image/x-ms-bmp', 'application/bmp', 'application/x-bmp', 'application/x-win-bitmap'),
+	'gif'	=>	'image/gif',
+	'jpeg'	=>	array('image/jpeg', 'image/pjpeg'),
+	'jpg'	=>	array('image/jpeg', 'image/pjpeg'),
+	'jpe'	=>	array('image/jpeg', 'image/pjpeg'),
+	'jp2'	=>	array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+	'j2k'	=>	array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+	'jpf'	=>	array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+	'jpg2'	=>	array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+	'jpx'	=>	array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+	'jpm'	=>	array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+	'mj2'	=>	array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+	'mjp2'	=>	array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+	'png'	=>	array('image/png',  'image/x-png'),
+	'tiff'	=>	'image/tiff',
+	'tif'	=>	'image/tiff',
+	'css'	=>	array('text/css', 'text/plain'),
+	'html'	=>	array('text/html', 'text/plain'),
+	'htm'	=>	array('text/html', 'text/plain'),
+	'shtml'	=>	array('text/html', 'text/plain'),
+	'txt'	=>	'text/plain',
+	'text'	=>	'text/plain',
+	'log'	=>	array('text/plain', 'text/x-log'),
+	'rtx'	=>	'text/richtext',
+	'rtf'	=>	'text/rtf',
+	'xml'	=>	array('application/xml', 'text/xml', 'text/plain'),
+	'xsl'	=>	array('application/xml', 'text/xsl', 'text/xml'),
+	'mpeg'	=>	'video/mpeg',
+	'mpg'	=>	'video/mpeg',
+	'mpe'	=>	'video/mpeg',
+	'qt'	=>	'video/quicktime',
+	'mov'	=>	'video/quicktime',
+	'avi'	=>	array('video/x-msvideo', 'video/msvideo', 'video/avi', 'application/x-troff-msvideo'),
+	'movie'	=>	'video/x-sgi-movie',
+	'doc'	=>	array('application/msword', 'application/vnd.ms-office'),
+	'docx'	=>	array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword', 'application/x-zip'),
+	'dot'	=>	array('application/msword', 'application/vnd.ms-office'),
+	'dotx'	=>	array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword'),
+	'xlsx'	=>	array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip', 'application/vnd.ms-excel', 'application/msword', 'application/x-zip'),
+	'word'	=>	array('application/msword', 'application/octet-stream'),
+	'xl'	=>	'application/excel',
+	'eml'	=>	'message/rfc822',
+	'json'  =>	array('application/json', 'text/json'),
+	'pem'   =>	array('application/x-x509-user-cert', 'application/x-pem-file', 'application/octet-stream'),
+	'p10'   =>	array('application/x-pkcs10', 'application/pkcs10'),
+	'p12'   =>	'application/x-pkcs12',
+	'p7a'   =>	'application/x-pkcs7-signature',
+	'p7c'   =>	array('application/pkcs7-mime', 'application/x-pkcs7-mime'),
+	'p7m'   =>	array('application/pkcs7-mime', 'application/x-pkcs7-mime'),
+	'p7r'   =>	'application/x-pkcs7-certreqresp',
+	'p7s'   =>	'application/pkcs7-signature',
+	'crt'   =>	array('application/x-x509-ca-cert', 'application/x-x509-user-cert', 'application/pkix-cert'),
+	'crl'   =>	array('application/pkix-crl', 'application/pkcs-crl'),
+	'der'   =>	'application/x-x509-ca-cert',
+	'kdb'   =>	'application/octet-stream',
+	'pgp'   =>	'application/pgp',
+	'gpg'   =>	'application/gpg-keys',
+	'sst'   =>	'application/octet-stream',
+	'csr'   =>	'application/octet-stream',
+	'rsa'   =>	'application/x-pkcs7',
+	'cer'   =>	array('application/pkix-cert', 'application/x-x509-ca-cert'),
+	'3g2'   =>	'video/3gpp2',
+	'3gp'   =>	array('video/3gp', 'video/3gpp'),
+	'mp4'   =>	'video/mp4',
+	'm4a'   =>	'audio/x-m4a',
+	'f4v'   =>	array('video/mp4', 'video/x-f4v'),
+	'flv'	=>	'video/x-flv',
+	'webm'	=>	'video/webm',
+	'aac'   =>	'audio/x-acc',
+	'm4u'   =>	'application/vnd.mpegurl',
+	'm3u'   =>	'text/plain',
+	'xspf'  =>	'application/xspf+xml',
+	'vlc'   =>	'application/videolan',
+	'wmv'   =>	array('video/x-ms-wmv', 'video/x-ms-asf'),
+	'au'    =>	'audio/x-au',
+	'ac3'   =>	'audio/ac3',
+	'flac'  =>	'audio/x-flac',
+	'ogg'   =>	array('audio/ogg', 'video/ogg', 'application/ogg'),
+	'kmz'	=>	array('application/vnd.google-earth.kmz', 'application/zip', 'application/x-zip'),
+	'kml'	=>	array('application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml'),
+	'ics'	=>	'text/calendar',
+	'ical'	=>	'text/calendar',
+	'zsh'	=>	'text/x-scriptzsh',
+	'7zip'	=>	array('application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'),
+	'cdr'	=>	array('application/cdr', 'application/coreldraw', 'application/x-cdr', 'application/x-coreldraw', 'image/cdr', 'image/x-cdr', 'zz-application/zz-winassoc-cdr'),
+	'wma'	=>	array('audio/x-ms-wma', 'video/x-ms-asf'),
+	'jar'	=>	array('application/java-archive', 'application/x-java-application', 'application/x-jar', 'application/x-compressed'),
+	'svg'	=>	array('image/svg+xml', 'application/xml', 'text/xml'),
+	'vcf'	=>	'text/x-vcard',
+	'srt'	=>	array('text/srt', 'text/plain'),
+	'vtt'	=>	array('text/vtt', 'text/plain'),
+	'ico'	=>	array('image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon'),
+	'odc'	=>	'application/vnd.oasis.opendocument.chart',
+	'otc'	=>	'application/vnd.oasis.opendocument.chart-template',
+	'odf'	=>	'application/vnd.oasis.opendocument.formula',
+	'otf'	=>	'application/vnd.oasis.opendocument.formula-template',
+	'odg'	=>	'application/vnd.oasis.opendocument.graphics',
+	'otg'	=>	'application/vnd.oasis.opendocument.graphics-template',
+	'odi'	=>	'application/vnd.oasis.opendocument.image',
+	'oti'	=>	'application/vnd.oasis.opendocument.image-template',
+	'odp'	=>	'application/vnd.oasis.opendocument.presentation',
+	'otp'	=>	'application/vnd.oasis.opendocument.presentation-template',
+	'ods'	=>	'application/vnd.oasis.opendocument.spreadsheet',
+	'ots'	=>	'application/vnd.oasis.opendocument.spreadsheet-template',
+	'odt'	=>	'application/vnd.oasis.opendocument.text',
+	'odm'	=>	'application/vnd.oasis.opendocument.text-master',
+	'ott'	=>	'application/vnd.oasis.opendocument.text-template',
+	'oth'	=>	'application/vnd.oasis.opendocument.text-web'
+);

+ 39 - 0
application/config/mongo_db.php

@@ -0,0 +1,39 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/*
+| -------------------------------------------------------------------------
+| DATABASE CONNECTIVITY SETTINGS
+| -------------------------------------------------------------------------
+| This file will contain the settings needed to access your Mongo database.
+|
+|
+| ------------------------------------------------------------------------
+| EXPLANATION OF VARIABLES
+| ------------------------------------------------------------------------
+|
+|	['hostname'] The hostname of your database server.
+|	['username'] The username used to connect to the database
+|	['password'] The password used to connect to the database
+|	['database'] The name of the database you want to connect to
+|	['db_debug'] TRUE/FALSE - Whether database errors should be displayed.
+|	['write_concerns'] Default is 1: acknowledge write operations.  ref(http://php.net/manual/en/mongo.writeconcerns.php)
+|	['journal'] Default is TRUE : journal flushed to disk. ref(http://php.net/manual/en/mongo.writeconcerns.php)
+|	['read_preference'] Set the read preference for this connection. ref (http://php.net/manual/en/mongoclient.setreadpreference.php)
+|	['read_preference_tags'] Set the read preference for this connection.  ref (http://php.net/manual/en/mongoclient.setreadpreference.php)
+|
+| The $config['mongo_db']['active'] variable lets you choose which connection group to
+| make active.  By default there is only one group (the 'default' group).
+|
+*/
+
+$config['mongo_db']['active'] = 'default';
+
+$config['mongo_db']['default']['no_auth'] = TRUE;
+$config['mongo_db']['default']['hostname'] = '127.0.0.1';
+$config['mongo_db']['default']['port'] = '27017';
+$config['mongo_db']['default']['username'] = 'admin';
+$config['mongo_db']['default']['password'] = 'abc123';
+$config['mongo_db']['default']['database'] = 'workorder';
+$config['mongo_db']['default']['db_debug'] = TRUE;
+
+/* End of file database.php */
+/* Location: ./application/config/database.php */

+ 14 - 0
application/config/profiler.php

@@ -0,0 +1,14 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------------
+| Profiler Sections
+| -------------------------------------------------------------------------
+| This file lets you determine whether or not various sections of Profiler
+| data are displayed when the Profiler is enabled.
+| Please see the user guide for info:
+|
+|	https://codeigniter.com/user_guide/general/profiling.html
+|
+*/

+ 606 - 0
application/config/rest.php

@@ -0,0 +1,606 @@
+<?php
+
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+|--------------------------------------------------------------------------
+| HTTP protocol
+|--------------------------------------------------------------------------
+|
+| Set to force the use of HTTPS for REST API calls
+|
+*/
+$config['force_https'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| REST Output Format
+|--------------------------------------------------------------------------
+|
+| The default format of the response
+|
+| 'array':      Array data structure
+| 'csv':        Comma separated file
+| 'json':       Uses json_encode(). Note: If a GET query string
+|               called 'callback' is passed, then jsonp will be returned
+| 'html'        HTML using the table library in CodeIgniter
+| 'php':        Uses var_export()
+| 'serialized':  Uses serialize()
+| 'xml':        Uses simplexml_load_string()
+|
+*/
+$config['rest_default_format'] = 'json';
+
+/*
+|--------------------------------------------------------------------------
+| REST Supported Output Formats
+|--------------------------------------------------------------------------
+|
+| The following setting contains a list of the supported/allowed formats.
+| You may remove those formats that you don't want to use.
+| If the default format $config['rest_default_format'] is missing within
+| $config['rest_supported_formats'], it will be added silently during
+| REST_Controller initialization.
+|
+*/
+$config['rest_supported_formats'] = [
+    'json',
+    'array',
+    'csv',
+    'html',
+    'jsonp',
+    'php',
+    'serialized',
+    'xml',
+];
+
+/*
+|--------------------------------------------------------------------------
+| REST Status Field Name
+|--------------------------------------------------------------------------
+|
+| The field name for the status inside the response
+|
+*/
+$config['rest_status_field_name'] = 'status';
+
+/*
+|--------------------------------------------------------------------------
+| REST Message Field Name
+|--------------------------------------------------------------------------
+|
+| The field name for the message inside the response
+|
+*/
+$config['rest_message_field_name'] = 'error';
+
+/*
+|--------------------------------------------------------------------------
+| Enable Emulate Request
+|--------------------------------------------------------------------------
+|
+| Should we enable emulation of the request (e.g. used in Mootools request)
+|
+*/
+$config['enable_emulate_request'] = TRUE;
+
+/*
+|--------------------------------------------------------------------------
+| REST Realm
+|--------------------------------------------------------------------------
+|
+| Name of the password protected REST API displayed on login dialogs
+|
+| e.g: My Secret REST API
+|
+*/
+$config['rest_realm'] = 'REST API';
+
+/*
+|--------------------------------------------------------------------------
+| REST Login
+|--------------------------------------------------------------------------
+|
+| Set to specify the REST API requires to be logged in
+|
+| FALSE     No login required
+| 'basic'   Unsecured login
+| 'digest'  More secured login
+| 'session' Check for a PHP session variable. See 'auth_source' to set the
+|           authorization key
+|
+*/
+$config['rest_auth'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| REST Login Source
+|--------------------------------------------------------------------------
+|
+| Is login required and if so, the user store to use
+|
+| ''        Use config based users or wildcard testing
+| 'ldap'    Use LDAP authentication
+| 'library' Use a authentication library
+|
+| Note: If 'rest_auth' is set to 'session' then change 'auth_source' to the name of the session variable
+|
+*/
+$config['auth_source'] = 'ldap';
+
+/*
+|--------------------------------------------------------------------------
+| Allow Authentication and API Keys
+|--------------------------------------------------------------------------
+|
+| Where you wish to have Basic, Digest or Session login, but also want to use API Keys (for limiting
+| requests etc), set to TRUE;
+|
+*/
+$config['allow_auth_and_keys'] = TRUE;
+$config['strict_api_and_auth'] = TRUE; // force the use of both api and auth before a valid api request is made
+
+/*
+|--------------------------------------------------------------------------
+| REST Login Class and Function
+|--------------------------------------------------------------------------
+|
+| If library authentication is used define the class and function name
+|
+| The function should accept two parameters: class->function($username, $password)
+| In other cases override the function _perform_library_auth in your controller
+|
+| For digest authentication the library function should return already a stored
+| md5(username:restrealm:password) for that username
+|
+| e.g: md5('admin:REST API:1234') = '1e957ebc35631ab22d5bd6526bd14ea2'
+|
+*/
+$config['auth_library_class'] = '';
+$config['auth_library_function'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Override auth types for specific class/method
+|--------------------------------------------------------------------------
+|
+| Set specific authentication types for methods within a class (controller)
+|
+| Set as many config entries as needed.  Any methods not set will use the default 'rest_auth' config value.
+|
+| e.g:
+|
+|           $config['auth_override_class_method']['deals']['view'] = 'none';
+|           $config['auth_override_class_method']['deals']['insert'] = 'digest';
+|           $config['auth_override_class_method']['accounts']['user'] = 'basic';
+|           $config['auth_override_class_method']['dashboard']['*'] = 'none|digest|basic';
+|
+| Here 'deals', 'accounts' and 'dashboard' are controller names, 'view', 'insert' and 'user' are methods within. An asterisk may also be used to specify an authentication method for an entire classes methods. Ex: $config['auth_override_class_method']['dashboard']['*'] = 'basic'; (NOTE: leave off the '_get' or '_post' from the end of the method name)
+| Acceptable values are; 'none', 'digest' and 'basic'.
+|
+*/
+// $config['auth_override_class_method']['deals']['view'] = 'none';
+// $config['auth_override_class_method']['deals']['insert'] = 'digest';
+// $config['auth_override_class_method']['accounts']['user'] = 'basic';
+// $config['auth_override_class_method']['dashboard']['*'] = 'basic';
+
+
+// ---Uncomment list line for the wildard unit test
+// $config['auth_override_class_method']['wildcard_test_cases']['*'] = 'basic';
+
+/*
+|--------------------------------------------------------------------------
+| Override auth types for specific 'class/method/HTTP method'
+|--------------------------------------------------------------------------
+|
+| example:
+|
+|            $config['auth_override_class_method_http']['deals']['view']['get'] = 'none';
+|            $config['auth_override_class_method_http']['deals']['insert']['post'] = 'none';
+|            $config['auth_override_class_method_http']['deals']['*']['options'] = 'none';
+*/
+
+// ---Uncomment list line for the wildard unit test
+// $config['auth_override_class_method_http']['wildcard_test_cases']['*']['options'] = 'basic';
+
+/*
+|--------------------------------------------------------------------------
+| REST Login Usernames
+|--------------------------------------------------------------------------
+|
+| Array of usernames and passwords for login, if ldap is configured this is ignored
+|
+*/
+$config['rest_valid_logins'] = ['admin' => '1234'];
+
+/*
+|--------------------------------------------------------------------------
+| Global IP White-listing
+|--------------------------------------------------------------------------
+|
+| 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 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'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| REST Handle Exceptions
+|--------------------------------------------------------------------------
+|
+| Handle exceptions caused by the controller
+|
+*/
+$config['rest_handle_exceptions'] = TRUE;
+
+/*
+|--------------------------------------------------------------------------
+| REST IP White-list
+|--------------------------------------------------------------------------
+|
+| Limit connections to your REST server with a comma separated
+| list of IP addresses
+|
+| e.g: '123.456.789.0, 987.654.32.1'
+|
+| 127.0.0.1 and 0.0.0.0 are allowed by default
+|
+*/
+$config['rest_ip_whitelist'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| 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
+|--------------------------------------------------------------------------
+|
+| The table name in your database that stores API keys
+|
+*/
+$config['rest_keys_table'] = 'keys';
+
+/*
+|--------------------------------------------------------------------------
+| REST Enable Keys
+|--------------------------------------------------------------------------
+|
+| When set to TRUE, the REST API will look for a column name called 'key'.
+| If no key is provided, the request will result in an error. To override the
+| column name see 'rest_key_column'
+|
+| 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',
+|       `is_private_key` TINYINT(1)  NOT NULL DEFAULT '0',
+|       `ip_addresses` TEXT NULL DEFAULT NULL,
+|       `date_created` INT(11) NOT NULL,
+|       PRIMARY KEY (`id`)
+|   ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+|
+*/
+$config['rest_enable_keys'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| 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'] = 'IP_ADDRESS'; // Put a limit per ip address
+| $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
+|--------------------------------------------------------------------------
+|
+| Custom header to specify the API key
+
+| Note: Custom headers with the X- prefix are deprecated as of
+| 2012/06/12. See RFC 6648 specification for more details
+|
+*/
+$config['rest_key_name'] = 'X-API-KEY';
+
+/*
+|--------------------------------------------------------------------------
+| REST Enable Logging
+|--------------------------------------------------------------------------
+|
+| 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;
+|
+*/
+$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 '',
+|       `all_access` TINYINT(1) NOT NULL DEFAULT '0',
+|       `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';
+
+/*
+|--------------------------------------------------------------------------
+| CORS Check
+|--------------------------------------------------------------------------
+|
+| Set to TRUE to enable Cross-Origin Resource Sharing (CORS). Useful if you
+| are hosting your API on a different domain from the application that
+| will access it through a browser
+|
+*/
+$config['check_cors'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| CORS Allowable Headers
+|--------------------------------------------------------------------------
+|
+| If using CORS checks, set the allowable headers here
+|
+*/
+$config['allowed_cors_headers'] = [
+  'Origin',
+  'X-Requested-With',
+  'Content-Type',
+  'Accept',
+  'Access-Control-Request-Method'
+];
+
+/*
+|--------------------------------------------------------------------------
+| CORS Allowable Methods
+|--------------------------------------------------------------------------
+|
+| If using CORS checks, you can set the methods you want to be allowed
+|
+*/
+$config['allowed_cors_methods'] = [
+  'GET',
+  'POST',
+  'OPTIONS',
+  'PUT',
+  'PATCH',
+  'DELETE'
+];
+
+/*
+|--------------------------------------------------------------------------
+| CORS Allow Any Domain
+|--------------------------------------------------------------------------
+|
+| Set to TRUE to enable Cross-Origin Resource Sharing (CORS) from any
+| source domain
+|
+*/
+$config['allow_any_cors_domain'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| CORS Allowable Domains
+|--------------------------------------------------------------------------
+|
+| Used if $config['check_cors'] is set to TRUE and $config['allow_any_cors_domain']
+| is set to FALSE. Set all the allowable domains within the array
+|
+| e.g. $config['allowed_origins'] = ['http://www.example.com', 'https://spa.example.com']
+|
+*/
+$config['allowed_cors_origins'] = [];

+ 72 - 0
application/config/routes.php

@@ -0,0 +1,72 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------------
+| URI ROUTING
+| -------------------------------------------------------------------------
+| This file lets you re-map URI requests to specific controller functions.
+|
+| Typically there is a one-to-one relationship between a URL string
+| and its corresponding controller class/method. The segments in a
+| URL normally follow this pattern:
+|
+|	example.com/class/method/id/
+|
+| In some instances, however, you may want to remap this relationship
+| so that a different class/function is called than the one
+| corresponding to the URL.
+|
+| Please see the user guide for complete details:
+|
+|	https://codeigniter.com/user_guide/general/routing.html
+|
+| -------------------------------------------------------------------------
+| RESERVED ROUTES
+| -------------------------------------------------------------------------
+|
+| There are three reserved routes:
+|
+|	$route['default_controller'] = 'welcome';
+|
+| This route indicates which controller class should be loaded if the
+| URI contains no data. In the above example, the "welcome" class
+| would be loaded.
+|
+|	$route['404_override'] = 'errors/page_missing';
+|
+| This route will tell the Router which controller/method to use if those
+| provided in the URL cannot be matched to a valid route.
+|
+|	$route['translate_uri_dashes'] = FALSE;
+|
+| This is not exactly a route, but allows you to automatically route
+| controller and method names that contain dashes. '-' isn't a valid
+| class or method name character, so it requires translation.
+| When you set this option to TRUE, it will replace ALL dashes in the
+| controller and method URI segments.
+|
+| Examples:	my-controller/index	-> my_controller/index
+|		my-controller/my-method	-> my_controller/my_method
+*/
+$route['default_controller'] = 'index/login';
+$route['404_override'] = '';
+$route['translate_uri_dashes'] = TRUE;
+
+$route['login'] = 'index/login';
+$route['checklogin'] = 'index/check_login';
+$route['logout'] = 'index/logout';
+$route['user/view/(:any)'] = 'user/view/$1';
+$route['user/delete/(:any)'] = 'user/delete/$1';
+$route['user/changepassword/(:any)'] = 'user/change_password/$1';
+$route['user/deleteall'] = 'user/delete_all';
+$route['user/disableall'] = 'user/disable_all';
+$route['user/enableall'] = 'user/enable_all';
+$route['user/validate/(:any)'] = 'user/validate/$1';
+$route['warning/index/'] = 'warning/index';
+$route['warning/ignore/(:any)'] = 'warning/ignore/$1';
+$route['workorder/create'] = 'workorder/create';
+$route['setting/setting'] = 'setting/setting';
+$route['appauth/view/(:any)'] = 'appauth/view/$1';
+$route['appauth/enableall'] = 'appauth/enable_all';
+$route['appauth/disableall'] = 'appauth/disable_all';

+ 14 - 0
application/config/smarty.php

@@ -0,0 +1,14 @@
+<?php
+if (!defined('BASEPATH')) {
+    exit('No direct script access allowed');
+}
+$config['cache_lifetime'] = 60;
+$config['caching'] = false;
+$config['template_dir'] = APPPATH . 'views/templates';
+$config['compile_dir'] = APPPATH . 'views/templates_c';
+$config['cache_dir'] = APPPATH . 'views/cache';
+$config['config_dir'] = APPPATH . 'views/config';
+$config['use_sub_dirs'] = false;
+//子目录变量(是否在缓存文件夹中生成子目录)
+$config['left_delimiter'] = '{';
+$config['right_delimiter'] = '}';

+ 64 - 0
application/config/smileys.php

@@ -0,0 +1,64 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------
+| SMILEYS
+| -------------------------------------------------------------------
+| This file contains an array of smileys for use with the emoticon helper.
+| Individual images can be used to replace multiple smileys.  For example:
+| :-) and :) use the same image replacement.
+|
+| Please see user guide for more info:
+| https://codeigniter.com/user_guide/helpers/smiley_helper.html
+|
+*/
+$smileys = array(
+
+//	smiley			image name						width	height	alt
+
+	':-)'			=>	array('grin.gif',			'19',	'19',	'grin'),
+	':lol:'			=>	array('lol.gif',			'19',	'19',	'LOL'),
+	':cheese:'		=>	array('cheese.gif',			'19',	'19',	'cheese'),
+	':)'			=>	array('smile.gif',			'19',	'19',	'smile'),
+	';-)'			=>	array('wink.gif',			'19',	'19',	'wink'),
+	';)'			=>	array('wink.gif',			'19',	'19',	'wink'),
+	':smirk:'		=>	array('smirk.gif',			'19',	'19',	'smirk'),
+	':roll:'		=>	array('rolleyes.gif',		'19',	'19',	'rolleyes'),
+	':-S'			=>	array('confused.gif',		'19',	'19',	'confused'),
+	':wow:'			=>	array('surprise.gif',		'19',	'19',	'surprised'),
+	':bug:'			=>	array('bigsurprise.gif',	'19',	'19',	'big surprise'),
+	':-P'			=>	array('tongue_laugh.gif',	'19',	'19',	'tongue laugh'),
+	'%-P'			=>	array('tongue_rolleye.gif',	'19',	'19',	'tongue rolleye'),
+	';-P'			=>	array('tongue_wink.gif',	'19',	'19',	'tongue wink'),
+	':P'			=>	array('raspberry.gif',		'19',	'19',	'raspberry'),
+	':blank:'		=>	array('blank.gif',			'19',	'19',	'blank stare'),
+	':long:'		=>	array('longface.gif',		'19',	'19',	'long face'),
+	':ohh:'			=>	array('ohh.gif',			'19',	'19',	'ohh'),
+	':grrr:'		=>	array('grrr.gif',			'19',	'19',	'grrr'),
+	':gulp:'		=>	array('gulp.gif',			'19',	'19',	'gulp'),
+	'8-/'			=>	array('ohoh.gif',			'19',	'19',	'oh oh'),
+	':down:'		=>	array('downer.gif',			'19',	'19',	'downer'),
+	':red:'			=>	array('embarrassed.gif',	'19',	'19',	'red face'),
+	':sick:'		=>	array('sick.gif',			'19',	'19',	'sick'),
+	':shut:'		=>	array('shuteye.gif',		'19',	'19',	'shut eye'),
+	':-/'			=>	array('hmm.gif',			'19',	'19',	'hmmm'),
+	'>:('			=>	array('mad.gif',			'19',	'19',	'mad'),
+	':mad:'			=>	array('mad.gif',			'19',	'19',	'mad'),
+	'>:-('			=>	array('angry.gif',			'19',	'19',	'angry'),
+	':angry:'		=>	array('angry.gif',			'19',	'19',	'angry'),
+	':zip:'			=>	array('zip.gif',			'19',	'19',	'zipper'),
+	':kiss:'		=>	array('kiss.gif',			'19',	'19',	'kiss'),
+	':ahhh:'		=>	array('shock.gif',			'19',	'19',	'shock'),
+	':coolsmile:'	=>	array('shade_smile.gif',	'19',	'19',	'cool smile'),
+	':coolsmirk:'	=>	array('shade_smirk.gif',	'19',	'19',	'cool smirk'),
+	':coolgrin:'	=>	array('shade_grin.gif',		'19',	'19',	'cool grin'),
+	':coolhmm:'		=>	array('shade_hmm.gif',		'19',	'19',	'cool hmm'),
+	':coolmad:'		=>	array('shade_mad.gif',		'19',	'19',	'cool mad'),
+	':coolcheese:'	=>	array('shade_cheese.gif',	'19',	'19',	'cool cheese'),
+	':vampire:'		=>	array('vampire.gif',		'19',	'19',	'vampire'),
+	':snake:'		=>	array('snake.gif',			'19',	'19',	'snake'),
+	':exclaim:'		=>	array('exclaim.gif',		'19',	'19',	'exclaim'),
+	':question:'	=>	array('question.gif',		'19',	'19',	'question')
+
+);

+ 214 - 0
application/config/user_agents.php

@@ -0,0 +1,214 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------
+| USER AGENT TYPES
+| -------------------------------------------------------------------
+| This file contains four arrays of user agent data. It is used by the
+| User Agent Class to help identify browser, platform, robot, and
+| mobile device data. The array keys are used to identify the device
+| and the array values are used to set the actual name of the item.
+*/
+$platforms = array(
+	'windows nt 10.0'	=> 'Windows 10',
+	'windows nt 6.3'	=> 'Windows 8.1',
+	'windows nt 6.2'	=> 'Windows 8',
+	'windows nt 6.1'	=> 'Windows 7',
+	'windows nt 6.0'	=> 'Windows Vista',
+	'windows nt 5.2'	=> 'Windows 2003',
+	'windows nt 5.1'	=> 'Windows XP',
+	'windows nt 5.0'	=> 'Windows 2000',
+	'windows nt 4.0'	=> 'Windows NT 4.0',
+	'winnt4.0'			=> 'Windows NT 4.0',
+	'winnt 4.0'			=> 'Windows NT',
+	'winnt'				=> 'Windows NT',
+	'windows 98'		=> 'Windows 98',
+	'win98'				=> 'Windows 98',
+	'windows 95'		=> 'Windows 95',
+	'win95'				=> 'Windows 95',
+	'windows phone'			=> 'Windows Phone',
+	'windows'			=> 'Unknown Windows OS',
+	'android'			=> 'Android',
+	'blackberry'		=> 'BlackBerry',
+	'iphone'			=> 'iOS',
+	'ipad'				=> 'iOS',
+	'ipod'				=> 'iOS',
+	'os x'				=> 'Mac OS X',
+	'ppc mac'			=> 'Power PC Mac',
+	'freebsd'			=> 'FreeBSD',
+	'ppc'				=> 'Macintosh',
+	'linux'				=> 'Linux',
+	'debian'			=> 'Debian',
+	'sunos'				=> 'Sun Solaris',
+	'beos'				=> 'BeOS',
+	'apachebench'		=> 'ApacheBench',
+	'aix'				=> 'AIX',
+	'irix'				=> 'Irix',
+	'osf'				=> 'DEC OSF',
+	'hp-ux'				=> 'HP-UX',
+	'netbsd'			=> 'NetBSD',
+	'bsdi'				=> 'BSDi',
+	'openbsd'			=> 'OpenBSD',
+	'gnu'				=> 'GNU/Linux',
+	'unix'				=> 'Unknown Unix OS',
+	'symbian' 			=> 'Symbian OS'
+);
+
+
+// The order of this array should NOT be changed. Many browsers return
+// multiple browser types so we want to identify the sub-type first.
+$browsers = array(
+	'OPR'			=> 'Opera',
+	'Flock'			=> 'Flock',
+	'Edge'			=> 'Spartan',
+	'Chrome'		=> 'Chrome',
+	// Opera 10+ always reports Opera/9.80 and appends Version/<real version> to the user agent string
+	'Opera.*?Version'	=> 'Opera',
+	'Opera'			=> 'Opera',
+	'MSIE'			=> 'Internet Explorer',
+	'Internet Explorer'	=> 'Internet Explorer',
+	'Trident.* rv'	=> 'Internet Explorer',
+	'Shiira'		=> 'Shiira',
+	'Firefox'		=> 'Firefox',
+	'Chimera'		=> 'Chimera',
+	'Phoenix'		=> 'Phoenix',
+	'Firebird'		=> 'Firebird',
+	'Camino'		=> 'Camino',
+	'Netscape'		=> 'Netscape',
+	'OmniWeb'		=> 'OmniWeb',
+	'Safari'		=> 'Safari',
+	'Mozilla'		=> 'Mozilla',
+	'Konqueror'		=> 'Konqueror',
+	'icab'			=> 'iCab',
+	'Lynx'			=> 'Lynx',
+	'Links'			=> 'Links',
+	'hotjava'		=> 'HotJava',
+	'amaya'			=> 'Amaya',
+	'IBrowse'		=> 'IBrowse',
+	'Maxthon'		=> 'Maxthon',
+	'Ubuntu'		=> 'Ubuntu Web Browser'
+);
+
+$mobiles = array(
+	// legacy array, old values commented out
+	'mobileexplorer'	=> 'Mobile Explorer',
+//  'openwave'			=> 'Open Wave',
+//	'opera mini'		=> 'Opera Mini',
+//	'operamini'			=> 'Opera Mini',
+//	'elaine'			=> 'Palm',
+	'palmsource'		=> 'Palm',
+//	'digital paths'		=> 'Palm',
+//	'avantgo'			=> 'Avantgo',
+//	'xiino'				=> 'Xiino',
+	'palmscape'			=> 'Palmscape',
+//	'nokia'				=> 'Nokia',
+//	'ericsson'			=> 'Ericsson',
+//	'blackberry'		=> 'BlackBerry',
+//	'motorola'			=> 'Motorola'
+
+	// Phones and Manufacturers
+	'motorola'		=> 'Motorola',
+	'nokia'			=> 'Nokia',
+	'palm'			=> 'Palm',
+	'iphone'		=> 'Apple iPhone',
+	'ipad'			=> 'iPad',
+	'ipod'			=> 'Apple iPod Touch',
+	'sony'			=> 'Sony Ericsson',
+	'ericsson'		=> 'Sony Ericsson',
+	'blackberry'	=> 'BlackBerry',
+	'cocoon'		=> 'O2 Cocoon',
+	'blazer'		=> 'Treo',
+	'lg'			=> 'LG',
+	'amoi'			=> 'Amoi',
+	'xda'			=> 'XDA',
+	'mda'			=> 'MDA',
+	'vario'			=> 'Vario',
+	'htc'			=> 'HTC',
+	'samsung'		=> 'Samsung',
+	'sharp'			=> 'Sharp',
+	'sie-'			=> 'Siemens',
+	'alcatel'		=> 'Alcatel',
+	'benq'			=> 'BenQ',
+	'ipaq'			=> 'HP iPaq',
+	'mot-'			=> 'Motorola',
+	'playstation portable'	=> 'PlayStation Portable',
+	'playstation 3'		=> 'PlayStation 3',
+	'playstation vita'  	=> 'PlayStation Vita',
+	'hiptop'		=> 'Danger Hiptop',
+	'nec-'			=> 'NEC',
+	'panasonic'		=> 'Panasonic',
+	'philips'		=> 'Philips',
+	'sagem'			=> 'Sagem',
+	'sanyo'			=> 'Sanyo',
+	'spv'			=> 'SPV',
+	'zte'			=> 'ZTE',
+	'sendo'			=> 'Sendo',
+	'nintendo dsi'	=> 'Nintendo DSi',
+	'nintendo ds'	=> 'Nintendo DS',
+	'nintendo 3ds'	=> 'Nintendo 3DS',
+	'wii'			=> 'Nintendo Wii',
+	'open web'		=> 'Open Web',
+	'openweb'		=> 'OpenWeb',
+
+	// Operating Systems
+	'android'		=> 'Android',
+	'symbian'		=> 'Symbian',
+	'SymbianOS'		=> 'SymbianOS',
+	'elaine'		=> 'Palm',
+	'series60'		=> 'Symbian S60',
+	'windows ce'	=> 'Windows CE',
+
+	// Browsers
+	'obigo'			=> 'Obigo',
+	'netfront'		=> 'Netfront Browser',
+	'openwave'		=> 'Openwave Browser',
+	'mobilexplorer'	=> 'Mobile Explorer',
+	'operamini'		=> 'Opera Mini',
+	'opera mini'	=> 'Opera Mini',
+	'opera mobi'	=> 'Opera Mobile',
+	'fennec'		=> 'Firefox Mobile',
+
+	// Other
+	'digital paths'	=> 'Digital Paths',
+	'avantgo'		=> 'AvantGo',
+	'xiino'			=> 'Xiino',
+	'novarra'		=> 'Novarra Transcoder',
+	'vodafone'		=> 'Vodafone',
+	'docomo'		=> 'NTT DoCoMo',
+	'o2'			=> 'O2',
+
+	// Fallback
+	'mobile'		=> 'Generic Mobile',
+	'wireless'		=> 'Generic Mobile',
+	'j2me'			=> 'Generic Mobile',
+	'midp'			=> 'Generic Mobile',
+	'cldc'			=> 'Generic Mobile',
+	'up.link'		=> 'Generic Mobile',
+	'up.browser'	=> 'Generic Mobile',
+	'smartphone'	=> 'Generic Mobile',
+	'cellphone'		=> 'Generic Mobile'
+);
+
+// There are hundreds of bots but these are the most common.
+$robots = array(
+	'googlebot'		=> 'Googlebot',
+	'msnbot'		=> 'MSNBot',
+	'baiduspider'		=> 'Baiduspider',
+	'bingbot'		=> 'Bing',
+	'slurp'			=> 'Inktomi Slurp',
+	'yahoo'			=> 'Yahoo',
+	'ask jeeves'		=> 'Ask Jeeves',
+	'fastcrawler'		=> 'FastCrawler',
+	'infoseek'		=> 'InfoSeek Robot 1.0',
+	'lycos'			=> 'Lycos',
+	'yandex'		=> 'YandexBot',
+	'mediapartners-google'	=> 'MediaPartners Google',
+	'CRAZYWEBCRAWLER'	=> 'Crazy Webcrawler',
+	'adsbot-google'		=> 'AdsBot Google',
+	'feedfetcher-google'	=> 'Feedfetcher Google',
+	'curious george'	=> 'Curious George',
+	'ia_archiver'		=> 'Alexa Crawler',
+	'MJ12bot'		=> 'Majestic-12',
+	'Uptimebot'		=> 'Uptimebot'
+);

+ 10 - 0
application/config/workorder.php

@@ -0,0 +1,10 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+$config['sys_name'] = '安全感知平台响应处置工单系统';
+$config['key_length'] = 40;
+$config['headers'] = array(
+    'Access-Control-Allow-Origin: *',
+    'Access-Control-Request-Method: GET, POST, PUT, DELETE, OPTIONS',
+    'Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization',
+);

+ 280 - 0
application/controllers/Appauth.php

@@ -0,0 +1,280 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/**
+ * Class 应用授权管理类
+ */
+class Appauth extends MY_Controller
+{
+    function __construct()
+    {
+        parent::__construct();
+        $this->load->model("appauth_model");
+        $this->load->library('MY_pagination');
+        $this->load->helper(array('url', 'form', 'date'));
+        $this->assign("appauth_status", $this->appauth_status);
+    }
+
+    /**
+     * 应用授权列表页
+     */
+    public function index()
+    {
+        $url = site_url("appauth/index?");
+        $wheres = array();
+        $order_info = array();
+        $keyword = $this->input->get("keyword", TRUE);
+        $status = $this->input->get("status", TRUE);
+        $order = $this->input->get("order", TRUE);
+        $page_num = $this->input->get("per_page", TRUE);
+        $page_size = $this->input->get("page_size", TRUE);
+        if ($keyword) {
+            $url .= "&keyword=" . $keyword;
+        }
+        if ($status) {
+            $wheres['status'] = $status;
+            $url .= "&status=" . $status;
+        }
+        if ($order) {
+            $orders = explode(" ", $order);
+            if (count($orders) == 2) {
+                $order_info[$orders[0]] = $orders[1];
+                $url .= "&order=" . $order;
+            }
+        }
+        if ($page_size) {
+            $this->page_size = $page_size;
+            $url .= "&page_size=" . $page_size;
+        }
+        $count = $this->appauth_model->count_appauth($keyword, $wheres);
+        $this->assign("count", $count);
+        $config = $this->page_config($count, $this->page_size, $url);
+        $this->my_pagination->initialize($config);
+        if ($page_num && $page_num > 1) {
+            $offset = (intval($page_num) - 1) * $this->page_size;
+        } else {
+            $offset = 0;
+        }
+        $appauth_list = $this->appauth_model->list_appauth($this->page_size, $offset, $keyword, $wheres, $order_info);
+        $this->assign("keyword", $keyword);
+        $this->assign("status", $status);
+        $this->assign("order", $order);
+        $this->assign("page_size", $this->page_size);
+        $this->assign("page", $this->my_pagination->create_pages());
+        $this->assign("appauth_list", $appauth_list);
+        $this->display("appauth/index.html");
+    }
+
+    /**
+     * 查看应用授权信息
+     * @param $app_id  APPID
+     */
+    public function view($app_id)
+    {
+        $message = "";
+        $appauth = $this->appauth_model->get_appauth_with_id($app_id);
+        if($appauth){
+            $this->assign("appauth",$appauth);
+        }else{
+            $this->assign("appauth",$this->appauth_model->get_model());
+            $message = "应用授权信息不存在或者已经被删除";
+        }
+        $this->assign("message",$message);
+        $this->display("appauth/view.html");
+    }
+
+    /**
+     * 增加应用授权
+     */
+    public function add()
+    {
+        $app_id = md5(uniqid(md5(microtime(true)), true));
+        $secret = md5(uniqid(md5(microtime(true)), true));
+        $this->assign("app_id", $app_id);
+        $this->assign("secret", $secret);
+        $this->display("appauth/add.html");
+    }
+
+    /**
+     * 保存应用授权信息
+     */
+    public function save()
+    {
+        $msg = array();
+        $data = array();
+        $msg['code'] = 1;
+        $msg['icon'] = 2;
+        $data['app_id'] = $app_id = $this->input->post("app_id", true);
+        $data['app_name'] = $app_name = $this->input->post("app_name", true);
+        $data['secret'] = $secret = $this->input->post("secret", true);
+        if (!$app_name) {
+            $msg['code'] = 0;
+            $msg['msg'] = "应用名称不能为空!";
+        } elseif ($this->appauth_model->is_exists("app_name", $app_name) && $msg['code']) {
+            $msg['code'] = 0;
+            $msg['msg'] = "应用名称已存在!";
+        }
+        if (!$app_id && $msg['code']) {
+            $msg['code'] = 0;
+            $msg['msg'] = "APPID不能为空!";
+        } elseif ($this->appauth_model->is_exists("app_id", $app_id) && $msg['code']) {
+            $msg['code'] = 0;
+            $msg['msg'] = "APPID已存在!请刷新后重试!";
+        }
+        if (!$secret && $msg['code']) {
+            $msg['code'] = 0;
+            $msg['msg'] = "SECRET不能为空!";
+        }
+        if ($msg['code']) {
+            $data['create_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+            $data['status'] = "10";
+            $this->appauth_model->insert_appauth($data);
+            $msg['icon'] = 1;
+            $msg['msg'] = "应用授权信息保存成功!";
+        }
+        $this->response($msg);
+    }
+
+    /**
+     * 更新应用授权信息
+     */
+    public function update()
+    {
+        $msg = array();
+        $data = array();
+        $msg['code'] = 1;
+        $msg['icon'] = 2;
+        $msg = array();
+        $data = array();
+        $msg['code'] = 1;
+        $msg['icon'] = 2;
+        $data['app_id']= $app_id = $this->input->post("app_id", true);
+        $old_appauth = $this->appauth_model->get_appauth_with_id($app_id);
+        $data['app_name'] = $app_name = $this->input->post("app_name", true);
+        $data['secret'] = $secret = $this->input->post("secret", true);
+        if (!$app_name) {
+            $msg['code'] = 0;
+            $msg['msg'] = "应用名称不能为空!";
+        } elseif ($this->appauth_model->is_exists("app_name", $app_name,$old_appauth['app_name']) && $msg['code']) {
+            $msg['code'] = 0;
+            $msg['msg'] = "应用名称已存在!";
+        }
+        if (!$secret && $msg['code']) {
+            $msg['code'] = 0;
+            $msg['msg'] = "SECRET不能为空!";
+        }
+        if ($msg['code']) {
+            $this->appauth_model->update_appauth($data);
+            $msg['icon'] = 1;
+            $msg['msg'] = "应用授权信息保存成功!";
+        }
+        $this->response($msg);
+    }
+
+    /**
+     * 删除应用授权
+     * @param $app_id
+     */
+    public function delete($app_id)
+    {
+        $data['icon'] = 1;
+        if ($app_id) {
+            $appauth = $this->appauth_model->get_appauth_with_id($app_id);
+            if ($appauth) {
+                $this->appauth_model->delete_appauth($app_id);
+                $data['msg'] = "应用授权信息删除成功!";
+            } else {
+                $data['icon'] = 2;
+                $data['msg'] = "应用授权信息不存在或者已经被删除!";
+            }
+        } else {
+            $data['icon'] = 2;
+            $data['msg'] = "参数错误请刷新后重试!";
+        }
+        $this->response($data);
+    }
+
+    /**
+     * 禁用应用授权
+     * @param $app_id
+     */
+    public function stopuse($app_id)
+    {
+        $data['icon'] = 1;
+        if ($app_id) {
+            $appauth = $this->appauth_model->get_appauth_with_id($app_id);
+            if ($appauth) {
+                $appauth['status'] = "40";
+                $this->appauth_model->update_appauth($appauth);
+                $data['msg'] = "应用授权信息停用成功!";
+            } else {
+                $data['icon'] = 2;
+                $data['msg'] = "应用授权信息不存在或者已经被删除!";
+            }
+        } else {
+            $data['icon'] = 2;
+            $data['msg'] = "参数错误请刷新后重试!";
+        }
+        $this->response($data);
+    }
+
+    /**
+     * 启用应用授权
+     * @param $app_id
+     */
+    public function restore($app_id)
+    {
+        $data['icon'] = 1;
+        if ($app_id) {
+            $appauth = $this->appauth_model->get_appauth_with_id($app_id);
+            if ($appauth) {
+                $appauth['status'] = "10";
+                $this->appauth_model->update_appauth($appauth);
+                $data['msg'] = "应用授权恢复成功!";
+            } else {
+                $data['icon'] = 2;
+                $data['msg'] = "应用授权信息不存在或者已经被删除!";
+            }
+        } else {
+            $data['icon'] = 2;
+            $data['msg'] = "参数错误请刷新后重试!";
+        }
+        $this->response($data);
+    }
+
+    /**
+     * 批量禁用应用授权
+     */
+    public function disable_all(){
+        $ids = rtrim($this->input->post("ids",true),",");
+        $ids = explode(",",$ids);
+        if(count($ids)<1){
+            $data['icon'] = 2;
+            $data['msg'] = "参数错误请刷新后重试!";
+        }else{
+            $wheres = array('app_id'=>array('$in'=>$ids));
+            $this->appauth_model->set_val("status",$wheres,"40");
+            $data['icon'] = 1;
+            $data['msg'] = "批量禁用应用授权成功!";
+        }
+        $this->response($data);
+    }
+
+    /**
+     * 批量启用应用授权
+     */
+    public function enable_all(){
+        $ids = rtrim($this->input->post("ids",true),",");
+        $ids = explode(",",$ids);
+        if(count($ids)<1){
+            $data['icon'] = 2;
+            $data['msg'] = "参数错误请刷新后重试!";
+        }else{
+            $wheres = array('app_id'=>array('$in'=>$ids));
+            $this->appauth_model->set_val("status",$wheres,"10");
+            $data['icon'] = 1;
+            $data['msg'] = "批量启用应用授权成功!";
+        }
+        $this->response($data);
+    }
+}

+ 74 - 0
application/controllers/Index.php

@@ -0,0 +1,74 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/**
+ * Class 登录类
+ */
+class Index extends Public_Controller {
+    function __construct(){
+			parent::__construct();
+			$this->load->helper(array('form','date'));
+			$this->load->model("user_model");
+    }
+
+    /**
+     * 登录页面
+     */
+    public function login(){
+        if($this->session->user_id){
+            redirect(base_url()."main/index");
+        }
+        $this->display("index/login.html");
+    }
+
+    /**
+     * 检查登录
+     */
+    public function check_login(){
+        if($this->input->post()){
+            $message = "";
+            $username = $this->input->post("username");
+            $password = $this->input->post("password");
+            if($username != "" && $password !="") {
+                $user = $this->user_model->get_user_with_username_password($username, hash_hmac('sha256',$password,$this->config->item('secret_key')));
+                if (count($user) >= 1) {
+                    if ($user[0]['status'] == "20") {
+                        $message = "该用户未验证,请验证后再登录!";
+                    } elseif ($user[0]['status'] == "30") {
+                        $message = "该用户已锁定,请联系管理员!";
+                    } elseif ($user[0]['status'] == "40") {
+                        $message = "该用户已停用,请联系管理员!";
+                    } else {
+                        $rand = substr(md5(microtime()), rand(0, 26), 5);
+                        $session_data = array("user_id" => (string)$user[0]["user_id"], "current_key" => $rand, "username" => $user[0]['username'], "user_type" => $user[0]['user_type']);
+                        $user[0]['last_login_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+                        $this->user_model->update_user($user[0]);
+                        $this->session->set_userdata($session_data);
+                    }
+                } else {
+                    $message = "用户名或密码错误,请重试!";
+                }
+            }else{
+                $message = "用户名或密码不能为空!";
+            }
+            if($message != "") {
+                $this->response(array("msg" => $message));
+            }else{
+                $this->response(array("url" => "main/index"));
+            }
+        } else{
+            $message = "参数错误,请重试!";
+            $this->response(array("msg"=>$message));
+        }
+    }
+
+    /**
+     * 登出
+     */
+    public function logout(){
+        if($this->session->user_id){
+            $this->session->unset_userdata(array("user_id","current_key","username","user_type"));
+        }
+        redirect("login");
+    }
+}

+ 14 - 0
application/controllers/Main.php

@@ -0,0 +1,14 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/**
+ * Class 主页面类
+ */
+class Main extends MY_Controller {
+    /**
+     * 显示主页面
+     */
+    public function index(){
+        $this->display("main.html");
+    }
+}

+ 351 - 0
application/controllers/Report.php

@@ -0,0 +1,351 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/**
+ * Class 统计报表类
+ */
+class Report extends MY_Controller
+{
+    function __construct()
+    {
+        parent::__construct();
+        $this->load->helper(array('form', 'date'));
+        $this->load->model("workorder_model");
+    }
+
+    /**
+     * 统计报表首页
+     */
+    public function index()
+    {
+        $sign = $this->input->get("sign", true);
+        $begin_date = $this->input->post("begin_date", true);
+        $end_date = $this->input->post("end_date", true);
+        $begin_time = " 0:0:0";
+        $end_time = " 23:59:59";
+        $now = new DateTime();
+        $end = $now->format("Y-m-d");
+        switch ($sign) {
+            case '1':
+                $title = "近7天";
+                $end_date_time = new DateTime($end . $end_time);
+                $end_datetime = new MongoDB\BSON\UTCDateTime($end_date_time->getTimestamp()*1000);
+                $now = new DateTime();
+                $now->modify("-6 day");
+                $begin = $now->format("Y-m-d");
+                $begin_date_time = new DateTime($begin . $begin_time);
+                $begin_datetime = new \MongoDB\BSON\UTCDateTime($begin_date_time->getTimestamp()*1000);
+                break;
+            case '2':
+                $title = "近30天";
+                $end_date_time = new DateTime($end . $end_time);
+                $end_datetime = new MongoDB\BSON\UTCDateTime($end_date_time->getTimestamp()*1000);
+                $now = new DateTime();
+                $now->modify("-30 day");
+                $begin = $now->format("Y-m-d");
+                $begin_date_time = new DateTime($begin . $begin_time);
+                $begin_datetime = new \MongoDB\BSON\UTCDateTime($begin_date_time->getTimestamp()*1000);
+                break;
+            case '3':
+                $title = "近三个月";
+                $end_date_time = new DateTime($end . $end_time);
+                $end_datetime = new MongoDB\BSON\UTCDateTime($end_date_time->getTimestamp()*1000);
+                $now = new DateTime();
+                $now->modify("-3 month");
+                $begin = $now->format("Y-m-d");
+                $begin_date_time = new DateTime($begin . $begin_time);
+                $begin_datetime = new \MongoDB\BSON\UTCDateTime($begin_date_time->getTimestamp()*1000);
+                break;
+            case '4':
+                $title = "近半年";
+                $end_date_time = new DateTime($end . $end_time);
+                $end_datetime = new MongoDB\BSON\UTCDateTime($end_date_time->getTimestamp()*1000);
+                $now = new DateTime();
+                $now->modify("-6 month");
+                $begin = $now->format("Y-m-d");
+                $begin_date_time = new DateTime($begin . $begin_time);
+                $begin_datetime = new \MongoDB\BSON\UTCDateTime($begin_date_time->getTimestamp()*1000);
+                break;
+            case '5':
+                $title = "近一年";
+                $end_date_time = new DateTime($end . $end_time);
+                $end_datetime = new MongoDB\BSON\UTCDateTime($end_date_time->getTimestamp()*1000);
+                $now = new DateTime();
+                $now->modify("-1 year");
+                $begin = $now->format("Y-m-d");
+                $begin_date_time = new DateTime($begin . $begin_time);
+                $begin_datetime = new \MongoDB\BSON\UTCDateTime($begin_date_time->getTimestamp()*1000);
+                break;
+            default:
+                $title = "近7天";
+                $end_date_time = new DateTime($end . $end_time);
+                $end_datetime = new MongoDB\BSON\UTCDateTime($end_date_time->getTimestamp()*1000);
+                $now = new DateTime();
+                $now->modify("-6 day");
+                $begin = $now->format("Y-m-d");
+                $begin_date_time = new DateTime($begin . $begin_time);
+                $begin_datetime = new \MongoDB\BSON\UTCDateTime($begin_date_time->getTimestamp()*1000);
+        }
+        if ($begin_date && $end_date) {
+            $title = "自" . $begin_date . "至" . $end_date;
+            $end_date_time = new DateTime($end_date . $end_time);
+            $begin_date_time = new DateTime($begin_date . $begin_time);
+            $end_datetime = new MongoDB\BSON\UTCDateTime($end_date_time->getTimestamp()*1000);
+            $begin_datetime = new \MongoDB\BSON\UTCDateTime($begin_date_time->getTimestamp()*1000);
+        }
+
+        /*图表1数据封装 各个状态的工单分布*/
+        $group1 = array(
+            "_id" => "\$status",
+            "value" => array("\$sum" => 1)
+        );
+        $result1 = $this->workorder_model->aggregate($begin_datetime, $end_datetime, $group1,NULL,array("status"=>array("\$ne"=>"60")));
+        $data1 = array();
+        if (is_array($result1) && count($result1) >= 1) {
+            foreach ($result1 as $key => $val) {
+                $data1[] = array(
+                    "name" => $this->workorder_status[$val['_id']],
+                    "value" => $val['value']
+                );
+            }
+        }
+
+        /*图表2数据封装 各分支工单总数*/
+        $group2 = array(
+            "_id" => "\$branch.branch_id",
+            "value" => array("\$sum" => 1)
+        );
+        $result2 = $this->workorder_model->aggregate($begin_datetime, $end_datetime, $group2,NULL,array("status"=>array("\$ne"=>"60")));
+        $data2x = array();
+        $data2y = array();
+        if (is_array($result2) && count($result2) >= 1) {
+            foreach ($this->branch_array as $key => $branch) {
+                $data2x[] = $branch['branch_name'];
+                $have_value = 0;
+                foreach ($result2 as $key => $val) {
+                    if ($val['_id'] == $branch['branch_id']) {
+                        $data2y[] = $val['value'];
+                        $have_value = 1;
+                    }
+                }
+                if (!$have_value) {
+                    $data2y[] = 0;
+                }
+            }
+        }
+
+        /*图表3数据封装 各分支工单状态数量*/
+        $group3 = array(
+            "_id" => array("branchs" => "\$branch.branch_id", "status" => "\$status"),
+            "value" => array("\$sum" => 1)
+        );
+        $result3 = $this->workorder_model->aggregate($begin_datetime, $end_datetime, $group3,NULL,array("status"=>array("\$ne"=>"60")));
+        $data3x = array();
+        $data3y = array();
+        $data3legend = array();
+        $i = 0;
+        foreach ($this->branch_array as $key => $branch) {
+            $data3x[] = $branch['branch_name'];
+        }
+        foreach ($this->workorder_status as $k => $status) {
+            if($k == "60") continue;
+            $data = array();
+            $data['name'] = $status;
+            $data['type'] = "bar";
+            $data['barGap'] = 0;
+            $data3y[] = $data;
+            $data3legend[] = $status;
+
+        }
+        $i = 0;
+        foreach ($this->workorder_status as $k => $status) {
+            if($k == "60") continue;
+            $value = array();
+            foreach ($this->branch_array as $key => $branch) {
+                $have_value = 0;
+                foreach ($result3 as $result) {
+                    if ($result['_id']['branchs'] == $branch['branch_id'] && $result['_id']['status'] == $k) {
+                        $value[] = $result['value'];
+                        $have_value = 1;
+                    }
+                }
+                if (!$have_value) {
+                    $value[] = 0;
+                }
+            }
+            $data3y[$i]['data'] = $value;
+            if ($i < count($data3y)) {
+                $i++;
+            }
+        }
+
+        $datediff = $end_date_time->diff($begin_date_time);
+        /*图表4数据封装 工单总数趋势图*/
+        $data4x = array();
+        $data4y = array();
+        if($sign==1 || $sign ==2 || ($datediff->m<3 && $datediff->y==0)) {
+            $start_date_time = new DateTime($begin_date_time->format("Y-m-d"));
+            for($i = 0;$i<=$datediff->d;$i++){
+                $data4x[] = $start_date_time->format("Y-m-d");
+                $start_date_time->modify("+1 day");
+            }
+            $group4 = array(
+                "_id" => array("\$dateToString" => array("format" => "%Y-%m-%d", "date" => array("\$add" => ["\$create_time", 28800000]))),
+                "value" => array("\$sum" => 1),
+            );
+        }else{
+            $start_date_time = new DateTime($begin_date_time->format("Y-m-d"));
+            if($datediff->y > 0){
+                $count = $datediff->y*12 + $datediff->m;
+            }else{
+                $count = $datediff->m;
+            }
+            for($i = 0;$i<$count;$i++){
+                $start_date_time->modify("+1 month");
+                $data4x[] = $start_date_time->format("Y-m");
+            }
+            $group4 = array(
+                "_id" => array("\$dateToString" => array("format" => "%Y-%m", "date" => array("\$add" => ["\$create_time", 28800000]))),
+                "value" => array("\$sum" => 1),
+            );
+        }
+        $result4 = $this->workorder_model->aggregate($begin_datetime, $end_datetime, $group4,NULL,array("status"=>array("\$ne"=>"60")),NULL,NULL,array("_id"=>"ASC"));
+        for ($i=0 ; $i<count($data4x) ; $i++){
+            $have_value = 0;
+            foreach ($result4 as $result) {
+                if($data4x[$i] == $result['_id']){
+                    $data4y[] = $result['value'];
+                    $have_value =1;
+                }
+            }
+            if(!$have_value){
+                $data4y[] = 0;
+            }
+
+        }
+
+        /*图表5数据封装 已处理工单总数趋势图*/
+        $data5x = array();
+        $data5y = array();
+        if($sign==1 || $sign ==2 || ($datediff->m<3 && $datediff->y==0)) {
+            $start_date_time = new DateTime($begin_date_time->format("Y-m-d"));
+            for($i = 0;$i<=$datediff->d;$i++){
+                $data5x[] = $start_date_time->format("Y-m-d");
+                $start_date_time->modify("+1 day");
+            }
+            $group5 = array(
+                "_id" => array("\$dateToString" => array("format" => "%Y-%m-%d", "date" => array("\$add" => ["\$end_time", 28800000]))),
+                "value" => array("\$sum" => 1),
+            );
+        }else{
+            $start_date_time = new DateTime($begin_date_time->format("Y-m-d"));
+            if($datediff->y > 0){
+                $count = $datediff->y*12 + $datediff->m;
+            }else{
+                $count = $datediff->m;
+            }
+            for($i = 0;$i<$count;$i++){
+                $start_date_time->modify("+1 month");
+                $data5x[] = $start_date_time->format("Y-m");
+            }
+            $group5 = array(
+                "_id" => array("\$dateToString" => array("format" => "%Y-%m", "date" => array("\$add" => ["\$end_time", 28800000]))),
+                "value" => array("\$sum" => 1),
+            );
+        }
+        $result5 = $this->workorder_model->aggregate($begin_datetime, $end_datetime, $group5,NULL,array("status"=>"50"),NULL,NULL,array("_id"=>"ASC"));
+        for ($i=0;$i<count($data5x);$i++){
+            $have_value = 0;
+            foreach ($result5 as $result) {
+                if($data5x[$i] == $result['_id']){
+                    $data5y[] = $result['value'];
+                    $have_value =1;
+                }
+            }
+            if(!$have_value){
+                $data5y[] = 0;
+            }
+
+        }
+        $this->assign("data1", json_encode($data1));
+        $this->assign("data2x", json_encode($data2x));
+        $this->assign("data2y", json_encode($data2y));
+        $this->assign("data3x", json_encode($data3x));
+        $this->assign("data3y", json_encode($data3y));
+        $this->assign("data3legend", json_encode($data3legend));
+        $this->assign("data4x", json_encode($data4x));
+        $this->assign("data4y", json_encode($data4y));
+        $this->assign("data5x", json_encode($data5x));
+        $this->assign("data5y", json_encode($data5y));
+        $this->assign("begin_date", $begin_date);
+        $this->assign("end_date", $end_date);
+        $this->assign("title", $title);
+        $this->assign("sign", $sign);
+        $this->assign("now", now());
+        $this->display("report/index.html");
+    }
+
+    /**
+     * 导出统计报表
+     */
+    public function export(){
+        $title = $this->input->get('title',true);
+        $chart1 = '<div id="chart1" style="text-align: center;"></div>' .
+                  '<script type="text/javascript">' .
+            'var chart1 = parent.echarts.getInstanceByDom(parent.document.getElementById("main1"));' .
+            'var imgdata = chart1.getDataURL({' .
+            'type:"jpeg",' .
+            'pixelRatio: 1,' .
+            'backgroundColor: "#fff"' .
+            '});' .
+            'document.getElementById("chart1").innerHTML = \'<img src="\'+imgdata+\'">\';' .
+            '</script>';
+        $chart2 = '<div id="chart2" style="text-align: center;"></div>' .
+            '<script type="text/javascript">' .
+            'var chart2 = parent.echarts.getInstanceByDom(parent.document.getElementById("main2"));' .
+            'var imgdata = chart2.getDataURL({' .
+            'type:"jpeg",' .
+            'pixelRatio: 1,' .
+            'backgroundColor: "#fff"' .
+            '});' .
+            'document.getElementById("chart2").innerHTML = \'<img src="\'+imgdata+\'">\';' .
+            '</script>';
+        $chart3 = '<div id="chart3" style="text-align: center;"></div>' .
+            '<script type="text/javascript">' .
+            'var chart3 = parent.echarts.getInstanceByDom(parent.document.getElementById("main3"));' .
+            'var imgdata = chart3.getDataURL({' .
+            'type:"jpeg",' .
+            'pixelRatio: 1,' .
+            'backgroundColor: "#fff"' .
+            '});' .
+            'document.getElementById("chart3").innerHTML = \'<img src="\'+imgdata+\'">\';' .
+            '</script>';
+        $chart4 = '<div id="chart4" style="text-align: center;"></div>' .
+            '<script type="text/javascript">' .
+            'var chart4 = parent.echarts.getInstanceByDom(parent.document.getElementById("main4"));' .
+            'var imgdata = chart4.getDataURL({' .
+            'type:"jpeg",' .
+            'pixelRatio: 1,' .
+            'backgroundColor: "#fff"' .
+            '});' .
+            'document.getElementById("chart4").innerHTML = \'<img src="\'+imgdata+\'">\';' .
+            '</script>';
+        $chart5 = '<div id="chart5" style="text-align: center;"></div>' .
+            '<script type="text/javascript">' .
+            'var chart5 = parent.echarts.getInstanceByDom(parent.document.getElementById("main5"));' .
+            'var imgdata = chart5.getDataURL({' .
+            'type:"jpeg",' .
+            'pixelRatio: 1,' .
+            'backgroundColor: "#fff"' .
+            '});' .
+            'document.getElementById("chart5").innerHTML = \'<img src="\'+imgdata+\'">\';' .
+            '</script>';
+        $this->assign("title", $title);
+        $this->assign("chart1", $chart1);
+        $this->assign("chart2", $chart2);
+        $this->assign("chart3", $chart3);
+        $this->assign("chart4", $chart4);
+        $this->assign("chart5", $chart5);
+        $this->display("export/report.html");
+    }
+}

+ 156 - 0
application/controllers/Setting.php

@@ -0,0 +1,156 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/**
+ * Class 设置类
+ */
+class Setting extends MY_controller
+{
+    function __construct()
+    {
+        parent::__construct();
+        $this->load->driver('cache', array('adapter' => 'apc', 'backup' => 'file'));
+        $this->load->helper(array('form', 'url', 'date', 'sms'));
+        $this->load->model("setting_model");
+        $this->load->library('aliyunsms');
+        $this->assign("setting", $this->cache->get('setting'));
+    }
+
+    /**
+     * 设置短信和邮件
+     */
+    public function setting()
+    {
+        if ($this->input->post()) {
+            $data['setting_id'] = $this->input->post("setting_id", true);
+            $data['is_sms'] = $this->input->post("is_sms", true);
+            $data['sms_type'] = $this->input->post("sms_type", true);
+            $data['serial_port'] = $this->input->post("serial_port", true);
+            $data['baud_rate'] = $this->input->post("baud_rate", true);
+            $data['sms_cneter_num'] = $this->input->post("sms_cneter_num", true);
+            $data['test_phone'] = $this->input->post("test_phone", true);
+            $data['product'] = $this->input->post("product", true);
+            $data['access_key_id'] = $this->input->post("access_key_id", true);
+            $data['access_key_secret'] = $this->input->post("access_key_secret", true);
+            $data['sign_name'] = $this->input->post("sign_name", true);
+            $data['template_codes'] = $this->input->post("template_codes", true);
+            $data['is_email'] = $this->input->post("is_email", true);
+            $data['server'] = $this->input->post("server", true);
+            $data['smtp_secure'] = $this->input->post("smtp_secure", true);
+            $data['port'] = $this->input->post("port", true);
+            $data['sender'] = $this->input->post("sender", true);
+            $data['secret_key'] = $this->input->post("secret_key", true);
+            $data['tester'] = $this->input->post("tester", true);
+            if ($data['setting_id']) {
+                $this->setting_model->update_setting($data);
+            } elseif($data['is_sms'] != null && $data['is_email'] != null) {
+                $data['setting_id'] = $this->create_id();
+                $data['save_time'] = "180";
+                $this->setting_model->save_setting($data);
+            }
+            $this->update_cahce();
+            $this->response(array("code" => 1, "icon" => 1, "msg" => "配置信息保存成功!"));
+        } else {
+            $setting= $this->cache->get('setting');
+            if (!$setting) {
+                $setting = $this->setting_model->get_model();
+            }
+
+            $this->assign("setting", $setting);
+            $this->display("setting/setting.html");
+        }
+    }
+
+    /**
+     * 更新设置缓存
+     */
+    private function update_cahce(){
+        $setting = $this->setting_model->get_setting();
+        $this->cache->save('setting', $setting, 30000);
+    }
+
+    /**
+     * 测试发送
+     */
+    public function test()
+    {
+        $setting = $this->setting_model->get_setting();
+        if ($setting) {
+            $msg = "";
+            if ($setting['is_email']) {
+                $this->load->library('mailer');
+                $this->mailer->set_config($setting);
+                if ($this->mailer->send_email($setting['tester'], "邮件发送测试!", "邮件发送测试!如果收到这封邮件说明的邮箱配置已经成功!")) {
+                    $msg .= "邮件发送成功!";
+                } else {
+                    $msg .= "邮件发送失败!请检查配置!";
+                }
+            } else {
+                $msg .= "未启用邮件发送!";
+            }
+            if ($setting['is_sms']) {
+                if($setting['sms_type']=='10'){
+                    if(send_by_modem($setting, $setting['test_phone'], "短息发送成!收到该短信说明短信发送已经配置成功!")) {
+                        $msg .= "短信发送成功!如未收到短信请检查配置!";
+                    }else{
+                        $msg .= "短信发送失败!端口被占用或者配置错误!";
+                    }
+                }elseif($setting['sms_type']=='20'){
+                    $sms_content = array("sys_name"=> $this->config->item('sys_name'));
+                    $resp = $this->aliyunsms->sendSms($setting['test_phone'],$setting['template_codes'][6],$sms_content);
+                    if($resp['Code'] == 'OK'){
+                        $msg .= "短信发送成功!如未收到短信请检查配置!";
+                    }else{
+                        $msg .= "短信发送失败!".$resp['Code'] ;
+                    }
+                }
+            } else {
+                $msg .= "未启用短信发送!";
+            }
+            $this->response(array("icon" => 1, "msg" => $msg));
+        } else {
+            $this->response(array("icon" => 2, "msg" => "未配置短信和邮箱不能测试发送!"));
+        }
+    }
+
+    /**
+     * 配置向导
+     */
+    public function step(){
+        $setting= $this->cache->get('setting');
+        if (!$setting) {
+            $setting = $this->setting_model->get_model();
+        }
+
+        $this->assign("setting", $setting);
+        $this->display("setting/step.html");
+    }
+
+    /**
+     * 设置已完成工单保存时间
+     */
+    public function savetime(){
+        if ($this->input->post()) {
+            $save_time= $this->input->post("save_time", true);
+            $setting = $this->setting_model->get_setting();
+            $setting['save_time']  = $save_time;
+            $this->setting_model->update_setting($setting);
+            $this->update_cahce();
+            $this->response(array("code" => 1, "icon" => 1, "msg" => "已完成工单保存时间修改成功!"));
+        }else{
+            $this->response(array("code" => 2, "icon" => 2, "msg" => "请勿非法提交数据!"));
+        }
+    }
+
+    /**
+     * 清除缓存
+     */
+    public function clearcache(){
+        if($this->cache->clean()) {
+            $this->ci_smarty->clearAllCache();
+            $this->response(array("code" => 1, "icon" => 1, "msg" => "缓存清除成功!"));
+        }else{
+            $this->response(array("code" => 2, "icon" => 2, "msg" => "缓存清除失败!请检查application/cache目录是否有写权限!"));
+        }
+    }
+}

+ 121 - 0
application/controllers/Template.php

@@ -0,0 +1,121 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/**
+ * Class 工单和报表模板编辑类
+ */
+class Template extends MY_Controller
+{
+    private $workorder = "workorder";
+    private $report = "report";
+
+    function __construct()
+    {
+        parent::__construct();
+        $this->load->helper(array('form', 'date', 'file'));
+        $this->load->model("template_model");
+    }
+
+    /**
+     * 编辑工单模板
+     */
+    public function workorder()
+    {
+        if ($this->input->post()) {
+            $template_id = $this->input->post("template_id", true);
+            $template = $this->get_param();
+            $template['template_id'] = $template_id;
+            if ($template_id) {
+                $this->template_model->update_template($template);
+                $this->assign("message", "模板更新成功!");
+            } else {
+                $template['template_id'] = $this->create_id();
+                $template['create_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+                $this->template_model->insert_template($template);
+                $this->assign("message", "模板保存成功!");
+            }
+            $this->create_file($template['template_file'],$template['template_html'],"workorder");
+        } else {
+            $this->assign("message", "");
+        }
+        $template = $this->template_model->get_template_with_name($this->workorder);
+        if ($template) {
+            $this->assign("template", $template);
+        } else {
+            $model = $this->template_model->get_model();
+            $model['template_name'] = $this->workorder;
+            $model['template_file'] = $this->workorder . ".html";
+            $this->assign("template", $model);
+        }
+        $this->display("template/workorder.html");
+    }
+
+    /**
+     * 编辑报表模板
+     */
+    public function report()
+    {
+        if ($this->input->post()) {
+            $template_id = $this->input->post("template_id", true);
+            $template = $this->get_param();
+            $template['template_id'] = $template_id;
+            if ($template_id) {
+                $this->template_model->update_template($template);
+                $this->assign("message", "模板更新成功!");
+            } else {
+                $template['template_id'] = $this->create_id();
+                $template['create_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+                $this->template_model->insert_template($template);
+                $this->assign("message", "模板保存成功!");
+            }
+            $this->create_file($template['template_file'],$template['template_html'],"report");
+        } else {
+            $this->assign("message", "");
+        }
+        $template = $this->template_model->get_template_with_name($this->report);
+        if ($template) {
+            $this->assign("template", $template);
+        } else {
+            $model = $this->template_model->get_model();
+            $model['template_name'] = $this->report;
+            $model['template_file'] = $this->report . ".html";
+            $this->assign("template", $model);
+        }
+        $this->display("template/report.html");
+    }
+
+    /**
+     * 获取提交参数
+     * @return array
+     */
+    public function get_param()
+    {
+        $template = array();
+        $template['template_name'] = $this->input->post("template_name", true);
+        $template['template_file'] = $this->input->post("template_file", true);
+        $template['template_html'] = htmlspecialchars_decode($this->input->post("template_html"));
+        return $template;
+    }
+
+    /**
+     * 生成模板文件
+     * @param $filename 文件名称
+     * @param $content 文件内容
+     * @param $end 文件名结尾
+     */
+    public function create_file($filename, $content, $end)
+    {
+        $path = getcwd() . "/application/views/templates/export/";
+        $file = $path . $filename;
+        $header = '{include file="export/header.html"}';
+        $foot = '{include file="export/foot_'.$end.'.html"}';
+        $data = $header . htmlspecialchars_decode($content,ENT_QUOTES ) . $foot;
+        if (file_exists($file)) {
+            delete_files($file);
+        }
+        if (!write_file($file, $data)) {
+            show_error("文件写入失败,请检查" . $path . "是否有写入权限!");
+        }
+    }
+
+}

+ 71 - 0
application/controllers/Ueditor.php

@@ -0,0 +1,71 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/**
+ * Class Ueditor文件管理类
+ */
+class Ueditor extends MY_Controller
+{
+    function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     *Ueditor 文件管理(上传图片、附件、涂鸦、文件等)
+     */
+    public function index()
+    {
+        $CONFIG = json_decode(preg_replace("/\/\*[\s\S]+?\*\//", "", file_get_contents(APPPATH.DIRECTORY_SEPARATOR."config".DIRECTORY_SEPARATOR."config.json")), true);
+        $action = $this->input->get("action", true);
+        switch ($action) {
+            case 'config':
+                $result = json_encode($CONFIG);
+                break;
+
+            /* 上传图片 */
+            case 'uploadimage':
+                /* 上传涂鸦 */
+            case 'uploadscrawl':
+                /* 上传视频 */
+            case 'uploadvideo':
+                /* 上传文件 */
+            case 'uploadfile':
+                $result = include(APPPATH.DIRECTORY_SEPARATOR."libraries".DIRECTORY_SEPARATOR."action_upload.php");
+                break;
+
+            /* 列出图片 */
+            case 'listimage':
+                $result = include(APPPATH.DIRECTORY_SEPARATOR."libraries".DIRECTORY_SEPARATOR."action_list.php");
+                break;
+            /* 列出文件 */
+            case 'listfile':
+                $result = include(APPPATH.DIRECTORY_SEPARATOR."libraries".DIRECTORY_SEPARATOR."action_list.php");
+                break;
+
+            /* 抓取远程文件 */
+            case 'catchimage':
+                $result = include(APPPATH.DIRECTORY_SEPARATOR."libraries".DIRECTORY_SEPARATOR."action_crawler.php");
+                break;
+
+            default:
+                $result = json_encode(array(
+                    'state' => '请求地址出错'
+                ));
+                break;
+        }
+
+        /* 输出结果 */
+        if (isset($_GET["callback"])) {
+            if (preg_match("/^[\w_]+$/", $_GET["callback"])) {
+                echo htmlspecialchars($_GET["callback"]) . '(' . $result . ')';
+            } else {
+                echo json_encode(array(
+                    'state' => 'callback参数不合法'
+                ));
+            }
+        } else {
+            echo $result;
+        }
+    }
+}

+ 498 - 0
application/controllers/User.php

@@ -0,0 +1,498 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/**
+ * Class 用户管理类
+ */
+class User extends MY_controller
+{
+    function __construct()
+    {
+        parent::__construct();
+        $this->load->helper(array('form', 'url', 'date'));
+        $this->load->model("user_model");
+        $this->load->driver('cache', array('adapter' => 'apc', 'backup' => 'file'));
+        if(array_key_exists("from",$this->session->userdata)){
+            $this->user_model->set_collection_name("sso_users");
+        }
+        $this->load->library('MY_pagination');
+        $this->assign("user_status", $this->user_status);
+        $this->assign("user_types", $this->user_types);
+    }
+
+    /**
+     * 用户列表页
+     */
+    public function index()
+    {
+        $url = site_url("user/index?");
+        $wheres = array();
+        $order_info = array();
+        $keyword = $this->input->get("keyword", TRUE);
+        $user_type = $this->input->get("user_type", TRUE);
+        $status = $this->input->get("status", TRUE);
+        $order = $this->input->get("order", TRUE);
+        $page_num = $this->input->get("per_page", TRUE);
+        $page_size = $this->input->get("page_size", TRUE);
+        if ($keyword) {
+            $url .= "&keyword=" . $keyword;
+        }
+        if ($user_type) {
+            $wheres['user_type'] = $user_type;
+            $url .= "&user_type=" . $user_type;
+        }
+        if ($status) {
+            $wheres['status'] = $status;
+            $url .= "&status=" . $status;
+        }
+        if ($order) {
+            $orders = explode(" ", $order);
+            if (count($orders) == 2) {
+                $order_info[$orders[0]] = $orders[1];
+                $url .= "&order=" . $order;
+            }
+        }
+        if ($page_size) {
+            $this->page_size = $page_size;
+            $url .= "&page_size=" . $page_size;
+        }
+        $count = $this->user_model->count_user($keyword, $wheres);
+        $this->assign("count", $count);
+        $config = $this->page_config($count, $this->page_size, $url);
+        $this->my_pagination->initialize($config);
+        if($page_num && $page_num>1) {
+            $offset = (intval($page_num)-1)*$this->page_size;
+        }else {
+            $offset = 0;
+        }
+        $user_list = $this->user_model->list_user($this->page_size, $offset, $keyword, $wheres, $order_info);
+        $this->assign("keyword", $keyword);
+        $this->assign("user_type", $user_type);
+        $this->assign("status", $status);
+        $this->assign("order", $order);
+        $this->assign("page_size", $this->page_size);
+        $this->assign("page", $this->my_pagination->create_pages());
+        $this->assign("user_list", $user_list);
+        $this->display("user/index.html");
+    }
+
+    /**
+     * 查看用户详情
+     * @param $user_id 用户id
+     */
+    public function view($user_id)
+    {
+        $message = "";
+        $user = $this->user_model->get_user_with_user_id($user_id);
+        if($user){
+            $this->assign("user",$user);
+        }else{
+            $message = "用户信息不存在或者已经被删除";
+        }
+        $this->assign("message",$message);
+        $this->display("user/view.html");
+    }
+
+    /**
+     * 更新用户信息
+     */
+    public function update()
+    {
+        $cahce_branch = $this->cache->get('branchs');
+        $msg=array();
+        $data = array();
+        $msg['code'] = 1;
+        $msg['icon'] = 2;
+        $data['user_id']=$user_id = $this->input->post("user_id",true);
+        $old_user = $this->user_model->get_user_with_user_id($user_id);
+        $data['username']=$username = $this->input->post("username",true);
+        $password = $this->input->post("password",true);
+        $repassword = $this->input->post("repassword",true);
+        $data['name']=$name = $this->input->post("name",true);
+        $data['mobile']=$mobile = $this->input->post("mobile",true);
+        $data['email']=$email = $this->input->post("email",true);
+        $branch_id = $this->input->post("branch",true);
+        if($branch_id != "") {
+            $branchs = array();
+            for ($i = 0;$i<count($branch_id);$i++){
+                $branchs[] = array('branch_id' => $branch_id[$i], 'branch_type' => $cahce_branch[$branch_id[$i]]['branch_type']);
+            }
+            $data['branch'] = $branchs;
+        }else{
+            $data['branch'] = array(array('branch_id' => "", 'branch_type' => ""));
+        }
+        $data['user_type']=$user_type = $this->input->post("user_type",true);
+        if(!$username){
+            $msg['code'] = 0;
+            $msg['msg'] = "用户名不能为空!";
+        }
+        if(!preg_match_all("/^[a-zA-Z\d_]{5,18}$/",$username) && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "用户名格式不正确,只支持英文和数字,最小长度为5,最大长度为18!";
+        }
+        if($this->user_model->is_exists("username",$username,$old_user['username']) && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "该用户名已存在请换一个。";
+        }
+        if($password && !preg_match_all("/^[a-zA-Z\d_]{8,}$/",$password) && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "密码格式不正确,最小长度为8!";
+        }
+        if($password && $password != $repassword && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "两次密码输入不一致,请检查。";
+        }
+        if(!$name && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "姓名不能为空!";
+        }
+        if(!preg_match('/[a-zA-Z\x{4e00}-\x{9fa5}]/u', $name)  && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "姓名格式不正确,正能是中文或者英文!";
+        }
+        if(!$mobile && $msg['code']) {
+            $msg['code'] = 0;
+            $msg['msg'] = "手机号码不能为空!";
+        }
+        if(!preg_match('/^0?(13|14|15|17|18)[0-9]{9}$/', $mobile) && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "手机号码格式不正确!";
+        }
+        if($this->user_model->is_exists("mobile",$mobile,$old_user['mobile']) && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "该手机号已存被使用请换一个。";
+        }
+        if(!$email && $msg['code']) {
+            $msg['code'] = 0;
+            $msg['msg'] = "邮箱不能为空!";
+        }
+        if(!preg_match('/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/', $email) && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "邮箱格式不正确!";
+        }
+        if($this->user_model->is_exists("email",$email,$old_user['email']) && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "该邮箱已存被使用请换一个。";
+        }
+        if($user_type == 2 && $branch_id =="" && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "用户类型为工程师时,必须填写分支机构。";
+        }
+        if($msg['code']){
+            $this->user_model->update_user($data);
+            $msg['icon'] = 1;
+            $msg['msg'] = "用户信息更新成功!";
+        }
+        $this->response($msg);
+    }
+
+    /**
+     * 验证是否存在
+     * @param null $old_val 原数据
+     */
+    public function validate($old_val=NULL){
+        $field = $this->input->post("name",true);
+        $value = $this->input->post("param",true);
+        if($field == "username"){
+            $msg = "用户名已存在!";
+        }
+        if($field == "mobile"){
+            $msg = "手机号码已存在!";
+        }
+        if($field == "email"){
+            $old_val = urldecode($old_val);
+            $msg = "邮箱已存在!";
+        }
+        if($this->user_model->is_exists($field,$value,$old_val)){
+            $this->response(array("info"=>$msg,"status"=>"n"));
+        }else{
+            $this->response(array("info"=>"已验证通过!","status"=>"y"));
+        }
+    }
+
+    /**
+     * 增加用户
+     */
+    public function add()
+    {
+        $id = $this->create_id();
+        $this->assign("user_id", $id);
+        $this->display("user/add.html");
+    }
+
+    /**
+     * 保存用户数据
+     */
+    public function save(){
+        $cahce_branch = $this->cache->get('branchs');
+        $msg=array();
+        $data = array();
+        $msg['code'] = 1;
+        $msg['icon'] = 2;
+        $data['user_id']=$user_id = $this->input->post("user_id",true);
+        $data['username']=$username = $this->input->post("username",true);
+        $password = $this->input->post("password",true);
+        $repassword = $this->input->post("repassword",true);
+        $data['name']=$name = $this->input->post("name",true);
+        $data['mobile']=$mobile = $this->input->post("mobile",true);
+        $data['email']=$email = $this->input->post("email",true);
+        $branch_id = $this->input->post("branch",true);
+        if($branch_id != "") {
+            $branchs = array();
+            for ($i = 0;$i<count($branch_id);$i++){
+                $branchs[] = array('branch_id' => $branch_id[$i], 'branch_type' => $cahce_branch[$branch_id[$i]]['branch_type']);
+            }
+            $data['branch'] = $branchs;
+        }else{
+            $data['branch'] = array(array('branch_id' => "", 'branch_type' => ""));
+        }
+        $data['user_type']=$user_type = $this->input->post("user_type",true);
+        if(!$username){
+            $msg['code'] = 0;
+            $msg['msg'] = "用户名不能为空!";
+        }elseif(!preg_match_all("/^[a-zA-Z\d_]{5,18}$/",$username) && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "用户名格式不正确,只支持英文和数字,最小长度为5,最大长度为18!";
+        }elseif($this->user_model->is_exists("username",$username) && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "该用户名已存在请换一个。";
+        }
+        if(!$password && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "密码不能为空!";
+        }elseif(!preg_match_all("/^[a-zA-Z\d_]{8,}$/",$password) && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "密码格式不正确,最小长度为8!";
+        }
+        if($password != $repassword && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "两次密码输入不一致,请检查。";
+        }
+        if(!$name && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "姓名不能为空!";
+        }elseif(!preg_match('/[a-zA-Z\x{4e00}-\x{9fa5}]/u', $name)  && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "姓名格式不正确,正能是中文或者英文!";
+        }
+        if(!$mobile && $msg['code']) {
+            $msg['code'] = 0;
+            $msg['msg'] = "手机号码不能为空!";
+        }elseif(!preg_match('/^0?(13|14|15|17|18)[0-9]{9}$/', $mobile) && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "手机号码格式不正确!";
+        }elseif($this->user_model->is_exists("mobile",$mobile) && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "该手机号已存被使用请换一个。";
+        }
+        if(!$email && $msg['code']) {
+            $msg['code'] = 0;
+            $msg['msg'] = "邮箱不能为空!";
+        }elseif(!preg_match('/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/', $email) && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "邮箱格式不正确!";
+        }elseif($this->user_model->is_exists("email",$email) && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "该邮箱已存被使用请换一个。";
+        }
+        if($user_type == 2 && $branch_id =="" && $msg['code']){
+            $msg['code'] = 0;
+            $msg['msg'] = "用户类型为工程师时,必须填写分支机构。";
+        }
+        if($msg['code']){
+            $data['password']= hash_hmac('sha256',$password,$this->config->item('secret_key'));
+            $data['create_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+            $data['status'] = "10";
+            $data['last_login_time'] = "";
+            $this->user_model->insert_user($data);
+            $msg['icon'] = 1;
+            $msg['msg'] = "用户信息保存成功!";
+        }
+        $this->response($msg);
+    }
+
+    /**
+     * 删除用户数据
+     * @param $user_id 用户ID
+     */
+    public function delete($user_id)
+    {
+        $data['icon'] = 1;
+        if ($user_id) {
+            if($user_id != 1) {
+                $user = $this->user_model->get_user_with_user_id($user_id);
+                if ($user) {
+                    $this->user_model->delete_user($user_id);
+                    $data['msg'] = "用户删除成功!";
+                } else {
+                    $data['icon'] = 2;
+                    $data['msg'] = "用户信息不存在或者已经被删除!";
+                }
+            }else{
+                $data['icon'] = 2;
+                $data['msg'] = "系统预定义的账户不允许删除!";
+            }
+        } else {
+            $data['icon'] = 2;
+            $data['msg'] = "参数错误请刷新后重试!";
+        }
+        $this->response($data);
+    }
+
+    /**
+     * 禁用用户
+     * @param $user_id 用户Id
+     */
+    public function stopuse($user_id){
+        $data['icon'] = 1;
+        if ($user_id) {
+            $user = $this->user_model->get_user_with_user_id($user_id);
+            if($user) {
+                $user['status'] = "40";
+                $this->user_model->update_user($user);
+                $data['msg'] = "用户停用成功!";
+            }else{
+                $data['icon'] = 2;
+                $data['msg'] = "用户信息不存在或者已经被删除!";
+            }
+        } else {
+            $data['icon'] = 2;
+            $data['msg'] = "参数错误请刷新后重试!";
+        }
+        $this->response($data);
+    }
+
+    /**
+     * 启用用户
+     * @param $user_id 用户Id
+     */
+    public function restore($user_id){
+        $data['icon'] = 1;
+        if ($user_id) {
+            $user = $this->user_model->get_user_with_user_id($user_id);
+            if($user) {
+                $user['status'] = "10";
+                $this->user_model->update_user($user);
+                $data['msg'] = "用户恢复成功!";
+            }else{
+                $data['icon'] = 2;
+                $data['msg'] = "用户信息不存在或者已经被删除!";
+            }
+        } else {
+            $data['icon'] = 2;
+            $data['msg'] = "参数错误请刷新后重试!";
+        }
+        $this->response($data);
+    }
+
+    /**
+     * 修改用户密码
+     * @param $user_id 用户ID
+     */
+    public function change_password($user_id){
+        $data['code'] = 0;
+        $message = "";
+        $user = $this->user_model->get_user_with_user_id($user_id);
+        if($user){
+            $this->assign("user",$user);
+        }else{
+           $message = "用户信息不存在或者已经被删除!";
+        }
+        if($this->input->post()){
+            $password = $this->input->post("password",true);
+            $repassword = $this->input->post("repassword",true);
+            if($password) {
+                if ($this->session->user_type != "1") {
+                    $old_password =  hash_hmac('sha256',$this->input->post("old_password", true),$this->config->item('secret_key'));
+                    if ($old_password != $user['password']) {
+                        $data['icon'] = 2;
+                        $data['msg'] = "旧密码不正确,请重新输入!";
+                    } elseif ($password != $repassword) {
+                        $data['icon'] = 2;
+                        $data['msg'] = "两次密码输入不一致,请重新输入!";
+                    } else {
+                        $user['password'] = hash_hmac('sha256',$password,$this->config->item('secret_key'));
+                        $this->user_model->update_user($user);
+                        $data['code'] = 1;
+                        $data['icon'] = 1;
+                        $data['msg'] = "密码修改成功!";
+                    }
+                } else {
+                    if ($password != $repassword) {
+                        $data['icon'] = 2;
+                        $data['msg'] = "两次密码输入不一致,请重新输入!";
+                    } else {
+                        $user['password'] =  hash_hmac('sha256',$password,$this->config->item('secret_key'));
+                        $this->user_model->update_user($user);
+                        $data['code'] = 1;
+                        $data['icon'] = 1;
+                        $data['msg'] = "密码修改成功!";
+                    }
+                }
+            }else{
+                $data['code'] = 1;
+                $data['icon'] = 1;
+                $data['msg'] = "放弃修改密码!";
+            }
+            $this->response($data);
+        }else{
+            $this->assign("message",$message);
+            $this->display("user/change_password.html");
+        }
+    }
+
+    /**
+     * 批量删除用户
+     */
+    public function delete_all(){
+        $ids = rtrim($this->input->post("ids",true),",");
+        $ids = explode(",",$ids);
+        if(count($ids)<1){
+            $data['icon'] = 2;
+            $data['msg'] = "参数错误请刷新后重试!";
+        }else{
+            $this->user_model->delete_all_user($ids);
+            $data['icon'] = 1;
+            $data['msg'] = "批量删除用户成功!";
+        }
+        $this->response($data);
+    }
+
+    /**
+     * 批量禁用用户
+     */
+    public function disable_all(){
+        $ids = rtrim($this->input->post("ids",true),",");
+        $ids = explode(",",$ids);
+        if(count($ids)<1){
+            $data['icon'] = 2;
+            $data['msg'] = "参数错误请刷新后重试!";
+        }else{
+            $wheres = array('user_id'=>array('$in'=>$ids));
+            $this->user_model->set_val("status",$wheres,"40");
+            $data['icon'] = 1;
+            $data['msg'] = "批量禁用用户成功!";
+        }
+        $this->response($data);
+    }
+
+    /**
+     * 批量启用用户
+     */
+    public function enable_all(){
+        $ids = rtrim($this->input->post("ids",true),",");
+        $ids = explode(",",$ids);
+        if(count($ids)<1){
+            $data['icon'] = 2;
+            $data['msg'] = "参数错误请刷新后重试!";
+        }else{
+            $wheres = array('user_id'=>array('$in'=>$ids));
+            $this->user_model->set_val("status",$wheres,"10");
+            $data['icon'] = 1;
+            $data['msg'] = "批量启用用户成功!";
+        }
+        $this->response($data);
+    }
+
+
+}

+ 191 - 0
application/controllers/Warning.php

@@ -0,0 +1,191 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/**
+ * Class 告警信息管理类
+ */
+class Warning extends MY_Controller{
+
+    function __construct(){
+        parent::__construct();
+        $this->load->helper('form');
+        $this->load->model("warning_model");
+        $this->load->library('MY_pagination');
+        $this->load->helper('url');
+        $this->assign("warning_type",$this->warning_type);
+        $this->assign("warning_level",$this->warning_level);
+        $this->assign("warning_status",$this->warning_status);
+    }
+
+    /**
+     * 状态数量统计
+     */
+    private function counts()
+    {
+        $count10 = $this->warning_model->count_warning(null, $wheres = array('status' => "10"));
+        $count20 = $this->warning_model->count_warning(null, $wheres = array('status' => "20"));
+        $count30 = $this->warning_model->count_warning(null, $wheres = array('status' => "30"));
+        $count40 = $this->warning_model->count_warning(null, $wheres = array('status' => "40"));
+        $this->assign("count10", $count10);
+        $this->assign("count20", $count20);
+        $this->assign("count30", $count30);
+        $this->assign("count40", $count40);
+    }
+
+    /**
+     * 告警列表页
+     */
+    public function index(){
+        $url = site_url("warning/index?");
+        $wheres = array();
+        $order_info = array("status"=>"ASC","create_time"=>"DESC");
+        $warning_name = $this->input->get("warning_name",TRUE);
+        $branch_id = $this->input->get("branch_id",TRUE);
+        $type = $this->input->get("type",TRUE);
+        $status = $this->input->get("status",TRUE);
+        $order = $this->input->get("order",TRUE);
+        $page_num = $this->input->get("per_page",TRUE);
+        $page_size = $this->input->get("page_size",TRUE);
+        if($warning_name){
+            $url .= "&warning_name=".$warning_name;
+        }
+        if($branch_id){
+            $wheres['branch.branch_id'] = $branch_id;
+            $url .= "&branch_id=".$branch_id;
+        }
+        if($type){
+            $wheres['type'] = $type;
+            $url .= "&type=".$type;
+        }
+        if($status) {
+            $wheres['status'] = $status;
+            $url .= "&status=".$status;
+        }
+        if($order){
+            $orders = explode(" ",$order);
+            if(count($orders)==2) {
+                $order_info[$orders[0]] = $orders[1];
+                $url .= "&order=".$order;
+            }
+        }
+        if($page_size){
+            $this->page_size = $page_size;
+            $url .= "&page_size=".$page_size;
+        }
+        $count = $this->warning_model->count_warning($warning_name,$wheres);
+        $this->assign("count",$count);
+        $config = $this->page_config($count,$this->page_size,$url);
+        $this->my_pagination->initialize ($config);
+        if($page_num && $page_num>1) {
+            $offset = (intval($page_num)-1)*$this->page_size;
+        }else {
+            $offset = 0;
+        }
+        $warning_list = $this->warning_model->list_warning($this->page_size,$offset,$warning_name,$wheres,$order_info);
+        $this->counts();
+        $this->assign("warning_name",$warning_name);
+        $this->assign("type",$type);
+        $this->assign("branch_id",$branch_id);
+        $this->assign("status",$status);
+        $this->assign("order",$order);
+        $this->assign("page_size",$this->page_size);
+        $this->assign("page",$this->my_pagination->create_pages());
+        $this->assign("warning_list",$warning_list);
+        $this->display("warning/index.html");
+    }
+
+    public function view($warning_id){
+        $warning_info = $this->warning_model->get_warning_with_id($warning_id);
+        $this->assign("warning",$warning_info);
+        $this->display("warning/view.html");
+    }
+
+    /**
+     * 已忽略告警信息列表页
+     */
+    public function ignoreindex(){
+        $url = site_url("warning/ignoreindex?");
+        $wheres = array();
+        $order_info = array();
+        $warning_name = $this->input->get("warning_name",TRUE);
+        $type = $this->input->get("type",TRUE);
+        $order = $this->input->get("order",TRUE);
+        $page_num = $this->input->get("per_page",TRUE);
+        $page_size = $this->input->get("page_size",TRUE);
+        if($warning_name){
+            $url .= "&warning_name=".$warning_name;
+        }
+        if($type){
+            $wheres['type'] = $type;
+            $url .= "&type=".$type;
+        }
+        $wheres['status'] = "20";
+        if($order){
+            $orders = explode(" ",$order);
+            if(count($orders)==2) {
+                $order_info[$orders[0]] = $orders[1];
+                $url .= "&order=".$order;
+            }
+        }
+        if($page_size){
+            $this->page_size = $page_size;
+            $url .= "&page_size=".$page_size;
+        }
+        $count = $this->warning_model->count_warning($warning_name,$wheres);
+        $config = $this->page_config($count,$this->page_size,$url);
+        $this->my_pagination->initialize ($config);
+        if($page_num && $page_num>1) {
+            $offset = (intval($page_num)-1)*$this->page_size;
+        }else {
+            $offset = 0;
+        }
+        $warning_list = $this->warning_model->list_warning($this->page_size,$offset,$warning_name,$wheres,$order_info);
+        $this->assign("count",$count);
+        $this->assign("warning_name",$warning_name);
+        $this->assign("type",$type);
+        $this->assign("order",$order);
+        $this->assign("page_size",$this->page_size);
+        $this->assign("page",$this->my_pagination->create_pages());
+        $this->assign("warning_list",$warning_list);
+        $this->display("warning/ignoreindex.html");
+    }
+
+    /**
+     * 忽略告警信息
+     * @param $warning_id 告警信息ID
+     */
+    public function ignore($warning_id){
+        $msg = array();
+        $warning_info = $this->warning_model->get_warning_with_id($warning_id);
+        if($warning_info){
+            $warning_info['status'] = "20";
+            $this->warning_model->update_warning($warning_info);
+            $msg['msg'] = "忽略告警信息成功!";
+            $msg['icon'] = 1;
+        }else{
+            $msg['msg'] = "告警信息不存在或者已经被删除!";
+            $msg['icon'] = 2;
+        }
+        $this->response($msg);
+    }
+
+    /**
+     * 批量忽略告警信息
+     */
+    public function ignoreselect(){
+        $warning_ids = $this->input->post("warning_ids",true);
+        $msg['msg'] = "忽略告警信息成功!";
+        $msg['icon'] = 1;
+        $ids = explode(",",$warning_ids);
+        foreach($ids as $key=>$val){
+            if($val){
+                $warning_info = $this->warning_model->get_warning_with_id($val);
+                if($warning_info){
+                    $warning_info['status'] = "20";
+                    $this->warning_model->update_warning($warning_info);
+                }
+            }
+        }
+        $this->response($msg);
+    }
+}

Різницю між файлами не показано, бо вона завелика
+ 578 - 0
application/controllers/Workorder.php


+ 11 - 0
application/controllers/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 237 - 0
application/controllers/v1/Api.php

@@ -0,0 +1,237 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+class Api extends Public_Controller
+{
+
+    function __construct()
+    {
+        parent::__construct();
+        $this->load->driver('cache', array('adapter' => 'apc', 'backup' => 'file'));
+        $this->load->model("user_model");
+        $this->load->model("token_model");
+        $this->load->model("branch_model");
+        $this->load->model("workorder_model");
+        $this->load->model("warning_model");
+        $this->load->model("appauth_model");
+        $this->load->library('MY_pagination');
+        $this->load->helper(array('url', 'date', 'sms'));
+    }
+
+    public function get_token()
+    {
+        $msg = array();
+        $appid = $this->input->get("appid", true);
+        $secret = $this->input->get("secret", true);
+        $appauth = $this->appauth_model->get_appauth_with_id($appid);
+        if ($appid && $secret && $appauth && $secret == $appauth['secret']) {
+            $data['token'] = $token = $this->create_token();
+            $expires = new DateTime();
+            $expires->modify("+2 hours");
+            $data['expires_time'] = new MongoDB\BSON\UTCDateTime($expires->getTimestamp()*1000);
+            if ($this->token_model->save_token($data)) {
+                $msg['errcode'] = 0;
+                $msg['errmsg'] = "ok";
+                $msg['access_token'] = $token;
+                $msg['expires_in'] = 7200;
+            } else {
+                $msg['errcode'] = 40013;
+                $msg['errmsg'] = "invalid appid";
+            }
+        } else {
+            $msg['errcode'] = 40013;
+            $msg['errmsg'] = "invalid appid";
+        }
+        $this->response($msg);
+    }
+
+    public function upload_data()
+    {
+        $access_token = $this->input->get("access_token", true);
+        $msg = array();
+        if ($access_token && $this->token_exists($access_token)) {
+            $json = $this->get_json();
+            $data = json_decode($json, true);
+            if(count($data)>=1){
+                $upload_info = $data['upload_info'];
+                $device = $data['device'];
+                if($upload_info['type'] == "20"){
+                    $branch_list = $data['data'];
+                    if (count($branch_list) > 0) {
+                        foreach ($branch_list as $key => $val) {
+                            $val['device'] = $device;
+                            $this->branch_model->save_branch($val);
+                            $this->update_branch_cache();
+                        }
+                    }
+                }elseif($upload_info['type'] == "10") {
+                    $warning_list = $data['data'];
+                    if (count($warning_list) > 0) {
+                        foreach ($warning_list as $key => $val) {
+                            $val['status'] = "10";
+                            $val['create_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+                            $val['device'] = $device;
+                            $this->warning_model->insert_warning($val);
+                        }
+                    }
+                }
+            }
+            $msg['errcode'] = 0;
+            $msg['errmsg'] = "OK";
+        } else {
+            $msg['errcode'] = 40012;
+            $msg['errmsg'] = "invalid access token";
+        }
+        $this->response($msg);
+    }
+
+    public function update_branch_cache(){
+        $branch_list = $this->branch_model->select_branch();
+        if($branch_list){
+            $branch = array();
+            foreach($branch_list as $key=>$val){
+                $branch[$val['branch_id']] = $val;
+            }
+            $this->cache->save('branchs', $branch, 30000);
+        }else{
+            $this->cache->save('branchs', array(), 30000);
+        }
+    }
+
+    public function get_status()
+    {
+        $access_token = $this->input->get("access_token", true);
+        $msg = array();
+        if ($access_token && $this->token_exists($access_token)) {
+            $json = $this->get_json();
+            $data = json_decode($json, true);
+            if(array_key_exists("id",$data)){
+                $ids = $data['id'];
+                for($i = 0;$i<count($ids);$i++){
+                    $waning = $this->warning_model->select_warning(array("status"),$ids[$i]);
+                    if($waning){
+                        if($waning['status'] == "40"){
+                            $msg[$ids[$i]] = true;
+                        }else {
+                            $msg[$ids[$i]] = false;
+                        }
+                    }else{
+                        $msg[$ids[$i]] = false;
+                    }
+                }
+            }
+            $msg['errcode'] = 0;
+            $msg['errmsg'] = "OK";
+        } else {
+            $msg['errcode'] = 40012;
+            $msg['errmsg'] = "invalid access token";
+        }
+        $this->response($msg);
+    }
+
+    public function get_login_url()
+    {
+        $access_token = $this->input->get("access_token", true);
+        $msg = array();
+        if ($access_token && $this->token_exists($access_token)) {
+            $json = $this->get_json();
+            $data = json_decode($json, true);
+            $user_model = $this->user_model;
+            $user_model->set_collection_name("sso_users");
+            if($user_model->is_exists("username",$data['username'])){
+                $info['last_login_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+                $info['code'] = $this->create_token();
+                $user_model->set_val($info,array("username"=>$data['username']));
+                $msg["login_url"]=site_url("v1/api/sso_login?code=".$info['code']);
+            }else {
+                $data['user_id'] = $this->create_id();
+                $data['status'] = "10";
+                $data['create_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+                $data['last_login_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+                $data['code'] = $this->create_token();
+                $user_model->insert_user($data);
+                $msg["login_url"]=site_url("v1/api/sso_login?code=".$data['code']);
+            }
+            $msg['errcode'] = 0;
+            $msg['errmsg'] = "OK";
+        } else {
+            $msg['errcode'] = 40012;
+            $msg['errmsg'] = "invalid access token";
+        }
+        $this->response($msg);
+    }
+
+    public function sso_login(){
+        $code = $this->input->get("code", true);
+        $msg = array();
+        $user_model = $this->user_model;
+        $user_model->set_collection_name("sso_users");
+        $sso_user = $user_model->get_user_with_code($code);
+        if($code &&  $sso_user){
+            $sso_user['code'] = "";
+            $rand = substr(md5(microtime()), rand(0, 26), 5);
+            $session_data = array("user_id" => (string)$sso_user["user_id"], "current_key" => $rand, "username" => $sso_user['username'], "user_type" => $sso_user['user_type'], "from" => $sso_user['from']);
+            $sso_user['last_login_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+            $user_model->update_user($sso_user);
+            $this->session->set_userdata($session_data);
+            redirect("main/index");
+        }else{
+            show_error("invalid code!");
+        }
+    }
+
+    public function send_sms(){
+        $access_token = $this->input->get("access_token", true);
+        $msg = array();
+        if ($access_token && $this->token_exists($access_token)) {
+            $json = $this->get_json();
+            $data = json_decode($json, true);
+            if(count($data)==2 && array_key_exists("mobile",$data) && array_key_exists("content",$data)){
+                for($i = 0; $i< count($data['mobile']);$i++){
+                    $number = $data['mobile'][$i];
+                    if(send_by_modem($this->cache->get('setting'),$number,$data['content'])){
+                        $msg[$number]=true;
+                    }else{
+                        $msg[$number]=false;
+                    }
+                }
+            }
+            $msg['errcode'] = 0;
+            $msg['errmsg'] = "OK";
+        }else {
+            $msg['errcode'] = 40012;
+            $msg['errmsg'] = "invalid access token";
+        }
+        $this->response($msg);
+    }
+
+    private function create_token()
+    {
+        do {
+            $salt = base_convert(bin2hex($this->security->get_random_bytes(64)), 11, 36);
+            if ($salt === FALSE) {
+                $salt = hash('sha256', time() . mt_rand());
+            }
+            $token = substr($salt, 0, config_item('key_length'));
+        } while ($this->token_exists($token));
+        return $token;
+    }
+
+    private function token_exists($token)
+    {
+        if ($token) {
+            if ($this->token_model->find_token($token, new MongoDB\BSON\UTCDateTime(time()*1000))) {
+                return true;
+            } else {
+                return false;
+            }
+        } else {
+            return false;
+        }
+    }
+
+    private function get_json(){
+        $postjson = file_get_contents('php://input');
+        return $postjson;
+    }
+}

+ 199 - 0
application/core/MY_Controller.php

@@ -0,0 +1,199 @@
+<?php
+
+class Public_Controller extends CI_Controller
+{
+    protected $page_size;
+    protected $branch_array;
+    protected $setting;
+
+    //告警类型
+    public $warning_type = array(
+        "10" => "失陷事件",
+        "20" => "脆弱性",
+        "30" => "残余攻击"
+    );
+
+    //告警级别
+    public $warning_level = array(
+        "10" => "已失陷",
+        "20" => "高可疑",
+        "30" => "低可疑",
+        "40" => "高危",
+        "50" => "中危",
+        "60" => "低危"
+    );
+
+    //告警状态
+    public $warning_status = array(
+        "10" => "待审核下发",
+        "20" => "已忽略",
+        "30" => "已生成工单",
+        "40" => "已处置"
+    );
+
+    //工单状态
+    public $workorder_status = array(
+        "10" => "待签收",
+        "20" => "已签收,正在处理",
+        "30" => "处理完成,待复核",
+        "40" => "驳回处理",
+        "50" => "已结束",
+        "60" => "已删除"
+    );
+
+    //发送类型
+    public $send_type = array(
+        "10" => "短信",
+        "20" => "邮件"
+    );
+
+    //用户角色
+    public $user_types = array(
+        "1" => "管理员",
+        "2" => "工程师"
+    );
+
+    //用户状态
+    public $user_status = array(
+        "10" => "正常",
+        "40" => "已停用"
+    );
+
+    //应用授权状态
+    public $appauth_status = array(
+        "10" => "启用",
+        "40" => "停用"
+    );
+
+    //平台对应关系
+    public $from = array(
+        "sip" => "安全感知平台"
+    );
+
+    public function __construct()
+    {
+        parent::__construct();
+        $this->load->helper(array('url'));
+        $this->load->driver('cache', array('adapter' => 'apc', 'backup' => 'file'));
+        $cahce_setting = $this->cache->get('setting');
+        if(!$cahce_setting){
+            $this->load->model("setting_model");
+            $setting = $this->setting_model->get_setting();
+            if($setting) {
+                $cahce_setting = $setting;
+                $this->cache->save('setting', $setting, 30000);
+            }
+        }
+        $cahce_branch = $this->cache->get('branchs');
+        if(!$cahce_branch){
+            $this->load->model("branch_model");
+            $branch_list = $this->branch_model->select_branch();
+            if($branch_list){
+                $branch = array();
+                foreach($branch_list as $key=>$val){
+                    $branch[$val['branch_id']] = $val;
+                }
+                $this->cache->save('branchs', $branch, 30000);
+                $cahce_branch= $branch;
+            }else{
+                $this->cache->save('branchs', array(), 30000);
+                $cahce_branch = array();
+            }
+        }
+        if(!array_key_exists('save_time',$cahce_setting) || $cahce_setting['save_time']==""){
+            $cahce_setting['save_time'] = "180";
+        }
+        $this->setting = $cahce_setting;
+        $this->branch_array = $cahce_branch;
+        $this->assign("setting",$cahce_setting);
+        $this->assign("branch",$cahce_branch);
+        $this->page_size = $this->config->item('page_size');
+        $this->assign("sys_name", $this->config->item('sys_name'));
+        $this->assign("from",$this->from);
+    }
+
+    public function assign($key, $val)
+    {
+        $this->ci_smarty->assign($key, $val);
+    }
+
+    //Smaty模板输出
+    public function display($html)
+    {
+        $this->output->set_header('X-Frame-Options: sameorigin');
+        $this->output->set_header("X-XSS-Protection: 1");
+        $this->output->set_header("X-Content-Type-Options:nosniff");
+        $this->ci_smarty->display($html);
+    }
+
+    //输出Json
+    public function response($data)
+    {
+        $this->output->set_header('X-Frame-Options: sameorigin');
+        $this->output->set_header("X-XSS-Protection: 1");
+        $this->output->set_header("X-Content-Type-Options:nosniff");
+        $this->output->set_header('Content-Type: application/json; charset=utf-8');
+        echo json_encode($data);
+    }
+
+    /*
+     * 创建唯一ID
+     */
+    public function create_id()
+    {
+        return date('Ymd') . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
+    }
+
+    /**
+     * 分页配置
+     * @param $count 内容总数
+     * @param $page_size 每页数量
+     * @param $url 分页URL
+     * @return mixed 分页html
+     */
+    public function page_config($count, $page_size, $url)
+    {
+        $config ['base_url'] = $url; //设置基地址
+        $config['num_links'] = 4;
+        $config ['total_rows'] = $count;
+        $config ['per_page'] = $page_size; //每页显示的数据数量
+        $config['use_page_numbers'] = TRUE;
+        $config['full_tag_open'] = '<ul class="pagination">';
+        $config['full_tag_close'] = '</ul>';
+        $config ['prev_link'] = '<';
+        $config['prev_tag_open'] = '<li>';
+        $config['prev_tag_close'] = '</li>';
+        $config ['next_link'] = '>';
+        $config['next_tag_open'] = '<li>';
+        $config['next_tag_close'] = '</li>';
+        $config['num_tag_open'] = '<li>';
+        $config['num_tag_close'] = '</li>';
+        $config['cur_tag_open'] = '<li class="active"><a href="#">';
+        $config['cur_tag_close'] = '</a></li>';
+        $config ['first_link'] = '«';
+        $config['first_tag_open'] = '<li>';
+        $config['first_tag_close'] = '</li>';
+        $config ['last_link'] = '»';
+        $config['last_tag_open'] = '<li>';
+        $config['last_tag_close'] = '</li>';
+        $config['page_query_string'] = TRUE;
+        return $config;
+    }
+
+
+}
+
+class MY_Controller extends Public_Controller
+{
+    public function __construct()
+    {
+        parent::__construct();
+        if (!$this->session->user_id || !$this->session->username) {
+            redirect("login");
+        } else {
+            $this->assign("username", $this->session->username);
+            $this->assign("user_type", $this->session->user_type);
+            $this->assign("user_id", $this->session->user_id);
+        }
+    }
+}

+ 11 - 0
application/core/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 11 - 0
application/helpers/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 108 - 0
application/helpers/sms_helper.php

@@ -0,0 +1,108 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+if (!function_exists('send_by_modem')) {
+    /**
+     * 使用短信猫发送短信
+     * @param $config 配置
+     * @param $mobile 接收号码
+     * @param $content 发送内容
+     * @return bool 是否发送成功
+     */
+    function send_by_modem($config, $mobile, $content)
+    {
+        $max_len = 280;
+        $serial = new Serial();
+        if(!$serial->deviceSet("COM" . $config['serial_port'])){
+            return false;
+        }else {
+            $serial->confBaudRate($config['baud_rate']);
+            if ($serial->deviceOpen()) {
+                $phone_center = InvertNumbers("86" . $config['sms_cneter_num']);
+                $phone_sendto = InvertNumbers("86" . $mobile);
+                $pdu_text = Ucs2Code($content);
+                do {
+                    $pdu_len = strlen($pdu_text);
+                    if ($pdu_len > $max_len) {
+                        $pdu_text1 = substr($pdu_text, 0, $max_len);
+                        $pdu_text = substr($pdu_text, $max_len, $pdu_len - $max_len);
+                    } else {
+                        $pdu_text1 = $pdu_text;
+                        $pdu_text = "";
+                    }
+                    $mess = "11000D91" . $phone_sendto . "000800" . sprintf("%02X", strlen($pdu_text1) / 2) . $pdu_text1;
+                    $serial->sendMessage("AT+CMGF=0" . chr(13),0.5);
+                    $cmd = "AT+CMGS=" . sprintf("%d", strlen($mess) / 2) . chr(13);
+                    $serial->sendMessage($cmd);
+                    $mess_ll = "0891" . $phone_center . $mess;
+                    $serial->sendMessage($mess_ll . chr(26), 0.5);
+                } while ($pdu_text != "");
+                $serial->deviceClose();
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+}
+/***
+ * @Method Ucs2Code UCS2编码
+ * @Param $str 输入字符串
+ * @Param $encod 输入字符串编码类型(UTF-8,GB2312,GBK)
+ * @Return 返回编码后的字符串
+ */
+function Ucs2Code($str, $encode = "UTF-8")
+{
+    $jumpbit = strtoupper($encode) == 'GB2312' ? 2 : 3;//跳转位数
+    $strlen = strlen($str);//字符串长度
+    $pos = 0;//位置
+    $buffer = array();
+    for ($pos = 0; $pos < $strlen;) {
+        if (ord(substr($str, $pos, 1)) >= 0xa1) {//0xa1(161)汉字编码开始
+            $tmpChar = substr($str, $pos, $jumpbit);
+            $pos += $jumpbit;
+        } else {
+            $tmpChar = substr($str, $pos, 1);
+            ++$pos;
+        }
+        $buffer[] = bin2hex(iconv("UTF-8", "UCS-2", $tmpChar));
+    }
+    return strtoupper(join("", $buffer));
+}
+
+/***
+ * @Method unUcs2Code UCS2解码
+ * @Param $str 输入字符串
+ * @Param $encod 输入字符串编码类型(UTF-8,GB2312,GBK)
+ * @Return 返回解码后的字符串
+ */
+function unUcs2Code($str, $encode = "UTF-8")
+{
+    $strlen = strlen($str);
+    $step = 4;
+    $buffer = array();
+    for ($i = 0; $i < $strlen; $i += $step) {
+        $buffer[] = iconv("UCS-2", $encode, pack("H4", substr($str, $i, $step)));
+    }
+    return join("", $buffer);
+}
+
+/**
+ * 号码PDU翻转
+ * @param $msisdn
+ * @return string
+ */
+function InvertNumbers($msisdn)
+{
+    $len = strlen($msisdn);
+    if (0 != fmod($len, 2)) {
+        $msisdn .= "F";
+        $len = $len + 1;
+    }
+    for ($i = 0; $i < $len; $i += 2) {
+        $t = $msisdn[$i];
+        $msisdn[$i] = $msisdn[$i + 1];
+        $msisdn[$i + 1] = $t;
+    }
+    return $msisdn;
+}

+ 11 - 0
application/hooks/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 11 - 0
application/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 11 - 0
application/language/bulgarian/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 18 - 0
application/language/bulgarian/rest_controller_lang.php

@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * Bulgarian language
+ */
+
+$lang['text_rest_invalid_api_key'] = 'Невалиден API ключ %s';
+$lang['text_rest_invalid_credentials'] = 'Невалидни данни за достъп';
+$lang['text_rest_ip_denied'] = 'Отказан IP адрес';
+$lang['text_rest_ip_unauthorized'] = 'Неоторизиран IP адрес';
+$lang['text_rest_unauthorized'] = 'Неоторизиран достъп';
+$lang['text_rest_ajax_only'] = 'Само AJAX заявки са разрешени';
+$lang['text_rest_api_key_unauthorized'] = 'API ключът не е оторизиран зо достъп до заявения контролер';
+$lang['text_rest_api_key_permissions'] = 'API ключът няма достатъчно права';
+$lang['text_rest_api_key_time_limit'] = 'API ключът е изполван с превишаване на времевия лимит за този метод';
+$lang['text_rest_ip_address_time_limit'] = 'За текущия IP адрес е превишен времевия лимит за изпълнение на метода';
+$lang['text_rest_unknown_method'] = 'Неизвестен метод';
+$lang['text_rest_unsupported'] = 'Неподдържан протокол';

+ 11 - 0
application/language/dutch/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 16 - 0
application/language/dutch/rest_controller_lang.php

@@ -0,0 +1,16 @@
+<?php
+/*
+ * Dutch language
+ */
+$lang['text_rest_invalid_api_key'] 		 = 'Ongeldige API sleutel %s'; // %s is the REST API key
+$lang['text_rest_invalid_credentials']   = 'Ongeldige gegevens';
+$lang['text_rest_ip_denied'] 			 = 'IP-adres geweigerd';
+$lang['text_rest_ip_unauthorized'] 		 = 'IP-adres niet toegestaan';
+$lang['text_rest_unauthorized'] 		 = 'Niet toegestaan';
+$lang['text_rest_ajax_only'] 			 = 'Alleen AJAX requests zijn toegestaan';
+$lang['text_rest_api_key_unauthorized']  = 'De API sleutel heeft geen toegang tot de gevraagde informatie';
+$lang['text_rest_api_key_permissions']   = 'De API sleutel heeft niet genoeg bevoegdheden';
+$lang['text_rest_api_key_time_limit'] 	 = 'De API sleutel heeft de tijdslimiet bereikt';
+$lang['text_rest_ip_address_time_limit'] = 'Het IP-adres heeft de tijdslimiet bereikt';
+$lang['text_rest_unknown_method'] 	     = 'Onbekende actie';
+$lang['text_rest_unsupported'] 			 = 'Protocol wordt niet ondersteund';

+ 18 - 0
application/language/english/rest_controller_lang.php

@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * English language
+ */
+
+$lang['text_rest_invalid_api_key'] = 'Invalid API key %s'; // %s is the REST API key
+$lang['text_rest_invalid_credentials'] = 'Invalid credentials';
+$lang['text_rest_ip_denied'] = 'IP denied';
+$lang['text_rest_ip_unauthorized'] = 'IP unauthorized';
+$lang['text_rest_unauthorized'] = 'Unauthorized';
+$lang['text_rest_ajax_only'] = 'Only AJAX requests are allowed';
+$lang['text_rest_api_key_unauthorized'] = 'This API key does not have access to the requested controller';
+$lang['text_rest_api_key_permissions'] = 'This API key does not have enough permissions';
+$lang['text_rest_api_key_time_limit'] = 'This API key has reached the time limit for this method';
+$lang['text_rest_ip_address_time_limit'] = 'This IP Address has reached the time limit for this method';
+$lang['text_rest_unknown_method'] = 'Unknown method';
+$lang['text_rest_unsupported'] = 'Unsupported protocol';

+ 11 - 0
application/language/french/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 18 - 0
application/language/french/rest_controller_lang.php

@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * French language
+ */
+
+$lang['text_rest_invalid_api_key'] = 'La clef d\'API %s est invalide'; // %s is the REST API key
+$lang['text_rest_invalid_credentials'] = 'Authentification invalide';
+$lang['text_rest_ip_denied'] = 'IP refusée';
+$lang['text_rest_ip_unauthorized'] = 'IP non-autorisée';
+$lang['text_rest_unauthorized'] = 'Non autorisé';
+$lang['text_rest_ajax_only'] = 'Seul les requêtes AJAX sont autorisées';
+$lang['text_rest_api_key_unauthorized'] = 'Cette clef d\'API n\'a pas accès au contrôleur demandé';
+$lang['text_rest_api_key_permissions'] = 'Cette clef d\'API n\'a pas les permissions requises';
+$lang['text_rest_api_key_time_limit'] = 'Cette clef d\'API a atteint sa limite de temps pour cette méthode';
+$lang['text_rest_ip_address_time_limit'] = 'This IP Address has reached the time limit for this method';//todo translate
+$lang['text_rest_unknown_method'] = 'Méthode inconnue';
+$lang['text_rest_unsupported'] = 'Protocole non-supporté';

+ 11 - 0
application/language/german/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 18 - 0
application/language/german/rest_controller_lang.php

@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * German language
+ */
+
+$lang['text_rest_invalid_api_key'] = 'Ungültiger API Schlüssel %s'; // %s is the REST API key | %s ist der REST API Schlüssel
+$lang['text_rest_invalid_credentials'] = 'Ungültige Zugangsdaten';
+$lang['text_rest_ip_denied'] = 'IP abgelehnt';
+$lang['text_rest_ip_unauthorized'] = 'IP nicht autorisiert';
+$lang['text_rest_unauthorized'] = 'Nicht autorisiert';
+$lang['text_rest_ajax_only'] = 'Nur AJAX-Anfragen zulässig';
+$lang['text_rest_api_key_unauthorized'] = 'Dieser API Schlüssel hat keinen Zugriff auf den angeforderten Controller';
+$lang['text_rest_api_key_permissions'] = 'Dieser API Schlüssel besitzt die erforderlichen Rechte nicht';
+$lang['text_rest_api_key_time_limit'] = 'Dieser API Schlüssel ist abgelaufen';
+$lang['text_rest_ip_address_time_limit'] = 'This IP Address has reached the time limit for this method';//todo translate
+$lang['text_rest_unknown_method'] = 'Unbekannte Methode';
+$lang['text_rest_unsupported'] = 'Protokoll nicht unterstützt';

+ 18 - 0
application/language/greek/rest_controller_lang.php

@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * Greek language
+ */
+
+$lang['text_rest_invalid_api_key'] = 'Λάθος API key %s'; // %s είναι το REST API key
+$lang['text_rest_invalid_credentials'] = 'Μή έγκυρα διαπιστευτήρια';
+$lang['text_rest_ip_denied'] = 'Άρνηση πρόσβασης της διεύθηνσης IP';
+$lang['text_rest_ip_unauthorized'] = 'Μη εξουσιοδοτημένη διεύθυνση IP';
+$lang['text_rest_unauthorized'] = 'Άρνηση Πρόσβασης. Μη εξουσιοδοτημένο';
+$lang['text_rest_ajax_only'] = 'Μόνο AJAX requests επιτρέπονται';
+$lang['text_rest_api_key_unauthorized'] = 'Αυτό το API key δεν έχει πρόσβαση στον συγκεκριμένο controller';
+$lang['text_rest_api_key_permissions'] = 'Αυτό το API key δεν έχει αρκετά δικαιώματα';
+$lang['text_rest_api_key_time_limit'] = 'Αυτό το API key έχει φτάσει στο μέγιστο όριο requests για την συγκεκριμένη μέθοδο';
+$lang['text_rest_ip_address_time_limit'] = 'This IP Address has reached the time limit for this method';//todo translate
+$lang['text_rest_unknown_method'] = 'Άγνωστη μέθοδος';
+$lang['text_rest_unsupported'] = 'Το συγκεκριμένο πρωτόκολλο δεν υποστηρίζεται';

+ 11 - 0
application/language/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 11 - 0
application/language/indonesia/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 18 - 0
application/language/indonesia/rest_controller_lang.php

@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * English language
+ */
+
+$lang['text_rest_invalid_api_key'] = 'Kunci API %s , tidak valid'; // %s is the REST API key
+$lang['text_rest_invalid_credentials'] = 'Hak kredensial tidak valid';
+$lang['text_rest_ip_denied'] = 'IP ditolak';
+$lang['text_rest_ip_unauthorized'] = 'IP tidak diberi kuasa';
+$lang['text_rest_unauthorized'] = 'Tidak diberi kuasa';
+$lang['text_rest_ajax_only'] = 'Hanya AJAX requests yang diperbolehkan';
+$lang['text_rest_api_key_unauthorized'] = 'Kunci API ini tidak memiliki akses ke Controller yang diminta';
+$lang['text_rest_api_key_permissions'] = 'Kunci API ini tidak memiliki izin akses yang cukup';
+$lang['text_rest_api_key_time_limit'] = 'Kunci API ini telah mencapai batas waktu untuk mengakses metode ini';
+$lang['text_rest_ip_address_time_limit'] = 'Alamat API ini telah mencapai batas waktu untuk mengakses metode ini';
+$lang['text_rest_unknown_method'] = 'Metode yang tidak ketahui';
+$lang['text_rest_unsupported'] = 'Protokol tidak mendukung';

+ 11 - 0
application/language/italian/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 16 - 0
application/language/italian/rest_controller_lang.php

@@ -0,0 +1,16 @@
+<?php
+/*
+ * Italian language
+ */
+$lang['text_rest_invalid_api_key'] = 'API key %s non valida'; // %s is the REST API key
+$lang['text_rest_invalid_credentials'] = 'Credenziali non valide';
+$lang['text_rest_ip_denied'] = 'IP non consentito';
+$lang['text_rest_ip_unauthorized'] = 'IP non autorizzato';
+$lang['text_rest_unauthorized'] = 'Non autorizzato';
+$lang['text_rest_ajax_only'] = 'Sono ammesse solo richieste AJAX';
+$lang['text_rest_api_key_unauthorized'] = 'Questa API key non ha accesso al controller richiesto';
+$lang['text_rest_api_key_permissions'] = 'Questa API key non dispone di autorizzazioni sufficienti';
+$lang['text_rest_api_key_time_limit'] = 'Questa API key ha raggiunto il limite di tempo per questo metodo';
+$lang['text_rest_ip_address_time_limit'] = 'Questo indirizzo IP ha raggiunto il limite di tempo per questo metodo';
+$lang['text_rest_unknown_method'] = 'Metodo sconosciuto';
+$lang['text_rest_unsupported'] = 'Protocollo non supportato';

+ 11 - 0
application/language/korean/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 16 - 0
application/language/korean/rest_controller_lang.php

@@ -0,0 +1,16 @@
+<?php
+/*
+ * Korean language
+ */
+$lang['text_rest_invalid_api_key'] = '유효하지 않은 API 키 : %s'; // %s is the REST API key
+$lang['text_rest_invalid_credentials'] = '잘못된 자격 증명';
+$lang['text_rest_ip_denied'] = '허용되지 않은 IP';
+$lang['text_rest_ip_unauthorized'] = '권한이 없는 IP';
+$lang['text_rest_unauthorized'] = '권한이 없음';
+$lang['text_rest_ajax_only'] = 'Ajax 요청만 허용됩니다.';
+$lang['text_rest_api_key_unauthorized'] = '해당 API 키는 요청된 컨트롤러에 접근되지 않습니다.';
+$lang['text_rest_api_key_permissions'] = '해당 API 키는 권한이 없습니다.';
+$lang['text_rest_api_key_time_limit'] = '해당 API 키는 메서드의 시간 제한에 도달했습니다.';
+$lang['text_rest_ip_address_time_limit'] = '해당 IP 주소는 메서드의 시간 제한에 도달했습니다.';
+$lang['text_rest_unknown_method'] = '알 수 없는 메서드입니다.';
+$lang['text_rest_unsupported'] = '지원하지 않는 프로토콜입니다.';

+ 11 - 0
application/language/portuguese-brazilian/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 18 - 0
application/language/portuguese-brazilian/rest_controller_lang.php

@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * Brazilian portuguese language
+ */
+
+$lang['text_rest_invalid_api_key'] = 'Chave da API %s inválida'; // %s is the REST API key
+$lang['text_rest_invalid_credentials'] = 'Credenciais inválidas';
+$lang['text_rest_ip_denied'] = 'IP proibido';
+$lang['text_rest_ip_unauthorized'] = 'IP não autorizado';
+$lang['text_rest_unauthorized'] = 'Não autorizado';
+$lang['text_rest_ajax_only'] = 'Apenas chamadas AJAX são permitidas';
+$lang['text_rest_api_key_unauthorized'] = 'Esta chave da API não tem acesso ao controller solicitado';
+$lang['text_rest_api_key_permissions'] = 'Esta chave da API não tem permissões suficientes';
+$lang['text_rest_api_key_time_limit'] = 'Esta chave da API já atingiu o tempo limite para este método';
+$lang['text_rest_ip_address_time_limit'] = 'Este Endereço IP atingiu o limite de tempo para este método';
+$lang['text_rest_unknown_method'] = 'Método desconhecido';
+$lang['text_rest_unsupported'] = 'Sem suporte para este protocolo';

+ 11 - 0
application/language/romanian/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 18 - 0
application/language/romanian/rest_controller_lang.php

@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * Romanian language
+ */
+
+$lang['text_rest_invalid_api_key'] = 'Cheie API invalidă %s'; // %s is the REST API key
+$lang['text_rest_invalid_credentials'] = 'Acreditări invalide';
+$lang['text_rest_ip_denied'] = 'IP respins';
+$lang['text_rest_ip_unauthorized'] = 'IP neautorizat';
+$lang['text_rest_unauthorized'] = 'Neautorizat';
+$lang['text_rest_ajax_only'] = 'Doar cererile AJAX sunt acceptate';
+$lang['text_rest_api_key_unauthorized'] = 'Această cheie API nu are acees la controller-ul solicitat';
+$lang['text_rest_api_key_permissions'] = 'Această cheie API nu are suficiente permisiuni';
+$lang['text_rest_api_key_time_limit'] = 'Această cheie API a atins limita de timp pentru această metodă';
+$lang['text_rest_ip_address_time_limit'] = 'This IP Address has reached the time limit for this method';//todo translate
+$lang['text_rest_unknown_method'] = 'Metodă necunoscută';
+$lang['text_rest_unsupported'] = 'Protocol neacceptat';

+ 11 - 0
application/language/serbian_cyr/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 18 - 0
application/language/serbian_cyr/rest_controller_lang.php

@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * Serbian language
+ */
+
+$lang['text_rest_invalid_api_key'] = 'Неправилан *API* кључ %s'; // %s је *REST API* кључ
+$lang['text_rest_invalid_credentials'] = 'Неодговарајући кориснички улазни подаци';
+$lang['text_rest_ip_denied'] = '*IP* одбијен';
+$lang['text_rest_ip_unauthorized'] = '*IP* неауторизован';
+$lang['text_rest_unauthorized'] = 'Неауторизовано';
+$lang['text_rest_ajax_only'] = 'Једино *AJAX* захтеви су дозвољени';
+$lang['text_rest_api_key_unauthorized'] = 'Овај *API* кључ нема овлашћења за захтевани контролер';
+$lang['text_rest_api_key_permissions'] = 'Овај *API* кључ нема дозвољен степен овлашћења';
+$lang['text_rest_api_key_time_limit'] = 'Овај *API* кључ је прекорачио временски лимит за дати метод';
+$lang['text_rest_ip_address_time_limit'] = 'Ова *IP* адреса је прекорачила временски лимит за дати метод';//todo translate
+$lang['text_rest_unknown_method'] = 'Непознат метод';
+$lang['text_rest_unsupported'] = 'Неподржан протокол';

+ 11 - 0
application/language/serbian_lat/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 18 - 0
application/language/serbian_lat/rest_controller_lang.php

@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * Serbian language
+ */
+
+$lang['text_rest_invalid_api_key'] = 'Nepravilan API klju&#269; %s'; // %s je REST API ključ
+$lang['text_rest_invalid_credentials'] = 'Neodgovaraju&#263;i korisni&#269;ki ulazni podaci';
+$lang['text_rest_ip_denied'] = 'IP odbijen';
+$lang['text_rest_ip_unauthorized'] = 'IP neautorizovan';
+$lang['text_rest_unauthorized'] = 'Neautorizovano';
+$lang['text_rest_ajax_only'] = 'Jedino AJAX zahtevi su dozvoljeni';
+$lang['text_rest_api_key_unauthorized'] = 'Ovaj API klju&#269; nema ovla&#353;&#263;enje za zahtevani kontroler';
+$lang['text_rest_api_key_permissions'] = 'Ovaj API klju&#269; nema dozvoljen stepen ovla&#353;&#263;enja';
+$lang['text_rest_api_key_time_limit'] = 'Ovaj API klju&#269; je prekora&#269;io vremenski limit za dati metod';
+$lang['text_rest_ip_address_time_limit'] = 'Ova IP adresa je prekora&#269;ila vremenski limit za dati metod';
+$lang['text_rest_unknown_method'] = 'Nepoznat metod';
+$lang['text_rest_unsupported'] = 'Nepodr&#382;an protokol';

+ 11 - 0
application/language/simplified-chinese/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 18 - 0
application/language/simplified-chinese/rest_controller_lang.php

@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * Simple Chinese language
+ */
+
+$lang['text_rest_invalid_api_key'] = '无效的 API key %s'; // %s is the REST API key
+$lang['text_rest_invalid_credentials'] = '无效的凭证';
+$lang['text_rest_ip_denied'] = 'IP 地址被拒绝';
+$lang['text_rest_ip_unauthorized'] = 'IP 地址未认证';
+$lang['text_rest_unauthorized'] = '未认证';
+$lang['text_rest_ajax_only'] = '只允许 AJAX 类型的请求';
+$lang['text_rest_api_key_unauthorized'] = '此 API key无法存取指定的 controller';
+$lang['text_rest_api_key_permissions'] = '此 API key没有足够的权限';
+$lang['text_rest_api_key_time_limit'] = '此 API key已经超过有效期限';
+$lang['text_rest_ip_address_time_limit'] = 'This IP Address has reached the time limit for this method';//todo translate
+$lang['text_rest_unknown_method'] = '未知的方法';
+$lang['text_rest_unsupported'] = '不支持的请求方法';

+ 11 - 0
application/language/spanish/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 18 - 0
application/language/spanish/rest_controller_lang.php

@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * Spanish language
+ */
+
+$lang['text_rest_invalid_api_key'] = 'API key %s No válida'; // %s is the REST API key
+$lang['text_rest_invalid_credentials'] = 'Credenciales Inválidas';
+$lang['text_rest_ip_denied'] = 'IP denegada';
+$lang['text_rest_ip_unauthorized'] = 'IP no autorizada';
+$lang['text_rest_unauthorized'] = 'Acceso no autorizado';
+$lang['text_rest_ajax_only'] = 'Sólo peticiones ajax permitidas';
+$lang['text_rest_api_key_unauthorized'] = 'Esta clave de API no tiene acceso al controlador solicitado';
+$lang['text_rest_api_key_permissions'] = 'Esta clave de API no tiene suficientes permisos';
+$lang['text_rest_api_key_time_limit'] = 'Esta clave de API ha alcanzado el límite de tiempo para este método';
+$lang['text_rest_ip_address_time_limit'] = 'Esta dirección IP ha alcanzado el límite de tiempo para este método';//todo translate
+$lang['text_rest_unknown_method'] = 'Método desconocido';
+$lang['text_rest_unsupported'] = 'Protocolo no soportado';

+ 11 - 0
application/language/traditional-chinese/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 18 - 0
application/language/traditional-chinese/rest_controller_lang.php

@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * Traditional Chinese language
+ */
+
+$lang['text_rest_invalid_api_key'] = '無效的 API 金鑰 %s'; // %s is the REST API key
+$lang['text_rest_invalid_credentials'] = '無效的憑證';
+$lang['text_rest_ip_denied'] = 'IP 位置被拒絕';
+$lang['text_rest_ip_unauthorized'] = 'IP 位置未認證';
+$lang['text_rest_unauthorized'] = '未認證';
+$lang['text_rest_ajax_only'] = '只有 AJAX 類型請求被允許';
+$lang['text_rest_api_key_unauthorized'] = '這個 API 金鑰沒有辦法存取指定的 controller';
+$lang['text_rest_api_key_permissions'] = '這個 API 金鑰沒有具備足夠權限';
+$lang['text_rest_api_key_time_limit'] = '這個 API 金鑰已經超過有效期限';
+$lang['text_rest_ip_address_time_limit'] = '這個 IP 位置的流量已經超過上限';
+$lang['text_rest_unknown_method'] = '未知的方法';
+$lang['text_rest_unsupported'] = '不支援的通訊協定';

+ 11 - 0
application/language/turkish/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 18 - 0
application/language/turkish/rest_controller_lang.php

@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * Turkish language
+ */
+
+$lang['text_rest_invalid_api_key'] = 'Geçersiz API anahtarı %s'; // %s is the REST API key
+$lang['text_rest_invalid_credentials'] = 'Geçersiz kimlik';
+$lang['text_rest_ip_denied'] = 'IP reddedildi';
+$lang['text_rest_ip_unauthorized'] = 'Yetkisiz IP';
+$lang['text_rest_unauthorized'] = 'İzinsiz';
+$lang['text_rest_ajax_only'] = 'Sadece AJAX isteklerine izin verildi';
+$lang['text_rest_api_key_unauthorized'] = 'Ulaşılmak istenilen controllera API anahtarının erişim yetkisi bulunmamaktadır';
+$lang['text_rest_api_key_permissions'] = 'Bu API anahtarının yeterli yetkisi bulunmamaktadır';
+$lang['text_rest_api_key_time_limit'] = 'API anahtarı bu metod için zaman sınırına ulaştı.';
+$lang['text_rest_ip_address_time_limit'] = 'IP adresi bu metod için zaman sınırına ulaştı.';
+$lang['text_rest_unknown_method'] = 'Bilinmeyen metod';
+$lang['text_rest_unsupported'] = 'Desteklenmeyen protokol';

+ 85 - 0
application/libraries/Aliyunsms.php

@@ -0,0 +1,85 @@
+<?php
+require_once  'api_sdk/vendor/autoload.php';
+use Aliyun\Core\Config;
+use Aliyun\Core\Profile\DefaultProfile;
+use Aliyun\Core\DefaultAcsClient;
+use Aliyun\Api\Sms\Request\V20170525\SendSmsRequest;
+use Aliyun\Api\Sms\Request\V20170525\SendBatchSmsRequest;
+use Aliyun\Api\Sms\Request\V20170525\QuerySendDetailsRequest;
+
+// 加载区域结点配置
+Config::load();
+
+/**
+ * Class Aliyunsms
+ *
+ * 阿里云短信发送
+ */
+class Aliyunsms
+{
+    private $CI;
+    private $setting;
+	
+    static $acsClient = null;
+
+    function __construct()
+    {
+        $this->CI = & get_instance();
+        $this->CI->load->driver('cache', array('adapter' => 'apc', 'backup' => 'file'));
+        $this->setting = $this->CI->cache->get('setting');
+    }
+
+    /**
+     * 取得AcsClient
+     *
+     * @return DefaultAcsClient
+     */
+    private function getAcsClient() {
+        //产品名称:云通信流量服务API产品,开发者无需替换
+        $product = "Dysmsapi";
+        //产品域名,开发者无需替换
+        $domain = "dysmsapi.aliyuncs.com";
+        $accessKeyId = $this->setting['access_key_id']; // AccessKeyId
+        $accessKeySecret = $this->setting['access_key_secret'];; // AccessKeySecret
+        // 暂时不支持多Region
+        $region = "cn-hangzhou";
+        // 服务结点
+        $endPointName = "cn-hangzhou";
+        if(static::$acsClient == null) {
+            //初始化acsClient,暂不支持region化
+            $profile = DefaultProfile::getProfile($region, $accessKeyId, $accessKeySecret);
+            // 增加服务结点
+            DefaultProfile::addEndpoint($endPointName, $region, $product, $domain);
+            // 初始化AcsClient用于发起请求
+            static::$acsClient = new DefaultAcsClient($profile);
+        }
+        return static::$acsClient;
+    }
+
+    /**
+     * 发送短信
+     * @return stdClass
+     */
+    public function sendSms($phone,$template_code,$content) {
+        if(is_array($content)){
+            // 初始化SendSmsRequest实例用于设置发送短信的参数
+            $request = new SendSmsRequest();
+            //可选-启用https协议
+            //$request->setProtocol("https");
+            // 必填,设置短信接收号码
+            $request->setPhoneNumbers($phone);
+            // 必填,设置签名名称,应严格按"签名名称"填写,请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/sign
+            $request->setSignName($this->setting['sign_name']);
+            // 必填,设置模板CODE,应严格按"模板CODE"填写, 请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/template
+            $request->setTemplateCode($template_code);
+            // 可选,设置模板参数, 假如模板中存在变量需要替换则为必填项
+            $request->setTemplateParam(json_encode($content), JSON_UNESCAPED_UNICODE);
+            // 发起访问请求
+            $acsResponse = $this->getAcsClient()->getAcsResponse($request);
+            return (array)$acsResponse;
+        }else{
+            return array("Code"=>0,"msg"=>"参数错误");
+        }
+    }
+
+}

+ 25 - 0
application/libraries/Ci_smarty.php

@@ -0,0 +1,25 @@
+<?php
+if (!defined('BASEPATH')) {
+    exit('No direct script access allowed');
+}
+require_once APPPATH.'libraries/smarty/Smarty.class.php';
+class Ci_smarty extends Smarty
+{
+    protected $ci;
+    public function __construct()
+    {
+        parent::__construct();
+        $this -> ci =& get_instance();
+        $this -> ci -> load -> config('smarty');
+        //加载smarty的配置文件
+        $this -> cache_lifetime = $this -> ci -> config -> item('cache_lifetime');
+        $this -> caching = $this -> ci -> config -> item('caching');
+        $this -> config_dir = $this -> ci -> config -> item('config_dir');
+        $this -> template_dir = $this -> ci -> config -> item('template_dir');
+        $this -> compile_dir = $this -> ci -> config -> item('compile_dir');
+        $this -> cache_dir = $this -> ci -> config -> item('cache_dir');
+        $this -> use_sub_dirs = $this -> ci -> config -> item('use_sub_dirs');
+        $this -> left_delimiter = $this -> ci -> config -> item('left_delimiter');
+        $this -> right_delimiter = $this -> ci -> config -> item('right_delimiter');
+    }
+}

+ 291 - 0
application/libraries/MY_pagination.php

@@ -0,0 +1,291 @@
+<?php
+if (!defined('BASEPATH')) {
+    exit('No direct script access allowed');
+}
+
+require_once SYSDIR."/libraries/Pagination.php";
+class MY_pagination extends CI_Pagination{
+
+    protected $page_count;
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * 获取总页数
+     */
+    public function get_page_count(){
+        return $this->page_count;
+    }
+
+    /**
+     * 生成分页连接
+     *
+     * @return	string
+     */
+    public function create_pages()
+    {
+        $this->page_count = (int) ceil($this->total_rows / $this->per_page);
+
+        if ($this->total_rows == 0 OR $this->per_page == 0)
+        {
+            return '';
+        }
+
+        // Calculate the total number of pages
+        $num_pages = $this->page_count;
+
+        // Check the user defined number of links.
+        $this->num_links = (int) $this->num_links;
+
+        if ($this->num_links < 0)
+        {
+            show_error('Your number of links must be a non-negative number.');
+        }
+
+        // Keep any existing query string items.
+        // Note: Has nothing to do with any other query string option.
+        if ($this->reuse_query_string === TRUE)
+        {
+            $get = $this->CI->input->get();
+
+            // Unset the control, method, old-school routing options
+            unset($get['c'], $get['m'], $get[$this->query_string_segment]);
+        }
+        else
+        {
+            $get = array();
+        }
+
+        // Put together our base and first URLs.
+        // Note: DO NOT append to the properties as that would break successive calls
+        $base_url = trim($this->base_url);
+        $first_url = $this->first_url;
+
+        $query_string = '';
+        $query_string_sep = (strpos($base_url, '?') === FALSE) ? '?' : '&amp;';
+
+        // Are we using query strings?
+        if ($this->page_query_string === TRUE)
+        {
+            // If a custom first_url hasn't been specified, we'll create one from
+            // the base_url, but without the page item.
+            if ($first_url === '')
+            {
+                $first_url = $base_url;
+
+                // If we saved any GET items earlier, make sure they're appended.
+                if ( ! empty($get))
+                {
+                    $first_url .= $query_string_sep.http_build_query($get);
+                }
+            }
+
+            // Add the page segment to the end of the query string, where the
+            // page number will be appended.
+            $base_url .= $query_string_sep.http_build_query(array_merge($get, array($this->query_string_segment => '')));
+        }
+        else
+        {
+            // Standard segment mode.
+            // Generate our saved query string to append later after the page number.
+            if ( ! empty($get))
+            {
+                $query_string = $query_string_sep.http_build_query($get);
+                $this->suffix .= $query_string;
+            }
+
+            // Does the base_url have the query string in it?
+            // If we're supposed to save it, remove it so we can append it later.
+            if ($this->reuse_query_string === TRUE && ($base_query_pos = strpos($base_url, '?')) !== FALSE)
+            {
+                $base_url = substr($base_url, 0, $base_query_pos);
+            }
+
+            if ($first_url === '')
+            {
+                $first_url = $base_url.$query_string;
+            }
+
+            $base_url = rtrim($base_url, '/').'/';
+        }
+
+        // Determine the current page number.
+        $base_page = ($this->use_page_numbers) ? 1 : 0;
+
+        // Are we using query strings?
+        if ($this->page_query_string === TRUE)
+        {
+            $this->cur_page = $this->CI->input->get($this->query_string_segment);
+        }
+        elseif (empty($this->cur_page))
+        {
+            // Default to the last segment number if one hasn't been defined.
+            if ($this->uri_segment === 0)
+            {
+                $this->uri_segment = count($this->CI->uri->segment_array());
+            }
+
+            $this->cur_page = $this->CI->uri->segment($this->uri_segment);
+
+            // Remove any specified prefix/suffix from the segment.
+            if ($this->prefix !== '' OR $this->suffix !== '')
+            {
+                $this->cur_page = str_replace(array($this->prefix, $this->suffix), '', $this->cur_page);
+            }
+        }
+        else
+        {
+            $this->cur_page = (string) $this->cur_page;
+        }
+
+        // If something isn't quite right, back to the default base page.
+        if ( ! ctype_digit($this->cur_page) OR ($this->use_page_numbers && (int) $this->cur_page === 0))
+        {
+            $this->cur_page = $base_page;
+        }
+        else
+        {
+            // Make sure we're using integers for comparisons later.
+            $this->cur_page = (int) $this->cur_page;
+        }
+
+        // Is the page number beyond the result range?
+        // If so, we show the last page.
+        if ($this->use_page_numbers)
+        {
+            if ($this->cur_page > $num_pages)
+            {
+                $this->cur_page = $num_pages;
+            }
+        }
+        elseif ($this->cur_page > $this->total_rows)
+        {
+            $this->cur_page = ($num_pages - 1) * $this->per_page;
+        }
+
+        $uri_page_number = $this->cur_page;
+
+        // If we're using offset instead of page numbers, convert it
+        // to a page number, so we can generate the surrounding number links.
+        if ( ! $this->use_page_numbers)
+        {
+            $this->cur_page = (int) floor(($this->cur_page/$this->per_page) + 1);
+        }
+
+        // Calculate the start and end numbers. These determine
+        // which number to start and end the digit links with.
+        $start	= (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1;
+        $end	= (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages;
+
+        // And here we go...
+        $output = '';
+
+        // Render the "First" link.
+        if ($this->first_link !== FALSE )
+        {
+            // Take the general parameters, and squeeze this pagination-page attr in for JS frameworks.
+            if($this->cur_page == 1){
+                $output .= '<li class="disabled"><a href="javascript:;" style="line-height: 26px">'
+                    . $this->first_link . '</a>' . $this->first_tag_close;
+            }else {
+                $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, 1);
+                $output .= $this->first_tag_open . '<a style="line-height: 26px" href="' . $first_url . '"' . $attributes . $this->_attr_rel('start') . '>'
+                    . $this->first_link . '</a>' . $this->first_tag_close;
+            }
+        }
+
+        // Render the "Previous" link.
+        if ($this->prev_link !== FALSE )
+        {
+            if($this->cur_page == 1){
+                $output .= '<li class="disabled"><a href="javascript:;">'
+                    . $this->prev_link . '</a>' . $this->prev_tag_close;
+            }else {
+                $i = ($this->use_page_numbers) ? $uri_page_number - 1 : $uri_page_number - $this->per_page;
+
+                $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, ($this->cur_page - 1));
+
+                if ($i === $base_page) {
+                    // First page
+                    $output .= $this->prev_tag_open . '<a href="' . $first_url . '"' . $attributes . $this->_attr_rel('prev') . '>'
+                        . $this->prev_link . '</a>' . $this->prev_tag_close;
+                } else {
+                    $append = $this->prefix . $i . $this->suffix;
+                    $output .= $this->prev_tag_open . '<a href="' . $base_url . $append . '"' . $attributes . $this->_attr_rel('prev') . '>'
+                        . $this->prev_link . '</a>' . $this->prev_tag_close;
+                }
+            }
+
+        }
+
+        // Render the pages
+        if ($this->display_pages !== FALSE)
+        {
+            // Write the digit links
+            for ($loop = $start - 1; $loop <= $end; $loop++)
+            {
+                $i = ($this->use_page_numbers) ? $loop : ($loop * $this->per_page) - $this->per_page;
+
+                $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, $loop);
+
+                if ($i >= $base_page)
+                {
+                    if ($this->cur_page === $loop)
+                    {
+                        // Current page
+                        $output .= $this->cur_tag_open.$loop.$this->cur_tag_close;
+                    }
+                    elseif ($i === $base_page)
+                    {
+                        // First page
+                        $output .= $this->num_tag_open.'<a href="'.$first_url.'"'.$attributes.$this->_attr_rel('start').'>'
+                            .$loop.'</a>'.$this->num_tag_close;
+                    }
+                    else
+                    {
+                        $append = $this->prefix.$i.$this->suffix;
+                        $output .= $this->num_tag_open.'<a href="'.$base_url.$append.'"'.$attributes.'>'
+                            .$loop.'</a>'.$this->num_tag_close;
+                    }
+                }
+            }
+        }
+
+        // Render the "next" link
+        if ($this->next_link !== FALSE)
+        {
+            $i = ($this->use_page_numbers) ? $this->cur_page + 1 : $this->cur_page * $this->per_page;
+            if($this->cur_page == $num_pages){
+                $output .= '<li class="disabled"><a href="javascript:;" >' . $this->next_link . '</a>' . $this->next_tag_close;
+            }else {
+                $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, $this->cur_page + 1);
+                $output .= $this->next_tag_open . '<a href="' . $base_url . $this->prefix . $i . $this->suffix . '"' . $attributes
+                    . $this->_attr_rel('next') . '>' . $this->next_link . '</a>' . $this->next_tag_close;
+            }
+        }
+
+        // Render the "Last" link
+        if ($this->last_link !== FALSE)
+        {
+            if($this->cur_page == $num_pages) {
+                $output .= '<li class="disabled"><a href="javascript:;" style="line-height: 26px">'. $this->last_link . '</a>' . $this->last_tag_close;
+            }else {
+                $i = ($this->use_page_numbers) ? $num_pages : ($num_pages * $this->per_page) - $this->per_page;
+                $attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, $num_pages);
+                $output .= $this->last_tag_open . '<a style="line-height: 26px" href="' . $base_url . $this->prefix . $i . $this->suffix . '"' . $attributes . '>'
+                    . $this->last_link . '</a>' . $this->last_tag_close;
+            }
+        }
+
+        // Kill double slashes. Note: Sometimes we can end up with a double slash
+        // in the penultimate link so we'll kill all double slashes.
+        $output = preg_replace('#([^:"])//+#', '\\1/', $output);
+
+        // Add the wrapper HTML if exists
+        return $this->full_tag_open.$output.$this->full_tag_close;
+    }
+
+}

+ 69 - 0
application/libraries/Mailer.php

@@ -0,0 +1,69 @@
+<?php
+if (!defined('BASEPATH')) exit('No direct script access allowed');
+
+require_once "PHPMail/PHPMailerAutoload.php";
+class Mailer
+{
+    var $mail;
+
+    public function __construct()
+    {
+        $this->mail = new PHPMailer();
+    }
+
+    public function set_config($config){
+        $this->mail->IsSMTP(); // telling the class to use SMTP
+        $this->mail->CharSet = "utf-8";                  // 一定要設定 CharSet 才能正确处理中文
+        $this->mail->SMTPDebug = 0;                     // enables SMTP debug information
+        $this->mail->SMTPAuth = true;                  // enable SMTP authentication
+        $this->mail->SMTPSecure = $config['smtp_secure'];                 // sets the prefix to the servier
+        $this->mail->Host = $config['server'];      // sets GMAIL as the SMTP server
+        $this->mail->Port = $config['port'];                   // set the SMTP port for the GMAIL server
+        $this->mail->Username = $config['sender'];
+        $this->mail->Password = $config['secret_key'];
+        $this->mail->AddReplyTo($config['sender']);
+        $this->mail->SetFrom($config['sender']);
+        $this->mail->isHTML(true);
+    }
+
+    public function add_recipient($recipient){
+        $this->mail->AddAddress($recipient);
+    }
+
+    /**
+     * 发送邮件
+     * @param $recipient
+     * @param $subject
+     * @param $content
+     * @param null $attachments
+     * @return bool
+     */
+    public function send_email($recipient,$subject,$content,$attachments=null){
+        try{
+            if($recipient) {
+                $this->mail->AddAddress($recipient);
+            }
+            $this->mail->Subject = $subject;
+            $this->mail->Body    = $content;
+            if($attachments){
+                if(is_array($attachments)){
+                    foreach($attachments as $k=>$val){
+                        $this->mail->addAttachment($val);
+                    }
+                }else{
+                    $this->mail->addAttachment($attachments);
+                }
+            }
+            if($this->mail->Send()) {
+                return true;
+            }else{
+                show_error($this->mail->ErrorInfo);
+                return false;
+            }
+        } catch (phpmailerException $e) {
+            show_error($e->errorMessage(),500); //Pretty error messages from PHPMailer
+        } catch (Exception $e) {
+            show_error($e->getMessage(),500); //Boring error messages from anything else!
+        }
+    }
+}

Різницю між файлами не показано, бо вона завелика
+ 1064 - 0
application/libraries/Mongo_db.php


+ 620 - 0
application/libraries/Notices.php

@@ -0,0 +1,620 @@
+<?php
+if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+require_once("Aliyunsms.php");
+/**
+ * 消息发送类
+ * Class Notices
+ */
+class Notices{
+
+    private $CI;
+    private $setting;
+    private $Aliyunsms;
+
+    public $warning_type = array(
+        "10" => "失陷事件",
+        "20" => "脆弱性",
+        "30" => "残余攻击"
+    );
+
+    public $warning_level = array(
+        "10" => "已失陷",
+        "20" => "高可疑",
+        "30" => "低可疑",
+        "40" => "高危",
+        "50" => "中危",
+        "60" => "低危"
+    );
+
+    function __construct()
+    {
+        $this->CI = & get_instance();
+        $this->CI->load->driver('cache', array('adapter' => 'apc', 'backup' => 'file'));
+        $this->setting = $this->CI->cache->get('setting');
+        $this->CI->load->helper(array('sms','date'));
+        $this->CI->load->library('mailer');
+        $this->CI->mailer->set_config($this->setting);
+        $this->CI->load->model("noticeslog_model");
+        $this->CI->load->model("user_model");
+        if($this->setting['is_sms'] == "1" && $this->setting['sms_type'] == '20' && $this->setting['product'] =='Dysmsapi'){
+            $this->Aliyunsms = new Aliyunsms();
+        }
+    }
+
+    /**
+     * 生成工单
+     * @param $workorder
+     */
+    public function create_workorder($workorder){
+        $receive_user = $this->CI->user_model->get_user_with_user_id($workorder['receive_user_id']);
+        if($this->setting['is_sms'] && in_array("10",$workorder['send_type'])){
+            $sms_content = '你有新工单需要处理,工单ID:'.$workorder['workorder_id'].',工单名称:'.$workorder['workorder_name'].',类型:'.$workorder['type'].',备注:'.$workorder['remark_list'][count($workorder['remark_list'])-1]['remark_content'];
+            $notices_log = $this->CI->noticeslog_model->get_model();
+            $notices_log['log_id'] = $this->create_id();
+            $notices_log['type'] = "sms";
+            $notices_log['mobile'] = $receive_user['mobile'];
+            $notices_log['content'] = $sms_content;
+            if($this->setting['sms_type'] == '10' ){
+                if(send_by_modem($this->setting,$receive_user['mobile'],$sms_content)){
+                    $notices_log['status'] = "1";
+                }else{
+                    $notices_log['status'] = "0";
+                }
+            }elseif($this->setting['sms_type'] == '20' ){
+                $sms_content = array(
+                    "workorder_id"=>$workorder['workorder_id'],
+                    "workorder_name"=>$workorder['workorder_name'],
+                    "workorder_type"=>$workorder['type'],
+                    "remark_content"=>$workorder['remark_list'][count($workorder['remark_list'])-1]['remark_content']
+                );
+                $resp = $this->Aliyunsms->sendSms($receive_user['mobile'],$this->setting['template_codes'][0],$sms_content);
+                if($resp['Code'] == 'OK'){
+                    $notices_log['status'] = "1";
+                }else{
+                    $notices_log['status'] = "0";
+                }
+            }
+            $notices_log['create_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+            $this->CI->noticeslog_model->save_notices_log($notices_log);
+        }
+        if($this->setting['is_email'] && in_array("20",$workorder['send_type'])){
+            $notices_log = $this->CI->noticeslog_model->get_model();
+            $notices_log['log_id'] = $this->create_id();
+            $notices_log['type'] = "email";
+            $notices_log['recipient'] = $receive_user['email'];
+            $notices_log['subject'] = "系统有新工单请处理,工单ID:".$workorder['workorder_id'];
+            $email_content = '<div style="font-size:12px;">';
+            $email_content .='<p style="white-space: normal; background-color: rgb(255, 255, 255);">'.$receive_user['name'].',您好!</p>';
+            $email_content .='<p style="white-space: normal; background-color: rgb(255, 255, 255); text-indent: 2em;">系统有新工单请处理:</p>';
+            $email_content .='<table align="left" border="1" cellspacing="0" cellpadding="0" style="font-size:12px;"><thead>';
+            $email_content .='<tr class="firstRow"><td valign="top" rowspan="1" colspan="5" style="word-break: break-all;">';
+            $email_content .='<strong>工单ID:'.$workorder['workorder_id'].'</strong><strong>工单名称:'.$workorder['workorder_name'].'</strong>';
+            $email_content .='</td></tr>';
+            $email_content .='<tr>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>工单名称</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>类型</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>等级</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>时间</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>告警详情</strong></th>';
+            $email_content .='</tr></thead><tbody>';
+            foreach($workorder['warning_list'] as $key=>$val) {
+                $email_content .= '<tr>';
+                $email_content .= '<td valign="top" colspan="1" rowspan="1">'.$val['warning_name'].'</td>';
+                $email_content .= '<td valign="middle" colspan="1" rowspan="1" align="center">'.$this->warning_type[$val['type']].'</td>';
+                $email_content .= '<td valign="middle" colspan="1" rowspan="1" align="center">'.$this->warning_level[$val['level']].'</td>';
+                $email_content .= '<td valign="middle" colspan="1" rowspan="1" align="center">'.date("Y-m-d H:i:s",$val['create_time']->toDateTime()->getTimestamp()).'</td>';
+                $email_content .= '<td valign="top" colspan="1" rowspan="1">'.$val['content'].'</td>';
+                $email_content .= '</tr>';
+            }
+            $email_content .='<tr>';
+            $email_content .='<td valign="top" rowspan="1" colspan="5" style="word-break: break-all;"><strong>备注:</strong>'.$workorder['remark_list'][count($workorder['remark_list'])-1]['remark_content'].'</td>';
+            $email_content .='</tr>';
+            $email_content .='</tbody></table>';
+            $email_content .='<p><br/>&nbsp;</p><p><br/>&nbsp;</p>';
+            $email_content .='<p style="text-align: right;">系统管理员&nbsp;&nbsp;<br>';
+            $email_content .=date("Y年m月d日",time()).'</p>';
+            $email_content .='</div>';
+            $notices_log['content'] = $email_content;
+            if($this->CI->mailer->send_email($receive_user['email'],$notices_log['subject'],$notices_log['content'])){
+                $notices_log['status'] = "1";
+            }else{
+                $notices_log['status'] = "0";
+            }
+            $notices_log['create_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+            $this->CI->noticeslog_model->save_notices_log($notices_log);
+        }
+    }
+
+    /**
+     * 签收工单
+     * @param $workorder
+     * @param $remark
+     */
+    public function sign_workorder($workorder,$remark){
+        $receive_user = $this->CI->user_model->get_user_with_user_id($workorder['receive_user_id']);
+        $admin_list = $this->CI->user_model->select_users("1");
+        $sso_admin_list = $this->CI->user_model->set_collection_name("sso_users")->select_users("1");
+        $mobiles = array();
+        $emails = array();
+        foreach ($admin_list as $key => $val){
+            $mobiles[] = $val['mobile'];
+            $emails[] = $val['email'];
+        }
+        foreach ($sso_admin_list as $key => $val){
+            $mobiles[] = $val['mobile'];
+            $emails[] = $val['email'];
+        }
+        if($this->setting['is_sms'] && in_array("10",$workorder['send_type'])){
+            $sms_content = '工单ID:'.$workorder['workorder_id'].',工单名称:'.$workorder['workorder_name'].',类型:'.$workorder['type'].',已由责任人'.$receive_user['name'].'签收,备注:'.$remark['remark_content'];
+            for($i = 0;$i<count($mobiles);$i++) {
+                $notices_log = $this->CI->noticeslog_model->get_model();
+                $notices_log['type'] = "sms";
+                $notices_log['content'] = $sms_content;
+                $notices_log['log_id'] = $this->create_id();
+                $notices_log['mobile'] = $mobiles[$i];
+                if($this->setting['sms_type'] == '10' ){
+                    if(send_by_modem($this->setting, $notices_log['mobile'], $sms_content)){
+                        $notices_log['status'] = "1";
+                    }else{
+                        $notices_log['status'] = "0";
+                    }
+                }elseif($this->setting['sms_type'] == '20' ){
+                    $sms_content = array(
+                        "workorder_id"=>$workorder['workorder_id'],
+                        "workorder_name"=>$workorder['workorder_name'],
+                        "workorder_type"=>$workorder['type'],
+                        "receive_user_name"=>$receive_user['name'],
+                        "remark_content"=>$workorder['remark_list'][count($workorder['remark_list'])-1]['remark_content']
+                    );
+                    $resp = $this->Aliyunsms->sendSms($notices_log['mobile'],$this->setting['template_codes'][1],$sms_content);
+                    if($resp['Code'] == 'OK'){
+                        $notices_log['status'] = "1";
+                    }else{
+                        $notices_log['status'] = "0";
+                    }
+                }
+                $notices_log['create_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+                $this->CI->noticeslog_model->save_notices_log($notices_log);
+            }
+        }
+        if($this->setting['is_email'] && in_array("20",$workorder['send_type'])){
+            $notices_log = $this->CI->noticeslog_model->get_model();
+            $notices_log['log_id'] = $this->create_id();
+            $notices_log['type'] = "email";
+            $notices_log['subject'] = "工单ID:".$workorder['workorder_id']."已由责任人:".$receive_user['name']."签收";
+            $email_content = '<div style="font-size:12px;">';
+            $email_content .='<p style="white-space: normal; background-color: rgb(255, 255, 255);">系统管理员,您好!</p>';
+            $email_content .='<p style="white-space: normal; background-color: rgb(255, 255, 255); text-indent: 2em;">以下工单已由责任人:'.$receive_user['name'].'签收:</p>';
+            $email_content .='<table align="left" border="1" cellspacing="0" cellpadding="0" style="font-size:12px;"><thead>';
+            $email_content .='<tr class="firstRow"><td valign="top" rowspan="1" colspan="5" style="word-break: break-all;">';
+            $email_content .='<strong>工单ID:'.$workorder['workorder_id'].'</strong><strong>工单名称:'.$workorder['workorder_name'].'</strong>';
+            $email_content .='</td></tr>';
+            $email_content .='<tr>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>工单名称</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>类型</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>等级</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>时间</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>告警详情</strong></th>';
+            $email_content .='</tr></thead><tbody>';
+            foreach($workorder['warning_list'] as $key=>$val) {
+                $email_content .= '<tr>';
+                $email_content .= '<td valign="top" colspan="1" rowspan="1">'.$val['warning_name'].'</td>';
+                $email_content .= '<td valign="middle" colspan="1" rowspan="1" align="center">'.$this->warning_type[$val['type']].'</td>';
+                $email_content .= '<td valign="middle" colspan="1" rowspan="1" align="center">'.$this->warning_level[$val['level']].'</td>';
+                $email_content .= '<td valign="middle" colspan="1" rowspan="1" align="center">'.date("Y-m-d H:i:s",$val['create_time']->toDateTime()->getTimestamp()).'</td>';
+                $email_content .= '<td valign="top" colspan="1" rowspan="1">'.$val['content'].'</td>';
+                $email_content .= '</tr>';
+            }
+            $email_content .='<tr>';
+            $email_content .='<td valign="top" rowspan="1" colspan="5" style="word-break: break-all;"><strong>备注:</strong>'.$remark['remark_content'].'</td>';
+            $email_content .='</tr>';
+            $email_content .='</tbody></table>';
+            $email_content .='<p><br/>&nbsp;</p><p><br/>&nbsp;</p>';
+            $email_content .='<p style="text-align: right;">责任人:'.$receive_user['name'].'&nbsp;<br>';
+            $email_content .=date("Y年m月d日",time()).'</p>';
+            $email_content .='</div>';
+            $notices_log['recipient'] = implode(",",$emails);
+            $notices_log['content'] = $email_content;
+            for ($i=0;$i<count($emails);$i++) {
+                $this->CI->mailer->add_recipient($emails[$i]);
+            }
+            if ($this->CI->mailer->send_email("", $notices_log['subject'], $notices_log['content'])) {
+                $notices_log['status'] = "1";
+            } else {
+                $notices_log['status'] = "0";
+            }
+            $notices_log['create_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+            $this->CI->noticeslog_model->save_notices_log($notices_log);
+        }
+    }
+
+    /**
+     * 核查工单未发现问题
+     * @param $workorder
+     * @param $remark
+     */
+    public function check_workorder($workorder,$remark){
+        $receive_user = $this->CI->user_model->get_user_with_user_id($workorder['receive_user_id']);
+        $admin_list = $this->CI->user_model->select_users("1");
+        $sso_admin_list = $this->CI->user_model->set_collection_name("sso_users")->select_users("1");
+        $mobiles = array();
+        $emails = array();
+        foreach ($admin_list as $key => $val){
+            $mobiles[] = $val['mobile'];
+            $emails[] = $val['email'];
+        }
+        foreach ($sso_admin_list as $key => $val){
+            $mobiles[] = $val['mobile'];
+            $emails[] = $val['email'];
+        }
+        if($this->setting['is_sms'] && in_array("10",$workorder['send_type'])){
+            $sms_content = '工单ID:'.$workorder['workorder_id'].',工单名称:'.$workorder['workorder_name'].',类型:'.$workorder['type'].',已由责任人'.$receive_user['name'].'核查无问题,备注:'.$remark['remark_content'];
+            for($i = 0;$i<count($mobiles);$i++) {
+                $notices_log = $this->CI->noticeslog_model->get_model();
+                $notices_log['type'] = "sms";
+                $notices_log['content'] = $sms_content;
+                $notices_log['log_id'] = $this->create_id();
+                $notices_log['mobile'] = $mobiles[$i];
+                if($this->setting['sms_type'] == '10' ){
+                    if(send_by_modem($this->setting, $notices_log['mobile'], $sms_content)){
+                        $notices_log['status'] = "1";
+                    }else{
+                        $notices_log['status'] = "0";
+                    }
+                }elseif($this->setting['sms_type'] == '20' ){
+                    $sms_content = array(
+                        "workorder_id"=>$workorder['workorder_id'],
+                        "workorder_name"=>$workorder['workorder_name'],
+                        "workorder_type"=>$workorder['type'],
+                        "receive_user_name"=>$receive_user['name'],
+                        "remark_content"=>$workorder['remark_list'][count($workorder['remark_list'])-1]['remark_content']
+                    );
+                    $resp = $this->Aliyunsms->sendSms($notices_log['mobile'],$this->setting['template_codes'][2],$sms_content);
+                    if($resp['Code'] == 'OK'){
+                        $notices_log['status'] = "1";
+                    }else{
+                        $notices_log['status'] = "0";
+                    }
+                }
+                $notices_log['create_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+                $this->CI->noticeslog_model->save_notices_log($notices_log);
+            }
+        }
+        if($this->setting['is_email'] && in_array("20",$workorder['send_type'])){
+            $notices_log = $this->CI->noticeslog_model->get_model();
+            $notices_log['log_id'] = $this->create_id();
+            $notices_log['type'] = "email";
+            $notices_log['subject'] = "工单ID:".$workorder['workorder_id']."已由责任人:".$receive_user['name']."核查无问题";
+            $email_content = '<div style="font-size:12px;">';
+            $email_content .='<p style="white-space: normal; background-color: rgb(255, 255, 255);">系统管理员,您好!</p>';
+            $email_content .='<p style="white-space: normal; background-color: rgb(255, 255, 255); text-indent: 2em;">以下工单已由责任人:'.$receive_user['name'].'核查无问题:</p>';
+            $email_content .='<table align="left" border="1" cellspacing="0" cellpadding="0" style="font-size:12px;"><thead>';
+            $email_content .='<tr class="firstRow"><td valign="top" rowspan="1" colspan="5" style="word-break: break-all;">';
+            $email_content .='<strong>工单ID:'.$workorder['workorder_id'].'</strong><strong>工单名称:'.$workorder['workorder_name'].'</strong>';
+            $email_content .='</td></tr>';
+            $email_content .='<tr>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>工单名称</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>类型</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>等级</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>时间</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>告警详情</strong></th>';
+            $email_content .='</tr></thead><tbody>';
+            foreach($workorder['warning_list'] as $key=>$val) {
+                $email_content .= '<tr>';
+                $email_content .= '<td valign="top" colspan="1" rowspan="1">'.$val['warning_name'].'</td>';
+                $email_content .= '<td valign="middle" colspan="1" rowspan="1" align="center">'.$this->warning_type[$val['type']].'</td>';
+                $email_content .= '<td valign="middle" colspan="1" rowspan="1" align="center">'.$this->warning_level[$val['level']].'</td>';
+                $email_content .= '<td valign="middle" colspan="1" rowspan="1" align="center">'.date("Y-m-d H:i:s",$val['create_time']->toDateTime()->getTimestamp()).'</td>';
+                $email_content .= '<td valign="top" colspan="1" rowspan="1">'.$val['content'].'</td>';
+                $email_content .= '</tr>';
+            }
+            $email_content .='<tr>';
+            $email_content .='<td valign="top" rowspan="1" colspan="5" style="word-break: break-all;"><strong>备注:</strong>'.$remark['remark_content'] .'</td>';
+            $email_content .='</tr>';
+            $email_content .='</tbody></table>';
+            $email_content .='<p><br/>&nbsp;</p><p><br/>&nbsp;</p>';
+            $email_content .='<p style="text-align: right;">责任人:'.$receive_user['name'].'&nbsp;<br>';
+            $email_content .=date("Y年m月d日",time()).'</p>';
+            $email_content .='</div>';
+            $notices_log['recipient'] = implode(",",$emails);
+            $notices_log['content'] = $email_content;
+            for ($i=0;$i<count($emails);$i++) {
+                $this->CI->mailer->add_recipient($emails[$i]);
+            }
+            if($remark['remark_file']){
+                $attachments = getcwd().'/static/upload'.$remark['remark_file'];
+            }else{
+                $attachments = null;
+            }
+            if ($this->CI->mailer->send_email("", $notices_log['subject'], $notices_log['content'],$attachments)) {
+                $notices_log['status'] = "1";
+            } else {
+                $notices_log['status'] = "0";
+            }
+            $notices_log['create_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+            $this->CI->noticeslog_model->save_notices_log($notices_log);
+        }
+    }
+
+    /**
+     * 工单已处理
+     * @param $workorder
+     * @param $remark
+     */
+    public function doit_workorder($workorder,$remark){
+        $receive_user = $this->CI->user_model->get_user_with_user_id($workorder['receive_user_id']);
+        $admin_list = $this->CI->user_model->select_users("1");
+        $sso_admin_list = $this->CI->user_model->set_collection_name("sso_users")->select_users("1");
+        $mobiles = array();
+        $emails = array();
+        foreach ($admin_list as $key => $val){
+            $mobiles[] = $val['mobile'];
+            $emails[] = $val['email'];
+        }
+        foreach ($sso_admin_list as $key => $val){
+            $mobiles[] = $val['mobile'];
+            $emails[] = $val['email'];
+        }
+        if($this->setting['is_sms'] && in_array("10",$workorder['send_type'])){
+            $sms_content = '工单ID:'.$workorder['workorder_id'].',工单名称:'.$workorder['workorder_name'].',类型:'.$workorder['type'].',已由责任人'.$receive_user['name'].'处理完成,备注:'.$remark['remark_content'];
+            for($i = 0;$i<count($mobiles);$i++) {
+                $notices_log = $this->CI->noticeslog_model->get_model();
+                $notices_log['type'] = "sms";
+                $notices_log['content'] = $sms_content;
+                $notices_log['log_id'] = $this->create_id();
+                $notices_log['mobile'] = $mobiles[$i];
+                if($this->setting['sms_type'] == '10' ){
+                    if(send_by_modem($this->setting, $notices_log['mobile'], $sms_content)){
+                        $notices_log['status'] = "1";
+                    }else{
+                        $notices_log['status'] = "0";
+                    }
+                }elseif($this->setting['sms_type'] == '20' ){
+                    $sms_content = array(
+                        "workorder_id"=>$workorder['workorder_id'],
+                        "workorder_name"=>$workorder['workorder_name'],
+                        "workorder_type"=>$workorder['type'],
+                        "receive_user_name"=>$receive_user['name'],
+                        "remark_content"=>$workorder['remark_list'][count($workorder['remark_list'])-1]['remark_content']
+                    );
+                    $resp = $this->Aliyunsms->sendSms($notices_log['mobile'],$this->setting['template_codes'][3],$sms_content);
+                    if($resp['Code'] == 'OK'){
+                        $notices_log['status'] = "1";
+                    }else{
+                        $notices_log['status'] = "0";
+                    }
+                }
+                $notices_log['create_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+                $this->CI->noticeslog_model->save_notices_log($notices_log);
+            }
+        }
+        if($this->setting['is_email'] && in_array("20",$workorder['send_type'])){
+            $notices_log = $this->CI->noticeslog_model->get_model();
+            $notices_log['log_id'] = $this->create_id();
+            $notices_log['type'] = "email";
+            $notices_log['subject'] = "工单ID:".$workorder['workorder_id']."已由责任人:".$receive_user['name']."处理完成";
+            $email_content = '<div style="font-size:12px;">';
+            $email_content .='<p style="white-space: normal; background-color: rgb(255, 255, 255);">系统管理员,您好!</p>';
+            $email_content .='<p style="white-space: normal; background-color: rgb(255, 255, 255); text-indent: 2em;">以下工单已由责任人:'.$receive_user['name'].'处理完成:</p>';
+            $email_content .='<table align="left" border="1" cellspacing="0" cellpadding="0" style="font-size:12px;"><thead>';
+            $email_content .='<tr class="firstRow"><td valign="top" rowspan="1" colspan="5" style="word-break: break-all;">';
+            $email_content .='<strong>工单ID:'.$workorder['workorder_id'].'</strong><strong>工单名称:'.$workorder['workorder_name'].'</strong>';
+            $email_content .='</td></tr>';
+            $email_content .='<tr>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>工单名称</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>类型</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>等级</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>时间</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>告警详情</strong></th>';
+            $email_content .='</tr></thead><tbody>';
+            foreach($workorder['warning_list'] as $key=>$val) {
+                $email_content .= '<tr>';
+                $email_content .= '<td valign="top" colspan="1" rowspan="1">'.$val['warning_name'].'</td>';
+                $email_content .= '<td valign="middle" colspan="1" rowspan="1" align="center">'.$this->warning_type[$val['type']].'</td>';
+                $email_content .= '<td valign="middle" colspan="1" rowspan="1" align="center">'.$this->warning_level[$val['level']].'</td>';
+                $email_content .= '<td valign="middle" colspan="1" rowspan="1" align="center">'.date("Y-m-d H:i:s",$val['create_time']->toDateTime()->getTimestamp()).'</td>';
+                $email_content .= '<td valign="top" colspan="1" rowspan="1">'.$val['content'].'</td>';
+                $email_content .= '</tr>';
+            }
+            $email_content .='<tr>';
+            $email_content .='<td valign="top" rowspan="1" colspan="5" style="word-break: break-all;"><strong>备注:</strong>'.$remark['remark_content'] .'</td>';
+            $email_content .='</tr>';
+            $email_content .='</tbody></table>';
+            $email_content .='<p><br/>&nbsp;</p><p><br/>&nbsp;</p>';
+            $email_content .='<p style="text-align: right;">责任人:'.$receive_user['name'].'&nbsp;<br>';
+            $email_content .=date("Y年m月d日",time()).'</p>';
+            $email_content .='</div>';
+            $notices_log['recipient'] = implode(",",$emails);
+            $notices_log['content'] = $email_content;
+            for ($i=0;$i<count($emails);$i++) {
+                $this->CI->mailer->add_recipient($emails[$i]);
+            }
+            if($remark['remark_file']){
+                $attachments = getcwd().'/static/upload'.$remark['remark_file'];
+            }else{
+                $attachments = null;
+            }
+            if ($this->CI->mailer->send_email("", $notices_log['subject'], $notices_log['content'],$attachments)) {
+                $notices_log['status'] = "1";
+            } else {
+                $notices_log['status'] = "0";
+            }
+            $notices_log['create_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+            $this->CI->noticeslog_model->save_notices_log($notices_log);
+        }
+    }
+
+    /**
+     * 驳回工单
+     * @param $workorder
+     * @param $remark
+     */
+    public function reject_workorder($workorder,$remark){
+        $receive_user = $this->CI->user_model->get_user_with_user_id($workorder['receive_user_id']);
+        if($this->setting['is_sms'] && in_array("10",$workorder['send_type'])){
+            $sms_content = '你的工单已由管理员驳回,请重新处理。工单ID:'.$workorder['workorder_id'].',工单名称:'.$workorder['workorder_name'].',类型:'.$workorder['type'].',备注:'.$remark['remark_content'];
+            $notices_log = $this->CI->noticeslog_model->get_model();
+            $notices_log['log_id'] = $this->create_id();
+            $notices_log['type'] = "sms";
+            $notices_log['mobile'] = $receive_user['mobile'];
+            $notices_log['content'] = $sms_content;
+            if($this->setting['sms_type'] == '10' ){
+                if(send_by_modem($this->setting, $receive_user['mobile'], $sms_content)){
+                    $notices_log['status'] = "1";
+                }else{
+                    $notices_log['status'] = "0";
+                }
+            }elseif($this->setting['sms_type'] == '20' ){
+                $sms_content = array(
+                    "workorder_id"=>$workorder['workorder_id'],
+                    "workorder_name"=>$workorder['workorder_name'],
+                    "workorder_type"=>$workorder['type'],
+                    "remark_content"=>$workorder['remark_list'][count($workorder['remark_list'])-1]['remark_content']
+                );
+                $resp = $this->Aliyunsms->sendSms($receive_user['mobile'],$this->setting['template_codes'][4],$sms_content);
+                if($resp['Code'] == 'OK'){
+                    $notices_log['status'] = "1";
+                }else{
+                    $notices_log['status'] = "0";
+                }
+            }
+            $notices_log['create_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+            $this->CI->noticeslog_model->save_notices_log($notices_log);
+        }
+        if($this->setting['is_email'] && in_array("20",$workorder['send_type'])){
+            $notices_log = $this->CI->noticeslog_model->get_model();
+            $notices_log['log_id'] = $this->create_id();
+            $notices_log['type'] = "email";
+            $notices_log['recipient'] = $receive_user['email'];
+            $notices_log['subject'] = "你的工单已由管理员驳回,请重新处理,工单ID:".$workorder['workorder_id'];
+            $email_content = '<div style="font-size:12px;">';
+            $email_content .='<p style="white-space: normal; background-color: rgb(255, 255, 255);">'.$receive_user['name'].',您好!</p>';
+            $email_content .='<p style="white-space: normal; background-color: rgb(255, 255, 255); text-indent: 2em;">以下工单已由管理员驳回,请重新处理:</p>';
+            $email_content .='<table align="left" border="1" cellspacing="0" cellpadding="0" style="font-size:12px;"><thead>';
+            $email_content .='<tr class="firstRow"><td valign="top" rowspan="1" colspan="5" style="word-break: break-all;">';
+            $email_content .='<strong>工单ID:'.$workorder['workorder_id'].'</strong><strong>工单名称:'.$workorder['workorder_name'].'</strong>';
+            $email_content .='</td></tr>';
+            $email_content .='<tr>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>工单名称</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>类型</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>等级</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>时间</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>告警详情</strong></th>';
+            $email_content .='</tr></thead><tbody>';
+            foreach($workorder['warning_list'] as $key=>$val) {
+                $email_content .= '<tr>';
+                $email_content .= '<td valign="top" colspan="1" rowspan="1">'.$val['warning_name'].'</td>';
+                $email_content .= '<td valign="middle" colspan="1" rowspan="1" align="center">'.$this->warning_type[$val['type']].'</td>';
+                $email_content .= '<td valign="middle" colspan="1" rowspan="1" align="center">'.$this->warning_level[$val['level']].'</td>';
+                $email_content .= '<td valign="middle" colspan="1" rowspan="1" align="center">'.date("Y-m-d H:i:s",$val['create_time']->toDateTime()->getTimestamp()).'</td>';
+                $email_content .= '<td valign="top" colspan="1" rowspan="1">'.$val['content'].'</td>';
+                $email_content .= '</tr>';
+            }
+            $email_content .='<tr>';
+            $email_content .='<td valign="top" rowspan="1" colspan="5" style="word-break: break-all;"><strong>备注:</strong>'.$remark['remark_content'] .'</td>';
+            $email_content .='</tr>';
+            $email_content .='</tbody></table>';
+            $email_content .='<p><br/>&nbsp;</p><p><br/>&nbsp;</p>';
+            $email_content .='<p style="text-align: right;">系统管理员&nbsp;&nbsp;<br>';
+            $email_content .=date("Y年m月d日",time()).'</p>';
+            $email_content .='</div>';
+            $notices_log['content'] = $email_content;
+            if($this->CI->mailer->send_email($receive_user['email'],$notices_log['subject'],$notices_log['content'])){
+                $notices_log['status'] = "1";
+            }else{
+                $notices_log['status'] = "0";
+            }
+            $notices_log['create_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+            $this->CI->noticeslog_model->save_notices_log($notices_log);
+        }
+    }
+
+    /**
+     * 完成工单
+     * @param $workorder
+     */
+    public function finish_workorder($workorder){
+        $receive_user = $this->CI->user_model->get_user_with_user_id($workorder['receive_user_id']);
+        if($this->setting['is_sms'] && in_array("10",$workorder['send_type'])){
+            $sms_content = '你的工单已由管理员结束,工单ID:'.$workorder['workorder_id'].',工单名称:'.$workorder['workorder_name'].',类型:'.$workorder['type'];
+            $notices_log = $this->CI->noticeslog_model->get_model();
+            $notices_log['log_id'] = $this->create_id();
+            $notices_log['type'] = "sms";
+            $notices_log['mobile'] = $receive_user['mobile'];
+            $notices_log['content'] = $sms_content;
+            if($this->setting['sms_type'] == '10' ){
+                if(send_by_modem($this->setting, $receive_user['mobile'], $sms_content)){
+                    $notices_log['status'] = "1";
+                }else{
+                    $notices_log['status'] = "0";
+                }
+            }elseif($this->setting['sms_type'] == '20' ){
+                $sms_content = array(
+                    "workorder_id"=>$workorder['workorder_id'],
+                    "workorder_name"=>$workorder['workorder_name'],
+                    "workorder_type"=>$workorder['type']
+                );
+                $resp = $this->Aliyunsms->sendSms($receive_user['mobile'],$this->setting['template_codes'][4],$sms_content);
+                if($resp['Code'] == 'OK'){
+                    $notices_log['status'] = "1";
+                }else{
+                    $notices_log['status'] = "0";
+                }
+            }
+            $notices_log['create_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+            $this->CI->noticeslog_model->save_notices_log($notices_log);
+        }
+        if($this->setting['is_email'] && in_array("20",$workorder['send_type'])){
+            $notices_log = $this->CI->noticeslog_model->get_model();
+            $notices_log['log_id'] = $this->create_id();
+            $notices_log['type'] = "email";
+            $notices_log['recipient'] = $receive_user['email'];
+            $notices_log['subject'] = "你的工单已由管理员结束,工单ID:".$workorder['workorder_id'];
+            $email_content = '<div style="font-size:12px;">';
+            $email_content .='<p style="white-space: normal; background-color: rgb(255, 255, 255);">'.$receive_user['name'].',您好!</p>';
+            $email_content .='<p style="white-space: normal; background-color: rgb(255, 255, 255); text-indent: 2em;">以下工单已由管理员确认结束:</p>';
+            $email_content .='<table align="left" border="1" cellspacing="0" cellpadding="0" style="font-size:12px;"><thead>';
+            $email_content .='<tr class="firstRow"><td valign="top" rowspan="1" colspan="5" style="word-break: break-all;">';
+            $email_content .='<strong>工单ID:'.$workorder['workorder_id'].'</strong><strong>工单名称:'.$workorder['workorder_name'].'</strong>';
+            $email_content .='</td></tr>';
+            $email_content .='<tr>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>工单名称</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>类型</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>等级</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>时间</strong></th>';
+            $email_content .='<th width="147" valign="middle" style="word-break: break-all;" align="center"><strong>告警详情</strong></th>';
+            $email_content .='</tr></thead><tbody>';
+            foreach($workorder['warning_list'] as $key=>$val) {
+                $email_content .= '<tr>';
+                $email_content .= '<td valign="top" colspan="1" rowspan="1">'.$val['warning_name'].'</td>';
+                $email_content .= '<td valign="middle" colspan="1" rowspan="1" align="center">'.$this->warning_type[$val['type']].'</td>';
+                $email_content .= '<td valign="middle" colspan="1" rowspan="1" align="center">'.$this->warning_level[$val['level']].'</td>';
+                $email_content .= '<td valign="middle" colspan="1" rowspan="1" align="center">'.date("Y-m-d H:i:s",$val['create_time']->toDateTime()->getTimestamp()).'</td>';
+                $email_content .= '<td valign="top" colspan="1" rowspan="1">'.$val['content'].'</td>';
+                $email_content .= '</tr>';
+            }
+            $email_content .='</tbody></table>';
+            $email_content .='<p><br/>&nbsp;</p><p><br/>&nbsp;</p>';
+            $email_content .='<p style="text-align: right;">系统管理员&nbsp;&nbsp;<br>';
+            $email_content .=date("Y年m月d日",time()).'</p>';
+            $email_content .='</div>';
+            $notices_log['content'] = $email_content;
+            if($this->CI->mailer->send_email($receive_user['email'],$notices_log['subject'],$notices_log['content'])){
+                $notices_log['status'] = "1";
+            }else{
+                $notices_log['status'] = "0";
+            }
+            $notices_log['create_time'] = new MongoDB\BSON\UTCDateTime(time()*1000);
+            $this->CI->noticeslog_model->save_notices_log($notices_log);
+        }
+    }
+
+    /**
+     * 生成ID
+     * @return string
+     */
+    public function create_id()
+    {
+        return date('Ymd') . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
+    }
+}

+ 502 - 0
application/libraries/PHPMail/LICENSE

@@ -0,0 +1,502 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!

+ 49 - 0
application/libraries/PHPMail/PHPMailerAutoload.php

@@ -0,0 +1,49 @@
+<?php
+/**
+ * PHPMailer SPL autoloader.
+ * PHP Version 5
+ * @package PHPMailer
+ * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
+ * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
+ * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
+ * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
+ * @author Brent R. Matzelle (original founder)
+ * @copyright 2012 - 2014 Marcus Bointon
+ * @copyright 2010 - 2012 Jim Jagielski
+ * @copyright 2004 - 2009 Andy Prevost
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
+ * @note This program is distributed in the hope that it will be useful - WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/**
+ * PHPMailer SPL autoloader.
+ * @param string $classname The name of the class to load
+ */
+function PHPMailerAutoload($classname)
+{
+    //Can't use __DIR__ as it's only in PHP 5.3+
+    $filename = dirname(__FILE__).DIRECTORY_SEPARATOR.'class.'.strtolower($classname).'.php';
+    if (is_readable($filename)) {
+        require $filename;
+    }
+}
+
+if (version_compare(PHP_VERSION, '5.1.2', '>=')) {
+    //SPL autoloading was introduced in PHP 5.1.2
+    if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
+        spl_autoload_register('PHPMailerAutoload', true, true);
+    } else {
+        spl_autoload_register('PHPMailerAutoload');
+    }
+} else {
+    /**
+     * Fall back to traditional autoload for old PHP versions
+     * @param string $classname The name of the class to load
+     */
+    function __autoload($classname)
+    {
+        PHPMailerAutoload($classname);
+    }
+}

+ 1 - 0
application/libraries/PHPMail/VERSION

@@ -0,0 +1 @@
+5.2.26

Різницю між файлами не показано, бо вона завелика
+ 4044 - 0
application/libraries/PHPMail/class.phpmailer.php


+ 197 - 0
application/libraries/PHPMail/class.phpmaileroauth.php

@@ -0,0 +1,197 @@
+<?php
+/**
+ * PHPMailer - PHP email creation and transport class.
+ * PHP Version 5.4
+ * @package PHPMailer
+ * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
+ * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
+ * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
+ * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
+ * @author Brent R. Matzelle (original founder)
+ * @copyright 2012 - 2014 Marcus Bointon
+ * @copyright 2010 - 2012 Jim Jagielski
+ * @copyright 2004 - 2009 Andy Prevost
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
+ * @note This program is distributed in the hope that it will be useful - WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/**
+ * PHPMailerOAuth - PHPMailer subclass adding OAuth support.
+ * @package PHPMailer
+ * @author @sherryl4george
+ * @author Marcus Bointon (@Synchro) <phpmailer@synchromedia.co.uk>
+ */
+class PHPMailerOAuth extends PHPMailer
+{
+    /**
+     * The OAuth user's email address
+     * @var string
+     */
+    public $oauthUserEmail = '';
+
+    /**
+     * The OAuth refresh token
+     * @var string
+     */
+    public $oauthRefreshToken = '';
+
+    /**
+     * The OAuth client ID
+     * @var string
+     */
+    public $oauthClientId = '';
+
+    /**
+     * The OAuth client secret
+     * @var string
+     */
+    public $oauthClientSecret = '';
+
+    /**
+     * An instance of the PHPMailerOAuthGoogle class.
+     * @var PHPMailerOAuthGoogle
+     * @access protected
+     */
+    protected $oauth = null;
+
+    /**
+     * Get a PHPMailerOAuthGoogle instance to use.
+     * @return PHPMailerOAuthGoogle
+     */
+    public function getOAUTHInstance()
+    {
+        if (!is_object($this->oauth)) {
+            $this->oauth = new PHPMailerOAuthGoogle(
+                $this->oauthUserEmail,
+                $this->oauthClientSecret,
+                $this->oauthClientId,
+                $this->oauthRefreshToken
+            );
+        }
+        return $this->oauth;
+    }
+
+    /**
+     * Initiate a connection to an SMTP server.
+     * Overrides the original smtpConnect method to add support for OAuth.
+     * @param array $options An array of options compatible with stream_context_create()
+     * @uses SMTP
+     * @access public
+     * @return bool
+     * @throws phpmailerException
+     */
+    public function smtpConnect($options = array())
+    {
+        if (is_null($this->smtp)) {
+            $this->smtp = $this->getSMTPInstance();
+        }
+
+        if (is_null($this->oauth)) {
+            $this->oauth = $this->getOAUTHInstance();
+        }
+
+        // Already connected?
+        if ($this->smtp->connected()) {
+            return true;
+        }
+
+        $this->smtp->setTimeout($this->Timeout);
+        $this->smtp->setDebugLevel($this->SMTPDebug);
+        $this->smtp->setDebugOutput($this->Debugoutput);
+        $this->smtp->setVerp($this->do_verp);
+        $hosts = explode(';', $this->Host);
+        $lastexception = null;
+
+        foreach ($hosts as $hostentry) {
+            $hostinfo = array();
+            if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {
+                // Not a valid host entry
+                continue;
+            }
+            // $hostinfo[2]: optional ssl or tls prefix
+            // $hostinfo[3]: the hostname
+            // $hostinfo[4]: optional port number
+            // The host string prefix can temporarily override the current setting for SMTPSecure
+            // If it's not specified, the default value is used
+            $prefix = '';
+            $secure = $this->SMTPSecure;
+            $tls = ($this->SMTPSecure == 'tls');
+            if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) {
+                $prefix = 'ssl://';
+                $tls = false; // Can't have SSL and TLS at the same time
+                $secure = 'ssl';
+            } elseif ($hostinfo[2] == 'tls') {
+                $tls = true;
+                // tls doesn't use a prefix
+                $secure = 'tls';
+            }
+            //Do we need the OpenSSL extension?
+            $sslext = defined('OPENSSL_ALGO_SHA1');
+            if ('tls' === $secure or 'ssl' === $secure) {
+                //Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled
+                if (!$sslext) {
+                    throw new phpmailerException($this->lang('extension_missing').'openssl', self::STOP_CRITICAL);
+                }
+            }
+            $host = $hostinfo[3];
+            $port = $this->Port;
+            $tport = (integer)$hostinfo[4];
+            if ($tport > 0 and $tport < 65536) {
+                $port = $tport;
+            }
+            if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {
+                try {
+                    if ($this->Helo) {
+                        $hello = $this->Helo;
+                    } else {
+                        $hello = $this->serverHostname();
+                    }
+                    $this->smtp->hello($hello);
+                    //Automatically enable TLS encryption if:
+                    // * it's not disabled
+                    // * we have openssl extension
+                    // * we are not already using SSL
+                    // * the server offers STARTTLS
+                    if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) {
+                        $tls = true;
+                    }
+                    if ($tls) {
+                        if (!$this->smtp->startTLS()) {
+                            throw new phpmailerException($this->lang('connect_host'));
+                        }
+                        // We must resend HELO after tls negotiation
+                        $this->smtp->hello($hello);
+                    }
+                    if ($this->SMTPAuth) {
+                        if (!$this->smtp->authenticate(
+                            $this->Username,
+                            $this->Password,
+                            $this->AuthType,
+                            $this->Realm,
+                            $this->Workstation,
+                            $this->oauth
+                        )
+                        ) {
+                            throw new phpmailerException($this->lang('authenticate'));
+                        }
+                    }
+                    return true;
+                } catch (phpmailerException $exc) {
+                    $lastexception = $exc;
+                    $this->edebug($exc->getMessage());
+                    // We must have connected, but then failed TLS or Auth, so close connection nicely
+                    $this->smtp->quit();
+                }
+            }
+        }
+        // If we get here, all connection attempts have failed, so close connection hard
+        $this->smtp->close();
+        // As we've caught all exceptions, just report whatever the last one was
+        if ($this->exceptions and !is_null($lastexception)) {
+            throw $lastexception;
+        }
+        return false;
+    }
+}

+ 77 - 0
application/libraries/PHPMail/class.phpmaileroauthgoogle.php

@@ -0,0 +1,77 @@
+<?php
+/**
+ * PHPMailer - PHP email creation and transport class.
+ * PHP Version 5.4
+ * @package PHPMailer
+ * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
+ * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
+ * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
+ * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
+ * @author Brent R. Matzelle (original founder)
+ * @copyright 2012 - 2014 Marcus Bointon
+ * @copyright 2010 - 2012 Jim Jagielski
+ * @copyright 2004 - 2009 Andy Prevost
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
+ * @note This program is distributed in the hope that it will be useful - WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/**
+ * PHPMailerOAuthGoogle - Wrapper for League OAuth2 Google provider.
+ * @package PHPMailer
+ * @author @sherryl4george
+ * @author Marcus Bointon (@Synchro) <phpmailer@synchromedia.co.uk>
+ * @link https://github.com/thephpleague/oauth2-client
+ */
+class PHPMailerOAuthGoogle
+{
+    private $oauthUserEmail = '';
+    private $oauthRefreshToken = '';
+    private $oauthClientId = '';
+    private $oauthClientSecret = '';
+
+    /**
+     * @param string $UserEmail
+     * @param string $ClientSecret
+     * @param string $ClientId
+     * @param string $RefreshToken
+     */
+    public function __construct(
+        $UserEmail,
+        $ClientSecret,
+        $ClientId,
+        $RefreshToken
+    ) {
+        $this->oauthClientId = $ClientId;
+        $this->oauthClientSecret = $ClientSecret;
+        $this->oauthRefreshToken = $RefreshToken;
+        $this->oauthUserEmail = $UserEmail;
+    }
+
+    private function getProvider()
+    {
+        return new League\OAuth2\Client\Provider\Google([
+            'clientId' => $this->oauthClientId,
+            'clientSecret' => $this->oauthClientSecret
+        ]);
+    }
+
+    private function getGrant()
+    {
+        return new \League\OAuth2\Client\Grant\RefreshToken();
+    }
+
+    private function getToken()
+    {
+        $provider = $this->getProvider();
+        $grant = $this->getGrant();
+        return $provider->getAccessToken($grant, ['refresh_token' => $this->oauthRefreshToken]);
+    }
+
+    public function getOauth64()
+    {
+        $token = $this->getToken();
+        return base64_encode("user=" . $this->oauthUserEmail . "\001auth=Bearer " . $token . "\001\001");
+    }
+}

+ 407 - 0
application/libraries/PHPMail/class.pop3.php

@@ -0,0 +1,407 @@
+<?php
+/**
+ * PHPMailer POP-Before-SMTP Authentication Class.
+ * PHP Version 5
+ * @package PHPMailer
+ * @link https://github.com/PHPMailer/PHPMailer/
+ * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
+ * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
+ * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
+ * @author Brent R. Matzelle (original founder)
+ * @copyright 2012 - 2014 Marcus Bointon
+ * @copyright 2010 - 2012 Jim Jagielski
+ * @copyright 2004 - 2009 Andy Prevost
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
+ * @note This program is distributed in the hope that it will be useful - WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/**
+ * PHPMailer POP-Before-SMTP Authentication Class.
+ * Specifically for PHPMailer to use for RFC1939 POP-before-SMTP authentication.
+ * Does not support APOP.
+ * @package PHPMailer
+ * @author Richard Davey (original author) <rich@corephp.co.uk>
+ * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
+ * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
+ * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
+ */
+class POP3
+{
+    /**
+     * The POP3 PHPMailer Version number.
+     * @var string
+     * @access public
+     */
+    public $Version = '5.2.26';
+
+    /**
+     * Default POP3 port number.
+     * @var integer
+     * @access public
+     */
+    public $POP3_PORT = 110;
+
+    /**
+     * Default timeout in seconds.
+     * @var integer
+     * @access public
+     */
+    public $POP3_TIMEOUT = 30;
+
+    /**
+     * POP3 Carriage Return + Line Feed.
+     * @var string
+     * @access public
+     * @deprecated Use the constant instead
+     */
+    public $CRLF = "\r\n";
+
+    /**
+     * Debug display level.
+     * Options: 0 = no, 1+ = yes
+     * @var integer
+     * @access public
+     */
+    public $do_debug = 0;
+
+    /**
+     * POP3 mail server hostname.
+     * @var string
+     * @access public
+     */
+    public $host;
+
+    /**
+     * POP3 port number.
+     * @var integer
+     * @access public
+     */
+    public $port;
+
+    /**
+     * POP3 Timeout Value in seconds.
+     * @var integer
+     * @access public
+     */
+    public $tval;
+
+    /**
+     * POP3 username
+     * @var string
+     * @access public
+     */
+    public $username;
+
+    /**
+     * POP3 password.
+     * @var string
+     * @access public
+     */
+    public $password;
+
+    /**
+     * Resource handle for the POP3 connection socket.
+     * @var resource
+     * @access protected
+     */
+    protected $pop_conn;
+
+    /**
+     * Are we connected?
+     * @var boolean
+     * @access protected
+     */
+    protected $connected = false;
+
+    /**
+     * Error container.
+     * @var array
+     * @access protected
+     */
+    protected $errors = array();
+
+    /**
+     * Line break constant
+     */
+    const CRLF = "\r\n";
+
+    /**
+     * Simple static wrapper for all-in-one POP before SMTP
+     * @param $host
+     * @param integer|boolean $port The port number to connect to
+     * @param integer|boolean $timeout The timeout value
+     * @param string $username
+     * @param string $password
+     * @param integer $debug_level
+     * @return boolean
+     */
+    public static function popBeforeSmtp(
+        $host,
+        $port = false,
+        $timeout = false,
+        $username = '',
+        $password = '',
+        $debug_level = 0
+    ) {
+        $pop = new POP3;
+        return $pop->authorise($host, $port, $timeout, $username, $password, $debug_level);
+    }
+
+    /**
+     * Authenticate with a POP3 server.
+     * A connect, login, disconnect sequence
+     * appropriate for POP-before SMTP authorisation.
+     * @access public
+     * @param string $host The hostname to connect to
+     * @param integer|boolean $port The port number to connect to
+     * @param integer|boolean $timeout The timeout value
+     * @param string $username
+     * @param string $password
+     * @param integer $debug_level
+     * @return boolean
+     */
+    public function authorise($host, $port = false, $timeout = false, $username = '', $password = '', $debug_level = 0)
+    {
+        $this->host = $host;
+        // If no port value provided, use default
+        if (false === $port) {
+            $this->port = $this->POP3_PORT;
+        } else {
+            $this->port = (integer)$port;
+        }
+        // If no timeout value provided, use default
+        if (false === $timeout) {
+            $this->tval = $this->POP3_TIMEOUT;
+        } else {
+            $this->tval = (integer)$timeout;
+        }
+        $this->do_debug = $debug_level;
+        $this->username = $username;
+        $this->password = $password;
+        //  Reset the error log
+        $this->errors = array();
+        //  connect
+        $result = $this->connect($this->host, $this->port, $this->tval);
+        if ($result) {
+            $login_result = $this->login($this->username, $this->password);
+            if ($login_result) {
+                $this->disconnect();
+                return true;
+            }
+        }
+        // We need to disconnect regardless of whether the login succeeded
+        $this->disconnect();
+        return false;
+    }
+
+    /**
+     * Connect to a POP3 server.
+     * @access public
+     * @param string $host
+     * @param integer|boolean $port
+     * @param integer $tval
+     * @return boolean
+     */
+    public function connect($host, $port = false, $tval = 30)
+    {
+        //  Are we already connected?
+        if ($this->connected) {
+            return true;
+        }
+
+        //On Windows this will raise a PHP Warning error if the hostname doesn't exist.
+        //Rather than suppress it with @fsockopen, capture it cleanly instead
+        set_error_handler(array($this, 'catchWarning'));
+
+        if (false === $port) {
+            $port = $this->POP3_PORT;
+        }
+
+        //  connect to the POP3 server
+        $this->pop_conn = fsockopen(
+            $host, //  POP3 Host
+            $port, //  Port #
+            $errno, //  Error Number
+            $errstr, //  Error Message
+            $tval
+        ); //  Timeout (seconds)
+        //  Restore the error handler
+        restore_error_handler();
+
+        //  Did we connect?
+        if (false === $this->pop_conn) {
+            //  It would appear not...
+            $this->setError(array(
+                'error' => "Failed to connect to server $host on port $port",
+                'errno' => $errno,
+                'errstr' => $errstr
+            ));
+            return false;
+        }
+
+        //  Increase the stream time-out
+        stream_set_timeout($this->pop_conn, $tval, 0);
+
+        //  Get the POP3 server response
+        $pop3_response = $this->getResponse();
+        //  Check for the +OK
+        if ($this->checkResponse($pop3_response)) {
+            //  The connection is established and the POP3 server is talking
+            $this->connected = true;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Log in to the POP3 server.
+     * Does not support APOP (RFC 2828, 4949).
+     * @access public
+     * @param string $username
+     * @param string $password
+     * @return boolean
+     */
+    public function login($username = '', $password = '')
+    {
+        if (!$this->connected) {
+            $this->setError('Not connected to POP3 server');
+        }
+        if (empty($username)) {
+            $username = $this->username;
+        }
+        if (empty($password)) {
+            $password = $this->password;
+        }
+
+        // Send the Username
+        $this->sendString("USER $username" . self::CRLF);
+        $pop3_response = $this->getResponse();
+        if ($this->checkResponse($pop3_response)) {
+            // Send the Password
+            $this->sendString("PASS $password" . self::CRLF);
+            $pop3_response = $this->getResponse();
+            if ($this->checkResponse($pop3_response)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Disconnect from the POP3 server.
+     * @access public
+     */
+    public function disconnect()
+    {
+        $this->sendString('QUIT');
+        //The QUIT command may cause the daemon to exit, which will kill our connection
+        //So ignore errors here
+        try {
+            @fclose($this->pop_conn);
+        } catch (Exception $e) {
+            //Do nothing
+        };
+    }
+
+    /**
+     * Get a response from the POP3 server.
+     * $size is the maximum number of bytes to retrieve
+     * @param integer $size
+     * @return string
+     * @access protected
+     */
+    protected function getResponse($size = 128)
+    {
+        $response = fgets($this->pop_conn, $size);
+        if ($this->do_debug >= 1) {
+            echo "Server -> Client: $response";
+        }
+        return $response;
+    }
+
+    /**
+     * Send raw data to the POP3 server.
+     * @param string $string
+     * @return integer
+     * @access protected
+     */
+    protected function sendString($string)
+    {
+        if ($this->pop_conn) {
+            if ($this->do_debug >= 2) { //Show client messages when debug >= 2
+                echo "Client -> Server: $string";
+            }
+            return fwrite($this->pop_conn, $string, strlen($string));
+        }
+        return 0;
+    }
+
+    /**
+     * Checks the POP3 server response.
+     * Looks for for +OK or -ERR.
+     * @param string $string
+     * @return boolean
+     * @access protected
+     */
+    protected function checkResponse($string)
+    {
+        if (substr($string, 0, 3) !== '+OK') {
+            $this->setError(array(
+                'error' => "Server reported an error: $string",
+                'errno' => 0,
+                'errstr' => ''
+            ));
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Add an error to the internal error store.
+     * Also display debug output if it's enabled.
+     * @param $error
+     * @access protected
+     */
+    protected function setError($error)
+    {
+        $this->errors[] = $error;
+        if ($this->do_debug >= 1) {
+            echo '<pre>';
+            foreach ($this->errors as $error) {
+                print_r($error);
+            }
+            echo '</pre>';
+        }
+    }
+
+    /**
+     * Get an array of error messages, if any.
+     * @return array
+     */
+    public function getErrors()
+    {
+        return $this->errors;
+    }
+
+    /**
+     * POP3 connection error handler.
+     * @param integer $errno
+     * @param string $errstr
+     * @param string $errfile
+     * @param integer $errline
+     * @access protected
+     */
+    protected function catchWarning($errno, $errstr, $errfile, $errline)
+    {
+        $this->setError(array(
+            'error' => "Connecting to the POP3 server raised a PHP warning: ",
+            'errno' => $errno,
+            'errstr' => $errstr,
+            'errfile' => $errfile,
+            'errline' => $errline
+        ));
+    }
+}

Різницю між файлами не показано, бо вона завелика
+ 1276 - 0
application/libraries/PHPMail/class.smtp.php


+ 61 - 0
application/libraries/PHPMail/composer.json

@@ -0,0 +1,61 @@
+{
+    "name": "phpmailer/phpmailer",
+    "type": "library",
+    "description": "PHPMailer is a full-featured email creation and transfer class for PHP",
+    "authors": [
+        {
+            "name": "Marcus Bointon",
+            "email": "phpmailer@synchromedia.co.uk"
+        },
+        {
+            "name": "Jim Jagielski",
+            "email": "jimjag@gmail.com"
+        },
+        {
+            "name": "Andy Prevost",
+            "email": "codeworxtech@users.sourceforge.net"
+        },
+        {
+            "name": "Brent R. Matzelle"
+        }
+    ],
+    "require": {
+        "ext-ctype": "*",
+        "php": ">=5.0.0"
+    },
+    "require-dev": {
+        "doctrine/annotations": "1.2.*",
+        "jms/serializer": "0.16.*",
+        "phpdocumentor/phpdocumentor": "2.*",
+        "phpunit/phpunit": "4.8.*",
+        "symfony/debug": "2.8.*",
+        "symfony/filesystem": "2.8.*",
+        "symfony/translation": "2.8.*",
+        "symfony/yaml": "2.8.*",
+        "zendframework/zend-cache": "2.5.1",
+        "zendframework/zend-config": "2.5.1",
+        "zendframework/zend-eventmanager": "2.5.1",
+        "zendframework/zend-filter": "2.5.1",
+        "zendframework/zend-i18n": "2.5.1",
+        "zendframework/zend-json": "2.5.1",
+        "zendframework/zend-math": "2.5.1",
+        "zendframework/zend-serializer": "2.5.*",
+        "zendframework/zend-servicemanager": "2.5.*",
+        "zendframework/zend-stdlib": "2.5.1"
+    },
+    "suggest": {
+        "league/oauth2-google": "Needed for Google XOAUTH2 authentication"
+    },
+    "autoload": {
+        "classmap": [
+            "class.phpmailer.php",
+            "class.phpmaileroauth.php",
+            "class.phpmaileroauthgoogle.php",
+            "class.smtp.php",
+            "class.pop3.php",
+            "extras/EasyPeasyICS.php",
+            "extras/ntlm_sasl_client.php"
+        ]
+    },
+    "license": "LGPL-2.1"
+}

Різницю між файлами не показано, бо вона завелика
+ 3593 - 0
application/libraries/PHPMail/composer.lock


+ 148 - 0
application/libraries/PHPMail/extras/EasyPeasyICS.php

@@ -0,0 +1,148 @@
+<?php
+/**
+ * EasyPeasyICS Simple ICS/vCal data generator.
+ * @author Marcus Bointon <phpmailer@synchromedia.co.uk>
+ * @author Manuel Reinhard <manu@sprain.ch>
+ *
+ * Built with inspiration from
+ * http://stackoverflow.com/questions/1463480/how-can-i-use-php-to-dynamically-publish-an-ical-file-to-be-read-by-google-calend/1464355#1464355
+ * History:
+ * 2010/12/17 - Manuel Reinhard - when it all started
+ * 2014 PHPMailer project becomes maintainer
+ */
+
+/**
+ * Class EasyPeasyICS.
+ * Simple ICS data generator
+ * @package phpmailer
+ * @subpackage easypeasyics
+ */
+class EasyPeasyICS
+{
+    /**
+     * The name of the calendar
+     * @var string
+     */
+    protected $calendarName;
+    /**
+     * The array of events to add to this calendar
+     * @var array
+     */
+    protected $events = array();
+
+    /**
+     * Constructor
+     * @param string $calendarName
+     */
+    public function __construct($calendarName = "")
+    {
+        $this->calendarName = $calendarName;
+    }
+
+    /**
+     * Add an event to this calendar.
+     * @param string $start The start date and time as a unix timestamp
+     * @param string $end The end date and time as a unix timestamp
+     * @param string $summary A summary or title for the event
+     * @param string $description A description of the event
+     * @param string $url A URL for the event
+     * @param string $uid A unique identifier for the event - generated automatically if not provided
+     * @return array An array of event details, including any generated UID
+     */
+    public function addEvent($start, $end, $summary = '', $description = '', $url = '', $uid = '')
+    {
+        if (empty($uid)) {
+            $uid = md5(uniqid(mt_rand(), true)) . '@EasyPeasyICS';
+        }
+        $event = array(
+            'start' => gmdate('Ymd', $start) . 'T' . gmdate('His', $start) . 'Z',
+            'end' => gmdate('Ymd', $end) . 'T' . gmdate('His', $end) . 'Z',
+            'summary' => $summary,
+            'description' => $description,
+            'url' => $url,
+            'uid' => $uid
+        );
+        $this->events[] = $event;
+        return $event;
+    }
+
+    /**
+     * @return array Get the array of events.
+     */
+    public function getEvents()
+    {
+        return $this->events;
+    }
+
+    /**
+     * Clear all events.
+     */
+    public function clearEvents()
+    {
+        $this->events = array();
+    }
+
+    /**
+     * Get the name of the calendar.
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->calendarName;
+    }
+
+    /**
+     * Set the name of the calendar.
+     * @param $name
+     */
+    public function setName($name)
+    {
+        $this->calendarName = $name;
+    }
+
+    /**
+     * Render and optionally output a vcal string.
+     * @param bool $output Whether to output the calendar data directly (the default).
+     * @return string The complete rendered vlal
+     */
+    public function render($output = true)
+    {
+        //Add header
+        $ics = 'BEGIN:VCALENDAR
+METHOD:PUBLISH
+VERSION:2.0
+X-WR-CALNAME:' . $this->calendarName . '
+PRODID:-//hacksw/handcal//NONSGML v1.0//EN';
+
+        //Add events
+        foreach ($this->events as $event) {
+            $ics .= '
+BEGIN:VEVENT
+UID:' . $event['uid'] . '
+DTSTAMP:' . gmdate('Ymd') . 'T' . gmdate('His') . 'Z
+DTSTART:' . $event['start'] . '
+DTEND:' . $event['end'] . '
+SUMMARY:' . str_replace("\n", "\\n", $event['summary']) . '
+DESCRIPTION:' . str_replace("\n", "\\n", $event['description']) . '
+URL;VALUE=URI:' . $event['url'] . '
+END:VEVENT';
+        }
+
+        //Add footer
+        $ics .= '
+END:VCALENDAR';
+
+        if ($output) {
+            //Output
+            $filename = $this->calendarName;
+            //Filename needs quoting if it contains spaces
+            if (strpos($filename, ' ') !== false) {
+                $filename = '"'.$filename.'"';
+            }
+            header('Content-type: text/calendar; charset=utf-8');
+            header('Content-Disposition: inline; filename=' . $filename . '.ics');
+            echo $ics;
+        }
+        return $ics;
+    }
+}

Різницю між файлами не показано, бо вона завелика
+ 17 - 0
application/libraries/PHPMail/extras/README.md


Різницю між файлами не показано, бо вона завелика
+ 1159 - 0
application/libraries/PHPMail/extras/htmlfilter.php


+ 185 - 0
application/libraries/PHPMail/extras/ntlm_sasl_client.php

@@ -0,0 +1,185 @@
+<?php
+/*
+ * ntlm_sasl_client.php
+ *
+ * @(#) $Id: ntlm_sasl_client.php,v 1.3 2004/11/17 08:00:37 mlemos Exp $
+ *
+ */
+
+define("SASL_NTLM_STATE_START", 0);
+define("SASL_NTLM_STATE_IDENTIFY_DOMAIN", 1);
+define("SASL_NTLM_STATE_RESPOND_CHALLENGE", 2);
+define("SASL_NTLM_STATE_DONE", 3);
+define("SASL_FAIL", -1);
+define("SASL_CONTINUE", 1);
+
+class ntlm_sasl_client_class
+{
+    public $credentials = array();
+    public $state = SASL_NTLM_STATE_START;
+
+    public function initialize(&$client)
+    {
+        if (!function_exists($function = "mcrypt_encrypt")
+            || !function_exists($function = "mhash")
+        ) {
+            $extensions = array(
+                "mcrypt_encrypt" => "mcrypt",
+                "mhash" => "mhash"
+            );
+            $client->error = "the extension " . $extensions[$function] .
+                " required by the NTLM SASL client class is not available in this PHP configuration";
+            return (0);
+        }
+        return (1);
+    }
+
+    public function ASCIIToUnicode($ascii)
+    {
+        for ($unicode = "", $a = 0; $a < strlen($ascii); $a++) {
+            $unicode .= substr($ascii, $a, 1) . chr(0);
+        }
+        return ($unicode);
+    }
+
+    public function typeMsg1($domain, $workstation)
+    {
+        $domain_length = strlen($domain);
+        $workstation_length = strlen($workstation);
+        $workstation_offset = 32;
+        $domain_offset = $workstation_offset + $workstation_length;
+        return (
+            "NTLMSSP\0" .
+            "\x01\x00\x00\x00" .
+            "\x07\x32\x00\x00" .
+            pack("v", $domain_length) .
+            pack("v", $domain_length) .
+            pack("V", $domain_offset) .
+            pack("v", $workstation_length) .
+            pack("v", $workstation_length) .
+            pack("V", $workstation_offset) .
+            $workstation .
+            $domain
+        );
+    }
+
+    public function NTLMResponse($challenge, $password)
+    {
+        $unicode = $this->ASCIIToUnicode($password);
+        $md4 = mhash(MHASH_MD4, $unicode);
+        $padded = $md4 . str_repeat(chr(0), 21 - strlen($md4));
+        $iv_size = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_ECB);
+        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
+        for ($response = "", $third = 0; $third < 21; $third += 7) {
+            for ($packed = "", $p = $third; $p < $third + 7; $p++) {
+                $packed .= str_pad(decbin(ord(substr($padded, $p, 1))), 8, "0", STR_PAD_LEFT);
+            }
+            for ($key = "", $p = 0; $p < strlen($packed); $p += 7) {
+                $s = substr($packed, $p, 7);
+                $b = $s . ((substr_count($s, "1") % 2) ? "0" : "1");
+                $key .= chr(bindec($b));
+            }
+            $ciphertext = mcrypt_encrypt(MCRYPT_DES, $key, $challenge, MCRYPT_MODE_ECB, $iv);
+            $response .= $ciphertext;
+        }
+        return $response;
+    }
+
+    public function typeMsg3($ntlm_response, $user, $domain, $workstation)
+    {
+        $domain_unicode = $this->ASCIIToUnicode($domain);
+        $domain_length = strlen($domain_unicode);
+        $domain_offset = 64;
+        $user_unicode = $this->ASCIIToUnicode($user);
+        $user_length = strlen($user_unicode);
+        $user_offset = $domain_offset + $domain_length;
+        $workstation_unicode = $this->ASCIIToUnicode($workstation);
+        $workstation_length = strlen($workstation_unicode);
+        $workstation_offset = $user_offset + $user_length;
+        $lm = "";
+        $lm_length = strlen($lm);
+        $lm_offset = $workstation_offset + $workstation_length;
+        $ntlm = $ntlm_response;
+        $ntlm_length = strlen($ntlm);
+        $ntlm_offset = $lm_offset + $lm_length;
+        $session = "";
+        $session_length = strlen($session);
+        $session_offset = $ntlm_offset + $ntlm_length;
+        return (
+            "NTLMSSP\0" .
+            "\x03\x00\x00\x00" .
+            pack("v", $lm_length) .
+            pack("v", $lm_length) .
+            pack("V", $lm_offset) .
+            pack("v", $ntlm_length) .
+            pack("v", $ntlm_length) .
+            pack("V", $ntlm_offset) .
+            pack("v", $domain_length) .
+            pack("v", $domain_length) .
+            pack("V", $domain_offset) .
+            pack("v", $user_length) .
+            pack("v", $user_length) .
+            pack("V", $user_offset) .
+            pack("v", $workstation_length) .
+            pack("v", $workstation_length) .
+            pack("V", $workstation_offset) .
+            pack("v", $session_length) .
+            pack("v", $session_length) .
+            pack("V", $session_offset) .
+            "\x01\x02\x00\x00" .
+            $domain_unicode .
+            $user_unicode .
+            $workstation_unicode .
+            $lm .
+            $ntlm
+        );
+    }
+
+    public function start(&$client, &$message, &$interactions)
+    {
+        if ($this->state != SASL_NTLM_STATE_START) {
+            $client->error = "NTLM authentication state is not at the start";
+            return (SASL_FAIL);
+        }
+        $this->credentials = array(
+            "user" => "",
+            "password" => "",
+            "realm" => "",
+            "workstation" => ""
+        );
+        $defaults = array();
+        $status = $client->GetCredentials($this->credentials, $defaults, $interactions);
+        if ($status == SASL_CONTINUE) {
+            $this->state = SASL_NTLM_STATE_IDENTIFY_DOMAIN;
+        }
+        unset($message);
+        return ($status);
+    }
+
+    public function step(&$client, $response, &$message, &$interactions)
+    {
+        switch ($this->state) {
+            case SASL_NTLM_STATE_IDENTIFY_DOMAIN:
+                $message = $this->typeMsg1($this->credentials["realm"], $this->credentials["workstation"]);
+                $this->state = SASL_NTLM_STATE_RESPOND_CHALLENGE;
+                break;
+            case SASL_NTLM_STATE_RESPOND_CHALLENGE:
+                $ntlm_response = $this->NTLMResponse(substr($response, 24, 8), $this->credentials["password"]);
+                $message = $this->typeMsg3(
+                    $ntlm_response,
+                    $this->credentials["user"],
+                    $this->credentials["realm"],
+                    $this->credentials["workstation"]
+                );
+                $this->state = SASL_NTLM_STATE_DONE;
+                break;
+            case SASL_NTLM_STATE_DONE:
+                $client->error = "NTLM authentication was finished without success";
+                return (SASL_FAIL);
+            default:
+                $client->error = "invalid NTLM authentication step state";
+                return (SASL_FAIL);
+        }
+        return (SASL_CONTINUE);
+    }
+}

+ 162 - 0
application/libraries/PHPMail/get_oauth_token.php

@@ -0,0 +1,162 @@
+<?php
+/**
+ * Get an OAuth2 token from Google.
+ * * Install this script on your server so that it's accessible
+ * as [https/http]://<yourdomain>/<folder>/get_oauth_token.php
+ * e.g.: http://localhost/phpmail/get_oauth_token.php
+ * * Ensure dependencies are installed with 'composer install'
+ * * Set up an app in your Google developer console
+ * * Set the script address as the app's redirect URL
+ * If no refresh token is obtained when running this file, revoke access to your app
+ * using link: https://accounts.google.com/b/0/IssuedAuthSubTokens and run the script again.
+ * This script requires PHP 5.4 or later
+ * PHP Version 5.4
+ */
+
+namespace League\OAuth2\Client\Provider;
+
+require 'vendor/autoload.php';
+
+use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
+use League\OAuth2\Client\Token\AccessToken;
+use League\OAuth2\Client\Tool\BearerAuthorizationTrait;
+use Psr\Http\Message\ResponseInterface;
+
+session_start();
+
+//If this automatic URL doesn't work, set it yourself manually
+$redirectUri = isset($_SERVER['HTTPS']) ? 'https://' : 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
+//$redirectUri = 'http://localhost/phpmailer/get_oauth_token.php';
+
+//These details obtained are by setting up app in Google developer console.
+$clientId = 'RANDOMCHARS-----duv1n2.apps.googleusercontent.com';
+$clientSecret = 'RANDOMCHARS-----lGyjPcRtvP';
+
+class Google extends AbstractProvider
+{
+    use BearerAuthorizationTrait;
+
+    const ACCESS_TOKEN_RESOURCE_OWNER_ID = 'id';
+
+    /**
+     * @var string If set, this will be sent to google as the "access_type" parameter.
+     * @link https://developers.google.com/accounts/docs/OAuth2WebServer#offline
+     */
+    protected $accessType;
+
+    /**
+     * @var string If set, this will be sent to google as the "hd" parameter.
+     * @link https://developers.google.com/accounts/docs/OAuth2Login#hd-param
+     */
+    protected $hostedDomain;
+
+    /**
+     * @var string If set, this will be sent to google as the "scope" parameter.
+     * @link https://developers.google.com/gmail/api/auth/scopes
+     */
+    protected $scope;
+
+    public function getBaseAuthorizationUrl()
+    {
+        return 'https://accounts.google.com/o/oauth2/auth';
+    }
+
+    public function getBaseAccessTokenUrl(array $params)
+    {
+        return 'https://accounts.google.com/o/oauth2/token';
+    }
+
+    public function getResourceOwnerDetailsUrl(AccessToken $token)
+    {
+	return ' ';
+    }
+
+    protected function getAuthorizationParameters(array $options)
+    {
+	if (is_array($this->scope)) {
+            $separator = $this->getScopeSeparator();
+            $this->scope = implode($separator, $this->scope);
+        }
+
+        $params = array_merge(
+            parent::getAuthorizationParameters($options),
+            array_filter([
+                'hd'          => $this->hostedDomain,
+                'access_type' => $this->accessType,
+		'scope'       => $this->scope,
+                // if the user is logged in with more than one account ask which one to use for the login!
+                'authuser'    => '-1'
+            ])
+        );
+        return $params;
+    }
+
+    protected function getDefaultScopes()
+    {
+        return [
+            'email',
+            'openid',
+            'profile',
+        ];
+    }
+
+    protected function getScopeSeparator()
+    {
+        return ' ';
+    }
+
+    protected function checkResponse(ResponseInterface $response, $data)
+    {
+        if (!empty($data['error'])) {
+            $code  = 0;
+            $error = $data['error'];
+
+            if (is_array($error)) {
+                $code  = $error['code'];
+                $error = $error['message'];
+            }
+
+            throw new IdentityProviderException($error, $code, $data);
+        }
+    }
+
+    protected function createResourceOwner(array $response, AccessToken $token)
+    {
+        return new GoogleUser($response);
+    }
+}
+
+
+//Set Redirect URI in Developer Console as [https/http]://<yourdomain>/<folder>/get_oauth_token.php
+$provider = new Google(
+    array(
+        'clientId' => $clientId,
+        'clientSecret' => $clientSecret,
+        'redirectUri' => $redirectUri,
+        'scope' => array('https://mail.google.com/'),
+	'accessType' => 'offline'
+    )
+);
+
+if (!isset($_GET['code'])) {
+    // If we don't have an authorization code then get one
+    $authUrl = $provider->getAuthorizationUrl();
+    $_SESSION['oauth2state'] = $provider->getState();
+    header('Location: ' . $authUrl);
+    exit;
+// Check given state against previously stored one to mitigate CSRF attack
+} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
+    unset($_SESSION['oauth2state']);
+    exit('Invalid state');
+} else {
+    // Try to get an access token (using the authorization code grant)
+    $token = $provider->getAccessToken(
+        'authorization_code',
+        array(
+            'code' => $_GET['code']
+        )
+    );
+
+    // Use this to get a new access token if the old one expires
+    echo 'Refresh Token: ' . $token->getRefreshToken();
+}

+ 26 - 0
application/libraries/PHPMail/language/phpmailer.lang-am.php

@@ -0,0 +1,26 @@
+<?php
+/**
+ * Armenian PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Hrayr Grigoryan <hrayr@bits.am>
+ */
+ 
+$PHPMAILER_LANG['authenticate']         = 'SMTP -ի սխալ: չհաջողվեց ստուգել իսկությունը.';
+$PHPMAILER_LANG['connect_host']         = 'SMTP -ի սխալ: չհաջողվեց կապ հաստատել SMTP սերվերի հետ.';
+$PHPMAILER_LANG['data_not_accepted']    = 'SMTP -ի սխալ: տվյալները ընդունված չեն.';
+$PHPMAILER_LANG['empty_message']        = 'Հաղորդագրությունը դատարկ է';
+$PHPMAILER_LANG['encoding']             = 'Կոդավորման անհայտ տեսակ: ';
+$PHPMAILER_LANG['execute']              = 'Չհաջողվեց իրականացնել հրամանը: ';
+$PHPMAILER_LANG['file_access']          = 'Ֆայլը հասանելի չէ: ';
+$PHPMAILER_LANG['file_open']            = 'Ֆայլի սխալ: ֆայլը չհաջողվեց բացել: ';
+$PHPMAILER_LANG['from_failed']          = 'Ուղարկողի հետևյալ հասցեն սխալ է: ';
+$PHPMAILER_LANG['instantiate']          = 'Հնարավոր չէ կանչել mail ֆունկցիան.';
+$PHPMAILER_LANG['invalid_address']      = 'Հասցեն սխալ է: ';
+$PHPMAILER_LANG['mailer_not_supported'] = ' փոստային սերվերի հետ չի աշխատում.';
+$PHPMAILER_LANG['provide_address']      = 'Անհրաժեշտ է տրամադրել գոնե մեկ ստացողի e-mail հասցե.';
+$PHPMAILER_LANG['recipients_failed']    = 'SMTP -ի սխալ: չի հաջողվել ուղարկել հետևյալ ստացողների հասցեներին: ';
+$PHPMAILER_LANG['signing']              = 'Ստորագրման սխալ: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP -ի connect() ֆունկցիան չի հաջողվել';
+$PHPMAILER_LANG['smtp_error']           = 'SMTP սերվերի սխալ: ';
+$PHPMAILER_LANG['variable_set']         = 'Չի հաջողվում ստեղծել կամ վերափոխել փոփոխականը: ';
+$PHPMAILER_LANG['extension_missing']    = 'Հավելվածը բացակայում է: ';

+ 0 - 0
application/libraries/PHPMail/language/phpmailer.lang-ar.php


Деякі файли не було показано, через те що забагато файлів було змінено