diff --git a/admin/core/HD_Controller.php b/admin/core/HD_Controller.php index df79a802..caf7af96 100644 --- a/admin/core/HD_Controller.php +++ b/admin/core/HD_Controller.php @@ -14,7 +14,7 @@ abstract class HD_Controller extends CI_Controller public $data = array(), $if_ajax = false; - public $city_lists = [430, 350]; //开发城市湖南 福建 + public $city_lists = [430, 350]; //开发城省份 湖南 福建 public function __construct() { diff --git a/api/.htaccess b/api/.htaccess index 83097d23..6c63ed4c 100644 --- a/api/.htaccess +++ b/api/.htaccess @@ -1,6 +1,6 @@ - - Require all denied - - - Deny from all + + Require all denied + + + Deny from all \ No newline at end of file diff --git a/api/cache/index.html b/api/cache/index.html index b48b4908..b702fbc3 100644 --- a/api/cache/index.html +++ b/api/cache/index.html @@ -1,11 +1,11 @@ - - - - 403 Forbidden - - - -

Directory access is forbidden.

- - - + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/api/config/alipay.php b/api/config/alipay.php index bc1d1604..dbea1eea 100644 --- a/api/config/alipay.php +++ b/api/config/alipay.php @@ -1,14 +1,14 @@ - [ - 'app_id' => '2021000118631895', - 'private_key' => 'MIIEpAIBAAKCAQEAk/KCpSBSJT8Ym6E2q8RhWXj6RHxP0orUOey/5pihXRj0UzQQiiB8pIb5TcB7G8bFSszhgao7DiObYnWUUvUpAGG8tL7aC+Td7JL11PR5Bv1e1HnymCrNWr/LrUAFBpmQ5480/BAX04SZh/RXRrYiM+L5JSRFwiiXaQ2lc9Q1oa+paKe6d19ZiHZ50JN9I9HLPmqchOLK+yIRRPyPoc0TOI7bz1kEW+U76/S+nE8RmSKq+LvDgWzgi4lIt1NXxfSU6z+MAtQHAF6TFeglquGnvFOHU/MkCPQ/+57n31L7DTEGsaLcUZfkipE70nlrYrJgE/jrqQLW4TsRPhJT2bUx4wIDAQABAoIBAHqCCeSqSttE0B+u8xJw3xuzrakgNwjkpLACdzV/lb79dvOe3UNDe3LRwYa8qDRr99rkpKc2Swh+O6DgNB4tm/IQ/K2+i9flgE7xslbQyZccH3ZaNKQEbV+ECihAJuk8KF1WnE1NFi20U13c2phXISNOA3jZ/Fm2Owpmnma3hmGHRbiXImsLhIDFl035Ekt605plriy6yvm6wyvdGGATQsXxDQ0CcOlWdgug7U+vyIc/afRC2kj/afVFqLFyUT2Xo1nTeedwTTSQ/rXRIurdLUVm75SDP1mdoAC+wMd/6LgY7byKPxlSslyaBm73o95feu7sV2dXhDipwThI+p1dQiECgYEA8wwk+l9Cxw5qZPtOXmLMUoqOtkESnZLIaFusm5Z0E1zdZhessVHQmWQ5RsVvYGYvcCG0ujTWNi6sq1fiPeZKnZj+r9Cy8UCQDssS3pV0jvy6ozKZvRMGzugQx3cPrmjwHO3Z6ycrtvz+la/H4VsWwdid8Tx1/KifHJq7XXQ3R/cCgYEAm9TuQOebvBA325rBJZnX6Ats6E9un9j5FRh7/j9CRHFFZmec79NX+306GH1j7WWO0g9nusQKysu9W54S37gIwta9h+46Hxq1bIqctDlL2SpgsZT8ZV8ejQePZwsaEaMh68u1yplPHuUWP4T+LEcH3X1E8l5KQ8Gg/B6aQXKRonUCgYEAqinKifDAFBWnr+OyzqplWzTfDgMpQWFPJqFoi9Yelp/h8mSI5+zcG0jsQPxiKh/g/qTan7P2diDfi2cQYz4k54oCZp27auVE9tZ+84+395RCJ5h5wsLbdWlMthpJxFZ8JgTxGY5nMMqYg7x6OPFJUZaTnh4yjR6Rp7k9jQSc36kCgYA5LQFWEyTS9ehozPk9QJs1aqvE+RAP2l5Z3Sfxe2hnEGB0WGP+or7PaX0dazR08CRc8oYOwstq6SJLMU6fgzjDtGLKMyBkNTqH3rvsbHFl9uSPg6iv0Ry2hiWZmzsvaXmSuKW09ldPcKKfH77apB1AqSvY+bup7KuSle/nP5Ar2QKBgQCbufjQ4I7Iej+KLz8/WVDIWa2to0tkQGxCUoVqxIxRQW8lHhRu5v9Y/gQ6d8dvx7rXb6V0VDf1joPFxnu3FwwMteMpQ8VrbH9vyqktSwCvU5t2dolcpv0MeePz9NPYdmz/MA/YIOmiUt0CVmca4q8WDNtJqjxShoIdbTH9oFXkeQ==', - 'public_key' => 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0FzytqTSTh3o8/Lbryi76MxKpOjJM4tho8HlzpOHFfPZ9JEnEQ+ddNcoSQaNfWJU3T73BDfNoaOZllWB13pvU3D/ZWGYkAJRLX4jT97Xvf9SYwyoEt5R2FTRQWBJT3N7sPX8NoM+dvEeqA9LgwY5Z6sIu9SxouPsfzCJSKjCmlcDoZJ1xjxusrqQF6gLkPW1loPFwx2xUQUFrGW4q1Yd8XwiqgljCqrLwi2tnZ3r5YOI1bIL589olUHf2KdNtH6KN7pC2+I5ovKEvuAZk7X6tPxYbxy5GSU1rWNhhNLpRL/RBTt+3dlqW/yadf/c3dHGVygSMo90KrG9uuOp/q5BQIDAQAB', - ] -]; + [ + 'app_id' => '2021000118631895', + 'private_key' => 'MIIEpAIBAAKCAQEAk/KCpSBSJT8Ym6E2q8RhWXj6RHxP0orUOey/5pihXRj0UzQQiiB8pIb5TcB7G8bFSszhgao7DiObYnWUUvUpAGG8tL7aC+Td7JL11PR5Bv1e1HnymCrNWr/LrUAFBpmQ5480/BAX04SZh/RXRrYiM+L5JSRFwiiXaQ2lc9Q1oa+paKe6d19ZiHZ50JN9I9HLPmqchOLK+yIRRPyPoc0TOI7bz1kEW+U76/S+nE8RmSKq+LvDgWzgi4lIt1NXxfSU6z+MAtQHAF6TFeglquGnvFOHU/MkCPQ/+57n31L7DTEGsaLcUZfkipE70nlrYrJgE/jrqQLW4TsRPhJT2bUx4wIDAQABAoIBAHqCCeSqSttE0B+u8xJw3xuzrakgNwjkpLACdzV/lb79dvOe3UNDe3LRwYa8qDRr99rkpKc2Swh+O6DgNB4tm/IQ/K2+i9flgE7xslbQyZccH3ZaNKQEbV+ECihAJuk8KF1WnE1NFi20U13c2phXISNOA3jZ/Fm2Owpmnma3hmGHRbiXImsLhIDFl035Ekt605plriy6yvm6wyvdGGATQsXxDQ0CcOlWdgug7U+vyIc/afRC2kj/afVFqLFyUT2Xo1nTeedwTTSQ/rXRIurdLUVm75SDP1mdoAC+wMd/6LgY7byKPxlSslyaBm73o95feu7sV2dXhDipwThI+p1dQiECgYEA8wwk+l9Cxw5qZPtOXmLMUoqOtkESnZLIaFusm5Z0E1zdZhessVHQmWQ5RsVvYGYvcCG0ujTWNi6sq1fiPeZKnZj+r9Cy8UCQDssS3pV0jvy6ozKZvRMGzugQx3cPrmjwHO3Z6ycrtvz+la/H4VsWwdid8Tx1/KifHJq7XXQ3R/cCgYEAm9TuQOebvBA325rBJZnX6Ats6E9un9j5FRh7/j9CRHFFZmec79NX+306GH1j7WWO0g9nusQKysu9W54S37gIwta9h+46Hxq1bIqctDlL2SpgsZT8ZV8ejQePZwsaEaMh68u1yplPHuUWP4T+LEcH3X1E8l5KQ8Gg/B6aQXKRonUCgYEAqinKifDAFBWnr+OyzqplWzTfDgMpQWFPJqFoi9Yelp/h8mSI5+zcG0jsQPxiKh/g/qTan7P2diDfi2cQYz4k54oCZp27auVE9tZ+84+395RCJ5h5wsLbdWlMthpJxFZ8JgTxGY5nMMqYg7x6OPFJUZaTnh4yjR6Rp7k9jQSc36kCgYA5LQFWEyTS9ehozPk9QJs1aqvE+RAP2l5Z3Sfxe2hnEGB0WGP+or7PaX0dazR08CRc8oYOwstq6SJLMU6fgzjDtGLKMyBkNTqH3rvsbHFl9uSPg6iv0Ry2hiWZmzsvaXmSuKW09ldPcKKfH77apB1AqSvY+bup7KuSle/nP5Ar2QKBgQCbufjQ4I7Iej+KLz8/WVDIWa2to0tkQGxCUoVqxIxRQW8lHhRu5v9Y/gQ6d8dvx7rXb6V0VDf1joPFxnu3FwwMteMpQ8VrbH9vyqktSwCvU5t2dolcpv0MeePz9NPYdmz/MA/YIOmiUt0CVmca4q8WDNtJqjxShoIdbTH9oFXkeQ==', + 'public_key' => 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0FzytqTSTh3o8/Lbryi76MxKpOjJM4tho8HlzpOHFfPZ9JEnEQ+ddNcoSQaNfWJU3T73BDfNoaOZllWB13pvU3D/ZWGYkAJRLX4jT97Xvf9SYwyoEt5R2FTRQWBJT3N7sPX8NoM+dvEeqA9LgwY5Z6sIu9SxouPsfzCJSKjCmlcDoZJ1xjxusrqQF6gLkPW1loPFwx2xUQUFrGW4q1Yd8XwiqgljCqrLwi2tnZ3r5YOI1bIL589olUHf2KdNtH6KN7pC2+I5ovKEvuAZk7X6tPxYbxy5GSU1rWNhhNLpRL/RBTt+3dlqW/yadf/c3dHGVygSMo90KrG9uuOp/q5BQIDAQAB', + ] +]; diff --git a/api/config/app.php b/api/config/app.php index b9648207..ac3c5359 100644 --- a/api/config/app.php +++ b/api/config/app.php @@ -1,16 +1,23 @@ - array( - 'id' => 2, - 'app_id' => 2, - 'name' => '狸车宝', - 'sign_key' => '71fd71173b776766a2ae1209d9a2c2ed', - 'wx' => array( - 'appid' => 'wx4733380c110313ec', - 'secret' => 'cfa1bb15b671f919e959100c0b4070a2', - ), - 'model' => array('user_model' => 'app/licheb/app_licheb_users_model') - ), -); + array( + 'id' => 2, + 'app_id' => 2, + 'name' => '狸车宝', + 'sign_key' => '71fd71173b776766a2ae1209d9a2c2ed', + 'wx' => array( + 'appid' => 'wx4733380c110313ec', + 'secret' => 'cfa1bb15b671f919e959100c0b4070a2', + ), + 'model' => array('user_model' => 'app/licheb/app_licheb_users_model') + ) +); diff --git a/api/config/autoload.php b/api/config/autoload.php index 80cccc18..fd7e2734 100644 --- a/api/config/autoload.php +++ b/api/config/autoload.php @@ -1,135 +1,135 @@ - 'ua'); -*/ -$autoload['libraries'] = array('database'); - -/* -| ------------------------------------------------------------------- -| 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('comm', 'url', 'array','order'); - -/* -| ------------------------------------------------------------------- -| 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(); - -/* -| ------------------------------------------------------------------- -| 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(); + 'ua'); +*/ +$autoload['libraries'] = array('database'); + +/* +| ------------------------------------------------------------------- +| 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('comm', 'url', 'array','order'); + +/* +| ------------------------------------------------------------------- +| 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(); + +/* +| ------------------------------------------------------------------- +| 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(); diff --git a/api/config/config.php b/api/config/config.php index 74faa632..add5e679 100644 --- a/api/config/config.php +++ b/api/config/config.php @@ -1,523 +1,523 @@ -]+$/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'] = 1; - -/* -|-------------------------------------------------------------------------- -| 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'] = 'haodian.ai'; - -/* -|-------------------------------------------------------------------------- -| 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_test_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'] = ''; +]+$/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'] = 1; + +/* +|-------------------------------------------------------------------------- +| 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'] = 'haodian.ai'; + +/* +|-------------------------------------------------------------------------- +| 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_test_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'] = ''; diff --git a/api/config/constants.php b/api/config/constants.php index fbb93ac6..25483a15 100644 --- a/api/config/constants.php +++ b/api/config/constants.php @@ -1,109 +1,109 @@ -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' => 'mysql:host=127.0.0.1;port=3306;dbname=ssdb', - 'username' => 'devuser', - 'password' => 'DEV@hdy1234561', - 'database' => 'ssdb', - 'dbdriver' => 'pdo', - 'dbprefix' => 'lc_', - 'pconnect' => FALSE, - 'db_debug' => (ENVIRONMENT !== 'production'), - 'cache_on' => FALSE, - 'cachedir' => '', - 'char_set' => 'utf8mb4', - 'dbcollat' => 'utf8_general_ci', - 'swap_pre' => '', - 'encrypt' => FALSE, - 'compress' => FALSE, - 'stricton' => FALSE, - 'failover' => array(), - 'save_queries' => TRUE -); +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' => 'mysql:host=127.0.0.1;port=3306;dbname=ssdb', + 'username' => 'devuser', + 'password' => 'DEV@hdy123456', + 'database' => 'ssdb', + 'dbdriver' => 'pdo', + 'dbprefix' => 'lc_', + 'pconnect' => FALSE, + 'db_debug' => (ENVIRONMENT !== 'production'), + 'cache_on' => FALSE, + 'cachedir' => '', + 'char_set' => 'utf8mb4', + 'dbcollat' => 'utf8_general_ci', + 'swap_pre' => '', + 'encrypt' => FALSE, + 'compress' => FALSE, + 'stricton' => FALSE, + 'failover' => array(), + 'save_queries' => TRUE +); diff --git a/api/config/doctypes.php b/api/config/doctypes.php index f95451b2..59a7991e 100644 --- a/api/config/doctypes.php +++ b/api/config/doctypes.php @@ -1,24 +1,24 @@ - '', - 'xhtml1-strict' => '', - 'xhtml1-trans' => '', - 'xhtml1-frame' => '', - 'xhtml-basic11' => '', - 'html5' => '', - 'html4-strict' => '', - 'html4-trans' => '', - 'html4-frame' => '', - 'mathml1' => '', - 'mathml2' => '', - 'svg10' => '', - 'svg11' => '', - 'svg11-basic' => '', - 'svg11-tiny' => '', - 'xhtml-math-svg-xh' => '', - 'xhtml-math-svg-sh' => '', - 'xhtml-rdfa-1' => '', - 'xhtml-rdfa-2' => '' -); + '', + 'xhtml1-strict' => '', + 'xhtml1-trans' => '', + 'xhtml1-frame' => '', + 'xhtml-basic11' => '', + 'html5' => '', + 'html4-strict' => '', + 'html4-trans' => '', + 'html4-frame' => '', + 'mathml1' => '', + 'mathml2' => '', + 'svg10' => '', + 'svg11' => '', + 'svg11-basic' => '', + 'svg11-tiny' => '', + 'xhtml-math-svg-xh' => '', + 'xhtml-math-svg-sh' => '', + 'xhtml-rdfa-1' => '', + 'xhtml-rdfa-2' => '' +); diff --git a/api/config/foreign_chars.php b/api/config/foreign_chars.php index 3cd03b42..995f4830 100644 --- a/api/config/foreign_chars.php +++ b/api/config/foreign_chars.php @@ -1,103 +1,103 @@ - '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' -); + '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' +); diff --git a/api/config/hooks.php b/api/config/hooks.php index 038a2a73..a8f38a5d 100644 --- a/api/config/hooks.php +++ b/api/config/hooks.php @@ -1,13 +1,13 @@ - - - - 403 Forbidden - - - -

Directory access is forbidden.

- - - + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/api/config/memcached.php b/api/config/memcached.php index ad0ac6cf..40365917 100644 --- a/api/config/memcached.php +++ b/api/config/memcached.php @@ -1,19 +1,19 @@ - array( - 'hostname' => '192.168.0.16', - 'port' => '12001', - 'weight' => '1', - ), -); + array( + 'hostname' => '192.168.0.16', + 'port' => '12001', + 'weight' => '1', + ), +); diff --git a/api/config/migration.php b/api/config/migration.php index e26f3612..4b585a65 100644 --- a/api/config/migration.php +++ b/api/config/migration.php @@ -1,84 +1,84 @@ -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/'; +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/'; diff --git a/api/config/mimes.php b/api/config/mimes.php index 27f470a4..0ec9db0a 100644 --- a/api/config/mimes.php +++ b/api/config/mimes.php @@ -1,184 +1,184 @@ - 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', - '7z' => array('application/x-7z-compressed', 'application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'), - '7zip' => array('application/x-7z-compressed', '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' -); + 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', + '7z' => array('application/x-7z-compressed', 'application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'), + '7zip' => array('application/x-7z-compressed', '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' +); diff --git a/api/config/mongo.php b/api/config/mongo.php index 24445c2d..20df9c11 100644 --- a/api/config/mongo.php +++ b/api/config/mongo.php @@ -1,11 +1,11 @@ - my_controller/index -| my-controller/my-method -> my_controller/my_method -*/ -$route['default_controller'] = 'welcome'; -$route['404_override'] = ''; -$route['translate_uri_dashes'] = FALSE; + my_controller/index +| my-controller/my-method -> my_controller/my_method +*/ +$route['default_controller'] = 'welcome'; +$route['404_override'] = ''; +$route['translate_uri_dashes'] = FALSE; diff --git a/api/config/smileys.php b/api/config/smileys.php index 52ca4f30..abf9a898 100644 --- a/api/config/smileys.php +++ b/api/config/smileys.php @@ -1,64 +1,64 @@ - 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') - -); + 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') + +); diff --git a/api/config/sphinx.php b/api/config/sphinx.php index b6f509b7..f40308bf 100644 --- a/api/config/sphinx.php +++ b/api/config/sphinx.php @@ -1,6 +1,6 @@ - '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' => 'Edge', - 'Chrome' => 'Chrome', - // Opera 10+ always reports Opera/9.80 and appends 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' -); + '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' => 'Edge', + 'Chrome' => 'Chrome', + // Opera 10+ always reports Opera/9.80 and appends 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' +); diff --git a/api/config/wxpay.php b/api/config/wxpay.php index 0ba204e7..e71fa49d 100644 --- a/api/config/wxpay.php +++ b/api/config/wxpay.php @@ -1,19 +1,19 @@ - 'wxe66f905683582780', //服应用ID - 'mchid' => '1612096731', //商户号 - 'merchantSerialNumber' => '761590F1FF6DFC2466894F96E2DE1169CE644A74', //商户号API证书序列号 - 'merchantPrivateKey' => '/home/dev28/liche/api/third_party/WXconfig/apiclient_key.pem', //商户私钥路径 - 'wechatpayCertificate' => '/home/dev28/liche/api/third_party/WXconfig/apiclient_wechatpay.pem', //微信支付平台证书路径 - 'sub_appid' => 'wx98e64c11aac45966' //子商户应用ID -]; - + 'wxe66f905683582780', //服应用ID + 'mchid' => '1612096731', //商户号 + 'merchantSerialNumber' => '761590F1FF6DFC2466894F96E2DE1169CE644A74', //商户号API证书序列号 + 'merchantPrivateKey' => '/home/dev28/liche/api/third_party/WXconfig/apiclient_key.pem', //商户私钥路径 + 'wechatpayCertificate' => '/home/dev28/liche/api/third_party/WXconfig/apiclient_wechatpay.pem', //微信支付平台证书路径 + 'sub_appid' => 'wx98e64c11aac45966' //子商户应用ID +]; + diff --git a/api/config/xcall.php b/api/config/xcall.php index f3571d27..38dfa006 100644 --- a/api/config/xcall.php +++ b/api/config/xcall.php @@ -1,19 +1,19 @@ - 'licheb' - ); - - /** - * 错误信息映射到lang,数字不能使用 - */ - private static $err_lang = array( - API_CODE_SUCCESS => 'api_code_success', - API_CODE_FAIL => 'api_code_fail', - API_CODE_NONE => 'api_code_none', - API_CODE_LOGOUT => 'api_code_logout', - ); - - private $request; - private $inputs; - private $log_file = 'hd.log'; - - public function wxapp(){ - $callback = $_GET['callback']; - !$callback && $callback = $_POST['callback']; - trim($callback);//去掉首尾空白符 - $callback = $this->match_version($callback); - $callback = explode('.', $callback); - if(count($callback) > 2) { - $method_name = array_pop($callback); - $class_name = ucfirst(array_pop($callback)); - $dir = implode('/', $callback); - } else { - echo 'inval request'; - exit; - } - define('WECHATAPP', 1); - $file_name = APPPATH."controllers/wxapp/{$dir}/{$class_name}.php"; - if(file_exists($file_name)) { - require_once $file_name; - } else { - echo "class {$class_name} not exist";exit; - } - if($class_name == 'Welcome') { - $class = $this; - } else { - $class = new $class_name(); - }; - if(!$method_name || !method_exists($class, $method_name)) { - echo "method {$method_name} not exist"; - exit; - }; - - try{ - if(method_exists($class, 'check_login')){//校验登录 - $class->check_login($method_name); - } - $result = $class->$method_name(); - if(!$result) { - throw new Exception('', ERR_SYS_FAIL); - } - $this->print_return($result); - } catch (Exception $e) { - $this->print_return($this->return_error($e->getCode(), $e->getMessage())); - } - } - - /** - * 内容入口 - */ - function content(){ - define('WXAPP_CONTENT', 1); - - //加载输入参数 - $this->input_param(); - $version = $this->input_param('version'); - $sversion = $this->input_param('sversion'); - - $app_id = $this->input_param('app_id'); - - $this->log_file = get_class($this) . "_{$app_id}.log"; - - //卡ID为空 - $app = self::$apps[$app_id]; - if(!$app_id){ - debug_log("[fail]". __FUNCTION__ . ":app_id is null; uri_string:" . $this->uri->uri_string(), $this->log_file); - return $this->print_return($this->return_error(API_CODE_INVILD_PARAM, '应用不存在')); - } - //签名不正确 - if(!$this->vaild_sign()){ - debug_log("[fail]". __FUNCTION__ . ":sign check fail; uri_string:" . $this->uri->uri_string() . "; param:".json_encode($this->inputs), $this->log_file); - return $this->print_return($this->return_error(API_CODE_INVILD_PARAM, '验签失败')); - } - - $app = self::$apps[$app_id]; - $class_name = ucfirst($this->uri->segment(3));//:hd/content/subject/tag - if($this->uri->segment(4)){ - $method = $this->request . "_" . $this->uri->segment(4); - } else { - $method = $this->request; - } - - //app定制ct - $file_name = APPPATH."controllers/wxapp/content/{$app}/{$class_name}.php"; - //ct不存在 - if(file_exists($file_name)) { - require_once $file_name; - } else { - //app定制ct不存在,使用公共ct - $file_name = APPPATH."controllers/wxapp/content/{$class_name}.php"; - if(file_exists($file_name)) { - require_once $file_name; - } else{ - debug_log("[fail]". __FUNCTION__ . ": file '{$file_name}' not exist; method:{$method}, app_id:".$app_id, $this->log_file); - return $this->print_return($this->return_error(API_CODE_NONE, '内部错误')); - } - } - - try{ - $class = new $class_name($this->inputs, $app); - - $result = $class->$method($version, $sversion); - if(!$result) { - throw new Exception('', ERR_SYS_FAIL); - } - return $this->print_return($result); - } catch (Exception $e){ - return $this->print_return($this->return_error($e->getCode(), $e->getMessage())); - } - } - - /** - * app其他入口 - */ - function app(){ - define('WXAPP_APP', 1); - - //加载输入参数 - $this->input_param(); - - $app_id = $this->input_param('app_id'); - $version = $this->input_param('version'); - $sversion = $this->input_param('sversion'); - - $this->log_file = get_class($this) . "_{$app_id}.log"; - - $app = self::$apps[$app_id]; - $dir = $app; - //卡ID为空 - if(!$app_id){ - debug_log("[fail]". __FUNCTION__ . ": app_id is null; uri_string:" . $this->uri->uri_string(), $this->log_file); - return $this->print_return($this->return_error(API_CODE_INVILD_PARAM, '应用不存在'.$app_id)); - } - //签名不正确 - if(!$this->vaild_sign()){ - debug_log("[fail]". __FUNCTION__ . ": sign check fail; uri_string:" . $this->uri->uri_string() . "; param:".json_encode($this->inputs), $this->log_file); - return $this->print_return($this->return_error(API_CODE_INVILD_PARAM, '验签失败')); - } - - $class_name = ucfirst($this->uri->segment(3));//:hd/app/user/ukey - if($this->uri->segment(4)){ - $method = $this->request . "_" . $this->uri->segment(4); - } else { - $method = $this->request; - } - //app定制ct - $file_name = APPPATH."controllers/wxapp/{$app}/{$class_name}.php"; - //ct不存在 - if(file_exists($file_name)) { - require_once $file_name; - } else { - $file_name = APPPATH."controllers/wxapp/app/{$dir}/Self_{$class_name}.php"; - if(file_exists($file_name)){ - require_once $file_name; - $class_name = "Self_{$class_name}"; - } else { - //app定制ct不存在,使用公共ct - $file_name = APPPATH."controllers/wxapp/app/{$class_name}.php"; - if(file_exists($file_name)) { - require_once $file_name; - } else{ - debug_log("[fail]". __FUNCTION__ . ": file '{$file_name}' not exist; method:{$method}, app_id:".$app_id, $this->log_file); - return $this->print_return($this->return_error(API_CODE_NONE, '内部错误')); - } - } - } - - try{ - $class = new $class_name($this->inputs, $app); - - $result = $class->$method($version, $sversion); - if(!$result) { - throw new Exception('', ERR_SYS_FAIL); - } - return $this->print_return($result); - } catch (Exception $e){ - return $this->print_return($this->return_error($e->getCode(), $e->getMessage())); - } - } - /** - * 分销入口 - */ - public function distribution(){ - define('WXAPP_ITEMS', 1); - //加载输入参数 - $this->input_param(); - $app_id = $this->input_param('app_id'); - !$app_id && $app_id = $this->input_param('vipcard_id'); - $version = $this->input_param('version'); - $sversion = $this->input_param('sversion'); - - $this->log_file = get_class($this) . "_{$app_id}.log"; - - //应用ID为空 - if(!$app_id){ - debug_log("[fail]". __FUNCTION__ . ":app_id is null; uri_string:" . $this->uri->uri_string(), $this->log_file); - return $this->print_return($this->return_error(API_CODE_INVILD_PARAM, '请求丢失')); - } - //签名不正确 - if(!$this->vaild_sign()){ - debug_log("[fail]". __FUNCTION__ . ":sign check fail; uri_string:" . $this->uri->uri_string() . "; param:".json_encode($this->inputs), $this->log_file); - return $this->print_return($this->return_error(API_CODE_INVILD_PARAM, '非法请求')); - } - $app = self::$apps[$app_id]; - $class_name = ucfirst($this->uri->segment(3)); - if($this->uri->segment(4)){ - $method = $this->request . "_" . $this->uri->segment(4); - } else { - $method = $this->request; - } - //app定制ct - $file_name = APPPATH."controllers/wxapp/distribution/{$app}/{$class_name}.php"; - //ct不存在 - if(file_exists($file_name)) { - require_once $file_name; - } else { - //app定制ct不存在,使用公共ct - $file_name = APPPATH."controllers/wxapp/distribution/{$class_name}.php"; - if(file_exists($file_name)) { - require_once $file_name; - } else{ - debug_log("[fail]". __FUNCTION__ . ": file '{$file_name}' not exist; method:{$method}, app_id:".$app_id, $this->log_file); - return $this->print_return($this->return_error(API_CODE_NONE, '非法请求')); - } - } - try{ - $class = new $class_name($this->inputs, $app); - $result = $class->$method($version, $sversion); - if(!$result) { - throw new Exception('', ERR_SYS_FAIL); - } - return $this->print_return($result); - } catch (Exception $e){ - return $this->print_return($this->return_error($e->getCode(), $e->getMessage())); - } - } - - /** - * 博饼入口 - */ - public function bobing() - { - define('WXAPP_ITEMS', 1); - //加载输入参数 - $this->input_param(); - $app_id = $this->input_param('app_id'); - !$app_id && $app_id = $this->input_param('vipcard_id'); - $version = $this->input_param('version'); - $sversion = $this->input_param('sversion'); - - $this->log_file = get_class($this) . "_{$app_id}.log"; - - //应用ID为空 - if (!$app_id) { - debug_log("[fail]" . __FUNCTION__ . ":app_id is null; uri_string:" . $this->uri->uri_string(), $this->log_file); - return $this->print_return($this->return_error(API_CODE_INVILD_PARAM, '请求丢失')); - } - //签名不正确 - if (!$this->vaild_sign()) { - debug_log("[fail]" . __FUNCTION__ . ":sign check fail; uri_string:" . $this->uri->uri_string() . "; param:" . json_encode($this->inputs), $this->log_file); - return $this->print_return($this->return_error(API_CODE_INVILD_PARAM, '非法请求')); - } - $app = self::$apps[$app_id]; - $class_name = ucfirst($this->uri->segment(3)); - if ($this->uri->segment(4)) { - $method = $this->request . "_" . $this->uri->segment(4); - } else { - $method = $this->request; - } - //app定制ct - $file_name = APPPATH . "controllers/wxapp/bobing/{$app}/{$class_name}.php"; - //ct不存在 - if (file_exists($file_name)) { - require_once $file_name; - } else { - //app定制ct不存在,使用公共ct - $file_name = APPPATH . "controllers/wxapp/bobing/{$class_name}.php"; - if (file_exists($file_name)) { - require_once $file_name; - } else { - debug_log("[fail]" . __FUNCTION__ . ": file '{$file_name}' not exist; method:{$method}, app_id:" . $app_id, $this->log_file); - return $this->print_return($this->return_error(API_CODE_NONE, '非法请求')); - } - } - try { - $class = new $class_name($this->inputs, $app); - $result = $class->$method($version, $sversion); - if (!$result) { - throw new Exception('', ERR_SYS_FAIL); - } - return $this->print_return($result); - } catch (Exception $e) { - return $this->print_return($this->return_error($e->getCode(), $e->getMessage())); - } - } - - /** - * 推广素材入口 - */ - public function material() - { - define('WXAPP_ITEMS', 1); - //加载输入参数 - $this->input_param(); - $app_id = $this->input_param('app_id'); - !$app_id && $app_id = $this->input_param('vipcard_id'); - $version = $this->input_param('version'); - $sversion = $this->input_param('sversion'); - - $this->log_file = get_class($this) . "_{$app_id}.log"; - - //应用ID为空 - if (!$app_id) { - debug_log("[fail]" . __FUNCTION__ . ":app_id is null; uri_string:" . $this->uri->uri_string(), $this->log_file); - return $this->print_return($this->return_error(API_CODE_INVILD_PARAM, '请求丢失')); - } - //签名不正确 - if (!$this->vaild_sign()) { - debug_log("[fail]" . __FUNCTION__ . ":sign check fail; uri_string:" . $this->uri->uri_string() . "; param:" . json_encode($this->inputs), $this->log_file); - return $this->print_return($this->return_error(API_CODE_INVILD_PARAM, '非法请求')); - } - $app = self::$apps[$app_id]; - $class_name = ucfirst($this->uri->segment(3)); - if ($this->uri->segment(4)) { - $method = $this->request . "_" . $this->uri->segment(4); - } else { - $method = $this->request; - } - //app定制ct - $file_name = APPPATH . "controllers/wxapp/material/{$app}/{$class_name}.php"; - //ct不存在 - if (file_exists($file_name)) { - require_once $file_name; - } else { - //app定制ct不存在,使用公共ct - $file_name = APPPATH . "controllers/wxapp/material/{$class_name}.php"; - if (file_exists($file_name)) { - require_once $file_name; - } else { - debug_log("[fail]" . __FUNCTION__ . ": file '{$file_name}' not exist; method:{$method}, app_id:" . $app_id, $this->log_file); - return $this->print_return($this->return_error(API_CODE_NONE, '非法请求')); - } - } - try { - $class = new $class_name($this->inputs, $app); - $result = $class->$method($version, $sversion); - if (!$result) { - throw new Exception('', ERR_SYS_FAIL); - } - return $this->print_return($result); - } catch (Exception $e) { - return $this->print_return($this->return_error($e->getCode(), $e->getMessage())); - } - } - - /** - * 测试签名(开发环境) - */ - public function test_sign(){ - if(false === strpos($_SERVER['SERVER_NAME'], 'dev')){ - exit('forbidden'); - } - //加载输入参数 - $this->input_param(); - - $param = $this->inputs; - $app_id = $param['app_id']; - !$app_id && $app_id = $param['vipcard_id']; - $sign = strtoupper($param['sign']); - $nonce_str = $param['nonce_str']; - - unset($param['sign']); - - if(!$app_id || !$sign || !$nonce_str){ - exit(json_encode($param)); - } - - //根据biz_id 获取key - $app = self::$apps[$app_id]; - $this->config->load('app', true, true); - $configs = $this->config->item('app'); - $config = $configs[$app]; - $key = $config['sign_key']; - - //按字典序排序参数 - ksort($param); - $buff = ""; - foreach($param as $k => $v){ - if(!is_array($v) && strlen($v) > 0){ -// $buff .= $k . "=" . $v . "&"; - $buff .= $k . "=" . ($v) . "&"; - } - } - $buff = trim($buff, "&"); - //在string后加入KEY - $buff = $buff . "&key=" . $key; - //MD5加密并转大写 - $string = strtoupper(md5($buff)); - -// if($sign == $string){ -// return true; -// } - - $res = array('sign_input' => $sign, 'sign_output' => $string, 'buff' => $buff); - exit(json_encode($res)); - } - - /** - * 可能要被废弃 - * @param $err_code - * @param string $err_info - * @return array - */ - function error_msg($err_code, $err_info = "") - { - if(!$err_info) { - $this->lang->load('error_lang','zh'); - $err_info = $this->lang->line(self::$err_lang[$err_code], false); - } - return array('errCode' => $err_code, 'errMessage' => $err_info); - } - - /** - * 打印返回值 - * @param array $data - * @param bool $ifgzip - */ - private function print_return($data = array(), $ifgzip = false){ - - if(!isset($data['code'])){ - $msg = $data['msg'] ? $data['msg'] : '执行成功'; - $data = array('code' => 200, 'data' => $data, 'msg' => $msg); - } - - if($ifgzip) - { - header('Content-Type: application/json'); - header('Content-Encoding: gzip'); - echo gzencode(json_encode($data, JSON_UNESCAPED_UNICODE), 6); - exit; - } - else - { - $result = json_encode($data, JSON_UNESCAPED_UNICODE); - echo $result; - exit; - } - } - - /** - * 根据错误码输出 - * @param $code - * @param string $msg - * @return array - */ - private function return_error($code, $msg = ''){ - if(!$msg) { - $this->lang->load('error_lang','zh'); - $msg = $this->lang->line(self::$err_lang[$code], false); - } - return array('code' => $code, 'msg' => $msg); - } - - /** - * 匹配版本url - * @param $callback - * @param string $version - * @return mixed - */ - private function match_version($callback, $version = ''){ - $version_group = self::$verison; - $ver_arr = $version_group[$callback]; - $ck = $callback; - if(!$ver_arr){ - foreach($version_group as $k => $arr){ - if(0 === strpos($callback, $k)){ - $ver_arr = $arr; - $ck = $k; - break; - } - } - } - - if($ver_arr){ - if(!$version){ - $cv = reset($ver_arr); - } else { - foreach($ver_arr as $k => $v){ - $cmp = $this->vercmp($version, $k); - if($cmp >= 0){ - $cv = $v; - break; - } - } - } - } - - if(isset($cv)){ - $callback = str_replace($ck, $cv, $callback); - } - - return $callback; - } - - /** - * 比较版本号 - * @param $ver1 - * @param $ver2 - * @return int 1:$ver1 > $ver2; -1:$ver1 < $ver2; 0:$ver1 == $ver2; - */ - private function vercmp($ver1, $ver2){ - $v1_arr = explode('.', $ver1); - $v2_arr = explode('.', $ver2); - foreach($v1_arr as $k => $v){ - $sub = $v - $v2_arr[$k]; - if(0 != $sub){ - return $sub > 0 ? 1 : -1; - } - } - - return 0; - } - - /** - * 获取参数 - * @param string $key - * @return array|mixed - */ - private function input_param($key = ''){ - if($key){ - return $this->inputs[$key]; - } - - $request = $this->input->method(); - - switch($request){ - case 'post': - case 'put': - case 'delete': - $input = json_decode(file_get_contents('php://input'), true); - break; - default: - $input = $this->input->get(); - } - - $this->request = $request; - $this->inputs = $input; - return $this->inputs; - } - - /** - * 校验签名 - * @return bool - */ - private function vaild_sign(){ - $param = $this->inputs; - $app_id = $param['app_id']; - !$app_id && $app_id = $param['vipcard_id']; - $sign = strtoupper($param['sign']); - $nonce_str = $param['nonce_str']; - - unset($param['sign']); - - if(!$app_id || !$sign || !$nonce_str){ - debug_log("[fail]". __FUNCTION__ . ": not app_id, sign, nonce_str", $this->log_file); - return false; - } - - //根据biz_id 获取key - $app = self::$apps[$app_id]; - $this->config->load('app', true, true); - $configs = $this->config->item('app'); - $config = $configs[$app]; - $key = $config['sign_key']; - - //按字典序排序参数 - ksort($param); - $buff = ""; - foreach($param as $k => $v){ - if(!is_array($v) && strlen($v) > 0){ - $buff .= $k . "=" . ($v) . "&"; - } - } - $buff = trim($buff, "&"); - //在string后加入KEY - $buff = $buff . "&key=" . $key; - //MD5加密并转大写 - $string = strtoupper(md5($buff)); - - //var_dump($string); - //var_dump($buff); - if($sign == $string){ - return true; - } - - debug_log("[fail]". __FUNCTION__ . ": sign:{$sign}, check:{$string}, buff:{$buff}", $this->log_file); - return false; - } - - /** - * 上传图片 - * @throws Exception - */ - public function upimg(){ - $app = $this->input->post('app'); - $log_name = "{$app}_upimg.log"; - try { - if(!$app){ - throw new Exception('参数错误', API_CODE_INVILD_PARAM); - } - - //接收图片 - if (!$file = $_FILES['img']) { - throw new Exception('请选择图片', API_CODE_INVILD_PARAM); - } - - if (!$file['tmp_name']) {//太大的图片上传,这个参数会变成空的 - debug_log(json_encode($file), $log_name); - throw new Exception('参数错误', API_CODE_INVILD_PARAM); - } - debug_log("[info]". __FUNCTION__ . ": tmp_name:" . $file['tmp_name'] . ";size:" . filesize($file['tmp_name']), $log_name); - if (!file_exists(TEMP_PATH)){ - $oldumask = umask(0); - mkdir(TEMP_PATH, 0777, true); - umask($oldumask); - } - $tmp = TEMP_PATH . md5($file['name'] . uniqid()) . substr($file['name'], strpos($file['name'], '.', strlen($file['name']) - 1)); - move_uploaded_file($file['tmp_name'], $tmp); - debug_log("[info]". __FUNCTION__ . "tmp:$tmp;size:" . filesize($tmp), $log_name); - - if (!filesize($tmp)) { - throw new Exception('图片有点问题,换个小的试试', API_CODE_INVILD_PARAM); - } - //上传图片到FTP - $res = $this->upload_img_qiniu($tmp,"{$app}/"); - if (!$res) { - throw new Exception('上传失败', API_CODE_FAIL); - } - - $data['full_url'] = build_qiniu_image_url($res['photo']); - $data['url'] = $res['photo']; - debug_log("[info]". __FUNCTION__ . "full_url:" . $data['full_url'], $log_name); - $this->print_return($data); - } catch (Exception $e) { - $message = $e->getMessage(); - $this->print_return($this->return_error($e->getCode(), $message)); - } - } - - /** - * @param string $file 上传的文件 - * @param string $path 要保存的目录 - * @param string $filename 原始文件名称 - * @throws Exception - * @return array - */ - private function upload_img_qiniu($file, $path = '',$filename = ''){ - $phoId = md5(uniqid().mt_rand(0,10000).time()); - - $filename = $filename ? $filename : $file; - $ext_arr = explode(".", $filename); - $ext = count($ext_arr)>1?$ext_arr[count($ext_arr)-1]:'jpg'; - - if (is_uploaded_file($file)) { - //上传图片 - $oriPath = TEMP_PATH . '/p_' . $phoId . '_ori.' . $ext; - move_uploaded_file($file, $oriPath); - } else { - $oriPath = $file; - } - - $oriKey = 'p_' . $phoId . '.' . $ext; - - // 上传到七牛后保存的文件名 - $photo = $path .date('Ym') . "/" . $oriKey; - - //上传图片到FTP - $this->load->library('qiniu'); - $res= $this->qiniu->save($photo, file_get_contents($oriPath)); - - $img_size = getimagesize($oriPath); - $file_size = filesize($oriPath); - $size = "{$img_size[0]},{$img_size[1]},{$file_size}"; - - unlink($oriPath); - if ($res) { - $size = getimagesize($res['url']); - return array('photo' => $res['file'], 'size' => $size); - } else { - return array(); - } - } -} + 'liche', + '1c156bb57cd6984a' => 'licheb', + 'fba9a12d2cd8599a' => 'neta', + ); + + /** + * 错误信息映射到lang,数字不能使用 + */ + private static $err_lang = array( + API_CODE_SUCCESS => 'api_code_success', + API_CODE_FAIL => 'api_code_fail', + API_CODE_NONE => 'api_code_none', + API_CODE_LOGOUT => 'api_code_logout', + ); + + private $request; + private $inputs; + private $log_file = 'hd.log'; + + public function wxapp(){ + $callback = $_GET['callback']; + !$callback && $callback = $_POST['callback']; + trim($callback);//去掉首尾空白符 + $callback = $this->match_version($callback); + $callback = explode('.', $callback); + if(count($callback) > 2) { + $method_name = array_pop($callback); + $class_name = ucfirst(array_pop($callback)); + $dir = implode('/', $callback); + } else { + echo 'inval request'; + exit; + } + define('WECHATAPP', 1); + $file_name = APPPATH."controllers/wxapp/{$dir}/{$class_name}.php"; + if(file_exists($file_name)) { + require_once $file_name; + } else { + echo "class {$class_name} not exist";exit; + } + if($class_name == 'Welcome') { + $class = $this; + } else { + $class = new $class_name(); + }; + if(!$method_name || !method_exists($class, $method_name)) { + echo "method {$method_name} not exist"; + exit; + }; + + try{ + if(method_exists($class, 'check_login')){//校验登录 + $class->check_login($method_name); + } + $result = $class->$method_name(); + if(!$result) { + throw new Exception('', ERR_SYS_FAIL); + } + $this->print_return($result); + } catch (Exception $e) { + $this->print_return($this->return_error($e->getCode(), $e->getMessage())); + } + } + + /** + * 内容入口 + */ + function content(){ + define('WXAPP_CONTENT', 1); + + //加载输入参数 + $this->input_param(); + $version = $this->input_param('version'); + $sversion = $this->input_param('sversion'); + + $app_id = $this->input_param('app_id'); + + $this->log_file = get_class($this) . "_{$app_id}.log"; + + //卡ID为空 + $app = self::$apps[$app_id]; + if(!$app_id){ + debug_log("[fail]". __FUNCTION__ . ":app_id is null; uri_string:" . $this->uri->uri_string(), $this->log_file); + return $this->print_return($this->return_error(API_CODE_INVILD_PARAM, '应用不存在')); + } + //签名不正确 + if(!$this->vaild_sign()){ + debug_log("[fail]". __FUNCTION__ . ":sign check fail; uri_string:" . $this->uri->uri_string() . "; param:".json_encode($this->inputs), $this->log_file); + return $this->print_return($this->return_error(API_CODE_INVILD_PARAM, '验签失败')); + } + + $app = self::$apps[$app_id]; + $class_name = ucfirst($this->uri->segment(3));//:hd/content/subject/tag + if($this->uri->segment(4)){ + $method = $this->request . "_" . $this->uri->segment(4); + } else { + $method = $this->request; + } + + //app定制ct + $file_name = APPPATH."controllers/wxapp/content/{$app}/{$class_name}.php"; + //ct不存在 + if(file_exists($file_name)) { + require_once $file_name; + } else { + //app定制ct不存在,使用公共ct + $file_name = APPPATH."controllers/wxapp/content/{$class_name}.php"; + if(file_exists($file_name)) { + require_once $file_name; + } else{ + debug_log("[fail]". __FUNCTION__ . ": file '{$file_name}' not exist; method:{$method}, app_id:".$app_id, $this->log_file); + return $this->print_return($this->return_error(API_CODE_NONE, '内部错误')); + } + } + + try{ + $class = new $class_name($this->inputs, $app); + + $result = $class->$method($version, $sversion); + if(!$result) { + throw new Exception('', ERR_SYS_FAIL); + } + return $this->print_return($result); + } catch (Exception $e){ + return $this->print_return($this->return_error($e->getCode(), $e->getMessage())); + } + } + + /** + * app其他入口 + */ + function app(){ + define('WXAPP_APP', 1); + + //加载输入参数 + $this->input_param(); + + $app_id = $this->input_param('app_id'); + $version = $this->input_param('version'); + $sversion = $this->input_param('sversion'); + + $this->log_file = get_class($this) . "_{$app_id}.log"; + + $app = self::$apps[$app_id]; + $dir = $app; + //卡ID为空 + if(!$app_id){ + debug_log("[fail]". __FUNCTION__ . ": app_id is null; uri_string:" . $this->uri->uri_string(), $this->log_file); + return $this->print_return($this->return_error(API_CODE_INVILD_PARAM, '应用不存在'.$app_id)); + } + //签名不正确 + if(!$this->vaild_sign()){ + debug_log("[fail]". __FUNCTION__ . ": sign check fail; uri_string:" . $this->uri->uri_string() . "; param:".json_encode($this->inputs), $this->log_file); + return $this->print_return($this->return_error(API_CODE_INVILD_PARAM, '验签失败')); + } + + $class_name = ucfirst($this->uri->segment(3));//:hd/app/user/ukey + if($this->uri->segment(4)){ + $method = $this->request . "_" . $this->uri->segment(4); + } else { + $method = $this->request; + } + //app定制ct + $file_name = APPPATH."controllers/wxapp/{$app}/{$class_name}.php"; + //ct不存在 + if(file_exists($file_name)) { + require_once $file_name; + } else { + $file_name = APPPATH."controllers/wxapp/app/{$dir}/Self_{$class_name}.php"; + if(file_exists($file_name)){ + require_once $file_name; + $class_name = "Self_{$class_name}"; + } else { + //app定制ct不存在,使用公共ct + $file_name = APPPATH."controllers/wxapp/app/{$class_name}.php"; + if(file_exists($file_name)) { + require_once $file_name; + } else{ + debug_log("[fail]". __FUNCTION__ . ": file '{$file_name}' not exist; method:{$method}, app_id:".$app_id, $this->log_file); + return $this->print_return($this->return_error(API_CODE_NONE, '内部错误')); + } + } + } + + try{ + $class = new $class_name($this->inputs, $app); + + $result = $class->$method($version, $sversion); + if(!$result) { + throw new Exception('', ERR_SYS_FAIL); + } + return $this->print_return($result); + } catch (Exception $e){ + return $this->print_return($this->return_error($e->getCode(), $e->getMessage())); + } + } + /** + * 分销入口 + */ + public function distribution(){ + define('WXAPP_ITEMS', 1); + //加载输入参数 + $this->input_param(); + $app_id = $this->input_param('app_id'); + !$app_id && $app_id = $this->input_param('vipcard_id'); + $version = $this->input_param('version'); + $sversion = $this->input_param('sversion'); + + $this->log_file = get_class($this) . "_{$app_id}.log"; + + //应用ID为空 + if(!$app_id){ + debug_log("[fail]". __FUNCTION__ . ":app_id is null; uri_string:" . $this->uri->uri_string(), $this->log_file); + return $this->print_return($this->return_error(API_CODE_INVILD_PARAM, '请求丢失')); + } + //签名不正确 + if(!$this->vaild_sign()){ + debug_log("[fail]". __FUNCTION__ . ":sign check fail; uri_string:" . $this->uri->uri_string() . "; param:".json_encode($this->inputs), $this->log_file); + return $this->print_return($this->return_error(API_CODE_INVILD_PARAM, '非法请求')); + } + $app = self::$apps[$app_id]; + $class_name = ucfirst($this->uri->segment(3)); + if($this->uri->segment(4)){ + $method = $this->request . "_" . $this->uri->segment(4); + } else { + $method = $this->request; + } + //app定制ct + $file_name = APPPATH."controllers/wxapp/distribution/{$app}/{$class_name}.php"; + //ct不存在 + if(file_exists($file_name)) { + require_once $file_name; + } else { + //app定制ct不存在,使用公共ct + $file_name = APPPATH."controllers/wxapp/distribution/{$class_name}.php"; + if(file_exists($file_name)) { + require_once $file_name; + } else{ + debug_log("[fail]". __FUNCTION__ . ": file '{$file_name}' not exist; method:{$method}, app_id:".$app_id, $this->log_file); + return $this->print_return($this->return_error(API_CODE_NONE, '非法请求')); + } + } + try{ + $class = new $class_name($this->inputs, $app); + $result = $class->$method($version, $sversion); + if(!$result) { + throw new Exception('', ERR_SYS_FAIL); + } + return $this->print_return($result); + } catch (Exception $e){ + return $this->print_return($this->return_error($e->getCode(), $e->getMessage())); + } + } + + /** + * 可能要被废弃 + * @param $err_code + * @param string $err_info + * @return array + */ + function error_msg($err_code, $err_info = "") + { + if(!$err_info) { + $this->lang->load('error_lang','zh'); + $err_info = $this->lang->line(self::$err_lang[$err_code], false); + } + return array('errCode' => $err_code, 'errMessage' => $err_info); + } + + /** + * 打印返回值 + * @param array $data + * @param bool $ifgzip + */ + private function print_return($data = array(), $ifgzip = false){ + + if(!isset($data['code'])){ + $msg = $data['msg'] ? $data['msg'] : '执行成功'; + $data = array('code' => 200, 'data' => $data, 'msg' => $msg); + } + + if($ifgzip) + { + header('Content-Type: application/json'); + header('Content-Encoding: gzip'); + echo gzencode(json_encode($data, JSON_UNESCAPED_UNICODE), 6); + exit; + } + else + { + $result = json_encode($data, JSON_UNESCAPED_UNICODE); + echo $result; + exit; + } + } + + /** + * 根据错误码输出 + * @param $code + * @param string $msg + * @return array + */ + private function return_error($code, $msg = ''){ + if(!$msg) { + $this->lang->load('error_lang','zh'); + $msg = $this->lang->line(self::$err_lang[$code], false); + } + return array('code' => $code, 'msg' => $msg); + } + + /** + * 匹配版本url + * @param $callback + * @param string $version + * @return mixed + */ + private function match_version($callback, $version = ''){ + $version_group = self::$verison; + $ver_arr = $version_group[$callback]; + $ck = $callback; + if(!$ver_arr){ + foreach($version_group as $k => $arr){ + if(0 === strpos($callback, $k)){ + $ver_arr = $arr; + $ck = $k; + break; + } + } + } + + if($ver_arr){ + if(!$version){ + $cv = reset($ver_arr); + } else { + foreach($ver_arr as $k => $v){ + $cmp = $this->vercmp($version, $k); + if($cmp >= 0){ + $cv = $v; + break; + } + } + } + } + + if(isset($cv)){ + $callback = str_replace($ck, $cv, $callback); + } + + return $callback; + } + + /** + * 比较版本号 + * @param $ver1 + * @param $ver2 + * @return int 1:$ver1 > $ver2; -1:$ver1 < $ver2; 0:$ver1 == $ver2; + */ + private function vercmp($ver1, $ver2){ + $v1_arr = explode('.', $ver1); + $v2_arr = explode('.', $ver2); + foreach($v1_arr as $k => $v){ + $sub = $v - $v2_arr[$k]; + if(0 != $sub){ + return $sub > 0 ? 1 : -1; + } + } + + return 0; + } + + /** + * 获取参数 + * @param string $key + * @return array|mixed + */ + private function input_param($key = ''){ + if($key){ + return $this->inputs[$key]; + } + + $request = $this->input->method(); + + switch($request){ + case 'post': + case 'put': + case 'delete': + $input = json_decode(file_get_contents('php://input'), true); + break; + default: + $input = $this->input->get(); + } + + $this->request = $request; + $this->inputs = $input; + return $this->inputs; + } + + /** + * 校验签名 + * @return bool + */ + private function vaild_sign(){ + $param = $this->inputs; + $app_id = $param['app_id']; + !$app_id && $app_id = $param['vipcard_id']; + $sign = strtoupper($param['sign']); + $nonce_str = $param['nonce_str']; + + unset($param['sign']); + + if(!$app_id || !$sign || !$nonce_str){ + debug_log("[fail]". __FUNCTION__ . ": not app_id, sign, nonce_str", $this->log_file); + return false; + } + + //根据biz_id 获取key + $app = self::$apps[$app_id]; + $this->config->load('app', true, true); + $configs = $this->config->item('app'); + $config = $configs[$app]; + $key = $config['sign_key']; + + //按字典序排序参数 + ksort($param); + $buff = ""; + foreach($param as $k => $v){ + if(!is_array($v) && strlen($v) > 0){ + $buff .= $k . "=" . ($v) . "&"; + } + } + $buff = trim($buff, "&"); + //在string后加入KEY + $buff = $buff . "&key=" . $key; + //MD5加密并转大写 + $string = strtoupper(md5($buff)); + + //var_dump($string); + //var_dump($buff); + if($sign == $string){ + return true; + } + + debug_log("[fail]". __FUNCTION__ . ": sign:{$sign}, check:{$string}, buff:{$buff}", $this->log_file); + return false; + } + + /** + * 上传图片 + * @throws Exception + */ + public function upimg(){ + $app = $this->input->post('app'); + $log_name = "{$app}_upimg.log"; + try { + if(!$app){ + throw new Exception('参数错误', API_CODE_INVILD_PARAM); + } + + //接收图片 + if (!$file = $_FILES['img']) { + throw new Exception('请选择图片', API_CODE_INVILD_PARAM); + } + + if (!$file['tmp_name']) {//太大的图片上传,这个参数会变成空的 + debug_log(json_encode($file), $log_name); + throw new Exception('参数错误', API_CODE_INVILD_PARAM); + } + debug_log("[info]". __FUNCTION__ . ": tmp_name:" . $file['tmp_name'] . ";size:" . filesize($file['tmp_name']), $log_name); + if (!file_exists(TEMP_PATH)){ + $oldumask = umask(0); + mkdir(TEMP_PATH, 0777, true); + umask($oldumask); + } + $tmp = TEMP_PATH . md5($file['name'] . uniqid()) . substr($file['name'], strpos($file['name'], '.', strlen($file['name']) - 1)); + move_uploaded_file($file['tmp_name'], $tmp); + debug_log("[info]". __FUNCTION__ . "tmp:$tmp;size:" . filesize($tmp), $log_name); + + if (!filesize($tmp)) { + throw new Exception('图片有点问题,换个小的试试', API_CODE_INVILD_PARAM); + } + //上传图片到FTP + $res = $this->upload_img_qiniu($tmp,"{$app}/"); + if (!$res) { + throw new Exception('上传失败', API_CODE_FAIL); + } + + $data['full_url'] = build_qiniu_image_url($res['photo']); + $data['url'] = $res['photo']; + debug_log("[info]". __FUNCTION__ . "full_url:" . $data['full_url'], $log_name); + $this->print_return($data); + } catch (Exception $e) { + $message = $e->getMessage(); + $this->print_return($this->return_error($e->getCode(), $message)); + } + } + + /** + * @param string $file 上传的文件 + * @param string $path 要保存的目录 + * @param string $filename 原始文件名称 + * @throws Exception + * @return array + */ + private function upload_img_qiniu($file, $path = '',$filename = ''){ + $phoId = md5(uniqid().mt_rand(0,10000).time()); + + $filename = $filename ? $filename : $file; + $ext_arr = explode(".", $filename); + $ext = count($ext_arr)>1?$ext_arr[count($ext_arr)-1]:'jpg'; + + if (is_uploaded_file($file)) { + //上传图片 + $oriPath = TEMP_PATH . '/p_' . $phoId . '_ori.' . $ext; + move_uploaded_file($file, $oriPath); + } else { + $oriPath = $file; + } + + $oriKey = 'p_' . $phoId . '.' . $ext; + + // 上传到七牛后保存的文件名 + $photo = $path .date('Ym') . "/" . $oriKey; + + //上传图片到FTP + $this->load->library('qiniu'); + $res= $this->qiniu->save($photo, file_get_contents($oriPath)); + + $img_size = getimagesize($oriPath); + $file_size = filesize($oriPath); + $size = "{$img_size[0]},{$img_size[1]},{$file_size}"; + + unlink($oriPath); + if ($res) { + $size = getimagesize($res['url']); + return array('photo' => $res['file'], 'size' => $size); + } else { + return array(); + } + } +} diff --git a/api/controllers/Weixin.php b/api/controllers/Weixin.php deleted file mode 100644 index 3d2292f4..00000000 --- a/api/controllers/Weixin.php +++ /dev/null @@ -1,153 +0,0 @@ -app_id = $this->input->get('app_id'); - $this->reset = $this->input->get('reset'); - $this->appid = $this->input->get('appid'); - $this->secret = $this->input->get('secret'); - $this->corpid = $this->input->get('corpid'); - $this->corpsecret = $this->input->get('corpsecret'); - - $wx_configs = array( - //小鱼冒泡 - "13.1" => array('appid' => "wx13bb4ff11493bc7c", "secret" => "40d6032dece9aba7f9c2faa482abd827"), - ); - - $wx_config = $wx_configs[$this->app_id]; - if ($wx_config) { - !$this->appid && $this->appid = $wx_config['appid']; - !$this->secret && $this->secret = $wx_config['secret']; - } - - $param = array('appid' => $this->appid, "secret" => $this->secret); - $this->load->library("hd_wechat", $param); - } - - /** - * 获取access_token - */ - function access_token() - { - $access_token = $this->hd_wechat->access_token($this->reset); - - $data = array("access_token" => $access_token); - - echo json_encode($data, JSON_UNESCAPED_UNICODE); - - return; - } - - /** - * 获取分享凭证 - */ - function api_ticket() - { - $api_ticket = $this->hd_wechat->api_ticket($this->reset); - - $data = array("api_ticket" => $api_ticket); - - echo json_encode($data, JSON_UNESCAPED_UNICODE); - return; - } - - /* - * 企业微信access_token - */ - public function qy_access_token() - { - $app = $this->input->get('app'); - $corpid = $this->input->get('corpid'); - $corpsecret = $this->input->get('corpsecret'); - $params = array(); - $app && $params['app'] = $app; - $corpid && $params['corpid'] = $corpid; - $corpsecret && $params['corpsecret'] = $corpsecret; - $this->load->library('wx_qyapi', $params); - $access_token = $this->wx_qyapi->access_token(); - $data['access_token'] = $access_token; - echo json_encode($data, JSON_UNESCAPED_UNICODE); - return; - } - - /** - * Notes:企业微信ticket - * Created on: 2022/3/30 9:53 - * Created by: dengbw - */ - public function qy_jsapi_ticket() - { - $app = $this->input->get('app'); - $corpid = $this->input->get('corpid'); - $corpsecret = $this->input->get('corpsecret'); - $params = array(); - $app && $params['app'] = $app; - $corpid && $params['corpid'] = $corpid; - $corpsecret && $params['corpsecret'] = $corpsecret; - $this->load->library('wx_qyapi', $params); - $ticket = $this->wx_qyapi->jsapi_ticket(); - $data['ticket'] = $ticket; - echo json_encode($data, JSON_UNESCAPED_UNICODE); - return; - } - - /** - * Notes:企业微信自建应用access_token - * Created on: 2022/3/30 9:57 - * Created by: dengbw - */ - public function qy_agent_access_token() - { - $app = $this->input->get('app'); - $corpid = $this->input->get('corpid'); - $corpsecret = $this->input->get('corpsecret'); - $params = array(); - $app && $params['app'] = $app; - $corpid && $params['corpid'] = $corpid; - $corpsecret && $params['corpsecret'] = $corpsecret; - $this->load->library('wx_qyapi_agent', $params); - $access_token = $this->wx_qyapi_agent->access_token(); - $data['access_token'] = $access_token; - echo json_encode($data, JSON_UNESCAPED_UNICODE); - return; - } - - /** - * Notes:企业微信自建应用ticket - * Created on: 2022/3/30 9:53 - * Created by: dengbw - */ - public function qy_agent_jsapi_ticket() - { - $app = $this->input->get('app'); - $corpid = $this->input->get('corpid'); - $corpsecret = $this->input->get('corpsecret'); - $params = array(); - $app && $params['app'] = $app; - $corpid && $params['corpid'] = $corpid; - $corpsecret && $params['corpsecret'] = $corpsecret; - $this->load->library('wx_qyapi_agent', $params); - $ticket = $this->wx_qyapi_agent->jsapi_ticket(); - $data['ticket'] = $ticket; - echo json_encode($data, JSON_UNESCAPED_UNICODE); - return; - } - -} \ No newline at end of file diff --git a/api/controllers/Welcome.php b/api/controllers/Welcome.php index eccdd489..b80b45fe 100644 --- a/api/controllers/Welcome.php +++ b/api/controllers/Welcome.php @@ -1,10 +1,15 @@ -load->view('welcome_message'); - } -} +load->view('welcome_message'); + } + + public function test(){ + } +} diff --git a/api/controllers/wxapp/Wxapp.php b/api/controllers/wxapp/Wxapp.php index 674a752d..519feffb 100644 --- a/api/controllers/wxapp/Wxapp.php +++ b/api/controllers/wxapp/Wxapp.php @@ -1,538 +1,523 @@ -app_key = $app_key; - $this->redis_login = "wxapp_{$app_key}_login_"; - $this->redis_mcode = "wxapp_{$app_key}_mcode_"; - $this->redis_hxcode = "wxapp_{$app_key}_hxcode_"; - - if (false !== strpos($_SERVER['HTTP_HOST'], 'dev')) { //dev 测试 - $this->env = 'd'; - } elseif (false !== strpos($_SERVER['HTTP_HOST'], 'test')) {//test 测试 - $this->env = 't'; - } else { // 正式 - $this->env = 'p'; - } - - //app配置 - $config = $this->get_config($app_key); - $this->wx_config = $config['wx']; - $this->cf_title = $config['name']; - $this->app_id = $config['app_id']; - $this->model_app_user = $config['model']['user_model'];//应用用户model - - //根据app_id重载model - $this->load->rebuild_model($this->app_id); - - //日志文件 - $class_name = lcfirst(get_class($this));//调用类的名称,子类或者当前类名称 - - $this->log_file = "wxapp_{$app_key}_{$class_name}.log"; - $this->log_dir = "wxapp_{$app_key}_{$class_name}"; - - //设置input - $this->set_input($inputs); - - //加载library - $this->load->library('entity/user_entity'); - $this->load->library('hd_exception'); - - $this->u_entity = new User_entity($this->app_id); - $this->app_redis = &load_cache('redis'); - - //加载model - if($this->model_app_user){ - $this->load->model($this->model_app_user, 'app_user_model'); - } - - //获取session - $this->fetch_session(); - } - - /** - * 获取参数 - * @param string $key - * @return array|mixed - */ - function input_param($key = ''){ - if($key){ - return $this->inputs[$key]; - } - - return $this->inputs; - } - - /** - * @param $name "请求方法" - * @param $arguments (第一个参数默认版本号) - * @return mixed - * @throws Exception - */ - function __call($name, $arguments){ - $version = $arguments[0]; - $sversion = $arguments[1]; - //一些接口的分支需要校验,如biz里的rec_list,是需要登录的 - $pre_call = 'call__'; - if(0 === strpos($name, $pre_call)){ - $name = substr($name, strlen($pre_call)); - } - $method = $name; - - if($version){//版本号的方法存在用版本号的,否则继续用默认的方法 - if(method_exists($this, $method . '__' . $version)){ - $method .= '__' . $version; - } - } - - if($sversion){//小版本,设置某个方法的版本 - $sversion = str_replace('.', '_', $sversion); - if(method_exists($this, $method . '__' . $sversion)){ - $method .= '__' . $sversion; - } - } - - if(!method_exists($this, $method)){ - debug_log("[fail]". __FUNCTION__ . ": request not allow; method:{$method}", $this->log_file); - throw new Exception('非法请求', API_CODE_NONE); - } - - //某个方法或者整个ct在白名单里无需校验 - $session = $this->session; - if(!in_array($name, $this->login_white) && 'all' != $this->login_white){ - if(!$session){ - throw new Exception('还未登录', API_CODE_LOGOUT); - } - - $user = $this->u_entity->get(array('id' => $session['uid'])); - if(!$user || -1 == $user['status']){ - $this->logout($this->ukey); - debug_log("[error]# user is delete, sql=". $this->u_entity->last_query(), __FUNCTION__, $this->log_dir); - throw new Exception('登录超时', API_CODE_LOGOUT); - } - - // 校验用户状态 - if(in_array($name, $this->check_status) || 'all' == $this->check_status){ - if(self::STATUS_NOR != $session['status']){ - throw new Exception('用户被禁用', API_CODE_FORB); - } - } - //是否绑定手机号 - if(in_array($name, $this->check_mobile) || 'all' == $this->check_mobile){ - if(!$session['mobile'] || !mobile_valid($session['mobile'])){ - throw new Exception('请绑定正确的手机号', API_CODE_FORB); - } - } - - // 校验用户头像 - if(in_array($name, $this->check_headimg) || 'all' == $this->check_headimg){ - if(!$session['headimg']){ - throw new Exception('获取头像信息失败', API_CODE_FORB); - } - } - - } - - //超级管理员登录其他用户操作权限控制 - /* not limit again edit by xxb 20200529 */ - /*if($session['is_majia']){ - if(!in_array($name, $this->majia_white) && 'all' != $this->majia_white){ - throw new Exception('无权限', API_CODE_FORB); - } - }*/ - - return $this->$method(); - } - - /** - * 刷新登录有效时间 - * @param $data - * @return string - */ - protected function refresh_login($data){ - $redis = $this->app_redis; - - $ukey = md5("{$data['uid']}_{$data['session_key']}"); - - $redis->save($this->redis_login.$ukey, json_encode($data, JSON_UNESCAPED_UNICODE), 30 * 24 * 3600); - - $this->ukey = $ukey; - return $ukey; - } - - /** - * 删除登录记录 - * @param $ukey - */ - protected function logout($ukey = ''){ - !$ukey && $ukey = $this->input_param('ukey'); - - if($ukey){ - $redis = $this->app_redis; - $redis->delete($this->redis_login.$ukey); - } - } - - /** - * 校验用户是否黑名单 - * @return bool - */ - protected function is_black(){ - $mobile = $this->session['mobile']; - if(!$mobile){ - return false; - } - - return $this->u_entity->is_black($mobile); - } - - /** - * - * @return array|mixed - */ - private function fetch_session(){ - $ukey = $this->input_param('ukey'); - $this->ukey = $ukey; - if(!$ukey){ - return array(); - } - - $redis = $this->app_redis; - - //data:{"uid":"用户ID", "session_key":"微信session_key"} - $data = json_decode($redis->get($this->redis_login.$ukey), true); - - if($data){ - $session = $data; - $source_uid = $uid = $session['uid']; - $user = $this->u_entity->get(array('id' => $uid)); - if($user){ - //判断是否超级管理员批马甲 - $json = $user['jsondata'] ? json_decode($user['jsondata'], true) : array(); - if($json['majia']){//披上马甲 - $muid = $json['majia']['uid']; - $row = $this->u_entity->get(array('id' => $muid)); - if($row){ - $uid = $muid; - $session['is_majia'] = 1; - $session['source_uid'] = $source_uid; - $session['uid'] = $uid; - $user = $row; - } - } - // 角色切换处理 - if ($session['group_id_type']){ - $user['group_id'] = $user['group_id1']; - $user['biz_id'] = $user['biz_id1']; - $user['city_id'] = $user['city_id1']; - } - //设置默认城市,取biz_id对应城市 - if (strlen($user['biz_id']) > strlen(str_replace(',', '', $user['biz_id']))){ - $this->load->model("biz/biz_model"); - $biz = $this->biz_model->get(['id' => intval($user['biz_id']), 'status' => 1], 'city_id'); - $user['city_id'] = $biz && $biz['city_id'] ? $biz['city_id'] : 0; - } - } - if($user){ - $session = array_merge($session, $user); - $this->session = $session; - //更新登录有效时间 - $this->refresh_login($data); - } else { - $this->logout($ukey); - } - } - $this->myuid = $this->session['uid']; - return $this->session; - } - - /** - * 设置 - * @param array $arr - * @param int $type "-1删除 0重置 1新增" - * @return mixed - */ - protected function set_session($arr = array(), $type=0){ - $redis = $this->app_redis; - - $ukey = $this->ukey; - - $data = json_decode($redis->get($this->redis_login.$ukey), true); - if(-1 == $type){//删除 - foreach($arr as $k){ - unset($data[$k]); - } - } elseif(0 == $type){//重置 - $data = $arr; - } elseif(1 == $type){//新增 - foreach($arr as $k => $v){ - $data[$k] = $v; - } - } - - $redis->save($this->redis_login.$ukey, json_encode($data, JSON_UNESCAPED_UNICODE), 30 * 24 * 3600); - - $this->ukey = $ukey; - return $ukey; - } - - /** - * 小程序开关 - * @param string $key (name, logo, biz_cate) - * @return mixed - */ - protected function app_config($key = ''){ - $this->load->model('app/app_model'); - $this->load->model("app/appusual/app_config_model"); - - if($this->app){ - $app = $this->app; - } else { - $where = array('id' => $this->app_id); - $app = $this->app_model->get($where); - $json = $app['jsondata'] ? json_decode($app['jsondata'], true) : array(); - - $where = array('app_id' => $this->app_id); - $select = "k,v"; - $map_config = $this->app_config_model->map('k', 'v', $where, '', 0, 0, $select); - if($map_config){ - foreach($map_config as $k => $v){ - $v && $json[$k] = json_decode($v, true); - } - } - $app['json'] = $json; - $this->app = $app; - } - - if(!$key){ - return $app; - }elseif($app[$key]){ - return $app[$key]; - }else{ - $json = $app['json']; - return $json[$key]; - } - } - - /** - * 获取app的配置 - * @param $app_key - * @param $app_id - * @return null - */ - protected function get_config($app_key = '', $app_id = ''){ - $this->config->load('app', true, true); - $configs = $this->config->item('app'); - if($app_key){ - return $configs[$app_key]; - } elseif($app_id) { - foreach($configs as $k => $v){ - if($app_id == $v['app_id']){ - return $v; - } - } - } - - return null; - } - - /** - * @return string - */ - protected function cityid(){ - - if(!$this->city_id){ - $city_id = $this->app_config('city_id'); - !$city_id && $city_id = '350200'; - $this->city_id = $city_id; - } - - return $this->city_id; - } - - /** - * 获取用户当前访问的城市ID - * @return mixed - */ - protected function ucityid(){ - $json = $this->session['jsondata']; - !is_array($json) && $json = json_decode($json, true); - return $json['city_id']; - } - - /** - * 用户访问城市配置 - * @param string $k - * @param string $cityid 取默认城市id - * @return array - */ - protected function config_ucity($k = '',$cityid=''){ - if($cityid){ - $city_id = $this->cityid(); - }else{ - $city_id = $this->ucityid(); - } - $citys = $this->app_config("citys"); - $config_city = $citys[$city_id]; - 1 == $config_city && $config_city = array(); - - return $k ? $config_city[$k]:$config_city; - } - - protected function get_pager() - { - $size = $this->input_param('size'); - $page = $this->input_param('page'); - $page = $page ? $page : '1'; - $size = $size ? $size : '10'; - return array('page' => $page, 'size' => $size); - } - - /** - * 解析获取微信 - * @param $code - * @return mixed|string - */ - protected function wx_session($code){ - $appid = $this->wx_config['appid']; - $secret = $this->wx_config['secret']; - $url = "https://api.weixin.qq.com/sns/jscode2session?appid={$appid}&secret={$secret}&js_code={$code}&grant_type=authorization_code"; - debug_log("[info] ". __FUNCTION__ . "微信授权:\n{$url}", $this->log_file); -// $ch = curl_init($url); -// curl_setopt($ch, CURLOPT_RETURNTRANSFER,true); -// //关闭https验证 -// curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); -// curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); -// $res = curl_exec($ch); - $res = file_get_contents($url); - //存日志 - debug_log("[info] ". __FUNCTION__ . "res={$res}", $this->log_file); - $ret = json_decode($res, true); -// { -// "session_key": "会话密钥", -// "openid": "用户唯一标识", -// "unionid": "用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回,详见 UnionID 机制说明。", -// "errcode": "错误码", -// "errmsg": "错误信息" -// } - - if(!$ret['session_key']){ - debug_log("[fail] ". __FUNCTION__ . ": session_key is null", $this->log_file); - } - - return $ret; - } - - /** - * 解析微信数据 - * @param $encrypted - * @param $iv - * @return array|mixed|string - */ - protected function wx_data($encrypted, $iv){ - require_once APPPATH."third_party/WeChat/wxBizDataCrypt.php"; - $pc = new WXBizDataCrypt($this->wx_config['appid'], $this->session['session_key']); - $wx_data = ''; - $errCode = $pc->decryptData($encrypted, $iv, $wx_data); - - debug_log("[info] ". __FUNCTION__ . ":code={$errCode}; wxdata:{$wx_data}", $this->log_file); - - if ($errCode == 0) { - $wx_data = json_decode($wx_data, true); - return $wx_data; - } - - debug_log("[warning] ". __FUNCTION__ . ":appid=" . $this->wx_config['appid'] . "; session_key=" . $this->session['session_key'] . "; encrypted={$encrypted}; iv={$iv}; wxdata:{$wx_data}", $this->log_file); - return array(); - } - - /** - * 输入参数处理 - * @param $inputs - * @return array - */ - private function set_input($inputs){ - if(!$inputs){ - return array(); - } - foreach($inputs as $k => $v){ - if('undefined' === $v){//前端空参数过滤 - $inputs[$k] = ''; - } - } - - $this->inputs = $inputs; - - return $this->inputs; - } - - /** - * h5地址 - * @return string - */ - protected function h5_host(){ - if (false !== strpos($_SERVER['HTTP_HOST'], 'dev')) { //dev 测试 - $h5_host = 'https://hd-wxdev.xiaoyu.com'; - } elseif (false !== strpos($_SERVER['HTTP_HOST'], 'test')) {//test 测试 - $h5_host = 'https://www.test.haodian.cn'; - } else { // 正式 - $h5_host = 'https://www.haodian.cn'; - } - return $h5_host; - } - - //获取当前门店id - protected function get_biz_id(){ - return $this->session['new_biz_id'] ? $this->session['new_biz_id'] : intval($this->session['biz_id']); - } -} +app_key = $app_key; + $this->redis_login = "wxapp_{$app_key}_login_"; + $this->redis_mcode = "wxapp_{$app_key}_mcode_"; + $this->redis_hxcode = "wxapp_{$app_key}_hxcode_"; + + if (false !== strpos($_SERVER['HTTP_HOST'], 'dev')) { //dev 测试 + $this->env = 'd'; + } elseif (false !== strpos($_SERVER['HTTP_HOST'], 'test')) {//test 测试 + $this->env = 't'; + } else { // 正式 + $this->env = 'p'; + } + + //app配置 + $config = $this->get_config($app_key); + $this->wx_config = $config['wx']; + $this->cf_title = $config['name']; + $this->app_id = $config['app_id']; + $this->model_app_user = $config['model']['user_model'];//应用用户model + + //根据app_id重载model + $this->load->rebuild_model($this->app_id); + + //日志文件 + $class_name = lcfirst(get_class($this));//调用类的名称,子类或者当前类名称 + + $this->log_file = "wxapp_{$app_key}_{$class_name}.log"; + $this->log_dir = "wxapp_{$app_key}_{$class_name}"; + + //设置input + $this->set_input($inputs); + + //加载library + $this->load->library('entity/user_entity'); + $this->load->library('hd_exception'); + + $this->u_entity = new User_entity($this->app_id); + $this->app_redis = &load_cache('redis'); + + //加载model + if($this->model_app_user){ + $this->load->model($this->model_app_user, 'app_user_model'); + } + + //获取session + $this->fetch_session(); + } + + /** + * 获取参数 + * @param string $key + * @return array|mixed + */ + function input_param($key = ''){ + if($key){ + return $this->inputs[$key]; + } + + return $this->inputs; + } + + /** + * @param $name "请求方法" + * @param $arguments (第一个参数默认版本号) + * @return mixed + * @throws Exception + */ + function __call($name, $arguments){ + $version = $arguments[0]; + $sversion = $arguments[1]; + //一些接口的分支需要校验,如biz里的rec_list,是需要登录的 + $pre_call = 'call__'; + if(0 === strpos($name, $pre_call)){ + $name = substr($name, strlen($pre_call)); + } + $method = $name; + + if($version){//版本号的方法存在用版本号的,否则继续用默认的方法 + if(method_exists($this, $method . '__' . $version)){ + $method .= '__' . $version; + } + } + + if($sversion){//小版本,设置某个方法的版本 + $sversion = str_replace('.', '_', $sversion); + if(method_exists($this, $method . '__' . $sversion)){ + $method .= '__' . $sversion; + } + } + + if(!method_exists($this, $method)){ + debug_log("[fail]". __FUNCTION__ . ": request not allow; method:{$method}", $this->log_file); + throw new Exception('非法请求', API_CODE_NONE); + } + + //某个方法或者整个ct在白名单里无需校验 + $session = $this->session; + if(!in_array($name, $this->login_white) && 'all' != $this->login_white){ + if(!$session){ + throw new Exception('还未登录', API_CODE_LOGOUT); + } + + $user = $this->u_entity->get(array('id' => $session['uid'])); + if(!$user || -1 == $user['status']){ + $this->logout($this->ukey); + debug_log("[error]# user is delete, sql=". $this->u_entity->last_query(), __FUNCTION__, $this->log_dir); + throw new Exception('登录超时', API_CODE_LOGOUT); + } + + // 校验用户状态 + if(in_array($name, $this->check_status) || 'all' == $this->check_status){ + if(self::STATUS_NOR != $session['status']){ + throw new Exception('用户被禁用', API_CODE_FORB); + } + } + //是否绑定手机号 + if(in_array($name, $this->check_mobile) || 'all' == $this->check_mobile){ + if(!$session['mobile'] || !mobile_valid($session['mobile'])){ + throw new Exception('请绑定正确的手机号', API_CODE_FORB); + } + } + + // 校验用户头像 + if(in_array($name, $this->check_headimg) || 'all' == $this->check_headimg){ + if(!$session['headimg']){ + throw new Exception('获取头像信息失败', API_CODE_FORB); + } + } + + } + + //超级管理员登录其他用户操作权限控制 + /* not limit again edit by xxb 20200529 */ + /*if($session['is_majia']){ + if(!in_array($name, $this->majia_white) && 'all' != $this->majia_white){ + throw new Exception('无权限', API_CODE_FORB); + } + }*/ + + return $this->$method(); + } + + /** + * 刷新登录有效时间 + * @param $data + * @return string + */ + protected function refresh_login($data){ + $redis = $this->app_redis; + + $ukey = md5("{$data['uid']}_{$data['session_key']}"); + + $redis->save($this->redis_login.$ukey, json_encode($data, JSON_UNESCAPED_UNICODE), 30 * 24 * 3600); + + $this->ukey = $ukey; + return $ukey; + } + + /** + * 删除登录记录 + * @param $ukey + */ + protected function logout($ukey = ''){ + !$ukey && $ukey = $this->input_param('ukey'); + + if($ukey){ + $redis = $this->app_redis; + $redis->delete($this->redis_login.$ukey); + } + } + + /** + * 校验用户是否黑名单 + * @return bool + */ + protected function is_black(){ + $mobile = $this->session['mobile']; + if(!$mobile){ + return false; + } + + return $this->u_entity->is_black($mobile); + } + + /** + * + * @return array|mixed + */ + private function fetch_session(){ + $ukey = $this->input_param('ukey'); + $this->ukey = $ukey; + if(!$ukey){ + return array(); + } + + $redis = $this->app_redis; + + //data:{"uid":"用户ID", "session_key":"微信session_key"} + $data = json_decode($redis->get($this->redis_login.$ukey), true); + + if($data){ + $session = $data; + $source_uid = $uid = $session['uid']; + $user = $this->u_entity->get(array('id' => $uid)); + if($user){ + //判断是否超级管理员批马甲 + $json = $user['jsondata'] ? json_decode($user['jsondata'], true) : array(); + if($json['majia']){//披上马甲 + $muid = $json['majia']['uid']; + $row = $this->u_entity->get(array('id' => $muid)); + if($row){ + $uid = $muid; + $session['is_majia'] = 1; + $session['source_uid'] = $source_uid; + $session['uid'] = $uid; + $user = $row; + } + } + // 角色切换处理 + if ($session['group_id_type']){ + $user['group_id'] = $user['group_id1']; + $user['biz_id'] = $user['biz_id1']; + $user['city_id'] = $user['city_id1']; + } + //设置默认城市,取biz_id对应城市 + if (strlen($user['biz_id']) > strlen(str_replace(',', '', $user['biz_id']))){ + $this->load->model("biz/biz_model"); + $biz = $this->biz_model->get(['id' => intval($user['biz_id']), 'status' => 1], 'city_id'); + $user['city_id'] = $biz && $biz['city_id'] ? $biz['city_id'] : 0; + } + } + if($user){ + $session = array_merge($session, $user); + $this->session = $session; + //更新登录有效时间 + $this->refresh_login($data); + } else { + $this->logout($ukey); + } + } + $this->myuid = $this->session['uid']; + return $this->session; + } + + /** + * 设置 + * @param array $arr + * @param int $type "-1删除 0重置 1新增" + * @return mixed + */ + protected function set_session($arr = array(), $type=0){ + $redis = $this->app_redis; + + $ukey = $this->ukey; + + $data = json_decode($redis->get($this->redis_login.$ukey), true); + if(-1 == $type){//删除 + foreach($arr as $k){ + unset($data[$k]); + } + } elseif(0 == $type){//重置 + $data = $arr; + } elseif(1 == $type){//新增 + foreach($arr as $k => $v){ + $data[$k] = $v; + } + } + + $redis->save($this->redis_login.$ukey, json_encode($data, JSON_UNESCAPED_UNICODE), 30 * 24 * 3600); + + $this->ukey = $ukey; + return $ukey; + } + + /** + * 小程序开关 + * @param string $key (name, logo, biz_cate) + * @return mixed + */ + protected function app_config($key = ''){ + $this->load->model('app/app_model'); + $this->load->model("app/appusual/app_config_model"); + + if($this->app){ + $app = $this->app; + } else { + $where = array('id' => $this->app_id); + $app = $this->app_model->get($where); + $json = $app['jsondata'] ? json_decode($app['jsondata'], true) : array(); + + $where = array('app_id' => $this->app_id); + $select = "k,v"; + $map_config = $this->app_config_model->map('k', 'v', $where, '', 0, 0, $select); + if($map_config){ + foreach($map_config as $k => $v){ + $v && $json[$k] = json_decode($v, true); + } + } + $app['json'] = $json; + $this->app = $app; + } + + if(!$key){ + return $app; + }elseif($app[$key]){ + return $app[$key]; + }else{ + $json = $app['json']; + return $json[$key]; + } + } + + /** + * 获取app的配置 + * @param $app_key + * @param $app_id + * @return null + */ + protected function get_config($app_key = '', $app_id = ''){ + $this->config->load('app', true, true); + $configs = $this->config->item('app'); + if($app_key){ + return $configs[$app_key]; + } elseif($app_id) { + foreach($configs as $k => $v){ + if($app_id == $v['app_id']){ + return $v; + } + } + } + + return null; + } + + /** + * @return string + */ + protected function cityid(){ + + if(!$this->city_id){ + $city_id = $this->app_config('city_id'); + !$city_id && $city_id = '350200'; + $this->city_id = $city_id; + } + + return $this->city_id; + } + + /** + * 获取用户当前访问的城市ID + * @return mixed + */ + protected function ucityid(){ + $json = $this->session['jsondata']; + !is_array($json) && $json = json_decode($json, true); + return $json['city_id']; + } + + /** + * 用户访问城市配置 + * @param string $k + * @param string $cityid 取默认城市id + * @return array + */ + protected function config_ucity($k = '',$cityid=''){ + if($cityid){ + $city_id = $this->cityid(); + }else{ + $city_id = $this->ucityid(); + } + $citys = $this->app_config("citys"); + $config_city = $citys[$city_id]; + 1 == $config_city && $config_city = array(); + + return $k ? $config_city[$k]:$config_city; + } + + protected function get_pager() + { + $size = $this->input_param('size'); + $page = $this->input_param('page'); + $page = $page ? $page : '1'; + $size = $size ? $size : '10'; + return array('page' => $page, 'size' => $size); + } + + /** + * 解析获取微信 + * @param $code + * @return mixed|string + */ + protected function wx_session($code){ + $appid = $this->wx_config['appid']; + $secret = $this->wx_config['secret']; + $url = "https://api.weixin.qq.com/sns/jscode2session?appid={$appid}&secret={$secret}&js_code={$code}&grant_type=authorization_code"; + debug_log("[info] ". __FUNCTION__ . "微信授权:\n{$url}", $this->log_file); +// $ch = curl_init($url); +// curl_setopt($ch, CURLOPT_RETURNTRANSFER,true); +// //关闭https验证 +// curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); +// curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); +// $res = curl_exec($ch); + $res = file_get_contents($url); + //存日志 + debug_log("[info] ". __FUNCTION__ . "res={$res}", $this->log_file); + $ret = json_decode($res, true); +// { +// "session_key": "会话密钥", +// "openid": "用户唯一标识", +// "unionid": "用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回,详见 UnionID 机制说明。", +// "errcode": "错误码", +// "errmsg": "错误信息" +// } + + if(!$ret['session_key']){ + debug_log("[fail] ". __FUNCTION__ . ": session_key is null", $this->log_file); + } + + return $ret; + } + + /** + * 解析微信数据 + * @param $encrypted + * @param $iv + * @return array|mixed|string + */ + protected function wx_data($encrypted, $iv){ + require_once APPPATH."third_party/WeChat/wxBizDataCrypt.php"; + $pc = new WXBizDataCrypt($this->wx_config['appid'], $this->session['session_key']); + $wx_data = ''; + $errCode = $pc->decryptData($encrypted, $iv, $wx_data); + + debug_log("[info] ". __FUNCTION__ . ":code={$errCode}; wxdata:{$wx_data}", $this->log_file); + + if ($errCode == 0) { + $wx_data = json_decode($wx_data, true); + return $wx_data; + } + + debug_log("[warning] ". __FUNCTION__ . ":appid=" . $this->wx_config['appid'] . "; session_key=" . $this->session['session_key'] . "; encrypted={$encrypted}; iv={$iv}; wxdata:{$wx_data}", $this->log_file); + return array(); + } + + /** + * 输入参数处理 + * @param $inputs + * @return array + */ + private function set_input($inputs){ + if(!$inputs){ + return array(); + } + foreach($inputs as $k => $v){ + if('undefined' === $v){//前端空参数过滤 + $inputs[$k] = ''; + } + } + + $this->inputs = $inputs; + + return $this->inputs; + } + + //获取当前门店id + protected function get_biz_id(){ + return $this->session['new_biz_id'] ? $this->session['new_biz_id'] : intval($this->session['biz_id']); + } +} diff --git a/api/controllers/wxapp/app/City.php b/api/controllers/wxapp/app/City.php new file mode 100644 index 00000000..77f5ff50 --- /dev/null +++ b/api/controllers/wxapp/app/City.php @@ -0,0 +1,142 @@ +login_white = array('get');//登录白名单 + $this->check_status = array();//用户状态校验 + $this->check_mobile = array();//需要手机号 + $this->check_headimg = array();//授权微信信息 + $this->load->model("sys/sys_city_model"); + $this->load->model("sys/sys_area_model"); + $this->load->model("biz/biz_model"); + $this->load->model('area_model', 'mdArea'); + $this->biz_id = $this->get_biz_id(); + } + + protected function get() + { + $page = $this->input_param('page'); + $size = $this->input_param('size'); + !$page && $page = 1; + !$size && $size = 20; + $default_city = $this->session['city_id'] ? $this->session['city_id'] : 350200; + + $where = [ + 'status' => 1 + ]; + if ($this->app_id == 2 && $this->session['group_id'] == 4) { + $biz_id_arr = explode(',', $this->session['biz_id']); + + $biz_where = ['city_id>' => 0, 'status' => 1, 'type<>' => 4]; + if ($this->session['biz_id'] && $biz_id_arr) { + $biz_ids = implode(',', $biz_id_arr); + $biz_where["id in ({$biz_ids})"] = null; + } + $typeAry = $this->biz_model->type_ary(); + $type_ids = implode(',', array_keys($typeAry)); + $type_ids && $biz_where["type in ($type_ids)"] = null; + $biz_rows = $this->biz_model->select_groupby('city_id', $biz_where, '', '', '', 'id,city_id'); + $city_ids = implode(',', array_column($biz_rows, 'city_id')); + $city_ids && $where["city_id in ($city_ids)"] = null; + } + $count = $this->sys_city_model->count($where); + $lists = []; + if ($count) { + $rows = $this->sys_city_model->select($where, 'id desc', $page, $size, 'id,city_id,name'); + $city_id_arr = array_column($rows, 'city_id'); + $default_city = in_array($default_city, $city_id_arr) ? $default_city : $city_id_arr[0]; + foreach ($rows as $key => $val) { + $lists = $val; + } + $lists = $rows; + } + $data = [ + 'list' => $lists, + 'total' => $count, + 'default' => $default_city + ]; + return $data; + } + + protected function get_lists() + { + $city_lists = [430, 350]; //开发城省份 湖南 福建 + $lists = []; + foreach ($city_lists as $item) { + $where['province_id'] = $item; + $rows = $this->mdArea->select_groupby('city_id', $where, '', 0, 100, 'city_id,city_name,id,province_name'); + $children = []; + foreach ($rows as $item2) { + $children[] = ['id' => $item2['id'], 'city_id' => $item2['city_id'], 'name' => $item2['city_name']]; + } + $lists[] = ['name' => $rows[0]['province_name'], 'propvince_id' => $item, 'children' => $children]; + } + $data = [ + 'area_list' => $lists, + 'default_area_id' => [350, 350200] + ]; + return $data; + } + + /** + * Notes:获取省/市/区/街道 + * Created on: 2022/7/1 11:17 + * Created by: dengbw + * @return mixed + */ + public function get_area() + { + $type = $this->input->get('type'); + $pid = intval($this->input->get('pid')); + $lists = []; + switch ($type) { + case 'city': + !$pid && $pid = 350;//默认福建 + if($this->biz_id){ + $biz = $this->biz_model->get(['id'=>$this->biz_id]); + $biz['province_id'] && $pid = $biz['province_id']; + } + $res = $this->mdArea->select(['province_id' => $pid], null, null, null, 'distinct(city_id), city_name'); + foreach ($res as $v) { + $lists[] = ['id' => $v['city_id'], 'name' => $v['city_name']]; + } + break; + case 'county': + $res = $this->mdArea->select(['city_id' => $pid], null, null, null, 'distinct(county_id), county_name'); + foreach ($res as $v) { + $lists[] = ['id' => $v['county_id'], 'name' => $v['county_name']]; + } + break; + case 'street': + $this->load->model('sys/sys_street_model', 'mdStreet'); + $res = $this->mdStreet->select(['county_id' => $pid], 'id ASC', 0, 0, 'street_id,street_name'); + foreach ($res as $v) { + $lists[] = ['id' => $v['street_id'], 'name' => $v['street_name']]; + } + break; + default: + $res = $this->mdArea->select(null, null, null, null, 'distinct(province_id), province_name'); + foreach ($res as $v) { + $lists[] = ['id' => $v['province_id'], 'name' => $v['province_name']]; + } + break; + } + $data = [ + 'list' => $lists, + ]; + return $data; + } +} \ No newline at end of file diff --git a/api/controllers/wxapp/licheb/Customerlogs.php b/api/controllers/wxapp/licheb/Customerlogs.php new file mode 100644 index 00000000..c81d531b --- /dev/null +++ b/api/controllers/wxapp/licheb/Customerlogs.php @@ -0,0 +1,132 @@ +login_white = array();//登录白名单 + $this->check_status = array();//用户状态校验 + $this->check_mobile = array();//需要手机号 + $this->check_headimg = array();//授权微信信息 + + $this->load->model('receiver/receiver_customers_model', 'customers_model'); + $this->load->model('receiver/receiver_customer_oplogs_model', 'customer_oplogs_model'); + $this->load->model('receiver/receiver_comments_model', 'mdComments'); +// $this->load->model('receiver/receiver_xz_model'); + } + + protected function get() + { + $id = $this->input_param('id'); + $page = $this->input_param('page'); + $size = $this->input_param('size'); + !$page && $page = 1; + !$size && $size = 20; + $where = [ + 'customer_id' => $id + ]; + $count = $this->customer_oplogs_model->count($where); + $lists = []; + if ($count) { + $rows = $this->customer_oplogs_model->select($where, 'id desc', $page, $size, 'id,log,uname,type,c_time,imgs'); + foreach ($rows as $key => $val) { + $record = ''; + $second = 0; + $content = $val['log']; + $img_json = json_decode($val['imgs'], true); + $imgs = []; + if ($img_json) { + foreach ($img_json as $val2) { + $imgs[] = build_qiniu_image_url($val2); + } + } + if ($val['type'] == 2) { + $rec_row = $this->receiver_xz_model->get(['id' => $val['log']], 'rec_url,duration'); + $content = '拨打电话'; + !$rec_row['duration'] && $content .= '(未接通)'; + $rec_row['rec_url'] && $record = $rec_row['rec_url']; + $rec_row['duration'] && $second = intval($rec_row['duration'] / 1000); + } + $comments = []; + $res = $this->mdComments->select(['pid' => $val['id'], 'status' => 1, 'type' => 0], 'id asc', 0, 0 + , 'uname,content'); + foreach ($res as $key2 => $val2) { + $comments[] = [ + 'uname' => $val2['uname'], + 'content' => $val2['content'] + ]; + } + $lists[] = [ + 'id' => $val['id'], + 'content' => "【{$val['uname']}】" . $content, + 'record_url' => $record, + 'second' => $second, + 'imgs' => $imgs, + 'comments' => $comments, + 'type_name' => $this->customer_oplogs_model->typeAry($val['type']), + 'c_time' => date('Y.m.d H:i', $val['c_time']) + ]; + } + } + $data = [ + 'list' => $lists, + 'total' => $count + ]; + if ($page == 1) { //获取统计数据 + $row = $this->customers_model->get(['id' => $id]); + $statistics = [ + [ + 'name' => '去电', + 'val' => $this->customer_oplogs_model->count(['customer_id' => $id, 'type' => 2]), + 'color' => '#f3f6fc', + ], + [ + 'name' => '短信', + 'val' => $this->customer_oplogs_model->count(['customer_id' => $id, 'type' => 1]), + 'color' => '#fffaeb', + ], + [ + 'name' => '到店', + 'val' => $row['a_num'], + 'color' => '#f1f9f8', + ], + [ + 'name' => '试驾', + 'val' => $row['t_num'], + 'color' => '#fff6f8', + ] + ]; + $data['statistics'] = $statistics; + } + return $data; + } + + protected function post() + { + $id = $this->input_param('cus_id'); + $log = trim($this->input_param('content')); + $img_arr = $this->input_param('imgs'); + if (!$log && !$img_arr) { + throw new Exception('参数错误', ERR_PARAMS_ERROR); + } + $this->load->library('receiver/customers_entity'); + $result = $this->customers_entity->add_log_visit($id, $this->session['uid'], $this->session['uname'], $log, 0, 1, $img_arr); + if ($result) { + throw new Exception('修改成功', API_CODE_SUCCESS); + } else { + throw new Exception('修改失败', ERR_PARAMS_ERROR); + } + } +} diff --git a/api/controllers/wxapp/licheb/Customers.php b/api/controllers/wxapp/licheb/Customers.php new file mode 100644 index 00000000..40fde1b8 --- /dev/null +++ b/api/controllers/wxapp/licheb/Customers.php @@ -0,0 +1,1445 @@ +login_white = array();//登录白名单 + $this->check_status = array();//用户状态校验 + $this->check_mobile = array();//需要手机号 + $this->check_headimg = array();//授权微信信息 + $this->load->model('receiver/receiver_customers_model', 'customers_model'); + $this->load->model('receiver/receiver_customer_oplogs_model', 'customer_oplogs_model'); + $this->load->model('receiver/receiver_customer_tag_model', 'mdCustomerTag'); + $this->load->model('receiver/receiver_customer_tagdata_model', 'mdCustomerTagdata'); + $this->load->model('receiver/receiver_customers_visit_data_model', 'mdCustomerVisitData'); +// $this->load->model('receiver/order/receiver_orders_v2_model', 'mdOrders'); + $this->load->model('area_model', 'mdArea'); + $this->load->model('auto/auto_series_model'); + $this->load->model('auto/auto_brand_model'); + $this->load->model("biz/biz_model"); + $this->load->library('receiver/customers_entity'); + $this->biz_id = $this->get_biz_id(); + } + + protected function get() + { + $id = $this->input_param('id'); + if ($id) { + $where = [ + 'id' => $id, + ]; + $row = $this->customers_model->get($where); + if (!$row) { + throw new Exception('数据不存在', ERR_PARAMS_ERROR); + } + $admin = $this->app_user_model->get(['id' => $row['admin_id']], 'id,uname'); + $tags = [$row['level'] . '级用户']; + $status_name = $this->customers_model->get_status(); + $tip = $status_name[$row['status']] ? $status_name[$row['status']] : ''; + $other_data = ['客户等级' => $row['level']]; + if ($row['county_id']) { + $re_area = $this->mdArea->get(['county_id' => $row['county_id']], 'city_name,county_name'); + $re_area && $other_data['所在地区'] = "{$re_area['city_name']}-{$re_area['county_name']}"; + } + if ($this->get_biz('type') != 5) { + $other_data['客户来源'] = $this->get_cfTitle($row); + } + $other_data['建卡时间'] = date('Y-m-d', $row['c_time']); + $row['cont_time'] != '0000-00-00 00:00:00' && $other_data['最近联系'] = date('Y-m-d', strtotime($row['cont_time'])); + if ($this->session['group_id'] == 1) { + $where_visit = ['c_id' => $id, 'biz_id' => $this->biz_id, 'sales_id' => $this->session['uid']]; + } else { + $where_visit = ['c_id' => $id, 'biz_id' => $row['biz_id'], 'sales_id' => $row['admin_id']]; + } + $visit_time = $this->get_visit_time($where_visit); + $visit_time && $other_data['计划回访时间'] = $visit_time; + $other_data['销售顾问'] = isset($admin) ? $admin['uname'] : ''; + $jsondata = $row['jsondata'] ? json_decode($row['jsondata'], true) : array(); + $data = [ + 'id' => $row['id'], + 'name' => $row['name'], + 'mobile' => $this->get_mobile(['mobile' => $row['mobile'], 'of_id' => $row['of_id'], 'of2_id' => $row['of2_id']]), + 'complete_mobile' => $row['mobile'], + 'tip' => $tip, + 'is_top' => $row['is_top'], + 'status' => $row['status'], + 'defeat' => $jsondata['defeat'], + 'other_data' => $other_data, + 'is_weChat' => $row['wxqy'] == 1 ? true : false, + 'generate_order' => $this->myuid == $row['admin_id'] ? true : false, + 'level' => $row['level'], + 'tags' => $tags, + 'wxgr' => $row['wxgr'], + 'wxgrimg' => $row['wxgrimg'], + 'wxgrimg_url' => $row['wxgrimg'] ? build_qiniu_image_url($row['wxgrimg']) : '', + ]; + return $data; + } else { + return $this->lists(); + } + } + + //获取客户其它信息 + protected function get_data() + { + $id = $this->input_param('id'); + $where = [ + 'id' => $id + ]; + $row = $this->customers_model->get($where); + if (!$row) { + throw new Exception('数据不存在', ERR_PARAMS_ERROR); + } + $of_title = $row['of_id'] ? $this->get_cfTitle($row) : ''; + $data['baseinfo'] = [ + 'name' => ['value' => $row['name'], 'cn' => '客户姓名'], + 'mobile' => ['value' => $this->get_mobile(['mobile' => $row['mobile'], 'of_id' => $row['of_id'], 'of2_id' => $row['of2_id']]), 'cn' => '客户电话'], + 'c_brand' => $row['c_brand'], + 'of_id' => ['value' => $of_title, 'of_id' => intval($row['of_id']), 'of2_id' => intval($row['of2_id']), 'cn' => '线索来源'], + 'buy_time' => ['value' => $row['buy_time'], 'cn' => '预计购车时间'], + 'wxgr' => $row['wxgr'], + 'wxgrimg' => $row['wxgrimg'], + 'wxgrimg_url' => $row['wxgrimg'] ? build_qiniu_image_url($row['wxgrimg']) : '', + ]; + return $data; + } + + # tag_type=2意向标签的类型:1到店意向 2 购买意向 + private function get_tag_type2_pid($tag_type2 = null) + { + $arr = array(1 => 120, 2 => 121); + if (!$tag_type2) { + return $arr; + } + if (!in_array($tag_type2, array_keys($arr))) { + $tag_type2 = 1; + } + return $arr[$tag_type2]; + } + + protected function get_tag() + { + $id = intval($this->input_param('id')); + $type = $this->input_param('type'); + $tag_type = $this->input_param('tag_type'); + !strlen($tag_type) && $tag_type = 0; + $tag_type2 = $this->input_param('tag_type2'); + #$tag_type == 1 && $tag_type = 2; # 手工测试tag_type=2用 + $tag_type == 2 && !$tag_type2 && $tag_type2 = 1; + $tag_type2_pid = $tag_type == 2 ? $this->get_tag_type2_pid($tag_type2) : 0; + $tag_id = 0; # 230312, $tag_type=1时首个select中tag的id + $tags = $res_td = $re_cus = []; + $re_biz = $this->get_biz(); + $city_id = intval($re_biz['city_id']); + $county_id = intval($re_biz['county_id']); + $c_brand = intval($re_biz['car_brand_id']); + if ($id) { + $re_cus = $this->customers_model->get(['id' => $id]); + $re_cus['city_id'] && $city_id = $re_cus['city_id']; + $re_cus['county_id'] && $county_id = $re_cus['county_id']; + $re_cus['c_brand'] && $c_brand = $re_cus['c_brand']; + } + $where = ['status' => 1, 'pid' => 0, 'show<>' => 1, 'tag_type' => $tag_type]; + $tag_type2_pid && $where['id'] = $tag_type2_pid; + $res = $this->mdCustomerTag->select($where, 'sort desc,id desc', 0, 0, 'id,name,type'); + if ($res) { + if ($id) { + $res_td = $this->mdCustomerTagdata->select(['c_id' => $id], 'id desc', 0, 0, 't_id'); + } + $tag_data = $res_td ? array_unique(array_column($res_td, 't_id')) : ''; + $tag_checked = array(); + $tag_checked_id = 0; + foreach ($res as $key => $val) { + $list = []; + $res2 = $this->mdCustomerTag->select(['status' => 1, 'pid' => $val['id']], 'sort desc,id desc', 0, 0, 'id,name'); + foreach ($res2 as $key2 => $val2) { + //检查是否选中标签 + $checked = $tag_data && in_array($val2['id'], $tag_data) ? true : false; + $list[] = ['id' => $val2['id'], 'name' => $val2['name'], 'checked' => $checked]; + $tag_type == 1 && $checked && $tag_checked[] = $val2['id']; + $tag_type == 1 && $checked && !$tag_checked_id && $tag_checked_id = $val['id']; + } + $tags[] = ['id' => $val['id'], 'name' => $val['name'], 'type' => $val['type'], 'list' => $list]; + } + $tag_type == 1 && count($tag_checked) == 1 && $tag_id = $tag_checked_id; + } + $res = ['tags' => $tags, 'city_id' => $city_id, 'county_id' => $county_id, 'c_brand' => $c_brand]; + $tag_type == 1 && $res['tag_id'] = $tag_id; + return $res; + } + + //修改基本信息 + protected function put_data() + { + $biz_id = $this->biz_id; + $id = $this->input_param('cus_id'); + $name = $this->input_param('name'); + $mobile = $this->input_param('mobile'); + $c_brand = $this->input_param('c_brand'); + $of_id = $this->input_param('of_id'); //线下来源一级 + $of2_id = $this->input_param('of2_id'); //线下来源一级 + $buy_time = $this->input_param('buy_time'); //预计购车时间 + $tag = $this->input_param('tag'); //客户标签 + $city_id = $this->input_param('city_id'); //城市id + $county_id = $this->input_param('county_id'); //区id + $wxgr = $this->input_param('wxgr'); //是否加个微 + $wxgrimg = $this->input_param('wxgrimg'); //个微截图 + $row = $this->customers_model->get(['id' => $id]); + if (!$row) { + throw new Exception('参数错误', ERR_PARAMS_ERROR); + } + if ($wxgr && !$wxgrimg && !$row['wxgrimg']) { + throw new Exception('请上传‘添加个微’截图!', ERR_PARAMS_ERROR); + } + $update = []; + if ($row['cf_title'] != '平台分配') { + if ($mobile) { + if (!mobile_valid($mobile)) { + throw new Exception('手机号格式错误', ERR_PARAMS_ERROR); + } + if ($this->customers_model->count(['biz_id' => $biz_id, 'mobile' => $mobile])) { + throw new Exception('客户已存在', API_CODE_FAIL); + } + $update['mobile'] = $mobile; + } + } + $name && $update['name'] = $name; + isset($c_brand) && $update['c_brand'] = $c_brand; + $of2_id && $update['of2_id'] = $of2_id; + $city_id && $update['city_id'] = $city_id; + $county_id && $update['county_id'] = $county_id; + $wxgr && $update['wxgr'] = intval($wxgr) ? 1 : 0; + $wxgrimg && $wxgrimg != $row['wxgrimg'] && $update['wxgrimg'] = $wxgrimg; + if ($buy_time) { + $update['level'] = $this->customers_entity->cal_level($buy_time); + $update['buy_time'] = $buy_time; + } + $update && $this->customers_model->update($update, ['id' => $id]); + //客户标签 + if ($tag) { + $add_tag = []; + //查找已加入标签 + $res_td = $this->mdCustomerTagdata->select(['c_id' => $id], 'id desc', 0, 0, 't_id'); + $tag_data = $res_td ? array_unique(array_column($res_td, 't_id')) : ''; + foreach ($tag as $key => $val) { + foreach ($val['list'] as $key2 => $val2) { + if ($val2['checked'] == true) { + if (!$tag_data || !in_array($val2['id'], $tag_data)) {//未加标签,新增 + $add_tag[] = ['c_id' => $id, 't_id' => $val2['id'], 'c_time' => time()]; + } + } else { + if ($tag_data && in_array($val2['id'], $tag_data)) {//删除标签 + $this->mdCustomerTagdata->delete(['c_id' => $id, 't_id' => $val2['id']]); + } + } + } + } + if ($add_tag && count($add_tag)) { + $this->mdCustomerTagdata->add_batch($add_tag); + } + } + $uname = $this->session['uname']; + $this->customers_entity->add_log($id, $this->session['uid'], $uname, "修改用户基本信息"); + + if ($wxgr) { + $uid = $this->session['uid']; + $res = $this->customer_oplogs_model->get(['customer_id' => $id, 'uid' => $uid, 'type' => 10]); + if ($res) { + if ($wxgrimg && $wxgrimg != $row['wxgrimg'] || $wxgrimg && !$res['imgs']) { + $imgs = $res['imgs'] ? json_decode($res['imgs'], true) : []; + $imgs[] = $wxgrimg; + $this->customer_oplogs_model->update(array('imgs' => json_encode($imgs, JSON_UNESCAPED_UNICODE)), array('id' => $res['id'])); + } + } else { + $imgs = []; + $wxgrimg && $imgs[] = $wxgrimg; + $this->customers_entity->add_log($id, $uid, $uname, '加个微', 10, 'wxapp', $imgs); + } + } + + throw new Exception('保存成功', API_CODE_SUCCESS); + } + + //创建客户 + protected function post() + { + $name = $this->input_param('name'); + $mobile = $this->input_param('mobile'); + $buy_time = $this->input_param('buy_time'); //预计购车时间 + $c_brand = $this->input_param('c_brand'); //线下来源一级 + $of_id = 1; //线下来源一级 + $of2_id = $this->input_param('of2_id'); //线下来源一级 + $status = 0; //状态 + $tag = $this->input_param('tag'); //客户标签 + $city_id = $this->input_param('city_id'); //城市id + $county_id = $this->input_param('county_id'); //区id + $wxgr = $this->input_param('wxgr'); //是否加个微 + $wxgrimg = $this->input_param('wxgrimg'); //个微截图 + if (!mobile_valid($mobile)) throw new Exception('请输入正确的手机号码', ERR_PARAMS_ERROR); + if (!$city_id || !$county_id) { + throw new Exception('请选择城市与行政区', API_CODE_FAIL); + } + if ($wxgr && !$wxgrimg) { + throw new Exception('请上传‘添加个微’截图!', ERR_PARAMS_ERROR); + } + $is_exit = $this->customers_model->get(['biz_id' => $this->biz_id, 'mobile' => $mobile], 'id,sales_id'); + if ($is_exit) { + if ($is_exit['sales_id'] != $this->session['uid']) { + $user = $this->app_user_model->get(['id' => $is_exit['sales_id']], 'uname'); + $msg = "该客户归属于{$user['uname']}"; + $owner = 0; + } else { + $msg = '客户已存在'; + $owner = 1; + } + return ['code' => API_CODE_FAIL, 'msg' => $msg, 'data' => ['id' => $is_exit['id'], 'owner' => $owner]]; + } + $biz_row = $this->biz_model->get(['id' => $this->biz_id]); + + $level = $this->customers_entity->cal_level($buy_time); + $time = date('Y-m-d H:i:s'); + $add_data = [ + 'name' => $name, + 'mobile' => $mobile, + 'biz_id' => $this->biz_id, + 'admin_id' => $this->session['uid'], + 'sales_id' => $this->session['uid'], + 'level' => $level, + 'cf_title' => '自有资源', + 'cont_time' => $time, + 'status' => $status, + 'province_id' => $biz_row['province_id'], + 'city_id' => $city_id, + 'county_id' => $county_id, + 'wxgr' => intval($wxgr) ? 1 : 0, + 'wxgrimg' => $wxgrimg ? $wxgrimg : '', + 'c_time' => time() + ]; + if (!$add_data['city_id'] && $biz_row['city_id']) { + $add_data['city_id'] = $biz_row['city_id']; + } + if (!$add_data['county_id'] && $biz_row['county_id']) { + $add_data['county_id'] = $biz_row['county_id']; + } + $buy_time && $add_data['buy_time'] = $buy_time; + $of_id && $add_data['of_id'] = $of_id; + $of2_id && $add_data['of2_id'] = $of2_id; + $id = $this->customers_model->add($add_data); + if ($id) { + //客户标签 + if ($tag) { + $add_tag = []; + //查找已加入标签 + $res_td = $this->mdCustomerTagdata->select(['c_id' => $id], 'id desc', 0, 0, 't_id'); + $tag_data = $res_td ? array_unique(array_column($res_td, 't_id')) : ''; + foreach ($tag as $key => $val) { + foreach ($val['list'] as $key2 => $val2) { + if ($val2['checked'] == true) { + if (!$tag_data || !in_array($val2['id'], $tag_data)) {//未加标签,新增 + $add_tag[] = ['c_id' => $id, 't_id' => $val2['id'], 'c_time' => time()]; + } + } + } + } + if ($add_tag && count($add_tag)) { + $this->mdCustomerTagdata->add_batch($add_tag); + } + } + $uid = $this->session['uid']; + $uname = $this->session['uname']; + $this->load->library('receiver/customers_entity'); + $this->customers_entity->add_log($id, $uid, $uname, "创建客户档案", 3); + if ($wxgr) { + $imgs = []; + $wxgrimg && $imgs[] = $wxgrimg; + $this->customers_entity->add_log($id, $uid, $uname, '加个微', 10, 'wxapp', $imgs); + } + throw new Exception('创建成功', API_CODE_SUCCESS); + } else { + throw new Exception('创建失败', ERR_PARAMS_ERROR); + } + } + + /** + * Notes:用户评论 + * Created on: 2022/6/20 14:05 + * Created by: dengbw + * @throws Exception + */ + protected function post_comments() + { + $pid = $this->input_param('id'); + $content = $this->input_param('content'); + if (!$pid) { + throw new Exception('参数错误', API_CODE_FAIL); + } + if (!$content) { + throw new Exception('请输入评论内容', API_CODE_FAIL); + } + $this->load->model('receiver/receiver_comments_model', 'mdComments'); + $uid = $this->session['uid']; + $uname = $this->session['uname']; + $add_data = ['pid' => $pid, 'content' => $content, 'uid' => $uid, 'uname' => $uname, 'c_time' => time()]; + $id = $this->mdComments->add($add_data); + if ($id) { + throw new Exception('评论成功', API_CODE_SUCCESS); + } else { + throw new Exception('评论失败', ERR_PARAMS_ERROR); + } + } + + //客户跟进 + protected function put() + { + $biz_id = $this->biz_id; + $uid = $this->session['uid']; + $uname = $this->session['uname']; + $id = $this->input_param('id'); + $status = $this->input_param('status'); + $t_num = $this->input_param('t_num'); + $a_num = $this->input_param('a_num'); + $wxgr = $this->input_param('wxgr'); + $wxgrimg = $this->input_param('wxgrimg'); + $is_top = $this->input_param('is_top'); + $defeat_reason = $this->input_param('defeat_reason');//申请战败内容 + $level = $this->input_param('level');//客户等级 + $content = trim($this->input_param('content'));//小记内容 + $content_imgs = $this->input_param('imgs');//小记图片 + $follow_channel = $this->input_param('follow_channel');//跟进渠道 + $visit_time = $this->input_param('visit_time');//计划回访时间 + $invalid_tag = $this->input_param('invalid_tag'); //战败标签 + $daodian_tag = $this->input_param('daodian_tag'); //意向标签-到店 + $goumai_tag = $this->input_param('goumai_tag'); //意向标签-购买 + if ($follow_channel == '微信' && !$content_imgs) { + throw new Exception('请上传跟进截图!', ERR_PARAMS_ERROR); + } + $row = $this->customers_model->get(['id' => $id]); + if (!$row) { + throw new Exception('数据不存在!', ERR_PARAMS_ERROR); + } + if ($wxgr && !$wxgrimg && !$row['wxgrimg']) { + throw new Exception('请上传‘添加个微’截图!', ERR_PARAMS_ERROR); + } + $check_admin_id = true;//检查销售 + if ($this->session['group_id'] == 2 || $this->session['group_id'] == 3) {//店长、老板可以操作其他人的客户 + $check_admin_id = false; + } + if ($check_admin_id && $row['admin_id'] != $uid) { + throw new Exception('无权限操作该客户!', ERR_PARAMS_ERROR); + } + $up_data = []; + //变成到店 + if (!$row['admin_id'] && $status == 1) { + $up_data['admin_id'] = $uid; + } + $daodian_tag_str = ''; + if ($daodian_tag) { + + $tag_arr_all = array(); + $tag_checked = 0; + foreach ($daodian_tag as $key => $val) { + $tag_arr = []; + foreach ($val['list'] as $kt => $vt) { + $vt['checked'] && $tag_arr[] = $vt['name']; + $vt['checked'] && $tag_checked = 1; + } + $tag_arr_all = array_merge($tag_arr_all, $tag_arr); + $tag_arr && $daodian_tag_str .= $val['name'] . ': ' . implode(', ', $tag_arr) . '; '; + } + if (!$tag_checked) { + throw new Exception("到店意向不能为空!", ERR_PARAMS_ERROR); + } + } + + $goumai_tag_str = ''; + if ($goumai_tag) { + $tag_arr_all = array(); + $tag_checked = 0; + foreach ($goumai_tag as $key => $val) { + $tag_arr = []; + foreach ($val['list'] as $kt => $vt) { + $vt['checked'] && $tag_arr[] = $vt['name']; + $vt['checked'] && $tag_checked = 1; + } + $tag_arr_all = array_merge($tag_arr_all, $tag_arr); + $tag_arr && $goumai_tag_str .= $val['name'] . ': ' . implode(', ', $tag_arr) . '; '; + } + if (!$tag_checked) { + throw new Exception("购买意向不能为空!", ERR_PARAMS_ERROR); + } + } + $log_0 = $log_4 = $log_9 = ''; + if ($status == 3) { + if (!$defeat_reason) { + throw new Exception('请输入战败理由!', ERR_PARAMS_ERROR); + } + $tag_str = ''; + $tag_arr_all = array(); + $tag_checked = 0; # 20230312 只要有一个选中即可 + foreach ($invalid_tag as $key => $val) { + $tag_arr = []; + foreach ($val['list'] as $kt => $vt) { + $vt['checked'] && $tag_arr[] = $vt['name']; + $vt['checked'] && $tag_checked = 1; + } + /*# 20230101 提示没选中的标签 + if (!$tag_arr){ + throw new Exception("请选择标签[{$val['name']}]!", ERR_PARAMS_ERROR); + }*/ + $tag_arr_all = array_merge($tag_arr_all, $tag_arr); + $tag_arr && $tag_str .= $val['name'] . ': ' . implode(', ', $tag_arr) . '; '; + } + if (!$tag_checked) { + throw new Exception("请选择至少一个标签!", ERR_PARAMS_ERROR); + } + #$tag_str = implode(', ', $tag_arr_all); + $jsondata = $row['jsondata'] ? json_decode($row['jsondata'], true) : array(); + $jsondata['defeat']['time'] = date("Y-m-d H:i:s"); + $jsondata['defeat']['reason'] = $defeat_reason . "({$tag_str})"; + $up_data['if_defeat'] = 1; + $up_data['jsondata'] = json_encode($jsondata, JSON_UNESCAPED_UNICODE); + $log_0 = '申请战败:' . $defeat_reason . "({$tag_str})"; + } else { + if (strlen($status) && $status != $row['status']) { //变更状态 + $up_data['status'] = $status; + $status_name = $this->customers_model->get_status(); + $log_9 = '状态变更为' . $status_name[$status]; + } + } + strlen($is_top) && $up_data['is_top'] = $is_top; + if ($status == 1 && $status != $row['status']) {//到店客户和数据库不同到店加1 + $a_num = 1; + } + $day = date('Y-m-d'); + if ($a_num || $t_num) { + if ($a_num) {//判断今日是否到店 + $re = $this->customer_oplogs_model->get(['customer_id' => $id, 'type' => 4, + 'c_time >=' => strtotime($day . ' 00:00:00'), 'c_time <=' => strtotime($day . ' 23:59:59')]); + $re && $a_num = 0; + } + if ($t_num) {//判断今日是否试驾 + $re = $this->customer_oplogs_model->get(['customer_id' => $id, 'type' => 5, + 'c_time >=' => strtotime($day . ' 00:00:00'), 'c_time <=' => strtotime($day . ' 23:59:59')]); + $re && $t_num = 0; + } + } + $a_num && $up_data['a_num = a_num+1'] = null; + $t_num && $up_data['t_num = t_num+1'] = null; + $wxgr && $up_data['wxgr'] = 1; + $wxgrimg && $wxgrimg != $row['wxgrimg'] && $up_data['wxgrimg'] = $wxgrimg; + $visit_time && $up_data['visit_time'] = $visit_time; + if ($level && $level != $row['level']) { + $up_data['level'] = $level;//更改客户等级 + } + $log_4 = '';//到店 + if ($a_num) { + $log_4 = $row['status'] == 1 ? '客户再次到店' : '客户到店'; + $up_data['cont_time'] = date('Y-m-d H:i:s'); //修改到店状态修改最后联系时间 + if ($row['dt_time'] == '0000-00-00 00:00:00') {//首次到店时间 + $up_data['dt_time'] = date('Y-m-d H:i:s'); + } + } + $result = true; + $this->load->library('receiver/customers_entity'); + if ($up_data) { + $result = $this->customers_model->update($up_data, ['id' => $id]); + if ($result) { //添加日志 + if ($level && $level != $row['level']) { + $this->customers_entity->add_log($id, $uid, $uname, '更改客户等级', 9); + } + if ($log_9) {//系统变更 + $this->customers_entity->add_log($id, $uid, $uname, $log_9, 9); + } + if ($log_4) {//到店 + $this->customers_entity->add_log($id, $uid, $uname, $log_4, 4); + } + if ($t_num) {//试驾 + $this->customers_entity->add_log($id, $uid, $uname, '客户试驾', 5); + } + if ($wxgr) { + $res = $this->customer_oplogs_model->get(['customer_id' => $id, 'uid' => $uid, 'type' => 10]); + if ($res) { + if ($wxgrimg && $wxgrimg != $row['wxgrimg'] || $wxgrimg && !$res['imgs']) { + $imgs = $res['imgs'] ? json_decode($res['imgs'], true) : []; + $imgs[] = $wxgrimg; + $this->customer_oplogs_model->update(array('imgs' => json_encode($imgs, JSON_UNESCAPED_UNICODE)), array('id' => $res['id'])); + } + } else { + $imgs = []; + $wxgrimg && $imgs[] = $wxgrimg; + $this->customers_entity->add_log($id, $uid, $uname, '加个微', 10, 'wxapp', $imgs); + } + } + if ($log_0) {//小记 + $this->customers_entity->add_log($id, $uid, $uname, $log_0, 0); + } +// if ($status == 2) {//变成订单客户 更新客户已回访 +// $this->customers_entity->add_log_visit($id, $uid, $uname, '', 0, 1); +// } + } + } + if ($content) {//加小记 + $follow_channel && $content = "跟进渠道($follow_channel):" . $content; + if ($visit_time) { + $content .= '。计划回访时间:' . $visit_time; + $daodian_tag_str && $content .= '。' . $daodian_tag_str; + $goumai_tag_str && $content .= '。' . $goumai_tag_str; + $sales_id = $row['admin_id'] ? $row['admin_id'] : $uid;//有销售id,回访归属销售 + $where_vis = ['c_id' => $id, 'biz_id' => $biz_id, 'sales_id' => $sales_id, 't_day' => $visit_time]; + $re_vis = $this->mdCustomerVisitData->get($where_vis); + if (!$re_vis) { + //删除大于等今天的回访记录 + $this->mdCustomerVisitData->delete(['c_id' => $id, 'biz_id' => $biz_id, 't_day>=' => date('Y-m-d')]); + $where_vis['level'] = $level; + $where_vis['c_time'] = time(); + $this->mdCustomerVisitData->add($where_vis); + } + } + $result = $this->customers_entity->add_log_visit($id, $uid, $uname, $content, 0, 1, $content_imgs); + } + if ($result) { + //战败标签 + //意向标签 合并到 战败标签 统一处理 + !$invalid_tag && $invalid_tag = array(); + $daodian_tag && $invalid_tag = array_merge($invalid_tag, $daodian_tag); + $goumai_tag && $invalid_tag = array_merge($invalid_tag, $goumai_tag); + if ($invalid_tag) { + $add_tag = []; + //查找已加入标签 + $res_td = $this->mdCustomerTagdata->select(['c_id' => $id], 'id desc', 0, 0, 't_id'); + $tag_data = $res_td ? array_unique(array_column($res_td, 't_id')) : ''; + foreach ($invalid_tag as $key => $val) { + foreach ($val['list'] as $key2 => $val2) { + if ($val2['checked'] == true) { + if (!$tag_data || !in_array($val2['id'], $tag_data)) {//未加标签,新增 + $add_tag[] = ['c_id' => $id, 't_id' => $val2['id'], 'c_time' => time()]; + } + } else { + if ($tag_data && in_array($val2['id'], $tag_data)) {//删除标签 + $this->mdCustomerTagdata->delete(['c_id' => $id, 't_id' => $val2['id']]); + } + } + } + } + if ($add_tag && count($add_tag)) { + $this->mdCustomerTagdata->add_batch($add_tag); + } + } + throw new Exception('操作成功', API_CODE_SUCCESS); + } else { + throw new Exception('操失败!', ERR_PARAMS_ERROR); + } + } + + //订单列表头部 + protected function get_tabs() + { + $rows = $this->customers_model->get_status(); + $lists = []; + if ($rows) { + foreach ($rows as $key => $val) { + if ($key != -1) { + $lists[] = [ + 'key' => $key, + 'name' => $val + ]; + } + } + } + return $lists; + } + + //获取筛选条件 + protected function get_filter() + { + $level = $this->customers_model->get_sdata('level'); + $cfrom = $this->customers_model->get_sdata(); + $follow_channel = $this->customers_model->get_sdata('follow_channel'); + $buy_time = $this->customers_model->get_sdata('btime'); + $show_btime = $tags = []; + foreach ($buy_time as $key => $val) { + $show_btime[] = ['id' => $key, 'name' => $val]; + } + $res_tag = $this->mdCustomerTag->select(['status' => 1, 'pid' => 0, 'show<>' => 1, 'tag_type' => 0], 'sort desc,id desc', 0, 0, 'id,name,type'); + if ($res_tag) { + foreach ($res_tag as $key => $val) { + $list = []; + $res2 = $this->mdCustomerTag->select(['status' => 1, 'pid' => $val['id']], 'sort desc,id desc', 0, 0, 'id,name'); + foreach ($res2 as $key2 => $val2) { + $list[] = ['id' => $val2['id'], 'name' => $val2['name'], 'checked' => false]; + } + $tags[] = ['id' => $val['id'], 'name' => $val['name'], 'type' => $val['type'], 'list' => $list]; + } + } + $data = [ + 'tags' => $tags, + 'level' => $level, + 'cfrom' => $cfrom, + 'buy_time' => $show_btime, + 'follow_channel' => $follow_channel + ]; + return $data; + } + + /** + * Notes:线下来源 + * Created on: 2022/3/7 10:01 + * Created by: dengbw + * @return mixed + */ + protected function get_offline_sources() + { + $offline_sources = $this->customers_model->offlineSources(); + $lists = []; + foreach ($offline_sources[3]['list'] as $key => $item) { + $lists[] = [ + 'id' => $key, + 'name' => $item, + ]; + } + return $lists; + } + + //获取客户列表 + private function lists() + { + $visit = $this->input_param('visit'); + if ($visit) { + return $this->visit_lists($this->input_param(), $visit); + } + $uid = $this->session['uid']; + $group_id = $this->session['group_id']; + $biz_type = $this->get_biz('type'); + $s_time = $this->input_param('s_time'); + $e_time = $this->input_param('e_time'); + $if_driver = $this->input_param('if_driver'); + $level = $this->input_param('level'); + $brand_id = $this->input_param('brand_id'); + $cfrom = $this->input_param('cfrom'); //客户来源id + $status = $this->input_param('status'); //状态 + $o_type = $this->input_param('o_type'); //排序 + $page = $this->input_param('page'); + $size = $this->input_param('size'); + $istop = $this->input_param('istop'); + $iscall = $this->input_param('iscall'); + $unuse = $this->input_param('unuse'); //未派客户 + $ismy = $this->input_param('ismy'); //是否只显示自己 + $name = $this->input_param('name'); + $mobile = $this->input_param('mobile'); + $admin_id = $this->input_param('admin_id'); + $id = $this->input_param('cus_id'); + $a_id = intval($this->input_param('a_id'));//私域通活动id + $of_id = intval($this->input_param('of_id'));//线下来源一级 + $of2_id = intval($this->input_param('of2_id'));//线下来源二级 + $s_visit_time = $this->input_param('s_visit_time');//回访开始时间 + $e_visit_time = $this->input_param('e_visit_time');//回访结束时间 + $status_tp = intval($this->input_param('status_tp')); //状态类型 + $admin_ids = $this->input_param('admin_ids');//多选销售人员 + $tag_ids = $this->input_param('tag_ids');//多选客户画像 + $city_id = $this->input_param('city_id'); + $county_id = $this->input_param('county_id'); + + !$page && $page = 1; + !$size && $size = 10; + + if ($o_type == 1) { //创建时间排序 + $orderby = 'c_time desc'; + } elseif ($o_type == 2) {//最近联系 + $orderby = 'cont_time desc'; + } else { //特别关注 + if ($group_id == 1) { + $orderby = 'is_top desc,c_time desc'; + } else { + $orderby = 'c_time desc'; + } + } + $where = [ + 'biz_id' => $this->biz_id, + 'cs_biz_id<>' => -1, + 'status>=' => 0 + ]; + if ($of_id) { + $where["of_id"] = $of_id; + } + if ($of2_id) { + $where["of2_id"] = $of2_id; + } + if ($a_id) { + $where["cf_id"] = 35; + $where["t_id"] = $a_id; + } + if ($group_id == 1 || $ismy) { + $where["admin_id"] = $uid; + } + if ($group_id == 4 && $this->biz_id != 1) { + $where['brand_id<>'] = 3; //渠道经理过滤 + } + if ($s_time && $e_time) { + $where['c_time >='] = strtotime($s_time); + $where['c_time <='] = strtotime(date('Y-m-d 23:59:59', strtotime($e_time))); + } + if ($s_visit_time && $e_visit_time) { + $where['visit_time >='] = $s_visit_time; + $where['visit_time <='] = $e_visit_time; + } + if (strlen($iscall)) { + if ($iscall) { + $where['cont_time!='] = '0000-00-00 00:00:00'; + } else { + $where['cont_time'] = '0000-00-00 00:00:00'; + $status_tp = 1; + } + } + if ($status_tp == 1) { + $where['status in(0,1)'] = null; + } + $unuse && $where['admin_id'] = 0; + $admin_id && $where['admin_id'] = $admin_id; + if ($admin_ids) { + $where["admin_id in ({$admin_ids})"] = null; + } + $id && $where['id'] = $id; + strlen($istop) && $where['is_top'] = $istop; + strlen($if_driver) && $where['if_driver'] = 1; + strlen($status) && $where['status'] = $status; + $brand_id && $where['brand_id'] = $brand_id; + $level && $where['level'] = $level; + $cfrom && $where['cf_title'] = $cfrom; + $name && $where["name like '%{$name}%'"] = null; + $mobile && $where["mobile like '%$mobile%'"] = null; + $city_id && $where['city_id'] = $city_id; + $county_id && $where['county_id'] = $county_id; + + if ($tag_ids) { + $pidAry = []; + $res_tag = $this->mdCustomerTag->select(["id in ({$tag_ids})" => null], 'id desc', 0, 0, 'pid,id'); + foreach ($res_tag as $v) { + $v['pid'] && $pidAry[$v['pid']][] = $v['id']; + } + $str_c_ids = $res_tag_data = ''; + foreach ($pidAry as $v) { + if ($v) { + $where_tag = []; + $str_ids = implode(',', $v); + $where_tag["t_id in({$str_ids})"] = null; + if ($str_c_ids) { + $where_tag["c_id in({$str_c_ids})"] = null; + } + $res_tag_data = $this->mdCustomerTagdata->select_groupby('c_id', $where_tag, "id desc", 0, 0, "c_id"); + if (!$res_tag_data) { + break; + } + if ($res_tag_data) { + $str_c_ids = implode(',', array_column($res_tag_data, 'c_id')); + } + } + } + if ($res_tag_data) { + $str_cids = implode(',', array_column($res_tag_data, 'c_id')); + $where["id in({$str_cids})"] = null; + } else { + $where["id"] = -1; + } + } + $count = $this->customers_model->count($where); + $lists = []; + if ($count) { + $fileds = 'id,name,admin_id,mobile,level,car_json,is_top,cf_title,brand_id,cont_time,c_time,if_defeat + ,of_id,of2_id,wxqy,status,biz_id,cs_biz_id,county_id'; + $rows = $this->customers_model->select($where, $orderby, $page, $size, $fileds); + $lists = $this->listCustomerField(['rows' => $rows, 'biz_type' => $biz_type, 'group_id' => $group_id]); + } + $data = [ + 'list' => $lists, + 'total' => $count + ]; + return $data; + } + + /** + * Notes:客户列表字段 + * Created on: 2022/10/14 16:03 + * Created by: dengbw + * @param array $param + * @return array + */ + private function listCustomerField($param = []) + { + $lists = $admins = $map_county = []; + //所在地区 + $str_county_ids = implode(',', array_unique(array_column($param['rows'], 'county_id'))); + if ($str_county_ids) { + $map_county = $this->mdArea->map('county_id', 'city_name,county_name', ["county_id in({$str_county_ids})" => null]); + } + //获取管理员 + $admin_ids = implode(',', array_unique(array_column($param['rows'], 'admin_id'))); + if ($admin_ids) { + $admins = $this->app_user_model->map('id', '', ["id in ({$admin_ids})" => null], '', '', '', 'id,uname'); + } + $allot = $this->get_allot(); + $status_name = $this->customers_model->get_status(); + foreach ($param['rows'] as $key => $val) { + if ($map_county[$val['county_id']]) { + $other_data['所在地区'] = "{$map_county[$val['county_id']]['city_name']}-{$map_county[$val['county_id']]['county_name']}"; + } + if ($param['biz_type'] != 5) { + $other_data['客户来源'] = $this->get_cfTitle($val); + } + $other_data['建卡时间'] = date('Y-m-d', $val['c_time']); + $val['cont_time'] != '0000-00-00 00:00:00' && $other_data['最近联系'] = date('Y-m-d', strtotime($val['cont_time'])); + if ($param['group_id'] == 1) { + $where_visit = ['c_id' => $val['id'], 'biz_id' => $this->biz_id, 'sales_id' => $this->session['uid']]; + } else { + $where_visit = ['c_id' => $val['id'], 'biz_id' => $val['biz_id'], 'sales_id' => $val['admin_id']]; + } + $visit_time = $this->get_visit_time($where_visit); + $visit_time && $other_data['计划回访时间'] = $visit_time; + $other_data['销售顾问'] = isset($admins[$val['admin_id']]) ? $admins[$val['admin_id']][0]['uname'] : ''; + $tags = [$val['level'] . '级用户']; + $defeat = $orders_pay = ''; + if ($val['if_defeat'] == 1) { + $defeat = '战败申请中'; + } else if ($val['if_defeat'] == 2) { + $defeat = '再战'; + } + $tip = $status_name[$val['status']] ? $status_name[$val['status']] : ''; + $lists[] = [ + 'id' => $val['id'], + 'name' => $val['name'], + 'mobile' => $this->get_mobile(['mobile' => $val['mobile'], 'of_id' => $val['of_id'], 'of2_id' => $val['of2_id']]), + 'complete_mobile' => $val['mobile'], + 'is_top' => $val['is_top'], + 'other_data' => $other_data, + 'tags' => $tags, + 'defeat' => $defeat, + 'orders_pay' => '', + 'group_id' => $param['group_id'], + 'is_weChat' => $val['wxqy'] == 1 ? true : false, + 'allot' => $allot, + 'tip' => $tip, + 'level' => $val['level'], + 'reassign' => $val['cs_biz_id'] > 0 ? '他店改派' : '', + ]; + } + return $lists; + } + + //派单给店员 + protected function put_admins() + { + $uname = $this->session['uname']; + $uid = $this->session['uid']; + $id_arr = $this->input_param('ids'); + $admin_id = $this->input_param('admin_id'); + $visit_time = $this->input_param('visit_time'); + $biz_id = intval($this->input_param('biz_id')); + $allot = $this->get_allot(); + if ($allot == 0) { + throw new Hd_exception('无权限分配', API_CODE_INVILD_PARAM); + } + if (!$id_arr) { + throw new Hd_exception('参数错误', API_CODE_INVILD_PARAM); + } + $this->load->library('receiver/customers_entity'); + if ($biz_id) {//改派 + $nums = count($id_arr); + foreach ($id_arr as $val) { + $id = $val; + $re = $this->customers_model->get(['id' => $id]); + if ($re['biz_id'] == $biz_id) {//同个门店跳出循环 + if ($nums == 1) { + throw new Hd_exception('不能分配给相同门店', API_CODE_INVILD_PARAM); + } + continue; + } + $re2 = $this->customers_model->get(['biz_id' => $biz_id, 'mobile' => $re['mobile']]); + if ($re2) {//客户已存在门店里 + if ($nums == 1) { + throw new Hd_exception('客户已在此门店', API_CODE_INVILD_PARAM); + } + continue; + } + $addData = ['rid' => $re['rid'], 'name' => $re['name'], 'mobile' => $re['mobile'], 'biz_id' => $biz_id + , 'cs_biz_id' => $re['biz_id'], 'level' => $re['level'], 'cf_title' => $re['cf_title'], 'cf_id' => $re['cf_id'] + , 'of_id' => $re['of_id'], 'of2_id' => $re['of2_id'], 'status' => $re['status'], 'c_time' => time(), 'city_id' => $re['city_id'] + , 'county_id' => $re['county_id']]; + $re['jsondata'] && $addData['jsondata'] = $re['jsondata']; + $customer_id = $this->customers_model->add($addData); + if ($customer_id) { + //初始门店更改-1,狸车宝过滤 + $this->customers_model->update(['cs_biz_id' => -1], ["id" => $id]); + //删除未回访计划 + $this->mdCustomerVisitData->delete(['c_id' => $id, 'biz_id' => $re['biz_id'], 'status<>' => 2, 't_day >=' => date('Y-m-d')]); + //同步客户标签 + $res_tag = $this->mdCustomerTagdata->select(['c_id' => $id], 'id asc', 0, 0, 't_id,c_time'); + if ($res_tag) { + $add_tag = []; + foreach ($res_tag as $val2) { + $val2['c_id'] = $customer_id; + $add_tag[] = $val2; + } + $this->mdCustomerTagdata->add_batch($add_tag); + } + //同步跟进记录 + $res_oplogs = $this->customer_oplogs_model->select(['customer_id' => $id], 'id asc', 0, 0 + , 'uid,uname,type,log,imgs,cf_platform,c_time'); + if ($res_oplogs) { + $add_oplogs = []; + foreach ($res_oplogs as $val3) { + $val3['customer_id'] = $customer_id; + $add_oplogs[] = $val3; + } + $this->customer_oplogs_model->add_batch($add_oplogs); + } + $this->customers_entity->add_log($id, $uid, $uname, "客户改派");//改派的客户日志 + $this->customers_entity->add_log($customer_id, $uid, $uname, "客户改派");//改派后的客户日志 + } + } + throw new Exception('分配成功', API_CODE_SUCCESS); + } + if (!$visit_time) { + throw new Hd_exception('请选择回访时间', API_CODE_INVILD_PARAM); + } + $admin = $this->app_user_model->get(['id' => $admin_id, 'status' => 1]); + if (!$admin) { + throw new Hd_exception('参数错误', API_CODE_INVILD_PARAM); + } + foreach ($id_arr as $val) { + $id = $val; + $re = $this->customers_model->get(['id' => $id]); + if ($re['admin_id'] == $admin_id) {//同个销售跳出循环 + continue; + } + $upDate = ['admin_id' => $admin_id, 'visit_time' => $visit_time]; + !$re['sales_id'] && $upDate['sales_id'] = $admin_id;//初始销售id + $ret = $this->customers_model->update($upDate, ["id" => $id]); + if ($ret) { + //写日志 + $this->customers_entity->add_log($id, $uid, $uname, "分配客户"); + $biz_id = $re['biz_id']; + $level = $re['level']; + $where_vis = ['c_id' => $id, 'biz_id' => $biz_id, 'sales_id' => $admin_id, 't_day' => $visit_time]; + $re_vis = $this->mdCustomerVisitData->get($where_vis); + if (!$re_vis) { + //删除未回访计划 + $this->mdCustomerVisitData->delete(['c_id' => $id, 'biz_id' => $biz_id, 'status<>' => 2, 't_day >=' => date('Y-m-d')]); + $where_vis['level'] = $level; + $where_vis['c_time'] = time(); + $this->mdCustomerVisitData->add($where_vis); + $this->customers_entity->add_log_visit($id, $uid, $uname, '计划回访时间:' . $visit_time, 0, 1); + } + //发送短信 + $num = $re['mobile'] ? substr($re['mobile'], -4) : 0; + send_alisms(array('mobile' => $admin['mobile'], 'template' => 'SMS_226945702', 'param' => ['num' => $num])); + } + } + throw new Exception('分配成功', API_CODE_SUCCESS); + } + + /** + * Notes:客户待回访tab + * Created on: 2022/6/2 10:20 + * Created by: dengbw + * @return array + */ + protected function get_visit_tabs() + { + $status = $this->input_param('status'); + $tabs = []; + if ($status == 1) {//跟进客户 + $tabs = [['name' => '本日新增跟进', 'id' => 1], ['name' => '逾期未跟进', 'id' => 3]]; + } else if ($status == 3) { + $tabs = [['name' => '今日', 'id' => 1], ['name' => '本月线索', 'id' => 2]]; + } else if ($status == 4) { + $tabs = [['name' => '今日', 'id' => 1], ['name' => '本月企v', 'id' => 2]]; + } else if ($status == 5) { + $tabs = [['name' => '今日', 'id' => 1], ['name' => '本月到店', 'id' => 2]]; + } else if ($status == 6) { + $tabs = [['name' => '今日', 'id' => 1], ['name' => '本月订单', 'id' => 2]]; + } else if ($status == 7) { + $tabs = [['name' => '今日', 'id' => 1], ['name' => '本月战败', 'id' => 2]]; + } else if ($status == 8) { + $tabs = [['name' => '今日', 'id' => 1], ['name' => '本月退订', 'id' => 2]]; + } + return ['list' => $tabs]; + } + + /** + * Notes:客户回访记录列表 + * Created on: 2022/10/14 14:40 + * Created by: dengbw + * @param array $params + * @param int $visit + * @return array + */ + private function visit_lists($params = [], $visit = 1) + { + $group_id = $this->session['group_id']; + $biz_type = $this->get_biz('type'); + $page = intval($params['page']); + $size = intval($params['size']); + $tab_id = intval($params['visit_tab_id']); + !$page && $page = 1; + !$size && $size = 10; + $count = 0; + $lists = $where = $rows = []; + if ($visit == 1) {//客户回访记录 + $status = intval($params['status']); + $t_day = date('Y-m-d'); + $where = array('a.biz_id' => $this->biz_id, 'a.cs_biz_id<>' => -1, 'a.status in(0,1)' => null, 'b.t_day' => $t_day); + $params['level'] && $where['a.level'] = $params['level'];//等级 + $params['admin_id'] && $where['a.admin_id'] = $params['admin_id'];//等级 + if ($status == 2) {//已跟进 + $where['b.status'] = 2; + } else { + if ($tab_id) { + $where['b.status'] = $tab_id; + } else { + $where['b.status<>'] = 2; + } + } + $group_id == 1 && $where['a.admin_id'] = $this->myuid; + $count = $this->mdCustomerVisitData->count_visit($where); + } else {//数据看板 数据列表 + if ($tab_id == 2) {//今日 + $s_c_time = date('Y-m-01', strtotime(date("Y-m-d"))) . ' 00:00:00'; + $e_c_time = date('Y-m-d', strtotime("$s_c_time +1 month -1 day")) . ' 23:59:59'; + } else {//本月 + $s_c_time = date('Y-m-d') . ' 00:00:00'; + $e_c_time = date('Y-m-d') . ' 23:59:59'; + } + if ($visit == 3) {//今日/本月线索 + $where = ['biz_id' => $this->biz_id, 'cs_biz_id<>' => -1, 'status>=' => 0, 'c_time>=' => strtotime($s_c_time) + , 'c_time<=' => strtotime($e_c_time)]; + $group_id == 1 && $where['admin_id'] = $this->myuid; + $count = $this->customers_model->count($where); + } else if ($visit == 4) {//今日/本月企v + $where = ['change_type' => 'add_external_contact', 'c_time>=' => strtotime($s_c_time), 'c_time<=' => strtotime($e_c_time)]; + if ($biz_type == 5) {//异业店 + $this->load->model('app/app_different_qy_log_model', 'mdWechatLog'); + $this->load->model('app/app_different_qy_model', 'mdWechat'); + } else { + $this->load->model('app/app_lichene_qy_log_model', 'mdWechatLog'); + $this->load->model('app/app_lichene_qy_model', 'mdWechat'); + } + if ($group_id == 1) { + $where['userid'] = $this->session['userid'] ? $this->session['userid'] : '-1'; + } else { + $res_user = $this->app_user_model->select(['biz_id' => $this->biz_id, 'group_id <' => 4, 'status >=' => 0, 'userid<>' => ''], 'id asc', 0, 0, 'userid'); + if ($res_user) { + $str_userids = implode("','", array_column($res_user, 'userid')); + $where["userid in('{$str_userids}')"] = null; + } else { + $where["userid"] = '-1'; + } + } + $count = $this->mdWechatLog->count($where, 'distinct(external_userid)'); + } else if ($visit == 5 || $visit == 7) {//今日/本月到店/战败 + $oplogs_type = $visit == 7 ? 7 : 4;//4到店7战败 + $s_c_time = strtotime($s_c_time); + $e_c_time = strtotime($e_c_time); + $where = ['biz_id' => $this->biz_id, 'status>=' => 0, 'cs_biz_id<>' => -1]; + $str_uids = ''; + if ($group_id == 1) { + $str_uids = $this->myuid; + } else { + $res_user = $this->app_user_model->select(['biz_id' => $this->biz_id, 'group_id <' => 4, 'status>=' => 0], 'id asc', 0, 0, 'id,userid'); + foreach ($res_user as $k => $v) { + $str_uids = $str_uids ? $str_uids . ',' . $v['id'] : $v['id']; + } + } + !$str_uids && $str_uids = '-1'; + $where["id in(select customer_id from lc_receiver_customer_oplogs where type={$oplogs_type} and uid in({$str_uids}) and c_time>={$s_c_time} and c_time<={$e_c_time})"] = null; + $count = $this->customers_model->count($where); + } + } + if ($count) { + $fileds = 'id,name,admin_id,mobile,level,car_json,is_top,cf_title,brand_id,s_id,cont_time,c_time,if_defeat + ,of_id,of2_id,wxqy,status,biz_id,cs_biz_id,county_id'; + if ($visit == 1) { + $fileds = 'a.id,a.name,a.admin_id,a.mobile,a.level,a.is_top,a.cont_time,a.c_time,a.if_defeat,a.cf_title + ,a.of_id,a.of2_id,a.status,a.biz_id,a.county_id'; + $rows = $this->mdCustomerVisitData->select_visit($where, 'a.id desc', $page, $size, $fileds); + $lists = $this->listCustomerField(['rows' => $rows, 'biz_type' => $biz_type, 'group_id' => $group_id]); + } else if ($visit == 4) { + $fileds = 'distinct(external_userid) as external_userid,userid,c_time'; + $rows = $this->mdWechatLog->select($where, 'c_time desc', $page, $size, $fileds); + foreach ($rows as $k => $v) { + $mobile = $nickname = $avatar = ''; + $re_item = []; + if ($v['external_userid']) {//查找企微用户 + $where_wec = ['external_userid' => $v['external_userid']]; + $v['userid'] && $where_wec['userid'] = $v['userid']; + $res_wec = $this->mdWechat->get($where_wec); + if ($res_wec) { + $mobile = $res_wec['mobile']; + $nickname = $res_wec['name']; + $avatar = $res_wec['avatar']; + } + } + if ($mobile) {//查找关连客户 + $where = ['mobile' => $mobile, 'cs_biz_id<>' => -1, 'status>=' => 0]; + $this->biz_id && $where['biz_id'] = $this->biz_id; + $res_cus = $this->customers_model->get($where); + if ($res_cus) { + if ($res_cus['wxqy'] == 0) {//更新为企微好友 + $res_cus['wxqy'] = 1; + $this->customers_model->update(['wxqy' => $res_cus['wxqy']], ['id' => $res_cus['id']]); + } + $rows = [$res_cus]; + $re = $this->listCustomerField(['rows' => $rows, 'biz_type' => $biz_type, 'group_id' => $group_id]); + count($re) && $re_item = $re[0]; + } + } + if (!$re_item) {//未关连到客户 + $other_data['通过时间'] = date('Y-m-d', $v['c_time']); + if ($v['userid']) {//查找销售顾问 + $res_user = $this->app_user_model->get(['userid' => $v['userid']]); + $res_user && $other_data['销售顾问'] = $res_user['uname'] ? $res_user['uname'] : $res_user['nickname']; + } + $re_item = ['nickname' => $nickname, 'avatar' => $avatar, 'other_data' => $other_data]; + } + $lists[] = $re_item; + } + } else { + $rows = $this->customers_model->select($where, 'c_time desc', $page, $size, $fileds); + $lists = $this->listCustomerField(['rows' => $rows, 'biz_type' => $biz_type, 'group_id' => $group_id]); + } + } + $data = [ + 'list' => $lists, + 'total' => $count + ]; + return $data; + } + + /** + * Notes:战败申请列表 + * Created on: 2021/10/21 15:19 + * Created by: dengbw + * @return array + * @throws Hd_exception + */ + protected function get_defeats() + { + $group_id = $this->session['group_id']; + if ($group_id == 1) { + return $data = ['list' => [], 'total' => 0]; + } + $params = $this->input_param(); + $page = $params['page']; + $size = $params['size']; + !$page && $page = 1; + !$size && $size = 10; + $where = array('biz_id' => $this->biz_id, 'cs_biz_id<>' => 1, 'if_defeat' => 1, 'status>' => -1); + $count = $this->customers_model->count($where); + $lists = []; + if ($count) { + $fileds = 'id,name,mobile,jsondata,cf_title,of_id,of2_id'; + $rows = $this->customers_model->select($where, 'id desc', $page, $size, $fileds); + foreach ($rows as $key => $val) { + $jsondata = $val['jsondata'] ? json_decode($val['jsondata'], true) : array(); + $reason = $jsondata['defeat']['reason'] ? '战败理由:' . $jsondata['defeat']['reason'] : ''; + $lists[] = [ + 'id' => $val['id'], + 'name' => $val['name'], + 'mobile' => $this->get_mobile(['mobile' => $val['mobile'], 'of_id' => $val['of_id'], 'of2_id' => $val['of2_id']]), + 'reason' => $reason, + ]; + } + } + $data = [ + 'list' => $lists, + 'total' => $count + ]; + return $data; + } + + /** + * Notes:通过战败申请 + * Created on: 2021/10/21 16:19 + * Created by: dengbw + * @throws Exception + */ + protected function put_defeats() + { + $group_id = $this->session['group_id']; + if ($group_id == 1) { + throw new Exception('无操作权限', ERR_PARAMS_ERROR); + } + $params = $this->input_param(); + $id = intval($params['id']); + $type = intval($params['type']); + if (!$id) { + throw new Exception('参数错误', ERR_PARAMS_ERROR); + } + $row = $this->customers_model->get(array('id' => $id)); + if (!$row) { + throw new Exception('用户不存在', ERR_PARAMS_ERROR); + } + if (!$row['if_defeat']) { + throw new Exception('未申请战败', ERR_PARAMS_ERROR); + } + $jsondata = $row['jsondata'] ? json_decode($row['jsondata'], true) : array(); + if ($type == 1) { + $update['if_defeat'] = 2;//再战 + } else { + $def_time = date("Y-m-d H:i:s"); + $jsondata['defeat']['pass_time'] = $def_time; + $update['status'] = 3; + $update['if_defeat'] = 0; + $update['def_time'] = $def_time; + } + $update['jsondata'] = json_encode($jsondata, JSON_UNESCAPED_UNICODE); + $ret = $this->customers_model->update($update, ['id' => $id]); + if ($ret) { + $this->load->library('receiver/customers_entity'); + $uid = $this->session['uid']; + $uname = $this->session['uname']; + if ($type == 1) { + $this->customers_entity->add_log($id, $uid, $uname, '拒绝战败申请', 9); + } else { + //战败 + $admin_id = $row['admin_id'] ? $row['admin_id'] : $uid;//战败归属顾问的uid + $this->customers_entity->add_log($id, $admin_id, $uname, '客户战败', 7); + //更新客户已回访 + $this->customers_entity->add_log_visit($id, $uid, $uname, '', 0, 1); + } + throw new Exception('操作成功', API_CODE_SUCCESS); + } + throw new Exception('操作失败', ERR_PARAMS_ERROR); + } + + /** + * Notes:来源title + * Created on: 2022/3/11 15:53 + * Created by: dengbw + * @param $params + * @return string + */ + private function get_cfTitle($params) + { + $title = $params['cf_title'] ? $params['cf_title'] : ''; + if ($title == '自有资源' && $params['of_id']) {//自有资源 取线下来源 + $of_ary = $this->customers_model->offlineSources()[$params['of_id']]; + $title = $of_ary['name']; + $params['of2_id'] && $title .= '-' . $of_ary['list'][$params['of2_id']]; + } + return $title; + } + + /** + * Notes:显示电话格式 + * Created on: 2022/3/9 14:38 + * Created by: dengbw + * @param $params + * @return string + */ + private function get_mobile($params) + { + $mobile = $params['mobile']; + if (!$mobile) { + return ''; + } +// $group_id = $this->session['group_id']; +// if ($params['cf_title'] == '自有资源' && ($group_id == 2 || $group_id == 3)) {//2店长,3老板显示全部电话 +// return $mobile; +// } +// if ($params['type'] == 1) { +// $mobile = '****' . substr($mobile, -4); +// } else { +// $mobile = mobile_asterisk($mobile); +// } + + // 0522 add + if ($this->biz_id == 97) { + return $mobile; + } + + $biz = $this->get_biz(); + if ($params['of2_id'] == 37 && $params['of_id'] == 3 && $biz['type'] != 1) { //客户来源:网络推广-狸车分配 隐藏手机号 不是直营店 + $mobile = '****' . substr($mobile, -4); + } + return $mobile; + } + + /** + * Notes:判断分配客户权限 + * Created on: 2022/3/18 10:02 + * Created by: dengbw + * @return int + */ + private function get_allot() + { + $allot = 1; + $group_id = $this->session['group_id']; + if ($group_id == 1) {//销售不可分配用户 + $allot = 0; + } + return $allot; + } + + /** + * Notes:计划回访时间 + * Created on: 2022/6/6 14:13 + * Created by: dengbw + * @param $params + * @return string + */ + private function get_visit_time($params) + { + $today = date('Y-m-d');//今天 + $re = $this->mdCustomerVisitData->get(['c_id' => $params['c_id'], 'biz_id' => $params['biz_id'] + , 'sales_id' => $params['sales_id'], 't_day' => $today]); + $visit_time = ''; + if ($re) { + if ($re['pid']) {//有逾期id 找最初回访日期并统计次数 + $re_pid = $this->mdCustomerVisitData->get(['id' => $re['pid']]); + if ($re_pid) { + $visit_time = $re_pid['t_day']; + $count = $this->mdCustomerVisitData->count(['pid' => $re['pid']]); + $count && $visit_time = $visit_time . "(逾期{$count}次)"; + } + } else { + $visit_time = $re['t_day']; + } + } else { + $re = $this->mdCustomerVisitData->get(['c_id' => $params['c_id'], 'biz_id' => $params['biz_id'], + 'sales_id' => $params['sales_id'], 't_day>' => $today]); + $re && $visit_time = $re['t_day']; + } + return $visit_time; + } + + /** + * Notes:获取门店信息 + * Created on: 2022/6/30 15:09 + * Created by: dengbw + * @param string $params + * @return string + */ + private function get_biz($params = '') + { + if ($params) { + $re = $this->biz_model->get(['id' => $this->biz_id, 'status' => 1], $params); + $re = $re ? $re[$params] : ''; + } else { + $re = $this->biz_model->get(['id' => $this->biz_id, 'status' => 1]); + } + return $re; + } + +} diff --git a/api/controllers/wxapp/licheb/Sms.php b/api/controllers/wxapp/licheb/Sms.php index 8eaa886b..95144598 100644 --- a/api/controllers/wxapp/licheb/Sms.php +++ b/api/controllers/wxapp/licheb/Sms.php @@ -1,8 +1,5 @@ app_user_model->get(['mobile' => $mobile, 'status>' => -1]); - exit; if (!$user) { throw new Exception('用户不存在', API_CODE_FAIL); } + $mc = &load_cache(); $key = "licheb_login_code_" . $mobile; - if (!$code = $this->app_redis->get($key)) { + if (!$code = $mc->get($key)) { $this->load->helper('string'); $code = random_string('numeric', 6); - $this->app_redis->save($key, $code, 600); + $mc->save($key, $code, 600); } - send_sms($mobile, $code); + $content = "【{$this->smsSign}】" . "您的验证码为:{$code},请勿泄露于他们!"; + b2m_send_sms($mobile, $content); $msg = '发送成功'; throw new Exception($msg, API_CODE_SUCCESS); } @@ -68,7 +67,7 @@ class Sms extends Wxapp throw new Exception('该客户不可操作', ERR_PARAMS_ERROR); } $mobile = $row['mobile']; - $content = '【狸车】' . $content; + $content = "【{$this->smsSign}】" . $content; b2m_send_sms($mobile, $content); $this->load->library('receiver/customers_entity'); $this->customers_entity->add_log_visit($id, $uid, $this->session['uname'], $content, 1, 1); @@ -91,7 +90,7 @@ class Sms extends Wxapp throw new Exception('参数错误', ERR_PARAMS_ERROR); } $mobile = $row['mobile']; - $content = '【狸车】' . $content; + $content = "【{$this->smsSign}】" . $content; b2m_send_sms($mobile, $content); $this->load->library('receiver/customers_entity'); $this->customers_entity->add_log($row['id'], $uid, $this->session['uname'], $content, 1); diff --git a/api/controllers/wxapp/licheb/Statistics.php b/api/controllers/wxapp/licheb/Statistics.php new file mode 100644 index 00000000..28e024c3 --- /dev/null +++ b/api/controllers/wxapp/licheb/Statistics.php @@ -0,0 +1,776 @@ +load->model("biz/biz_model"); + $this->load->model('receiver/receiver_customers_model','customers_model'); +// $this->load->model('receiver/order/receiver_orders_model','orders_model'); +// $this->load->model('receiver/order/receiver_orders_v2_model', 'mdOrders'); +// $this->load->library('receiver/stats_entity'); + } + + protected function get(){ + + } + + //统计客户 + protected function get_cust(){ + $season = $this->input_param('season'); + $city_id = $this->input_param('city_id'); + !strlen($season) && $season = date('n')-1;//当前月份 + $month = $season+1; + $season_data = $this->months(); + $series = []; + $bizs = []; + $months_arr = []; + $months_arr[] = [ + 'cn' => $season_data[$season], + 's_time' => date("Y-{$month}-01 00:00:00"), + 'e_time' => date("Y-{$month}-t 23:59:59"), + ]; + $fileds = 'id,biz_name'; + $biz_id_arr = explode(',',$this->session['biz_id']); + if($this->session['biz_id'] && $biz_id_arr){ + $city_id && $o_where = ['city_id'=>$city_id]; + $bizs_lists = $this->biz_model->get_by_id_arr($biz_id_arr,$o_where,$fileds); + }else{ + $typeAry = $this->biz_model->type_ary(); + $type_ids = implode(',',array_keys($typeAry)); + $bizs_lists = $this->biz_model->select(['status'=>1,'city_id'=>$city_id,"type in ($type_ids)" => null],'id desc','','',$fileds); + } + if($bizs_lists){ + $bizs = array_column($bizs_lists,'biz_name'); + foreach($bizs_lists as $key=>$val){ + $count_data = []; + foreach($months_arr as $v2){ + $where = [ + 'biz_id' => $val['id'], + 'status>=' => 0, + 'c_time>=' => strtotime($v2['s_time']), + 'c_time<=' => strtotime($v2['e_time']), + 'brand_id!=' => 3, + ]; + $count_data[] = $this->customers_model->count($where); + } + $series[] = [ + 'name' => $val['biz_name'], + 'type' => 'bar', + 'data' => $count_data + ]; + } + } + $stat_data = [ + 'tooltip' => [ + 'trigger' => 'axis', + 'axisPointer' => ['type'=>'shadow'] + ], + 'legend' => [ + 'top' => 'bottom', + 'data'=> $bizs + ], + 'grid' => [ + 'top' => '8%', + 'left' => '2%', + 'right' => '5%', + 'bottom' => '12%', + 'containLabel' => true + ], + 'xAxis' => [ + 'type' => 'value', + 'boundaryGap' => [0, 0.01] + ], + 'yAxis' => [ + 'type' => 'category', + 'data' => array_column($months_arr,'cn') + ], + 'series' => $series + ]; + $data = [ + 'stat_data' => $stat_data, + 'season_data' => $season_data, + 'season' => $season + ]; + return $data; + } + + //统计订单 + protected function get_orders(){ + $season = $this->input_param('season'); + $city_id = $this->input_param('city_id'); + !strlen($season) && $season = ceil((date('n'))/3)-1;//当月是第几季度 + $season_data = $this->season_data($season+1); + $days = getMonth($season+1); + $series = []; + $bizs = []; + $months_arr = []; + foreach($days as $val){ + $months_arr[] = [ + 'cn' => date('n月',strtotime($val)), + 's_time' => date('Y-m-01 00:00:00',strtotime($val)), + 'e_time' => date('Y-m-t 23:59:59',strtotime($val)), + ]; + } + $fileds = 'id,biz_name'; + $biz_id_arr = explode(',',$this->session['biz_id']); + if($this->session['biz_id'] && $biz_id_arr){ + $city_id && $o_where = ['city_id'=>$city_id]; + $bizs_lists = $this->biz_model->get_by_id_arr($biz_id_arr,$o_where,$fileds); + }else{ + $typeAry = $this->biz_model->type_ary(); + $type_ids = implode(',',array_keys($typeAry)); + $bizs_lists = $this->biz_model->select(['status'=>1,'city_id'=>$city_id,"type in ($type_ids)" => null],'id desc','','',$fileds); + } + if($bizs_lists){ + $bizs = array_column($bizs_lists,'biz_name'); + foreach($bizs_lists as $key=>$val){ + $count_data = []; + foreach($months_arr as $v2){ + $where = [ + 'biz_id' => $val['id'], + 'status>=' => 0, + 'c_time>=' => strtotime($v2['s_time']), + 'c_time<=' => strtotime($v2['e_time']), + 'brand_id!=' => 3, + ]; + $count_data[] = $this->orders_model->count($where); + } + $series[] = [ + 'name' => $val['biz_name'], + 'type' => 'line', + 'stack' => '总量', + 'data' => $count_data, + 'smooth' => true + ]; + } + + } + $stat_data = [ + 'tooltip' => ['trigger' => 'axis'], + 'legend' => ['top'=>'bottom','data'=>$bizs], + 'grid' => [ + 'top' => '10%', + 'left' => '2%', + 'right' => '5%', + 'bottom' => '12%', + 'containLabel' => true + + ], + 'xAxis' => [ + 'type' => 'category', + 'boundaryGap' => false, + 'data' => array_column($months_arr,'cn') + ], + 'yAxis' => ['type'=>'value'], + 'series' => $series, + ]; + $data = [ + 'stat_data' => $stat_data, + 'season_data' => $season_data, + 'season' => $season + ]; + return $data; + } + + //数据分析页面客户数据 + protected function get_scust(){ + $day = $this->input_param('day'); + $month = $this->input_param('month'); + $biz_id = $this->input_param('biz_id'); + $admin_id = $this->input_param('admin_id'); + if(!$biz_id){ + throw new Exception('参数错误', ERR_PARAMS_ERROR); + } + if(!$day && $month){ + $day = date("Y-{$month}-01"); + } + !$day && $day = date('Y-m-d');//获取当天 + $status_list = [ + [ + 'title' => '订单客户', + 'icon' => 'icon-statistics-custom-1', + 'status' => 2 + ], + [ + 'title' => '到店客户', + 'icon' => 'icon-statistics-custom-2', + 'status' => 1 + ], + [ + 'title' => '未见客户', + 'icon' => 'icon-statistics-custom-3', + 'status' => 0 + ], + [ + 'title' => '未联潜客', + 'icon' => 'icon-statistics-custom-4', + 'status' => '' + ], + [ + 'title' =>'战败客户', + 'icon' => 'icon-statistics-custom-5', + 'status' => 3 + ], + ]; + foreach($status_list as $key => $val){ + $setValue = [ + 'title' => $val['title'], + 'icon' => $val['icon'], + ]; + $where = [ + 'biz_id' => $biz_id, + 'brand_id!=' => 3 + ]; + $admin_id && $where['admin_id'] = $admin_id; + if($day){ + $s_time = date('Y-m-01 00:00:00',strtotime($day)); + $e_time = date('Y-m-t 23:59:59',strtotime($day)); + $where['c_time>='] = strtotime($s_time); + $where['c_time<='] = strtotime($e_time); + } + if(strlen($val['status'])){ + $where['status'] = $val['status']; + $setValue['value'] = $this->customers_model->count($where); + }else{ + $where["cont_time = '0000-00-00 00:00:00'"] = null; + $setValue['value'] = $this->customers_model->count($where); + } + $custom[] = $setValue; + } + $months_arr = []; + for($i=2;$i>=0;$i--){ + $_time = date("Y-m-01",mktime(0, 0 , 0,date("m",strtotime($day))-$i,1,date("Y",strtotime($day)))); + $months_arr [] = [ + 'cn' => date('n月',strtotime($_time)), + 's_time' => date('Y-m-01 00:00:00',strtotime($_time)), + 'e_time' => date('Y-m-t 23:59:59',strtotime($_time)) + ]; + } + foreach($months_arr as $val){ + $where = [ + 'biz_id' => $biz_id, + 'status>=' => 0, + 'c_time>=' => strtotime($val['s_time']), + 'c_time<=' => strtotime($val['e_time']), + 'brand_id!=' => 3, + ]; + $count_data[] = $this->customers_model->count($where); + } + + //图标数据 + $stat_data = [ + 'tooltip' => [ + 'trigger' => 'axis', + 'axisPointer' => [ + 'type' => 'shadow' + ] + ], + 'grid' => [ + 'top' => '10%', + 'left' => '2%', + 'right' => '5%', + 'bottom' => '5%', + 'containLabel' => true + ], + 'xAxis' => [ + 'type' => 'value', + 'boundaryGap' => [0, 0.01] + ], + 'yAxis' => [ + 'type' => 'category', + 'data' => array_column($months_arr,'cn'), + ], + 'series' => [ + [ + 'type' => 'bar', + 'itemStyle' => [ + 'color' => '#2e3246', + 'borderRadius' => [0, 20, 20, 0], + ], + 'barWidth' => '15', + 'data' => $count_data, + 'label' => [ + 'show' => true, + 'position' => 'right', + 'formatter' => '{@[n]}', + 'valueAnimation' => true + ] + ] + ] + ]; + + $data = [ + 'custom' => $custom, + 'stat_data' => $stat_data, + ]; + return $data; + } + //数据分析页面订单数据 + protected function get_ocust(){ + $day = $this->input_param('day'); + $biz_id = $this->input_param('biz_id'); + $month = $this->input_param('month'); + $admin_id = $this->input_param('admin_id'); + if(!$biz_id){ + throw new Exception('参数错误', ERR_PARAMS_ERROR); + } + if(!$day && $month){ + $day = date("Y-{$month}-01"); + } + !$day && $day = date('Y-m-d');//获取当天 + + $status_list = [ + [ + 'title' => '合同签订', + 'icon' => 'icon-statistics-order-1', + 'status' => 0 + ], + [ + 'title' => '分期办理', + 'icon' => 'icon-statistics-order-2', + 'status' => 1 + ], + [ + 'title' => '车辆确认', + 'icon' => 'icon-statistics-order-3', + 'status' => 2 + ], + [ + 'title' => '申请开票', + 'icon' => 'icon-statistics-order-4', + 'status' => 3 + ], + [ + 'title' =>'代办服务', + 'icon' => 'icon-statistics-order-5', + 'status' => 4 + ], + [ + 'title' =>'交付确认', + 'icon' => 'icon-statistics-order-6', + 'status' => 5 + ], + [ + 'title' =>'完成交付', + 'icon' => 'icon-statistics-order-7', + 'status' => 6 + ], + ]; + foreach($status_list as $key => $val){ + $setValue = [ + 'title' => $val['title'], + 'icon' => $val['icon'], + ]; + $where = [ + 'status' => $val['status'], + 'biz_id' => $biz_id, + 'brand_id!=' => 3, + ]; + if($day){ + $s_time = date('Y-m-01 00:00:00',strtotime($day)); + $e_time = date('Y-m-t 23:59:59',strtotime($day)); + $where['c_time>='] = strtotime($s_time); + $where['c_time<='] = strtotime($e_time); + } + $admin_id && $where['admin_id'] = $admin_id; + $setValue['value'] = $this->orders_model->count($where); + $custom[] = $setValue; + } + + $months_arr = []; + for($i=2;$i>=0;$i--){ + $_time = date("Y-m-01",mktime(0, 0 , 0,date("m",strtotime($day))-$i,1,date("Y",strtotime($day)))); + $months_arr [] = [ + 'cn' => date('n月',strtotime($_time)), + 's_time' => date('Y-m-01 00:00:00',strtotime($_time)), + 'e_time' => date('Y-m-t 23:59:59',strtotime($_time)) + ]; + } + foreach($months_arr as $val){ + $where = [ + 'biz_id' => $biz_id, + 'status>=' => 0, + 'c_time>=' => strtotime($val['s_time']), + 'c_time<=' => strtotime($val['e_time']), + 'brand_id!=' => 3, + ]; + $count_data[] = $this->orders_model->count($where); + } + + $stat_data = [ + 'grid' => [ + 'top' => '15%', + 'left' => '2%', + 'right' => '5%', + 'bottom' => '5%', + 'containLabel' => true + ], + 'xAxis' =>[ + 'type' => 'category', + 'data' => array_column($months_arr,'cn'), + ], + 'yAxis' => [ + 'type' => 'value' + ], + 'series' => [ + [ + 'data' => $count_data, + 'type' => 'line', + 'smooth' => true + ] + ] + ]; + $data = [ + 'custom' => $custom, + 'stat_data' => $stat_data, + ]; + return $data; + } + //首页饼状图客户统计 + protected function get_hcust(){ + $biz_id = $this->input_param('biz_id'); + $group_id = $this->session['group_id']; + $uid = $this->session['uid']; + !$biz_id && $biz_id = intval($this->session['biz_id']); + if(!$biz_id){ + throw new Exception('参数错误', ERR_PARAMS_ERROR); + } + $status_list = $this->customers_model->get_status(); + unset($status_list[-1]); + $count_data = []; + foreach($status_list as $key => $val){ + $where = [ + 'biz_id' => $biz_id, + 'status' => $key + ]; + $group_id == 1 && $where['admin_id'] = $uid; + $group_id == 4 && $where['brand_id!='] = 3; //渠道经理过滤 + $count = $this->customers_model->count($where); + $count_data[] = [ + 'value' => $count, + 'name' => $val + ]; + } + //所有客户数据 + $where = [ + 'status>='=>0, + 'biz_id'=>$biz_id + ]; + $group_id == 1 && $where['admin_id'] = $uid; + $group_id == 4 && $where['brand_id!='] = 3; //渠道经理过滤 + $count = $this->customers_model->count($where); + $where = [ + 'status>='=>0, + 'biz_id'=>$biz_id, + 'is_top'=>1 + ]; + $group_id == 1 && $where['admin_id'] = $uid; + $group_id == 4 && $where['brand_id!='] = 3; //渠道经理过滤 + $top_count = $this->customers_model->count($where); //关注 + $where = [ + 'status>='=>0, + 'biz_id'=>$biz_id, + "cont_time = '0000-00-00 00:00:00'"=>null + ]; + $group_id == 1 && $where['admin_id'] = $uid; + $group_id == 4 && $where['brand_id!='] = 3; //渠道经理过滤 + $un_count = $this->customers_model->count($where);//未联系 + $stat_data = [ + 'tooltip' =>[ + 'trigger' => 'axis', + ], + 'legend' => [ + 'top' => 'bottom', + 'orient' => 'horizontal', + 'textStyle' =>[ + 'fontSize' => 9, + ] + ], + 'series' => [ + 'type' => 'pie', + 'top' => '0', + 'radius' => ['30%', '48%'], + 'data' => $count_data, + 'label' =>[ + 'formatter' => '\n{b|{b}}\n{c|{c}}\n{per|{d}%} ', + 'rich' => [ + 'b' =>[ + 'color' => '#4C5058', + 'fontSize' => 10, + 'lineHeight' => 15, + 'align' => 'left', + ], + 'b' =>[ + 'color' => '#4C5058', + 'fontSize' => 10, + 'lineHeight' => 15, + 'align' => 'left', + ], + 'per' => [ + 'color' => '#4C5058', + 'fontSize' => 10, + 'lineHeight' => 15, + 'align' => 'left', + ], + ] + ], + ] + ]; + $data = [ + 'stat_data' => $stat_data, + 'total' => $count, + 'cont_total' => $un_count, + 'top_total' => $top_count + ]; + return $data; + } + //首页柱状图订单统计 + protected function get_horder(){ + $biz_id = $this->input_param('biz_id'); + $group_id = $this->session['group_id']; + $uid = $this->session['uid']; + !$biz_id && $biz_id = intval($this->session['biz_id']); + if(!$biz_id){ + throw new Exception('参数错误', ERR_PARAMS_ERROR); + } + $status_list = $this->orders_model->get_status(); + unset($status_list[7]); + $count_data = []; + $total = 0; + foreach($status_list as $key => $val){ + $where = [ + 'biz_id' => $biz_id, + 'status' => $key + ]; + $group_id == 1 && $where['admin_id'] = $uid; + $group_id == 4 && $where['brand_id!='] = 3; //渠道经理过滤 + $count = $this->orders_model->count($where); + $total += $count; + $count_data[] = [ + 'value' => $count, + 'name' => $val + ]; + } + $stat_data = [ + 'tooltip' =>[ + 'trigger' => 'axis', + 'axisPointer' => [ + 'type' => 'shadow' + ] + ], + 'grid' =>[ + 'top' => '8%', + 'left' => '2%', + 'right' => '5%', + 'bottom' => '2%', + 'containLabel' => true + ], + 'xAxis' =>[ + 'type' => 'value', + 'boundaryGap' => [0, 0.01] + ], + 'yAxis' =>[ + 'type' => 'category', + 'data' => array_column($count_data,'name'), + ], + 'series' =>[ + 'type' => 'bar', + 'itemStyle' =>[ + 'color' => '#2e3246', + 'borderRadius' => [0, 20, 20, 0], + ], + 'barWidth' => '15', + 'data' => array_column($count_data,'value'), + 'label'=>[ + 'show' => true, + 'position' => 'right', + 'formatter' => '{@[n]}', + 'valueAnimation' => true + ] + ] + ]; + $data = [ + 'stat_data' => $stat_data, + 'total' => $total + ]; + return $data; + } + + /** + * 获取月份 + */ + private function months(){ + $months = ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月']; + return $months; + } + /** + * 获取季度 + * @param int $season 当前季度 + */ + private function season_data($season){ + $chiNum = ['一','二','三','四']; + if($season>4){ + return []; + } + for($i=0;$i<$season;$i++){ + $season_data[] = "第{$chiNum[$i]}季度"; + } + return $season_data; + } + + + protected function get_stats() + { + $s_time = $this->input_param('s_time'); + $e_time = $this->input_param('e_time'); + $city_id = intval($this->input_param('city_id')); + !$s_time && $s_time = date('Y-m-d'); + !$e_time && $e_time = date('Y-m-d'); + $c_time = ['s_time' => strtotime($s_time), 'e_time' => strtotime(date('Y-m-d 23:59:59', strtotime($e_time)))]; + $o_time = ['s_time' => $s_time . ' 00:00:00', 'e_time' => $e_time . ' 23:59:59']; + //客户 + $where = [ + 'status>=' => 0, + 'cs_biz_id!=' => -1, + 'c_time>=' => $c_time['s_time'], + 'c_time<=' => $c_time['e_time'], + "biz_id in (select id from lc_biz where city_id={$city_id} and status=1)" => null + ]; + $customers = $this->customers_model->count($where); + //进店 + $where = [ + 'a.type' => 4, + 'a.log' => '客户到店', + 'a.c_time>=' => $c_time['s_time'], + 'a.c_time<=' => $c_time['e_time'], + 'b.status>=' => 0, + 'b.cs_biz_id!=' => -1, + "b.biz_id in (select id from lc_biz where city_id={$city_id} and status=1)" => null + ]; + $intos = $this->customers_model->db->select('a.id') + ->from('lc_receiver_customer_oplogs as a') + ->join('lc_receiver_customers as b', "b.id=a.customer_id", 'left') + ->where($where) + ->count_all_results(); + //成交 + $where = [ + 'status>=' => 0, + 'order_time>=' => $o_time['s_time'], + 'order_time<=' => $o_time['e_time'], + "customer_id in ( + select id from lc_receiver_customers where status>=0 and cs_biz_id!=-1 and + biz_id in (select id from lc_biz where city_id={$city_id} and status=1) + )" => null + ]; + $orders = $this->mdOrders->count($where); + $where = [ + 'a.status>=' => 0, + 'a.bill_time>=' => $o_time['s_time'], + 'a.bill_time<=' => $o_time['e_time'], + 'a.status<>' => 2, + 'b.pid_status' => 3, + 'b.status in (1,2)' => null, + "a.customer_id in ( + select id from lc_receiver_customers where status>=0 and cs_biz_id!=-1 and + biz_id in (select id from lc_biz where city_id={$city_id} and status=1) + )" => null + ]; + $bill_orders = $this->customers_model->db->select('a.id,count(b.status) as total') + ->from('lc_receiver_orders_v2 as a') + ->join('lc_receiver_order_status as b', "b.o_id=a.id", 'left') + ->where($where)->group_by('b.o_id')->having('total=1') + ->count_all_results(); + $data['tabs'] = [ + ['title' => '全部客户', 'value_1' => $customers, 'url' => '/pages/dataAnalysis/detail/index?type=0'], + ['title' => '到店客户', 'value_1' => $intos, 'url' => '/pages/dataAnalysis/detail/index?type=1'], + ['title' => '订单数', 'value_1' => $orders, 'url' => '/pages/dataAnalysis/detail/index?type=2'], + ['title' => '开票数', 'value_1' => $bill_orders, 'url' => '/pages/dataAnalysis/detail/index?type=3'], + ]; + $orders_per = number_format_com($orders / $customers * 100, 1, ''); + $intos_per = number_format_com($intos / $customers * 100, 1, ''); + $data['funnel'] = [ + 'title' => '线索转化漏斗', + 'expected_data' => [ + ['name' => "成交数({$orders_per}%)", 'value' => 33.3], + ['name' => "到店数({$intos_per}%)", 'value' => 66.7], + ['name' => '客户数100%', 'value' => 100] + ], + 'actual_data' => [ + ['name' => '成交数', 'value' => $orders], + ['name' => '到店数', 'value' => $intos], + ['name' => '客户量', 'value' => $customers] + ] + ]; + $data['title'] = '数据看板'; + return $data; + } + + protected function get_stats_days() + { + $days = intval($this->input_param('days')); + $city_id = intval($this->input_param('city_id')); + !$days && $days = 7; + $customers = $orders = $xAxis = []; + for ($i = ($days - 1); $i >= 0; $i--) { + $s_time = date('Y-m-d', strtotime("-{$i} day")); + $c_time = ['s_time' => strtotime($s_time), 'e_time' => strtotime(date('Y-m-d 23:59:59', strtotime($s_time)))]; + $o_time = ['s_time' => $s_time . ' 00:00:00', 'e_time' => $s_time . ' 23:59:59']; + $xAxis[] = $days > 7 ? date('d', strtotime($s_time)) : date('n-d', strtotime($s_time)); + $where = [ + 'status>=' => 0, + 'cs_biz_id!=' => -1, + 'c_time>=' => $c_time['s_time'], + 'c_time<=' => $c_time['e_time'], + "biz_id in (select id from lc_biz where city_id={$city_id} and status=1)" => null + ]; + $customers[] = $this->customers_model->count($where); + $where = [ + 'status>=' => 0, + 'order_time>=' => $o_time['s_time'], + 'order_time<=' => $o_time['e_time'], + "customer_id in ( + select id from lc_receiver_customers where status>=0 and cs_biz_id!=-1 and + biz_id in (select id from lc_biz where city_id={$city_id} and status=1) + )" => null + ]; + $orders[] = $this->mdOrders->count($where); + } + $title = $days == 7 ? "近一周" : "近{$days}日"; + $data = [ + 'title' => "{$title}走势图", 'legend_data' => ["客户数", "订单数"], + 'xAxis' => $xAxis, + 'series' => [ + ['name' => "客户数", 'type' => 'line', 'smooth' => true, 'data' => $customers], + ['name' => "订单数", 'type' => 'line', 'smooth' => true, 'data' => $orders] + ] + ]; + return $data; + } + + protected function get_stats_customer() + { + $s_time = $this->input_param('s_time'); + $e_time = $this->input_param('e_time'); + $city_id = intval($this->input_param('city_id')); + $type = intval($this->input_param('type')); + switch ($type){ + case 1: //到店客户 + return $this->stats_entity->customers($s_time,$e_time,$city_id,$type); + case 2: //订单数 + return $this->stats_entity->orders($s_time,$e_time,$city_id);; + case 3: //开票数 + return $this->stats_entity->orders($s_time,$e_time,$city_id,$type); + default: //全部客户 + return $this->stats_entity->customers($s_time,$e_time,$city_id); + } + } +} diff --git a/api/controllers/wxapp/licheb/User.php b/api/controllers/wxapp/licheb/User.php index e17f9d71..097edbcd 100644 --- a/api/controllers/wxapp/licheb/User.php +++ b/api/controllers/wxapp/licheb/User.php @@ -1,302 +1,628 @@ -login_white = array('get_ukey');//登录白名单 - $this->majia_white = array('get_ukey', 'get');//超级管理员披上马甲可操作权限 - $this->check_status = array();//用户状态校验 - $this->check_mobile = array();//需要手机号 - $this->check_headimg = array();//授权微信信息 - - $this->load->model("biz/biz_model"); - $this->load->model('auto/auto_brand_model'); - $this->load->model('auto/auto_brand_biz_model'); - $this->load->model('items/items_model', 'mdItems'); - $this->load->model('items/items_oplogs_model', 'mdItemsOplogs'); - $this->load->model('sys/sys_city_model'); - $this->load->library('receiver/orders_v2_entity'); - } - - /** - * 获取ukey - * @return array - * @throws Exception - */ - protected function get_ukey() - { - $mobile_white = ['15359333655', '18350451617', '13860199666']; - $code = $this->input_param('code'); - $mobile = $this->input_param('mobile'); - $sms_code = $this->input_param('sms_code'); - - if (!$code || !$mobile || !$sms_code) { - throw new Exception('参数错误', API_CODE_INVILD_PARAM); - } - //判断验证码 - if (!in_array($mobile, $mobile_white) && $this->env != 'd') {//测试环境和测试号码 - $mc = &load_cache(); - $key = "licheb_login_code_" . $mobile; - $cache_code = $mc->get($key); - if ($sms_code != $cache_code) { - throw new Exception('验证码错误', API_CODE_FAIL); - } - } - $user = $this->app_user_model->get(['mobile' => $mobile, 'status>' => -1]); - if (!$user) { - throw new Exception('用户不存在', API_CODE_FAIL); - } - if (!$user['status']) { - throw new Exception('该账号已停用', API_CODE_FAIL); - } - //判断门店是否存在 - if ($user['group_id'] < 4) { - $biz_id = intval($user['biz_id']); - $biz = $this->biz_model->get(['id' => $biz_id, 'status' => 1]); - if (!$biz) { - throw new Exception('门店不存在', API_CODE_FAIL); - } - } - $session = $this->wx_session($code); - //print_r($session); - if (!$session['session_key']) { - throw new Exception('登录失败', API_CODE_FAIL); - } - - $uid = $user['id']; - if (!$user['openid']) { //未绑定微信 - $upd = [ - 'openid' => $session['openid'] - ]; - $session['unionid'] && $upd['unionid'] = $session['unionid']; - $ret = $this->app_user_model->update($upd, array('id' => $uid)); - if (!$ret) { - debug_log("[error]# code:{$code}; " . $this->app_user_model->db->last_query(), __FUNCTION__, $this->log_dir); - throw new Exception('授权用户信息失败', API_CODE_FAIL); - } - } - - $udata = array('uid' => $uid, 'session_key' => $session['session_key']); - $ukey = $this->refresh_login($udata); - - return array('ukey' => $ukey); - } - - /** - * Notes:用户信息 - * Created on: 2022/10/12 14:09 - * Created by: dengbw - * @return array - * @throws Exception - */ - protected function get() - { - $uid = $this->session['uid']; - $biz_id = $this->session['new_biz_id'] ? $this->session['new_biz_id'] : intval($this->session['biz_id']); - - $user = $this->app_user_model->get(array('id' => $uid)); - //获取所属店铺字段 - $biz = $this->biz_model->get(['id' => $biz_id, 'status' => 1], 'biz_name,type'); - //判断门店是否存在 - if (!$biz && $this->session['group_id'] < 4) { - $this->logout(); - throw new Exception('门店不存在', API_CODE_FAIL); - } - $group_arr = $this->app_user_model->get_group(); - - $group_name = $group_arr[$user['group_id']] ? $group_arr[$user['group_id']] : ''; - - //获取拨打电话 - $json = $this->session['jsondata'] ? json_decode($this->session['jsondata'], true) : array(); - $tel = $this->session['mobile']; - if ($json && $json['licheb'] && $json['licheb']['tel']) { - $tel = $json['licheb']['tel']; - } - - $data = array( - 'uid' => $uid, - 'uname' => $user['uname'], - 'mobile' => $user['mobile'], - 'headimg' => $user['headimg'], - 'tel' => $tel, - 'group_id' => $user['group_id'], - 'group_name' => $group_name, - 'biz_id' => $biz_id, - 'biz_name' => $biz['biz_name'] ? $biz['biz_name'] : '', - 'biz_type' => $biz['type'] ? $biz['type'] : '', - 'show_sa' => $biz_id == 70 ? true : false, - 'new_biz_id' => $this->session['new_biz_id'] ? $this->session['new_biz_id'] : '', - 'group_id_type' => $this->session['group_id_type'] ? $this->session['group_id_type'] : '', - ); - - # 用户可切换的组别 - $group_name1 = $group_arr[$user['group_id1']] ? $group_arr[$user['group_id1']] : ''; - $group_name_arr = array(); - if ($user['group_id'] && $user['group_id1']){ - # 渠道角色 再显示下城市名称,门店角色 再显示下门店名称 - $where_biz = ["id in ({$user['biz_id']}, {$user['biz_id1']})" => null]; - $map_biz = $this->biz_model->map('id', 'biz_name', $where_biz, '', 0, 0, 'id,biz_name'); - - $where_city = ["city_id in ({$user['city_id']}, {$user['city_id1']})" => null]; - $map_city = $this->sys_city_model->map('city_id', 'name', $where_city, '', 0, 0, 'city_id,name'); - - $group_name_ = '默认角色:'.$group_name; - if ($user['group_id'] == 4){ - $group_name_ = $user['city_id'] ? $group_name_."({$map_city[$user['city_id']]})" : $group_name_; - } - else{ - $group_name_ = $user['biz_id'] ? $group_name_."({$map_biz[$user['biz_id']]})" : $group_name_; - } - - $group_name1_ = '第二角色:'.$group_name1; - if ($user['group_id1'] == 4){ - $group_name1_ = $user['city_id1'] ? $group_name1_."({$map_city[$user['city_id1']]})" : $group_name1_; - } - else{ - $group_name1_ = $user['biz_id1'] ? $group_name1_."({$map_biz[$user['biz_id1']]})" : $group_name1_; - } - - $this->session['group_id_type'] && $group_name_arr[] = array('group_id'=>'group_id', "geoup_name"=>$group_name_); - !$this->session['group_id_type'] && $group_name_arr[] = array('group_id'=>'group_id1', "geoup_name"=>$group_name1_); - } - $data['group_name_arr'] = $group_name_arr; - if ($this->session['group_id_type']){ - $data['group_id'] = $user['group_id1']; - $data['group_name'] = $group_name1; - - if ($user['group_id1'] != 4){ - $biz_id1 = $user['biz_id1']; - $data['biz_id'] = $biz_id1; - $biz1 = $this->biz_model->get(['id' => $biz_id1, 'status' => 1], 'biz_name,type'); - $data['biz_name'] = $biz1['biz_name'] ? $biz1['biz_name'] : ''; - $data['biz_type'] = $biz1['type'] ? $biz1['type'] : ''; - } - } - - return $data; - } - - /** - * 更新用户信息 - * @return array - * @throws Exception - */ - protected function put() - { - $encrypted = $this->input_param('encryptedData'); - $iv = $this->input_param('iv'); - $intro = $this->input_param('intro'); - - //获取用户信息 - $uid = $this->session['uid']; - $user = $this->app_user_model->get(array('id' => $uid)); - - $upd = array(); - $mobile = ''; - //授权 - if (!is_null($encrypted)) { - if (!$encrypted || !$iv) { - throw new Exception('授权失败', API_CODE_INVILD_PARAM); - } - $wxdata = $this->wx_data($encrypted, $iv); - - if (!$wxdata) { - throw new Exception('授权失败', API_CODE_FAIL); - } - $openid = $wxdata['openId']; - $nickname = $wxdata['nickName']; - $sex = $wxdata['gender']; - $headimg = $wxdata['avatarUrl']; - $unionid = $wxdata['unionId']; - $mobile = $wxdata['phoneNumber']; - if (!$mobile && isset($wxdata['phoneNumber'])) { - throw new Exception('微信未绑定手机号', API_CODE_FAIL); - } - $mobile && !$user['mobile'] && $upd['mobile'] = $mobile; - $nickname && $upd['nickname'] = $nickname; - $headimg && $upd['headimg'] = $headimg; - if ($mobile) {//判断手机号是否重复 - if (!mobile_valid($mobile)) { - throw new Exception("请输入正确的手机号", API_CODE_FAIL); - } - $where = array('mobile' => $mobile, 'id <>' => $uid, "status<>" => -1); - $count = $this->app_user_model->count($where); - if ($count > 0) { - throw new Exception("{$mobile}已被绑", API_CODE_FAIL); - } - } - } else {//编辑其他信息 - $userInfo = $this->input_param('userInfo'); - $userInfo['nickName'] && $upd['nickname'] = $userInfo['nickName']; - $userInfo['avatarUrl'] && $upd['headimg'] = $userInfo['avatarUrl']; - if ($intro) { - if (mb_strlen($intro, 'utf8') > 20) { - throw new Exception('介绍自己20个字够啦', API_CODE_FAIL); - } - $upd['signature'] = $intro; - } - } - if ($upd) { - $ret = $this->app_user_model->update($upd, array('id' => $uid)); - if (!$ret) { - debug_log("[error]# " . $this->app_user_model->db->last_query(), __FUNCTION__, $this->log_dir); - throw new Exception('请求失败', API_CODE_FAIL); - } - } - $data = array( - 'mobile' => $mobile, - 'nickname' => $upd['nickname'] ? $upd['nickname'] : $user['nickname'], - 'headimg' => $upd['headimg'] ? $upd['headimg'] : $user['headimg'], - ); - return $data; - } - - - /** - * 切换角色:重新设置用户session里的group_id - */ - protected function put_resetgroupid() - { - $ukey = $this->input_param('ukey'); - $group_id_type = $this->input_param('group_id'); - if (!$group_id_type) { - throw new Exception('参数错误', API_CODE_INVILD_PARAM); - } - - $uid = $this->session['uid']; - $user = $this->app_user_model->get(array('id' => $uid)); - - if ($group_id_type == 'group_id1'){ - $this->session['group_id'] = $user['group_id1']; - $this->session['biz_id'] = $user['biz_id1']; - $this->session['city_id'] = $user['city_id1']; - - $this->session['group_id_type'] = $group_id_type; - $this->session['new_biz_id'] = intval($user['biz_id1']); - } - else{ - $this->session['group_id'] = $user['group_id']; - $this->session['biz_id'] = $user['biz_id']; - $this->session['city_id'] = $user['city_id']; - - $this->session['group_id_type'] = ''; - $this->session['new_biz_id'] = ''; - } - - $this->app_redis->save($this->redis_login . $ukey, json_encode($this->session, JSON_UNESCAPED_UNICODE), 30 * 24 * 3600); - throw new Exception('保存成功', API_CODE_SUCCESS); - } -} +login_white = array('get_ukey');//登录白名单 + $this->majia_white = array('get_ukey', 'get');//超级管理员披上马甲可操作权限 + $this->check_status = array();//用户状态校验 + $this->check_mobile = array();//需要手机号 + $this->check_headimg = array();//授权微信信息 + + $this->load->model("biz/biz_model"); + $this->load->model('auto/auto_brand_model'); +// $this->load->model('auto/auto_brand_biz_model'); +// $this->load->model('items/items_model', 'mdItems'); +// $this->load->model('items/items_oplogs_model', 'mdItemsOplogs'); + $this->load->model('sys/sys_city_model'); +// $this->load->library('receiver/orders_v2_entity'); + } + + /** + * 获取ukey + * @return array + * @throws Exception + */ + protected function get_ukey() + { + $mobile_white = ['18350451617']; + $code = $this->input_param('code'); + $mobile = $this->input_param('mobile'); + $sms_code = $this->input_param('sms_code'); + + if (!$code || !$mobile || !$sms_code) { + throw new Exception('参数错误', API_CODE_INVILD_PARAM); + } + //判断验证码 + if (!in_array($mobile, $mobile_white) && $this->env != 'd') {//测试环境和测试号码 + $key = "licheb_login_code_" . $mobile; + $cache_code = $this->app_redis->get($key); + if ($sms_code != $cache_code) { + throw new Exception('验证码错误', API_CODE_FAIL); + } + } + $user = $this->app_user_model->get(['mobile' => $mobile, 'status>' => -1]); + if (!$user) { + throw new Exception('用户不存在', API_CODE_FAIL); + } + if (!$user['status']) { + throw new Exception('该账号已停用', API_CODE_FAIL); + } + //判断门店是否存在 + if ($user['group_id'] < 4) { + $biz_id = intval($user['biz_id']); + $biz = $this->biz_model->get(['id' => $biz_id, 'status' => 1]); + if (!$biz) { + throw new Exception('门店不存在', API_CODE_FAIL); + } + } + $session = $this->wx_session($code); + if (!$session['session_key']) { + throw new Exception('登录失败', API_CODE_FAIL); + } + + $uid = $user['id']; + if (!$user['openid']) { //未绑定微信 + $upd = [ + 'openid' => $session['openid'] + ]; + $session['unionid'] && $upd['unionid'] = $session['unionid']; + $ret = $this->app_user_model->update($upd, array('id' => $uid)); + if (!$ret) { + debug_log("[error]# code:{$code}; " . $this->app_user_model->db->last_query(), __FUNCTION__, $this->log_dir); + throw new Exception('授权用户信息失败', API_CODE_FAIL); + } + } + + $udata = array('uid' => $uid, 'session_key' => $session['session_key']); + $ukey = $this->refresh_login($udata); + + return array('ukey' => $ukey); + } + + /** + * Notes:用户信息 + * Created on: 2022/10/12 14:09 + * Created by: dengbw + * @return array + * @throws Exception + */ + protected function get() + { + $uid = $this->session['uid']; + $biz_id = $this->session['new_biz_id'] ? $this->session['new_biz_id'] : intval($this->session['biz_id']); + + $user = $this->app_user_model->get(array('id' => $uid)); + //获取所属店铺字段 + $biz = $this->biz_model->get(['id' => $biz_id, 'status' => 1], 'biz_name,type'); + //判断门店是否存在 + if (!$biz && $this->session['group_id'] < 4) { + $this->logout(); + throw new Exception('门店不存在', API_CODE_FAIL); + } + $group_arr = $this->app_user_model->get_group(); + + $group_name = $group_arr[$user['group_id']] ? $group_arr[$user['group_id']] : ''; + + //获取拨打电话 + $json = $this->session['jsondata'] ? json_decode($this->session['jsondata'], true) : array(); + $tel = $this->session['mobile']; + if ($json && $json['licheb'] && $json['licheb']['tel']) { + $tel = $json['licheb']['tel']; + } + + $data = array( + 'uid' => $uid, + 'uname' => $user['uname'], + 'mobile' => $user['mobile'], + 'headimg' => $user['headimg'], + 'tel' => $tel, + 'group_id' => $user['group_id'], + 'group_name' => $group_name, + 'biz_id' => $biz_id, + 'biz_name' => $biz['biz_name'] ? $biz['biz_name'] : '', + 'biz_type' => $biz['type'] ? $biz['type'] : '', + 'show_sa' => $biz_id == 70 ? true : false, + 'new_biz_id' => $this->session['new_biz_id'] ? $this->session['new_biz_id'] : '', + 'group_id_type' => $this->session['group_id_type'] ? $this->session['group_id_type'] : '', + ); + + # 用户可切换的组别 + $group_name1 = $group_arr[$user['group_id1']] ? $group_arr[$user['group_id1']] : ''; + $group_name_arr = array(); + if ($user['group_id'] && $user['group_id1']) { + # 渠道角色 再显示下城市名称,门店角色 再显示下门店名称 + $where_biz = ["id in ({$user['biz_id']}, {$user['biz_id1']})" => null]; + $map_biz = $this->biz_model->map('id', 'biz_name', $where_biz, '', 0, 0, 'id,biz_name'); + + $where_city = ["city_id in ({$user['city_id']}, {$user['city_id1']})" => null]; + $map_city = $this->sys_city_model->map('city_id', 'name', $where_city, '', 0, 0, 'city_id,name'); + + $group_name_ = '默认角色:' . $group_name; + if ($user['group_id'] == 4) { + $group_name_ = $user['city_id'] ? $group_name_ . "({$map_city[$user['city_id']]})" : $group_name_; + } else { + $group_name_ = $user['biz_id'] ? $group_name_ . "({$map_biz[$user['biz_id']]})" : $group_name_; + } + + $group_name1_ = '第二角色:' . $group_name1; + if ($user['group_id1'] == 4) { + $group_name1_ = $user['city_id1'] ? $group_name1_ . "({$map_city[$user['city_id1']]})" : $group_name1_; + } else { + $group_name1_ = $user['biz_id1'] ? $group_name1_ . "({$map_biz[$user['biz_id1']]})" : $group_name1_; + } + + $this->session['group_id_type'] && $group_name_arr[] = array('group_id' => 'group_id', "geoup_name" => $group_name_); + !$this->session['group_id_type'] && $group_name_arr[] = array('group_id' => 'group_id1', "geoup_name" => $group_name1_); + } + $data['group_name_arr'] = $group_name_arr; + if ($this->session['group_id_type']) { + $data['group_id'] = $user['group_id1']; + $data['group_name'] = $group_name1; + + if ($user['group_id1'] != 4) { + $biz_id1 = $user['biz_id1']; + $data['biz_id'] = $biz_id1; + $biz1 = $this->biz_model->get(['id' => $biz_id1, 'status' => 1], 'biz_name,type'); + $data['biz_name'] = $biz1['biz_name'] ? $biz1['biz_name'] : ''; + $data['biz_type'] = $biz1['type'] ? $biz1['type'] : ''; + } + } + + return $data; + } + + /** + * 更新用户信息 + * @return array + * @throws Exception + */ + protected function put() + { + $encrypted = $this->input_param('encryptedData'); + $iv = $this->input_param('iv'); + $intro = $this->input_param('intro'); + + //获取用户信息 + $uid = $this->session['uid']; + $user = $this->app_user_model->get(array('id' => $uid)); + + $upd = array(); + $mobile = ''; + //授权 + if (!is_null($encrypted)) { + if (!$encrypted || !$iv) { + throw new Exception('授权失败', API_CODE_INVILD_PARAM); + } + $wxdata = $this->wx_data($encrypted, $iv); + + if (!$wxdata) { + throw new Exception('授权失败', API_CODE_FAIL); + } + $openid = $wxdata['openId']; + $nickname = $wxdata['nickName']; + $sex = $wxdata['gender']; + $headimg = $wxdata['avatarUrl']; + $unionid = $wxdata['unionId']; + $mobile = $wxdata['phoneNumber']; + if (!$mobile && isset($wxdata['phoneNumber'])) { + throw new Exception('微信未绑定手机号', API_CODE_FAIL); + } + $mobile && !$user['mobile'] && $upd['mobile'] = $mobile; + $nickname && $upd['nickname'] = $nickname; + $headimg && $upd['headimg'] = $headimg; + if ($mobile) {//判断手机号是否重复 + if (!mobile_valid($mobile)) { + throw new Exception("请输入正确的手机号", API_CODE_FAIL); + } + $where = array('mobile' => $mobile, 'id <>' => $uid, "status<>" => -1); + $count = $this->app_user_model->count($where); + if ($count > 0) { + throw new Exception("{$mobile}已被绑", API_CODE_FAIL); + } + } + } else {//编辑其他信息 + $userInfo = $this->input_param('userInfo'); + $userInfo['nickName'] && $upd['nickname'] = $userInfo['nickName']; + $userInfo['avatarUrl'] && $upd['headimg'] = $userInfo['avatarUrl']; + if ($intro) { + if (mb_strlen($intro, 'utf8') > 20) { + throw new Exception('介绍自己20个字够啦', API_CODE_FAIL); + } + $upd['signature'] = $intro; + } + } + if ($upd) { + $ret = $this->app_user_model->update($upd, array('id' => $uid)); + if (!$ret) { + debug_log("[error]# " . $this->app_user_model->db->last_query(), __FUNCTION__, $this->log_dir); + throw new Exception('请求失败', API_CODE_FAIL); + } + } + $data = array( + 'mobile' => $mobile, + 'nickname' => $upd['nickname'] ? $upd['nickname'] : $user['nickname'], + 'headimg' => $upd['headimg'] ? $upd['headimg'] : $user['headimg'], + ); + return $data; + } + + /** + * 统计数据 + */ + protected function get_cal() + { + $uid = $this->session['uid']; + $biz_id = $this->session['new_biz_id'] ? $this->session['new_biz_id'] : intval($this->session['biz_id']); + $group_id = $this->session['group_id']; + $this->load->model('receiver/receiver_customers_model', 'customers_model'); +// $this->load->model('receiver/order/receiver_orders_model', 'orders_model'); +// $this->load->model('receiver/order/receiver_orders_v2_model'); +// $this->load->model('receiver/order/receiver_order_signs_model', 'order_signs_model'); + $this->load->model('receiver/receiver_customers_visit_data_model', 'mdCustomerVisitData'); + $where = ['status>' => -1, 'is_top' => 1, 'biz_id' => $biz_id, 'cs_biz_id<>' => -1, 'status!=' => 2]; + $group_id == 1 && $where['admin_id'] = $uid; + $group_id == 4 && $where['brand_id!='] = 3; //渠道经理过滤 + $gz_count = $this->customers_model->count($where); + $where = ['status' => 0, 'biz_id' => $biz_id]; + $group_id == 1 && $where['admin_id'] = $uid; + $group_id == 4 && $where['brand_id!='] = 3; //渠道经理过滤 + $sign_count = 0; + $where = ['status' => 1, 'biz_id' => $biz_id]; + $group_id == 1 && $where['admin_id'] = $uid; + $group_id == 4 && $where['brand_id!='] = 3; //渠道经理过滤 + $loan_count = 0; + //客户代办事项 + if ($group_id == 1) { + $customer_op_list = []; + } else { + //未派单客户 + $where = ['admin_id' => 0, 'biz_id' => $biz_id, 'cs_biz_id<>' => -1, 'status>=' => 0]; + if ($group_id == 4 && $biz_id != 1) { + $where['brand_id!='] = 3; //渠道经理过滤 + } + $unuse_count = $this->customers_model->count($where); + $defeat_count = $this->customers_model->count(['biz_id' => $biz_id, 'cs_biz_id<>' => -1, 'if_defeat' => 1, 'status>' => -1]); + $customer_op_list = [ + ['title' => '待分配客户(人)', 'icon' => 'icon-daifenpei', 'total' => $unuse_count, 'page' => '/pages/customer/allot/index'], + ['title' => '战败申请(人)', 'icon' => 'icon-statistics-custom-5', 'total' => $defeat_count, 'page' => '/pages/customer/optDefeat/index'], + ]; + } + $where = ['status>=' => 0, 'payway' => 0, 'brand_id>' => 0, 'biz_id' => $biz_id, 'status!=' => 2,]; + $group_id == 1 && $where['sale_id'] = $uid; + $group_id == 4 && $where['brand_id!='] = 3; //渠道经理过滤 + $fq_total = 0; + $where = ['status>=' => 0, + 'brand_id>' => 0, 'biz_id' => $biz_id, 'status!=' => 2, + 'id not in (select o_id from lc_receiver_order_status where pid_status=2 and status=1)' => null]; + $group_id == 1 && $where['sale_id'] = $uid; + $group_id == 4 && $where['brand_id!='] = 3; //渠道经理过滤 + $pc_total = 0; + $where = [ + 'status>=' => 0, + 'brand_id>' => 0, 'biz_id' => $biz_id, 'status!=' => 2, + 'id not in (select o_id from lc_receiver_order_status where pid_status=3 and status=1)' => null, + 'id in (select o_id from lc_receiver_order_status where pid_status=0 and status=2)' => null]; + $group_id == 1 && $where['sale_id'] = $uid; + $group_id == 4 && $where['brand_id!='] = 3; //渠道经理过滤 + $kp_total = 0; + $where = [ + 'status>=' => 0, + 'brand_id>' => 0, 'biz_id' => $biz_id, 'status!=' => 2, + 'id in (select o_id from lc_receiver_order_status where pid_status=3 and status=1)' => null, + 'id not in (select o_id from lc_receiver_order_status where pid_status=4 and status=2)' => null + ]; + $group_id == 1 && $where['sale_id'] = $uid; + $group_id == 4 && $where['brand_id!='] = 3; //渠道经理过滤 + $ck_total = 0; + $deallist = [ + ['title' => '分期办理 ', 'icon' => 'icon-banfenqi', 'total' => $fq_total, 'page' => '/pages/order/filterList/index2?type=fq&title=分期办理'], + ['title' => '车辆匹配', 'icon' => 'icon-cheliangfenpei', 'total' => $pc_total, 'page' => '/pages/order/filterList/index2?type=pc&title=车辆分配'], + ['title' => '发票开具', 'icon' => 'icon-kaipiao1', 'total' => $kp_total, 'page' => '/pages/order/filterList/index2?type=kp&title=发票开具'], + ['title' => '交付确认', 'icon' => 'icon-jiaofu', 'total' => $ck_total, 'page' => '/pages/order/filterList/index2?type=jf&title=交付确认'], + ]; + $where_v = ['a.biz_id' => $biz_id, 'a.cs_biz_id<>' => -1, 'a.status in(0,1)' => null, 'b.t_day' => date('Y-m-d')]; + $where_c = ['biz_id' => $biz_id, 'cs_biz_id<>' => -1, 'status in(0,1)' => null]; + $group_id == 4 && $where_c['brand_id!='] = 3; + if ($group_id == 1) { + $where_v['b.sales_id'] = $uid; + $where_c['admin_id'] = $uid; + } + $h_num = $this->customers_model->count(array_merge($where_c, ['level' => 'H'])); + $h_num_1 = $this->mdCustomerVisitData->count_visit(array_merge($where_v, ['a.level' => 'H', 'b.status<>' => 2])); + $h_num_2 = $this->mdCustomerVisitData->count_visit(array_merge($where_v, ['a.level' => 'H', 'b.status' => 2])); + $a_num = $this->customers_model->count(array_merge($where_c, ['level' => 'A'])); + $a_num_1 = $this->mdCustomerVisitData->count_visit(array_merge($where_v, ['a.level' => 'A', 'b.status<>' => 2])); + $a_num_2 = $this->mdCustomerVisitData->count_visit(array_merge($where_v, ['a.level' => 'A', 'b.status' => 2])); + $b_num = $this->customers_model->count(array_merge($where_c, ['level' => 'B'])); + $b_num_1 = $this->mdCustomerVisitData->count_visit(array_merge($where_v, ['a.level' => 'B', 'b.status<>' => 2])); + $b_num_2 = $this->mdCustomerVisitData->count_visit(array_merge($where_v, ['a.level' => 'B', 'b.status' => 2])); + $c_num = $this->customers_model->count(array_merge($where_c, ['level' => 'C'])); + $c_num_1 = $this->mdCustomerVisitData->count_visit(array_merge($where_v, ['a.level' => 'C', 'b.status<>' => 2])); + $c_num_2 = $this->mdCustomerVisitData->count_visit(array_merge($where_v, ['a.level' => 'C', 'b.status' => 2])); + $levelSt = [ + ['title' => 'H级客户', 'list' => [['title' => '总数 >', 'num' => $h_num, 'url' => '/pages/customer/filterList/index?level=H&status_tp=1&title=H级客户'] + , ['title' => '今日需跟进 >', 'num' => $h_num_1, 'url' => '/pages/customer/filterList/index?level=H&status=1&visit=1&title=H级今日需跟进'] + , ['title' => '今日已跟进 >', 'num' => $h_num_2, 'url' => '/pages/customer/filterList/index?level=H&status=2&visit=1&title=H级今日已跟进']]], + ['title' => 'A级客户', 'list' => [['title' => '总数 >', 'num' => $a_num, 'url' => '/pages/customer/filterList/index?level=A&status_tp=1&title=A级客户'] + , ['title' => '今日需跟进 >', 'num' => $a_num_1, 'url' => '/pages/customer/filterList/index?level=A&status=1&visit=1&title=A级今日需跟进'] + , ['title' => '今日已跟进 >', 'num' => $a_num_2, 'url' => '/pages/customer/filterList/index?level=A&status=2&visit=1&title=A级今日已跟进']]], + ['title' => 'B级客户', 'list' => [['title' => '总数 >', 'num' => $b_num, 'url' => '/pages/customer/filterList/index?level=B&status_tp=1&title=B级客户'] + , ['title' => '今日需跟进 >', 'num' => $b_num_1, 'url' => '/pages/customer/filterList/index?level=B&status=1&visit=1&title=B级今日需跟进'] + , ['title' => '今日已跟进 >', 'num' => $b_num_2, 'url' => '/pages/customer/filterList/index?level=B&status=2&visit=1&title=B级今日已跟进']]], + ['title' => 'C级客户', 'list' => [['title' => '总数 >', 'num' => $c_num, 'url' => '/pages/customer/filterList/index?level=C&status_tp=1&title=C级客户'] + , ['title' => '今日需跟进 >', 'num' => $c_num_1, 'url' => '/pages/customer/filterList/index?level=C&status=1&visit=1&title=C级今日需跟进'] + , ['title' => '今日已跟进 >', 'num' => $c_num_2, 'url' => '/pages/customer/filterList/index?level=C&status=2&visit=1&title=C级今日已跟进']]], + ]; + $wl_num = $this->mdCustomerVisitData->count_visit(array_merge($where_v, ['b.status<>' => 2])); + //数据统计 + $str_uids = $str_userids = ''; + if ($group_id == 1) { + $str_uids = $uid; + $str_userids = $this->session['userid']; + } else { + $res_user = $this->app_user_model->select(['biz_id' => $biz_id, 'group_id <' => 4, 'status>=' => 0], 'id asc', 0, 0, 'id,userid'); + foreach ($res_user as $k => $v) { + $str_uids = $str_uids ? $str_uids . ',' . $v['id'] : $v['id']; + $v['userid'] && $str_userids = $str_userids ? $str_userids . "','" . $v['userid'] : $v['userid']; + } + } + !$str_uids && $str_uids = '-1'; + !$str_userids && $str_userids = '-1'; + $this->load->model('receiver/receiver_customer_oplogs_model', 'mdCustomerOpLogs'); + $s_today = date('Y-m-d') . ' 00:00:00'; + $e_today = date('Y-m-d') . ' 23:59:59'; + $s_month = date('Y-m-01', strtotime(date("Y-m-d"))) . ' 00:00:00'; + $e_month = date('Y-m-d', strtotime("$s_month +1 month -1 day")) . ' 23:59:59'; + //线索 + $where_today_xs = ['biz_id' => $biz_id, 'cs_biz_id<>' => -1, 'status>=' => 0, 'c_time>=' => strtotime($s_today), 'c_time<=' => strtotime($e_today)]; + $where_month_xs = ['biz_id' => $biz_id, 'cs_biz_id<>' => -1, 'status>=' => 0, 'c_time>=' => strtotime($s_month), 'c_time<=' => strtotime($e_month)]; + //企微 + $where_today_qy = ['change_type' => 'add_external_contact', 'c_time>=' => strtotime($s_today), 'c_time<=' => strtotime($e_today)]; + $where_month_qy = ['change_type' => 'add_external_contact', 'c_time>=' => strtotime($s_month), 'c_time<=' => strtotime($e_month)]; + //到店 + $where_today_dd = ['biz_id' => $biz_id, 'status>=' => 0, 'cs_biz_id<>' => -1, + "id in(select customer_id from lc_receiver_customer_oplogs where type=4 and uid in({$str_uids}) and c_time>=" . strtotime($s_today) . " and c_time<=" . strtotime($e_today) . ")" => null]; + $where_month_dd = ['biz_id' => $biz_id, 'status>=' => 0, 'cs_biz_id<>' => -1, + "id in(select customer_id from lc_receiver_customer_oplogs where type=4 and uid in({$str_uids}) and c_time>=" . strtotime($s_month) . " and c_time<=" . strtotime($e_month) . ")" => null]; + //订单 + $where_today_order = ['status>=' => 0, 'order_time>=' => $s_today, 'order_time<=' => $e_today]; + $where_month_order = ['status>=' => 0, 'order_time>=' => $s_month, 'order_time<=' => $e_month]; + //战败 + $where_today_defeat = ['biz_id' => $biz_id, 'status>=' => 0, 'cs_biz_id<>' => -1, + "id in(select customer_id from lc_receiver_customer_oplogs where type=7 and uid in({$str_uids}) and c_time>=" . strtotime($s_today) . " and c_time<=" . strtotime($e_today) . ")" => null]; + $where_month_defeat = ['biz_id' => $biz_id, 'status>=' => 0, 'cs_biz_id<>' => -1, + "id in(select customer_id from lc_receiver_customer_oplogs where type=7 and uid in({$str_uids}) and c_time>=" . strtotime($s_month) . " and c_time<=" . strtotime($e_month) . ")" => null]; + //退订 + $where_today_refund = ['status' => 2, 'refund_time>=' => $s_today, 'refund_time<=' => $e_today]; + $where_month_refund = ['status' => 2, 'refund_time>=' => $s_month, 'refund_time<=' => $e_month]; + if ($group_id == 1) { + $where_today_xs['admin_id'] = $uid; + $where_month_xs['admin_id'] = $uid; + $where_today_order['admin_id'] = $uid; + $where_month_order['admin_id'] = $uid; + $where_today_refund['admin_id'] = $uid; + $where_month_refund['admin_id'] = $uid; + } else if ($group_id == 2 || $group_id == 3) {//店长/老板 + $where_today_order["(biz_id = {$biz_id} OR admin_id = {$uid})"] = null; + $where_month_order["(biz_id = {$biz_id} OR admin_id = {$uid})"] = null; + $where_today_refund["(biz_id = {$biz_id} OR admin_id = {$uid})"] = null; + $where_month_refund["(biz_id = {$biz_id} OR admin_id = {$uid})"] = null; + } else if ($group_id == 4) { + $where_today_order['biz_id'] = $biz_id; + $where_month_order['biz_id'] = $biz_id; + $where_today_refund['biz_id'] = $biz_id; + $where_month_refund['biz_id'] = $biz_id; + if ($biz_id != 1) {//渠道经理过滤 + $where_today_order['brand_id<>'] = 3; + $where_month_order['brand_id<>'] = 3; + $where_today_refund['brand_id<>'] = 3; + $where_month_refund['brand_id<>'] = 3; + } + } + $today_qy = $month_qy = 0; + if ($str_userids) { + $where_today_qy["userid in('{$str_userids}')"] = null; + $where_month_qy["userid in('{$str_userids}')"] = null; + $re_biz = $this->biz_model->get(['id' => $biz_id]); + if ($re_biz['type'] == 5) {//异业店 + $this->load->model('app/app_different_qy_log_model', 'mdDifferentQyLog'); + $today_qy = $this->mdDifferentQyLog->count($where_today_qy, 'distinct(external_userid)'); + $month_qy = $this->mdDifferentQyLog->count($where_month_qy, 'distinct(external_userid)'); + } else { + $today_qy = 0; + $month_qy = 0; + } + } + $statistics = [ + ['today' => ['title' => '今日', 'value' => $this->customers_model->count($where_today_xs), 'url' => '/pages/customer/filterList/index?status=3&visit=3&title=线索'] + , 'month' => ['title' => '本月线索', 'value' => $this->customers_model->count($where_month_xs)]], + ['today' => ['title' => '今日', 'value' => $today_qy, 'url' => '/pages/customer/filterList/index?status=4&visit=4&title=企v'] + , 'month' => ['title' => '本月企v', 'value' => $month_qy]], + ['today' => ['title' => '今日', 'value' => $this->customers_model->count($where_today_dd), 'url' => '/pages/customer/filterList/index?status=5&visit=5&title=到店'] + , 'month' => ['title' => '本月到店', 'value' => $this->customers_model->count($where_month_dd)]], + ['today' => ['title' => '今日', 'value' => 0, 'url' => '/pages/order/filterList/index2?status=6&visit=6&title=订单'] + , 'month' => ['title' => '本月订单', 'value' => 0]], + ['today' => ['title' => '今日', 'value' => $this->customers_model->count($where_today_defeat), 'url' => '/pages/customer/filterList/index?status=7&visit=7&title=战败'] + , 'month' => ['title' => '本月战败', 'value' => $this->customers_model->count($where_month_defeat)]], + ['today' => ['title' => '今日', 'value' => 0, 'url' => '/pages/order/filterList/index2?status=8&visit=8&title=退订'] + , 'month' => ['title' => '本月退订', 'value' => 0]] + ]; + $data = [ + 'wl_count' => ['title' => '待跟进客户(人)', 'num' => $wl_num, 'url' => '/pages/customer/filterList/index?status=1&visit=1&title=待跟进客户'], + 'gz_count' => ['title' => '特别关注客户(人)', 'num' => $gz_count, 'url' => '/pages/customer/filterList/index?istop=1&title=特别关注客户'], + 'sign_count' => $sign_count, + 'loan_count' => $loan_count, + 'deallist' => $deallist, + 'customer_op_list' => $customer_op_list, + 'levelSt' => $levelSt, + 'where_today_qy' => $where_today_qy, + 'statistics' => $statistics, + 'str_uids' => $str_uids + ]; + return $data; + } + + /** + * 更新联系手机号 + * @return array + * @throws Hd_Exception + */ + protected function put_tel() + { + $tel = $this->input_param('tel'); + if (!mobile_valid($tel)) { + throw new Hd_Exception('确认一下手机号是否正确', API_CODE_INVILD_PARAM); + } + + $uid = $this->session['uid']; + + $user = $this->app_user_model->get(array('id' => $uid)); + $json = $user['jsondata'] ? json_decode($user['jsondata'], true) : array(); + $json['licheb']['tel'] = $tel; + $upd = array('jsondata' => json_encode($json, JSON_UNESCAPED_UNICODE)); + $ret = $this->app_user_model->update($upd, array('id' => $uid)); + if (!$ret) { + throw new Hd_Exception('更新失败', API_CODE_FAIL); + } + + $data = array('tel' => $tel); + + return $data; + } + + /** + * 获取门店信息 + * @return array + */ + protected function get_bizs() + { + $city_id = $this->input_param('city_id'); + $lists = []; + + $biz_id_arr = explode(',', $this->session['biz_id']); + $fileds = 'id,biz_name'; + if ($this->session['biz_id'] && $biz_id_arr) { + $city_id && $o_where = ['city_id' => $city_id, 'type<>' => 4]; + $bizs = $this->biz_model->get_by_id_arr($biz_id_arr, $o_where, $fileds); + } else { + $typeAry = $this->biz_model->type_ary(); + $type_ids = implode(',', array_keys($typeAry)); + $bizs = $this->biz_model->select(['status' => 1, 'city_id' => $city_id, "type in ($type_ids)" => null, 'type<>' => 4], 'id desc', '', '', $fileds); + } + if ($bizs) { + foreach ($bizs as $key => $val) { + $auto_brands = []; + $lists[] = [ + 'id' => $val['id'], + 'name' => $val['biz_name'], + 'auto_brands' => $auto_brands + ]; + } + } + + $data = [ + 'list' => $lists, + ]; + return $data; + } + + //获取门店管理员 + protected function get_admins() + { + $biz_id = $this->input_param('biz_id'); + $page = $this->input_param('page'); + $size = $this->input_param('size'); + + !$page && $page = 1; + !$size && $size = 10; + if (!$biz_id) { + $biz_id = $this->session['new_biz_id'] ? $this->session['new_biz_id'] : intval($this->session['biz_id']); + } + $where = [ + 'status' => 1, + 'biz_id' => $biz_id + ]; + $lists = []; + $count = $this->app_user_model->count($where); + if ($count) { + $rows = $this->app_user_model->select($where, 'id desc', $page, $size, 'id,uname'); + $lists = $rows; + } + $tabs = $bizs = []; + $re_biz = $this->biz_model->get(['id' => $biz_id, 'status' => 1]); + if ($re_biz['type'] == 1) {//品牌店 + $tabs = [['id' => 1, 'name' => '本店'], ['id' => 2, 'name' => '其它门店']]; + $bizs = $this->biz_model->select(['type' => 1, 'status' => 1], 'id desc', 0, 0, 'id, biz_name as name'); + } + $data = [ + 'list' => $lists, + 'total' => $count, + 'tabs' => $tabs, + 'bizs' => $bizs, + ]; + return $data; + } + + /** + * 重新设置用户session里的biz_id + */ + protected function put_resetbiz() + { + $ukey = $this->input_param('ukey'); + $biz_id = $this->input_param('biz_id'); + if (!$biz_id) { + throw new Hd_Exception('参数错误', API_CODE_INVILD_PARAM); + } + $this->session['new_biz_id'] = $biz_id; + $this->app_redis->save($this->redis_login . $ukey, json_encode($this->session, JSON_UNESCAPED_UNICODE), 30 * 24 * 3600); + throw new Exception('保存成功', API_CODE_SUCCESS); + } + + /** + * 切换角色:重新设置用户session里的group_id + */ + protected function put_resetgroupid() + { + $ukey = $this->input_param('ukey'); + $group_id_type = $this->input_param('group_id'); + if (!$group_id_type) { + throw new Exception('参数错误', API_CODE_INVILD_PARAM); + } + + $uid = $this->session['uid']; + $user = $this->app_user_model->get(array('id' => $uid)); + + if ($group_id_type == 'group_id1') { + $this->session['group_id'] = $user['group_id1']; + $this->session['biz_id'] = $user['biz_id1']; + $this->session['city_id'] = $user['city_id1']; + + $this->session['group_id_type'] = $group_id_type; + $this->session['new_biz_id'] = intval($user['biz_id1']); + } else { + $this->session['group_id'] = $user['group_id']; + $this->session['biz_id'] = $user['biz_id']; + $this->session['city_id'] = $user['city_id']; + + $this->session['group_id_type'] = ''; + $this->session['new_biz_id'] = ''; + } + + $this->app_redis->save($this->redis_login . $ukey, json_encode($this->session, JSON_UNESCAPED_UNICODE), 30 * 24 * 3600); + throw new Exception('保存成功', API_CODE_SUCCESS); + } +} diff --git a/api/core/HD_Controller.php b/api/core/HD_Controller.php index 2a61196b..dedd43de 100644 --- a/api/core/HD_Controller.php +++ b/api/core/HD_Controller.php @@ -1,26 +1,26 @@ - $returnData, 'code' => $code, 'msg' => $msg), JSON_UNESCAPED_UNICODE); - exit(); - } - - public function fail($returnData, $msg = 'fail', $code = 400) - { - header('Content-Type:application/json; charset=utf-8'); - echo json_encode(array('data' => $returnData, 'code' => $code, 'msg' => $msg), JSON_UNESCAPED_UNICODE); - exit(); - } - + $returnData, 'code' => $code, 'msg' => $msg), JSON_UNESCAPED_UNICODE); + exit(); + } + + public function fail($returnData, $msg = 'fail', $code = 400) + { + header('Content-Type:application/json; charset=utf-8'); + echo json_encode(array('data' => $returnData, 'code' => $code, 'msg' => $msg), JSON_UNESCAPED_UNICODE); + exit(); + } + } \ No newline at end of file diff --git a/api/core/HD_Loader.php b/api/core/HD_Loader.php index 8f01cad5..f02d2be9 100644 --- a/api/core/HD_Loader.php +++ b/api/core/HD_Loader.php @@ -1,1584 +1,1584 @@ - TRUE); - - /** - * List of paths to load libraries from - * - * @var array - */ - // add COMMPATH by 0fun - protected $_ci_library_paths = array(APPPATH, COMMPATH, BASEPATH); - - /** - * List of paths to load service from - * - * @var array - */ - // add lcc - protected $_ci_service_paths = array(APPPATH, COMMPATH); - - /** - * List of paths to load models from - * - * @var array - */ - // add COMMPATH by 0fun - protected $_ci_model_paths = array(APPPATH, COMMPATH); - - /** - * List of paths to load helpers from - * - * @var array - */ - // add COMMPATH by 0fun - protected $_ci_helper_paths = array(APPPATH, COMMPATH, BASEPATH); - - /** - * List of cached variables - * - * @var array - */ - protected $_ci_cached_vars = array(); - - /** - * List of loaded classes - * - * @var array - */ - protected $_ci_classes = array(); - - /** - * List of loaded models - * - * @var array - */ - protected $_ci_models = array(); - - /** - * List of loaded helpers - * - * @var array - */ - protected $_ci_helpers = array(); - - /** - * List of class name mappings - * - * @var array - */ - protected $_ci_varmap = array( - 'unit_test' => 'unit', - 'user_agent' => 'agent' - ); - - // -------------------------------------------------------------------- - - /** - * Class constructor - * - * Sets component load paths, gets the initial output buffering level. - * - * @return void - */ - public function __construct() - { - $this->_ci_ob_level = ob_get_level(); - $this->_ci_classes =& is_loaded(); - - log_message('info', 'Loader Class Initialized'); - } - - // -------------------------------------------------------------------- - - /** - * Initializer - * - * @todo Figure out a way to move this to the constructor - * without breaking *package_path*() methods. - * @uses CI_Loader::_ci_autoloader() - * @used-by CI_Controller::__construct() - * @return void - */ - public function initialize() - { - $this->_ci_autoloader(); - } - - // -------------------------------------------------------------------- - - /** - * Is Loaded - * - * A utility method to test if a class is in the self::$_ci_classes array. - * - * @used-by Mainly used by Form Helper function _get_validation_object(). - * - * @param string $class Class name to check for - * @return string|bool Class object name if loaded or FALSE - */ - public function is_loaded($class) - { - return array_search(ucfirst($class), $this->_ci_classes, TRUE); - } - - // -------------------------------------------------------------------- - - /** - * Library Loader - * - * Loads and instantiates libraries. - * Designed to be called from application controllers. - * - * @param mixed $library Library name - * @param array $params Optional parameters to pass to the library class constructor - * @param string $object_name An optional object name to assign to - * @return object - */ - public function library($library, $params = NULL, $object_name = NULL) - { - if (empty($library)) - { - return $this; - } - elseif (is_array($library)) - { - foreach ($library as $key => $value) - { - if (is_int($key)) - { - $this->library($value, $params); - } - else - { - $this->library($key, $params, $value); - } - } - - return $this; - } - - if ($params !== NULL && ! is_array($params)) - { - $params = NULL; - } - - $this->_ci_load_library($library, $params, $object_name); - return $this; - } - /** - * Service Loader - * - * This function lets users load and instantiate classes. - * It is designed to be called from a user's app controllers. - * - * @param string the name of the class - * @param mixed the optional parameters - * @param string an optional object name - * @return void - */ - public function service($service = '', $params = NULL, $object_name = NULL){ - if (empty($service)){ - return $this; - }elseif(is_array($service)){ - foreach($service as $class) - { - $this->service($class, $params); - } - return $this; - } - - $path = ''; - - // Is the service in a sub-folder? If so, parse out the filename and path. - if (($last_slash = strrpos($service, '/')) !== FALSE) - { - // The path is in front of the last slash - $path = substr($service, 0, ++$last_slash); - - // And the model name behind it - $service = substr($service, $last_slash); - } - - if (empty($object_name)) - { - $object_name = $service; - } - - if($this->_ci_services && is_array($this->_ci_services)){ - if (in_array($object_name, $this->_ci_services, TRUE)) - { - return $this; - } - } - $CI =& get_instance(); - if (isset($CI->$object_name)) - { - throw new RuntimeException('The service name you are loading is the name of a resource that is already being used: '.$object_name); - } - - // Note: All of the code under this condition used to be just: - // - // load_class('Service', 'core'); - // - // However, load_class() instantiates classes - // to cache them for later use and that prevents - // MY_Service from being an abstract class and is - // sub-optimal otherwise anyway. - if ( ! class_exists('CI_Service', FALSE)) - { - $app_path = APPPATH.'core'.DIRECTORY_SEPARATOR; - if (file_exists($app_path.'Service.php')) - { - require_once($app_path.'Service.php'); - if ( ! class_exists('CI_Service', FALSE)) - { - throw new RuntimeException($app_path."Service.php exists, but doesn't declare class CI_Service"); - } - - log_message('info', 'CI_Service class loaded'); - } - - $class = config_item('subclass_prefix').'Service'; - if (file_exists($app_path.$class.'.php')) - { - require_once($app_path.$class.'.php'); - if ( ! class_exists($class, FALSE)) - { - throw new RuntimeException($app_path.$class.".php exists, but doesn't declare class ".$class); - } - - log_message('info', config_item('subclass_prefix').'Service class loaded'); - } - } - $service = ucfirst($service); - - if ( ! class_exists($service, FALSE)) - { - foreach ($this->_ci_service_paths as $mod_path) - { - if ( ! file_exists($mod_path.'services/'.$path.$service.'.php')) - { - continue; - } - - require_once($mod_path.'services/'.$path.$service.'.php'); - if ( ! class_exists($service, FALSE)) - { - throw new RuntimeException($mod_path."services/".$path.$service.".php exists, but doesn't declare class ".$service); - } - - break; - } - - if ( ! class_exists($service, FALSE)) - { - throw new RuntimeException('Unable to locate the model you have specified: '.$service); - } - } - - - $this->_ci_services[] = $object_name; - if(empty($params)){ - $service = new $service(); - }else{ - $service = new $service($params); - } - $CI->$object_name = $service; - log_message('info', 'Service "'.get_class($service).'" initialized'); - return $this; - } - // -------------------------------------------------------------------- - - /** - * Model Loader - * - * Loads and instantiates models. - * - * @param mixed $model Model name - * @param string $name An optional object name to assign to - * @param bool $db_conn An optional database connection configuration to initialize - * @return object - */ - public function model($model, $name = '', $db_conn = FALSE) - { - if (empty($model)) - { - return $this; - } - elseif (is_array($model)) - { - foreach ($model as $key => $value) - { - is_int($key) ? $this->model($value, '', $db_conn) : $this->model($key, $value, $db_conn); - } - - return $this; - } - - $path = ''; - - // Is the model in a sub-folder? If so, parse out the filename and path. - if (($last_slash = strrpos($model, '/')) !== FALSE) - { - // The path is in front of the last slash - $path = substr($model, 0, ++$last_slash); - - // And the model name behind it - $model = substr($model, $last_slash); - } - - if (empty($name)) - { - $name = $model; - } - - if (in_array($name, $this->_ci_models, TRUE)) - { - return $this; - } - - $CI =& get_instance(); - if (isset($CI->$name)) - { - throw new RuntimeException('The model name you are loading is the name of a resource that is already being used: '.$name); - } - - if ($db_conn !== FALSE && ! class_exists('CI_DB', FALSE)) - { - if ($db_conn === TRUE) - { - $db_conn = ''; - } - - $this->database($db_conn, FALSE, TRUE); - } - - // Note: All of the code under this condition used to be just: - // - // load_class('Model', 'core'); - // - // However, load_class() instantiates classes - // to cache them for later use and that prevents - // MY_Model from being an abstract class and is - // sub-optimal otherwise anyway. - if ( ! class_exists('CI_Model', FALSE)) - { - $app_path = APPPATH.'core'.DIRECTORY_SEPARATOR; - if (file_exists($app_path.'Model.php')) - { - require_once($app_path.'Model.php'); - if ( ! class_exists('CI_Model', FALSE)) - { - throw new RuntimeException($app_path."Model.php exists, but doesn't declare class CI_Model"); - } - - log_message('info', 'CI_Model class loaded'); - } - elseif ( ! class_exists('CI_Model', FALSE)) - { - require_once(BASEPATH.'core'.DIRECTORY_SEPARATOR.'Model.php'); - } - - $class = config_item('subclass_prefix').'Model'; - if (file_exists($app_path.$class.'.php')) - { - require_once($app_path.$class.'.php'); - if ( ! class_exists($class, FALSE)) - { - throw new RuntimeException($app_path.$class.".php exists, but doesn't declare class ".$class); - } - - log_message('info', config_item('subclass_prefix').'Model class loaded'); - } - } - - $model = ucfirst($model); - if ( ! class_exists($model, FALSE)) - { - foreach ($this->_ci_model_paths as $mod_path) - { - if ( ! file_exists($mod_path.'models/'.$path.$model.'.php')) - { - continue; - } - - require_once($mod_path.'models/'.$path.$model.'.php'); - if ( ! class_exists($model, FALSE)) - { - throw new RuntimeException($mod_path."models/".$path.$model.".php exists, but doesn't declare class ".$model); - } - - break; - } - - if ( ! class_exists($model, FALSE)) - { - throw new RuntimeException('Unable to locate the model you have specified: '.$model); - } - } - elseif ( ! is_subclass_of($model, 'CI_Model')) - { - throw new RuntimeException("Class ".$model." already exists and doesn't extend CI_Model"); - } - - $this->_ci_models[] = $name; - $model = new $model(); - $CI->$name = $model; - log_message('info', 'Model "'.get_class($model).'" initialized'); - return $this; - } - - /** - * 根据app_id重建model - * @param $app_id - * @return $this - */ - public function rebuild_model($app_id){ - if(!$app_id){ - return $this; - } - - $CI =& get_instance(); - - $CI->config->load("app", true); - $configs = $CI->config->item('app'); - $config= array(); - foreach($configs as $v){ - if($v['app_id'] == $app_id){ - $config = $v; - break; - } - } - - $app_db = $config['db']; - if($config && $app_db){ - $GLOBALS['app_db'] = $app_db; - - $CI->load->config("dbtable", true, true); - $dbtable = $CI->config->item($app_db, "dbtable"); - $models = $this->_ci_models; - foreach($models as $model){ - $CI->$model->set_appdb($app_db, $dbtable); - } - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Database Loader - * - * @param mixed $params Database configuration options - * @param bool $return Whether to return the database object - * @param bool $query_builder Whether to enable Query Builder - * (overrides the configuration setting) - * - * @return object|bool Database object if $return is set to TRUE, - * FALSE on failure, CI_Loader instance in any other case - */ - public function database($params = '', $return = FALSE, $query_builder = NULL) - { - // Grab the super object - $CI =& get_instance(); - - // Do we even need to load the database class? - if ($return === FALSE && $query_builder === NULL && isset($CI->db) && is_object($CI->db) && ! empty($CI->db->conn_id)) - { - return FALSE; - } - - require_once(BASEPATH.'database/DB.php'); - - if ($return === TRUE) - { - return DB($params, $query_builder); - } - - // Initialize the db variable. Needed to prevent - // reference errors with some configurations - $CI->db = ''; - - // Load the DB class - $CI->db =& DB($params, $query_builder); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Load the Database Utilities Class - * - * @param object $db Database object - * @param bool $return Whether to return the DB Utilities class object or not - * @return object - */ - public function dbutil($db = NULL, $return = FALSE) - { - $CI =& get_instance(); - - if ( ! is_object($db) OR ! ($db instanceof CI_DB)) - { - class_exists('CI_DB', FALSE) OR $this->database(); - $db =& $CI->db; - } - - require_once(BASEPATH.'database/DB_utility.php'); - require_once(BASEPATH.'database/drivers/'.$db->dbdriver.'/'.$db->dbdriver.'_utility.php'); - $class = 'CI_DB_'.$db->dbdriver.'_utility'; - - if ($return === TRUE) - { - return new $class($db); - } - - $CI->dbutil = new $class($db); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Load the Database Forge Class - * - * @param object $db Database object - * @param bool $return Whether to return the DB Forge class object or not - * @return object - */ - public function dbforge($db = NULL, $return = FALSE) - { - $CI =& get_instance(); - if ( ! is_object($db) OR ! ($db instanceof CI_DB)) - { - class_exists('CI_DB', FALSE) OR $this->database(); - $db =& $CI->db; - } - - require_once(BASEPATH.'database/DB_forge.php'); - require_once(BASEPATH.'database/drivers/'.$db->dbdriver.'/'.$db->dbdriver.'_forge.php'); - - if ( ! empty($db->subdriver)) - { - $driver_path = BASEPATH.'database/drivers/'.$db->dbdriver.'/subdrivers/'.$db->dbdriver.'_'.$db->subdriver.'_forge.php'; - if (file_exists($driver_path)) - { - require_once($driver_path); - $class = 'CI_DB_'.$db->dbdriver.'_'.$db->subdriver.'_forge'; - } - } - else - { - $class = 'CI_DB_'.$db->dbdriver.'_forge'; - } - - if ($return === TRUE) - { - return new $class($db); - } - - $CI->dbforge = new $class($db); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * View Loader - * - * Loads "view" files. - * - * @param string $view View name - * @param array $vars An associative array of data - * to be extracted for use in the view - * @param bool $return Whether to return the view output - * or leave it to the Output class - * @return object|string - */ - public function view($view, $vars = array(), $return = FALSE) - { - return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_prepare_view_vars($vars), '_ci_return' => $return)); - } - - // -------------------------------------------------------------------- - - /** - * Generic File Loader - * - * @param string $path File path - * @param bool $return Whether to return the file output - * @return object|string - */ - public function file($path, $return = FALSE) - { - return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return)); - } - - // -------------------------------------------------------------------- - - /** - * Set Variables - * - * Once variables are set they become available within - * the controller class and its "view" files. - * - * @param array|object|string $vars - * An associative array or object containing values - * to be set, or a value's name if string - * @param string $val Value to set, only used if $vars is a string - * @return object - */ - public function vars($vars, $val = '') - { - $vars = is_string($vars) - ? array($vars => $val) - : $this->_ci_prepare_view_vars($vars); - - foreach ($vars as $key => $val) - { - $this->_ci_cached_vars[$key] = $val; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Clear Cached Variables - * - * Clears the cached variables. - * - * @return CI_Loader - */ - public function clear_vars() - { - $this->_ci_cached_vars = array(); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Get Variable - * - * Check if a variable is set and retrieve it. - * - * @param string $key Variable name - * @return mixed The variable or NULL if not found - */ - public function get_var($key) - { - return isset($this->_ci_cached_vars[$key]) ? $this->_ci_cached_vars[$key] : NULL; - } - - // -------------------------------------------------------------------- - - /** - * Get Variables - * - * Retrieves all loaded variables. - * - * @return array - */ - public function get_vars() - { - return $this->_ci_cached_vars; - } - - // -------------------------------------------------------------------- - - /** - * Helper Loader - * - * @param string|string[] $helpers Helper name(s) - * @return object - */ - public function helper($helpers = array()) - { - is_array($helpers) OR $helpers = array($helpers); - foreach ($helpers as &$helper) - { - $filename = basename($helper); - $filepath = ($filename === $helper) ? '' : substr($helper, 0, strlen($helper) - strlen($filename)); - $filename = strtolower(preg_replace('#(_helper)?(\.php)?$#i', '', $filename)).'_helper'; - $helper = $filepath.$filename; - - if (isset($this->_ci_helpers[$helper])) - { - continue; - } - - // Is this a helper extension request? - $ext_helper = config_item('subclass_prefix').$filename; - $ext_loaded = FALSE; - foreach ($this->_ci_helper_paths as $path) - { - if (file_exists($path.'helpers/'.$ext_helper.'.php')) - { - include_once($path.'helpers/'.$ext_helper.'.php'); - $ext_loaded = TRUE; - } - } - - // If we have loaded extensions - check if the base one is here - if ($ext_loaded === TRUE) - { - $base_helper = BASEPATH.'helpers/'.$helper.'.php'; - if ( ! file_exists($base_helper)) - { - show_error('Unable to load the requested file: helpers/'.$helper.'.php'); - } - - include_once($base_helper); - $this->_ci_helpers[$helper] = TRUE; - log_message('info', 'Helper loaded: '.$helper); - continue; - } - - // No extensions found ... try loading regular helpers and/or overrides - foreach ($this->_ci_helper_paths as $path) - { - if (file_exists($path.'helpers/'.$helper.'.php')) - { - include_once($path.'helpers/'.$helper.'.php'); - - $this->_ci_helpers[$helper] = TRUE; - log_message('info', 'Helper loaded: '.$helper); - break; - } - } - - // unable to load the helper - if ( ! isset($this->_ci_helpers[$helper])) - { - show_error('Unable to load the requested file: helpers/'.$helper.'.php'); - } - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Load Helpers - * - * An alias for the helper() method in case the developer has - * written the plural form of it. - * - * @uses CI_Loader::helper() - * @param string|string[] $helpers Helper name(s) - * @return object - */ - public function helpers($helpers = array()) - { - return $this->helper($helpers); - } - - // -------------------------------------------------------------------- - - /** - * Language Loader - * - * Loads language files. - * - * @param string|string[] $files List of language file names to load - * @param string Language name - * @return object - */ - public function language($files, $lang = '') - { - get_instance()->lang->load($files, $lang); - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Config Loader - * - * Loads a config file (an alias for CI_Config::load()). - * - * @uses CI_Config::load() - * @param string $file Configuration file name - * @param bool $use_sections Whether configuration values should be loaded into their own section - * @param bool $fail_gracefully Whether to just return FALSE or display an error message - * @return bool TRUE if the file was loaded correctly or FALSE on failure - */ - public function config($file, $use_sections = FALSE, $fail_gracefully = FALSE) - { - return get_instance()->config->load($file, $use_sections, $fail_gracefully); - } - - // -------------------------------------------------------------------- - - /** - * Driver Loader - * - * Loads a driver library. - * - * @param string|string[] $library Driver name(s) - * @param array $params Optional parameters to pass to the driver - * @param string $object_name An optional object name to assign to - * - * @return object|bool Object or FALSE on failure if $library is a string - * and $object_name is set. CI_Loader instance otherwise. - */ - public function driver($library, $params = NULL, $object_name = NULL) - { - if (is_array($library)) - { - foreach ($library as $key => $value) - { - if (is_int($key)) - { - $this->driver($value, $params); - } - else - { - $this->driver($key, $params, $value); - } - } - - return $this; - } - elseif (empty($library)) - { - return FALSE; - } - - if ( ! class_exists('CI_Driver_Library', FALSE)) - { - // We aren't instantiating an object here, just making the base class available - require BASEPATH.'libraries/Driver.php'; - } - - // We can save the loader some time since Drivers will *always* be in a subfolder, - // and typically identically named to the library - if ( ! strpos($library, '/')) - { - $library = ucfirst($library).'/'.$library; - } - - return $this->library($library, $params, $object_name); - } - - // -------------------------------------------------------------------- - - /** - * Add Package Path - * - * Prepends a parent path to the library, model, helper and config - * path arrays. - * - * @see CI_Loader::$_ci_library_paths - * @see CI_Loader::$_ci_model_paths - * @see CI_Loader::$_ci_helper_paths - * @see CI_Config::$_config_paths - * - * @param string $path Path to add - * @param bool $view_cascade (default: TRUE) - * @return object - */ - public function add_package_path($path, $view_cascade = TRUE) - { - $path = rtrim($path, '/').'/'; - - array_unshift($this->_ci_library_paths, $path); - array_unshift($this->_ci_model_paths, $path); - array_unshift($this->_ci_helper_paths, $path); - - $this->_ci_view_paths = array($path.'views/' => $view_cascade) + $this->_ci_view_paths; - - // Add config file path - $config =& $this->_ci_get_component('config'); - $config->_config_paths[] = $path; - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Get Package Paths - * - * Return a list of all package paths. - * - * @param bool $include_base Whether to include BASEPATH (default: FALSE) - * @return array - */ - public function get_package_paths($include_base = FALSE) - { - return ($include_base === TRUE) ? $this->_ci_library_paths : $this->_ci_model_paths; - } - - // -------------------------------------------------------------------- - - /** - * Remove Package Path - * - * Remove a path from the library, model, helper and/or config - * path arrays if it exists. If no path is provided, the most recently - * added path will be removed removed. - * - * @param string $path Path to remove - * @return object - */ - public function remove_package_path($path = '') - { - $config =& $this->_ci_get_component('config'); - - if ($path === '') - { - array_shift($this->_ci_library_paths); - array_shift($this->_ci_model_paths); - array_shift($this->_ci_helper_paths); - array_shift($this->_ci_view_paths); - array_pop($config->_config_paths); - } - else - { - $path = rtrim($path, '/').'/'; - foreach (array('_ci_library_paths', '_ci_model_paths', '_ci_helper_paths') as $var) - { - if (($key = array_search($path, $this->{$var})) !== FALSE) - { - unset($this->{$var}[$key]); - } - } - - if (isset($this->_ci_view_paths[$path.'views/'])) - { - unset($this->_ci_view_paths[$path.'views/']); - } - - if (($key = array_search($path, $config->_config_paths)) !== FALSE) - { - unset($config->_config_paths[$key]); - } - } - - // make sure the application default paths are still in the array - $this->_ci_library_paths = array_unique(array_merge($this->_ci_library_paths, array(APPPATH, BASEPATH))); - $this->_ci_helper_paths = array_unique(array_merge($this->_ci_helper_paths, array(APPPATH, BASEPATH))); - $this->_ci_model_paths = array_unique(array_merge($this->_ci_model_paths, array(APPPATH))); - $this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH.'views/' => TRUE)); - $config->_config_paths = array_unique(array_merge($config->_config_paths, array(APPPATH))); - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Internal CI Data Loader - * - * Used to load views and files. - * - * Variables are prefixed with _ci_ to avoid symbol collision with - * variables made available to view files. - * - * @used-by CI_Loader::view() - * @used-by CI_Loader::file() - * @param array $_ci_data Data to load - * @return object - */ - protected function _ci_load($_ci_data) - { - // Set the default data variables - foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val) - { - $$_ci_val = isset($_ci_data[$_ci_val]) ? $_ci_data[$_ci_val] : FALSE; - } - - $file_exists = FALSE; - - // Set the path to the requested file - if (is_string($_ci_path) && $_ci_path !== '') - { - $_ci_x = explode('/', $_ci_path); - $_ci_file = end($_ci_x); - } - else - { - $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION); - $_ci_file = ($_ci_ext === '') ? $_ci_view.'.php' : $_ci_view; - - foreach ($this->_ci_view_paths as $_ci_view_file => $cascade) - { - if (file_exists($_ci_view_file.$_ci_file)) - { - $_ci_path = $_ci_view_file.$_ci_file; - $file_exists = TRUE; - break; - } - - if ( ! $cascade) - { - break; - } - } - } - - if ( ! $file_exists && ! file_exists($_ci_path)) - { - show_error('Unable to load the requested file: '.$_ci_file); - } - - // This allows anything loaded using $this->load (views, files, etc.) - // to become accessible from within the Controller and Model functions. - $_ci_CI =& get_instance(); - foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var) - { - if ( ! isset($this->$_ci_key)) - { - $this->$_ci_key =& $_ci_CI->$_ci_key; - } - } - - /* - * Extract and cache variables - * - * You can either set variables using the dedicated $this->load->vars() - * function or via the second parameter of this function. We'll merge - * the two types and cache them so that views that are embedded within - * other views can have access to these variables. - */ - empty($_ci_vars) OR $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars); - extract($this->_ci_cached_vars); - - /* - * Buffer the output - * - * We buffer the output for two reasons: - * 1. Speed. You get a significant speed boost. - * 2. So that the final rendered template can be post-processed by - * the output class. Why do we need post processing? For one thing, - * in order to show the elapsed page load time. Unless we can - * intercept the cms right before it's sent to the browser and - * then stop the timer it won't be accurate. - */ - ob_start(); - - // If the PHP installation does not support short tags we'll - // do a little string replacement, changing the short tags - // to standard PHP echo statements. - if ( ! is_php('5.4') && ! ini_get('short_open_tag') && config_item('rewrite_short_tags') === TRUE) - { - echo eval('?>'.preg_replace('/;*\s*\?>/', '; ?>', str_replace(' $this->_ci_ob_level + 1) - { - ob_end_flush(); - } - else - { - $_ci_CI->output->append_output(ob_get_contents()); - @ob_end_clean(); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Internal CI Library Loader - * - * @used-by CI_Loader::library() - * @uses CI_Loader::_ci_init_library() - * - * @param string $class Class name to load - * @param mixed $params Optional parameters to pass to the class constructor - * @param string $object_name Optional object name to assign to - * @return void - */ - protected function _ci_load_library($class, $params = NULL, $object_name = NULL) - { - // Get the class name, and while we're at it trim any slashes. - // The directory path can be included as part of the class name, - // but we don't want a leading slash - $class = str_replace('.php', '', trim($class, '/')); - - // Was the path included with the class name? - // We look for a slash to determine this - if (($last_slash = strrpos($class, '/')) !== FALSE) - { - // Extract the path - $subdir = substr($class, 0, ++$last_slash); - - // Get the filename from the path - $class = substr($class, $last_slash); - } - else - { - $subdir = ''; - } - - $class = ucfirst($class); - - // Is this a stock library? There are a few special conditions if so ... - if (file_exists(BASEPATH.'libraries/'.$subdir.$class.'.php')) - { - return $this->_ci_load_stock_library($class, $subdir, $params, $object_name); - } - - // Safety: Was the class already loaded by a previous call? - if (class_exists($class, FALSE)) - { - $property = $object_name; - if (empty($property)) - { - $property = strtolower($class); - isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property]; - } - - $CI =& get_instance(); - if (isset($CI->$property)) - { - log_message('debug', $class.' class already loaded. Second attempt ignored.'); - return; - } - - return $this->_ci_init_library($class, '', $params, $object_name); - } - - // Let's search for the requested library file and load it. - foreach ($this->_ci_library_paths as $path) - { - // BASEPATH has already been checked for - if ($path === BASEPATH) - { - continue; - } - - $filepath = $path.'libraries/'.$subdir.$class.'.php'; - // Does the file exist? No? Bummer... - if ( ! file_exists($filepath)) - { - continue; - } - - include_once($filepath); - return $this->_ci_init_library($class, '', $params, $object_name); - } - - // One last attempt. Maybe the library is in a subdirectory, but it wasn't specified? - if ($subdir === '') - { - return $this->_ci_load_library($class.'/'.$class, $params, $object_name); - } - - // If we got this far we were unable to find the requested class. - log_message('error', 'Unable to load the requested class: '.$class); - show_error('Unable to load the requested class: '.$class); - } - - // -------------------------------------------------------------------- - - /** - * Internal CI Stock Library Loader - * - * @used-by CI_Loader::_ci_load_library() - * @uses CI_Loader::_ci_init_library() - * - * @param string $library_name Library name to load - * @param string $file_path Path to the library filename, relative to libraries/ - * @param mixed $params Optional parameters to pass to the class constructor - * @param string $object_name Optional object name to assign to - * @return void - */ - protected function _ci_load_stock_library($library_name, $file_path, $params, $object_name) - { - $prefix = 'CI_'; - - if (class_exists($prefix.$library_name, FALSE)) - { - if (class_exists(config_item('subclass_prefix').$library_name, FALSE)) - { - $prefix = config_item('subclass_prefix'); - } - - $property = $object_name; - if (empty($property)) - { - $property = strtolower($library_name); - isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property]; - } - - $CI =& get_instance(); - if ( ! isset($CI->$property)) - { - return $this->_ci_init_library($library_name, $prefix, $params, $object_name); - } - - log_message('debug', $library_name.' class already loaded. Second attempt ignored.'); - return; - } - - $paths = $this->_ci_library_paths; - array_pop($paths); // BASEPATH - array_pop($paths); // APPPATH (needs to be the first path checked) - array_unshift($paths, APPPATH); - - foreach ($paths as $path) - { - if (file_exists($path = $path.'libraries/'.$file_path.$library_name.'.php')) - { - // Override - include_once($path); - if (class_exists($prefix.$library_name, FALSE)) - { - return $this->_ci_init_library($library_name, $prefix, $params, $object_name); - } - - log_message('debug', $path.' exists, but does not declare '.$prefix.$library_name); - } - } - - include_once(BASEPATH.'libraries/'.$file_path.$library_name.'.php'); - - // Check for extensions - $subclass = config_item('subclass_prefix').$library_name; - foreach ($paths as $path) - { - if (file_exists($path = $path.'libraries/'.$file_path.$subclass.'.php')) - { - include_once($path); - if (class_exists($subclass, FALSE)) - { - $prefix = config_item('subclass_prefix'); - break; - } - - log_message('debug', $path.' exists, but does not declare '.$subclass); - } - } - - return $this->_ci_init_library($library_name, $prefix, $params, $object_name); - } - - // -------------------------------------------------------------------- - - /** - * Internal CI Library Instantiator - * - * @used-by CI_Loader::_ci_load_stock_library() - * @used-by CI_Loader::_ci_load_library() - * - * @param string $class Class name - * @param string $prefix Class name prefix - * @param array|null|bool $config Optional configuration to pass to the class constructor: - * FALSE to skip; - * NULL to search in config paths; - * array containing configuration data - * @param string $object_name Optional object name to assign to - * @return void - */ - protected function _ci_init_library($class, $prefix, $config = FALSE, $object_name = NULL) - { - // Is there an associated config file for this class? Note: these should always be lowercase - if ($config === NULL) - { - // Fetch the config paths containing any package paths - $config_component = $this->_ci_get_component('config'); - - if (is_array($config_component->_config_paths)) - { - $found = FALSE; - foreach ($config_component->_config_paths as $path) - { - // We test for both uppercase and lowercase, for servers that - // are case-sensitive with regard to file names. Load global first, - // override with environment next - if (file_exists($path.'config/'.strtolower($class).'.php')) - { - include($path.'config/'.strtolower($class).'.php'); - $found = TRUE; - } - elseif (file_exists($path.'config/'.ucfirst(strtolower($class)).'.php')) - { - include($path.'config/'.ucfirst(strtolower($class)).'.php'); - $found = TRUE; - } - - if (file_exists($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php')) - { - include($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php'); - $found = TRUE; - } - elseif (file_exists($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php')) - { - include($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php'); - $found = TRUE; - } - - // Break on the first found configuration, thus package - // files are not overridden by default paths - if ($found === TRUE) - { - break; - } - } - } - } - - $class_name = $prefix.$class; - - // Is the class name valid? - if ( ! class_exists($class_name, FALSE)) - { - log_message('error', 'Non-existent class: '.$class_name); - show_error('Non-existent class: '.$class_name); - } - - // Set the variable name we will assign the class to - // Was a custom class name supplied? If so we'll use it - if (empty($object_name)) - { - $object_name = strtolower($class); - if (isset($this->_ci_varmap[$object_name])) - { - $object_name = $this->_ci_varmap[$object_name]; - } - } - - // Don't overwrite existing properties - $CI =& get_instance(); - if (isset($CI->$object_name)) - { - if ($CI->$object_name instanceof $class_name) - { - log_message('debug', $class_name." has already been instantiated as '".$object_name."'. Second attempt aborted."); - return; - } - - show_error("Resource '".$object_name."' already exists and is not a ".$class_name." instance."); - } - - // Save the class name and object name - $this->_ci_classes[$object_name] = $class; - - // Instantiate the class - $CI->$object_name = isset($config) - ? new $class_name($config) - : new $class_name(); - } - - // -------------------------------------------------------------------- - - /** - * CI Autoloader - * - * Loads component listed in the config/autoload.php file. - * - * @used-by CI_Loader::initialize() - * @return void - */ - protected function _ci_autoloader() - { - if (file_exists(APPPATH.'config/autoload.php')) - { - include(APPPATH.'config/autoload.php'); - } - - if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php')) - { - include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'); - } - - if ( ! isset($autoload)) - { - return; - } - - // Autoload packages - if (isset($autoload['packages'])) - { - foreach ($autoload['packages'] as $package_path) - { - $this->add_package_path($package_path); - } - } - - // Load any custom config file - if (count($autoload['config']) > 0) - { - foreach ($autoload['config'] as $val) - { - $this->config($val); - } - } - - // Autoload helpers and languages - foreach (array('helper', 'language') as $type) - { - if (isset($autoload[$type]) && count($autoload[$type]) > 0) - { - $this->$type($autoload[$type]); - } - } - - // Autoload drivers - if (isset($autoload['drivers'])) - { - $this->driver($autoload['drivers']); - } - - // Load libraries - if (isset($autoload['libraries']) && count($autoload['libraries']) > 0) - { - // Load the database driver. - if (in_array('database', $autoload['libraries'])) - { - $this->database(); - $autoload['libraries'] = array_diff($autoload['libraries'], array('database')); - } - - // Load all other libraries - $this->library($autoload['libraries']); - } - - // Autoload models - if (isset($autoload['model'])) - { - $this->model($autoload['model']); - } - } - - // -------------------------------------------------------------------- - - /** - * Prepare variables for _ci_vars, to be later extract()-ed inside views - * - * Converts objects to associative arrays and filters-out internal - * variable names (i.e. keys prefixed with '_ci_'). - * - * @param mixed $vars - * @return array - */ - protected function _ci_prepare_view_vars($vars) - { - if ( ! is_array($vars)) - { - $vars = is_object($vars) - ? get_object_vars($vars) - : array(); - } - - foreach (array_keys($vars) as $key) - { - if (strncmp($key, '_ci_', 4) === 0) - { - unset($vars[$key]); - } - } - - return $vars; - } - - // -------------------------------------------------------------------- - - /** - * CI Component getter - * - * Get a reference to a specific library or model. - * - * @param string $component Component name - * @return bool - */ - protected function &_ci_get_component($component) - { - $CI =& get_instance(); - return $CI->$component; - } -} + TRUE); + + /** + * List of paths to load libraries from + * + * @var array + */ + // add COMMPATH by 0fun + protected $_ci_library_paths = array(APPPATH, COMMPATH, BASEPATH); + + /** + * List of paths to load service from + * + * @var array + */ + // add lcc + protected $_ci_service_paths = array(APPPATH, COMMPATH); + + /** + * List of paths to load models from + * + * @var array + */ + // add COMMPATH by 0fun + protected $_ci_model_paths = array(APPPATH, COMMPATH); + + /** + * List of paths to load helpers from + * + * @var array + */ + // add COMMPATH by 0fun + protected $_ci_helper_paths = array(APPPATH, COMMPATH, BASEPATH); + + /** + * List of cached variables + * + * @var array + */ + protected $_ci_cached_vars = array(); + + /** + * List of loaded classes + * + * @var array + */ + protected $_ci_classes = array(); + + /** + * List of loaded models + * + * @var array + */ + protected $_ci_models = array(); + + /** + * List of loaded helpers + * + * @var array + */ + protected $_ci_helpers = array(); + + /** + * List of class name mappings + * + * @var array + */ + protected $_ci_varmap = array( + 'unit_test' => 'unit', + 'user_agent' => 'agent' + ); + + // -------------------------------------------------------------------- + + /** + * Class constructor + * + * Sets component load paths, gets the initial output buffering level. + * + * @return void + */ + public function __construct() + { + $this->_ci_ob_level = ob_get_level(); + $this->_ci_classes =& is_loaded(); + + log_message('info', 'Loader Class Initialized'); + } + + // -------------------------------------------------------------------- + + /** + * Initializer + * + * @todo Figure out a way to move this to the constructor + * without breaking *package_path*() methods. + * @uses CI_Loader::_ci_autoloader() + * @used-by CI_Controller::__construct() + * @return void + */ + public function initialize() + { + $this->_ci_autoloader(); + } + + // -------------------------------------------------------------------- + + /** + * Is Loaded + * + * A utility method to test if a class is in the self::$_ci_classes array. + * + * @used-by Mainly used by Form Helper function _get_validation_object(). + * + * @param string $class Class name to check for + * @return string|bool Class object name if loaded or FALSE + */ + public function is_loaded($class) + { + return array_search(ucfirst($class), $this->_ci_classes, TRUE); + } + + // -------------------------------------------------------------------- + + /** + * Library Loader + * + * Loads and instantiates libraries. + * Designed to be called from application controllers. + * + * @param mixed $library Library name + * @param array $params Optional parameters to pass to the library class constructor + * @param string $object_name An optional object name to assign to + * @return object + */ + public function library($library, $params = NULL, $object_name = NULL) + { + if (empty($library)) + { + return $this; + } + elseif (is_array($library)) + { + foreach ($library as $key => $value) + { + if (is_int($key)) + { + $this->library($value, $params); + } + else + { + $this->library($key, $params, $value); + } + } + + return $this; + } + + if ($params !== NULL && ! is_array($params)) + { + $params = NULL; + } + + $this->_ci_load_library($library, $params, $object_name); + return $this; + } + /** + * Service Loader + * + * This function lets users load and instantiate classes. + * It is designed to be called from a user's app controllers. + * + * @param string the name of the class + * @param mixed the optional parameters + * @param string an optional object name + * @return void + */ + public function service($service = '', $params = NULL, $object_name = NULL){ + if (empty($service)){ + return $this; + }elseif(is_array($service)){ + foreach($service as $class) + { + $this->service($class, $params); + } + return $this; + } + + $path = ''; + + // Is the service in a sub-folder? If so, parse out the filename and path. + if (($last_slash = strrpos($service, '/')) !== FALSE) + { + // The path is in front of the last slash + $path = substr($service, 0, ++$last_slash); + + // And the model name behind it + $service = substr($service, $last_slash); + } + + if (empty($object_name)) + { + $object_name = $service; + } + + if($this->_ci_services && is_array($this->_ci_services)){ + if (in_array($object_name, $this->_ci_services, TRUE)) + { + return $this; + } + } + $CI =& get_instance(); + if (isset($CI->$object_name)) + { + throw new RuntimeException('The service name you are loading is the name of a resource that is already being used: '.$object_name); + } + + // Note: All of the code under this condition used to be just: + // + // load_class('Service', 'core'); + // + // However, load_class() instantiates classes + // to cache them for later use and that prevents + // MY_Service from being an abstract class and is + // sub-optimal otherwise anyway. + if ( ! class_exists('CI_Service', FALSE)) + { + $app_path = APPPATH.'core'.DIRECTORY_SEPARATOR; + if (file_exists($app_path.'Service.php')) + { + require_once($app_path.'Service.php'); + if ( ! class_exists('CI_Service', FALSE)) + { + throw new RuntimeException($app_path."Service.php exists, but doesn't declare class CI_Service"); + } + + log_message('info', 'CI_Service class loaded'); + } + + $class = config_item('subclass_prefix').'Service'; + if (file_exists($app_path.$class.'.php')) + { + require_once($app_path.$class.'.php'); + if ( ! class_exists($class, FALSE)) + { + throw new RuntimeException($app_path.$class.".php exists, but doesn't declare class ".$class); + } + + log_message('info', config_item('subclass_prefix').'Service class loaded'); + } + } + $service = ucfirst($service); + + if ( ! class_exists($service, FALSE)) + { + foreach ($this->_ci_service_paths as $mod_path) + { + if ( ! file_exists($mod_path.'services/'.$path.$service.'.php')) + { + continue; + } + + require_once($mod_path.'services/'.$path.$service.'.php'); + if ( ! class_exists($service, FALSE)) + { + throw new RuntimeException($mod_path."services/".$path.$service.".php exists, but doesn't declare class ".$service); + } + + break; + } + + if ( ! class_exists($service, FALSE)) + { + throw new RuntimeException('Unable to locate the model you have specified: '.$service); + } + } + + + $this->_ci_services[] = $object_name; + if(empty($params)){ + $service = new $service(); + }else{ + $service = new $service($params); + } + $CI->$object_name = $service; + log_message('info', 'Service "'.get_class($service).'" initialized'); + return $this; + } + // -------------------------------------------------------------------- + + /** + * Model Loader + * + * Loads and instantiates models. + * + * @param mixed $model Model name + * @param string $name An optional object name to assign to + * @param bool $db_conn An optional database connection configuration to initialize + * @return object + */ + public function model($model, $name = '', $db_conn = FALSE) + { + if (empty($model)) + { + return $this; + } + elseif (is_array($model)) + { + foreach ($model as $key => $value) + { + is_int($key) ? $this->model($value, '', $db_conn) : $this->model($key, $value, $db_conn); + } + + return $this; + } + + $path = ''; + + // Is the model in a sub-folder? If so, parse out the filename and path. + if (($last_slash = strrpos($model, '/')) !== FALSE) + { + // The path is in front of the last slash + $path = substr($model, 0, ++$last_slash); + + // And the model name behind it + $model = substr($model, $last_slash); + } + + if (empty($name)) + { + $name = $model; + } + + if (in_array($name, $this->_ci_models, TRUE)) + { + return $this; + } + + $CI =& get_instance(); + if (isset($CI->$name)) + { + throw new RuntimeException('The model name you are loading is the name of a resource that is already being used: '.$name); + } + + if ($db_conn !== FALSE && ! class_exists('CI_DB', FALSE)) + { + if ($db_conn === TRUE) + { + $db_conn = ''; + } + + $this->database($db_conn, FALSE, TRUE); + } + + // Note: All of the code under this condition used to be just: + // + // load_class('Model', 'core'); + // + // However, load_class() instantiates classes + // to cache them for later use and that prevents + // MY_Model from being an abstract class and is + // sub-optimal otherwise anyway. + if ( ! class_exists('CI_Model', FALSE)) + { + $app_path = APPPATH.'core'.DIRECTORY_SEPARATOR; + if (file_exists($app_path.'Model.php')) + { + require_once($app_path.'Model.php'); + if ( ! class_exists('CI_Model', FALSE)) + { + throw new RuntimeException($app_path."Model.php exists, but doesn't declare class CI_Model"); + } + + log_message('info', 'CI_Model class loaded'); + } + elseif ( ! class_exists('CI_Model', FALSE)) + { + require_once(BASEPATH.'core'.DIRECTORY_SEPARATOR.'Model.php'); + } + + $class = config_item('subclass_prefix').'Model'; + if (file_exists($app_path.$class.'.php')) + { + require_once($app_path.$class.'.php'); + if ( ! class_exists($class, FALSE)) + { + throw new RuntimeException($app_path.$class.".php exists, but doesn't declare class ".$class); + } + + log_message('info', config_item('subclass_prefix').'Model class loaded'); + } + } + + $model = ucfirst($model); + if ( ! class_exists($model, FALSE)) + { + foreach ($this->_ci_model_paths as $mod_path) + { + if ( ! file_exists($mod_path.'models/'.$path.$model.'.php')) + { + continue; + } + + require_once($mod_path.'models/'.$path.$model.'.php'); + if ( ! class_exists($model, FALSE)) + { + throw new RuntimeException($mod_path."models/".$path.$model.".php exists, but doesn't declare class ".$model); + } + + break; + } + + if ( ! class_exists($model, FALSE)) + { + throw new RuntimeException('Unable to locate the model you have specified: '.$model); + } + } + elseif ( ! is_subclass_of($model, 'CI_Model')) + { + throw new RuntimeException("Class ".$model." already exists and doesn't extend CI_Model"); + } + + $this->_ci_models[] = $name; + $model = new $model(); + $CI->$name = $model; + log_message('info', 'Model "'.get_class($model).'" initialized'); + return $this; + } + + /** + * 根据app_id重建model + * @param $app_id + * @return $this + */ + public function rebuild_model($app_id){ + if(!$app_id){ + return $this; + } + + $CI =& get_instance(); + + $CI->config->load("app", true); + $configs = $CI->config->item('app'); + $config= array(); + foreach($configs as $v){ + if($v['app_id'] == $app_id){ + $config = $v; + break; + } + } + + $app_db = $config['db']; + if($config && $app_db){ + $GLOBALS['app_db'] = $app_db; + + $CI->load->config("dbtable", true, true); + $dbtable = $CI->config->item($app_db, "dbtable"); + $models = $this->_ci_models; + foreach($models as $model){ + $CI->$model->set_appdb($app_db, $dbtable); + } + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Database Loader + * + * @param mixed $params Database configuration options + * @param bool $return Whether to return the database object + * @param bool $query_builder Whether to enable Query Builder + * (overrides the configuration setting) + * + * @return object|bool Database object if $return is set to TRUE, + * FALSE on failure, CI_Loader instance in any other case + */ + public function database($params = '', $return = FALSE, $query_builder = NULL) + { + // Grab the super object + $CI =& get_instance(); + + // Do we even need to load the database class? + if ($return === FALSE && $query_builder === NULL && isset($CI->db) && is_object($CI->db) && ! empty($CI->db->conn_id)) + { + return FALSE; + } + + require_once(BASEPATH.'database/DB.php'); + + if ($return === TRUE) + { + return DB($params, $query_builder); + } + + // Initialize the db variable. Needed to prevent + // reference errors with some configurations + $CI->db = ''; + + // Load the DB class + $CI->db =& DB($params, $query_builder); + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Load the Database Utilities Class + * + * @param object $db Database object + * @param bool $return Whether to return the DB Utilities class object or not + * @return object + */ + public function dbutil($db = NULL, $return = FALSE) + { + $CI =& get_instance(); + + if ( ! is_object($db) OR ! ($db instanceof CI_DB)) + { + class_exists('CI_DB', FALSE) OR $this->database(); + $db =& $CI->db; + } + + require_once(BASEPATH.'database/DB_utility.php'); + require_once(BASEPATH.'database/drivers/'.$db->dbdriver.'/'.$db->dbdriver.'_utility.php'); + $class = 'CI_DB_'.$db->dbdriver.'_utility'; + + if ($return === TRUE) + { + return new $class($db); + } + + $CI->dbutil = new $class($db); + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Load the Database Forge Class + * + * @param object $db Database object + * @param bool $return Whether to return the DB Forge class object or not + * @return object + */ + public function dbforge($db = NULL, $return = FALSE) + { + $CI =& get_instance(); + if ( ! is_object($db) OR ! ($db instanceof CI_DB)) + { + class_exists('CI_DB', FALSE) OR $this->database(); + $db =& $CI->db; + } + + require_once(BASEPATH.'database/DB_forge.php'); + require_once(BASEPATH.'database/drivers/'.$db->dbdriver.'/'.$db->dbdriver.'_forge.php'); + + if ( ! empty($db->subdriver)) + { + $driver_path = BASEPATH.'database/drivers/'.$db->dbdriver.'/subdrivers/'.$db->dbdriver.'_'.$db->subdriver.'_forge.php'; + if (file_exists($driver_path)) + { + require_once($driver_path); + $class = 'CI_DB_'.$db->dbdriver.'_'.$db->subdriver.'_forge'; + } + } + else + { + $class = 'CI_DB_'.$db->dbdriver.'_forge'; + } + + if ($return === TRUE) + { + return new $class($db); + } + + $CI->dbforge = new $class($db); + return $this; + } + + // -------------------------------------------------------------------- + + /** + * View Loader + * + * Loads "view" files. + * + * @param string $view View name + * @param array $vars An associative array of data + * to be extracted for use in the view + * @param bool $return Whether to return the view output + * or leave it to the Output class + * @return object|string + */ + public function view($view, $vars = array(), $return = FALSE) + { + return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_prepare_view_vars($vars), '_ci_return' => $return)); + } + + // -------------------------------------------------------------------- + + /** + * Generic File Loader + * + * @param string $path File path + * @param bool $return Whether to return the file output + * @return object|string + */ + public function file($path, $return = FALSE) + { + return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return)); + } + + // -------------------------------------------------------------------- + + /** + * Set Variables + * + * Once variables are set they become available within + * the controller class and its "view" files. + * + * @param array|object|string $vars + * An associative array or object containing values + * to be set, or a value's name if string + * @param string $val Value to set, only used if $vars is a string + * @return object + */ + public function vars($vars, $val = '') + { + $vars = is_string($vars) + ? array($vars => $val) + : $this->_ci_prepare_view_vars($vars); + + foreach ($vars as $key => $val) + { + $this->_ci_cached_vars[$key] = $val; + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Clear Cached Variables + * + * Clears the cached variables. + * + * @return CI_Loader + */ + public function clear_vars() + { + $this->_ci_cached_vars = array(); + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Get Variable + * + * Check if a variable is set and retrieve it. + * + * @param string $key Variable name + * @return mixed The variable or NULL if not found + */ + public function get_var($key) + { + return isset($this->_ci_cached_vars[$key]) ? $this->_ci_cached_vars[$key] : NULL; + } + + // -------------------------------------------------------------------- + + /** + * Get Variables + * + * Retrieves all loaded variables. + * + * @return array + */ + public function get_vars() + { + return $this->_ci_cached_vars; + } + + // -------------------------------------------------------------------- + + /** + * Helper Loader + * + * @param string|string[] $helpers Helper name(s) + * @return object + */ + public function helper($helpers = array()) + { + is_array($helpers) OR $helpers = array($helpers); + foreach ($helpers as &$helper) + { + $filename = basename($helper); + $filepath = ($filename === $helper) ? '' : substr($helper, 0, strlen($helper) - strlen($filename)); + $filename = strtolower(preg_replace('#(_helper)?(\.php)?$#i', '', $filename)).'_helper'; + $helper = $filepath.$filename; + + if (isset($this->_ci_helpers[$helper])) + { + continue; + } + + // Is this a helper extension request? + $ext_helper = config_item('subclass_prefix').$filename; + $ext_loaded = FALSE; + foreach ($this->_ci_helper_paths as $path) + { + if (file_exists($path.'helpers/'.$ext_helper.'.php')) + { + include_once($path.'helpers/'.$ext_helper.'.php'); + $ext_loaded = TRUE; + } + } + + // If we have loaded extensions - check if the base one is here + if ($ext_loaded === TRUE) + { + $base_helper = BASEPATH.'helpers/'.$helper.'.php'; + if ( ! file_exists($base_helper)) + { + show_error('Unable to load the requested file: helpers/'.$helper.'.php'); + } + + include_once($base_helper); + $this->_ci_helpers[$helper] = TRUE; + log_message('info', 'Helper loaded: '.$helper); + continue; + } + + // No extensions found ... try loading regular helpers and/or overrides + foreach ($this->_ci_helper_paths as $path) + { + if (file_exists($path.'helpers/'.$helper.'.php')) + { + include_once($path.'helpers/'.$helper.'.php'); + + $this->_ci_helpers[$helper] = TRUE; + log_message('info', 'Helper loaded: '.$helper); + break; + } + } + + // unable to load the helper + if ( ! isset($this->_ci_helpers[$helper])) + { + show_error('Unable to load the requested file: helpers/'.$helper.'.php'); + } + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Load Helpers + * + * An alias for the helper() method in case the developer has + * written the plural form of it. + * + * @uses CI_Loader::helper() + * @param string|string[] $helpers Helper name(s) + * @return object + */ + public function helpers($helpers = array()) + { + return $this->helper($helpers); + } + + // -------------------------------------------------------------------- + + /** + * Language Loader + * + * Loads language files. + * + * @param string|string[] $files List of language file names to load + * @param string Language name + * @return object + */ + public function language($files, $lang = '') + { + get_instance()->lang->load($files, $lang); + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Config Loader + * + * Loads a config file (an alias for CI_Config::load()). + * + * @uses CI_Config::load() + * @param string $file Configuration file name + * @param bool $use_sections Whether configuration values should be loaded into their own section + * @param bool $fail_gracefully Whether to just return FALSE or display an error message + * @return bool TRUE if the file was loaded correctly or FALSE on failure + */ + public function config($file, $use_sections = FALSE, $fail_gracefully = FALSE) + { + return get_instance()->config->load($file, $use_sections, $fail_gracefully); + } + + // -------------------------------------------------------------------- + + /** + * Driver Loader + * + * Loads a driver library. + * + * @param string|string[] $library Driver name(s) + * @param array $params Optional parameters to pass to the driver + * @param string $object_name An optional object name to assign to + * + * @return object|bool Object or FALSE on failure if $library is a string + * and $object_name is set. CI_Loader instance otherwise. + */ + public function driver($library, $params = NULL, $object_name = NULL) + { + if (is_array($library)) + { + foreach ($library as $key => $value) + { + if (is_int($key)) + { + $this->driver($value, $params); + } + else + { + $this->driver($key, $params, $value); + } + } + + return $this; + } + elseif (empty($library)) + { + return FALSE; + } + + if ( ! class_exists('CI_Driver_Library', FALSE)) + { + // We aren't instantiating an object here, just making the base class available + require BASEPATH.'libraries/Driver.php'; + } + + // We can save the loader some time since Drivers will *always* be in a subfolder, + // and typically identically named to the library + if ( ! strpos($library, '/')) + { + $library = ucfirst($library).'/'.$library; + } + + return $this->library($library, $params, $object_name); + } + + // -------------------------------------------------------------------- + + /** + * Add Package Path + * + * Prepends a parent path to the library, model, helper and config + * path arrays. + * + * @see CI_Loader::$_ci_library_paths + * @see CI_Loader::$_ci_model_paths + * @see CI_Loader::$_ci_helper_paths + * @see CI_Config::$_config_paths + * + * @param string $path Path to add + * @param bool $view_cascade (default: TRUE) + * @return object + */ + public function add_package_path($path, $view_cascade = TRUE) + { + $path = rtrim($path, '/').'/'; + + array_unshift($this->_ci_library_paths, $path); + array_unshift($this->_ci_model_paths, $path); + array_unshift($this->_ci_helper_paths, $path); + + $this->_ci_view_paths = array($path.'views/' => $view_cascade) + $this->_ci_view_paths; + + // Add config file path + $config =& $this->_ci_get_component('config'); + $config->_config_paths[] = $path; + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Get Package Paths + * + * Return a list of all package paths. + * + * @param bool $include_base Whether to include BASEPATH (default: FALSE) + * @return array + */ + public function get_package_paths($include_base = FALSE) + { + return ($include_base === TRUE) ? $this->_ci_library_paths : $this->_ci_model_paths; + } + + // -------------------------------------------------------------------- + + /** + * Remove Package Path + * + * Remove a path from the library, model, helper and/or config + * path arrays if it exists. If no path is provided, the most recently + * added path will be removed removed. + * + * @param string $path Path to remove + * @return object + */ + public function remove_package_path($path = '') + { + $config =& $this->_ci_get_component('config'); + + if ($path === '') + { + array_shift($this->_ci_library_paths); + array_shift($this->_ci_model_paths); + array_shift($this->_ci_helper_paths); + array_shift($this->_ci_view_paths); + array_pop($config->_config_paths); + } + else + { + $path = rtrim($path, '/').'/'; + foreach (array('_ci_library_paths', '_ci_model_paths', '_ci_helper_paths') as $var) + { + if (($key = array_search($path, $this->{$var})) !== FALSE) + { + unset($this->{$var}[$key]); + } + } + + if (isset($this->_ci_view_paths[$path.'views/'])) + { + unset($this->_ci_view_paths[$path.'views/']); + } + + if (($key = array_search($path, $config->_config_paths)) !== FALSE) + { + unset($config->_config_paths[$key]); + } + } + + // make sure the application default paths are still in the array + $this->_ci_library_paths = array_unique(array_merge($this->_ci_library_paths, array(APPPATH, BASEPATH))); + $this->_ci_helper_paths = array_unique(array_merge($this->_ci_helper_paths, array(APPPATH, BASEPATH))); + $this->_ci_model_paths = array_unique(array_merge($this->_ci_model_paths, array(APPPATH))); + $this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH.'views/' => TRUE)); + $config->_config_paths = array_unique(array_merge($config->_config_paths, array(APPPATH))); + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Internal CI Data Loader + * + * Used to load views and files. + * + * Variables are prefixed with _ci_ to avoid symbol collision with + * variables made available to view files. + * + * @used-by CI_Loader::view() + * @used-by CI_Loader::file() + * @param array $_ci_data Data to load + * @return object + */ + protected function _ci_load($_ci_data) + { + // Set the default data variables + foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val) + { + $$_ci_val = isset($_ci_data[$_ci_val]) ? $_ci_data[$_ci_val] : FALSE; + } + + $file_exists = FALSE; + + // Set the path to the requested file + if (is_string($_ci_path) && $_ci_path !== '') + { + $_ci_x = explode('/', $_ci_path); + $_ci_file = end($_ci_x); + } + else + { + $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION); + $_ci_file = ($_ci_ext === '') ? $_ci_view.'.php' : $_ci_view; + + foreach ($this->_ci_view_paths as $_ci_view_file => $cascade) + { + if (file_exists($_ci_view_file.$_ci_file)) + { + $_ci_path = $_ci_view_file.$_ci_file; + $file_exists = TRUE; + break; + } + + if ( ! $cascade) + { + break; + } + } + } + + if ( ! $file_exists && ! file_exists($_ci_path)) + { + show_error('Unable to load the requested file: '.$_ci_file); + } + + // This allows anything loaded using $this->load (views, files, etc.) + // to become accessible from within the Controller and Model functions. + $_ci_CI =& get_instance(); + foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var) + { + if ( ! isset($this->$_ci_key)) + { + $this->$_ci_key =& $_ci_CI->$_ci_key; + } + } + + /* + * Extract and cache variables + * + * You can either set variables using the dedicated $this->load->vars() + * function or via the second parameter of this function. We'll merge + * the two types and cache them so that views that are embedded within + * other views can have access to these variables. + */ + empty($_ci_vars) OR $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars); + extract($this->_ci_cached_vars); + + /* + * Buffer the output + * + * We buffer the output for two reasons: + * 1. Speed. You get a significant speed boost. + * 2. So that the final rendered template can be post-processed by + * the output class. Why do we need post processing? For one thing, + * in order to show the elapsed page load time. Unless we can + * intercept the cms right before it's sent to the browser and + * then stop the timer it won't be accurate. + */ + ob_start(); + + // If the PHP installation does not support short tags we'll + // do a little string replacement, changing the short tags + // to standard PHP echo statements. + if ( ! is_php('5.4') && ! ini_get('short_open_tag') && config_item('rewrite_short_tags') === TRUE) + { + echo eval('?>'.preg_replace('/;*\s*\?>/', '; ?>', str_replace(' $this->_ci_ob_level + 1) + { + ob_end_flush(); + } + else + { + $_ci_CI->output->append_output(ob_get_contents()); + @ob_end_clean(); + } + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Internal CI Library Loader + * + * @used-by CI_Loader::library() + * @uses CI_Loader::_ci_init_library() + * + * @param string $class Class name to load + * @param mixed $params Optional parameters to pass to the class constructor + * @param string $object_name Optional object name to assign to + * @return void + */ + protected function _ci_load_library($class, $params = NULL, $object_name = NULL) + { + // Get the class name, and while we're at it trim any slashes. + // The directory path can be included as part of the class name, + // but we don't want a leading slash + $class = str_replace('.php', '', trim($class, '/')); + + // Was the path included with the class name? + // We look for a slash to determine this + if (($last_slash = strrpos($class, '/')) !== FALSE) + { + // Extract the path + $subdir = substr($class, 0, ++$last_slash); + + // Get the filename from the path + $class = substr($class, $last_slash); + } + else + { + $subdir = ''; + } + + $class = ucfirst($class); + + // Is this a stock library? There are a few special conditions if so ... + if (file_exists(BASEPATH.'libraries/'.$subdir.$class.'.php')) + { + return $this->_ci_load_stock_library($class, $subdir, $params, $object_name); + } + + // Safety: Was the class already loaded by a previous call? + if (class_exists($class, FALSE)) + { + $property = $object_name; + if (empty($property)) + { + $property = strtolower($class); + isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property]; + } + + $CI =& get_instance(); + if (isset($CI->$property)) + { + log_message('debug', $class.' class already loaded. Second attempt ignored.'); + return; + } + + return $this->_ci_init_library($class, '', $params, $object_name); + } + + // Let's search for the requested library file and load it. + foreach ($this->_ci_library_paths as $path) + { + // BASEPATH has already been checked for + if ($path === BASEPATH) + { + continue; + } + + $filepath = $path.'libraries/'.$subdir.$class.'.php'; + // Does the file exist? No? Bummer... + if ( ! file_exists($filepath)) + { + continue; + } + + include_once($filepath); + return $this->_ci_init_library($class, '', $params, $object_name); + } + + // One last attempt. Maybe the library is in a subdirectory, but it wasn't specified? + if ($subdir === '') + { + return $this->_ci_load_library($class.'/'.$class, $params, $object_name); + } + + // If we got this far we were unable to find the requested class. + log_message('error', 'Unable to load the requested class: '.$class); + show_error('Unable to load the requested class: '.$class); + } + + // -------------------------------------------------------------------- + + /** + * Internal CI Stock Library Loader + * + * @used-by CI_Loader::_ci_load_library() + * @uses CI_Loader::_ci_init_library() + * + * @param string $library_name Library name to load + * @param string $file_path Path to the library filename, relative to libraries/ + * @param mixed $params Optional parameters to pass to the class constructor + * @param string $object_name Optional object name to assign to + * @return void + */ + protected function _ci_load_stock_library($library_name, $file_path, $params, $object_name) + { + $prefix = 'CI_'; + + if (class_exists($prefix.$library_name, FALSE)) + { + if (class_exists(config_item('subclass_prefix').$library_name, FALSE)) + { + $prefix = config_item('subclass_prefix'); + } + + $property = $object_name; + if (empty($property)) + { + $property = strtolower($library_name); + isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property]; + } + + $CI =& get_instance(); + if ( ! isset($CI->$property)) + { + return $this->_ci_init_library($library_name, $prefix, $params, $object_name); + } + + log_message('debug', $library_name.' class already loaded. Second attempt ignored.'); + return; + } + + $paths = $this->_ci_library_paths; + array_pop($paths); // BASEPATH + array_pop($paths); // APPPATH (needs to be the first path checked) + array_unshift($paths, APPPATH); + + foreach ($paths as $path) + { + if (file_exists($path = $path.'libraries/'.$file_path.$library_name.'.php')) + { + // Override + include_once($path); + if (class_exists($prefix.$library_name, FALSE)) + { + return $this->_ci_init_library($library_name, $prefix, $params, $object_name); + } + + log_message('debug', $path.' exists, but does not declare '.$prefix.$library_name); + } + } + + include_once(BASEPATH.'libraries/'.$file_path.$library_name.'.php'); + + // Check for extensions + $subclass = config_item('subclass_prefix').$library_name; + foreach ($paths as $path) + { + if (file_exists($path = $path.'libraries/'.$file_path.$subclass.'.php')) + { + include_once($path); + if (class_exists($subclass, FALSE)) + { + $prefix = config_item('subclass_prefix'); + break; + } + + log_message('debug', $path.' exists, but does not declare '.$subclass); + } + } + + return $this->_ci_init_library($library_name, $prefix, $params, $object_name); + } + + // -------------------------------------------------------------------- + + /** + * Internal CI Library Instantiator + * + * @used-by CI_Loader::_ci_load_stock_library() + * @used-by CI_Loader::_ci_load_library() + * + * @param string $class Class name + * @param string $prefix Class name prefix + * @param array|null|bool $config Optional configuration to pass to the class constructor: + * FALSE to skip; + * NULL to search in config paths; + * array containing configuration data + * @param string $object_name Optional object name to assign to + * @return void + */ + protected function _ci_init_library($class, $prefix, $config = FALSE, $object_name = NULL) + { + // Is there an associated config file for this class? Note: these should always be lowercase + if ($config === NULL) + { + // Fetch the config paths containing any package paths + $config_component = $this->_ci_get_component('config'); + + if (is_array($config_component->_config_paths)) + { + $found = FALSE; + foreach ($config_component->_config_paths as $path) + { + // We test for both uppercase and lowercase, for servers that + // are case-sensitive with regard to file names. Load global first, + // override with environment next + if (file_exists($path.'config/'.strtolower($class).'.php')) + { + include($path.'config/'.strtolower($class).'.php'); + $found = TRUE; + } + elseif (file_exists($path.'config/'.ucfirst(strtolower($class)).'.php')) + { + include($path.'config/'.ucfirst(strtolower($class)).'.php'); + $found = TRUE; + } + + if (file_exists($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php')) + { + include($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php'); + $found = TRUE; + } + elseif (file_exists($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php')) + { + include($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php'); + $found = TRUE; + } + + // Break on the first found configuration, thus package + // files are not overridden by default paths + if ($found === TRUE) + { + break; + } + } + } + } + + $class_name = $prefix.$class; + + // Is the class name valid? + if ( ! class_exists($class_name, FALSE)) + { + log_message('error', 'Non-existent class: '.$class_name); + show_error('Non-existent class: '.$class_name); + } + + // Set the variable name we will assign the class to + // Was a custom class name supplied? If so we'll use it + if (empty($object_name)) + { + $object_name = strtolower($class); + if (isset($this->_ci_varmap[$object_name])) + { + $object_name = $this->_ci_varmap[$object_name]; + } + } + + // Don't overwrite existing properties + $CI =& get_instance(); + if (isset($CI->$object_name)) + { + if ($CI->$object_name instanceof $class_name) + { + log_message('debug', $class_name." has already been instantiated as '".$object_name."'. Second attempt aborted."); + return; + } + + show_error("Resource '".$object_name."' already exists and is not a ".$class_name." instance."); + } + + // Save the class name and object name + $this->_ci_classes[$object_name] = $class; + + // Instantiate the class + $CI->$object_name = isset($config) + ? new $class_name($config) + : new $class_name(); + } + + // -------------------------------------------------------------------- + + /** + * CI Autoloader + * + * Loads component listed in the config/autoload.php file. + * + * @used-by CI_Loader::initialize() + * @return void + */ + protected function _ci_autoloader() + { + if (file_exists(APPPATH.'config/autoload.php')) + { + include(APPPATH.'config/autoload.php'); + } + + if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php')) + { + include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'); + } + + if ( ! isset($autoload)) + { + return; + } + + // Autoload packages + if (isset($autoload['packages'])) + { + foreach ($autoload['packages'] as $package_path) + { + $this->add_package_path($package_path); + } + } + + // Load any custom config file + if (count($autoload['config']) > 0) + { + foreach ($autoload['config'] as $val) + { + $this->config($val); + } + } + + // Autoload helpers and languages + foreach (array('helper', 'language') as $type) + { + if (isset($autoload[$type]) && count($autoload[$type]) > 0) + { + $this->$type($autoload[$type]); + } + } + + // Autoload drivers + if (isset($autoload['drivers'])) + { + $this->driver($autoload['drivers']); + } + + // Load libraries + if (isset($autoload['libraries']) && count($autoload['libraries']) > 0) + { + // Load the database driver. + if (in_array('database', $autoload['libraries'])) + { + $this->database(); + $autoload['libraries'] = array_diff($autoload['libraries'], array('database')); + } + + // Load all other libraries + $this->library($autoload['libraries']); + } + + // Autoload models + if (isset($autoload['model'])) + { + $this->model($autoload['model']); + } + } + + // -------------------------------------------------------------------- + + /** + * Prepare variables for _ci_vars, to be later extract()-ed inside views + * + * Converts objects to associative arrays and filters-out internal + * variable names (i.e. keys prefixed with '_ci_'). + * + * @param mixed $vars + * @return array + */ + protected function _ci_prepare_view_vars($vars) + { + if ( ! is_array($vars)) + { + $vars = is_object($vars) + ? get_object_vars($vars) + : array(); + } + + foreach (array_keys($vars) as $key) + { + if (strncmp($key, '_ci_', 4) === 0) + { + unset($vars[$key]); + } + } + + return $vars; + } + + // -------------------------------------------------------------------- + + /** + * CI Component getter + * + * Get a reference to a specific library or model. + * + * @param string $component Component name + * @return bool + */ + protected function &_ci_get_component($component) + { + $CI =& get_instance(); + return $CI->$component; + } +} diff --git a/api/core/HD_Model.php b/api/core/HD_Model.php index 45c8eded..93c150ca 100644 --- a/api/core/HD_Model.php +++ b/api/core/HD_Model.php @@ -1,606 +1,606 @@ -load->config("dbtable", true, true); - $dbtable = $this->config->item($app_db, "dbtable"); - if(is_array($dbtable) && in_array($table_name, $dbtable)){ - $db_group = $GLOBALS['app_db']; - } - } - - $this->set_db($db_group); - $this->set_table_name($table_name); - } - - public function set_db($db_group = 'default') - { - if(!isset(self::$dbs[$db_group])) - { - self::$dbs[$db_group] = $this->load->database($db_group, true); - } - - $this->db = self::$dbs[$db_group]; - } - - /** - * 根据app应用表设置库 - * @param $db_group - * @param $apptabs - */ - public function set_appdb($db_group, $apptabs){ - $table_name = $this->table_name; - if(is_array($apptabs) && in_array($table_name, $apptabs)){ - $this->set_db($db_group); - } - } - - public function set_table_name($table_name) - { - $this->table_name = $table_name; - } - - /** - * 表字段列表 - * @return mixed - */ - public function fields(){ - return $this->db->list_fields($this->table_name); - } - - - /** - * 添加单条数据 - * @param $data - * @return mixed - */ - public function add($data) - { - $result = $this->db->insert($this->table_name, $data); - return $this->db->insert_id() ? $this->db->insert_id() : $result; - } - - /** - * 添加多条数据 - * @param $data_array - * @return mixed - */ - public function add_batch($data_array) - { - if(is_array($data_array)) - { - return $this->db->insert_batch($this->table_name, $data_array); - } - - return false; - } - - /** - * 修改数据 - * @param $data - * @param $where - * @return mixed - */ - public function update($data, $where) - { - foreach($data as $k => $v) - { - if($v == null) { - if(strstr($k, ' = ')) { - $field = explode(' = ', $k); - $this->db->set($field[0], $field[1], FALSE); - unset($data[$k]); - } - } - } - - $result = $this->db->update($this->table_name, $data, $where); - return $this->db->affected_rows() ? $this->db->affected_rows() : $result; - } - - /** - * 修改数据2:支持order与limit - * @param $data - * @param $where - * @param $order - * @param $limit - * @return mixed - */ - public function update2($data, $where, $order = '', $limit = 0) - { - foreach($data as $k => $v) - { - if($v == null) { - if(strstr($k, ' = ')) { - $field = explode(' = ', $k); - $this->db->set($field[0], $field[1], FALSE); - unset($data[$k]); - } - } - } - - if($order){ - $this->db->order_by($order); - } - - if($limit) { - $this->db->limit($limit); - } - - $result = $this->db->update($this->table_name, $data, $where); - return $this->db->affected_rows() ? $this->db->affected_rows() : $result; - } - - /** - * 更新或插入数据 - * @param $data - * @return mixed - */ - public function replace($data) - { - if($data) - { - $result = $this->db->replace($this->table_name, $data); - return $this->db->affected_rows() ? $this->db->affected_rows() : $result; - } - - return false; - } - - /** - * 批量插入 - * @param $data - * @return CI_DB_active_record - */ - public function replace_batch($data) - { - if($data && is_array($data[0])) - { - $keys = array_keys($data[0]); - $keys = implode(',', $keys); - - $values = array(); - foreach($data as $item) - { - $item_values = array_values($item); - foreach($item_values as &$v) - { - if(!is_numeric($v)) - { - $v = addslashes($v); - $v = "'{$v}'"; - } - } - - $item_values = implode(',', $item_values); - $values[] = "({$item_values})"; - } - - $values = implode(',', $values); - $sql = "REPLACE {$this->table_name}({$keys}) VALUES {$values}"; - - return $this->db->query($sql); - } - } - - /** - * 获取单条数据 - * @param $where - * @param string $select - * @param object $obj 自定义结果对象 - * @return mixed - */ - public function get($where, $select = '', $obj = '') - { - if($select) - { - $this->db->select($select, false); - } - - if($obj && file_exists($class = COMMPATH.'libraries/entity/'.ucfirst($obj).'.php')) - { - require_once $class; - - if (class_exists(ucfirst($obj))) - { - return $this->db->get_where($this->table_name, $where)->custom_row_object(0, $obj); - } - } - - return $this->db->get_where($this->table_name, $where)->row_array(); - } - - - /** - * 获取多条数据集 - * @param array $where - * @param string $order - * @param int $page - * @param int $page_size - * @param string $select - * @param object obj - * @return mixed - */ - public function select($where = array(), $order = '', $page = 0, $page_size = 20, $select = '', $obj = '') - { - if($select) - { - $this->db->select($select, false); - } - - if($where) - { - $this->db->where($where); - } - - if($order) - { - $this->db->order_by($order); - } - - if($page) - { - $offset = ($page - 1) * $page_size; - $limit = $page_size; - } - else - { - $offset = null; - $limit = null; - } - $this->db->from($this->table_name); - $this->db->limit($limit, $offset); - $query = $this->db->get(); - $result = $query ? $query->result_array() : []; - if($obj && file_exists($class = APPPATH.'libraries/entity/'.ucfirst($obj).'.php')) - { - require_once $class; - if(class_exists($obj)) - { - $result = $this->db->get($this->table_name, $limit, $offset)->custom_result_object($obj); - } - } - return $result; - } - - /** - * @param $groupby - * @param array $where - * @param string $order - * @param int $page - * @param int $page_size - * @param string $select - * @param string $obj - * @return mixed - */ - public function select_groupby($groupby, $where = array(), $order = '', $page = 0, $page_size = 20, $select = '', $obj = ''){ - $this->db->group_by($groupby); - - return $this->select($where, $order, $page, $page_size, $select, $obj); - } - - /** - * 获取最大值 - * @param $field - * @param array $where - * @return mixed - */ - public function max($field, $where=array()) - { - if($where) - { - $this->db->where($where); - } - - if(is_array($field)) - { - foreach($field as $v) - { - $this->db->select_max($v); - } - } - else - { - $this->db->select_max($field); - } - - return $this->db->get($this->table_name)->row_array(); - } - - /** - * 删除 - * @param array $where - * @return mixed - */ - public function delete($where = array()) - { - $result = $this->db->delete($this->table_name, $where); - return $this->db->affected_rows() ? $this->db->affected_rows() : $result; - } - - /** - * 将获取的数据集组装成map类型 - * @param string $map_key - * @param string $map_value - * @param array $where - * @param string $order - * @param int $page - * @param int $page_size - * @param string $select - * @return array - */ - public function map($map_key = 'id', $map_value = '', $where = array(), $order = '', $page = 0, $page_size = 20, $select = '') - { - $map = array(); - $list = $this->select($where, $order, $page, $page_size, $select); - - if($list) - { - foreach($list as $item) - { - //指定列, map格式为{k:v} - if($map_value) - { - //指定列存在取具体值,格式为{k:v},指定列不存在取全部列,格式为{k:{k1:v1,k2:v2}} - $map[$item[$map_key]] = null !== $item[$map_value] ? $item[$map_value] : $item; - } - else - {//不指定列,表示一个k对应多个v,格式为{k:[{k1:v1,k2:v2},{k1:v1,k2:v2}]} - $map[$item[$map_key]][] = $item; - } - } - } - - return $map; - } - - /** - * 获取总条数 - * @param array $where - * @param string $distinct - * @return mixed - */ - public function count($where = array(), $distinct = '') - { - if($where) - { - $this->db->where($where); - } - - if($distinct) - { - $this->db->distinct(); - $this->db->select($distinct, false); - } - - return $this->db->count_all_results($this->table_name); - - } - - /** - * 获取某字段总和 - * @param $field - * @param array $where - * @return mixed - */ - public function sum($field, $where = array()) - { - if(is_array($field)) - { - foreach($field as $v) - { - $this->select_sum($v); - } - } - else - { - $this->db->select_sum($field); - } - - if($where) - { - $this->db->where($where); - } - - return $this->db->get($this->table_name)->row_array(); - } - - /** - * 对方法的某个结果集做mc缓存【结果集为非对象数组】 - * @param $func - * @param array $param - * @param string $ttl - * @return mixed - */ - public function mc_cache($func, $param = array(), $ttl = 0, $skey = '') - { - if(IF_MC_CACHE) - { - $cache = & load_cache('mc'); - $cache_key = MC_CACHE_PREFIX.md5(get_called_class().'.'.$func.json_encode($param)); - $ttl = is_numeric($ttl) ? $ttl : $this->mc_cache_expire; - $result = $cache->get($cache_key); - - if($result === FALSE ) - { - $result = call_user_func_array(array($this, $func), $param); - $cache->save($cache_key, $result, $ttl); - $this->add_cache_key(get_called_class(), $func, 'mc', $cache_key, $ttl, $skey); - } - - return $result; - } - - return call_user_func_array(array($this, $func), $param); - } - - /** - * 删除某方法某个结果集的mc缓存【结果集为非对象数组】 - * @param $func - * @param array $param - * @return mixed - */ - public function un_mc_cache($func, $param = array()) - { - if(IF_MC_CACHE) - { - $cache = & load_cache('mc'); - $cache_key = MC_CACHE_PREFIX.md5(get_called_class().'.'.$func.json_encode($param)); - return $cache->delete($cache_key); - } - - return false; - } - - /** - * 对方法的某个结果集做redis缓存【结果集为非对象数组】 - * @param $func - * @param array $param - * @param bool $force - * @return array|mixed - */ - public function redis_cache($func,$param = array()) - { - if(IF_REDIS_CACHE) - { - $cache = & load_cache('redis'); - $cache_key = REDIS_CACHE_PREFIX.md5(get_called_class().'.'.$func.json_encode($param)); - - if(!$result = $cache->get($cache_key)) - { - $result = call_user_func_array(array($this, $func), $param); - $cache->save($cache_key, $result); - $this->add_cache_key(get_called_class(), $func, 'redis', $cache_key); - } - - return $result; - } - - return call_user_func_array(array($this, $func), $param); - } - - /** - * 删除某方法某个结果集的redis缓存【结果集为非对象数组】 - * @param $func - * @param array $param - * @return mixed - */ - public function un_redis_cache($func, $param = array()) - { - if(IF_REDIS_CACHE) - { - $cache = & load_cache('redis'); - $cache_key = REDIS_CACHE_PREFIX.md5(get_called_class().'.'.$func.json_encode($param)); - return $cache->delete($cache_key); - } - - return false; - } - - /** - * 对某方法某个结果集的file缓存【结果集为非对象数组】 - * @param $func - * @param array $param - * @return mixed - */ - public function file_cache($func, $param = array()) - { - if(IF_FILE_CACHE) - { - $cache = & load_cache('file'); - $cache_key = FILE_CACHE_PREFIX.get_called_class().'.'.$func.'_'.md5($param); - - if(!$result = $cache->get($cache_key)) - { - $result = call_user_func_array(array($this, $func), $param); - $cache->save($cache_key, $result, $this->file_cache_expire); - $this->add_cache_key(get_called_class(), $func, 'file', $cache_key); - } - - return $result; - } - - return call_user_func_array(array($this, $func), $param); - } - - /** - * 删除某方法某个结果集的file缓存【结果集为非对象数组】 - * @param $func - * @param array $param - * @return mixed - */ - public function un_file_cache($func, $param =array()) - { - if(IF_FILE_CACHE) - { - $cache = & load_cache('file'); - $cache_key = FILE_CACHE_PREFIX.get_called_class().'.'.$func.'_'.md5($param); - return $cache->delete($cache_key); - } - } - - /** - * 清除cache - * @param $method - * @param $type - * @return bool - */ - public function del_cache($method, $type, $skey = '') - { - $cache = & load_cache($type); - $db = $this->load->database('default', true); - $where = $skey ? array("skey like '{$skey}'" => null) : array('class' => get_called_class(), 'method' => $method, 'cache_type' => $type); - $db->where($where); - - $cache_list = $db->get('hd_cache_key')->result_array(); - - if($cache_list) - { - foreach($cache_list as $v) - { - $cache->delete($v['cache_key']); - } - } - - $db->delete('hd_cache_key', $where); - return true; - } - - private function add_cache_key($class, $method, $type, $key, $expire_time = 0, $skey = '') - { - $db = $this->load->database('default', true); - - $data = array( - 'class' => $class, - 'method' => $method, - 'cache_type' => $type, - 'cache_key' => $key, - 'expire_time' => time() + $expire_time, - 'skey' => $skey ? $skey : '' - ); - - $result = $db->insert('hd_cache_key', $data); - return $this->db->insert_id() ? $this->db->insert_id() : $result; - } -} - +load->config("dbtable", true, true); + $dbtable = $this->config->item($app_db, "dbtable"); + if(is_array($dbtable) && in_array($table_name, $dbtable)){ + $db_group = $GLOBALS['app_db']; + } + } + + $this->set_db($db_group); + $this->set_table_name($table_name); + } + + public function set_db($db_group = 'default') + { + if(!isset(self::$dbs[$db_group])) + { + self::$dbs[$db_group] = $this->load->database($db_group, true); + } + + $this->db = self::$dbs[$db_group]; + } + + /** + * 根据app应用表设置库 + * @param $db_group + * @param $apptabs + */ + public function set_appdb($db_group, $apptabs){ + $table_name = $this->table_name; + if(is_array($apptabs) && in_array($table_name, $apptabs)){ + $this->set_db($db_group); + } + } + + public function set_table_name($table_name) + { + $this->table_name = $table_name; + } + + /** + * 表字段列表 + * @return mixed + */ + public function fields(){ + return $this->db->list_fields($this->table_name); + } + + + /** + * 添加单条数据 + * @param $data + * @return mixed + */ + public function add($data) + { + $result = $this->db->insert($this->table_name, $data); + return $this->db->insert_id() ? $this->db->insert_id() : $result; + } + + /** + * 添加多条数据 + * @param $data_array + * @return mixed + */ + public function add_batch($data_array) + { + if(is_array($data_array)) + { + return $this->db->insert_batch($this->table_name, $data_array); + } + + return false; + } + + /** + * 修改数据 + * @param $data + * @param $where + * @return mixed + */ + public function update($data, $where) + { + foreach($data as $k => $v) + { + if($v == null) { + if(strstr($k, ' = ')) { + $field = explode(' = ', $k); + $this->db->set($field[0], $field[1], FALSE); + unset($data[$k]); + } + } + } + + $result = $this->db->update($this->table_name, $data, $where); + return $this->db->affected_rows() ? $this->db->affected_rows() : $result; + } + + /** + * 修改数据2:支持order与limit + * @param $data + * @param $where + * @param $order + * @param $limit + * @return mixed + */ + public function update2($data, $where, $order = '', $limit = 0) + { + foreach($data as $k => $v) + { + if($v == null) { + if(strstr($k, ' = ')) { + $field = explode(' = ', $k); + $this->db->set($field[0], $field[1], FALSE); + unset($data[$k]); + } + } + } + + if($order){ + $this->db->order_by($order); + } + + if($limit) { + $this->db->limit($limit); + } + + $result = $this->db->update($this->table_name, $data, $where); + return $this->db->affected_rows() ? $this->db->affected_rows() : $result; + } + + /** + * 更新或插入数据 + * @param $data + * @return mixed + */ + public function replace($data) + { + if($data) + { + $result = $this->db->replace($this->table_name, $data); + return $this->db->affected_rows() ? $this->db->affected_rows() : $result; + } + + return false; + } + + /** + * 批量插入 + * @param $data + * @return CI_DB_active_record + */ + public function replace_batch($data) + { + if($data && is_array($data[0])) + { + $keys = array_keys($data[0]); + $keys = implode(',', $keys); + + $values = array(); + foreach($data as $item) + { + $item_values = array_values($item); + foreach($item_values as &$v) + { + if(!is_numeric($v)) + { + $v = addslashes($v); + $v = "'{$v}'"; + } + } + + $item_values = implode(',', $item_values); + $values[] = "({$item_values})"; + } + + $values = implode(',', $values); + $sql = "REPLACE {$this->table_name}({$keys}) VALUES {$values}"; + + return $this->db->query($sql); + } + } + + /** + * 获取单条数据 + * @param $where + * @param string $select + * @param object $obj 自定义结果对象 + * @return mixed + */ + public function get($where, $select = '', $obj = '') + { + if($select) + { + $this->db->select($select, false); + } + + if($obj && file_exists($class = COMMPATH.'libraries/entity/'.ucfirst($obj).'.php')) + { + require_once $class; + + if (class_exists(ucfirst($obj))) + { + return $this->db->get_where($this->table_name, $where)->custom_row_object(0, $obj); + } + } + + return $this->db->get_where($this->table_name, $where)->row_array(); + } + + + /** + * 获取多条数据集 + * @param array $where + * @param string $order + * @param int $page + * @param int $page_size + * @param string $select + * @param object obj + * @return mixed + */ + public function select($where = array(), $order = '', $page = 0, $page_size = 20, $select = '', $obj = '') + { + if($select) + { + $this->db->select($select, false); + } + + if($where) + { + $this->db->where($where); + } + + if($order) + { + $this->db->order_by($order); + } + + if($page) + { + $offset = ($page - 1) * $page_size; + $limit = $page_size; + } + else + { + $offset = null; + $limit = null; + } + $this->db->from($this->table_name); + $this->db->limit($limit, $offset); + $query = $this->db->get(); + $result = $query ? $query->result_array() : []; + if($obj && file_exists($class = APPPATH.'libraries/entity/'.ucfirst($obj).'.php')) + { + require_once $class; + if(class_exists($obj)) + { + $result = $this->db->get($this->table_name, $limit, $offset)->custom_result_object($obj); + } + } + return $result; + } + + /** + * @param $groupby + * @param array $where + * @param string $order + * @param int $page + * @param int $page_size + * @param string $select + * @param string $obj + * @return mixed + */ + public function select_groupby($groupby, $where = array(), $order = '', $page = 0, $page_size = 20, $select = '', $obj = ''){ + $this->db->group_by($groupby); + + return $this->select($where, $order, $page, $page_size, $select, $obj); + } + + /** + * 获取最大值 + * @param $field + * @param array $where + * @return mixed + */ + public function max($field, $where=array()) + { + if($where) + { + $this->db->where($where); + } + + if(is_array($field)) + { + foreach($field as $v) + { + $this->db->select_max($v); + } + } + else + { + $this->db->select_max($field); + } + + return $this->db->get($this->table_name)->row_array(); + } + + /** + * 删除 + * @param array $where + * @return mixed + */ + public function delete($where = array()) + { + $result = $this->db->delete($this->table_name, $where); + return $this->db->affected_rows() ? $this->db->affected_rows() : $result; + } + + /** + * 将获取的数据集组装成map类型 + * @param string $map_key + * @param string $map_value + * @param array $where + * @param string $order + * @param int $page + * @param int $page_size + * @param string $select + * @return array + */ + public function map($map_key = 'id', $map_value = '', $where = array(), $order = '', $page = 0, $page_size = 20, $select = '') + { + $map = array(); + $list = $this->select($where, $order, $page, $page_size, $select); + + if($list) + { + foreach($list as $item) + { + //指定列, map格式为{k:v} + if($map_value) + { + //指定列存在取具体值,格式为{k:v},指定列不存在取全部列,格式为{k:{k1:v1,k2:v2}} + $map[$item[$map_key]] = null !== $item[$map_value] ? $item[$map_value] : $item; + } + else + {//不指定列,表示一个k对应多个v,格式为{k:[{k1:v1,k2:v2},{k1:v1,k2:v2}]} + $map[$item[$map_key]][] = $item; + } + } + } + + return $map; + } + + /** + * 获取总条数 + * @param array $where + * @param string $distinct + * @return mixed + */ + public function count($where = array(), $distinct = '') + { + if($where) + { + $this->db->where($where); + } + + if($distinct) + { + $this->db->distinct(); + $this->db->select($distinct, false); + } + + return $this->db->count_all_results($this->table_name); + + } + + /** + * 获取某字段总和 + * @param $field + * @param array $where + * @return mixed + */ + public function sum($field, $where = array()) + { + if(is_array($field)) + { + foreach($field as $v) + { + $this->select_sum($v); + } + } + else + { + $this->db->select_sum($field); + } + + if($where) + { + $this->db->where($where); + } + + return $this->db->get($this->table_name)->row_array(); + } + + /** + * 对方法的某个结果集做mc缓存【结果集为非对象数组】 + * @param $func + * @param array $param + * @param string $ttl + * @return mixed + */ + public function mc_cache($func, $param = array(), $ttl = 0, $skey = '') + { + if(IF_MC_CACHE) + { + $cache = & load_cache('mc'); + $cache_key = MC_CACHE_PREFIX.md5(get_called_class().'.'.$func.json_encode($param)); + $ttl = is_numeric($ttl) ? $ttl : $this->mc_cache_expire; + $result = $cache->get($cache_key); + + if($result === FALSE ) + { + $result = call_user_func_array(array($this, $func), $param); + $cache->save($cache_key, $result, $ttl); + $this->add_cache_key(get_called_class(), $func, 'mc', $cache_key, $ttl, $skey); + } + + return $result; + } + + return call_user_func_array(array($this, $func), $param); + } + + /** + * 删除某方法某个结果集的mc缓存【结果集为非对象数组】 + * @param $func + * @param array $param + * @return mixed + */ + public function un_mc_cache($func, $param = array()) + { + if(IF_MC_CACHE) + { + $cache = & load_cache('mc'); + $cache_key = MC_CACHE_PREFIX.md5(get_called_class().'.'.$func.json_encode($param)); + return $cache->delete($cache_key); + } + + return false; + } + + /** + * 对方法的某个结果集做redis缓存【结果集为非对象数组】 + * @param $func + * @param array $param + * @param bool $force + * @return array|mixed + */ + public function redis_cache($func,$param = array()) + { + if(IF_REDIS_CACHE) + { + $cache = & load_cache('redis'); + $cache_key = REDIS_CACHE_PREFIX.md5(get_called_class().'.'.$func.json_encode($param)); + + if(!$result = $cache->get($cache_key)) + { + $result = call_user_func_array(array($this, $func), $param); + $cache->save($cache_key, $result); + $this->add_cache_key(get_called_class(), $func, 'redis', $cache_key); + } + + return $result; + } + + return call_user_func_array(array($this, $func), $param); + } + + /** + * 删除某方法某个结果集的redis缓存【结果集为非对象数组】 + * @param $func + * @param array $param + * @return mixed + */ + public function un_redis_cache($func, $param = array()) + { + if(IF_REDIS_CACHE) + { + $cache = & load_cache('redis'); + $cache_key = REDIS_CACHE_PREFIX.md5(get_called_class().'.'.$func.json_encode($param)); + return $cache->delete($cache_key); + } + + return false; + } + + /** + * 对某方法某个结果集的file缓存【结果集为非对象数组】 + * @param $func + * @param array $param + * @return mixed + */ + public function file_cache($func, $param = array()) + { + if(IF_FILE_CACHE) + { + $cache = & load_cache('file'); + $cache_key = FILE_CACHE_PREFIX.get_called_class().'.'.$func.'_'.md5($param); + + if(!$result = $cache->get($cache_key)) + { + $result = call_user_func_array(array($this, $func), $param); + $cache->save($cache_key, $result, $this->file_cache_expire); + $this->add_cache_key(get_called_class(), $func, 'file', $cache_key); + } + + return $result; + } + + return call_user_func_array(array($this, $func), $param); + } + + /** + * 删除某方法某个结果集的file缓存【结果集为非对象数组】 + * @param $func + * @param array $param + * @return mixed + */ + public function un_file_cache($func, $param =array()) + { + if(IF_FILE_CACHE) + { + $cache = & load_cache('file'); + $cache_key = FILE_CACHE_PREFIX.get_called_class().'.'.$func.'_'.md5($param); + return $cache->delete($cache_key); + } + } + + /** + * 清除cache + * @param $method + * @param $type + * @return bool + */ + public function del_cache($method, $type, $skey = '') + { + $cache = & load_cache($type); + $db = $this->load->database('default', true); + $where = $skey ? array("skey like '{$skey}'" => null) : array('class' => get_called_class(), 'method' => $method, 'cache_type' => $type); + $db->where($where); + + $cache_list = $db->get('hd_cache_key')->result_array(); + + if($cache_list) + { + foreach($cache_list as $v) + { + $cache->delete($v['cache_key']); + } + } + + $db->delete('hd_cache_key', $where); + return true; + } + + private function add_cache_key($class, $method, $type, $key, $expire_time = 0, $skey = '') + { + $db = $this->load->database('default', true); + + $data = array( + 'class' => $class, + 'method' => $method, + 'cache_type' => $type, + 'cache_key' => $key, + 'expire_time' => time() + $expire_time, + 'skey' => $skey ? $skey : '' + ); + + $result = $db->insert('hd_cache_key', $data); + return $this->db->insert_id() ? $this->db->insert_id() : $result; + } +} + diff --git a/api/core/HD_Service.php b/api/core/HD_Service.php index 9bb29367..3d1c1ace 100644 --- a/api/core/HD_Service.php +++ b/api/core/HD_Service.php @@ -1,32 +1,32 @@ -CI = & get_instance(); - $this->log_dir = lcfirst(get_class($this)); - } - - function __get($name){ - if('_model' === substr($name, -6)){ - return $this->CI->$name; - } elseif('_service' === substr($name, -8)){ - return $this->CI->$name; - } elseif('load' == $name){ - return $this->CI->load; - } elseif('config' == $name){ - return $this->CI->config; - } elseif(isset($this->CI->$name)){ - return $this->CI->$name; - } - return null; - } +CI = & get_instance(); + $this->log_dir = lcfirst(get_class($this)); + } + + function __get($name){ + if('_model' === substr($name, -6)){ + return $this->CI->$name; + } elseif('_service' === substr($name, -8)){ + return $this->CI->$name; + } elseif('load' == $name){ + return $this->CI->load; + } elseif('config' == $name){ + return $this->CI->config; + } elseif(isset($this->CI->$name)){ + return $this->CI->$name; + } + return null; + } } \ No newline at end of file diff --git a/api/core/index.html b/api/core/index.html index b48b4908..b702fbc3 100644 --- a/api/core/index.html +++ b/api/core/index.html @@ -1,11 +1,11 @@ - - - - 403 Forbidden - - - -

Directory access is forbidden.

- - - + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/api/helpers/format_helper.php b/api/helpers/format_helper.php index c95b3d2a..4cb894a4 100644 --- a/api/helpers/format_helper.php +++ b/api/helpers/format_helper.php @@ -1,101 +1,101 @@ - $data); - is_numeric($data) && $data = array('count' => $data); - is_string($data) && $data = array('result' => $data); - - if(is_array($data) && array_search(current($data), $data) === 0) - { - $data = array('list' => $data); - } - - if(empty($data)) - { - $data = array('result' => array()); - } - - return array('errCode' => '0', 'data' => $data); - } -} - -/** - * 过滤空字符 - * @param $array - * @return array - */ -if(!function_exists('_clean')) -{ - function _clean($array) - { - if(!is_array($array)) - { - return $array; - } - - foreach($array as $k => $v) - { - if($v === '' || $v === null || $v === array()) - { - unset($array[$k]); - } - elseif(is_array($v)) - { - $array[$k] = _clean($v); - } - } - - return $array; - } -} - -/** - * API 输出 - * @param $result - * @param bool $ifgzip - */ - -if(!function_exists('print_result')) -{ - function print_result($result, $ifgzip = false) - { - if(!isset($result['errCode'])) - { - $data = info_format($result); - } - else - { - $data = $result; - } - - if($ifgzip) - { - header('Content-Type: application/json'); - header('Content-Encoding: gzip'); - echo gzencode(json_encode($data, JSON_UNESCAPED_UNICODE), 6); - exit; - } - else - { - $result = json_encode($data, JSON_UNESCAPED_UNICODE); - echo $result; - exit; - } - } -} - - - - + $data); + is_numeric($data) && $data = array('count' => $data); + is_string($data) && $data = array('result' => $data); + + if(is_array($data) && array_search(current($data), $data) === 0) + { + $data = array('list' => $data); + } + + if(empty($data)) + { + $data = array('result' => array()); + } + + return array('errCode' => '0', 'data' => $data); + } +} + +/** + * 过滤空字符 + * @param $array + * @return array + */ +if(!function_exists('_clean')) +{ + function _clean($array) + { + if(!is_array($array)) + { + return $array; + } + + foreach($array as $k => $v) + { + if($v === '' || $v === null || $v === array()) + { + unset($array[$k]); + } + elseif(is_array($v)) + { + $array[$k] = _clean($v); + } + } + + return $array; + } +} + +/** + * API 输出 + * @param $result + * @param bool $ifgzip + */ + +if(!function_exists('print_result')) +{ + function print_result($result, $ifgzip = false) + { + if(!isset($result['errCode'])) + { + $data = info_format($result); + } + else + { + $data = $result; + } + + if($ifgzip) + { + header('Content-Type: application/json'); + header('Content-Encoding: gzip'); + echo gzencode(json_encode($data, JSON_UNESCAPED_UNICODE), 6); + exit; + } + else + { + $result = json_encode($data, JSON_UNESCAPED_UNICODE); + echo $result; + exit; + } + } +} + + + + diff --git a/api/helpers/image_helper.php b/api/helpers/image_helper.php index ee887e0e..7c49f41f 100644 --- a/api/helpers/image_helper.php +++ b/api/helpers/image_helper.php @@ -1,46 +1,46 @@ -load->library('qiniu'); - foreach ($srcs as $key => $val) - { - $filename = $ci->qiniu->getFileName($val); - $filename = $path . date('Y/m').'/'.$filename; - $file = $ci->qiniu->fetch($val, $filename); - - if (!$file) - { - $urls[$key] = ''; - continue; - } - else - { - $urls[$key] = $file['file']; - } - } - } - - return $urls; - } +load->library('qiniu'); + foreach ($srcs as $key => $val) + { + $filename = $ci->qiniu->getFileName($val); + $filename = $path . date('Y/m').'/'.$filename; + $file = $ci->qiniu->fetch($val, $filename); + + if (!$file) + { + $urls[$key] = ''; + continue; + } + else + { + $urls[$key] = $file['file']; + } + } + } + + return $urls; + } } \ No newline at end of file diff --git a/api/helpers/index.html b/api/helpers/index.html index b48b4908..b702fbc3 100644 --- a/api/helpers/index.html +++ b/api/helpers/index.html @@ -1,11 +1,11 @@ - - - - 403 Forbidden - - - -

Directory access is forbidden.

- - - + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/api/hooks/index.html b/api/hooks/index.html index b48b4908..b702fbc3 100644 --- a/api/hooks/index.html +++ b/api/hooks/index.html @@ -1,11 +1,11 @@ - - - - 403 Forbidden - - - -

Directory access is forbidden.

- - - + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/api/index.html b/api/index.html index b48b4908..b702fbc3 100644 --- a/api/index.html +++ b/api/index.html @@ -1,11 +1,11 @@ - - - - 403 Forbidden - - - -

Directory access is forbidden.

- - - + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/api/language/english/index.html b/api/language/english/index.html index b48b4908..b702fbc3 100644 --- a/api/language/english/index.html +++ b/api/language/english/index.html @@ -1,11 +1,11 @@ - - - - 403 Forbidden - - - -

Directory access is forbidden.

- - - + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/api/language/index.html b/api/language/index.html index b48b4908..b702fbc3 100644 --- a/api/language/index.html +++ b/api/language/index.html @@ -1,11 +1,11 @@ - - - - 403 Forbidden - - - -

Directory access is forbidden.

- - - + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/api/language/zh/error_lang.php b/api/language/zh/error_lang.php index c97c5320..c69f7263 100644 --- a/api/language/zh/error_lang.php +++ b/api/language/zh/error_lang.php @@ -1,23 +1,23 @@ - 'smtp.163.com', + 'port' => '25', + 'username' => '18350451617@163.com', + 'pwd' => 'lin2821808', + 'fromname' => '小鱼网', + ); + + public function __construct($params = array()) + { + $params && $this->init($params); + } + + /** + * 初始化 + * @param array $params 未设置默认server配置mail数组第一项 + * @param boolean $debug + */ + public function init($params = array(), $debug = false){ + + if($params){ + $this->host = $params['host']; + $this->port = $params['port']; + $this->username = $params['username']; + $this->pwd = $params['pwd']; + $this->fromname = $params['fromname']; + $this->debug = $debug; + } else { + $params = $this->config; + $this->host = $params['host']; + $this->port = $params['port']; + $this->username = $params['username']; + $this->pwd = $params['pwd']; + $this->fromname = $params['fromname']; + } + + $mailer = new PHPMailer(); + /* Server Settings */ + $mailer->IsSMTP(); // 使用 SMTP 方式发送邮件 + $mailer->SMTPAuth = true; //启用SMTP认证 + $mailer->Host = $this->host; //SMTP服务器 以163邮箱为例子 + $mailer->Port = $this->port; //邮件发送端口,163的是25,设置ssl连接smtp服务器的远程服务器端口号465 +// $mailer->SMTPSecure = 'ssl'; + $mailer->SMTPDebug = $this->debug;// 是否启用smtp的debug进行调试 开发环境建议开启 生产环境注释掉即可 默认关闭debug调试模式 + /* Account Settings */ + $mailer->Username = $this->username; + $mailer->Password = $this->pwd; + $mailer->From = $this->username; + /* Content Setting */ + $mailer->IsHTML(true); //支持html格式内容 + $mailer->CharSet = 'UTF-8'; + + $this->mailer = $mailer; + } + + /** + * 添加附件 + * @param $path (文件路径 + * @param string $name (指定名称 + */ + public function add_attachment($path, $name=''){ + $this->mailer->AddAttachment($path, $name); + } + + /** + * 发送邮件 + * @param $email (接收邮件地址 + * @param $title (邮件标题 + * @param $content (邮件内容 + * @return bool + */ + public function send($email, $title, $content){ + $this->mailer->FromName = $this->fromname; + $this->mailer->addAddress($email); + $this->mailer->Subject = $title; + $this->mailer->Body = $content; + + return (bool)$this->mailer->send(); // 发送邮件 + } + + public function error(){ + var_dump($this->mailer->ErrorInfo); + } +} \ No newline at end of file diff --git a/api/libraries/index.html b/api/libraries/index.html index b48b4908..b702fbc3 100644 --- a/api/libraries/index.html +++ b/api/libraries/index.html @@ -1,11 +1,11 @@ - - - - 403 Forbidden - - - -

Directory access is forbidden.

- - - + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/api/models/index.html b/api/models/index.html index b48b4908..b702fbc3 100644 --- a/api/models/index.html +++ b/api/models/index.html @@ -1,11 +1,11 @@ - - - - 403 Forbidden - - - -

Directory access is forbidden.

- - - + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/api/third_party/PHPMailer.php b/api/third_party/PHPMailer.php new file mode 100644 index 00000000..77d7e595 --- /dev/null +++ b/api/third_party/PHPMailer.php @@ -0,0 +1,1721 @@ +exceptions=($exceptions==true); + } + public function IsHTML($ishtml=true){ + if($ishtml){ + $this->ContentType='text/html'; + }else{ + $this->ContentType='text/plain'; + } + } + public function IsSMTP(){ + $this->Mailer='SMTP'; + } + public function IsMail(){ + $this->Mailer='mail'; + } + public function IsSendmail(){ + if(!stristr(ini_get('sendmail_path'),'sendmail')){ + $this->Sendmail='/var/qmail/bin/sendmail'; + } + $this->Mailer='sendmail'; + } + public function IsQmail(){ + if(stristr(ini_get('sendmail_path'),'qmail')){ + $this->Sendmail='/var/qmail/bin/sendmail'; + } + $this->Mailer='sendmail'; + } + public function AddAddress($address,$name=''){ + return $this->AddAnAddress('to',$address,$name); + } + public function AddCC($address,$name=''){ + return $this->AddAnAddress('cc',$address,$name); + } + public function AddBCC($address,$name=''){ + return $this->AddAnAddress('bcc',$address,$name); + } + public function AddReplyTo($address,$name=''){ + return $this->AddAnAddress('ReplyTo',$address,$name); + } + private function AddAnAddress($kind,$address,$name=''){ + if(!preg_match('/^(to|cc|bcc|ReplyTo)$/',$kind)){ + if($this->exceptions){ + throw new phpmailerException('Invalid recipient array: '.$kind); + } + return false; + } + $address=trim($address); + $name=trim(preg_replace('/[\r\n]+/','',$name)); + if(!self::ValidateAddress($address)){ + $this->SetError($this->Lang('invalid_address').': '.$address); + if($this->exceptions){ + throw new phpmailerException($this->Lang('invalid_address').': '.$address); + } + return false; + } + if($kind!='ReplyTo'){ + if(!isset($this->all_recipients[strtolower($address)])){ + array_push($this->$kind,array($address,$name)); + $this->all_recipients[strtolower($address)]=true; + return true; + } + }else{ + if(!array_key_exists(strtolower($address),$this->ReplyTo)){ + $this->ReplyTo[strtolower($address)]=array($address,$name); + return true; + } + } + return false; + } + public function SetFrom($address,$name='',$auto=1){ + $address=trim($address); + $name=trim(preg_replace('/[\r\n]+/','',$name)); + if(!self::ValidateAddress($address)){ + $this->SetError($this->Lang('invalid_address').': '.$address); + if($this->exceptions){ + throw new phpmailerException($this->Lang('invalid_address').': '.$address); + } + return false; + } + + $this->From=$address; + $this->FromName=$name; + if($auto){ + if(empty($this->ReplyTo)){ + $this->AddAnAddress('ReplyTo',$address,$name); + } + if(empty($this->Sender)){ + $this->Sender=$address; + } + } + return true; + } + public static function ValidateAddress($address){ + if(function_exists('filter_var')){ + if(filter_var($address,FILTER_VALIDATE_EMAIL)===FALSE){ + return false; + }else{ + return true; + } + }else{ + return preg_match('/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!\.)){0,61}[a-zA-Z0-9_-]?\.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!$)){0,61}[a-zA-Z0-9_]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/',$address); + } + } + + public function Send(){ + try{ + if((count($this->to)+count($this->cc)+count($this->bcc))<1){ + throw new phpmailerException($this->Lang('provide_address'),self::STOP_CRITICAL); + } + if(!empty($this->AltBody)){ + $this->ContentType='multipart/alternative'; + } + $this->error_count=0; + $this->SetMessageType(); + $header=$this->CreateHeader(); + $body=$this->CreateBody(); + if(empty($this->Body)){ + throw new phpmailerException($this->Lang('empty_message'),self::STOP_CRITICAL); + } + if($this->DKIM_domain&&$this->DKIM_private){ + $header_dkim=$this->DKIM_Add($header,$this->Subject,$body);$header=str_replace("\r\n","\n",$header_dkim).$header; + } + switch($this->Mailer){ + case 'sendmail': + return $this->SendmailSend($header,$body); + case 'SMTP': + return $this->SmtpSend($header,$body); + default: + return $this->MailSend($header,$body); + } + }catch(phpmailerException $e){ + $this->SetError($e->getMessage()); + if($this->exceptions){ + throw $e; + } + return false; + } + } + + protected function SendmailSend($header,$body){ + if($this->Sender!=''){ + $sendmail=sprintf("%s -oi -f %s -t",escapeshellcmd($this->Sendmail),escapeshellarg($this->Sender)); + }else{ + $sendmail=sprintf("%s -oi -t",escapeshellcmd($this->Sendmail)); + }if($this->SingleTo===true){ + foreach($this->SingleToArray as $key=>$val){ + if(!@$mail=popen($sendmail,'w')){ + throw new phpmailerException($this->Lang('execute').$this->Sendmail,self::STOP_CRITICAL); + } + fputs($mail,"To: ".$val."\n"); + fputs($mail,$header); + fputs($mail,$body); + $result=pclose($mail); + $isSent=($result==0)?1:0; + $this->doCallback($isSent,$val,$this->cc,$this->bcc,$this->Subject,$body); + if($result!=0){ + throw new phpmailerException($this->Lang('execute').$this->Sendmail,self::STOP_CRITICAL); + } + } + }else{ + if(!@$mail=popen($sendmail,'w')){ + throw new phpmailerException($this->Lang('execute').$this->Sendmail,self::STOP_CRITICAL); + } + fputs($mail,$header); + fputs($mail,$body); + $result=pclose($mail); + $isSent=($result==0)?1:0; + $this->doCallback($isSent,$this->to,$this->cc,$this->bcc,$this->Subject,$body); + if($result!=0){ + throw new phpmailerException($this->Lang('execute').$this->Sendmail,self::STOP_CRITICAL); + } + } + return true; + } + protected function MailSend($header,$body){ + $toArr=array(); + foreach($this->to as $t){ + $toArr[]=$this->AddrFormat($t); + } + $to=implode(', ',$toArr); + $params=sprintf("-oi -f %s",$this->Sender); + if($this->Sender!=''&&strlen(ini_get('safe_mode'))<1){ + $old_from=ini_get('sendmail_from'); + ini_set('sendmail_from',$this->Sender); + if($this->SingleTo===true&&count($toArr)>1){ + foreach($toArr as $key=>$val){ + $rt=@mail($val,$this->EncodeHeader($this->SecureHeader($this->Subject)),$body,$header,$params); + $isSent=($rt==1)?1:0; + $this->doCallback($isSent,$val,$this->cc,$this->bcc,$this->Subject,$body); + } + }else{ + $rt=@mail($to,$this->EncodeHeader($this->SecureHeader($this->Subject)),$body,$header,$params); + $isSent=($rt==1)?1:0; + $this->doCallback($isSent,$to,$this->cc,$this->bcc,$this->Subject,$body); + } + }else{ + if($this->SingleTo===true&&count($toArr)>1){ + foreach($toArr as $key=>$val){ + $rt=@mail($val,$this->EncodeHeader($this->SecureHeader($this->Subject)),$body,$header,$params); + $isSent=($rt==1)?1:0; + $this->doCallback($isSent,$val,$this->cc,$this->bcc,$this->Subject,$body); + } + }else{ + $rt=@mail($to,$this->EncodeHeader($this->SecureHeader($this->Subject)),$body,$header); + $isSent=($rt==1)?1:0; + $this->doCallback($isSent,$to,$this->cc,$this->bcc,$this->Subject,$body); + } + } + if(isset($old_from)){ + ini_set('sendmail_from',$old_from); + } + if(!$rt){ + throw new phpmailerException($this->Lang('instantiate'),self::STOP_CRITICAL); + } + return true; + } + + protected function SmtpSend($header,$body){ + $bad_rcpt=array(); + if(!$this->SmtpConnect()){ + throw new phpmailerException($this->Lang('smtp_connect_failed'),self::STOP_CRITICAL); + } + $smtp_from=($this->Sender=='')?$this->From:$this->Sender; + if(!$this->smtp->Mail($smtp_from)){ + throw new phpmailerException($this->Lang('from_failed').$smtp_from,self::STOP_CRITICAL); + } + foreach($this->to as $to){ + if(!$this->smtp->Recipient($to[0])){ + $bad_rcpt[]=$to[0]; + $isSent=0; + $this->doCallback($isSent,$to[0],'','',$this->Subject,$body); + }else{ + $isSent=1; + $this->doCallback($isSent,$to[0],'','',$this->Subject,$body); + } + } + foreach($this->cc as $cc){ + if(!$this->smtp->Recipient($cc[0])){ + $bad_rcpt[]=$cc[0]; + $isSent=0; + $this->doCallback($isSent,'',$cc[0],'',$this->Subject,$body); + }else{ + $isSent=1; + $this->doCallback($isSent,'',$cc[0],'',$this->Subject,$body); + } + } + foreach($this->bcc as $bcc){ + if(!$this->smtp->Recipient($bcc[0])){ + $bad_rcpt[]=$bcc[0]; + $isSent=0; + $this->doCallback($isSent,'','',$bcc[0],$this->Subject,$body); + }else{ + $isSent=1; + $this->doCallback($isSent,'','',$bcc[0],$this->Subject,$body); + } + } + if(count($bad_rcpt)>0){ + $badaddresses=implode(', ',$bad_rcpt); + throw new phpmailerException($this->Lang('recipients_failed').$badaddresses); + } + if(!$this->smtp->Data($header.$body)){ + throw new phpmailerException($this->Lang('data_not_accepted'),self::STOP_CRITICAL); + } + if($this->SMTPKeepAlive==true){ + $this->smtp->Reset(); + } + return true; + } + + public function SmtpConnect(){ + if(is_null($this->smtp)){ + $this->smtp=new SMTP(); + } + $this->smtp->do_debug=$this->SMTPDebug; + $hosts=explode(';',$this->Host); + $index=0; + $connection=$this->smtp->Connected(); + try{ + while($indexPort; + } + $tls=($this->SMTPSecure=='tls'); + $ssl=($this->SMTPSecure=='ssl'); + if($this->smtp->Connect(($ssl?'ssl://':'').$host,$port,$this->Timeout)){ + $hello=($this->Helo!=''?$this->Helo:$this->ServerHostname()); + $this->smtp->Hello($hello); + if($tls){ + if(!$this->smtp->StartTLS()){ + throw new phpmailerException($this->Lang('tls')); + } + $this->smtp->Hello($hello); + } + $connection=true; + if($this->SMTPAuth){ + if(!$this->smtp->Authenticate($this->Username,$this->Password)){ + throw new phpmailerException($this->Lang('authenticate')); + } + } + } + $index++; + if(!$connection){ + throw new phpmailerException($this->Lang('connect_host')); + } + } + }catch(phpmailerException$e){ + $this->smtp->Reset(); + throw $e; + } + return true; + } + public function SmtpClose(){ + if(!is_null($this->smtp)){ + if($this->smtp->Connected()){ + $this->smtp->Quit(); + $this->smtp->Close(); + } + } + } + + function SetLanguage($langcode='en',$lang_path='language/'){ + $PHPMAILER_LANG=array(); + $PHPMAILER_LANG['authenticate']='SMTP 错误:登录失败。'; + $PHPMAILER_LANG['connect_host']='SMTP 错误:无法连接到 SMTP 主机。'; + $PHPMAILER_LANG['data_not_accepted']='SMTP 错误:数据不被接受。'; + $PHPMAILER_LANG['encoding']='未知编码: '; + $PHPMAILER_LANG['execute']='无法执行:'; + $PHPMAILER_LANG['file_access']='无法访问文件:'; + $PHPMAILER_LANG['file_open']='文件错误:无法打开文件:'; + $PHPMAILER_LANG['from_failed']='发送地址错误:'; + $PHPMAILER_LANG['instantiate']='未知函数调用。'; + $PHPMAILER_LANG['mailer_not_supported']='发信客户端不被支持。'; + $PHPMAILER_LANG['provide_address']='必须提供至少一个收件人地址。'; + $PHPMAILER_LANG['recipients_failed']='SMTP 错误:收件人地址错误:'; + $l=true; + $this->language=$PHPMAILER_LANG; + return ($l==true); + } + + public function GetTranslations(){ + return $this->language; + } + public function AddrAppend($type,$addr){ + $addr_str=$type.': '; + $addresses=array(); + foreach($addr as $a){ + $addresses[]=$this->AddrFormat($a); + } + $addr_str.=implode(', ',$addresses); + $addr_str.=$this->LE; + return $addr_str; + } + public function AddrFormat($addr){ + if(empty($addr[1])){ + return $this->SecureHeader($addr[0]); + }else{ + return $this->EncodeHeader($this->SecureHeader($addr[1]),'phrase')." <".$this->SecureHeader($addr[0]).">"; + } + } + public function WrapText($message,$length,$qp_mode=false){ + $soft_break=($qp_mode)?sprintf(" =%s",$this->LE):$this->LE; + $is_utf8=(strtolower($this->CharSet)=="utf-8"); + $message=$this->FixEOL($message); + if(substr($message,-1)==$this->LE){ + $message=substr($message,0,-1); + } + $line=explode($this->LE,$message); + $message=''; + for($i=0;$i$length)){ + $space_left=$length-strlen($buf)-1; + if($e!=0){ + if($space_left>20){ + $len=$space_left; + if($is_utf8){ + $len=$this->UTF8CharBoundary($word,$len); + }elseif(substr($word,$len-1,1)=="="){ + $len--; + }elseif(substr($word,$len-2,1)=="="){ + $len-=2; + } + $part=substr($word,0,$len); + $word=substr($word,$len); + $buf.=' '.$part; + $message.=$buf.sprintf("=%s",$this->LE); + }else{ + $message.=$buf.$soft_break; + } + $buf=''; + } + while(strlen($word)>0){ + $len=$length; + if($is_utf8){ + $len=$this->UTF8CharBoundary($word,$len); + }elseif(substr($word,$len-1,1)=="="){ + $len--; + }elseif(substr($word,$len-2,1)=="="){ + $len-=2; + } + $part=substr($word,0,$len); + $word=substr($word,$len); + if(strlen($word)>0){ + $message.=$part.sprintf("=%s",$this->LE); + }else{ + $buf=$part; + } + } + }else{ + $buf_o=$buf; + $buf.=($e==0)?$word:(' '.$word); + if(strlen($buf)>$length and $buf_o!=''){ + $message.=$buf_o.$soft_break;$buf=$word; + } + } + } + $message.=$buf.$this->LE; + } + return $message; + } + public function UTF8CharBoundary($encodedText,$maxLength){ + $foundSplitPos=false; + $lookBack=3; + while(!$foundSplitPos){ + $lastChunk=substr($encodedText,$maxLength-$lookBack,$lookBack); + $encodedCharPos=strpos($lastChunk,"="); + if($encodedCharPos!==false){ + $hex=substr($encodedText,$maxLength-$lookBack+$encodedCharPos+1,2); + $dec=hexdec($hex); + if($dec<128){ + $maxLength=($encodedCharPos==0)?$maxLength:$maxLength-($lookBack-$encodedCharPos); + $foundSplitPos=true; + }elseif($dec>=192){ + $maxLength=$maxLength-($lookBack-$encodedCharPos); + $foundSplitPos=true; + }elseif($dec<192){ + $lookBack+=3; + } + }else{ + $foundSplitPos=true; + } + } + return $maxLength; + } + public function SetWordWrap(){ + if($this->WordWrap<1){ + return ; + } + switch($this->message_type){ + case 'alt': + case 'alt_attachments': + $this->AltBody=$this->WrapText($this->AltBody,$this->WordWrap); + break; + default: + $this->Body=$this->WrapText($this->Body,$this->WordWrap); + break; + } + } + public function CreateHeader(){ + $result=''; + $uniq_id=md5(uniqid(time())); + $this->boundary[1]='b1_'.$uniq_id; + $this->boundary[2]='b2_'.$uniq_id; + $result.=$this->HeaderLine('Date',self::RFCDate()); + if($this->Sender==''){ + $result.=$this->HeaderLine('Return-Path',trim($this->From)); + }else{ + $result.=$this->HeaderLine('Return-Path',trim($this->Sender)); + } + if($this->Mailer!='mail'){ + if($this->SingleTo===true){ + foreach($this->to as $t){ + $this->SingleToArray[]=$this->AddrFormat($t); + } + }else{ + if(count($this->to)>0){ + $result.=$this->AddrAppend('To',$this->to); + }elseif(count($this->cc)==0){ + $result.=$this->HeaderLine('To','undisclosed-recipients:;'); + } + } + } + $from=array(); + $from[0][0]=trim($this->From); + $from[0][1]=$this->FromName; + $result.=$this->AddrAppend('From',$from); + if(count($this->cc)>0){ + $result.=$this->AddrAppend('Cc',$this->cc); + } + if((($this->Mailer=='sendmail')||($this->Mailer=='mail'))&&(count($this->bcc)>0)){ + $result.=$this->AddrAppend('Bcc',$this->bcc); + } + if(count($this->ReplyTo)>0){ + $result.=$this->AddrAppend('Reply-to',$this->ReplyTo); + } + if($this->Mailer!='mail'){ + $result.=$this->HeaderLine('Subject',$this->EncodeHeader($this->SecureHeader($this->Subject))); + } + if($this->MessageID!=''){ + $result.=$this->HeaderLine('Message-ID',$this->MessageID); + }else{ + $result.=sprintf("Message-ID: <%s@%s>%s",$uniq_id,$this->ServerHostname(),$this->LE); + } + $result.=$this->HeaderLine('X-Priority',$this->Priority); + $result.=$this->HeaderLine('X-Mailer','PHPMailer '.$this->Version.' (phpmailer.sourceforge.net)'); + if($this->ConfirmReadingTo!=''){ + $result.=$this->HeaderLine('Disposition-Notification-To','<'.trim($this->ConfirmReadingTo).'>'); + } + for($index=0;$indexCustomHeader);$index++){ + $result.=$this->HeaderLine(trim($this->CustomHeader[$index][0]),$this->EncodeHeader(trim($this->CustomHeader[$index][1]))); + } + if(!$this->sign_key_file){ + $result.=$this->HeaderLine('MIME-Version','1.0'); + $result.=$this->GetMailMIME(); + } + return $result; + } + public function GetMailMIME(){ + $result=''; + switch($this->message_type){ + case 'plain': + $result.=$this->HeaderLine('Content-Transfer-Encoding',$this->Encoding); + $result.=sprintf("Content-Type: %s; charset=\"%s\"",$this->ContentType,$this->CharSet); + break; + case 'attachments': + case 'alt_attachments': + if($this->InlineImageExists()){ + $result.=sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s",'multipart/related',$this->LE,$this->LE,$this->boundary[1],$this->LE); + }else{ + $result.=$this->HeaderLine('Content-Type','multipart/mixed;'); + $result.=$this->TextLine("\tboundary=\"".$this->boundary[1].'"'); + } + break; + case 'alt': + $result.=$this->HeaderLine('Content-Type','multipart/alternative;'); + $result.=$this->TextLine("\tboundary=\"".$this->boundary[1].'"'); + break; + } + if($this->Mailer!='mail'){ + $result.=$this->LE.$this->LE; + } + return $result; + } + public function CreateBody(){ + $body=''; + if($this->sign_key_file){ + $body.=$this->GetMailMIME(); + } + $this->SetWordWrap(); + switch($this->message_type){ + case 'alt': + $body.=$this->GetBoundary($this->boundary[1],'','text/plain',''); + $body.=$this->EncodeString($this->AltBody,$this->Encoding); + $body.=$this->LE.$this->LE; + $body.=$this->GetBoundary($this->boundary[1],'','text/html',''); + $body.=$this->EncodeString($this->Body,$this->Encoding); + $body.=$this->LE.$this->LE; + $body.=$this->EndBoundary($this->boundary[1]); + break; + case 'plain': + $body.=$this->EncodeString($this->Body,$this->Encoding); + break; + case 'attachments': + $body.=$this->GetBoundary($this->boundary[1],'','',''); + $body.=$this->EncodeString($this->Body,$this->Encoding); + $body.=$this->LE; + $body.=$this->AttachAll(); + break; + case 'alt_attachments': + $body.=sprintf("--%s%s",$this->boundary[1],$this->LE); + $body.=sprintf("Content-Type: %s;%s"."\tboundary=\"%s\"%s",'multipart/alternative',$this->LE,$this->boundary[2],$this->LE.$this->LE); + $body.=$this->GetBoundary($this->boundary[2],'','text/plain','').$this->LE; + $body.=$this->EncodeString($this->AltBody,$this->Encoding); + $body.=$this->LE.$this->LE; + $body.=$this->GetBoundary($this->boundary[2],'','text/html','').$this->LE; + $body.=$this->EncodeString($this->Body,$this->Encoding); + $body.=$this->LE.$this->LE; + $body.=$this->EndBoundary($this->boundary[2]); + $body.=$this->AttachAll(); + break; + } + if($this->IsError()){ + $body=''; + }elseif($this->sign_key_file){ + try{ + $file=tempnam('','mail'); + file_put_contents($file,$body); + $signed=tempnam("","signed"); + if(@openssl_pkcs7_sign($file,$signed,"file://".$this->sign_cert_file,array("file://".$this->sign_key_file,$this->sign_key_pass),NULL)){ + @unlink($file); + @unlink($signed); + $body=file_get_contents($signed); + }else{ + @unlink($file); + @unlink($signed); + throw new phpmailerException($this->Lang("signing").openssl_error_string()); + } + }catch(phpmailerException$e){ + $body=''; + if($this->exceptions){ + throw $e; + } + } + } + return $body; + } + private function GetBoundary($boundary,$charSet,$contentType,$encoding){ + $result=''; + if($charSet==''){ + $charSet=$this->CharSet; + } + if($contentType==''){ + $contentType=$this->ContentType; + } + if($encoding==''){ + $encoding=$this->Encoding; + } + $result.=$this->TextLine('--'.$boundary); + $result.=sprintf("Content-Type: %s; charset = \"%s\"",$contentType,$charSet); + $result.=$this->LE; + $result.=$this->HeaderLine('Content-Transfer-Encoding',$encoding); + $result.=$this->LE; + return $result; + } + private function EndBoundary($boundary){ + return $this->LE.'--'.$boundary.'--'.$this->LE; + } + private function SetMessageType(){ + if(count($this->attachment)<1&&strlen($this->AltBody)<1){ + $this->message_type='plain'; + }else{ + if(count($this->attachment)>0){ + $this->message_type='attachments'; + } + if(strlen($this->AltBody)>0&&count($this->attachment)<1){ + $this->message_type='alt'; + } + if(strlen($this->AltBody)>0&&count($this->attachment)>0){ + $this->message_type='alt_attachments'; + } + } + } + public function HeaderLine($name,$value){ + return $name.': '.$value.$this->LE; + } + public function TextLine($value){ + return $value.$this->LE; + } + public function AddAttachment($path,$name='',$encoding='base64',$type='application/octet-stream'){ + try{ + if(!@is_file($path)){ + throw new phpmailerException($this->Lang('file_access').$path,self::STOP_CONTINUE); + } + $filename=basename($path); + if($name==''){ + $name=$filename; + } + $this->attachment[]=array(0=>$path,1=>$filename,2=>$name,3=>$encoding,4=>$type,5=>false,6=>'attachment',7=>0); + }catch(phpmailerException$e){ + $this->SetError($e->getMessage()); + if($this->exceptions){ + throw $e; + } + if($e->getCode()==self::STOP_CRITICAL){ + return false; + } + } + return true; + } + public function GetAttachments(){ + return $this->attachment; + } + private function AttachAll(){ + $mime=array(); + $cidUniq=array(); + $incl=array(); + foreach($this->attachment as $attachment){ + $bString=$attachment[5]; + if($bString){ + $string=$attachment[0]; + }else{ + $path=$attachment[0]; + } + if(in_array($attachment[0],$incl)){ + continue; + } + $filename=$attachment[1]; + $name=$attachment[2]; + $encoding=$attachment[3]; + $type=$attachment[4]; + $disposition=$attachment[6]; + $cid=$attachment[7]; + $incl[]=$attachment[0]; + if($disposition=='inline'&&isset($cidUniq[$cid])){ + continue; + } + $cidUniq[$cid]=true; + $mime[]=sprintf("--%s%s",$this->boundary[1],$this->LE); + $mime[]=sprintf("Content-Type: %s; name=\"%s\"%s",$type,$this->EncodeHeader($this->SecureHeader($name)),$this->LE); + $mime[]=sprintf("Content-Transfer-Encoding: %s%s",$encoding,$this->LE); + if($disposition=='inline'){ + $mime[]=sprintf("Content-ID: <%s>%s",$cid,$this->LE); + } + $mime[]=sprintf("Content-Disposition: %s; filename=\"%s\"%s",$disposition,$this->EncodeHeader($this->SecureHeader($name)),$this->LE.$this->LE); + if($bString){ + $mime[]=$this->EncodeString($string,$encoding); + if($this->IsError()){ + return ''; + } + $mime[]=$this->LE.$this->LE; + }else{ + $mime[]=$this->EncodeFile($path,$encoding); + if($this->IsError()){ + return ''; + } + $mime[]=$this->LE.$this->LE; + } + } + $mime[]=sprintf("--%s--%s",$this->boundary[1],$this->LE); + return join('',$mime); + } + private function EncodeFile($path,$encoding='base64'){ + try{ + if(!is_readable($path)){ + throw new phpmailerException($this->Lang('file_open').$path,self::STOP_CONTINUE); + } + if(function_exists('get_magic_quotes')){ + function get_magic_quotes(){ + return false; + } + } + if(PHP_VERSION<6){ + $magic_quotes=get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + } + $file_buffer=file_get_contents($path); + $file_buffer=$this->EncodeString($file_buffer,$encoding); + if(PHP_VERSION<6){ + set_magic_quotes_runtime($magic_quotes); + } + return $file_buffer; + }catch(Exception$e){ + $this->SetError($e->getMessage());return ''; + } + } + public function EncodeString($str,$encoding='base64'){ + $encoded=''; + switch(strtolower($encoding)){ + case 'base64': + $encoded=chunk_split(base64_encode($str),76,$this->LE); + break; + case '7bit': + case '8bit': + $encoded=$this->FixEOL($str); + if(substr($encoded,-(strlen($this->LE)))!=$this->LE)$encoded.=$this->LE; + break; + case 'binary': + $encoded=$str; + break; + case 'quoted-printable': + $encoded=$this->EncodeQP($str); + break; + default: + $this->SetError($this->Lang('encoding').$encoding); + break; + } + return $encoded; + } + public function EncodeHeader($str,$position='text'){ + $x=0; + switch(strtolower($position)){ + case 'phrase': + if(!preg_match('/[\200-\377]/',$str)){ + $encoded=addcslashes($str,"\0..\37\177\\\""); + if(($str==$encoded)&&!preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/',$str)){ + return ($encoded); + }else{ + return ("\"$encoded\""); + } + } + $x=preg_match_all('/[^\040\041\043-\133\135-\176]/',$str,$matches); + break; + case 'comment': + $x=preg_match_all('/[()"]/',$str,$matches); + case 'text': + default: + $x+=preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/',$str,$matches);break; + } + if($x==0){ + return ($str); + } + $maxlen=75-7-strlen($this->CharSet); + if(strlen($str)/3<$x){ + $encoding='B'; + if(function_exists('mb_strlen')&&$this->HasMultiBytes($str)){ + $encoded=$this->Base64EncodeWrapMB($str); + }else{ + $encoded=base64_encode($str); + $maxlen-=$maxlen%4; + $encoded=trim(chunk_split($encoded,$maxlen,"\n")); + } + }else{ + $encoding='Q'; + $encoded=$this->EncodeQ($str,$position); + $encoded=$this->WrapText($encoded,$maxlen,true); + $encoded=str_replace('='.$this->LE,"\n",trim($encoded)); + } + $encoded=preg_replace('/^(.*)$/m'," =?".$this->CharSet."?$encoding?\\1?=",$encoded); + $encoded=trim(str_replace("\n",$this->LE,$encoded)); + return $encoded; + } + public function HasMultiBytes($str){ + if(function_exists('mb_strlen')){ + return (strlen($str)>mb_strlen($str,$this->CharSet)); + }else{ + return false; + } + } + public function Base64EncodeWrapMB($str){ + $start="=?".$this->CharSet."?B?"; + $end="?="; + $encoded=""; + $mb_length=mb_strlen($str,$this->CharSet); + $length=75-strlen($start)-strlen($end); + $ratio=$mb_length/strlen($str); + $offset=$avgLength=floor($length*$ratio*.75); + for($i=0;$i<$mb_length;$i+=$offset){ + $lookBack=0; + do{ + $offset=$avgLength-$lookBack; + $chunk=mb_substr($str,$i,$offset,$this->CharSet); + $chunk=base64_encode($chunk);$lookBack++; + }while(strlen($chunk)>$length); + $encoded.=$chunk.$this->LE; + } + $encoded=substr($encoded,0,-strlen($this->LE)); + return $encoded; + } + public function EncodeQPphp($input='',$line_max=76,$space_conv=false){ + $hex=array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'); + $lines=preg_split('/(?:\r\n|\r|\n)/',$input); + $eol="\r\n"; + $escape='='; + $output=''; + while(list(,$line)=each($lines)){ + $linlen=strlen($line); + $newline=''; + for($i=0;$i<$linlen;$i++){ + $c=substr($line,$i,1); + $dec=ord($c); + if(($i==0)&&($dec==46)){ + $c='=2E'; + } + if($dec==32){ + if($i==($linlen-1)){ + $c='=20'; + }elseif($space_conv){ + $c='=20'; + } + }elseif(($dec==61)||($dec<32)||($dec>126)){ + $h2=floor($dec/16); + $h1=floor($dec%16); + $c=$escape.$hex[$h2].$hex[$h1]; + } + if((strlen($newline)+strlen($c))>=$line_max){ + $output.=$newline.$escape.$eol; + $newline=''; + if($dec==46){ + $c='=2E'; + } + } + $newline.=$c; + } + $output.=$newline.$eol; + } + return $output; + } + public function EncodeQP($string,$line_max=76,$space_conv=false){ + if(function_exists('quoted_printable_encode')){ + return quoted_printable_encode($string); + } + $filters=stream_get_filters(); + if(!in_array('convert.*',$filters)){ + return $this->EncodeQPphp($string,$line_max,$space_conv); + } + $fp=fopen('php://temp/','r+'); + $string=preg_replace('/\r\n?/',$this->LE,$string); + $params=array('line-length'=>$line_max,'line-break-chars'=>$this->LE); + $s=stream_filter_append($fp,'convert.quoted-printable-encode',STREAM_FILTER_READ,$params); + fputs($fp,$string); + rewind($fp); + $out=stream_get_contents($fp); + stream_filter_remove($s); + $out=preg_replace('/^\./m','=2E',$out); + fclose($fp); + return $out; + } + public function EncodeQ($str,$position='text'){ + $encoded=preg_replace('/[\r\n]*/','',$str); + switch(strtolower($position)){ + case 'phrase': + $encoded=preg_replace("/([^A-Za-z0-9!*+\/ -])/e","'='.sprintf('%02X', ord('\\1'))",$encoded); + break; + case 'comment': + $encoded=preg_replace("/([\(\)\"])/e","'='.sprintf('%02X', ord('\\1'))",$encoded); + case 'text': + default: + $encoded=preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',"'='.sprintf('%02X', ord('\\1'))",$encoded); + break; + } + $encoded=str_replace(' ','_',$encoded); + return $encoded; + } + public function AddStringAttachment($string,$filename,$encoding='base64',$type='application/octet-stream'){ + $this->attachment[]=array(0=>$string,1=>$filename,2=>basename($filename),3=>$encoding,4=>$type,5=>true,6=>'attachment',7=>0); + } + public function AddEmbeddedImage($path,$cid,$name='',$encoding='base64',$type='application/octet-stream'){ + if(!@is_file($path)){ + $this->SetError($this->Lang('file_access').$path); + return false; + } + $filename=basename($path); + if($name==''){ + $name=$filename; + } + $this->attachment[]=array(0=>$path,1=>$filename,2=>$name,3=>$encoding,4=>$type,5=>false,6=>'inline',7=>$cid); + return true; + } + public function InlineImageExists(){ + foreach($this->attachment as $attachment){ + if($attachment[6]=='inline'){ + return true; + } + } + return false; + } + public function ClearAddresses(){ + foreach($this->to as $to){ + unset($this->all_recipients[strtolower($to[0])]); + } + $this->to=array(); + } + public function ClearCCs(){ + foreach($this->cc as $cc){ + unset($this->all_recipients[strtolower($cc[0])]); + } + $this->cc=array(); + } + public function ClearBCCs(){ + foreach($this->bcc as $bcc){ + unset($this->all_recipients[strtolower($bcc[0])]); + } + $this->bcc=array(); + } + public function ClearReplyTos(){ + $this->ReplyTo=array(); + } + public function ClearAllRecipients(){ + $this->to=array(); + $this->cc=array(); + $this->bcc=array(); + $this->all_recipients=array(); + } + public function ClearAttachments(){ + $this->attachment=array(); + } + public function ClearCustomHeaders(){ + $this->CustomHeader=array(); + } + protected function SetError($msg){ + $this->error_count++; + if($this->Mailer=='smtp' and !is_null($this->smtp)){ + $lasterror=$this->smtp->getError(); + if(!empty($lasterror) and array_key_exists('smtp_msg',$lasterror)){ + $msg.='

'.$this->Lang('smtp_error').$lasterror['smtp_msg']."

\n"; + } + } + $this->ErrorInfo=$msg; + } + public static function RFCDate(){ + $tz=date('Z'); + $tzs=($tz<0)?'-':'+'; + $tz=abs($tz); + $tz=(int)($tz/3600)*100+($tz%3600)/60; + $result=sprintf("%s %s%04d",date('D, j M Y H:i:s'),$tzs,$tz); + return $result; + } + private function ServerHostname(){ + if(!empty($this->Hostname)){ + $result=$this->Hostname; + }elseif(isset($_SERVER['SERVER_NAME'])){ + $result=$_SERVER['SERVER_NAME']; + }else{ + $result='localhost.localdomain'; + } + return $result; + } + private function Lang($key){ + if(count($this->language)<1){ + $this->SetLanguage('en'); + } + if(isset($this->language[$key])){ + return $this->language[$key]; + }else{ + return 'Language string failed to load: '.$key; + } + } + + public function IsError(){ + return ($this->error_count>0); + } + private function FixEOL($str){ + $str=str_replace("\r\n","\n",$str); + $str=str_replace("\r","\n",$str); + $str=str_replace("\n",$this->LE,$str); + return $str; + } + public function AddCustomHeader($custom_header){ + $this->CustomHeader[]=explode(':',$custom_header,2); + } + public function MsgHTML($message,$basedir=''){ + preg_match_all("/(src|background)=\"(.*)\"/Ui",$message,$images); + if(isset($images[2])){ + foreach($images[2] as $i=>$url){ + if(!preg_match('#^[A-z]+://#',$url)){ + $filename=basename($url); + $directory=dirname($url); + ($directory=='.')?$directory='':''; + $cid='cid:'.md5($filename); + $ext=pathinfo($filename,PATHINFO_EXTENSION); + $mimeType=self::_mime_types($ext); + if(strlen($basedir)>1&&substr($basedir,-1)!='/'){ + $basedir.='/'; + } + if(strlen($directory)>1&&substr($directory,-1)!='/'){ + $directory.='/'; + } + if($this->AddEmbeddedImage($basedir.$directory.$filename,md5($filename),$filename,'base64',$mimeType)){ + $message=preg_replace("/".$images[1][$i]."=\"".preg_quote($url,'/')."\"/Ui",$images[1][$i]."=\"".$cid."\"",$message); + } + } + } + } + $this->IsHTML(true); + $this->Body=$message; + $textMsg=trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s','',$message))); + if(!empty($textMsg)&&empty($this->AltBody)){ + $this->AltBody=html_entity_decode($textMsg); + } + if(empty($this->AltBody)){ + $this->AltBody='To view this email message, open it in a program that understands HTML!'."\n\n"; + } + } + public static function _mime_types($ext=''){ + $mimes=array( + 'hqx'=>'application/mac-binhex40', + 'cpt'=>'application/mac-compactpro', + 'doc'=>'application/msword', + 'bin'=>'application/macbinary', + 'dms'=>'application/octet-stream', + 'lha'=>'application/octet-stream', + 'lzh'=>'application/octet-stream', + 'exe'=>'application/octet-stream', + 'class'=>'application/octet-stream', + 'psd'=>'application/octet-stream', + 'so'=>'application/octet-stream', + 'sea'=>'application/octet-stream', + 'dll'=>'application/octet-stream', + 'oda'=>'application/oda', + 'pdf'=>'application/pdf', + 'ai'=>'application/postscript', + 'eps'=>'application/postscript', + 'ps'=>'application/postscript', + 'smi'=>'application/smil', + 'smil'=>'application/smil', + 'mif'=>'application/vnd.mif', + 'xls'=>'application/vnd.ms-excel', + 'ppt'=>'application/vnd.ms-powerpoint', + 'wbxml'=>'application/vnd.wap.wbxml', + 'wmlc'=>'application/vnd.wap.wmlc', + 'dcr'=>'application/x-director', + 'dir'=>'application/x-director', + 'dxr'=>'application/x-director', + 'dvi'=>'application/x-dvi', + 'gtar'=>'application/x-gtar', + 'php'=>'application/x-httpd-php', + 'php4'=>'application/x-httpd-php', + 'php3'=>'application/x-httpd-php', + 'phtml'=>'application/x-httpd-php', + 'phps'=>'application/x-httpd-php-source', + 'js'=>'application/x-javascript', + 'swf'=>'application/x-shockwave-flash', + 'sit'=>'application/x-stuffit', + 'tar'=>'application/x-tar', + 'tgz'=>'application/x-tar', + 'xhtml'=>'application/xhtml+xml', + 'xht'=>'application/xhtml+xml', + 'zip'=>'application/zip', + 'mid'=>'audio/midi', + 'midi'=>'audio/midi', + 'mpga'=>'audio/mpeg', + 'mp2'=>'audio/mpeg', + 'mp3'=>'audio/mpeg', + 'aif'=>'audio/x-aiff', + 'aiff'=>'audio/x-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'=>'audio/x-wav', + 'bmp'=>'image/bmp', + 'gif'=>'image/gif', + 'jpeg'=>'image/jpeg', + 'jpg'=>'image/jpeg', + 'jpe'=>'image/jpeg', + 'png'=>'image/png', + 'tiff'=>'image/tiff', + 'tif'=>'image/tiff', + 'css'=>'text/css', + 'html'=>'text/html', + 'htm'=>'text/html', + 'shtml'=>'text/html', + 'txt'=>'text/plain', + 'text'=>'text/plain', + 'log'=>'text/plain', + 'rtx'=>'text/richtext', + 'rtf'=>'text/rtf', + 'xml'=>'text/xml', + 'xsl'=>'text/xml', + 'mpeg'=>'video/mpeg', + 'mpg'=>'video/mpeg', + 'mpe'=>'video/mpeg', + 'qt'=>'video/quicktime', + 'mov'=>'video/quicktime', + 'avi'=>'video/x-msvideo', + 'movie'=>'video/x-sgi-movie', + 'doc'=>'application/msword', + 'word'=>'application/msword', + 'xl'=>'application/excel', + 'eml'=>'message/rfc822' + ); + return (!isset($mimes[strtolower($ext)]))?'application/octet-stream':$mimes[strtolower($ext)]; + } + public function set($name,$value=''){ + try{ + if(isset($this->$name)){ + $this->$name=$value; + }else{ + throw new phpmailerException($this->Lang('variable_set').$name,self::STOP_CRITICAL); + } + }catch(Exception$e){ + $this->SetError($e->getMessage()); + if($e->getCode()==self::STOP_CRITICAL){ + return false; + } + } + return true; + } + public function SecureHeader($str){ + $str=str_replace("\r",'',$str); + $str=str_replace("\n",'',$str); + return trim($str); + } + public function Sign($cert_filename,$key_filename,$key_pass){ + $this->sign_cert_file=$cert_filename; + $this->sign_key_file=$key_filename; + $this->sign_key_pass=$key_pass; + } + public function DKIM_QP($txt){ + $tmp=""; + $line=""; + for($i=0;$iDKIM_private); + if($this->DKIM_passphrase!=''){ + $privKey=openssl_pkey_get_private($privKeyStr,$this->DKIM_passphrase); + }else{ + $privKey=$privKeyStr; + } + if(openssl_sign($s,$signature,$privKey)){ + return base64_encode($signature); + } + } + public function DKIM_HeaderC($s){ + $s=preg_replace("/\r\n\s+/"," ",$s); + $lines=explode("\r\n",$s); + foreach($lines as $key=>$line){ + list($heading,$value)=explode(":",$line,2); + $heading=strtolower($heading); + $value=preg_replace("/\s+/"," ",$value); + $lines[$key]=$heading.":".trim($value); + } + $s=implode("\r\n",$lines); + return $s; + } + public function DKIM_BodyC($body){ + if($body=='')return "\r\n"; + $body=str_replace("\r\n","\n",$body); + $body=str_replace("\n","\r\n",$body); + while(substr($body,strlen($body)-4,4)=="\r\n\r\n"){ + $body=substr($body,0,strlen($body)-2); + } + return $body; + } + public function DKIM_Add($headers_line,$subject,$body){ + $DKIMsignatureType='rsa-sha1'; + $DKIMcanonicalization='relaxed/simple'; + $DKIMquery='dns/txt'; + $DKIMtime=time(); + $subject_header="Subject: $subject"; + $headers=explode("\r\n",$headers_line); + foreach($headers as $header){ + if(strpos($header,'From:')===0){ + $from_header=$header; + }elseif(strpos($header,'To:')===0){ + $to_header=$header; + } + } + $from=str_replace('|','=7C',$this->DKIM_QP($from_header)); + $to=str_replace('|','=7C',$this->DKIM_QP($to_header)); + $subject=str_replace('|','=7C',$this->DKIM_QP($subject_header)); + $body=$this->DKIM_BodyC($body); + $DKIMlen=strlen($body); + $DKIMb64=base64_encode(pack("H*",sha1($body))); + $ident=($this->DKIM_identity=='')?'':" i=".$this->DKIM_identity.";"; + $dkimhdrs="DKIM-Signature: v=1; a=".$DKIMsignatureType."; q=".$DKIMquery."; l=".$DKIMlen."; s=".$this->DKIM_selector.";\r\n"."\tt=".$DKIMtime."; c=".$DKIMcanonicalization.";\r\n"."\th=From:To:Subject;\r\n"."\td=".$this->DKIM_domain.";".$ident."\r\n"."\tz=$from\r\n"."\t|$to\r\n"."\t|$subject;\r\n"."\tbh=".$DKIMb64.";\r\n"."\tb="; + $toSign=$this->DKIM_HeaderC($from_header."\r\n".$to_header."\r\n".$subject_header."\r\n".$dkimhdrs); + $signed=$this->DKIM_Sign($toSign); + return "X-PHPMAILER-DKIM: phpmailer.worxware.com\r\n".$dkimhdrs.$signed."\r\n"; + } + protected function doCallback($isSent,$to,$cc,$bcc,$subject,$body){ + if(!empty($this->action_function)&&function_exists($this->action_function)){ + $params=array($isSent,$to,$cc,$bcc,$subject,$body); + call_user_func_array($this->action_function,$params); + } + } +} + +class phpmailerException extends Exception{ + public function errorMessage(){ + return $this->getMessage(); + } +} + +class SMTP{ + public $SMTP_PORT=25; + public $CRLF="\r\n"; + public $do_debug; + public $do_verp=false; + private $smtp_conn; + private $error; + private $helo_rply; + public function __construct(){ + $this->smtp_conn=0; + $this->error=null; + $this->helo_rply=null; + $this->do_debug=0; + } + public function Connect($host,$port=0,$tval=30){ + $this->error=null; + if($this->connected()){ + $this->error=array("error"=>"Already connected to a server"); + return false; + } + if(empty($port)){ + $port=$this->SMTP_PORT; + } + $this->smtp_conn=@fsockopen($host,$port,$errno,$errstr,$tval); + stream_set_blocking($this->smtp_conn, true); //重要,设置为非阻塞模式 + stream_set_timeout($this->smtp_conn,10); //设置超时 + if(empty($this->smtp_conn)){ + $this->error=array("error"=>"Failed to connect to server","errno"=>$errno,"errstr"=>$errstr); + if($this->do_debug>=1){ + echo "SMTP -> ERROR: ".$this->error["error"].": $errstr ($errno)".$this->CRLF.'
'; + } + return false; + } + if(substr(PHP_OS,0,3)!="WIN")socket_set_timeout($this->smtp_conn,$tval,0); + $announce=$this->get_lines(); + if($this->do_debug>=2){ + echo "SMTP -> FROM SERVER:".$announce.$this->CRLF.'
'; + } + return true; + } + public function StartTLS(){ + $this->error=null; + if(!$this->connected()){ + $this->error=array("error"=>"Called StartTLS() without being connected"); + return false; + } + fputs($this->smtp_conn,"STARTTLS".$this->CRLF); + $rply=$this->get_lines(); + $code=substr($rply,0,3); + if($this->do_debug>=2){ + echo "SMTP -> FROM SERVER:".$rply.$this->CRLF.'
'; + } + if($code!=220){ + $this->error=array("error"=>"STARTTLS not accepted from server","smtp_code"=>$code,"smtp_msg"=>substr($rply,4)); + if($this->do_debug>=1){ + echo "SMTP -> ERROR: ".$this->error["error"].": ".$rply.$this->CRLF.'
'; + } + return false; + }if(!stream_socket_enable_crypto($this->smtp_conn,true,STREAM_CRYPTO_METHOD_TLS_CLIENT)){ + return false; + } + return true; + } + public function Authenticate($username,$password){ + fputs($this->smtp_conn,"AUTH LOGIN".$this->CRLF); + $rply=$this->get_lines(); + $code=substr($rply,0,3); + if($code!=334){ + $this->error=array("error"=>"AUTH not accepted from server","smtp_code"=>$code,"smtp_msg"=>substr($rply,4)); + if($this->do_debug>=1){ + echo "SMTP -> ERROR: ".$this->error["error"].": ".$rply.$this->CRLF.'
'; + } + return false; + } + fputs($this->smtp_conn,base64_encode($username).$this->CRLF); + $rply=$this->get_lines(); + $code=substr($rply,0,3); + if($code!=334){ + $this->error=array("error"=>"Username not accepted from server","smtp_code"=>$code,"smtp_msg"=>substr($rply,4)); + if($this->do_debug>=1){ + echo "SMTP -> ERROR: ".$this->error["error"].": ".$rply.$this->CRLF.'
'; + } + return false; + } + fputs($this->smtp_conn,base64_encode($password).$this->CRLF); + $rply=$this->get_lines(); + $code=substr($rply,0,3); + if($code!=235){ + $this->error=array("error"=>"Password not accepted from server","smtp_code"=>$code,"smtp_msg"=>substr($rply,4)); + if($this->do_debug>=1){ + echo "SMTP -> ERROR: ".$this->error["error"].": ".$rply.$this->CRLF.'
'; + } + return false; + } + return true; + } + public function Connected(){ + if(!empty($this->smtp_conn)){ + $sock_status=socket_get_status($this->smtp_conn); + if($sock_status["eof"]){ + if($this->do_debug>=1){ + echo "SMTP -> NOTICE:".$this->CRLF."EOF caught while checking if connected"; + } + $this->Close(); + return false; + } + return true; + } + return false; + } + public function Close(){ + $this->error=null; + $this->helo_rply=null; + if(!empty($this->smtp_conn)){ + fclose($this->smtp_conn); + $this->smtp_conn=0; + } + } + public function Data($msg_data){ + $this->error=null; + if(!$this->connected()){ + $this->error=array("error"=>"Called Data() without being connected"); + return false; + } + fputs($this->smtp_conn,"DATA".$this->CRLF); + $rply=$this->get_lines(); + $code=substr($rply,0,3); + if($this->do_debug>=2){ + echo "SMTP -> FROM SERVER:".$rply.$this->CRLF.'
'; + } + if($code!=354){ + $this->error=array("error"=>"DATA command not accepted from server","smtp_code"=>$code,"smtp_msg"=>substr($rply,4)); + if($this->do_debug>=1){ + echo "SMTP -> ERROR: ".$this->error["error"].": ".$rply.$this->CRLF.'
'; + } + return false; + } + $msg_data=str_replace("\r\n","\n",$msg_data); + $msg_data=str_replace("\r","\n",$msg_data); + $lines=explode("\n",$msg_data); + $field=substr($lines[0],0,strpos($lines[0],":")); + $in_headers=false; + if(!empty($field)&&!strstr($field," ")){ + $in_headers=true; + } + $max_line_length=998; + while(list(,$line)=@each($lines)){ + $lines_out=null; + if($line==""&&$in_headers){ + $in_headers=false; + } + while(strlen($line)>$max_line_length){ + $pos=strrpos(substr($line,0,$max_line_length)," "); + if(!$pos){ + $pos=$max_line_length-1; + $lines_out[]=substr($line,0,$pos); + $line=substr($line,$pos); + }else{ + $lines_out[]=substr($line,0,$pos); + $line=substr($line,$pos+1); + } + if($in_headers){ + $line="\t".$line; + } + } + $lines_out[]=$line; + while(list(,$line_out)=@each($lines_out)){ + if(strlen($line_out)>0){ + if(substr($line_out,0,1)=="."){ + $line_out=".".$line_out; + } + } + fputs($this->smtp_conn,$line_out.$this->CRLF); + } + } + fputs($this->smtp_conn,$this->CRLF.".".$this->CRLF); + $rply=$this->get_lines(); + $code=substr($rply,0,3); + if($this->do_debug>=2){ + echo "SMTP -> FROM SERVER:".$rply.$this->CRLF.'
'; + } + if($code!=250){ + $this->error=array("error"=>"DATA not accepted from server","smtp_code"=>$code,"smtp_msg"=>substr($rply,4)); + if($this->do_debug>=1){ + echo "SMTP -> ERROR: ".$this->error["error"].": ".$rply.$this->CRLF.'
'; + } + return false; + } + return true; + } + public function Hello($host=''){ + $this->error=null; + if(!$this->connected()){ + $this->error=array("error"=>"Called Hello() without being connected"); + return false; + } + if(empty($host)){ + $host="localhost"; + } + if(!$this->SendHello("EHLO",$host)){ + if(!$this->SendHello("HELO",$host)){ + return false; + } + } + return true; + } + private function SendHello($hello,$host){ + fputs($this->smtp_conn,$hello." ".$host.$this->CRLF); + $rply=$this->get_lines(); + $code=substr($rply,0,3); + if($this->do_debug>=2){ + echo "SMTP -> FROM SERVER: ".$rply.$this->CRLF.'
'; + } + if($code!=250){ + $this->error=array("error"=>$hello." not accepted from server","smtp_code"=>$code,"smtp_msg"=>substr($rply,4)); + if($this->do_debug>=1){ + echo "SMTP -> ERROR: ".$this->error["error"].": ".$rply.$this->CRLF.'
'; + } + return false; + } + $this->helo_rply=$rply; + return true; + } + public function Mail($from){ + $this->error=null; + if(!$this->connected()){ + $this->error=array("error"=>"Called Mail() without being connected"); + return false; + } + $useVerp=($this->do_verp?"XVERP":""); + fputs($this->smtp_conn,"MAIL FROM:<".$from.">".$useVerp.$this->CRLF); + $rply=$this->get_lines(); + $code=substr($rply,0,3); + if($this->do_debug>=2){ + echo "SMTP -> FROM SERVER:".$rply.$this->CRLF.'
'; + } + if($code!=250){ + $this->error=array("error"=>"MAIL not accepted from server","smtp_code"=>$code,"smtp_msg"=>substr($rply,4)); + if($this->do_debug>=1){ + echo "SMTP -> ERROR: ".$this->error["error"].": ".$rply.$this->CRLF.'
'; + } + return false; + } + return true; + } + public function Quit($close_on_error=true){ + $this->error=null; + if(!$this->connected()){ + $this->error=array("error"=>"Called Quit() without being connected"); + return false; + } + fputs($this->smtp_conn,"quit".$this->CRLF); + $byemsg=$this->get_lines(); + if($this->do_debug>=2){ + echo "SMTP -> FROM SERVER:".$byemsg.$this->CRLF.'
'; + } + $rval=true; + $e=null; + $code=substr($byemsg,0,3); + if($code!=221){ + $e=array("error"=>"SMTP server rejected quit command","smtp_code"=>$code,"smtp_rply"=>substr($byemsg,4)); + $rval=false; + if($this->do_debug>=1){ + echo "SMTP -> ERROR: ".$e["error"].": ".$byemsg.$this->CRLF.'
'; + } + }if(empty($e)||$close_on_error){ + $this->Close(); + } + return $rval; + } + public function Recipient($to){ + $this->error=null; + if(!$this->connected()){ + $this->error=array("error"=>"Called Recipient() without being connected"); + return false; + } + fputs($this->smtp_conn,"RCPT TO:<".$to.">".$this->CRLF); + $rply=$this->get_lines(); + $code=substr($rply,0,3); + if($this->do_debug>=2){ + echo "SMTP -> FROM SERVER:".$rply.$this->CRLF.'
'; + } + if($code!=250&&$code!=251){ + $this->error=array("error"=>"RCPT not accepted from server","smtp_code"=>$code,"smtp_msg"=>substr($rply,4)); + if($this->do_debug>=1){ + echo "SMTP -> ERROR: ".$this->error["error"].": ".$rply.$this->CRLF.'
'; + } + return false; + } + return true; + } + public function Reset(){ + $this->error=null; + if(!$this->connected()){ + $this->error=array("error"=>"Called Reset() without being connected"); + return false; + } + fputs($this->smtp_conn,"RSET".$this->CRLF); + $rply=$this->get_lines(); + $code=substr($rply,0,3); + if($this->do_debug>=2){ + echo "SMTP -> FROM SERVER:".$rply.$this->CRLF.'
'; + } + if($code!=250){ + $this->error=array("error"=>"RSET failed","smtp_code"=>$code,"smtp_msg"=>substr($rply,4)); + if($this->do_debug>=1){ + echo "SMTP -> ERROR: ".$this->error["error"].": ".$rply.$this->CRLF.'
'; + } + return false; + } + return true; + } + public function SendAndMail($from){ + $this->error=null; + if(!$this->connected()){ + $this->error=array("error"=>"Called SendAndMail() without being connected"); + return false; + } + fputs($this->smtp_conn,"SAML FROM:".$from.$this->CRLF); + $rply=$this->get_lines(); + $code=substr($rply,0,3); + if($this->do_debug>=2){ + echo "SMTP -> FROM SERVER:".$rply.$this->CRLF.'
'; + } + if($code!=250){ + $this->error=array("error"=>"SAML not accepted from server","smtp_code"=>$code,"smtp_msg"=>substr($rply,4)); + if($this->do_debug>=1){ + echo "SMTP -> ERROR: ".$this->error["error"].": ".$rply.$this->CRLF.'
'; + } + return false; + } + return true; + } + public function Turn(){ + $this->error=array("error"=>"This method, TURN, of the SMTP "."is not implemented"); + if($this->do_debug>=1){ + echo "SMTP -> NOTICE: ".$this->error["error"].$this->CRLF.'
'; + } + return false; + } + public function getError(){ + return $this->error; + } + private function get_lines(){ + $data=""; + while($str=@fgets($this->smtp_conn,515)){ + $info = stream_get_meta_data($this->smtp_conn); + if($this->do_debug>=4){ + echo "SMTP -> get_lines(): \$data was \"$data\"".$this->CRLF.'
'; + echo "SMTP -> get_lines(): \$str is \"$str\"".$this->CRLF.'
'; + } + $data.=$str; + if($this->do_debug>=4){ + echo "SMTP -> get_lines(): \$data is \"$data\"".$this->CRLF.'
'; + } + if(substr($str,3,1)==" "){ + break; + } + } + return $data; + } +} + +function SendMail($address,$title,$message,$fromname='优优汇联',$img='',$file=''){ + $mail= new PHPMailer(true); + try { + $mail->IsSMTP(); + $mail->CharSet=C('MAIL_CHARSET'); + if(is_array($address)){ + foreach ($address as $v){ + $mail->AddAddress($v); + } + }else{ + $mail->AddAddress($address); + } + + $mail->Body=$message; + $mail->From= C('MAIL_ADDRESS'); + $mail->FromName=$fromname; + $mail->Subject=$title; + $mail->Host=C('MAIL_SMTP'); + $mail->SMTPAuth=C('MAIL_AUTH'); + $mail->Port=C('MAIL_PORT'); + $mail->SMTPSecure= C('MAIL_SECURE'); + $mail->Username=C('MAIL_LOGINNAME'); + $mail->Password=C('MAIL_PASSWORD'); + $mail->IsHTML(true); + $mail->MsgHTML($message); + return($mail->Send()); + } catch (phpmailerException $e) { + return $e->errorMessage(); + } catch (Exception $e) { + return $e->getMessage(); + } +} +?> \ No newline at end of file diff --git a/api/third_party/index.html b/api/third_party/index.html new file mode 100644 index 00000000..b702fbc3 --- /dev/null +++ b/api/third_party/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/api/views/errors/cli/error_404.php b/api/views/errors/cli/error_404.php index af8fecd0..6984b61e 100644 --- a/api/views/errors/cli/error_404.php +++ b/api/views/errors/cli/error_404.php @@ -1,8 +1,8 @@ - - -An uncaught Exception was encountered - -Type: -Message: -Filename: getFile(), "\n"; ?> -Line Number: getLine(); ?> - - - -Backtrace: -getTrace() as $error): ?> - - File: - Line: - Function: - - - - + + +An uncaught Exception was encountered + +Type: +Message: +Filename: getFile(), "\n"; ?> +Line Number: getLine(); ?> + + + +Backtrace: +getTrace() as $error): ?> + + File: + Line: + Function: + + + + diff --git a/api/views/errors/cli/error_general.php b/api/views/errors/cli/error_general.php index af8fecd0..6984b61e 100644 --- a/api/views/errors/cli/error_general.php +++ b/api/views/errors/cli/error_general.php @@ -1,8 +1,8 @@ - - -A PHP Error was encountered - -Severity: -Message: -Filename: -Line Number: - - - -Backtrace: - - - File: - Line: - Function: - - - - + + +A PHP Error was encountered + +Severity: +Message: +Filename: +Line Number: + + + +Backtrace: + + + File: + Line: + Function: + + + + diff --git a/api/views/errors/cli/index.html b/api/views/errors/cli/index.html index b48b4908..b702fbc3 100644 --- a/api/views/errors/cli/index.html +++ b/api/views/errors/cli/index.html @@ -1,11 +1,11 @@ - - - - 403 Forbidden - - - -

Directory access is forbidden.

- - - + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/api/views/errors/html/error_404.php b/api/views/errors/html/error_404.php index 38689d75..756ea9d6 100644 --- a/api/views/errors/html/error_404.php +++ b/api/views/errors/html/error_404.php @@ -1,64 +1,64 @@ - - - - -404 Page Not Found - - - -
-

- -
- + + + + +404 Page Not Found + + + +
+

+ +
+ \ No newline at end of file diff --git a/api/views/errors/html/error_db.php b/api/views/errors/html/error_db.php index 899d072b..f5a43f63 100644 --- a/api/views/errors/html/error_db.php +++ b/api/views/errors/html/error_db.php @@ -1,64 +1,64 @@ - - - - -Database Error - - - -
-

- -
- + + + + +Database Error + + + +
+

+ +
+ \ No newline at end of file diff --git a/api/views/errors/html/error_exception.php b/api/views/errors/html/error_exception.php index bde0dc3c..87848866 100644 --- a/api/views/errors/html/error_exception.php +++ b/api/views/errors/html/error_exception.php @@ -1,32 +1,32 @@ - - -
- -

An uncaught Exception was encountered

- -

Type:

-

Message:

-

Filename: getFile(); ?>

-

Line Number: getLine(); ?>

- - - -

Backtrace:

- getTrace() as $error): ?> - - - -

- File:
- Line:
- Function: -

- - - - - - + + +
+ +

An uncaught Exception was encountered

+ +

Type:

+

Message:

+

Filename: getFile(); ?>

+

Line Number: getLine(); ?>

+ + + +

Backtrace:

+ getTrace() as $error): ?> + + + +

+ File:
+ Line:
+ Function: +

+ + + + + +
\ No newline at end of file diff --git a/api/views/errors/html/error_general.php b/api/views/errors/html/error_general.php index 3a64a4f4..fc3b2eba 100644 --- a/api/views/errors/html/error_general.php +++ b/api/views/errors/html/error_general.php @@ -1,64 +1,64 @@ - - - - -Error - - - -
-

- -
- + + + + +Error + + + +
+

+ +
+ \ No newline at end of file diff --git a/api/views/errors/html/error_php.php b/api/views/errors/html/error_php.php index be4d2f14..b146f9c5 100644 --- a/api/views/errors/html/error_php.php +++ b/api/views/errors/html/error_php.php @@ -1,33 +1,33 @@ - - -
- -

A PHP Error was encountered

- -

Severity:

-

Message:

-

Filename:

-

Line Number:

- - - -

Backtrace:

- - - - -

- File:
- Line:
- Function: -

- - - - - - - + + +
+ +

A PHP Error was encountered

+ +

Severity:

+

Message:

+

Filename:

+

Line Number:

+ + + +

Backtrace:

+ + + + +

+ File:
+ Line:
+ Function: +

+ + + + + + +
\ No newline at end of file diff --git a/api/views/errors/html/index.html b/api/views/errors/html/index.html index b48b4908..b702fbc3 100644 --- a/api/views/errors/html/index.html +++ b/api/views/errors/html/index.html @@ -1,11 +1,11 @@ - - - - 403 Forbidden - - - -

Directory access is forbidden.

- - - + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/api/views/errors/index.html b/api/views/errors/index.html index b48b4908..b702fbc3 100644 --- a/api/views/errors/index.html +++ b/api/views/errors/index.html @@ -1,11 +1,11 @@ - - - - 403 Forbidden - - - -

Directory access is forbidden.

- - - + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/api/views/welcome_message.php b/api/views/welcome_message.php index ec5e39b5..d96a2668 100644 --- a/api/views/welcome_message.php +++ b/api/views/welcome_message.php @@ -1,45 +1,45 @@ - - - - - - 理车平台 - - - - - - - - - - - - - - - + + + + + + 狸车平台 + + + + + + + + + + + + + + + diff --git a/common/helpers/comm_helper.php b/common/helpers/comm_helper.php index adf47a9d..47c56e10 100644 --- a/common/helpers/comm_helper.php +++ b/common/helpers/comm_helper.php @@ -438,7 +438,8 @@ if (!function_exists('send_sms')) { require_once COMMPATH . '/third_party/alisms/alisms.php'; $template = 'SMS_218630210'; $alisms = new AliSms(); - $alisms->sendSms($mobile, array('code' => $code), $template, $sign); + $req = $alisms->sendSms($mobile, array('code' => $code), $template, $sign); + var_dump($req);exit; return true; } } diff --git a/common/models/receiver/Receiver_comments_model.php b/common/models/receiver/Receiver_comments_model.php new file mode 100644 index 00000000..3b106fd8 --- /dev/null +++ b/common/models/receiver/Receiver_comments_model.php @@ -0,0 +1,19 @@ +table_name, 'default'); + } + +} \ No newline at end of file diff --git a/common/models/receiver/Receiver_customers_model.php b/common/models/receiver/Receiver_customers_model.php index bb9e42f7..60fe9636 100644 --- a/common/models/receiver/Receiver_customers_model.php +++ b/common/models/receiver/Receiver_customers_model.php @@ -86,9 +86,9 @@ class Receiver_customers_model extends HD_Model public function offlineSources($id = 0) { - $arr[1] = ['name' => '空间站', 'list' => [1 => '汽车之家', 2 => '平安创展', 3 => '天天拍']]; - $arr[2] = ['name' => '营销中心', 'list' => [4 => '抖音本地通', 5 => '抖音拦截', 6 => '抖音直播', 7 => '微信视频号', 8 => '车卖场小程序']]; - $arr[3] = ['name' => '卫星门店', 'list' => [9 => '自然到店', 10 => '转介绍', 11 => '自媒体', 12 => '外展外拓', 13 => '汽车之家垂媒', 14 => '懂车帝垂媒', 15 => '易车垂媒']]; + $arr[1] = ['name' => '空间站', 'list' => [20 => '汽车之家', 21 => '平安创展', 22 => '天天拍']]; + $arr[2] = ['name' => '营销中心', 'list' => [30 => '抖音本地通', 31 => '抖音拦截', 32 => '抖音直播', 33 => '微信视频号', 34 => '车卖场小程序']]; + $arr[3] = ['name' => '卫星门店', 'list' => [40 => '自然到店', 41 => '转介绍', 42 => '自媒体', 43 => '外展外拓', 44 => '汽车之家垂媒', 45 => '懂车帝垂媒', 46 => '易车垂媒']]; if ($id) { return $arr[$id]; diff --git a/common/models/receiver/Receiver_customers_visit_data_model.php b/common/models/receiver/Receiver_customers_visit_data_model.php new file mode 100644 index 00000000..6a3fc571 --- /dev/null +++ b/common/models/receiver/Receiver_customers_visit_data_model.php @@ -0,0 +1,51 @@ +table_name, 'default'); + } + + //关联客户待回访 + public function count_visit($where) + { + return $this->select_visit($where, '', '', '', '', 1); + } + + public function select_visit($where = array(), $order = '', $page = 0, $page_size = 20, $fileds = '', $count = 0) + { + !$fileds && $fileds = 'a.*'; + $this->db->select($fileds); + $this->db->from('lc_receiver_customers as a'); + $this->db->join('lc_receiver_customer_visit_data as b', 'b.c_id = a.id', 'left'); + if ($where) { + $this->db->where($where); + } + if ($count) { + return $this->db->count_all_results(); + } + if ($order) { + $this->db->order_by($order); + } + if ($page) { + $offset = ($page - 1) * $page_size; + $limit = $page_size; + } else { + $offset = null; + $limit = null; + } + $this->db->limit($limit, $offset); + return $this->db->get()->result_array(); + } + +} \ No newline at end of file diff --git a/common/models/receiver/Receiver_customers_visit_model.php b/common/models/receiver/Receiver_customers_visit_model.php new file mode 100644 index 00000000..23b26a80 --- /dev/null +++ b/common/models/receiver/Receiver_customers_visit_model.php @@ -0,0 +1,51 @@ +table_name, 'default'); + } + + //关联客户待回访 + public function count_visit($where) + { + return $this->select_visit($where, '', '', '', '', 1); + } + + public function select_visit($where = array(), $order = '', $page = 0, $page_size = 20, $fileds = '', $count = 0) + { + !$fileds && $fileds = 'a.*'; + $this->db->select($fileds); + $this->db->from('lc_receiver_customers as a'); + $this->db->join('lc_receiver_customer_visit as b', 'b.c_id = a.id', 'left'); + if ($where) { + $this->db->where($where); + } + if ($count) { + return $this->db->count_all_results(); + } + if ($order) { + $this->db->order_by($order); + } + if ($page) { + $offset = ($page - 1) * $page_size; + $limit = $page_size; + } else { + $offset = null; + $limit = null; + } + $this->db->limit($limit, $offset); + return $this->db->get()->result_array(); + } + +}