Initial commit - Gowtham
This commit is contained in:
commit
c679f8e500
44
.env
Executable file
44
.env
Executable file
@ -0,0 +1,44 @@
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# ENVIRONMENT
|
||||
#--------------------------------------------------------------------
|
||||
|
||||
CI_ENVIRONMENT = development
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# APP
|
||||
#--------------------------------------------------------------------
|
||||
|
||||
app.baseURL = 'http://localhost/ts_tat/'
|
||||
|
||||
ORG_id = 1
|
||||
FE_URL = 'https://apitest.tripapprovaltool.com/tstat/index.html'
|
||||
encryption.key = 'e3bf95f0ef4a5d2707e9a84d44d50b33'
|
||||
|
||||
# IdP (Identity Provider)
|
||||
# IDP_EntityId = 'https://sts.windows.net/84750c4c-1e54-4d6d-9d5f-c395e8b1faf2/'; // Identity Provider Entity ID from the XML
|
||||
# IDP_SSOUrl = 'https://login.microsoftonline.com/84750c4c-1e54-4d6d-9d5f-c395e8b1faf2/saml2'; // Single Sign-On URL
|
||||
# IDP_SLOUrl = 'https://login.microsoftonline.com/84750c4c-1e54-4d6d-9d5f-c395e8b1faf2/saml2'; // Single Logout URL
|
||||
# IDP_X509Cert = 'MIIC8DCCAdigAwIBAgIQWleLECyLTpdMmXTERG7FojANBgkqhkiG9w0BAQsFADA0MTIwMAYDVQQDEylNaWNyb3NvZnQgQXp1cmUgRmVkZXJhdGVkIFNTTyBDZXJ0aWZpY2F0ZTAeFw0yNTAxMjEwNTQyMTZaFw0yODAxMjEwNTQyMTZaMDQxMjAwBgNVBAMTKU1pY3Jvc29mdCBBenVyZSBGZWRlcmF0ZWQgU1NPIENlcnRpZmljYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApJwYcfg/Fy3vuQ1LMWDKO4lNhnJenUZGDtE5KNjfAmR6ihCklQffrHF5DcTg5C72H62q1Me+Og2TnzOvUCepTUi88eoFh3rNfKyTcaKpcp7cx3lBy51iZIw5WYUqLz/547bA/m585bIVHMD8A3WiqOLUCaYoP8zbVb51uqa5+lPPscRj0DMAKuENf0FLvLbVLzFvWXH2VUbLJcErqumIb1eBg31rppcU+sS+wzNiZ8CIPPz0GpebQvcQpMR+OBbqG+jtDneyT9e20M9BHg303DTXsxxkAVHJiB8cUnFKHsDsfTuDtGvFXk/yUz9QP89SKDvxe6TlmrpeXyapPdZT/QIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQACOvBUZ+d0BHNXPB0DsekCciK0wXlhPZVTNzCKtCyIcmQWXd2vOhxUEt7qm90R92Gnb5r6BDpLD8ng2AkqYg5dSfgk8xq8oSSxbiQVLypFwOelH7B0bNbF4OdRAQnovFH78ZZG8agT73xYJpcod5dyNwHGJXi/X+A0mHtYNFjZb5Nj5DVPfaXbvp440i0mGrK1MX9pgoQnY5F2749dyZiedXFTpL0S6r4LOYtUUlxnI1CI+f7Zy2oaijh22yZp2PS5cTo9BDx+tJbv2jEhF4L1ITrJnCRlvdxeJD9lGnSE9CfsN6kRNzxuUNiUVM+/s1j0nB3k303OE5y2F/fCDzjx'; // Identity Provider's X.509 certificate
|
||||
|
||||
|
||||
IDP_EntityId = 'https://sts.windows.net/284bf2b6-6dd8-4b46-881c-de45fde35736/'; // Identity Provider Entity ID from the XML
|
||||
IDP_SSOUrl = 'https://login.microsoftonline.com/284bf2b6-6dd8-4b46-881c-de45fde35736/saml2'; // Single Sign-On URL
|
||||
IDP_SLOUrl = 'https://login.microsoftonline.com/284bf2b6-6dd8-4b46-881c-de45fde35736/saml2'; // Single Logout URL
|
||||
IDP_X509Cert = 'MIIC8DCCAdigAwIBAgIQZBsZqgPgSLRAMuQzWQDkDTANBgkqhkiG9w0BAQsFADA0MTIwMAYDVQQDEylNaWNyb3NvZnQgQXp1cmUgRmVkZXJhdGVkIFNTTyBDZXJ0aWZpY2F0ZTAeFw0yNTAxMjMxMjM4MTdaFw0yODAxMjMxMjM4MTdaMDQxMjAwBgNVBAMTKU1pY3Jvc29mdCBBenVyZSBGZWRlcmF0ZWQgU1NPIENlcnRpZmljYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApzTls3aSwJi8mYI78WsJRGg6cBdLkatWIYUqYPw8x1iTJ1GYPOuQdqk5PM34ybwHRTPcDjfHsIOjksvIrcOOtfXQ8MIqMaCYFcACqOAEM/Qb1pIvQBUT4TtiprzM01GzqFq5K7fYEftqKuQ+53yZFFb/xP/3CCWM8fRZOxoI9igexlaJT0MY0ics7Pi/kjPQt8OGncZMJhsiMmIzCJxDaj0dKAPaxZzpFZYkediw3SYbNa8Q18oA/zi32tT/0hC8DqWJkR+1i3DRwnp82wfH4BZDqPt6bgBlcs4V1WkVo+z6bX+HXIq1PGdIX6nPeKxMPupx3za+CIKVE8Jf3qX+zQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCUILtMUKA6u36R5FtgTT0KmxdIDRax+LJyzOW4GpS/cM2YJye2HR1HTaOmMLvthEp67hkseJjIfqDrT0ZZ56iiKblDUTDhvs2dHt1+gly3lBtL4AG0pvn/D7vSvCyN6cjUguQ6upwG/jhP5b6wbYH3hSkPq2cbq6GMU1JlGjVK2BhyseJ9dxsqetDkE1nWi4maPyjXisTM+QC9Y6VIMvfn+ZfSdZJsm6jeIlpXFDyefputXdtfyjlB9fcHYi0Udy15KGA9FOFBTrCnvuScF1tFBOJwvbx8jKJSNfHXim7laMhVmO8/RTrnyKxnXy5KO7mGcD8wQJy4nZreZTEACubu'; // Identity Provider's X.509 certificate
|
||||
|
||||
JWT_SECRET = b5f9d3a16e92e0f8e3c0f2b8e4d6f9a12234b5c6d7e8f9a0b1c2d3e4f5a6b7c8
|
||||
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# DATABASE
|
||||
#--------------------------------------------------------------------
|
||||
|
||||
database.default.hostname = '119.18.54.85'
|
||||
database.default.database = 'venbaehn_ts'
|
||||
database.default.username = 'venbaehn_ts'
|
||||
database.default.password = '9[b~~Ge9[f&;'
|
||||
|
||||
database.default.DBDriver = MySQLi
|
||||
database.default.DBPrefix =
|
||||
database.default.port = 3306
|
||||
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
# Ignore vendor folder
|
||||
/vendor/
|
||||
|
||||
# Ignore logs folder
|
||||
/writable/logs/
|
||||
/writable/debugbar/
|
||||
/writable/session/
|
||||
55
.htaccess
Executable file
55
.htaccess
Executable file
@ -0,0 +1,55 @@
|
||||
# Disable directory browsing
|
||||
Options -Indexes
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Rewrite engine
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# Turning on the rewrite engine is necessary for the following rules and features.
|
||||
# FollowSymLinks must be enabled for this to work.
|
||||
<IfModule mod_rewrite.c>
|
||||
Options +FollowSymlinks
|
||||
RewriteEngine On
|
||||
|
||||
# If you installed CodeIgniter in a subfolder, you will need to
|
||||
# change the following line to match the subfolder you need.
|
||||
# http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase
|
||||
# RewriteBase /
|
||||
|
||||
# Redirect Trailing Slashes...
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_URI} (.+)/$
|
||||
RewriteRule ^ %1 [L,R=301]
|
||||
|
||||
# Rewrite "www.example.com -> example.com"
|
||||
RewriteCond %{HTTPS} !=on
|
||||
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
|
||||
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
|
||||
|
||||
# Checks to see if the user is attempting to access a valid file,
|
||||
# such as an image or css document, if this isn't true it sends the
|
||||
# request to the front controller, index.php
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^([\s\S]*)$ index.php/$1 [L,NC,QSA]
|
||||
|
||||
# Ensure Authorization header is passed along
|
||||
RewriteCond %{HTTP:Authorization} .
|
||||
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
||||
</IfModule>
|
||||
|
||||
<IfModule !mod_rewrite.c>
|
||||
# If we don't have mod_rewrite installed, all 404's
|
||||
# can be sent to index.php, and everything works as normal.
|
||||
ErrorDocument 404 index.php
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_headers.c>
|
||||
Header set Access-Control-Allow-Origin "*"
|
||||
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE"
|
||||
Header set Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With"
|
||||
</IfModule>
|
||||
|
||||
# Disable server signature start
|
||||
ServerSignature Off
|
||||
# Disable server signature end
|
||||
22
LICENSE
Executable file
22
LICENSE
Executable file
@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2019 British Columbia Institute of Technology
|
||||
Copyright (c) 2019-present CodeIgniter Foundation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
60
README.md
Executable file
60
README.md
Executable file
@ -0,0 +1,60 @@
|
||||
# CodeIgniter 4 Framework
|
||||
|
||||
## What is CodeIgniter?
|
||||
|
||||
CodeIgniter is a PHP full-stack web framework that is light, fast, flexible and secure.
|
||||
More information can be found at the [official site](https://codeigniter.com).
|
||||
|
||||
This repository holds the distributable version of the framework.
|
||||
It has been built from the
|
||||
[development repository](https://github.com/codeigniter4/CodeIgniter4).
|
||||
|
||||
More information about the plans for version 4 can be found in [CodeIgniter 4](https://forum.codeigniter.com/forumdisplay.php?fid=28) on the forums.
|
||||
|
||||
You can read the [user guide](https://codeigniter.com/user_guide/)
|
||||
corresponding to the latest version of the framework.
|
||||
|
||||
## Important Change with index.php
|
||||
|
||||
`index.php` is no longer in the root of the project! It has been moved inside the *public* folder,
|
||||
for better security and separation of components.
|
||||
|
||||
This means that you should configure your web server to "point" to your project's *public* folder, and
|
||||
not to the project root. A better practice would be to configure a virtual host to point there. A poor practice would be to point your web server to the project root and expect to enter *public/...*, as the rest of your logic and the
|
||||
framework are exposed.
|
||||
|
||||
**Please** read the user guide for a better explanation of how CI4 works!
|
||||
|
||||
## Repository Management
|
||||
|
||||
We use GitHub issues, in our main repository, to track **BUGS** and to track approved **DEVELOPMENT** work packages.
|
||||
We use our [forum](http://forum.codeigniter.com) to provide SUPPORT and to discuss
|
||||
FEATURE REQUESTS.
|
||||
|
||||
This repository is a "distribution" one, built by our release preparation script.
|
||||
Problems with it can be raised on our forum, or as issues in the main repository.
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome contributions from the community.
|
||||
|
||||
Please read the [*Contributing to CodeIgniter*](https://github.com/codeigniter4/CodeIgniter4/blob/develop/CONTRIBUTING.md) section in the development repository.
|
||||
|
||||
## Server Requirements
|
||||
|
||||
PHP version 8.1 or higher is required, with the following extensions installed:
|
||||
|
||||
- [intl](http://php.net/manual/en/intl.requirements.php)
|
||||
- [mbstring](http://php.net/manual/en/mbstring.installation.php)
|
||||
|
||||
> [!WARNING]
|
||||
> - The end of life date for PHP 7.4 was November 28, 2022.
|
||||
> - The end of life date for PHP 8.0 was November 26, 2023.
|
||||
> - If you are still using PHP 7.4 or 8.0, you should upgrade immediately.
|
||||
> - The end of life date for PHP 8.1 will be December 31, 2025.
|
||||
|
||||
Additionally, make sure that the following extensions are enabled in your PHP:
|
||||
|
||||
- json (enabled by default - don't turn it off)
|
||||
- [mysqlnd](http://php.net/manual/en/mysqlnd.install.php) if you plan to use MySQL
|
||||
- [libcurl](http://php.net/manual/en/curl.requirements.php) if you plan to use the HTTP\CURLRequest library
|
||||
6
app/.htaccess
Executable file
6
app/.htaccess
Executable file
@ -0,0 +1,6 @@
|
||||
<IfModule authz_core_module>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
<IfModule !authz_core_module>
|
||||
Deny from all
|
||||
</IfModule>
|
||||
15
app/Common.php
Executable file
15
app/Common.php
Executable file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The goal of this file is to allow developers a location
|
||||
* where they can overwrite core procedural functions and
|
||||
* replace them with their own. This file is loaded during
|
||||
* the bootstrap process and is called during the framework's
|
||||
* execution.
|
||||
*
|
||||
* This can be looked at as a `master helper` file that is
|
||||
* loaded early on, and may also contain additional functions
|
||||
* that you'd like to use throughout your entire application
|
||||
*
|
||||
* @see: https://codeigniter.com/user_guide/extending/common.html
|
||||
*/
|
||||
202
app/Config/App.php
Executable file
202
app/Config/App.php
Executable file
@ -0,0 +1,202 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
class App extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Base Site URL
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* URL to your CodeIgniter root. Typically, this will be your base URL,
|
||||
* WITH a trailing slash:
|
||||
*
|
||||
* E.g., http://example.com/
|
||||
*/
|
||||
public string $baseURL = 'http://localhost:8080/';
|
||||
|
||||
/**
|
||||
* Allowed Hostnames in the Site URL other than the hostname in the baseURL.
|
||||
* If you want to accept multiple Hostnames, set this.
|
||||
*
|
||||
* E.g.,
|
||||
* When your site URL ($baseURL) is 'http://example.com/', and your site
|
||||
* also accepts 'http://media.example.com/' and 'http://accounts.example.com/':
|
||||
* ['media.example.com', 'accounts.example.com']
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
public array $allowedHostnames = [];
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Index File
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Typically, this will be your `index.php` file, unless you've renamed it to
|
||||
* something else. If you have configured your web server to remove this file
|
||||
* from your site URIs, set this variable to an empty string.
|
||||
*/
|
||||
public string $indexPage = 'index.php';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* URI PROTOCOL
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* This item determines which server global should be used to retrieve the
|
||||
* URI string. The default setting of 'REQUEST_URI' works for most servers.
|
||||
* If your links do not seem to work, try one of the other delicious flavors:
|
||||
*
|
||||
* 'REQUEST_URI': Uses $_SERVER['REQUEST_URI']
|
||||
* 'QUERY_STRING': Uses $_SERVER['QUERY_STRING']
|
||||
* 'PATH_INFO': Uses $_SERVER['PATH_INFO']
|
||||
*
|
||||
* WARNING: If you set this to 'PATH_INFO', URIs will always be URL-decoded!
|
||||
*/
|
||||
public string $uriProtocol = 'REQUEST_URI';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Allowed URL Characters
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This lets you specify which characters are permitted within your URLs.
|
||||
| When someone tries to submit a URL with disallowed characters they will
|
||||
| get a warning message.
|
||||
|
|
||||
| As a security measure you are STRONGLY encouraged to restrict URLs to
|
||||
| as few characters as possible.
|
||||
|
|
||||
| By default, only these are allowed: `a-z 0-9~%.:_-`
|
||||
|
|
||||
| Set an empty string to allow all characters -- but only if you are insane.
|
||||
|
|
||||
| The configured value is actually a regular expression character group
|
||||
| and it will be used as: '/\A[<permittedURIChars>]+\z/iu'
|
||||
|
|
||||
| DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!!
|
||||
|
|
||||
*/
|
||||
public string $permittedURIChars = 'a-z 0-9~%.:_\-';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Default Locale
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* The Locale roughly represents the language and location that your visitor
|
||||
* is viewing the site from. It affects the language strings and other
|
||||
* strings (like currency markers, numbers, etc), that your program
|
||||
* should run under for this request.
|
||||
*/
|
||||
public string $defaultLocale = 'en';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Negotiate Locale
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* If true, the current Request object will automatically determine the
|
||||
* language to use based on the value of the Accept-Language header.
|
||||
*
|
||||
* If false, no automatic detection will be performed.
|
||||
*/
|
||||
public bool $negotiateLocale = false;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Supported Locales
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* If $negotiateLocale is true, this array lists the locales supported
|
||||
* by the application in descending order of priority. If no match is
|
||||
* found, the first locale will be used.
|
||||
*
|
||||
* IncomingRequest::setLocale() also uses this list.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
public array $supportedLocales = ['en'];
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Application Timezone
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* The default timezone that will be used in your application to display
|
||||
* dates with the date helper, and can be retrieved through app_timezone()
|
||||
*
|
||||
* @see https://www.php.net/manual/en/timezones.php for list of timezones
|
||||
* supported by PHP.
|
||||
*/
|
||||
public string $appTimezone = 'UTC';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Default Character Set
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* This determines which character set is used by default in various methods
|
||||
* that require a character set to be provided.
|
||||
*
|
||||
* @see http://php.net/htmlspecialchars for a list of supported charsets.
|
||||
*/
|
||||
public string $charset = 'UTF-8';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Force Global Secure Requests
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* If true, this will force every request made to this application to be
|
||||
* made via a secure connection (HTTPS). If the incoming request is not
|
||||
* secure, the user will be redirected to a secure version of the page
|
||||
* and the HTTP Strict Transport Security (HSTS) header will be set.
|
||||
*/
|
||||
public bool $forceGlobalSecureRequests = 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
|
||||
* X-Forwarded-For or Client-IP in order to properly identify
|
||||
* the visitor's IP address.
|
||||
*
|
||||
* You need to set a proxy IP address or IP address with subnets and
|
||||
* the HTTP header for the client IP address.
|
||||
*
|
||||
* Here are some examples:
|
||||
* [
|
||||
* '10.0.1.200' => 'X-Forwarded-For',
|
||||
* '192.168.5.0/24' => 'X-Real-IP',
|
||||
* ]
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
public array $proxyIPs = [];
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Content Security Policy
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Enables the Response's Content Secure Policy to restrict the sources that
|
||||
* can be used for images, scripts, CSS files, audio, video, etc. If enabled,
|
||||
* the Response object will populate default values for the policy from the
|
||||
* `ContentSecurityPolicy.php` file. Controllers can always add to those
|
||||
* restrictions at run time.
|
||||
*
|
||||
* For a better understanding of CSP, see these documents:
|
||||
*
|
||||
* @see http://www.html5rocks.com/en/tutorials/security/content-security-policy/
|
||||
* @see http://www.w3.org/TR/CSP/
|
||||
*/
|
||||
public bool $CSPEnabled = false;
|
||||
}
|
||||
94
app/Config/Autoload.php
Executable file
94
app/Config/Autoload.php
Executable file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\AutoloadConfig;
|
||||
|
||||
/**
|
||||
* -------------------------------------------------------------------
|
||||
* AUTOLOADER CONFIGURATION
|
||||
* -------------------------------------------------------------------
|
||||
*
|
||||
* This file defines the namespaces and class maps so the Autoloader
|
||||
* can find the files as needed.
|
||||
*
|
||||
* NOTE: If you use an identical key in $psr4 or $classmap, then
|
||||
* the values in this file will overwrite the framework's values.
|
||||
*
|
||||
* NOTE: This class is required prior to Autoloader instantiation,
|
||||
* and does not extend BaseConfig.
|
||||
*
|
||||
* @immutable
|
||||
*/
|
||||
class Autoload extends AutoloadConfig
|
||||
{
|
||||
/**
|
||||
* -------------------------------------------------------------------
|
||||
* Namespaces
|
||||
* -------------------------------------------------------------------
|
||||
* This maps the locations of any namespaces in your application to
|
||||
* their location on the file system. These are used by the autoloader
|
||||
* to locate files the first time they have been instantiated.
|
||||
*
|
||||
* The 'Config' (APPPATH . 'Config') and 'CodeIgniter' (SYSTEMPATH) are
|
||||
* already mapped for you.
|
||||
*
|
||||
* You may change the name of the 'App' namespace if you wish,
|
||||
* but this should be done prior to creating any namespaced classes,
|
||||
* else you will need to modify all of those classes for this to work.
|
||||
*
|
||||
* @var array<string, list<string>|string>
|
||||
*/
|
||||
public $psr4 = [
|
||||
APP_NAMESPACE => APPPATH,
|
||||
];
|
||||
|
||||
/**
|
||||
* -------------------------------------------------------------------
|
||||
* Class Map
|
||||
* -------------------------------------------------------------------
|
||||
* The class map provides a map of class names and their exact
|
||||
* location on the drive. Classes loaded in this manner will have
|
||||
* slightly faster performance because they will not have to be
|
||||
* searched for within one or more directories as they would if they
|
||||
* were being autoloaded through a namespace.
|
||||
*
|
||||
* Prototype:
|
||||
* $classmap = [
|
||||
* 'MyClass' => '/path/to/class/file.php'
|
||||
* ];
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
public $classmap = [];
|
||||
|
||||
/**
|
||||
* -------------------------------------------------------------------
|
||||
* Files
|
||||
* -------------------------------------------------------------------
|
||||
* The files array provides a list of paths to __non-class__ files
|
||||
* that will be autoloaded. This can be useful for bootstrap operations
|
||||
* or for loading functions.
|
||||
*
|
||||
* Prototype:
|
||||
* $files = [
|
||||
* '/path/to/my/file.php',
|
||||
* ];
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
public $files = [];
|
||||
|
||||
/**
|
||||
* -------------------------------------------------------------------
|
||||
* Helpers
|
||||
* -------------------------------------------------------------------
|
||||
* Prototype:
|
||||
* $helpers = [
|
||||
* 'form',
|
||||
* ];
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
public $helpers = ['JwtHelper','common_helper','mail_helper','url_helper','status_helper'];
|
||||
}
|
||||
34
app/Config/Boot/development.php
Executable file
34
app/Config/Boot/development.php
Executable file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| ERROR DISPLAY
|
||||
|--------------------------------------------------------------------------
|
||||
| In development, we want to show as many errors as possible to help
|
||||
| make sure they don't make it to production. And save us hours of
|
||||
| painful debugging.
|
||||
|
|
||||
| If you set 'display_errors' to '1', CI4's detailed error report will show.
|
||||
*/
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', '1');
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| DEBUG BACKTRACES
|
||||
|--------------------------------------------------------------------------
|
||||
| If true, this constant will tell the error screens to display debug
|
||||
| backtraces along with the other error information. If you would
|
||||
| prefer to not see this, set this value to false.
|
||||
*/
|
||||
defined('SHOW_DEBUG_BACKTRACE') || define('SHOW_DEBUG_BACKTRACE', true);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| DEBUG MODE
|
||||
|--------------------------------------------------------------------------
|
||||
| Debug mode is an experimental flag that can allow changes throughout
|
||||
| the system. This will control whether Kint is loaded, and a few other
|
||||
| items. It can always be used within your own application too.
|
||||
*/
|
||||
defined('CI_DEBUG') || define('CI_DEBUG', true);
|
||||
25
app/Config/Boot/production.php
Executable file
25
app/Config/Boot/production.php
Executable file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| ERROR DISPLAY
|
||||
|--------------------------------------------------------------------------
|
||||
| Don't show ANY in production environments. Instead, let the system catch
|
||||
| it and display a generic error message.
|
||||
|
|
||||
| If you set 'display_errors' to '1', CI4's detailed error report will show.
|
||||
*/
|
||||
error_reporting(E_ALL & ~E_DEPRECATED);
|
||||
// If you want to suppress more types of errors.
|
||||
// error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED);
|
||||
ini_set('display_errors', '0');
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| DEBUG MODE
|
||||
|--------------------------------------------------------------------------
|
||||
| Debug mode is an experimental flag that can allow changes throughout
|
||||
| the system. It's not widely used currently, and may not survive
|
||||
| release of the framework.
|
||||
*/
|
||||
defined('CI_DEBUG') || define('CI_DEBUG', false);
|
||||
38
app/Config/Boot/testing.php
Executable file
38
app/Config/Boot/testing.php
Executable file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* The environment testing is reserved for PHPUnit testing. It has special
|
||||
* conditions built into the framework at various places to assist with that.
|
||||
* You can’t use it for your development.
|
||||
*/
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| ERROR DISPLAY
|
||||
|--------------------------------------------------------------------------
|
||||
| In development, we want to show as many errors as possible to help
|
||||
| make sure they don't make it to production. And save us hours of
|
||||
| painful debugging.
|
||||
*/
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', '1');
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| DEBUG BACKTRACES
|
||||
|--------------------------------------------------------------------------
|
||||
| If true, this constant will tell the error screens to display debug
|
||||
| backtraces along with the other error information. If you would
|
||||
| prefer to not see this, set this value to false.
|
||||
*/
|
||||
defined('SHOW_DEBUG_BACKTRACE') || define('SHOW_DEBUG_BACKTRACE', true);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| DEBUG MODE
|
||||
|--------------------------------------------------------------------------
|
||||
| Debug mode is an experimental flag that can allow changes throughout
|
||||
| the system. It's not widely used currently, and may not survive
|
||||
| release of the framework.
|
||||
*/
|
||||
defined('CI_DEBUG') || define('CI_DEBUG', true);
|
||||
20
app/Config/CURLRequest.php
Executable file
20
app/Config/CURLRequest.php
Executable file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
class CURLRequest extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* CURLRequest Share Options
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Whether share options between requests or not.
|
||||
*
|
||||
* If true, all the options won't be reset between requests.
|
||||
* It may cause an error request with unnecessary headers.
|
||||
*/
|
||||
public bool $shareOptions = false;
|
||||
}
|
||||
161
app/Config/Cache.php
Executable file
161
app/Config/Cache.php
Executable file
@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Cache\CacheInterface;
|
||||
use CodeIgniter\Cache\Handlers\DummyHandler;
|
||||
use CodeIgniter\Cache\Handlers\FileHandler;
|
||||
use CodeIgniter\Cache\Handlers\MemcachedHandler;
|
||||
use CodeIgniter\Cache\Handlers\PredisHandler;
|
||||
use CodeIgniter\Cache\Handlers\RedisHandler;
|
||||
use CodeIgniter\Cache\Handlers\WincacheHandler;
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
class Cache extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Primary Handler
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* The name of the preferred handler that should be used. If for some reason
|
||||
* it is not available, the $backupHandler will be used in its place.
|
||||
*/
|
||||
public string $handler = 'file';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Backup Handler
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* The name of the handler that will be used in case the first one is
|
||||
* unreachable. Often, 'file' is used here since the filesystem is
|
||||
* always available, though that's not always practical for the app.
|
||||
*/
|
||||
public string $backupHandler = 'dummy';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Key Prefix
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* This string is added to all cache item names to help avoid collisions
|
||||
* if you run multiple applications with the same cache engine.
|
||||
*/
|
||||
public string $prefix = '';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Default TTL
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* The default number of seconds to save items when none is specified.
|
||||
*
|
||||
* WARNING: This is not used by framework handlers where 60 seconds is
|
||||
* hard-coded, but may be useful to projects and modules. This will replace
|
||||
* the hard-coded value in a future release.
|
||||
*/
|
||||
public int $ttl = 60;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Reserved Characters
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* A string of reserved characters that will not be allowed in keys or tags.
|
||||
* Strings that violate this restriction will cause handlers to throw.
|
||||
* Default: {}()/\@:
|
||||
*
|
||||
* NOTE: The default set is required for PSR-6 compliance.
|
||||
*/
|
||||
public string $reservedCharacters = '{}()/\@:';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* File settings
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Your file storage preferences can be specified below, if you are using
|
||||
* the File driver.
|
||||
*
|
||||
* @var array<string, int|string|null>
|
||||
*/
|
||||
public array $file = [
|
||||
'storePath' => WRITEPATH . 'cache/',
|
||||
'mode' => 0640,
|
||||
];
|
||||
|
||||
/**
|
||||
* -------------------------------------------------------------------------
|
||||
* Memcached settings
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Your Memcached servers can be specified below, if you are using
|
||||
* the Memcached drivers.
|
||||
*
|
||||
* @see https://codeigniter.com/user_guide/libraries/caching.html#memcached
|
||||
*
|
||||
* @var array<string, bool|int|string>
|
||||
*/
|
||||
public array $memcached = [
|
||||
'host' => '127.0.0.1',
|
||||
'port' => 11211,
|
||||
'weight' => 1,
|
||||
'raw' => false,
|
||||
];
|
||||
|
||||
/**
|
||||
* -------------------------------------------------------------------------
|
||||
* Redis settings
|
||||
* -------------------------------------------------------------------------
|
||||
* Your Redis server can be specified below, if you are using
|
||||
* the Redis or Predis drivers.
|
||||
*
|
||||
* @var array<string, int|string|null>
|
||||
*/
|
||||
public array $redis = [
|
||||
'host' => '127.0.0.1',
|
||||
'password' => null,
|
||||
'port' => 6379,
|
||||
'timeout' => 0,
|
||||
'database' => 0,
|
||||
];
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Available Cache Handlers
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* This is an array of cache engine alias' and class names. Only engines
|
||||
* that are listed here are allowed to be used.
|
||||
*
|
||||
* @var array<string, class-string<CacheInterface>>
|
||||
*/
|
||||
public array $validHandlers = [
|
||||
'dummy' => DummyHandler::class,
|
||||
'file' => FileHandler::class,
|
||||
'memcached' => MemcachedHandler::class,
|
||||
'predis' => PredisHandler::class,
|
||||
'redis' => RedisHandler::class,
|
||||
'wincache' => WincacheHandler::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Web Page Caching: 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.
|
||||
* ['q'] = Enabled, but only take into account the specified list
|
||||
* of query parameters.
|
||||
*
|
||||
* @var bool|list<string>
|
||||
*/
|
||||
public $cacheQueryString = false;
|
||||
}
|
||||
79
app/Config/Constants.php
Executable file
79
app/Config/Constants.php
Executable file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
| --------------------------------------------------------------------
|
||||
| App Namespace
|
||||
| --------------------------------------------------------------------
|
||||
|
|
||||
| This defines the default Namespace that is used throughout
|
||||
| CodeIgniter to refer to the Application directory. Change
|
||||
| this constant to change the namespace that all application
|
||||
| classes should use.
|
||||
|
|
||||
| NOTE: changing this will require manually modifying the
|
||||
| existing namespaces of App\* namespaced-classes.
|
||||
*/
|
||||
defined('APP_NAMESPACE') || define('APP_NAMESPACE', 'App');
|
||||
|
||||
/*
|
||||
| --------------------------------------------------------------------------
|
||||
| Composer Path
|
||||
| --------------------------------------------------------------------------
|
||||
|
|
||||
| The path that Composer's autoload file is expected to live. By default,
|
||||
| the vendor folder is in the Root directory, but you can customize that here.
|
||||
*/
|
||||
defined('COMPOSER_PATH') || define('COMPOSER_PATH', ROOTPATH . 'vendor/autoload.php');
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Timing Constants
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Provide simple ways to work with the myriad of PHP functions that
|
||||
| require information to be in seconds.
|
||||
*/
|
||||
defined('SECOND') || define('SECOND', 1);
|
||||
defined('MINUTE') || define('MINUTE', 60);
|
||||
defined('HOUR') || define('HOUR', 3600);
|
||||
defined('DAY') || define('DAY', 86400);
|
||||
defined('WEEK') || define('WEEK', 604800);
|
||||
defined('MONTH') || define('MONTH', 2_592_000);
|
||||
defined('YEAR') || define('YEAR', 31_536_000);
|
||||
defined('DECADE') || define('DECADE', 315_360_000);
|
||||
|
||||
/*
|
||||
| --------------------------------------------------------------------------
|
||||
| Exit Status Codes
|
||||
| --------------------------------------------------------------------------
|
||||
|
|
||||
| Used to indicate the conditions under which the script is exit()ing.
|
||||
| While there is no universal standard for error codes, there are some
|
||||
| broad conventions. Three such conventions are mentioned below, for
|
||||
| those who wish to make use of them. The CodeIgniter defaults were
|
||||
| chosen for the least overlap with these conventions, while still
|
||||
| leaving room for others to be defined in future versions and user
|
||||
| applications.
|
||||
|
|
||||
| The three main conventions used for determining exit status codes
|
||||
| are as follows:
|
||||
|
|
||||
| Standard C/C++ Library (stdlibc):
|
||||
| http://www.gnu.org/software/libc/manual/html_node/Exit-Status.html
|
||||
| (This link also contains other GNU-specific conventions)
|
||||
| BSD sysexits.h:
|
||||
| http://www.gsp.com/cgi-bin/man.cgi?section=3&topic=sysexits
|
||||
| Bash scripting:
|
||||
| http://tldp.org/LDP/abs/html/exitcodes.html
|
||||
|
|
||||
*/
|
||||
defined('EXIT_SUCCESS') || define('EXIT_SUCCESS', 0); // no errors
|
||||
defined('EXIT_ERROR') || define('EXIT_ERROR', 1); // generic error
|
||||
defined('EXIT_CONFIG') || define('EXIT_CONFIG', 3); // configuration error
|
||||
defined('EXIT_UNKNOWN_FILE') || define('EXIT_UNKNOWN_FILE', 4); // file not found
|
||||
defined('EXIT_UNKNOWN_CLASS') || define('EXIT_UNKNOWN_CLASS', 5); // unknown class
|
||||
defined('EXIT_UNKNOWN_METHOD') || define('EXIT_UNKNOWN_METHOD', 6); // unknown class member
|
||||
defined('EXIT_USER_INPUT') || define('EXIT_USER_INPUT', 7); // invalid user input
|
||||
defined('EXIT_DATABASE') || define('EXIT_DATABASE', 8); // database error
|
||||
defined('EXIT__AUTO_MIN') || define('EXIT__AUTO_MIN', 9); // lowest automatically-assigned error code
|
||||
defined('EXIT__AUTO_MAX') || define('EXIT__AUTO_MAX', 125); // highest automatically-assigned error code
|
||||
176
app/Config/ContentSecurityPolicy.php
Executable file
176
app/Config/ContentSecurityPolicy.php
Executable file
@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
/**
|
||||
* Stores the default settings for the ContentSecurityPolicy, if you
|
||||
* choose to use it. The values here will be read in and set as defaults
|
||||
* for the site. If needed, they can be overridden on a page-by-page basis.
|
||||
*
|
||||
* Suggested reference for explanations:
|
||||
*
|
||||
* @see https://www.html5rocks.com/en/tutorials/security/content-security-policy/
|
||||
*/
|
||||
class ContentSecurityPolicy extends BaseConfig
|
||||
{
|
||||
// -------------------------------------------------------------------------
|
||||
// Broadbrush CSP management
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Default CSP report context
|
||||
*/
|
||||
public bool $reportOnly = false;
|
||||
|
||||
/**
|
||||
* Specifies a URL where a browser will send reports
|
||||
* when a content security policy is violated.
|
||||
*/
|
||||
public ?string $reportURI = null;
|
||||
|
||||
/**
|
||||
* Instructs user agents to rewrite URL schemes, changing
|
||||
* HTTP to HTTPS. This directive is for websites with
|
||||
* large numbers of old URLs that need to be rewritten.
|
||||
*/
|
||||
public bool $upgradeInsecureRequests = false;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Sources allowed
|
||||
// NOTE: once you set a policy to 'none', it cannot be further restricted
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Will default to self if not overridden
|
||||
*
|
||||
* @var list<string>|string|null
|
||||
*/
|
||||
public $defaultSrc;
|
||||
|
||||
/**
|
||||
* Lists allowed scripts' URLs.
|
||||
*
|
||||
* @var list<string>|string
|
||||
*/
|
||||
public $scriptSrc = 'self';
|
||||
|
||||
/**
|
||||
* Lists allowed stylesheets' URLs.
|
||||
*
|
||||
* @var list<string>|string
|
||||
*/
|
||||
public $styleSrc = 'self';
|
||||
|
||||
/**
|
||||
* Defines the origins from which images can be loaded.
|
||||
*
|
||||
* @var list<string>|string
|
||||
*/
|
||||
public $imageSrc = 'self';
|
||||
|
||||
/**
|
||||
* Restricts the URLs that can appear in a page's `<base>` element.
|
||||
*
|
||||
* Will default to self if not overridden
|
||||
*
|
||||
* @var list<string>|string|null
|
||||
*/
|
||||
public $baseURI;
|
||||
|
||||
/**
|
||||
* Lists the URLs for workers and embedded frame contents
|
||||
*
|
||||
* @var list<string>|string
|
||||
*/
|
||||
public $childSrc = 'self';
|
||||
|
||||
/**
|
||||
* Limits the origins that you can connect to (via XHR,
|
||||
* WebSockets, and EventSource).
|
||||
*
|
||||
* @var list<string>|string
|
||||
*/
|
||||
public $connectSrc = 'self';
|
||||
|
||||
/**
|
||||
* Specifies the origins that can serve web fonts.
|
||||
*
|
||||
* @var list<string>|string
|
||||
*/
|
||||
public $fontSrc;
|
||||
|
||||
/**
|
||||
* Lists valid endpoints for submission from `<form>` tags.
|
||||
*
|
||||
* @var list<string>|string
|
||||
*/
|
||||
public $formAction = 'self';
|
||||
|
||||
/**
|
||||
* Specifies the sources that can embed the current page.
|
||||
* This directive applies to `<frame>`, `<iframe>`, `<embed>`,
|
||||
* and `<applet>` tags. This directive can't be used in
|
||||
* `<meta>` tags and applies only to non-HTML resources.
|
||||
*
|
||||
* @var list<string>|string|null
|
||||
*/
|
||||
public $frameAncestors;
|
||||
|
||||
/**
|
||||
* The frame-src directive restricts the URLs which may
|
||||
* be loaded into nested browsing contexts.
|
||||
*
|
||||
* @var list<string>|string|null
|
||||
*/
|
||||
public $frameSrc;
|
||||
|
||||
/**
|
||||
* Restricts the origins allowed to deliver video and audio.
|
||||
*
|
||||
* @var list<string>|string|null
|
||||
*/
|
||||
public $mediaSrc;
|
||||
|
||||
/**
|
||||
* Allows control over Flash and other plugins.
|
||||
*
|
||||
* @var list<string>|string
|
||||
*/
|
||||
public $objectSrc = 'self';
|
||||
|
||||
/**
|
||||
* @var list<string>|string|null
|
||||
*/
|
||||
public $manifestSrc;
|
||||
|
||||
/**
|
||||
* Limits the kinds of plugins a page may invoke.
|
||||
*
|
||||
* @var list<string>|string|null
|
||||
*/
|
||||
public $pluginTypes;
|
||||
|
||||
/**
|
||||
* List of actions allowed.
|
||||
*
|
||||
* @var list<string>|string|null
|
||||
*/
|
||||
public $sandbox;
|
||||
|
||||
/**
|
||||
* Nonce tag for style
|
||||
*/
|
||||
public string $styleNonceTag = '{csp-style-nonce}';
|
||||
|
||||
/**
|
||||
* Nonce tag for script
|
||||
*/
|
||||
public string $scriptNonceTag = '{csp-script-nonce}';
|
||||
|
||||
/**
|
||||
* Replace nonce tag automatically
|
||||
*/
|
||||
public bool $autoNonce = true;
|
||||
}
|
||||
107
app/Config/Cookie.php
Executable file
107
app/Config/Cookie.php
Executable file
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
use DateTimeInterface;
|
||||
|
||||
class Cookie extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Cookie Prefix
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Set a cookie name prefix if you need to avoid collisions.
|
||||
*/
|
||||
public string $prefix = '';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Cookie Expires Timestamp
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Default expires timestamp for cookies. Setting this to `0` will mean the
|
||||
* cookie will not have the `Expires` attribute and will behave as a session
|
||||
* cookie.
|
||||
*
|
||||
* @var DateTimeInterface|int|string
|
||||
*/
|
||||
public $expires = 0;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Cookie Path
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Typically will be a forward slash.
|
||||
*/
|
||||
public string $path = '/';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Cookie Domain
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Set to `.your-domain.com` for site-wide cookies.
|
||||
*/
|
||||
public string $domain = '';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Cookie Secure
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Cookie will only be set if a secure HTTPS connection exists.
|
||||
*/
|
||||
public bool $secure = false;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Cookie HTTPOnly
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Cookie will only be accessible via HTTP(S) (no JavaScript).
|
||||
*/
|
||||
public bool $httponly = true;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Cookie SameSite
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Configure cookie SameSite setting. Allowed values are:
|
||||
* - None
|
||||
* - Lax
|
||||
* - Strict
|
||||
* - ''
|
||||
*
|
||||
* Alternatively, you can use the constant names:
|
||||
* - `Cookie::SAMESITE_NONE`
|
||||
* - `Cookie::SAMESITE_LAX`
|
||||
* - `Cookie::SAMESITE_STRICT`
|
||||
*
|
||||
* Defaults to `Lax` for compatibility with modern browsers. Setting `''`
|
||||
* (empty string) means default SameSite attribute set by browsers (`Lax`)
|
||||
* will be set on cookies. If set to `None`, `$secure` must also be set.
|
||||
*
|
||||
* @phpstan-var 'None'|'Lax'|'Strict'|''
|
||||
*/
|
||||
public string $samesite = 'Lax';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Cookie Raw
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* This flag allows setting a "raw" cookie, i.e., its name and value are
|
||||
* not URL encoded using `rawurlencode()`.
|
||||
*
|
||||
* If this is set to `true`, cookie names should be compliant of RFC 2616's
|
||||
* list of allowed characters.
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#attributes
|
||||
* @see https://tools.ietf.org/html/rfc2616#section-2.2
|
||||
*/
|
||||
public bool $raw = false;
|
||||
}
|
||||
105
app/Config/Cors.php
Executable file
105
app/Config/Cors.php
Executable file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
/**
|
||||
* Cross-Origin Resource Sharing (CORS) Configuration
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
||||
*/
|
||||
class Cors extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* The default CORS configuration.
|
||||
*
|
||||
* @var array{
|
||||
* allowedOrigins: list<string>,
|
||||
* allowedOriginsPatterns: list<string>,
|
||||
* supportsCredentials: bool,
|
||||
* allowedHeaders: list<string>,
|
||||
* exposedHeaders: list<string>,
|
||||
* allowedMethods: list<string>,
|
||||
* maxAge: int,
|
||||
* }
|
||||
*/
|
||||
public array $default = [
|
||||
/**
|
||||
* Origins for the `Access-Control-Allow-Origin` header.
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
|
||||
*
|
||||
* E.g.:
|
||||
* - ['http://localhost:8080']
|
||||
* - ['https://www.example.com']
|
||||
*/
|
||||
'allowedOrigins' => [],
|
||||
|
||||
/**
|
||||
* Origin regex patterns for the `Access-Control-Allow-Origin` header.
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
|
||||
*
|
||||
* NOTE: A pattern specified here is part of a regular expression. It will
|
||||
* be actually `#\A<pattern>\z#`.
|
||||
*
|
||||
* E.g.:
|
||||
* - ['https://\w+\.example\.com']
|
||||
*/
|
||||
'allowedOriginsPatterns' => [],
|
||||
|
||||
/**
|
||||
* Weather to send the `Access-Control-Allow-Credentials` header.
|
||||
*
|
||||
* The Access-Control-Allow-Credentials response header tells browsers whether
|
||||
* the server allows cross-origin HTTP requests to include credentials.
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials
|
||||
*/
|
||||
'supportsCredentials' => false,
|
||||
|
||||
/**
|
||||
* Set headers to allow.
|
||||
*
|
||||
* The Access-Control-Allow-Headers response header is used in response to
|
||||
* a preflight request which includes the Access-Control-Request-Headers to
|
||||
* indicate which HTTP headers can be used during the actual request.
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
|
||||
*/
|
||||
'allowedHeaders' => [],
|
||||
|
||||
/**
|
||||
* Set headers to expose.
|
||||
*
|
||||
* The Access-Control-Expose-Headers response header allows a server to
|
||||
* indicate which response headers should be made available to scripts running
|
||||
* in the browser, in response to a cross-origin request.
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers
|
||||
*/
|
||||
'exposedHeaders' => [],
|
||||
|
||||
/**
|
||||
* Set methods to allow.
|
||||
*
|
||||
* The Access-Control-Allow-Methods response header specifies one or more
|
||||
* methods allowed when accessing a resource in response to a preflight
|
||||
* request.
|
||||
*
|
||||
* E.g.:
|
||||
* - ['GET', 'POST', 'PUT', 'DELETE']
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
|
||||
*/
|
||||
'allowedMethods' => [],
|
||||
|
||||
/**
|
||||
* Set how many seconds the results of a preflight request can be cached.
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
|
||||
*/
|
||||
'maxAge' => 7200,
|
||||
];
|
||||
}
|
||||
203
app/Config/Database.php
Executable file
203
app/Config/Database.php
Executable file
@ -0,0 +1,203 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Database\Config;
|
||||
|
||||
/**
|
||||
* Database Configuration
|
||||
*/
|
||||
class Database extends Config
|
||||
{
|
||||
/**
|
||||
* The directory that holds the Migrations and Seeds directories.
|
||||
*/
|
||||
public string $filesPath = APPPATH . 'Database' . DIRECTORY_SEPARATOR;
|
||||
|
||||
/**
|
||||
* Lets you choose which connection group to use if no other is specified.
|
||||
*/
|
||||
public string $defaultGroup = 'default';
|
||||
|
||||
/**
|
||||
* The default database connection.
|
||||
*
|
||||
* @var array<string, mixed>
|
||||
*/
|
||||
public array $default = [
|
||||
'DSN' => '',
|
||||
'hostname' => 'localhost',
|
||||
'username' => '',
|
||||
'password' => '',
|
||||
'database' => '',
|
||||
'DBDriver' => 'MySQLi',
|
||||
'DBPrefix' => '',
|
||||
'pConnect' => false,
|
||||
'DBDebug' => true,
|
||||
'charset' => 'utf8mb4',
|
||||
'DBCollat' => 'utf8mb4_general_ci',
|
||||
'swapPre' => '',
|
||||
'encrypt' => false,
|
||||
'compress' => false,
|
||||
'strictOn' => false,
|
||||
'failover' => [],
|
||||
'port' => 3306,
|
||||
'numberNative' => false,
|
||||
'foundRows' => false,
|
||||
'dateFormat' => [
|
||||
'date' => 'Y-m-d',
|
||||
'datetime' => 'Y-m-d H:i:s',
|
||||
'time' => 'H:i:s',
|
||||
],
|
||||
];
|
||||
|
||||
// /**
|
||||
// * Sample database connection for SQLite3.
|
||||
// *
|
||||
// * @var array<string, mixed>
|
||||
// */
|
||||
// public array $default = [
|
||||
// 'database' => 'database.db',
|
||||
// 'DBDriver' => 'SQLite3',
|
||||
// 'DBPrefix' => '',
|
||||
// 'DBDebug' => true,
|
||||
// 'swapPre' => '',
|
||||
// 'failover' => [],
|
||||
// 'foreignKeys' => true,
|
||||
// 'busyTimeout' => 1000,
|
||||
// 'synchronous' => null,
|
||||
// 'dateFormat' => [
|
||||
// 'date' => 'Y-m-d',
|
||||
// 'datetime' => 'Y-m-d H:i:s',
|
||||
// 'time' => 'H:i:s',
|
||||
// ],
|
||||
// ];
|
||||
|
||||
// /**
|
||||
// * Sample database connection for Postgre.
|
||||
// *
|
||||
// * @var array<string, mixed>
|
||||
// */
|
||||
// public array $default = [
|
||||
// 'DSN' => '',
|
||||
// 'hostname' => 'localhost',
|
||||
// 'username' => 'root',
|
||||
// 'password' => 'root',
|
||||
// 'database' => 'ci4',
|
||||
// 'schema' => 'public',
|
||||
// 'DBDriver' => 'Postgre',
|
||||
// 'DBPrefix' => '',
|
||||
// 'pConnect' => false,
|
||||
// 'DBDebug' => true,
|
||||
// 'charset' => 'utf8',
|
||||
// 'swapPre' => '',
|
||||
// 'failover' => [],
|
||||
// 'port' => 5432,
|
||||
// 'dateFormat' => [
|
||||
// 'date' => 'Y-m-d',
|
||||
// 'datetime' => 'Y-m-d H:i:s',
|
||||
// 'time' => 'H:i:s',
|
||||
// ],
|
||||
// ];
|
||||
|
||||
// /**
|
||||
// * Sample database connection for SQLSRV.
|
||||
// *
|
||||
// * @var array<string, mixed>
|
||||
// */
|
||||
// public array $default = [
|
||||
// 'DSN' => '',
|
||||
// 'hostname' => 'localhost',
|
||||
// 'username' => 'root',
|
||||
// 'password' => 'root',
|
||||
// 'database' => 'ci4',
|
||||
// 'schema' => 'dbo',
|
||||
// 'DBDriver' => 'SQLSRV',
|
||||
// 'DBPrefix' => '',
|
||||
// 'pConnect' => false,
|
||||
// 'DBDebug' => true,
|
||||
// 'charset' => 'utf8',
|
||||
// 'swapPre' => '',
|
||||
// 'encrypt' => false,
|
||||
// 'failover' => [],
|
||||
// 'port' => 1433,
|
||||
// 'dateFormat' => [
|
||||
// 'date' => 'Y-m-d',
|
||||
// 'datetime' => 'Y-m-d H:i:s',
|
||||
// 'time' => 'H:i:s',
|
||||
// ],
|
||||
// ];
|
||||
|
||||
// /**
|
||||
// * Sample database connection for OCI8.
|
||||
// *
|
||||
// * You may need the following environment variables:
|
||||
// * NLS_LANG = 'AMERICAN_AMERICA.UTF8'
|
||||
// * NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'
|
||||
// * NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS'
|
||||
// * NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SS'
|
||||
// *
|
||||
// * @var array<string, mixed>
|
||||
// */
|
||||
// public array $default = [
|
||||
// 'DSN' => 'localhost:1521/XEPDB1',
|
||||
// 'username' => 'root',
|
||||
// 'password' => 'root',
|
||||
// 'DBDriver' => 'OCI8',
|
||||
// 'DBPrefix' => '',
|
||||
// 'pConnect' => false,
|
||||
// 'DBDebug' => true,
|
||||
// 'charset' => 'AL32UTF8',
|
||||
// 'swapPre' => '',
|
||||
// 'failover' => [],
|
||||
// 'dateFormat' => [
|
||||
// 'date' => 'Y-m-d',
|
||||
// 'datetime' => 'Y-m-d H:i:s',
|
||||
// 'time' => 'H:i:s',
|
||||
// ],
|
||||
// ];
|
||||
|
||||
/**
|
||||
* This database connection is used when running PHPUnit database tests.
|
||||
*
|
||||
* @var array<string, mixed>
|
||||
*/
|
||||
public array $tests = [
|
||||
'DSN' => '',
|
||||
'hostname' => '127.0.0.1',
|
||||
'username' => '',
|
||||
'password' => '',
|
||||
'database' => ':memory:',
|
||||
'DBDriver' => 'SQLite3',
|
||||
'DBPrefix' => 'db_', // Needed to ensure we're working correctly with prefixes live. DO NOT REMOVE FOR CI DEVS
|
||||
'pConnect' => false,
|
||||
'DBDebug' => true,
|
||||
'charset' => 'utf8',
|
||||
'DBCollat' => '',
|
||||
'swapPre' => '',
|
||||
'encrypt' => false,
|
||||
'compress' => false,
|
||||
'strictOn' => false,
|
||||
'failover' => [],
|
||||
'port' => 3306,
|
||||
'foreignKeys' => true,
|
||||
'busyTimeout' => 1000,
|
||||
'dateFormat' => [
|
||||
'date' => 'Y-m-d',
|
||||
'datetime' => 'Y-m-d H:i:s',
|
||||
'time' => 'H:i:s',
|
||||
],
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// Ensure that we always set the database group to 'tests' if
|
||||
// we are currently running an automated test suite, so that
|
||||
// we don't overwrite live data on accident.
|
||||
if (ENVIRONMENT === 'testing') {
|
||||
$this->defaultGroup = 'tests';
|
||||
}
|
||||
}
|
||||
}
|
||||
46
app/Config/DocTypes.php
Executable file
46
app/Config/DocTypes.php
Executable file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
/**
|
||||
* @immutable
|
||||
*/
|
||||
class DocTypes
|
||||
{
|
||||
/**
|
||||
* List of valid document types.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
public array $list = [
|
||||
'xhtml11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
|
||||
'xhtml1-strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
|
||||
'xhtml1-trans' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
|
||||
'xhtml1-frame' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
|
||||
'xhtml-basic11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',
|
||||
'html5' => '<!DOCTYPE html>',
|
||||
'html4-strict' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
|
||||
'html4-trans' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
|
||||
'html4-frame' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">',
|
||||
'mathml1' => '<!DOCTYPE math SYSTEM "http://www.w3.org/Math/DTD/mathml1/mathml.dtd">',
|
||||
'mathml2' => '<!DOCTYPE math PUBLIC "-//W3C//DTD MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/mathml2.dtd">',
|
||||
'svg10' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">',
|
||||
'svg11' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">',
|
||||
'svg11-basic' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">',
|
||||
'svg11-tiny' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">',
|
||||
'xhtml-math-svg-xh' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">',
|
||||
'xhtml-math-svg-sh' => '<!DOCTYPE svg:svg PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">',
|
||||
'xhtml-rdfa-1' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">',
|
||||
'xhtml-rdfa-2' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.1//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd">',
|
||||
];
|
||||
|
||||
/**
|
||||
* Whether to remove the solidus (`/`) character for void HTML elements (e.g. `<input>`)
|
||||
* for HTML5 compatibility.
|
||||
*
|
||||
* Set to:
|
||||
* `true` - to be HTML5 compatible
|
||||
* `false` - to be XHTML compatible
|
||||
*/
|
||||
public bool $html5 = true;
|
||||
}
|
||||
121
app/Config/Email.php
Executable file
121
app/Config/Email.php
Executable file
@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
class Email extends BaseConfig
|
||||
{
|
||||
public string $fromEmail = '';
|
||||
public string $fromName = '';
|
||||
public string $recipients = '';
|
||||
|
||||
/**
|
||||
* The "user agent"
|
||||
*/
|
||||
public string $userAgent = 'CodeIgniter';
|
||||
|
||||
/**
|
||||
* The mail sending protocol: mail, sendmail, smtp
|
||||
*/
|
||||
public string $protocol = 'mail';
|
||||
|
||||
/**
|
||||
* The server path to Sendmail.
|
||||
*/
|
||||
public string $mailPath = '/usr/sbin/sendmail';
|
||||
|
||||
/**
|
||||
* SMTP Server Hostname
|
||||
*/
|
||||
public string $SMTPHost = '';
|
||||
|
||||
/**
|
||||
* SMTP Username
|
||||
*/
|
||||
public string $SMTPUser = '';
|
||||
|
||||
/**
|
||||
* SMTP Password
|
||||
*/
|
||||
public string $SMTPPass = '';
|
||||
|
||||
/**
|
||||
* SMTP Port
|
||||
*/
|
||||
public int $SMTPPort = 25;
|
||||
|
||||
/**
|
||||
* SMTP Timeout (in seconds)
|
||||
*/
|
||||
public int $SMTPTimeout = 5;
|
||||
|
||||
/**
|
||||
* Enable persistent SMTP connections
|
||||
*/
|
||||
public bool $SMTPKeepAlive = false;
|
||||
|
||||
/**
|
||||
* SMTP Encryption.
|
||||
*
|
||||
* @var string '', 'tls' or 'ssl'. 'tls' will issue a STARTTLS command
|
||||
* to the server. 'ssl' means implicit SSL. Connection on port
|
||||
* 465 should set this to ''.
|
||||
*/
|
||||
public string $SMTPCrypto = 'tls';
|
||||
|
||||
/**
|
||||
* Enable word-wrap
|
||||
*/
|
||||
public bool $wordWrap = true;
|
||||
|
||||
/**
|
||||
* Character count to wrap at
|
||||
*/
|
||||
public int $wrapChars = 76;
|
||||
|
||||
/**
|
||||
* Type of mail, either 'text' or 'html'
|
||||
*/
|
||||
public string $mailType = 'text';
|
||||
|
||||
/**
|
||||
* Character set (utf-8, iso-8859-1, etc.)
|
||||
*/
|
||||
public string $charset = 'UTF-8';
|
||||
|
||||
/**
|
||||
* Whether to validate the email address
|
||||
*/
|
||||
public bool $validate = false;
|
||||
|
||||
/**
|
||||
* Email Priority. 1 = highest. 5 = lowest. 3 = normal
|
||||
*/
|
||||
public int $priority = 3;
|
||||
|
||||
/**
|
||||
* Newline character. (Use “\r\n” to comply with RFC 822)
|
||||
*/
|
||||
public string $CRLF = "\r\n";
|
||||
|
||||
/**
|
||||
* Newline character. (Use “\r\n” to comply with RFC 822)
|
||||
*/
|
||||
public string $newline = "\r\n";
|
||||
|
||||
/**
|
||||
* Enable BCC Batch Mode.
|
||||
*/
|
||||
public bool $BCCBatchMode = false;
|
||||
|
||||
/**
|
||||
* Number of emails in each BCC batch
|
||||
*/
|
||||
public int $BCCBatchSize = 200;
|
||||
|
||||
/**
|
||||
* Enable notify message from server
|
||||
*/
|
||||
public bool $DSN = false;
|
||||
}
|
||||
92
app/Config/Encryption.php
Executable file
92
app/Config/Encryption.php
Executable file
@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
/**
|
||||
* Encryption configuration.
|
||||
*
|
||||
* These are the settings used for encryption, if you don't pass a parameter
|
||||
* array to the encrypter for creation/initialization.
|
||||
*/
|
||||
class Encryption extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Encryption Key Starter
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* If you use the Encryption class you must set an encryption key (seed).
|
||||
* You need to ensure it is long enough for the cipher and mode you plan to use.
|
||||
* See the user guide for more info.
|
||||
*/
|
||||
public string $key = '';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Encryption Driver to Use
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* One of the supported encryption drivers.
|
||||
*
|
||||
* Available drivers:
|
||||
* - OpenSSL
|
||||
* - Sodium
|
||||
*/
|
||||
public string $driver = 'OpenSSL';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* SodiumHandler's Padding Length in Bytes
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* This is the number of bytes that will be padded to the plaintext message
|
||||
* before it is encrypted. This value should be greater than zero.
|
||||
*
|
||||
* See the user guide for more information on padding.
|
||||
*/
|
||||
public int $blockSize = 16;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Encryption digest
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* HMAC digest to use, e.g. 'SHA512' or 'SHA256'. Default value is 'SHA512'.
|
||||
*/
|
||||
public string $digest = 'SHA512';
|
||||
|
||||
/**
|
||||
* Whether the cipher-text should be raw. If set to false, then it will be base64 encoded.
|
||||
* This setting is only used by OpenSSLHandler.
|
||||
*
|
||||
* Set to false for CI3 Encryption compatibility.
|
||||
*/
|
||||
public bool $rawData = true;
|
||||
|
||||
/**
|
||||
* Encryption key info.
|
||||
* This setting is only used by OpenSSLHandler.
|
||||
*
|
||||
* Set to 'encryption' for CI3 Encryption compatibility.
|
||||
*/
|
||||
public string $encryptKeyInfo = '';
|
||||
|
||||
/**
|
||||
* Authentication key info.
|
||||
* This setting is only used by OpenSSLHandler.
|
||||
*
|
||||
* Set to 'authentication' for CI3 Encryption compatibility.
|
||||
*/
|
||||
public string $authKeyInfo = '';
|
||||
|
||||
/**
|
||||
* Cipher to use.
|
||||
* This setting is only used by OpenSSLHandler.
|
||||
*
|
||||
* Set to 'AES-128-CBC' to decrypt encrypted data that encrypted
|
||||
* by CI3 Encryption default configuration.
|
||||
*/
|
||||
public string $cipher = 'AES-256-CTR';
|
||||
}
|
||||
55
app/Config/Events.php
Executable file
55
app/Config/Events.php
Executable file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Events\Events;
|
||||
use CodeIgniter\Exceptions\FrameworkException;
|
||||
use CodeIgniter\HotReloader\HotReloader;
|
||||
|
||||
/*
|
||||
* --------------------------------------------------------------------
|
||||
* Application Events
|
||||
* --------------------------------------------------------------------
|
||||
* Events allow you to tap into the execution of the program without
|
||||
* modifying or extending core files. This file provides a central
|
||||
* location to define your events, though they can always be added
|
||||
* at run-time, also, if needed.
|
||||
*
|
||||
* You create code that can execute by subscribing to events with
|
||||
* the 'on()' method. This accepts any form of callable, including
|
||||
* Closures, that will be executed when the event is triggered.
|
||||
*
|
||||
* Example:
|
||||
* Events::on('create', [$myInstance, 'myMethod']);
|
||||
*/
|
||||
|
||||
Events::on('pre_system', static function (): void {
|
||||
if (ENVIRONMENT !== 'testing') {
|
||||
if (ini_get('zlib.output_compression')) {
|
||||
throw FrameworkException::forEnabledZlibOutputCompression();
|
||||
}
|
||||
|
||||
while (ob_get_level() > 0) {
|
||||
ob_end_flush();
|
||||
}
|
||||
|
||||
ob_start(static fn ($buffer) => $buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* --------------------------------------------------------------------
|
||||
* Debug Toolbar Listeners.
|
||||
* --------------------------------------------------------------------
|
||||
* If you delete, they will no longer be collected.
|
||||
*/
|
||||
if (CI_DEBUG && ! is_cli()) {
|
||||
Events::on('DBQuery', 'CodeIgniter\Debug\Toolbar\Collectors\Database::collect');
|
||||
service('toolbar')->respond();
|
||||
// Hot Reload route - for framework use on the hot reloader.
|
||||
if (ENVIRONMENT === 'development') {
|
||||
service('routes')->get('__hot-reload', static function (): void {
|
||||
(new HotReloader())->run();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
106
app/Config/Exceptions.php
Executable file
106
app/Config/Exceptions.php
Executable file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
use CodeIgniter\Debug\ExceptionHandler;
|
||||
use CodeIgniter\Debug\ExceptionHandlerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Setup how the exception handler works.
|
||||
*/
|
||||
class Exceptions extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* LOG EXCEPTIONS?
|
||||
* --------------------------------------------------------------------------
|
||||
* If true, then exceptions will be logged
|
||||
* through Services::Log.
|
||||
*
|
||||
* Default: true
|
||||
*/
|
||||
public bool $log = true;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* DO NOT LOG STATUS CODES
|
||||
* --------------------------------------------------------------------------
|
||||
* Any status codes here will NOT be logged if logging is turned on.
|
||||
* By default, only 404 (Page Not Found) exceptions are ignored.
|
||||
*
|
||||
* @var list<int>
|
||||
*/
|
||||
public array $ignoreCodes = [404];
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Error Views Path
|
||||
* --------------------------------------------------------------------------
|
||||
* This is the path to the directory that contains the 'cli' and 'html'
|
||||
* directories that hold the views used to generate errors.
|
||||
*
|
||||
* Default: APPPATH.'Views/errors'
|
||||
*/
|
||||
public string $errorViewPath = APPPATH . 'Views/errors';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* HIDE FROM DEBUG TRACE
|
||||
* --------------------------------------------------------------------------
|
||||
* Any data that you would like to hide from the debug trace.
|
||||
* In order to specify 2 levels, use "/" to separate.
|
||||
* ex. ['server', 'setup/password', 'secret_token']
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
public array $sensitiveDataInTrace = [];
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* WHETHER TO THROW AN EXCEPTION ON DEPRECATED ERRORS
|
||||
* --------------------------------------------------------------------------
|
||||
* If set to `true`, DEPRECATED errors are only logged and no exceptions are
|
||||
* thrown. This option also works for user deprecations.
|
||||
*/
|
||||
public bool $logDeprecations = true;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* LOG LEVEL THRESHOLD FOR DEPRECATIONS
|
||||
* --------------------------------------------------------------------------
|
||||
* If `$logDeprecations` is set to `true`, this sets the log level
|
||||
* to which the deprecation will be logged. This should be one of the log
|
||||
* levels recognized by PSR-3.
|
||||
*
|
||||
* The related `Config\Logger::$threshold` should be adjusted, if needed,
|
||||
* to capture logging the deprecations.
|
||||
*/
|
||||
public string $deprecationLogLevel = LogLevel::WARNING;
|
||||
|
||||
/*
|
||||
* DEFINE THE HANDLERS USED
|
||||
* --------------------------------------------------------------------------
|
||||
* Given the HTTP status code, returns exception handler that
|
||||
* should be used to deal with this error. By default, it will run CodeIgniter's
|
||||
* default handler and display the error information in the expected format
|
||||
* for CLI, HTTP, or AJAX requests, as determined by is_cli() and the expected
|
||||
* response format.
|
||||
*
|
||||
* Custom handlers can be returned if you want to handle one or more specific
|
||||
* error codes yourself like:
|
||||
*
|
||||
* if (in_array($statusCode, [400, 404, 500])) {
|
||||
* return new \App\Libraries\MyExceptionHandler();
|
||||
* }
|
||||
* if ($exception instanceOf PageNotFoundException) {
|
||||
* return new \App\Libraries\MyExceptionHandler();
|
||||
* }
|
||||
*/
|
||||
public function handler(int $statusCode, Throwable $exception): ExceptionHandlerInterface
|
||||
{
|
||||
return new ExceptionHandler($this);
|
||||
}
|
||||
}
|
||||
37
app/Config/Feature.php
Executable file
37
app/Config/Feature.php
Executable file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
/**
|
||||
* Enable/disable backward compatibility breaking features.
|
||||
*/
|
||||
class Feature extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* Use improved new auto routing instead of the legacy version.
|
||||
*/
|
||||
public bool $autoRoutesImproved = true;
|
||||
|
||||
/**
|
||||
* Use filter execution order in 4.4 or before.
|
||||
*/
|
||||
public bool $oldFilterOrder = false;
|
||||
|
||||
/**
|
||||
* The behavior of `limit(0)` in Query Builder.
|
||||
*
|
||||
* If true, `limit(0)` returns all records. (the behavior of 4.4.x or before in version 4.x.)
|
||||
* If false, `limit(0)` returns no records. (the behavior of 3.1.9 or later in version 3.x.)
|
||||
*/
|
||||
public bool $limitZeroAsAll = true;
|
||||
|
||||
/**
|
||||
* Use strict location negotiation.
|
||||
*
|
||||
* By default, the locale is selected based on a loose comparison of the language code (ISO 639-1)
|
||||
* Enabling strict comparison will also consider the region code (ISO 3166-1 alpha-2).
|
||||
*/
|
||||
public bool $strictLocaleNegotiation = false;
|
||||
}
|
||||
115
app/Config/Filters.php
Executable file
115
app/Config/Filters.php
Executable file
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\Filters as BaseFilters;
|
||||
use CodeIgniter\Filters\Cors;
|
||||
use CodeIgniter\Filters\CSRF;
|
||||
use CodeIgniter\Filters\DebugToolbar;
|
||||
use CodeIgniter\Filters\ForceHTTPS;
|
||||
use CodeIgniter\Filters\Honeypot;
|
||||
use CodeIgniter\Filters\InvalidChars;
|
||||
use CodeIgniter\Filters\PageCache;
|
||||
use CodeIgniter\Filters\PerformanceMetrics;
|
||||
use CodeIgniter\Filters\SecureHeaders;
|
||||
use App\Filters\JwtAuthFilter;
|
||||
use App\Filters\SignedUrlFilter;
|
||||
class Filters extends BaseFilters
|
||||
{
|
||||
/**
|
||||
* Configures aliases for Filter classes to
|
||||
* make reading things nicer and simpler.
|
||||
*
|
||||
* @var array<string, class-string|list<class-string>>
|
||||
*
|
||||
* [filter_name => classname]
|
||||
* or [filter_name => [classname1, classname2, ...]]
|
||||
*/
|
||||
public array $aliases = [
|
||||
'csrf' => CSRF::class,
|
||||
'toolbar' => DebugToolbar::class,
|
||||
'honeypot' => Honeypot::class,
|
||||
'invalidchars' => InvalidChars::class,
|
||||
'secureheaders' => SecureHeaders::class,
|
||||
'cors' => Cors::class,
|
||||
'forcehttps' => ForceHTTPS::class,
|
||||
'pagecache' => PageCache::class,
|
||||
'performance' => PerformanceMetrics::class,
|
||||
'jwtAuth' => JwtAuthFilter::class,
|
||||
'signedUrl' => SignedUrlFilter::class,
|
||||
];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* List of special required filters.
|
||||
*
|
||||
* The filters listed here are special. They are applied before and after
|
||||
* other kinds of filters, and always applied even if a route does not exist.
|
||||
*
|
||||
* Filters set by default provide framework functionality. If removed,
|
||||
* those functions will no longer work.
|
||||
*
|
||||
* @see https://codeigniter.com/user_guide/incoming/filters.html#provided-filters
|
||||
*
|
||||
* @var array{before: list<string>, after: list<string>}
|
||||
*/
|
||||
public array $required = [
|
||||
'before' => [
|
||||
'forcehttps', // Force Global Secure Requests
|
||||
'pagecache', // Web Page Caching
|
||||
],
|
||||
'after' => [
|
||||
'pagecache', // Web Page Caching
|
||||
'performance', // Performance Metrics
|
||||
'toolbar', // Debug Toolbar
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* List of filter aliases that are always
|
||||
* applied before and after every request.
|
||||
*
|
||||
* @var array<string, array<string, array<string, string>>>|array<string, list<string>>
|
||||
*/
|
||||
public array $globals = [
|
||||
'before' => [
|
||||
// 'honeypot',
|
||||
// 'csrf',
|
||||
// 'invalidchars',
|
||||
],
|
||||
'after' => [
|
||||
// 'honeypot',
|
||||
// 'secureheaders',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* List of filter aliases that works on a
|
||||
* particular HTTP method (GET, POST, etc.).
|
||||
*
|
||||
* Example:
|
||||
* 'POST' => ['foo', 'bar']
|
||||
*
|
||||
* If you use this, you should disable auto-routing because auto-routing
|
||||
* permits any HTTP method to access a controller. Accessing the controller
|
||||
* with a method you don't expect could bypass the filter.
|
||||
*
|
||||
* @var array<string, list<string>>
|
||||
*/
|
||||
public array $methods = [];
|
||||
|
||||
/**
|
||||
* List of filter aliases that should run on any
|
||||
* before or after URI patterns.
|
||||
*
|
||||
* Example:
|
||||
* 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']]
|
||||
*
|
||||
* @var array<string, array<string, list<string>>>
|
||||
*/
|
||||
public array $filters = [];
|
||||
}
|
||||
12
app/Config/ForeignCharacters.php
Executable file
12
app/Config/ForeignCharacters.php
Executable file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\ForeignCharacters as BaseForeignCharacters;
|
||||
|
||||
/**
|
||||
* @immutable
|
||||
*/
|
||||
class ForeignCharacters extends BaseForeignCharacters
|
||||
{
|
||||
}
|
||||
64
app/Config/Format.php
Executable file
64
app/Config/Format.php
Executable file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
use CodeIgniter\Format\JSONFormatter;
|
||||
use CodeIgniter\Format\XMLFormatter;
|
||||
|
||||
class Format extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Available Response Formats
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* When you perform content negotiation with the request, these are the
|
||||
* available formats that your application supports. This is currently
|
||||
* only used with the API\ResponseTrait. A valid Formatter must exist
|
||||
* for the specified format.
|
||||
*
|
||||
* These formats are only checked when the data passed to the respond()
|
||||
* method is an array.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
public array $supportedResponseFormats = [
|
||||
'application/json',
|
||||
'application/xml', // machine-readable XML
|
||||
'text/xml', // human-readable XML
|
||||
];
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Formatters
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Lists the class to use to format responses with of a particular type.
|
||||
* For each mime type, list the class that should be used. Formatters
|
||||
* can be retrieved through the getFormatter() method.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
public array $formatters = [
|
||||
'application/json' => JSONFormatter::class,
|
||||
'application/xml' => XMLFormatter::class,
|
||||
'text/xml' => XMLFormatter::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Formatters Options
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Additional Options to adjust default formatters behaviour.
|
||||
* For each mime type, list the additional options that should be used.
|
||||
*
|
||||
* @var array<string, int>
|
||||
*/
|
||||
public array $formatterOptions = [
|
||||
'application/json' => JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES,
|
||||
'application/xml' => 0,
|
||||
'text/xml' => 0,
|
||||
];
|
||||
}
|
||||
44
app/Config/Generators.php
Executable file
44
app/Config/Generators.php
Executable file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
class Generators extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Generator Commands' Views
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* This array defines the mapping of generator commands to the view files
|
||||
* they are using. If you need to customize them for your own, copy these
|
||||
* view files in your own folder and indicate the location here.
|
||||
*
|
||||
* You will notice that the views have special placeholders enclosed in
|
||||
* curly braces `{...}`. These placeholders are used internally by the
|
||||
* generator commands in processing replacements, thus you are warned
|
||||
* not to delete them or modify the names. If you will do so, you may
|
||||
* end up disrupting the scaffolding process and throw errors.
|
||||
*
|
||||
* YOU HAVE BEEN WARNED!
|
||||
*
|
||||
* @var array<string, array<string, string>|string>
|
||||
*/
|
||||
public array $views = [
|
||||
'make:cell' => [
|
||||
'class' => 'CodeIgniter\Commands\Generators\Views\cell.tpl.php',
|
||||
'view' => 'CodeIgniter\Commands\Generators\Views\cell_view.tpl.php',
|
||||
],
|
||||
'make:command' => 'CodeIgniter\Commands\Generators\Views\command.tpl.php',
|
||||
'make:config' => 'CodeIgniter\Commands\Generators\Views\config.tpl.php',
|
||||
'make:controller' => 'CodeIgniter\Commands\Generators\Views\controller.tpl.php',
|
||||
'make:entity' => 'CodeIgniter\Commands\Generators\Views\entity.tpl.php',
|
||||
'make:filter' => 'CodeIgniter\Commands\Generators\Views\filter.tpl.php',
|
||||
'make:migration' => 'CodeIgniter\Commands\Generators\Views\migration.tpl.php',
|
||||
'make:model' => 'CodeIgniter\Commands\Generators\Views\model.tpl.php',
|
||||
'make:seeder' => 'CodeIgniter\Commands\Generators\Views\seeder.tpl.php',
|
||||
'make:validation' => 'CodeIgniter\Commands\Generators\Views\validation.tpl.php',
|
||||
'session:migration' => 'CodeIgniter\Commands\Generators\Views\migration.tpl.php',
|
||||
];
|
||||
}
|
||||
42
app/Config/Honeypot.php
Executable file
42
app/Config/Honeypot.php
Executable file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
class Honeypot extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* Makes Honeypot visible or not to human
|
||||
*/
|
||||
public bool $hidden = true;
|
||||
|
||||
/**
|
||||
* Honeypot Label Content
|
||||
*/
|
||||
public string $label = 'Fill This Field';
|
||||
|
||||
/**
|
||||
* Honeypot Field Name
|
||||
*/
|
||||
public string $name = 'honeypot';
|
||||
|
||||
/**
|
||||
* Honeypot HTML Template
|
||||
*/
|
||||
public string $template = '<label>{label}</label><input type="text" name="{name}" value="">';
|
||||
|
||||
/**
|
||||
* Honeypot container
|
||||
*
|
||||
* If you enabled CSP, you can remove `style="display:none"`.
|
||||
*/
|
||||
public string $container = '<div style="display:none">{template}</div>';
|
||||
|
||||
/**
|
||||
* The id attribute for Honeypot container tag
|
||||
*
|
||||
* Used when CSP is enabled.
|
||||
*/
|
||||
public string $containerId = 'hpc';
|
||||
}
|
||||
31
app/Config/Images.php
Executable file
31
app/Config/Images.php
Executable file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
use CodeIgniter\Images\Handlers\GDHandler;
|
||||
use CodeIgniter\Images\Handlers\ImageMagickHandler;
|
||||
|
||||
class Images extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* Default handler used if no other handler is specified.
|
||||
*/
|
||||
public string $defaultHandler = 'gd';
|
||||
|
||||
/**
|
||||
* The path to the image library.
|
||||
* Required for ImageMagick, GraphicsMagick, or NetPBM.
|
||||
*/
|
||||
public string $libraryPath = '/usr/local/bin/convert';
|
||||
|
||||
/**
|
||||
* The available handler classes.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
public array $handlers = [
|
||||
'gd' => GDHandler::class,
|
||||
'imagick' => ImageMagickHandler::class,
|
||||
];
|
||||
}
|
||||
63
app/Config/Kint.php
Executable file
63
app/Config/Kint.php
Executable file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use Kint\Parser\ConstructablePluginInterface;
|
||||
use Kint\Renderer\Rich\TabPluginInterface;
|
||||
use Kint\Renderer\Rich\ValuePluginInterface;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Kint
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* We use Kint's `RichRenderer` and `CLIRenderer`. This area contains options
|
||||
* that you can set to customize how Kint works for you.
|
||||
*
|
||||
* @see https://kint-php.github.io/kint/ for details on these settings.
|
||||
*/
|
||||
class Kint
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Global Settings
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* @var list<class-string<ConstructablePluginInterface>|ConstructablePluginInterface>|null
|
||||
*/
|
||||
public $plugins;
|
||||
|
||||
public int $maxDepth = 6;
|
||||
public bool $displayCalledFrom = true;
|
||||
public bool $expanded = false;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| RichRenderer Settings
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
public string $richTheme = 'aante-light.css';
|
||||
public bool $richFolder = false;
|
||||
|
||||
/**
|
||||
* @var array<string, class-string<ValuePluginInterface>>|null
|
||||
*/
|
||||
public $richObjectPlugins;
|
||||
|
||||
/**
|
||||
* @var array<string, class-string<TabPluginInterface>>|null
|
||||
*/
|
||||
public $richTabPlugins;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| CLI Settings
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
public bool $cliColors = true;
|
||||
public bool $cliForceUTF8 = false;
|
||||
public bool $cliDetectWidth = true;
|
||||
public int $cliMinWidth = 40;
|
||||
}
|
||||
150
app/Config/Logger.php
Executable file
150
app/Config/Logger.php
Executable file
@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
use CodeIgniter\Log\Handlers\FileHandler;
|
||||
|
||||
class Logger extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Error Logging Threshold
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* You can enable error logging by setting a threshold over zero. The
|
||||
* threshold determines what gets logged. Any values below or equal to the
|
||||
* threshold will be logged.
|
||||
*
|
||||
* Threshold options are:
|
||||
*
|
||||
* - 0 = Disables logging, Error logging TURNED OFF
|
||||
* - 1 = Emergency Messages - System is unusable
|
||||
* - 2 = Alert Messages - Action Must Be Taken Immediately
|
||||
* - 3 = Critical Messages - Application component unavailable, unexpected exception.
|
||||
* - 4 = Runtime Errors - Don't need immediate action, but should be monitored.
|
||||
* - 5 = Warnings - Exceptional occurrences that are not errors.
|
||||
* - 6 = Notices - Normal but significant events.
|
||||
* - 7 = Info - Interesting events, like user logging in, etc.
|
||||
* - 8 = Debug - Detailed debug information.
|
||||
* - 9 = All Messages
|
||||
*
|
||||
* You can also pass an array with threshold levels to show individual error types
|
||||
*
|
||||
* array(1, 2, 3, 8) = Emergency, Alert, Critical, and Debug messages
|
||||
*
|
||||
* For a live site you'll usually enable Critical or higher (3) to be logged otherwise
|
||||
* your log files will fill up very fast.
|
||||
*
|
||||
* @var int|list<int>
|
||||
*/
|
||||
public $threshold = (ENVIRONMENT === 'production') ? 4 : 9;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* 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
|
||||
*/
|
||||
public string $dateFormat = 'Y-m-d H:i:s';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Log Handlers
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* The logging system supports multiple actions to be taken when something
|
||||
* is logged. This is done by allowing for multiple Handlers, special classes
|
||||
* designed to write the log to their chosen destinations, whether that is
|
||||
* a file on the getServer, a cloud-based service, or even taking actions such
|
||||
* as emailing the dev team.
|
||||
*
|
||||
* Each handler is defined by the class name used for that handler, and it
|
||||
* MUST implement the `CodeIgniter\Log\Handlers\HandlerInterface` interface.
|
||||
*
|
||||
* The value of each key is an array of configuration items that are sent
|
||||
* to the constructor of each handler. The only required configuration item
|
||||
* is the 'handles' element, which must be an array of integer log levels.
|
||||
* This is most easily handled by using the constants defined in the
|
||||
* `Psr\Log\LogLevel` class.
|
||||
*
|
||||
* Handlers are executed in the order defined in this array, starting with
|
||||
* the handler on top and continuing down.
|
||||
*
|
||||
* @var array<class-string, array<string, int|list<string>|string>>
|
||||
*/
|
||||
public array $handlers = [
|
||||
/*
|
||||
* --------------------------------------------------------------------
|
||||
* File Handler
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
FileHandler::class => [
|
||||
// The log levels that this handler will handle.
|
||||
'handles' => [
|
||||
'critical',
|
||||
'alert',
|
||||
'emergency',
|
||||
'debug',
|
||||
'error',
|
||||
'info',
|
||||
'notice',
|
||||
'warning',
|
||||
],
|
||||
|
||||
/*
|
||||
* The default filename extension for log files.
|
||||
* An extension of '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 'log'.
|
||||
*/
|
||||
'fileExtension' => '',
|
||||
|
||||
/*
|
||||
* 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.)
|
||||
*/
|
||||
'filePermissions' => 0644,
|
||||
|
||||
/*
|
||||
* Logging Directory Path
|
||||
*
|
||||
* By default, logs are written to WRITEPATH . 'logs/'
|
||||
* Specify a different destination here, if desired.
|
||||
*/
|
||||
'path' => '',
|
||||
],
|
||||
|
||||
/*
|
||||
* The ChromeLoggerHandler requires the use of the Chrome web browser
|
||||
* and the ChromeLogger extension. Uncomment this block to use it.
|
||||
*/
|
||||
// 'CodeIgniter\Log\Handlers\ChromeLoggerHandler' => [
|
||||
// /*
|
||||
// * The log levels that this handler will handle.
|
||||
// */
|
||||
// 'handles' => ['critical', 'alert', 'emergency', 'debug',
|
||||
// 'error', 'info', 'notice', 'warning'],
|
||||
// ],
|
||||
|
||||
/*
|
||||
* The ErrorlogHandler writes the logs to PHP's native `error_log()` function.
|
||||
* Uncomment this block to use it.
|
||||
*/
|
||||
// 'CodeIgniter\Log\Handlers\ErrorlogHandler' => [
|
||||
// /* The log levels this handler can handle. */
|
||||
// 'handles' => ['critical', 'alert', 'emergency', 'debug', 'error', 'info', 'notice', 'warning'],
|
||||
//
|
||||
// /*
|
||||
// * The message type where the error should go. Can be 0 or 4, or use the
|
||||
// * class constants: `ErrorlogHandler::TYPE_OS` (0) or `ErrorlogHandler::TYPE_SAPI` (4)
|
||||
// */
|
||||
// 'messageType' => 0,
|
||||
// ],
|
||||
];
|
||||
}
|
||||
50
app/Config/Migrations.php
Executable file
50
app/Config/Migrations.php
Executable file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
class Migrations extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Enable/Disable Migrations
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Migrations are enabled by default.
|
||||
*
|
||||
* You should enable migrations whenever you intend to do a schema migration
|
||||
* and disable it back when you're done.
|
||||
*/
|
||||
public bool $enabled = true;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Migrations Table
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* This is the name of the table that will store the current migrations state.
|
||||
* When migrations runs it will store in a database table which migration
|
||||
* files have already been run.
|
||||
*/
|
||||
public string $table = 'migrations';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Timestamp Format
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* This is the format that will be used when creating new migrations
|
||||
* using the CLI command:
|
||||
* > php spark make:migration
|
||||
*
|
||||
* NOTE: if you set an unsupported format, migration runner will not find
|
||||
* your migration files.
|
||||
*
|
||||
* Supported formats:
|
||||
* - YmdHis_
|
||||
* - Y-m-d-His_
|
||||
* - Y_m_d_His_
|
||||
*/
|
||||
public string $timestampFormat = 'Y-m-d-His_';
|
||||
}
|
||||
536
app/Config/Mimes.php
Executable file
536
app/Config/Mimes.php
Executable file
@ -0,0 +1,536 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
/**
|
||||
* Mimes
|
||||
*
|
||||
* This file contains an array of mime types. It is used by the
|
||||
* Upload class to help identify allowed file types.
|
||||
*
|
||||
* When more than one variation for an extension exist (like jpg, jpeg, etc)
|
||||
* the most common one should be first in the array to aid the guess*
|
||||
* methods. The same applies when more than one mime-type exists for a
|
||||
* single extension.
|
||||
*
|
||||
* When working with mime types, please make sure you have the ´fileinfo´
|
||||
* extension enabled to reliably detect the media types.
|
||||
*
|
||||
* @immutable
|
||||
*/
|
||||
class Mimes
|
||||
{
|
||||
/**
|
||||
* Map of extensions to mime types.
|
||||
*
|
||||
* @var array<string, list<string>|string>
|
||||
*/
|
||||
public static array $mimes = [
|
||||
'hqx' => [
|
||||
'application/mac-binhex40',
|
||||
'application/mac-binhex',
|
||||
'application/x-binhex40',
|
||||
'application/x-mac-binhex40',
|
||||
],
|
||||
'cpt' => 'application/mac-compactpro',
|
||||
'csv' => [
|
||||
'text/csv',
|
||||
'text/x-comma-separated-values',
|
||||
'text/comma-separated-values',
|
||||
'application/vnd.ms-excel',
|
||||
'application/x-csv',
|
||||
'text/x-csv',
|
||||
'application/csv',
|
||||
'application/excel',
|
||||
'application/vnd.msexcel',
|
||||
'text/plain',
|
||||
],
|
||||
'bin' => [
|
||||
'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' => [
|
||||
'application/octet-stream',
|
||||
'application/vnd.microsoft.portable-executable',
|
||||
'application/x-dosexec',
|
||||
'application/x-msdownload',
|
||||
],
|
||||
'class' => 'application/octet-stream',
|
||||
'psd' => [
|
||||
'application/x-photoshop',
|
||||
'image/vnd.adobe.photoshop',
|
||||
],
|
||||
'so' => 'application/octet-stream',
|
||||
'sea' => 'application/octet-stream',
|
||||
'dll' => 'application/octet-stream',
|
||||
'oda' => 'application/oda',
|
||||
'pdf' => [
|
||||
'application/pdf',
|
||||
'application/force-download',
|
||||
'application/x-download',
|
||||
],
|
||||
'ai' => [
|
||||
'application/pdf',
|
||||
'application/postscript',
|
||||
],
|
||||
'eps' => 'application/postscript',
|
||||
'ps' => 'application/postscript',
|
||||
'smi' => 'application/smil',
|
||||
'smil' => 'application/smil',
|
||||
'mif' => 'application/vnd.mif',
|
||||
'xls' => [
|
||||
'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' => [
|
||||
'application/vnd.ms-powerpoint',
|
||||
'application/powerpoint',
|
||||
'application/vnd.ms-office',
|
||||
'application/msword',
|
||||
],
|
||||
'pptx' => [
|
||||
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
],
|
||||
'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' => [
|
||||
'application/x-php',
|
||||
'application/x-httpd-php',
|
||||
'application/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' => [
|
||||
'application/x-javascript',
|
||||
'text/plain',
|
||||
],
|
||||
'swf' => 'application/x-shockwave-flash',
|
||||
'sit' => 'application/x-stuffit',
|
||||
'tar' => 'application/x-tar',
|
||||
'tgz' => [
|
||||
'application/x-tar',
|
||||
'application/x-gzip-compressed',
|
||||
],
|
||||
'z' => 'application/x-compress',
|
||||
'xhtml' => 'application/xhtml+xml',
|
||||
'xht' => 'application/xhtml+xml',
|
||||
'zip' => [
|
||||
'application/x-zip',
|
||||
'application/zip',
|
||||
'application/x-zip-compressed',
|
||||
'application/s-compressed',
|
||||
'multipart/x-zip',
|
||||
],
|
||||
'rar' => [
|
||||
'application/vnd.rar',
|
||||
'application/x-rar',
|
||||
'application/rar',
|
||||
'application/x-rar-compressed',
|
||||
],
|
||||
'mid' => 'audio/midi',
|
||||
'midi' => 'audio/midi',
|
||||
'mpga' => 'audio/mpeg',
|
||||
'mp2' => 'audio/mpeg',
|
||||
'mp3' => [
|
||||
'audio/mpeg',
|
||||
'audio/mpg',
|
||||
'audio/mpeg3',
|
||||
'audio/mp3',
|
||||
],
|
||||
'aif' => [
|
||||
'audio/x-aiff',
|
||||
'audio/aiff',
|
||||
],
|
||||
'aiff' => [
|
||||
'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' => [
|
||||
'audio/x-wav',
|
||||
'audio/wave',
|
||||
'audio/wav',
|
||||
],
|
||||
'bmp' => [
|
||||
'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',
|
||||
'jpg' => [
|
||||
'image/jpeg',
|
||||
'image/pjpeg',
|
||||
],
|
||||
'jpeg' => [
|
||||
'image/jpeg',
|
||||
'image/pjpeg',
|
||||
],
|
||||
'jpe' => [
|
||||
'image/jpeg',
|
||||
'image/pjpeg',
|
||||
],
|
||||
'jp2' => [
|
||||
'image/jp2',
|
||||
'video/mj2',
|
||||
'image/jpx',
|
||||
'image/jpm',
|
||||
],
|
||||
'j2k' => [
|
||||
'image/jp2',
|
||||
'video/mj2',
|
||||
'image/jpx',
|
||||
'image/jpm',
|
||||
],
|
||||
'jpf' => [
|
||||
'image/jp2',
|
||||
'video/mj2',
|
||||
'image/jpx',
|
||||
'image/jpm',
|
||||
],
|
||||
'jpg2' => [
|
||||
'image/jp2',
|
||||
'video/mj2',
|
||||
'image/jpx',
|
||||
'image/jpm',
|
||||
],
|
||||
'jpx' => [
|
||||
'image/jp2',
|
||||
'video/mj2',
|
||||
'image/jpx',
|
||||
'image/jpm',
|
||||
],
|
||||
'jpm' => [
|
||||
'image/jp2',
|
||||
'video/mj2',
|
||||
'image/jpx',
|
||||
'image/jpm',
|
||||
],
|
||||
'mj2' => [
|
||||
'image/jp2',
|
||||
'video/mj2',
|
||||
'image/jpx',
|
||||
'image/jpm',
|
||||
],
|
||||
'mjp2' => [
|
||||
'image/jp2',
|
||||
'video/mj2',
|
||||
'image/jpx',
|
||||
'image/jpm',
|
||||
],
|
||||
'png' => [
|
||||
'image/png',
|
||||
'image/x-png',
|
||||
],
|
||||
'webp' => 'image/webp',
|
||||
'tif' => 'image/tiff',
|
||||
'tiff' => 'image/tiff',
|
||||
'css' => [
|
||||
'text/css',
|
||||
'text/plain',
|
||||
],
|
||||
'html' => [
|
||||
'text/html',
|
||||
'text/plain',
|
||||
],
|
||||
'htm' => [
|
||||
'text/html',
|
||||
'text/plain',
|
||||
],
|
||||
'shtml' => [
|
||||
'text/html',
|
||||
'text/plain',
|
||||
],
|
||||
'txt' => 'text/plain',
|
||||
'text' => 'text/plain',
|
||||
'log' => [
|
||||
'text/plain',
|
||||
'text/x-log',
|
||||
],
|
||||
'rtx' => 'text/richtext',
|
||||
'rtf' => 'text/rtf',
|
||||
'xml' => [
|
||||
'application/xml',
|
||||
'text/xml',
|
||||
'text/plain',
|
||||
],
|
||||
'xsl' => [
|
||||
'application/xml',
|
||||
'text/xsl',
|
||||
'text/xml',
|
||||
],
|
||||
'mpeg' => 'video/mpeg',
|
||||
'mpg' => 'video/mpeg',
|
||||
'mpe' => 'video/mpeg',
|
||||
'qt' => 'video/quicktime',
|
||||
'mov' => 'video/quicktime',
|
||||
'avi' => [
|
||||
'video/x-msvideo',
|
||||
'video/msvideo',
|
||||
'video/avi',
|
||||
'application/x-troff-msvideo',
|
||||
],
|
||||
'movie' => 'video/x-sgi-movie',
|
||||
'doc' => [
|
||||
'application/msword',
|
||||
'application/vnd.ms-office',
|
||||
],
|
||||
'docx' => [
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'application/zip',
|
||||
'application/msword',
|
||||
'application/x-zip',
|
||||
],
|
||||
'dot' => [
|
||||
'application/msword',
|
||||
'application/vnd.ms-office',
|
||||
],
|
||||
'dotx' => [
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'application/zip',
|
||||
'application/msword',
|
||||
],
|
||||
'xlsx' => [
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'application/zip',
|
||||
'application/vnd.ms-excel',
|
||||
'application/msword',
|
||||
'application/x-zip',
|
||||
],
|
||||
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
|
||||
'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
|
||||
'word' => [
|
||||
'application/msword',
|
||||
'application/octet-stream',
|
||||
],
|
||||
'xl' => 'application/excel',
|
||||
'eml' => 'message/rfc822',
|
||||
'json' => [
|
||||
'application/json',
|
||||
'text/json',
|
||||
],
|
||||
'pem' => [
|
||||
'application/x-x509-user-cert',
|
||||
'application/x-pem-file',
|
||||
'application/octet-stream',
|
||||
],
|
||||
'p10' => [
|
||||
'application/x-pkcs10',
|
||||
'application/pkcs10',
|
||||
],
|
||||
'p12' => 'application/x-pkcs12',
|
||||
'p7a' => 'application/x-pkcs7-signature',
|
||||
'p7c' => [
|
||||
'application/pkcs7-mime',
|
||||
'application/x-pkcs7-mime',
|
||||
],
|
||||
'p7m' => [
|
||||
'application/pkcs7-mime',
|
||||
'application/x-pkcs7-mime',
|
||||
],
|
||||
'p7r' => 'application/x-pkcs7-certreqresp',
|
||||
'p7s' => 'application/pkcs7-signature',
|
||||
'crt' => [
|
||||
'application/x-x509-ca-cert',
|
||||
'application/x-x509-user-cert',
|
||||
'application/pkix-cert',
|
||||
],
|
||||
'crl' => [
|
||||
'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' => [
|
||||
'application/pkix-cert',
|
||||
'application/x-x509-ca-cert',
|
||||
],
|
||||
'3g2' => 'video/3gpp2',
|
||||
'3gp' => [
|
||||
'video/3gp',
|
||||
'video/3gpp',
|
||||
],
|
||||
'mp4' => 'video/mp4',
|
||||
'm4a' => 'audio/x-m4a',
|
||||
'f4v' => [
|
||||
'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' => [
|
||||
'video/x-ms-wmv',
|
||||
'video/x-ms-asf',
|
||||
],
|
||||
'au' => 'audio/x-au',
|
||||
'ac3' => 'audio/ac3',
|
||||
'flac' => 'audio/x-flac',
|
||||
'ogg' => [
|
||||
'audio/ogg',
|
||||
'video/ogg',
|
||||
'application/ogg',
|
||||
],
|
||||
'kmz' => [
|
||||
'application/vnd.google-earth.kmz',
|
||||
'application/zip',
|
||||
'application/x-zip',
|
||||
],
|
||||
'kml' => [
|
||||
'application/vnd.google-earth.kml+xml',
|
||||
'application/xml',
|
||||
'text/xml',
|
||||
],
|
||||
'ics' => 'text/calendar',
|
||||
'ical' => 'text/calendar',
|
||||
'zsh' => 'text/x-scriptzsh',
|
||||
'7zip' => [
|
||||
'application/x-compressed',
|
||||
'application/x-zip-compressed',
|
||||
'application/zip',
|
||||
'multipart/x-zip',
|
||||
],
|
||||
'cdr' => [
|
||||
'application/cdr',
|
||||
'application/coreldraw',
|
||||
'application/x-cdr',
|
||||
'application/x-coreldraw',
|
||||
'image/cdr',
|
||||
'image/x-cdr',
|
||||
'zz-application/zz-winassoc-cdr',
|
||||
],
|
||||
'wma' => [
|
||||
'audio/x-ms-wma',
|
||||
'video/x-ms-asf',
|
||||
],
|
||||
'jar' => [
|
||||
'application/java-archive',
|
||||
'application/x-java-application',
|
||||
'application/x-jar',
|
||||
'application/x-compressed',
|
||||
],
|
||||
'svg' => [
|
||||
'image/svg+xml',
|
||||
'image/svg',
|
||||
'application/xml',
|
||||
'text/xml',
|
||||
],
|
||||
'vcf' => 'text/x-vcard',
|
||||
'srt' => [
|
||||
'text/srt',
|
||||
'text/plain',
|
||||
],
|
||||
'vtt' => [
|
||||
'text/vtt',
|
||||
'text/plain',
|
||||
],
|
||||
'ico' => [
|
||||
'image/x-icon',
|
||||
'image/x-ico',
|
||||
'image/vnd.microsoft.icon',
|
||||
],
|
||||
'stl' => [
|
||||
'application/sla',
|
||||
'application/vnd.ms-pki.stl',
|
||||
'application/x-navistyle',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Attempts to determine the best mime type for the given file extension.
|
||||
*
|
||||
* @return string|null The mime type found, or none if unable to determine.
|
||||
*/
|
||||
public static function guessTypeFromExtension(string $extension)
|
||||
{
|
||||
$extension = trim(strtolower($extension), '. ');
|
||||
|
||||
if (! array_key_exists($extension, static::$mimes)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return is_array(static::$mimes[$extension]) ? static::$mimes[$extension][0] : static::$mimes[$extension];
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to determine the best file extension for a given mime type.
|
||||
*
|
||||
* @param string|null $proposedExtension - default extension (in case there is more than one with the same mime type)
|
||||
*
|
||||
* @return string|null The extension determined, or null if unable to match.
|
||||
*/
|
||||
public static function guessExtensionFromType(string $type, ?string $proposedExtension = null)
|
||||
{
|
||||
$type = trim(strtolower($type), '. ');
|
||||
|
||||
$proposedExtension = trim(strtolower($proposedExtension ?? ''));
|
||||
|
||||
if (
|
||||
$proposedExtension !== ''
|
||||
&& array_key_exists($proposedExtension, static::$mimes)
|
||||
&& in_array($type, (array) static::$mimes[$proposedExtension], true)
|
||||
) {
|
||||
// The detected mime type matches with the proposed extension.
|
||||
return $proposedExtension;
|
||||
}
|
||||
|
||||
// Reverse check the mime type list if no extension was proposed.
|
||||
// This search is order sensitive!
|
||||
foreach (static::$mimes as $ext => $types) {
|
||||
if (in_array($type, (array) $types, true)) {
|
||||
return $ext;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
84
app/Config/Modules.php
Executable file
84
app/Config/Modules.php
Executable file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Modules\Modules as BaseModules;
|
||||
|
||||
/**
|
||||
* Modules Configuration.
|
||||
*
|
||||
* NOTE: This class is required prior to Autoloader instantiation,
|
||||
* and does not extend BaseConfig.
|
||||
*
|
||||
* @immutable
|
||||
*/
|
||||
class Modules extends BaseModules
|
||||
{
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Enable Auto-Discovery?
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* If true, then auto-discovery will happen across all elements listed in
|
||||
* $aliases below. If false, no auto-discovery will happen at all,
|
||||
* giving a slight performance boost.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $enabled = true;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Enable Auto-Discovery Within Composer Packages?
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* If true, then auto-discovery will happen across all namespaces loaded
|
||||
* by Composer, as well as the namespaces configured locally.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $discoverInComposer = true;
|
||||
|
||||
/**
|
||||
* The Composer package list for Auto-Discovery
|
||||
* This setting is optional.
|
||||
*
|
||||
* E.g.:
|
||||
* [
|
||||
* 'only' => [
|
||||
* // List up all packages to auto-discover
|
||||
* 'codeigniter4/shield',
|
||||
* ],
|
||||
* ]
|
||||
* or
|
||||
* [
|
||||
* 'exclude' => [
|
||||
* // List up packages to exclude.
|
||||
* 'pestphp/pest',
|
||||
* ],
|
||||
* ]
|
||||
*
|
||||
* @var array{only?: list<string>, exclude?: list<string>}
|
||||
*/
|
||||
public $composerPackages = [];
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Auto-Discovery Rules
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Aliases list of all discovery classes that will be active and used during
|
||||
* the current application request.
|
||||
*
|
||||
* If it is not listed, only the base application elements will be used.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
public $aliases = [
|
||||
'events',
|
||||
'filters',
|
||||
'registrars',
|
||||
'routes',
|
||||
'services',
|
||||
];
|
||||
}
|
||||
32
app/Config/Optimize.php
Executable file
32
app/Config/Optimize.php
Executable file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
/**
|
||||
* Optimization Configuration.
|
||||
*
|
||||
* NOTE: This class does not extend BaseConfig for performance reasons.
|
||||
* So you cannot replace the property values with Environment Variables.
|
||||
*
|
||||
* @immutable
|
||||
*/
|
||||
class Optimize
|
||||
{
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Config Caching
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* @see https://codeigniter.com/user_guide/concepts/factories.html#config-caching
|
||||
*/
|
||||
public bool $configCacheEnabled = false;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Config Caching
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* @see https://codeigniter.com/user_guide/concepts/autoloader.html#file-locator-caching
|
||||
*/
|
||||
public bool $locatorCacheEnabled = false;
|
||||
}
|
||||
37
app/Config/Pager.php
Executable file
37
app/Config/Pager.php
Executable file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
class Pager extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Templates
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Pagination links are rendered out using views to configure their
|
||||
* appearance. This array contains aliases and the view names to
|
||||
* use when rendering the links.
|
||||
*
|
||||
* Within each view, the Pager object will be available as $pager,
|
||||
* and the desired group as $pagerGroup;
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
public array $templates = [
|
||||
'default_full' => 'CodeIgniter\Pager\Views\default_full',
|
||||
'default_simple' => 'CodeIgniter\Pager\Views\default_simple',
|
||||
'default_head' => 'CodeIgniter\Pager\Views\default_head',
|
||||
];
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Items Per Page
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* The default number of results shown in a single page.
|
||||
*/
|
||||
public int $perPage = 20;
|
||||
}
|
||||
80
app/Config/Paths.php
Executable file
80
app/Config/Paths.php
Executable file
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
/**
|
||||
* Paths
|
||||
*
|
||||
* Holds the paths that are used by the system to
|
||||
* locate the main directories, app, system, etc.
|
||||
*
|
||||
* Modifying these allows you to restructure your application,
|
||||
* share a system folder between multiple applications, and more.
|
||||
*
|
||||
* All paths are relative to the project's root folder.
|
||||
*
|
||||
* NOTE: This class is required prior to Autoloader instantiation,
|
||||
* and does not extend BaseConfig.
|
||||
*
|
||||
* @immutable
|
||||
*/
|
||||
class Paths
|
||||
{
|
||||
/**
|
||||
* ---------------------------------------------------------------
|
||||
* SYSTEM FOLDER NAME
|
||||
* ---------------------------------------------------------------
|
||||
*
|
||||
* This must contain the name of your "system" folder. Include
|
||||
* the path if the folder is not in the same directory as this file.
|
||||
*/
|
||||
public string $systemDirectory = __DIR__ . '/../../system';
|
||||
|
||||
/**
|
||||
* ---------------------------------------------------------------
|
||||
* APPLICATION FOLDER NAME
|
||||
* ---------------------------------------------------------------
|
||||
*
|
||||
* If you want this front controller to use a different "app"
|
||||
* folder than the default one you can set its name here. The folder
|
||||
* can also be renamed or relocated anywhere on your server. If
|
||||
* you do, use a full server path.
|
||||
*
|
||||
* @see http://codeigniter.com/user_guide/general/managing_apps.html
|
||||
*/
|
||||
public string $appDirectory = __DIR__ . '/..';
|
||||
|
||||
/**
|
||||
* ---------------------------------------------------------------
|
||||
* WRITABLE DIRECTORY NAME
|
||||
* ---------------------------------------------------------------
|
||||
*
|
||||
* This variable must contain the name of your "writable" directory.
|
||||
* The writable directory allows you to group all directories that
|
||||
* need write permission to a single place that can be tucked away
|
||||
* for maximum security, keeping it out of the app and/or
|
||||
* system directories.
|
||||
*/
|
||||
public string $writableDirectory = __DIR__ . '/../../writable';
|
||||
|
||||
/**
|
||||
* ---------------------------------------------------------------
|
||||
* TESTS DIRECTORY NAME
|
||||
* ---------------------------------------------------------------
|
||||
*
|
||||
* This variable must contain the name of your "tests" directory.
|
||||
*/
|
||||
public string $testsDirectory = __DIR__ . '/../../tests';
|
||||
|
||||
/**
|
||||
* ---------------------------------------------------------------
|
||||
* VIEW DIRECTORY NAME
|
||||
* ---------------------------------------------------------------
|
||||
*
|
||||
* This variable must contain the name of the directory that
|
||||
* contains the view files used by your application. By
|
||||
* default this is in `app/Views`. This value
|
||||
* is used when no value is provided to `Services::renderer()`.
|
||||
*/
|
||||
public string $viewDirectory = __DIR__ . '/../Views';
|
||||
}
|
||||
28
app/Config/Publisher.php
Executable file
28
app/Config/Publisher.php
Executable file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\Publisher as BasePublisher;
|
||||
|
||||
/**
|
||||
* Publisher Configuration
|
||||
*
|
||||
* Defines basic security restrictions for the Publisher class
|
||||
* to prevent abuse by injecting malicious files into a project.
|
||||
*/
|
||||
class Publisher extends BasePublisher
|
||||
{
|
||||
/**
|
||||
* A list of allowed destinations with a (pseudo-)regex
|
||||
* of allowed files for each destination.
|
||||
* Attempts to publish to directories not in this list will
|
||||
* result in a PublisherException. Files that do no fit the
|
||||
* pattern will cause copy/merge to fail.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
public $restrictions = [
|
||||
ROOTPATH => '*',
|
||||
FCPATH => '#\.(s?css|js|map|html?|xml|json|webmanifest|ttf|eot|woff2?|gif|jpe?g|tiff?|png|webp|bmp|ico|svg)$#i',
|
||||
];
|
||||
}
|
||||
190
app/Config/Routes.php
Executable file
190
app/Config/Routes.php
Executable file
@ -0,0 +1,190 @@
|
||||
<?php
|
||||
|
||||
use CodeIgniter\Router\RouteCollection;
|
||||
|
||||
/**
|
||||
* @var RouteCollection $routes
|
||||
*/
|
||||
$routes->get('swagger', 'SwaggerController::view');
|
||||
$routes->get('swagger/json', 'SwaggerController::generate');
|
||||
|
||||
|
||||
//saml apis
|
||||
$routes->get('/landingpage', 'SamlController::index');
|
||||
$routes->get('login', 'SamlController::login');
|
||||
$routes->post('acs', 'SamlController::acs');
|
||||
$routes->post('logout', 'SamlController::slo');
|
||||
$routes->get('metadata', 'SamlController::metadata');
|
||||
|
||||
|
||||
//login api
|
||||
$routes->post('auth/login', 'AuthController::login');
|
||||
$routes->get('auth/oauthClient', 'AuthController::oauthClient');
|
||||
$routes->post('auth/oauthlogin', 'AuthController::oauthlogin');
|
||||
|
||||
|
||||
//forgot password
|
||||
$routes->post('forgotPassword/verifyUser', 'UserController::verifyUser');
|
||||
$routes->post('forgotPassword/changePassword', 'UserController::forgotChangePassword');
|
||||
|
||||
|
||||
//api's with token
|
||||
// $routes->group('api', ['filter' => 'jwtAuth'], function ($routes) {
|
||||
|
||||
|
||||
//Organization
|
||||
$routes->get('organizations', 'OrganizationController::index');
|
||||
$routes->get('organizations/find/(:num)', 'OrganizationController::find/$1');
|
||||
$routes->post('organizations/create', 'OrganizationController::create');
|
||||
$routes->put('organizations/update/(:num)', 'OrganizationController::update/$1');
|
||||
$routes->put('organizations/org-status/(:num)', 'OrganizationController::updateOrganizationStatus/$1');
|
||||
$routes->post('organizations/testMail', 'OrganizationController::testMail');
|
||||
|
||||
//Service
|
||||
$routes->get('service', 'OrganizationController::getServices');
|
||||
|
||||
//Group
|
||||
$routes->get('groups', 'OrganizationController::getGroups');
|
||||
$routes->get('groups/find/(:num)', 'OrganizationController::findGroup/$1');
|
||||
$routes->post('groups/create', 'OrganizationController::createGroup');
|
||||
$routes->put('groups/update/(:num)', 'OrganizationController::updateGroup/$1');
|
||||
$routes->put('groups/group-status/(:num)', 'OrganizationController::updateGroupStatus/$1');
|
||||
|
||||
//Policy
|
||||
$routes->get('policy', 'OrganizationController::getPolicy');
|
||||
$routes->get('policy/find/(:num)', 'OrganizationController::findPolicy/$1');
|
||||
$routes->post('policy/createOrUpdate', 'OrganizationController::createOrUpdatePolicy');
|
||||
$routes->put('policy/policy-status/(:num)', 'OrganizationController::updatePolicyStatus/$1');
|
||||
|
||||
//User
|
||||
$routes->get('users', 'UserController::index');
|
||||
$routes->get('agentList', 'UserController::agentList');
|
||||
$routes->get('users/find/(:num)', 'UserController::find/$1');
|
||||
$routes->post('users/create', 'UserController::create');
|
||||
$routes->put('users/update/(:num)', 'UserController::update/$1');
|
||||
$routes->put('user/user-status/(:num)', 'UserController::updateUserStatus/$1');
|
||||
$routes->put('user/user-password/(:num)', 'UserController::changePassword/$1');
|
||||
$routes->get('checkDuplicate', 'UserController::checkDuplicate');
|
||||
$routes->post('user/userUpload','UserController::userUpload');
|
||||
$routes->get('user/userUploadTemplate','UserController::userUploadTemplate');
|
||||
|
||||
|
||||
//Traveller
|
||||
$routes->get('travellers', 'TravellerController::index');
|
||||
$routes->post('travellers/create', 'TravellerController::create');
|
||||
$routes->get('travellers/find', 'TravellerController::find');
|
||||
$routes->put('travellers/update/(:num)', 'TravellerController::update/$1');
|
||||
$routes->get('travellers/find/name/(:any)', 'TravellerController::findByName/$1');
|
||||
$routes->get('travellers/find/email/(:any)', 'TravellerController::findByEmail/$1');
|
||||
$routes->get('travellers/find/mobile/(:any)', 'TravellerController::findByMobile/$1');
|
||||
|
||||
|
||||
//Plan
|
||||
$routes->get('plans', 'PlanController::index');
|
||||
$routes->put('plans/find/(:num)', 'PlanController::find/$1');
|
||||
$routes->post('plans/createOrEditPlan', 'PlanController::createOrEditPlan');
|
||||
$routes->post('plans/getForexPerdiem', 'PlanController::getForexPerdiem');
|
||||
$routes->post('plans/approvePlan', 'PlanController::approvePlan');
|
||||
$routes->post('plans/rejectPlan', 'PlanController::rejectPlan');
|
||||
$routes->get('plans/statusDashboard', 'PlanController::statusDashboard');
|
||||
$routes->get('plans/download', 'PlanController::downloadPlan');
|
||||
$routes->get('plans/view', 'PlanController::viewPlan');
|
||||
$routes->get('plans/findApprovalList', 'PlanController::findApprovalList');
|
||||
$routes->get('plans/findTravelAgentPlanList', 'PlanController::findTravelAgentPlanList');
|
||||
$routes->post('plans/addOrEditPlanRemark', 'PlanController::addOrEditPlanRemark');
|
||||
$routes->get('plans/getRemarksByPlanId', 'PlanController::getRemarksByPlanId');
|
||||
$routes->get('plans/forexDownload', 'PlanController::forexDownload');
|
||||
$routes->get('plans/cancle_plan', 'PlanController::canclePlan');
|
||||
$routes->get('plans/get_plan_approval_status', 'PlanController::get_plan_approval_status');
|
||||
|
||||
$routes->get('plans/plan_pdf', 'PlanController::plan_pdf');
|
||||
|
||||
//Master
|
||||
$routes->get('getDropdownMaster', 'MasterController::getDropdownMaster');
|
||||
$routes->get('getTravelStatusMaster', 'MasterController::getTravelStatusMaster');
|
||||
$routes->get('getcountryMaster', 'MasterController::getcountryMaster');
|
||||
$routes->get('getAirportCodeMaster', 'MasterController::getAirportCodeMaster');
|
||||
$routes->get('getAirlineMaster', 'MasterController::getAirlineMaster');
|
||||
$routes->get('getTrainCodeMaster', 'MasterController::getTrainCodeMaster');
|
||||
$routes->get('getFlightAndTrainClass', 'MasterController::getFlightAndTrainClass');
|
||||
// Costcenter
|
||||
$routes->get('getCostCenterMaster', 'MasterController::getCostCenterMaster');
|
||||
$routes->post('createCostCenter', 'MasterController::createCostCenter');
|
||||
$routes->get('findCostCenter', 'MasterController::findCostCenter');
|
||||
$routes->put('updateCostCenter/(:num)', 'MasterController::updateCostCenter/$1');
|
||||
// Department Master
|
||||
$routes->get('getDepartmentList', 'MasterController::getDepartmentList');
|
||||
$routes->post('createDepartment', 'MasterController::createDepartment');
|
||||
$routes->get('findDepartment', 'MasterController::findDepartment');
|
||||
$routes->put('updateDepartment/(:num)', 'MasterController::updateDepartment/$1');
|
||||
// Purpose of travel Master
|
||||
$routes->get('getPurposeOfTravelList', 'MasterController::getPurposeOfTravelList');
|
||||
$routes->post('createPurposeOfTravel', 'MasterController::createPurposeOfTravel');
|
||||
$routes->get('findPurposeOfTravel', 'MasterController::findPurposeOfTravel');
|
||||
$routes->put('updatePurposeOfTravel/(:num)', 'MasterController::updatePurposeOfTravel/$1');
|
||||
// Forex Master
|
||||
$routes->get('getForexPerdiemList', 'MasterController::getForexPerdiemList');
|
||||
$routes->post('createForexPerdiem', 'MasterController::createForexPerdiem');
|
||||
$routes->get('findForexPerdiem', 'MasterController::findForexPerdiem');
|
||||
$routes->put('updateForexPerdiem/(:num)', 'MasterController::updateForexPerdiem/$1');
|
||||
// Hotels Master
|
||||
$routes->get('getHotels', 'MasterController::getHotels');
|
||||
$routes->post('createHotels', 'MasterController::createHotels');
|
||||
$routes->get('findHotels', 'MasterController::findHotels');
|
||||
$routes->put('updateHotels/(:num)', 'MasterController::updateHotels/$1');
|
||||
|
||||
|
||||
//mail template
|
||||
$routes->get('template', 'EmailTemplateController::index');
|
||||
$routes->put('template/find/(:num)', 'EmailTemplateController::find/$1');
|
||||
$routes->post('template/create', 'EmailTemplateController::create');
|
||||
$routes->put('template/update/(:num)', 'EmailTemplateController::update/$1');
|
||||
$routes->get('getForexTemplate', 'EmailTemplateController::getForexTemplate');
|
||||
|
||||
$routes->get('getRoles', 'UserController::roleList');
|
||||
|
||||
|
||||
$routes->post('advancePurchaseReport', 'ReportsController::advancePurchaseReport');
|
||||
$routes->post('misServicesAnalysis', 'ReportsController::misServicesAnalysis');
|
||||
$routes->post('misAirReport', 'ReportsController::misAirReport');
|
||||
$routes->post('misHotelReport', 'ReportsController::misHotelReport');
|
||||
$routes->post('misForexReport', 'ReportsController::misForexReport');
|
||||
$routes->post('guestHouseReport', 'ReportsController::guestHouseReport');
|
||||
|
||||
|
||||
// });
|
||||
|
||||
|
||||
// plan review related signed url
|
||||
$routes->post('approvePlan', 'PlanController::approvePlan');
|
||||
$routes->post('rejectPlan', 'PlanController::rejectPlan');
|
||||
$routes->get('review', 'PlanController::protectedPage', ['filter' => 'signedUrl']);
|
||||
$routes->get('url', 'PlanController::url');
|
||||
|
||||
|
||||
// MS OAuth api's
|
||||
$routes->get('auth/mslogin', 'AuthController::mslogin');
|
||||
$routes->get('auth/verifyMSAuthUser', 'AuthController::verifyMSAuthUser');
|
||||
|
||||
|
||||
|
||||
$routes->get('googleoauth', 'AuthController::receiveGoogleOAuthResponse');
|
||||
$routes->get('auth/googlelogin', 'AuthController::initiateGoogleOAuth');
|
||||
$routes->get('logout', 'AuthController::logout');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
140
app/Config/Routing.php
Executable file
140
app/Config/Routing.php
Executable file
@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of CodeIgniter 4 framework.
|
||||
*
|
||||
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\Routing as BaseRouting;
|
||||
|
||||
/**
|
||||
* Routing configuration
|
||||
*/
|
||||
class Routing extends BaseRouting
|
||||
{
|
||||
/**
|
||||
* For Defined Routes.
|
||||
* An array of files that contain route definitions.
|
||||
* Route files are read in order, with the first match
|
||||
* found taking precedence.
|
||||
*
|
||||
* Default: APPPATH . 'Config/Routes.php'
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
public array $routeFiles = [
|
||||
APPPATH . 'Config/Routes.php',
|
||||
];
|
||||
|
||||
/**
|
||||
* For Defined Routes and Auto Routing.
|
||||
* The default namespace to use for Controllers when no other
|
||||
* namespace has been specified.
|
||||
*
|
||||
* Default: 'App\Controllers'
|
||||
*/
|
||||
public string $defaultNamespace = 'App\Controllers';
|
||||
|
||||
/**
|
||||
* For Auto Routing.
|
||||
* The default controller to use when no other controller has been
|
||||
* specified.
|
||||
*
|
||||
* Default: 'Home'
|
||||
*/
|
||||
public string $defaultController = 'Home';
|
||||
|
||||
/**
|
||||
* For Defined Routes and Auto Routing.
|
||||
* The default method to call on the controller when no other
|
||||
* method has been set in the route.
|
||||
*
|
||||
* Default: 'index'
|
||||
*/
|
||||
public string $defaultMethod = 'index';
|
||||
|
||||
/**
|
||||
* For Auto Routing.
|
||||
* Whether to translate dashes in URIs for controller/method to underscores.
|
||||
* Primarily useful when using the auto-routing.
|
||||
*
|
||||
* Default: false
|
||||
*/
|
||||
public bool $translateURIDashes = false;
|
||||
|
||||
/**
|
||||
* Sets the class/method that should be called if routing doesn't
|
||||
* find a match. It can be the controller/method name like: Users::index
|
||||
*
|
||||
* This setting is passed to the Router class and handled there.
|
||||
*
|
||||
* If you want to use a closure, you will have to set it in the
|
||||
* routes file by calling:
|
||||
*
|
||||
* $routes->set404Override(function() {
|
||||
* // Do something here
|
||||
* });
|
||||
*
|
||||
* Example:
|
||||
* public $override404 = 'App\Errors::show404';
|
||||
*/
|
||||
public ?string $override404 = null;
|
||||
|
||||
/**
|
||||
* If TRUE, the system will attempt to match the URI against
|
||||
* Controllers by matching each segment against folders/files
|
||||
* in APPPATH/Controllers, when a match wasn't found against
|
||||
* defined routes.
|
||||
*
|
||||
* If FALSE, will stop searching and do NO automatic routing.
|
||||
*/
|
||||
public bool $autoRoute = false;
|
||||
|
||||
/**
|
||||
* For Defined Routes.
|
||||
* If TRUE, will enable the use of the 'prioritize' option
|
||||
* when defining routes.
|
||||
*
|
||||
* Default: false
|
||||
*/
|
||||
public bool $prioritize = false;
|
||||
|
||||
/**
|
||||
* For Defined Routes.
|
||||
* If TRUE, matched multiple URI segments will be passed as one parameter.
|
||||
*
|
||||
* Default: false
|
||||
*/
|
||||
public bool $multipleSegmentsOneParam = false;
|
||||
|
||||
/**
|
||||
* For Auto Routing (Improved).
|
||||
* Map of URI segments and namespaces.
|
||||
*
|
||||
* The key is the first URI segment. The value is the controller namespace.
|
||||
* E.g.,
|
||||
* [
|
||||
* 'blog' => 'Acme\Blog\Controllers',
|
||||
* ]
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
public array $moduleRoutes = [];
|
||||
|
||||
/**
|
||||
* For Auto Routing (Improved).
|
||||
* Whether to translate dashes in URIs for controller/method to CamelCase.
|
||||
* E.g., blog-controller -> BlogController
|
||||
*
|
||||
* If you enable this, $translateURIDashes is ignored.
|
||||
*
|
||||
* Default: false
|
||||
*/
|
||||
public bool $translateUriToCamelCase = true;
|
||||
}
|
||||
100
app/Config/SamlSettings.php
Executable file
100
app/Config/SamlSettings.php
Executable file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
class SamlSettings extends BaseConfig
|
||||
{
|
||||
|
||||
// IdP (Identity Provider)
|
||||
public $idpEntityId;
|
||||
public $idpSSOUrl;
|
||||
public $idpSLOUrl;
|
||||
public $idpX509Cert;
|
||||
|
||||
// SP (Service Provider)
|
||||
public $spEntityId;
|
||||
public $spAssertionConsumerServiceUrl;
|
||||
public $spSingleLogoutServiceUrl;
|
||||
public $spCert;
|
||||
public $spPrivateKey;
|
||||
|
||||
public $strict = true; // Enable strict mode
|
||||
public $debug = true; // Enable debug mode for development
|
||||
|
||||
private $publicCertPath;
|
||||
private $privateKeyPath;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// Define idp details
|
||||
$this->idpEntityId = env('IDP_EntityId');
|
||||
$this->idpSSOUrl = env('IDP_SSOUrl');
|
||||
$this->idpSLOUrl = env('IDP_SLOUrl');
|
||||
$this->idpX509Cert = env('IDP_X509Cert');
|
||||
|
||||
|
||||
// Define the public and private key file paths
|
||||
$this->publicCertPath = ROOTPATH . 'sp_cert.pem';
|
||||
$this->privateKeyPath = ROOTPATH . 'sp_private_key.pem';
|
||||
|
||||
// Set SP URLs
|
||||
$this->spEntityId = base_url();
|
||||
$this->spAssertionConsumerServiceUrl = base_url() . 'acs';
|
||||
$this->spSingleLogoutServiceUrl = base_url() . 'logout';
|
||||
|
||||
// Load the public certificate
|
||||
$this->spCert = $this->loadFile($this->publicCertPath);
|
||||
|
||||
// Load the private key
|
||||
$this->spPrivateKey = $this->loadPrivateKey($this->privateKeyPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a file and return its contents.
|
||||
*
|
||||
* @param string $filePath Path to the file.
|
||||
* @return string The file contents.
|
||||
*/
|
||||
private function loadFile($filePath)
|
||||
{
|
||||
$fileContents = file_get_contents($filePath);
|
||||
|
||||
if ($fileContents === false) {
|
||||
die("Failed to load the public certificate from {$filePath}");
|
||||
}
|
||||
|
||||
return $fileContents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and validate a private key.
|
||||
*
|
||||
* @param string $filePath Path to the private key file.
|
||||
* @return string The private key contents.
|
||||
*/
|
||||
private function loadPrivateKey($filePath)
|
||||
{
|
||||
$privateKey = file_get_contents($filePath);
|
||||
|
||||
if ($privateKey === false) {
|
||||
die("Failed to read private key from {$filePath}");
|
||||
}
|
||||
|
||||
// Validate the private key
|
||||
if (openssl_pkey_get_private($privateKey) === false) {
|
||||
die("Invalid private key at {$filePath}");
|
||||
}
|
||||
|
||||
return $privateKey;
|
||||
}
|
||||
|
||||
}
|
||||
86
app/Config/Security.php
Executable file
86
app/Config/Security.php
Executable file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
class Security extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* CSRF Protection Method
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Protection Method for Cross Site Request Forgery protection.
|
||||
*
|
||||
* @var string 'cookie' or 'session'
|
||||
*/
|
||||
public string $csrfProtection = 'cookie';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* CSRF Token Randomization
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Randomize the CSRF Token for added security.
|
||||
*/
|
||||
public bool $tokenRandomize = false;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* CSRF Token Name
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Token name for Cross Site Request Forgery protection.
|
||||
*/
|
||||
public string $tokenName = 'csrf_test_name';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* CSRF Header Name
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Header name for Cross Site Request Forgery protection.
|
||||
*/
|
||||
public string $headerName = 'X-CSRF-TOKEN';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* CSRF Cookie Name
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Cookie name for Cross Site Request Forgery protection.
|
||||
*/
|
||||
public string $cookieName = 'csrf_cookie_name';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* CSRF Expires
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Expiration time for Cross Site Request Forgery protection cookie.
|
||||
*
|
||||
* Defaults to two hours (in seconds).
|
||||
*/
|
||||
public int $expires = 7200;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* CSRF Regenerate
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Regenerate CSRF Token on every submission.
|
||||
*/
|
||||
public bool $regenerate = true;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* CSRF Redirect
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Redirect to previous page with error on failure.
|
||||
*
|
||||
* @see https://codeigniter4.github.io/userguide/libraries/security.html#redirection-on-failure
|
||||
*/
|
||||
public bool $redirect = (ENVIRONMENT === 'production');
|
||||
}
|
||||
32
app/Config/Services.php
Executable file
32
app/Config/Services.php
Executable file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseService;
|
||||
|
||||
/**
|
||||
* Services Configuration file.
|
||||
*
|
||||
* Services are simply other classes/libraries that the system uses
|
||||
* to do its job. This is used by CodeIgniter to allow the core of the
|
||||
* framework to be swapped out easily without affecting the usage within
|
||||
* the rest of your application.
|
||||
*
|
||||
* This file holds any application-specific services, or service overrides
|
||||
* that you might need. An example has been included with the general
|
||||
* method format you should use for your service methods. For more examples,
|
||||
* see the core Services file at system/Config/Services.php.
|
||||
*/
|
||||
class Services extends BaseService
|
||||
{
|
||||
/*
|
||||
* public static function example($getShared = true)
|
||||
* {
|
||||
* if ($getShared) {
|
||||
* return static::getSharedInstance('example');
|
||||
* }
|
||||
*
|
||||
* return new \CodeIgniter\Example();
|
||||
* }
|
||||
*/
|
||||
}
|
||||
127
app/Config/Session.php
Executable file
127
app/Config/Session.php
Executable file
@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
use CodeIgniter\Session\Handlers\BaseHandler;
|
||||
use CodeIgniter\Session\Handlers\FileHandler;
|
||||
|
||||
class Session extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Session Driver
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* The session storage driver to use:
|
||||
* - `CodeIgniter\Session\Handlers\FileHandler`
|
||||
* - `CodeIgniter\Session\Handlers\DatabaseHandler`
|
||||
* - `CodeIgniter\Session\Handlers\MemcachedHandler`
|
||||
* - `CodeIgniter\Session\Handlers\RedisHandler`
|
||||
*
|
||||
* @var class-string<BaseHandler>
|
||||
*/
|
||||
public string $driver = FileHandler::class;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Session Cookie Name
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* The session cookie name, must contain only [0-9a-z_-] characters
|
||||
*/
|
||||
public string $cookieName = 'ci_session';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Session Expiration
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* The number of SECONDS you want the session to last.
|
||||
* Setting to 0 (zero) means expire when the browser is closed.
|
||||
*/
|
||||
public int $expiration = 7200;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Session Save Path
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* The location to save sessions to and is 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!
|
||||
*/
|
||||
public string $savePath = WRITEPATH . 'session';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Session 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.
|
||||
*/
|
||||
public bool $matchIP = false;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Session Time to Update
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* How many seconds between CI regenerating the session ID.
|
||||
*/
|
||||
public int $timeToUpdate = 300;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Session 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.
|
||||
*/
|
||||
public bool $regenerateDestroy = false;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Session Database Group
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* DB Group for the database session.
|
||||
*/
|
||||
public ?string $DBGroup = null;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Lock Retry Interval (microseconds)
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* This is used for RedisHandler.
|
||||
*
|
||||
* Time (microseconds) to wait if lock cannot be acquired.
|
||||
* The default is 100,000 microseconds (= 0.1 seconds).
|
||||
*/
|
||||
public int $lockRetryInterval = 100_000;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Lock Max Retries
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* This is used for RedisHandler.
|
||||
*
|
||||
* Maximum number of lock acquisition attempts.
|
||||
* The default is 300 times. That is lock timeout is about 30 (0.1 * 300)
|
||||
* seconds.
|
||||
*/
|
||||
public int $lockMaxRetries = 300;
|
||||
}
|
||||
122
app/Config/Toolbar.php
Executable file
122
app/Config/Toolbar.php
Executable file
@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
use CodeIgniter\Debug\Toolbar\Collectors\Database;
|
||||
use CodeIgniter\Debug\Toolbar\Collectors\Events;
|
||||
use CodeIgniter\Debug\Toolbar\Collectors\Files;
|
||||
use CodeIgniter\Debug\Toolbar\Collectors\Logs;
|
||||
use CodeIgniter\Debug\Toolbar\Collectors\Routes;
|
||||
use CodeIgniter\Debug\Toolbar\Collectors\Timers;
|
||||
use CodeIgniter\Debug\Toolbar\Collectors\Views;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Debug Toolbar
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* The Debug Toolbar provides a way to see information about the performance
|
||||
* and state of your application during that page display. By default it will
|
||||
* NOT be displayed under production environments, and will only display if
|
||||
* `CI_DEBUG` is true, since if it's not, there's not much to display anyway.
|
||||
*/
|
||||
class Toolbar extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Toolbar Collectors
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* List of toolbar collectors that will be called when Debug Toolbar
|
||||
* fires up and collects data from.
|
||||
*
|
||||
* @var list<class-string>
|
||||
*/
|
||||
public array $collectors = [
|
||||
Timers::class,
|
||||
Database::class,
|
||||
Logs::class,
|
||||
Views::class,
|
||||
// \CodeIgniter\Debug\Toolbar\Collectors\Cache::class,
|
||||
Files::class,
|
||||
Routes::class,
|
||||
Events::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Collect Var Data
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* If set to false var data from the views will not be collected. Useful to
|
||||
* avoid high memory usage when there are lots of data passed to the view.
|
||||
*/
|
||||
public bool $collectVarData = true;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Max History
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* `$maxHistory` sets a limit on the number of past requests that are stored,
|
||||
* helping to conserve file space used to store them. You can set it to
|
||||
* 0 (zero) to not have any history stored, or -1 for unlimited history.
|
||||
*/
|
||||
public int $maxHistory = 20;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Toolbar Views Path
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* The full path to the the views that are used by the toolbar.
|
||||
* This MUST have a trailing slash.
|
||||
*/
|
||||
public string $viewsPath = SYSTEMPATH . 'Debug/Toolbar/Views/';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Max Queries
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* If the Database Collector is enabled, it will log every query that the
|
||||
* the system generates so they can be displayed on the toolbar's timeline
|
||||
* and in the query log. This can lead to memory issues in some instances
|
||||
* with hundreds of queries.
|
||||
*
|
||||
* `$maxQueries` defines the maximum amount of queries that will be stored.
|
||||
*/
|
||||
public int $maxQueries = 100;
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Watched Directories
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Contains an array of directories that will be watched for changes and
|
||||
* used to determine if the hot-reload feature should reload the page or not.
|
||||
* We restrict the values to keep performance as high as possible.
|
||||
*
|
||||
* NOTE: The ROOTPATH will be prepended to all values.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
public array $watchedDirectories = [
|
||||
'app',
|
||||
];
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Watched File Extensions
|
||||
* --------------------------------------------------------------------------
|
||||
*
|
||||
* Contains an array of file extensions that will be watched for changes and
|
||||
* used to determine if the hot-reload feature should reload the page or not.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
public array $watchedExtensions = [
|
||||
'php', 'css', 'js', 'html', 'svg', 'json', 'env',
|
||||
];
|
||||
}
|
||||
252
app/Config/UserAgents.php
Executable file
252
app/Config/UserAgents.php
Executable file
@ -0,0 +1,252 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
/**
|
||||
* -------------------------------------------------------------------
|
||||
* User Agents
|
||||
* -------------------------------------------------------------------
|
||||
*
|
||||
* This file contains four arrays of user agent data. It is used by the
|
||||
* User Agent Class to help identify browser, platform, robot, and
|
||||
* mobile device data. The array keys are used to identify the device
|
||||
* and the array values are used to set the actual name of the item.
|
||||
*/
|
||||
class UserAgents extends BaseConfig
|
||||
{
|
||||
/**
|
||||
* -------------------------------------------------------------------
|
||||
* OS Platforms
|
||||
* -------------------------------------------------------------------
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
public array $platforms = [
|
||||
'windows nt 10.0' => 'Windows 10',
|
||||
'windows nt 6.3' => 'Windows 8.1',
|
||||
'windows nt 6.2' => 'Windows 8',
|
||||
'windows nt 6.1' => 'Windows 7',
|
||||
'windows nt 6.0' => 'Windows Vista',
|
||||
'windows nt 5.2' => 'Windows 2003',
|
||||
'windows nt 5.1' => 'Windows XP',
|
||||
'windows nt 5.0' => 'Windows 2000',
|
||||
'windows nt 4.0' => 'Windows NT 4.0',
|
||||
'winnt4.0' => 'Windows NT 4.0',
|
||||
'winnt 4.0' => 'Windows NT',
|
||||
'winnt' => 'Windows NT',
|
||||
'windows 98' => 'Windows 98',
|
||||
'win98' => 'Windows 98',
|
||||
'windows 95' => 'Windows 95',
|
||||
'win95' => 'Windows 95',
|
||||
'windows phone' => 'Windows Phone',
|
||||
'windows' => 'Unknown Windows OS',
|
||||
'android' => 'Android',
|
||||
'blackberry' => 'BlackBerry',
|
||||
'iphone' => 'iOS',
|
||||
'ipad' => 'iOS',
|
||||
'ipod' => 'iOS',
|
||||
'os x' => 'Mac OS X',
|
||||
'ppc mac' => 'Power PC Mac',
|
||||
'freebsd' => 'FreeBSD',
|
||||
'ppc' => 'Macintosh',
|
||||
'linux' => 'Linux',
|
||||
'debian' => 'Debian',
|
||||
'sunos' => 'Sun Solaris',
|
||||
'beos' => 'BeOS',
|
||||
'apachebench' => 'ApacheBench',
|
||||
'aix' => 'AIX',
|
||||
'irix' => 'Irix',
|
||||
'osf' => 'DEC OSF',
|
||||
'hp-ux' => 'HP-UX',
|
||||
'netbsd' => 'NetBSD',
|
||||
'bsdi' => 'BSDi',
|
||||
'openbsd' => 'OpenBSD',
|
||||
'gnu' => 'GNU/Linux',
|
||||
'unix' => 'Unknown Unix OS',
|
||||
'symbian' => 'Symbian OS',
|
||||
];
|
||||
|
||||
/**
|
||||
* -------------------------------------------------------------------
|
||||
* Browsers
|
||||
* -------------------------------------------------------------------
|
||||
*
|
||||
* The order of this array should NOT be changed. Many browsers return
|
||||
* multiple browser types so we want to identify the subtype first.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
public array $browsers = [
|
||||
'OPR' => 'Opera',
|
||||
'Flock' => 'Flock',
|
||||
'Edge' => 'Spartan',
|
||||
'Edg' => 'Edge',
|
||||
'Chrome' => 'Chrome',
|
||||
// Opera 10+ always reports Opera/9.80 and appends Version/<real version> to the user agent string
|
||||
'Opera.*?Version' => 'Opera',
|
||||
'Opera' => 'Opera',
|
||||
'MSIE' => 'Internet Explorer',
|
||||
'Internet Explorer' => 'Internet Explorer',
|
||||
'Trident.* rv' => 'Internet Explorer',
|
||||
'Shiira' => 'Shiira',
|
||||
'Firefox' => 'Firefox',
|
||||
'Chimera' => 'Chimera',
|
||||
'Phoenix' => 'Phoenix',
|
||||
'Firebird' => 'Firebird',
|
||||
'Camino' => 'Camino',
|
||||
'Netscape' => 'Netscape',
|
||||
'OmniWeb' => 'OmniWeb',
|
||||
'Safari' => 'Safari',
|
||||
'Mozilla' => 'Mozilla',
|
||||
'Konqueror' => 'Konqueror',
|
||||
'icab' => 'iCab',
|
||||
'Lynx' => 'Lynx',
|
||||
'Links' => 'Links',
|
||||
'hotjava' => 'HotJava',
|
||||
'amaya' => 'Amaya',
|
||||
'IBrowse' => 'IBrowse',
|
||||
'Maxthon' => 'Maxthon',
|
||||
'Ubuntu' => 'Ubuntu Web Browser',
|
||||
'Vivaldi' => 'Vivaldi',
|
||||
];
|
||||
|
||||
/**
|
||||
* -------------------------------------------------------------------
|
||||
* Mobiles
|
||||
* -------------------------------------------------------------------
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
public array $mobiles = [
|
||||
// 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',
|
||||
];
|
||||
|
||||
/**
|
||||
* -------------------------------------------------------------------
|
||||
* Robots
|
||||
* -------------------------------------------------------------------
|
||||
*
|
||||
* There are hundred of bots but these are the most common.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
public array $robots = [
|
||||
'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',
|
||||
];
|
||||
}
|
||||
44
app/Config/Validation.php
Executable file
44
app/Config/Validation.php
Executable file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
use CodeIgniter\Validation\StrictRules\CreditCardRules;
|
||||
use CodeIgniter\Validation\StrictRules\FileRules;
|
||||
use CodeIgniter\Validation\StrictRules\FormatRules;
|
||||
use CodeIgniter\Validation\StrictRules\Rules;
|
||||
|
||||
class Validation extends BaseConfig
|
||||
{
|
||||
// --------------------------------------------------------------------
|
||||
// Setup
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Stores the classes that contain the
|
||||
* rules that are available.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
public array $ruleSets = [
|
||||
Rules::class,
|
||||
FormatRules::class,
|
||||
FileRules::class,
|
||||
CreditCardRules::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Specifies the views that are used to display the
|
||||
* errors.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
public array $templates = [
|
||||
'list' => 'CodeIgniter\Validation\Views\list',
|
||||
'single' => 'CodeIgniter\Validation\Views\single',
|
||||
];
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Rules
|
||||
// --------------------------------------------------------------------
|
||||
}
|
||||
62
app/Config/View.php
Executable file
62
app/Config/View.php
Executable file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Config;
|
||||
|
||||
use CodeIgniter\Config\View as BaseView;
|
||||
use CodeIgniter\View\ViewDecoratorInterface;
|
||||
|
||||
/**
|
||||
* @phpstan-type parser_callable (callable(mixed): mixed)
|
||||
* @phpstan-type parser_callable_string (callable(mixed): mixed)&string
|
||||
*/
|
||||
class View extends BaseView
|
||||
{
|
||||
/**
|
||||
* When false, the view method will clear the data between each
|
||||
* call. This keeps your data safe and ensures there is no accidental
|
||||
* leaking between calls, so you would need to explicitly pass the data
|
||||
* to each view. You might prefer to have the data stick around between
|
||||
* calls so that it is available to all views. If that is the case,
|
||||
* set $saveData to true.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $saveData = true;
|
||||
|
||||
/**
|
||||
* Parser Filters map a filter name with any PHP callable. When the
|
||||
* Parser prepares a variable for display, it will chain it
|
||||
* through the filters in the order defined, inserting any parameters.
|
||||
* To prevent potential abuse, all filters MUST be defined here
|
||||
* in order for them to be available for use within the Parser.
|
||||
*
|
||||
* Examples:
|
||||
* { title|esc(js) }
|
||||
* { created_on|date(Y-m-d)|esc(attr) }
|
||||
*
|
||||
* @var array<string, string>
|
||||
* @phpstan-var array<string, parser_callable_string>
|
||||
*/
|
||||
public $filters = [];
|
||||
|
||||
/**
|
||||
* Parser Plugins provide a way to extend the functionality provided
|
||||
* by the core Parser by creating aliases that will be replaced with
|
||||
* any callable. Can be single or tag pair.
|
||||
*
|
||||
* @var array<string, callable|list<string>|string>
|
||||
* @phpstan-var array<string, list<parser_callable_string>|parser_callable_string|parser_callable>
|
||||
*/
|
||||
public $plugins = [];
|
||||
|
||||
/**
|
||||
* View Decorators are class methods that will be run in sequence to
|
||||
* have a chance to alter the generated output just prior to caching
|
||||
* the results.
|
||||
*
|
||||
* All classes must implement CodeIgniter\View\ViewDecoratorInterface
|
||||
*
|
||||
* @var list<class-string<ViewDecoratorInterface>>
|
||||
*/
|
||||
public array $decorators = [];
|
||||
}
|
||||
318
app/Controllers/AuthController.php
Normal file
318
app/Controllers/AuthController.php
Normal file
@ -0,0 +1,318 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
use CodeIgniter\RESTful\ResourceController;
|
||||
use App\Models\UserModel;
|
||||
use App\Models\OrganizationModel;
|
||||
use App\Models\GroupModel;
|
||||
use App\Models\PolicyModel;
|
||||
use App\Models\PolicyDetailsModel;
|
||||
use App\Models\ServiceModel;
|
||||
|
||||
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
|
||||
use TheNetworg\OAuth2\Client\Provider\Azure;
|
||||
use Google\Client as GoogleClient;
|
||||
use Google\Service\Oauth2;
|
||||
|
||||
class AuthController extends ResourceController
|
||||
{
|
||||
protected $format = 'json';
|
||||
protected $userModel;
|
||||
protected $organizationModel;
|
||||
protected $groupModel;
|
||||
protected $policyModel;
|
||||
protected $policyDetailsModel;
|
||||
protected $serviceModel;
|
||||
protected $provider;
|
||||
protected $googleProvider;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
helper('jwt_helper');
|
||||
helper('oauth_helper');
|
||||
$this->userModel = new UserModel();
|
||||
$this->organizationModel = new OrganizationModel();
|
||||
$this->groupModel = new GroupModel();
|
||||
$this->policyModel = new PolicyModel();
|
||||
$this->policyDetailsModel = new PolicyDetailsModel();
|
||||
$this->serviceModel = new ServiceModel();
|
||||
|
||||
$this->provider = new Azure([
|
||||
'clientId' => "9af66888-eb85-48ec-b3a0-ba857734f52b",
|
||||
'clientSecret' => "N2_8Q~FBEXtoZft2UgJ6FQZCh3ZIbJydYgxREbUb",
|
||||
'redirectUri' => "https://apitest.tripapprovaltool.com/tstat/authredirection",
|
||||
'tenant' => "284bf2b6-6dd8-4b46-881c-de45fde35736",
|
||||
]);
|
||||
$this->provider->scope = [
|
||||
'openid',
|
||||
'profile',
|
||||
'email',
|
||||
'offline_access',
|
||||
'User.Read'
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
public function login()
|
||||
{
|
||||
|
||||
|
||||
$rules = [
|
||||
'email' => 'required|valid_email',
|
||||
'password' => 'required'
|
||||
];
|
||||
|
||||
if (!$this->validate($rules)) {
|
||||
return $this->failValidationErrors($this->validator->getErrors());
|
||||
}
|
||||
|
||||
|
||||
$data = $this->request->getJSON();
|
||||
$user = $this->userModel->where('email', $data->email)->where('is_active',1)->first();
|
||||
// print_r($user);die;
|
||||
if (!$user) {
|
||||
return $this->failUnauthorized('Invalid email or password');
|
||||
}
|
||||
|
||||
// Verify password (assuming it's hashed)
|
||||
if (!password_verify($data->password, $user['password'])) {
|
||||
return $this->failUnauthorized('Invalid email or password');
|
||||
}
|
||||
|
||||
//update last login time in last_login_at column
|
||||
$this->userModel->update($user['user_id'], ['last_login_at' => date('Y-m-d H:i:s')]);
|
||||
|
||||
|
||||
$user = $this->userModel->where('email', $data->email)->first();
|
||||
if (!empty($user['last_login_at'])) {
|
||||
$user['last_login_at'] = date('d, M-Y h:iA', strtotime($user['last_login_at']));
|
||||
} else {
|
||||
$user['last_login_at'] = null;
|
||||
}
|
||||
|
||||
|
||||
//get service for the organization
|
||||
$orgService = $this->organizationModel->find($user['org_id']);
|
||||
$user['service'] = json_decode($orgService['services_ids'],true);
|
||||
foreach ($user['service'] as $key => $value)
|
||||
{
|
||||
$serviceData = $this->serviceModel->find($value['service_id']);
|
||||
$user['service'][$key]['name'] = $serviceData['name'];
|
||||
$user['service'][$key]['icon'] = $serviceData['icon'];
|
||||
$user['service'][$key]['order'] = $serviceData['order'];
|
||||
}
|
||||
|
||||
//get role
|
||||
$user['role'] = $this->userModel->getRole($user['role_id']);
|
||||
|
||||
//find user has the all access
|
||||
$user['plan_action'] = getUserPlanCreationRestrictionStatus($user);
|
||||
|
||||
// Generate JWT Token
|
||||
$token = generateJWT($user);
|
||||
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Login successful',
|
||||
'token' => $token
|
||||
]);
|
||||
}
|
||||
|
||||
public function oauthClient()
|
||||
{
|
||||
$orgData = $this->organizationModel->find(env('ORG_id'));
|
||||
|
||||
if (!$orgData) { return $this->failUnauthorized('Organization Id Not Set'); }
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'success',
|
||||
'data' => ['oauth_client_id' => $orgData['oauth_client_id'] , 'oauth_client_secret' => $orgData['oauth_client_secret']]
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function oauthlogin()
|
||||
{
|
||||
$rules = [
|
||||
'email' => 'required|valid_email',
|
||||
'name' => 'required',
|
||||
];
|
||||
|
||||
if (!$this->validate($rules)) {
|
||||
return $this->failValidationErrors($this->validator->getErrors());
|
||||
}
|
||||
|
||||
|
||||
$data = $this->request->getJSON();
|
||||
$user = $this->userModel->where('email', $data->email)->first();
|
||||
|
||||
if (!$user) {
|
||||
$insert['email'] = $data->email;
|
||||
$insert['first_name'] = $data->name;
|
||||
$insert['org_id'] = env('ORG_id');
|
||||
$insert['role_id'] = 4;
|
||||
$userId = $this->userModel->insert($insert, true);
|
||||
$user = $this->userModel->where('user_id', $userId)->first();
|
||||
}
|
||||
|
||||
//get service for the organization
|
||||
$orgService = $this->organizationModel->find($user['org_id']);
|
||||
$user['service'] = json_decode($orgService['services_ids'],true);
|
||||
foreach ($user['service'] as $key => $value)
|
||||
{
|
||||
$serviceData = $this->serviceModel->find($value['service_id']);
|
||||
$user['service'][$key]['name'] = $serviceData['name'];
|
||||
$user['service'][$key]['icon'] = $serviceData['icon'];
|
||||
}
|
||||
|
||||
//get role
|
||||
$user['role'] = $this->userModel->getRole($user['role_id']);
|
||||
|
||||
//find user has the all access
|
||||
$user['plan_action'] = getUserPlanCreationRestrictionStatus($user);
|
||||
|
||||
// Generate JWT Token
|
||||
$token = generateJWT($user);
|
||||
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Login successful',
|
||||
'token' => $token
|
||||
]);
|
||||
}
|
||||
|
||||
//microsoft oAuth
|
||||
public function mslogin()
|
||||
{
|
||||
$options = [
|
||||
'scope' => ['openid', 'email', 'profile', 'User.Read']
|
||||
];
|
||||
|
||||
$authUrl = $this->provider->getAuthorizationUrl($options);
|
||||
|
||||
return $this->response->setJSON([
|
||||
'auth_url' => $authUrl
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function verifyMSAuthUser()
|
||||
{
|
||||
|
||||
$code = $this->request->getVar('code');
|
||||
// echo $code;
|
||||
try {
|
||||
$token = $this->provider->getAccessToken('authorization_code', [
|
||||
'code' => $code
|
||||
]);
|
||||
|
||||
$ownerDetails = $this->provider->getResourceOwner($token);
|
||||
$data = $ownerDetails->toArray();
|
||||
|
||||
$name = $data['name'] ?? null;
|
||||
$email = $data['upn'] ?? $data['unique_name'] ?? null;
|
||||
|
||||
$res = checkUserExist($name, $email);
|
||||
|
||||
if($res['status'] == true)
|
||||
{
|
||||
$user = $res['data'];
|
||||
//get service for the organization
|
||||
$orgService = $this->organizationModel->find($user['org_id']);
|
||||
$user['service'] = json_decode($orgService['services_ids'],true);
|
||||
foreach ($user['service'] as $key => $value)
|
||||
{
|
||||
$serviceData = $this->serviceModel->find($value['service_id']);
|
||||
$user['service'][$key]['name'] = $serviceData['name'];
|
||||
$user['service'][$key]['icon'] = $serviceData['icon'];
|
||||
}
|
||||
|
||||
//get role
|
||||
$user['role'] = $this->userModel->getRole($user['role_id']);
|
||||
|
||||
//find user has the all access
|
||||
$user['plan_action'] = getUserPlanCreationRestrictionStatus($user);
|
||||
|
||||
$token = generateJWT($user);
|
||||
|
||||
return $this->respond([ 'status' => 200,'message' => 'Login successful','token' => $token ]);
|
||||
|
||||
}else{
|
||||
return $this->respond([ 'status' => 401,'message' => 'Login Failed','data' => [] ]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} catch (IdentityProviderException $e) {
|
||||
exit($e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
//end of microsoft oAuth
|
||||
|
||||
|
||||
public function receiveGoogleOAuthResponse()
|
||||
{
|
||||
|
||||
if ($this->request->getGet('code')) {
|
||||
|
||||
$value = googleOAuthLogin($this->request->getGet('code'));
|
||||
if ($value) {
|
||||
|
||||
$user = $this->userModel->where('email', $value->email)->first();
|
||||
// print_r($user);die;
|
||||
if (empty($user)) {
|
||||
return $this->failUnauthorized('User Not Found');
|
||||
}
|
||||
|
||||
if ($user['is_active'] == 0) {
|
||||
return $this->failUnauthorized('User Not Active');
|
||||
}
|
||||
|
||||
//get service for the organization
|
||||
$orgService = $this->organizationModel->find($user['org_id']);
|
||||
$user['service'] = json_decode($orgService['services_ids'],true);
|
||||
foreach ($user['service'] as $key => $value)
|
||||
{
|
||||
$serviceData = $this->serviceModel->find($value['service_id']);
|
||||
$user['service'][$key]['name'] = $serviceData['name'];
|
||||
$user['service'][$key]['icon'] = $serviceData['icon'];
|
||||
$user['service'][$key]['order'] = $serviceData['order'];
|
||||
}
|
||||
|
||||
//get role
|
||||
$user['role'] = $this->userModel->getRole($user['role_id']);
|
||||
|
||||
//find user has the all access
|
||||
$user['plan_action'] = getUserPlanCreationRestrictionStatus($user);
|
||||
|
||||
// Generate JWT Token
|
||||
$token = generateJWT($user);
|
||||
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Login successful',
|
||||
'token' => $token
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
return $this->respond([
|
||||
'status' => 400,
|
||||
'message' => 'Login failed',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function initiateGoogleOAuth()
|
||||
{
|
||||
return googleOAuthLogin(false);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
58
app/Controllers/BaseController.php
Executable file
58
app/Controllers/BaseController.php
Executable file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use CodeIgniter\Controller;
|
||||
use CodeIgniter\HTTP\CLIRequest;
|
||||
use CodeIgniter\HTTP\IncomingRequest;
|
||||
use CodeIgniter\HTTP\RequestInterface;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Class BaseController
|
||||
*
|
||||
* BaseController provides a convenient place for loading components
|
||||
* and performing functions that are needed by all your controllers.
|
||||
* Extend this class in any new controllers:
|
||||
* class Home extends BaseController
|
||||
*
|
||||
* For security be sure to declare any new methods as protected or private.
|
||||
*/
|
||||
abstract class BaseController extends Controller
|
||||
{
|
||||
/**
|
||||
* Instance of the main Request object.
|
||||
*
|
||||
* @var CLIRequest|IncomingRequest
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* An array of helpers to be loaded automatically upon
|
||||
* class instantiation. These helpers will be available
|
||||
* to all other controllers that extend BaseController.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $helpers = [];
|
||||
|
||||
/**
|
||||
* Be sure to declare properties for any property fetch you initialized.
|
||||
* The creation of dynamic property is deprecated in PHP 8.2.
|
||||
*/
|
||||
// protected $session;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
|
||||
{
|
||||
// Do Not Edit This Line
|
||||
parent::initController($request, $response, $logger);
|
||||
|
||||
// Preload any models, libraries, etc, here.
|
||||
|
||||
// E.g.: $this->session = service('session');
|
||||
}
|
||||
}
|
||||
132
app/Controllers/EmailTemplateController.php
Normal file
132
app/Controllers/EmailTemplateController.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use CodeIgniter\RESTful\ResourceController;
|
||||
use App\Models\MailTemplateModel;
|
||||
|
||||
class EmailTemplateController extends ResourceController
|
||||
{
|
||||
protected $format = 'json';
|
||||
protected $myLogger;
|
||||
protected $mailTemplateModel;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->mailTemplateModel = new MailTemplateModel();
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$org_id = $this->request->getGet('org_id');
|
||||
|
||||
if (!$org_id) {
|
||||
log_message('error', 'Organization ID missing in index() template list');
|
||||
return $this->failNotFound('Organization ID is required');
|
||||
}
|
||||
|
||||
//fetch existing template data for the give ORG ID
|
||||
$mailTemplateData = $this->mailTemplateModel->where('org_id', $org_id)->where('template_name !=', 'forex')->findAll();
|
||||
|
||||
if (!$mailTemplateData) {
|
||||
log_message('error', "No mail template found for org_id: {$org_id} in index()");
|
||||
return $this->failNotFound('No template found');
|
||||
}
|
||||
|
||||
log_message('error', "Mail templates found for org_id: {$org_id} in index()");
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Template found',
|
||||
'data' => $mailTemplateData
|
||||
]);
|
||||
}
|
||||
|
||||
public function getForexTemplate()
|
||||
{
|
||||
$template_name = $this->request->getGet('template_name');
|
||||
|
||||
if (!$template_name) {
|
||||
log_message('error', 'template_name missing ');
|
||||
return $this->failNotFound('template_name is required');
|
||||
}
|
||||
|
||||
//fetch existing template data for the give ID
|
||||
$singleMailTemplateData = $this->mailTemplateModel->where('template_name', $template_name)->first();
|
||||
|
||||
if (!$singleMailTemplateData) {
|
||||
log_message('error', "Template not found for template: {$template_name} in find()");
|
||||
return $this->failNotFound('Template not found');
|
||||
}
|
||||
|
||||
log_message('error', "Template found for template: {$template_name} in find()");
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Template found',
|
||||
'data' => $singleMailTemplateData
|
||||
]);
|
||||
}
|
||||
|
||||
public function find($id = null)
|
||||
{
|
||||
if (!$id) {
|
||||
log_message('error', 'Template ID missing in find()');
|
||||
return $this->failNotFound('Template id is required');
|
||||
}
|
||||
|
||||
//fetch existing template data for the give ID
|
||||
$singleMailTemplateData = $this->mailTemplateModel->find($id);
|
||||
|
||||
if (!$singleMailTemplateData) {
|
||||
log_message('error', "Template not found for id: {$id} in find()");
|
||||
return $this->failNotFound('Template not found');
|
||||
}
|
||||
|
||||
log_message('error', "Template found for id: {$id} in find()");
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Template found',
|
||||
'data' => $singleMailTemplateData
|
||||
]);
|
||||
}
|
||||
|
||||
public function update($id = null)
|
||||
{
|
||||
if (!$id) {
|
||||
log_message('error', 'Template ID missing in update()');
|
||||
return $this->failNotFound('Template ID is required');
|
||||
}
|
||||
|
||||
//request data
|
||||
$data = $this->request->getJSON(true);
|
||||
$req['body_html'] = (string)$data['body_html'];
|
||||
$req['subject'] = $data['subject'];
|
||||
// print_r($data); die;
|
||||
|
||||
if (empty($data)) {
|
||||
log_message('error', "No data provided for update in update() with id: {$id}");
|
||||
return $this->failValidationErrors('No data provided for update');
|
||||
}
|
||||
|
||||
//fetch existing template data for the give ID
|
||||
$singleMailTemplateData = $this->mailTemplateModel->find($id);
|
||||
if (!$singleMailTemplateData) {
|
||||
log_message('error', "Template not found for update() with id: {$id}");
|
||||
return $this->failNotFound('Template not found');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->mailTemplateModel->update($id, $req);
|
||||
log_message('error', "Template updated successfully for id: {$id} in update()");
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Template updated successfully',
|
||||
'data' => $this->mailTemplateModel->find($id)
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
log_message('error', "Failed to update template in update() with id: {$id}, Error: {$e->getMessage()}");
|
||||
return $this->failServerError('Failed to update template: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
11
app/Controllers/Home.php
Executable file
11
app/Controllers/Home.php
Executable file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
class Home extends BaseController
|
||||
{
|
||||
public function index(): string
|
||||
{
|
||||
return view('welcome_message');
|
||||
}
|
||||
}
|
||||
635
app/Controllers/MasterController.php
Normal file
635
app/Controllers/MasterController.php
Normal file
@ -0,0 +1,635 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use CodeIgniter\RESTful\ResourceController;
|
||||
use App\Models\DropdownModel;
|
||||
use App\Models\DepartmentModel;
|
||||
use App\Models\TravelStatusModel;
|
||||
use App\Models\CountryModel;
|
||||
use App\Models\AirportCodeModel;
|
||||
use App\Models\TrainStationsModel;
|
||||
use App\Models\UserModel;
|
||||
use App\Models\OrganizationModel;
|
||||
use App\Models\GroupModel;
|
||||
use App\Models\PolicyModel;
|
||||
use App\Models\PolicyDetailsModel;
|
||||
use App\Models\ServiceModel;
|
||||
use App\Models\ForexPerdiemModel;
|
||||
use App\Models\HotelModel;
|
||||
use App\Models\CostCenterModel;
|
||||
use App\Models\AirlineModel;
|
||||
|
||||
class MasterController extends ResourceController
|
||||
{
|
||||
protected $format = 'json';
|
||||
protected $myLogger;
|
||||
protected $dropdownModel;
|
||||
protected $departmentModel;
|
||||
protected $travelStatusModel;
|
||||
protected $countryModel;
|
||||
protected $airportCodeModel;
|
||||
protected $trainStationsModel;
|
||||
protected $userModel;
|
||||
protected $organizationModel;
|
||||
protected $groupModel;
|
||||
protected $policyModel;
|
||||
protected $policyDetailsModel;
|
||||
protected $serviceModel;
|
||||
protected $forexPerdiemModel;
|
||||
protected $hotelModel;
|
||||
protected $costCenterModel;
|
||||
protected $airlineModel;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->myLogger = \Config\Services::mylogger();
|
||||
$this->dropdownModel = new DropdownModel();
|
||||
$this->departmentModel = new DepartmentModel();
|
||||
$this->travelStatusModel = new TravelStatusModel();
|
||||
$this->countryModel = new CountryModel();
|
||||
$this->airportCodeModel = new AirportCodeModel();
|
||||
$this->trainStationsModel = new TrainStationsModel();
|
||||
$this->userModel = new UserModel();
|
||||
$this->organizationModel = new OrganizationModel();
|
||||
$this->groupModel = new GroupModel();
|
||||
$this->policyModel = new PolicyModel();
|
||||
$this->policyDetailsModel = new PolicyDetailsModel();
|
||||
$this->serviceModel = new ServiceModel();
|
||||
$this->forexPerdiemModel = new ForexPerdiemModel();
|
||||
$this->hotelModel = new HotelModel();
|
||||
$this->costCenterModel = new CostCenterModel();
|
||||
$this->airlineModel = new AirlineModel();
|
||||
}
|
||||
|
||||
|
||||
public function getDropdownMaster()
|
||||
{
|
||||
$data = $this->dropdownModel->select('dropdown')->groupBy('dropdown')->findAll();
|
||||
|
||||
if (!$data) {
|
||||
return $this->failNotFound('No data found');
|
||||
}
|
||||
|
||||
if ($data)
|
||||
{
|
||||
foreach ($data as &$val)
|
||||
{
|
||||
$temp[$val['dropdown']] = $this->dropdownModel->where('dropdown', $val['dropdown'])->where('is_active',1)->findAll();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->respond(['status' => 200,'message' => 'success','data' => $temp]);
|
||||
}
|
||||
|
||||
|
||||
public function getTravelStatusMaster()
|
||||
{
|
||||
$data = $this->travelStatusModel->where('is_active',1)->findAll();
|
||||
|
||||
if (!$data) {
|
||||
return $this->failNotFound('No data found');
|
||||
}
|
||||
|
||||
return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
|
||||
}
|
||||
|
||||
public function getcountryMaster()
|
||||
{
|
||||
$data = $this->countryModel->where('is_active',1)->findAll();
|
||||
|
||||
if (!$data) {
|
||||
return $this->failNotFound('No data found');
|
||||
}
|
||||
|
||||
return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
|
||||
}
|
||||
|
||||
public function getAirlineMaster()
|
||||
{
|
||||
$data = $this->airlineModel->findAll();
|
||||
|
||||
if (!$data) {
|
||||
return $this->failNotFound('No data found');
|
||||
}
|
||||
|
||||
return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
|
||||
}
|
||||
|
||||
|
||||
public function getAirportCodeMaster()
|
||||
{
|
||||
$type = $this->request->getGet('trip_type');
|
||||
|
||||
// Build the query
|
||||
$query = $this->airportCodeModel->where('is_active', 1);
|
||||
if ($type == 1) {
|
||||
$query->where('Country_Code', 'IN');
|
||||
}
|
||||
|
||||
// Execute the query and get the result
|
||||
$data = $query->findAll();
|
||||
|
||||
// Check if data exists
|
||||
if (empty($data)) {
|
||||
return $this->failNotFound('No data found');
|
||||
}
|
||||
|
||||
// Return success response
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'success',
|
||||
'data' => $data
|
||||
]);
|
||||
}
|
||||
|
||||
public function getTrainCodeMaster()
|
||||
{
|
||||
$data = $this->trainStationsModel->where('is_active',1)->findAll();
|
||||
|
||||
if (!$data) {
|
||||
return $this->failNotFound('No data found');
|
||||
}
|
||||
|
||||
return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
|
||||
}
|
||||
|
||||
public function getFlightAndTrainClass()
|
||||
{
|
||||
|
||||
|
||||
$trip_type = $this->request->getGet('trip_type');
|
||||
$user_id = $this->request->getVar('user_id');
|
||||
|
||||
$user = $this->userModel->where('user_id', $user_id)->first();
|
||||
$groupData = $this->groupModel->find($user['group_id']);
|
||||
if($groupData)
|
||||
{
|
||||
if($trip_type == 1) { $policyId = $groupData['domestic_policy_id'];}else{ $policyId = $groupData['international_policy_id'];}
|
||||
if($policyId != null)
|
||||
{
|
||||
$minFlightClassKey = $this->policyDetailsModel->where('policy_id',$policyId)->where('service_id',1)->get()->getRow()->class;
|
||||
$minTrainClassKey = $this->policyDetailsModel->where('policy_id',$policyId)->where('service_id',2)->get()->getRow()->class;
|
||||
$minHotelClassKey = $this->policyDetailsModel->where('policy_id',$policyId)->where('service_id',5)->get()->getRow()->class;
|
||||
}
|
||||
|
||||
|
||||
//flight
|
||||
$allFlightClass = $this->dropdownModel->where('dropdown', 'flight_class')->orderBy('dropdown_key','ASC')->findAll();
|
||||
$minFlightClassKey = $minFlightClassKey ?? 0;
|
||||
$data['flight_class'] = [];
|
||||
foreach ($allFlightClass as $key => $value) {
|
||||
|
||||
if((int)$value['dropdown_key'] >= (int)$minFlightClassKey){
|
||||
$value['is_allowed'] = 'yes';
|
||||
array_push($data['flight_class'] , $value);
|
||||
}else{
|
||||
$value['is_allowed'] = 'No';
|
||||
array_push($data['flight_class'] , $value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//train
|
||||
$allTrainClass = $this->dropdownModel->where('dropdown', 'train_class')->orderBy('dropdown_key','ASC')->findAll();
|
||||
$minTrainClassKey = $minTrainClassKey ?? 0;
|
||||
$data['train_class'] = [];
|
||||
|
||||
foreach ($allTrainClass as $key => $value) {
|
||||
|
||||
if((int)$value['dropdown_key'] >= (int)$minTrainClassKey){
|
||||
$value['is_allowed'] = 'yes';
|
||||
array_push($data['train_class'] , $value);
|
||||
}else{
|
||||
$value['is_allowed'] = 'No';
|
||||
array_push($data['train_class'] , $value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//hotel
|
||||
$allHotelClass = $this->dropdownModel->where('dropdown', 'hotel_class')->orderBy('dropdown_key','ASC')->findAll();
|
||||
$minHotelClassKey = $minHotelClassKey ?? 0;
|
||||
$data['hotel_class'] = [];
|
||||
|
||||
foreach ($allHotelClass as $key => $value) {
|
||||
|
||||
if((int)$value['dropdown_key'] >= (int)$minHotelClassKey){
|
||||
$value['is_allowed'] = 'yes';
|
||||
array_push($data['hotel_class'] , $value);
|
||||
}else{
|
||||
$value['is_allowed'] = 'No';
|
||||
array_push($data['hotel_class'] , $value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!$data) {
|
||||
return $this->failNotFound('No data found');
|
||||
}
|
||||
|
||||
return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
|
||||
}
|
||||
|
||||
|
||||
// Department crud
|
||||
public function getDepartmentList()
|
||||
{
|
||||
$for = $this->request->getVar('for');
|
||||
|
||||
if (isset($for) && $for === 'table_view')
|
||||
{
|
||||
$data = $this->dropdownModel->where('dropdown','plan_functional_department')->findAll();
|
||||
} else {
|
||||
$data = $this->dropdownModel->where('dropdown','plan_functional_department')->where('is_active', 1)->findAll();
|
||||
}
|
||||
|
||||
if (!$data) {
|
||||
return $this->failNotFound('No data found');
|
||||
}
|
||||
|
||||
return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
|
||||
}
|
||||
|
||||
public function createDepartment()
|
||||
{
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
$data['dropdown'] = 'plan_functional_department';
|
||||
$data['is_active'] = 1;
|
||||
$existData = $this->dropdownModel->where('dropdown','plan_functional_department')->findAll();
|
||||
$data['dropdown_key'] = count($existData) + 1;
|
||||
|
||||
if (!$this->dropdownModel->insert($data)) {
|
||||
return $this->failValidationErrors($this->dropdownModel->errors());
|
||||
}
|
||||
|
||||
return $this->respondCreated([
|
||||
'status' => 201,
|
||||
'message' => 'Department created successfully'
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function findDepartment()
|
||||
{
|
||||
|
||||
$id = $this->request->getGet('id');
|
||||
|
||||
$data = $this->dropdownModel->where('id',$id)->find();
|
||||
|
||||
if (!$data) {
|
||||
return $this->failNotFound('No data found');
|
||||
}
|
||||
|
||||
return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
|
||||
}
|
||||
|
||||
public function updateDepartment($id = null)
|
||||
{
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
if (!$this->dropdownModel->find($id)) {
|
||||
return $this->failNotFound('Department not found');
|
||||
}
|
||||
|
||||
if (!$this->dropdownModel->update($id, $data)) {
|
||||
return $this->failValidationErrors($this->dropdownModel->errors());
|
||||
}
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Department updated successfully'
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
// Purpose of travel crud
|
||||
public function getPurposeOfTravelList()
|
||||
{
|
||||
$for = $this->request->getVar('for');
|
||||
|
||||
if (isset($for) && $for === 'table_view')
|
||||
{
|
||||
$data = $this->dropdownModel->where('dropdown','plan_purpose_of_travel')->findAll();
|
||||
} else {
|
||||
$data = $this->dropdownModel->where('dropdown','plan_purpose_of_travel')->where('is_active', 1)->findAll();
|
||||
}
|
||||
|
||||
if (!$data) {
|
||||
return $this->failNotFound('No data found');
|
||||
}
|
||||
|
||||
return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
|
||||
}
|
||||
|
||||
public function createPurposeOfTravel()
|
||||
{
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
$data['dropdown'] = 'plan_purpose_of_travel';
|
||||
$data['is_active'] = 1;
|
||||
$existData = $this->dropdownModel->where('dropdown','plan_purpose_of_travel')->findAll();
|
||||
$data['dropdown_key'] = count($existData) + 1;
|
||||
|
||||
if (!$this->dropdownModel->insert($data)) {
|
||||
return $this->failValidationErrors($this->dropdownModel->errors());
|
||||
}
|
||||
|
||||
return $this->respondCreated([
|
||||
'status' => 201,
|
||||
'message' => 'Department created successfully'
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function findPurposeOfTravel()
|
||||
{
|
||||
|
||||
$id = $this->request->getGet('id');
|
||||
|
||||
$data = $this->dropdownModel->where('id',$id)->find();
|
||||
|
||||
if (!$data) {
|
||||
return $this->failNotFound('No data found');
|
||||
}
|
||||
|
||||
return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
|
||||
}
|
||||
|
||||
public function updatePurposeOfTravel($id = null)
|
||||
{
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
if (!$this->dropdownModel->find($id)) {
|
||||
return $this->failNotFound('Department not found');
|
||||
}
|
||||
|
||||
if (!$this->dropdownModel->update($id, $data)) {
|
||||
return $this->failValidationErrors($this->dropdownModel->errors());
|
||||
}
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Department updated successfully'
|
||||
]);
|
||||
}
|
||||
|
||||
// Cost center crud
|
||||
public function getCostCenterMaster()
|
||||
{
|
||||
$for = $this->request->getVar('for');
|
||||
|
||||
if (isset($for) && $for === 'table_view')
|
||||
{
|
||||
$data = $this->costCenterModel->findAll();
|
||||
} else {
|
||||
$data = $this->costCenterModel->where('is_active', 1)->findAll();
|
||||
}
|
||||
|
||||
if (!$data) {
|
||||
return $this->failNotFound('No data found');
|
||||
}
|
||||
|
||||
return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
|
||||
}
|
||||
|
||||
public function createCostCenter()
|
||||
{
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
if (!$this->costCenterModel->insert($data)) {
|
||||
return $this->failValidationErrors($this->costCenterModel->errors());
|
||||
}
|
||||
|
||||
return $this->respondCreated([
|
||||
'status' => 201,
|
||||
'message' => 'Cost Center created successfully'
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function findCostCenter()
|
||||
{
|
||||
|
||||
$id = $this->request->getGet('cost_center_id');
|
||||
|
||||
$data = $this->costCenterModel->where('cost_center_id',$id)->find();
|
||||
|
||||
if (!$data) {
|
||||
return $this->failNotFound('No data found');
|
||||
}
|
||||
|
||||
return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
|
||||
}
|
||||
|
||||
public function updateCostCenter($id = null)
|
||||
{
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
if (!$this->costCenterModel->find($id)) {
|
||||
return $this->failNotFound('Cost Center not found');
|
||||
}
|
||||
|
||||
if (!$this->costCenterModel->update($id, $data)) {
|
||||
return $this->failValidationErrors($this->costCenterModel->errors());
|
||||
}
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Cost Center updated successfully'
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
// Forex crud
|
||||
public function getForexPerdiemList()
|
||||
{
|
||||
|
||||
$for = $this->request->getVar('for');
|
||||
|
||||
if (isset($for) && $for === 'table_view')
|
||||
{
|
||||
$data = $this->forexPerdiemModel->findAll();
|
||||
} else {
|
||||
$data = $this->forexPerdiemModel->where('is_active', 1)->findAll();
|
||||
}
|
||||
|
||||
if (!$data) {
|
||||
return $this->failNotFound('No data found');
|
||||
}
|
||||
|
||||
return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
|
||||
}
|
||||
|
||||
public function createForexPerdiem()
|
||||
{
|
||||
|
||||
|
||||
try {
|
||||
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
if (!$this->forexPerdiemModel->insert($data)) {
|
||||
return $this->failValidationErrors($this->forexPerdiemModel->errors());
|
||||
}
|
||||
|
||||
return $this->respondCreated([
|
||||
'status' => 201,
|
||||
'message' => 'Forex Perdiem created successfully'
|
||||
]);
|
||||
} catch (\CodeIgniter\Database\Exceptions\DatabaseException $e) {
|
||||
|
||||
if (strpos($e->getMessage(), 'Duplicate entry') !== false) {
|
||||
return $this->respond([
|
||||
'status' => 404,
|
||||
'message' => 'Duplicate entry'
|
||||
],404);
|
||||
}
|
||||
|
||||
// For other DB-related exceptions
|
||||
return $this->failServerError($e->getMessage());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function findForexPerdiem()
|
||||
{
|
||||
|
||||
$id = $this->request->getGet('forex_perdiem_id');
|
||||
|
||||
$data = $this->forexPerdiemModel->where('forex_perdiem_id',$id)->find();
|
||||
|
||||
if (!$data) {
|
||||
return $this->failNotFound('No data found');
|
||||
}
|
||||
|
||||
return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
|
||||
}
|
||||
|
||||
public function updateForexPerdiem($id = null)
|
||||
{
|
||||
try{
|
||||
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
if (!$this->forexPerdiemModel->find($id)) {
|
||||
return $this->failNotFound('Forex Perdiem not found');
|
||||
}
|
||||
|
||||
|
||||
if (!$this->forexPerdiemModel->update($id, $data)) {
|
||||
return $this->failValidationErrors($this->forexPerdiemModel->errors());
|
||||
}
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Forex Perdiem updated successfully'
|
||||
]);
|
||||
|
||||
} catch (\CodeIgniter\Database\Exceptions\DatabaseException $e) {
|
||||
|
||||
if (strpos($e->getMessage(), 'Duplicate entry') !== false) {
|
||||
return $this->respond([
|
||||
'status' => 404,
|
||||
'message' => 'Duplicate entry'
|
||||
]);
|
||||
}
|
||||
|
||||
// For other DB-related exceptions
|
||||
return $this->failServerError($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Hotels crud
|
||||
public function getHotels()
|
||||
{
|
||||
|
||||
$for = $this->request->getVar('for');
|
||||
|
||||
if (isset($for) && $for === 'table_view')
|
||||
{
|
||||
$hotels = $this->hotelModel->select('m_hotels.* , C.country_name')
|
||||
->join('m_country C', 'C.country_code = m_hotels.country_code', 'left')
|
||||
->findAll();
|
||||
} else {
|
||||
$hotels = $this->hotelModel->select('m_hotels.* , C.country_name')
|
||||
->join('m_country C', 'C.country_code = m_hotels.country_code', 'left')
|
||||
->where('m_hotels.is_active', 1)
|
||||
->findAll();
|
||||
}
|
||||
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => 200,
|
||||
'message' => 'Hotel list fetched successfully',
|
||||
'data' => $hotels
|
||||
]);
|
||||
}
|
||||
|
||||
public function createHotels()
|
||||
{
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
if (!$this->hotelModel->insert($data)) {
|
||||
return $this->failValidationErrors($this->hotelModel->errors());
|
||||
}
|
||||
|
||||
return $this->respondCreated([
|
||||
'status' => 201,
|
||||
'message' => 'Hotels created successfully'
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function findHotels()
|
||||
{
|
||||
|
||||
$id = $this->request->getGet('hotel_id');
|
||||
|
||||
$data = $this->hotelModel->where('hotel_id',$id)->find();
|
||||
|
||||
if (!$data) {
|
||||
return $this->failNotFound('No data found');
|
||||
}
|
||||
|
||||
return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
|
||||
}
|
||||
|
||||
public function updateHotels($id = null)
|
||||
{
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
if (!$this->hotelModel->find($id)) {
|
||||
return $this->failNotFound('Hotels not found');
|
||||
}
|
||||
|
||||
if (!$this->hotelModel->update($id, $data)) {
|
||||
return $this->failValidationErrors($this->hotelModel->errors());
|
||||
}
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Hotels updated successfully'
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
511
app/Controllers/OrganizationController.php
Normal file
511
app/Controllers/OrganizationController.php
Normal file
@ -0,0 +1,511 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use CodeIgniter\RESTful\ResourceController;
|
||||
use App\Models\OrganizationModel;
|
||||
use App\Models\UserModel;
|
||||
use App\Models\GroupModel;
|
||||
use App\Models\PolicyModel;
|
||||
use App\Models\PolicyDetailsModel;
|
||||
use App\Models\ServiceModel;
|
||||
|
||||
class OrganizationController extends ResourceController
|
||||
{
|
||||
protected $format = 'json';
|
||||
protected $myLogger;
|
||||
protected $organizationModel;
|
||||
protected $userModel;
|
||||
protected $groupModel;
|
||||
protected $policyModel;
|
||||
protected $policyDetailsModel;
|
||||
protected $serviceModel;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->myLogger = \Config\Services::mylogger();
|
||||
$this->organizationModel = new OrganizationModel();
|
||||
$this->userModel = new UserModel();
|
||||
$this->groupModel = new GroupModel();
|
||||
$this->policyModel = new PolicyModel();
|
||||
$this->policyDetailsModel = new PolicyDetailsModel();
|
||||
$this->serviceModel = new ServiceModel();
|
||||
}
|
||||
|
||||
|
||||
public function index()
|
||||
{
|
||||
|
||||
$organization = $this->organizationModel->findAll();
|
||||
|
||||
if (!$organization) {
|
||||
return $this->failNotFound('No organizations found');
|
||||
}
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'organization retrieved successfully',
|
||||
'data' => $organization
|
||||
]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
|
||||
$data = $this->request->getPost();
|
||||
|
||||
// Handle file upload
|
||||
$file = $this->request->getFile('logo');
|
||||
if ($file && $file->isValid() && !$file->hasMoved()) {
|
||||
$newName = $file->getRandomName(); // Generate a unique name
|
||||
$uploadPath = FCPATH.'assets/images/logo';
|
||||
|
||||
// Move file to the specified directory
|
||||
$file->move($uploadPath, $newName);
|
||||
|
||||
// Save file path in database
|
||||
$data['logo'] = $uploadPath . '/' . $newName;
|
||||
} else {
|
||||
// return $this->failValidationErrors(['passport_document' => 'Invalid file upload']);
|
||||
}
|
||||
|
||||
try {
|
||||
$data['services_ids'] = json_encode($data['services_ids']);
|
||||
$this->organizationModel->insert($data);
|
||||
|
||||
$organizationId = $this->organizationModel->insertID(); // Get the last inserted ID
|
||||
|
||||
// Create Admin User for the Organization
|
||||
$adminData = [
|
||||
'first_name' => 'Admin',
|
||||
'email' => $data['sender_email'],
|
||||
'password' => password_hash('password', PASSWORD_DEFAULT), // Default password
|
||||
'role_id' => 2,
|
||||
'org_id' => $organizationId
|
||||
];
|
||||
|
||||
$this->userModel->insert($adminData);
|
||||
|
||||
return $this->respondCreated([
|
||||
'status' => 201,
|
||||
'message' => 'organization created successfully',
|
||||
'data' => $data
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->failServerError('Failed to create organization: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function find($id = null)
|
||||
{
|
||||
if (!$id) {
|
||||
return $this->failNotFound('organization id is required');
|
||||
}
|
||||
|
||||
// Fetch organization by ID
|
||||
$organization = $this->organizationModel->find($id);
|
||||
|
||||
if (!$organization) {
|
||||
return $this->failNotFound('organization not found');
|
||||
}
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'organization retrieved successfully',
|
||||
'data' => $organization
|
||||
]);
|
||||
}
|
||||
|
||||
public function update($id = null)
|
||||
{
|
||||
if (!$id){
|
||||
return $this->failNotFound('organization ID is required');
|
||||
}
|
||||
|
||||
$data = $this->request->getPost();
|
||||
|
||||
if (empty($data)) {
|
||||
return $this->failValidationErrors('No data provided for update');
|
||||
}
|
||||
|
||||
// Check if organization exists
|
||||
$organization = $this->organizationModel->find($id);
|
||||
if (!$organization) {
|
||||
return $this->failNotFound('organization not found');
|
||||
}
|
||||
|
||||
// Handle file upload
|
||||
$file = $this->request->getFile('logo');
|
||||
if ($file && $file->isValid() && !$file->hasMoved()) {
|
||||
$newName = $file->getRandomName(); // Generate a unique file name
|
||||
$uploadPath = FCPATH.'assets/images/logo';
|
||||
|
||||
// Move file to the directory
|
||||
$file->move($uploadPath, $newName);
|
||||
|
||||
// Delete the old file if it exists
|
||||
if (!empty($organization['logo']) && file_exists($organization['logo'])) {
|
||||
unlink($organization['logo']); // Remove old file
|
||||
}
|
||||
|
||||
// Save the new file path
|
||||
$data['logo'] = $uploadPath . '/' . $newName;
|
||||
}
|
||||
|
||||
// Update organization details
|
||||
try {
|
||||
$this->organizationModel->update($id, $data);
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'organization updated successfully',
|
||||
'data' => $data
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->failServerError('Failed to update organization: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function updateOrganizationStatus($id)
|
||||
{
|
||||
// Fetch organization by ID
|
||||
$organization = $this->organizationModel->find($id);
|
||||
|
||||
if (!$organization) {
|
||||
return $this->failNotFound('organization not found');
|
||||
}
|
||||
|
||||
// Toggle the is_active status
|
||||
$newStatus = $organization['is_active'] == 1 ? 0 : 1;
|
||||
|
||||
// Update organization status
|
||||
$this->organizationModel->update($id, ['is_active' => $newStatus]);
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => $newStatus ? 'organization activated successfully' : 'organization deactivated successfully',
|
||||
'is_active' => $newStatus
|
||||
]);
|
||||
}
|
||||
|
||||
public function testMail()
|
||||
{
|
||||
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
$to_mail = $data['to_mail'];
|
||||
|
||||
$mail_config = [
|
||||
'SMTPHost' => $data['mail_host'],
|
||||
'SMTPUser' => $data['mail_user_name'],
|
||||
'SMTPPass' => $data['mail_password'],
|
||||
'SMTPPort' => $data['mail_port'],
|
||||
'sender_email' => $data['sender_email']
|
||||
];
|
||||
|
||||
|
||||
return check_mail_config($to_mail, $mail_config);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------Service---------------------------------------------------
|
||||
|
||||
|
||||
public function getServices()
|
||||
{
|
||||
$service = $this->serviceModel->findAll();
|
||||
|
||||
if (!$service) {
|
||||
return $this->failNotFound('No service found');
|
||||
}
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'service retrieved successfully',
|
||||
'data' => $service
|
||||
]);
|
||||
}
|
||||
|
||||
//------------------------------------------------Group-------------------------------------------------------
|
||||
|
||||
|
||||
public function getGroups()
|
||||
{
|
||||
|
||||
$org_id = $this->request->getVar('org_id');
|
||||
|
||||
$for = $this->request->getVar('for');
|
||||
|
||||
if (isset($for) && $for === 'table_view')
|
||||
{
|
||||
$group = $this->groupModel->select('m_group.*, CONCAT_WS(U.first_name," ",U.last_name) as created_by,DP.name as domestic_policy_name , IP.name as international_policy_name')
|
||||
->join('m_users U', 'U.user_id = m_group.created_by ', 'left')
|
||||
->join('m_policy DP', 'DP.policy_id = m_group.domestic_policy_id ', 'left')
|
||||
->join('m_policy IP', 'IP.policy_id = m_group.international_policy_id ', 'left')
|
||||
->where('m_group.org_id',$org_id)
|
||||
->findAll();
|
||||
} else {
|
||||
$group = $this->groupModel->select('m_group.*, CONCAT_WS(U.first_name," ",U.last_name) as created_by,DP.name as domestic_policy_name , IP.name as international_policy_name')
|
||||
->join('m_users U', 'U.user_id = m_group.created_by ', 'left')
|
||||
->join('m_policy DP', 'DP.policy_id = m_group.domestic_policy_id ', 'left')
|
||||
->join('m_policy IP', 'IP.policy_id = m_group.international_policy_id ', 'left')
|
||||
->where('m_group.org_id',$org_id)
|
||||
->where('m_group.is_active',1)
|
||||
->findAll();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (!$group) {
|
||||
return $this->failNotFound('No group found');
|
||||
}
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'group retrieved successfully',
|
||||
'data' => $group
|
||||
]);
|
||||
}
|
||||
|
||||
public function createGroup()
|
||||
{
|
||||
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
try {
|
||||
$insertedId = $this->groupModel->insert($data);
|
||||
|
||||
if (!$insertedId) {
|
||||
return $this->fail('Data not inserted');
|
||||
}
|
||||
|
||||
return $this->respondCreated([
|
||||
'status' => 201,
|
||||
'message' => 'Group created successfully',
|
||||
'data' => $data
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->failServerError('Failed to create Group: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function findGroup($id = null)
|
||||
{
|
||||
if (!$id) {
|
||||
return $this->failNotFound('group id is required');
|
||||
}
|
||||
|
||||
// Fetch group by ID
|
||||
$group = $this->groupModel->find($id);
|
||||
|
||||
if (!$group) {
|
||||
return $this->failNotFound('group not found');
|
||||
}
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'group retrieved successfully',
|
||||
'data' => $group
|
||||
]);
|
||||
}
|
||||
|
||||
public function updateGroup($id)
|
||||
{
|
||||
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
// Check if group exists
|
||||
$group = $this->groupModel->find($id);
|
||||
if (!$group) {
|
||||
return $this->failNotFound('group not found');
|
||||
}
|
||||
|
||||
|
||||
// Update group details
|
||||
try {
|
||||
$this->groupModel->update($id, $data);
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'group updated successfully',
|
||||
'data' => $data
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->failServerError('Failed to update group: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function updateGroupStatus($id)
|
||||
{
|
||||
// Fetch group by ID
|
||||
$group = $this->groupModel->find($id);
|
||||
|
||||
if (!$group) {
|
||||
return $this->failNotFound('group not found');
|
||||
}
|
||||
|
||||
// Toggle the is_active status
|
||||
$newStatus = $group['is_active'] == 1 ? 0 : 1;
|
||||
|
||||
// Update group status
|
||||
$this->groupModel->update($id, ['is_active' => $newStatus]);
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => $newStatus ? 'group activated successfully' : 'group deactivated successfully',
|
||||
'is_active' => $newStatus
|
||||
]);
|
||||
}
|
||||
|
||||
//---------------------------------------------------Policy---------------------------------------------------
|
||||
|
||||
|
||||
public function getPolicy()
|
||||
{
|
||||
|
||||
$org_id = $this->request->getVar('org_id');
|
||||
|
||||
$for = $this->request->getVar('for');
|
||||
|
||||
if (isset($for) && $for === 'table_view')
|
||||
{
|
||||
$policy = $this->policyModel->select('m_policy.*, CONCAT_WS(U.first_name," ",U.last_name) as created_by')
|
||||
->join('m_users U', 'U.user_id = m_policy.created_by ', 'left')
|
||||
->where('m_policy.org_id',$org_id)
|
||||
->findAll();
|
||||
} else {
|
||||
$policy = $this->policyModel->select('m_policy.*, CONCAT_WS(U.first_name," ",U.last_name) as created_by')
|
||||
->join('m_users U', 'U.user_id = m_policy.created_by ', 'left')
|
||||
->where('m_policy.org_id',$org_id)
|
||||
->where('m_policy.is_active',1)
|
||||
->findAll();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!$policy) {
|
||||
return $this->failNotFound('No policy found');
|
||||
}
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'policy retrieved successfully',
|
||||
'data' => $policy
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function createOrUpdatePolicy()
|
||||
{
|
||||
|
||||
try {
|
||||
|
||||
$json = $this->request->getJSON(true);
|
||||
|
||||
// var_dump($json);die;
|
||||
// Check if policy_id exists
|
||||
if (!empty($json['policy_id'])) {
|
||||
$policy = $this->policyModel->find($json['policy_id']);
|
||||
}
|
||||
|
||||
$json['services_ids'] = json_encode($json['services_ids']);
|
||||
|
||||
if (isset($policy)) {
|
||||
// Update existing plan
|
||||
$this->policyModel->update($json['policy_id'], $json);
|
||||
$policyId = $json['policy_id'];
|
||||
} else {
|
||||
// Insert new plan
|
||||
$policyId = $this->policyModel->insert($json, true);
|
||||
}
|
||||
|
||||
|
||||
// Process related table
|
||||
if (!empty($json['policy_details'])) {
|
||||
$this->savePolicyDetails($json['policy_details'], $policyId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Policy Date Affected successfully',
|
||||
'policy_id' => $policyId
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return $this->failServerError('Failed to create : ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function savePolicyDetails($policyDetails, $policyId)
|
||||
{
|
||||
|
||||
foreach ($policyDetails as $data) {
|
||||
$data['policy_id'] = $policyId;
|
||||
if (!empty($data['policy_details_id'])) {
|
||||
$this->policyDetailsModel->update($data['policy_details_id'], $data);
|
||||
} else {
|
||||
$this->policyDetailsModel->insert($data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function findPolicy($id = null)
|
||||
{
|
||||
if (!$id) {
|
||||
return $this->failNotFound('Policy id is required');
|
||||
}
|
||||
|
||||
// Fetch policy by ID
|
||||
$policy = $this->policyModel->find($id);
|
||||
|
||||
if (!$policy) {
|
||||
return $this->failNotFound('policy not found');
|
||||
}
|
||||
|
||||
$policy['policy_details'] = $this->policyDetailsModel->where('policy_id',$id)->findAll();
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'policy retrieved successfully',
|
||||
'data' => $policy
|
||||
]);
|
||||
}
|
||||
|
||||
public function updatePolicyStatus($id)
|
||||
{
|
||||
// Fetch policy by ID
|
||||
$policy = $this->policyModel->find($id);
|
||||
|
||||
if (!$policy) {
|
||||
return $this->failNotFound('policy not found');
|
||||
}
|
||||
|
||||
// Toggle the is_active status
|
||||
$newStatus = $policy['is_active'] == 1 ? 0 : 1;
|
||||
|
||||
// Update policy status
|
||||
$this->policyModel->update($id, ['is_active' => $newStatus]);
|
||||
$this->policyDetailsModel->set(['is_active' => $newStatus])->where('policy_id',$id)->update();
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => $newStatus ? 'policy activated successfully' : 'policy deactivated successfully',
|
||||
'is_active' => $newStatus
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
1408
app/Controllers/PlanController.php
Normal file
1408
app/Controllers/PlanController.php
Normal file
File diff suppressed because it is too large
Load Diff
418
app/Controllers/ReportsController.php
Normal file
418
app/Controllers/ReportsController.php
Normal file
@ -0,0 +1,418 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Controllers\BaseController;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
|
||||
use App\Models\ReportsModel;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||
|
||||
class ReportsController extends BaseController
|
||||
{
|
||||
protected $reportsModel;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// Load any necessary models or libraries here
|
||||
$this->reportsModel = new ReportsModel();
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function advancePurchaseReport()
|
||||
{
|
||||
try {
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
$fromDate = $data['fromDate'] ?? '';
|
||||
$toDate = $data['toDate'] ?? '';
|
||||
|
||||
$result = $this->reportsModel->advancePurchaseReport($fromDate, $toDate);
|
||||
|
||||
if (empty($result)) {
|
||||
return $this->response->setJSON([
|
||||
'status' => 'error',
|
||||
'message' => 'No data found for the given criteria.'
|
||||
])->setStatusCode(ResponseInterface::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Separate domestic
|
||||
$domestic = array_values(array_filter($result, fn($row) => $row['plan_trip_type'] === 'domestic'));
|
||||
|
||||
// Separate international
|
||||
$international = array_values(array_filter($result, fn($row) => $row['plan_trip_type'] === 'international'));
|
||||
|
||||
if(isset($data['export']))
|
||||
{
|
||||
if($data['export'] == 'domestic'){ $exportData = $domestic; }else{ $exportData = $international; }
|
||||
|
||||
if(count($exportData) == 0){ return $this->response->setJSON(['status' => 'failed','message' => 'No Data','data' => [ ]]); }
|
||||
|
||||
return $this->downloadExcel($exportData);
|
||||
}
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => 'success',
|
||||
'message' => 'Data found for the given criteria.',
|
||||
'data' => [
|
||||
'domestic' => $domestic,
|
||||
'international' => $international
|
||||
]
|
||||
])->setStatusCode(ResponseInterface::HTTP_OK);
|
||||
|
||||
} catch (\Throwable $th) {
|
||||
log_message('error', 'advancePurchaseReport Exception: ' . $th->getMessage());
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => 'error',
|
||||
'message' => 'Something went wrong while processing the request.'
|
||||
])->setStatusCode(ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);
|
||||
|
||||
} finally {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function misServicesAnalysis()
|
||||
{
|
||||
try {
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
$fromDate = $data['fromDate'] ?? '';
|
||||
$toDate = $data['toDate'] ?? '';
|
||||
|
||||
$result = $this->reportsModel->misServicesAnalysis( $fromDate, $toDate);
|
||||
|
||||
|
||||
if (empty($result)) {
|
||||
return $this->response->setJSON([
|
||||
'status' => 'error',
|
||||
'message' => 'No data found for the given criteria.'
|
||||
])->setStatusCode(ResponseInterface::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Flatten the array
|
||||
$flat_result = [];
|
||||
|
||||
foreach ($result as $group) {
|
||||
foreach ($group as $row) {
|
||||
$flat_result[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
// Separate domestic
|
||||
$domestic = array_values(array_filter($flat_result, fn($row) => $row['plan_trip_type'] === 'domestic'));
|
||||
|
||||
// Separate international
|
||||
$international = array_values(array_filter($flat_result, fn($row) => $row['plan_trip_type'] === 'international'));
|
||||
|
||||
|
||||
|
||||
if(isset($data['export']))
|
||||
{
|
||||
if($data['export'] == 'domestic'){ $exportData = $domestic; }else{ $exportData = $international; }
|
||||
|
||||
if(count($exportData) == 0){ return $this->response->setJSON(['status' => 'failed','message' => 'No Data','data' => [ ]]); }
|
||||
|
||||
return $this->downloadExcel($exportData);
|
||||
}
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => 'success',
|
||||
'message' => 'Data found for the given criteria.',
|
||||
'data' => [
|
||||
'domestic' => $domestic,
|
||||
'international' => $international
|
||||
]
|
||||
])->setStatusCode(ResponseInterface::HTTP_OK);
|
||||
|
||||
|
||||
} catch (\Throwable $th) {
|
||||
log_message('error', 'misServicesAnalysis Exception: ' . $th->getMessage());
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => 'error',
|
||||
'message' => 'Something went wrong while processing the request.'
|
||||
])->setStatusCode(ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);
|
||||
|
||||
} finally {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function misAirReport()
|
||||
{
|
||||
|
||||
try {
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
$fromDate = $data['fromDate'] ?? '';
|
||||
$toDate = $data['toDate'] ?? '';
|
||||
|
||||
$result = $this->reportsModel->misAirReport($fromDate, $toDate);
|
||||
|
||||
if (empty($result)) {
|
||||
return $this->response->setJSON([
|
||||
'status' => 'error',
|
||||
'message' => 'No data found for the given criteria.'
|
||||
])->setStatusCode(ResponseInterface::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Separate domestic
|
||||
$domestic = array_values(array_filter($result, fn($row) => $row['plan_trip_type'] === 'domestic'));
|
||||
|
||||
// Separate international
|
||||
$international = array_values(array_filter($result, fn($row) => $row['plan_trip_type'] === 'international'));
|
||||
|
||||
if(isset($data['export']))
|
||||
{
|
||||
if($data['export'] == 'domestic'){ $exportData = $domestic; }else{ $exportData = $international; }
|
||||
|
||||
if(count($exportData) == 0){ return $this->response->setJSON(['status' => 'failed','message' => 'No Data','data' => [ ]]); }
|
||||
|
||||
return $this->downloadExcel($exportData);
|
||||
}
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => 'success',
|
||||
'message' => 'Data found for the given criteria.',
|
||||
'data' => [
|
||||
'domestic' => $domestic,
|
||||
'international' => $international
|
||||
]
|
||||
])->setStatusCode(ResponseInterface::HTTP_OK);
|
||||
|
||||
} catch (\Throwable $th) {
|
||||
log_message('error', 'misAirReport Exception: ' . $th->getMessage());
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => 'error',
|
||||
'message' => 'Something went wrong while processing the request.'
|
||||
])->setStatusCode(ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);
|
||||
|
||||
} finally {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function misHotelReport()
|
||||
{
|
||||
|
||||
try {
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
$fromDate = $data['fromDate'] ?? '';
|
||||
$toDate = $data['toDate'] ?? '';
|
||||
|
||||
$result = $this->reportsModel->misHotelReport($fromDate, $toDate);
|
||||
|
||||
if (empty($result)) {
|
||||
return $this->response->setJSON([
|
||||
'status' => 'error',
|
||||
'message' => 'No data found for the given criteria.'
|
||||
])->setStatusCode(ResponseInterface::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Separate domestic
|
||||
$domestic = array_values(array_filter($result, fn($row) => $row['plan_trip_type'] === 'domestic'));
|
||||
|
||||
// Separate international
|
||||
$international = array_values(array_filter($result, fn($row) => $row['plan_trip_type'] === 'international'));
|
||||
|
||||
|
||||
if(isset($data['export']))
|
||||
{
|
||||
if($data['export'] == 'domestic'){ $exportData = $domestic; }else{ $exportData = $international; }
|
||||
|
||||
if(count($exportData) == 0){ return $this->response->setJSON(['status' => 'failed','message' => 'No Data','data' => [ ]]); }
|
||||
|
||||
return $this->downloadExcel($exportData);
|
||||
}
|
||||
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => 'success',
|
||||
'message' => 'Data found for the given criteria.',
|
||||
'data' => [
|
||||
'domestic' => $domestic,
|
||||
'international' => $international
|
||||
]
|
||||
])->setStatusCode(ResponseInterface::HTTP_OK);
|
||||
|
||||
} catch (\Throwable $th) {
|
||||
log_message('error', 'misAirReport Exception: ' . $th->getMessage());
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => 'error',
|
||||
'message' => 'Something went wrong while processing the request.'
|
||||
])->setStatusCode(ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);
|
||||
|
||||
} finally {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function misForexReport()
|
||||
{
|
||||
|
||||
try {
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
$fromDate = $data['fromDate'] ?? '';
|
||||
$toDate = $data['toDate'] ?? '';
|
||||
|
||||
$result = $this->reportsModel->misForexReport($fromDate, $toDate);
|
||||
|
||||
if (empty($result)) {
|
||||
return $this->response->setJSON([
|
||||
'status' => 'error',
|
||||
'message' => 'No data found for the given criteria.'
|
||||
])->setStatusCode(ResponseInterface::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
if(isset($data['export']))
|
||||
{
|
||||
if(count($result) == 0){ return $this->response->setJSON(['status' => 'failed','message' => 'No Data','data' => [ ]]); }
|
||||
|
||||
return $this->downloadExcel($result);
|
||||
}
|
||||
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => 'success',
|
||||
'message' => 'Data found for the given criteria.',
|
||||
'data' => $result
|
||||
])->setStatusCode(ResponseInterface::HTTP_OK);
|
||||
|
||||
} catch (\Throwable $th) {
|
||||
log_message('error', 'misAirReport Exception: ' . $th->getMessage());
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => 'error',
|
||||
'message' => 'Something went wrong while processing the request.'
|
||||
])->setStatusCode(ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);
|
||||
|
||||
} finally {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function guestHouseReport()
|
||||
{
|
||||
|
||||
try {
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
$fromDate = $data['fromDate'] ?? '';
|
||||
$toDate = $data['toDate'] ?? '';
|
||||
|
||||
$result = $this->reportsModel->guestHouseReport($fromDate, $toDate);
|
||||
|
||||
if (empty($result)) {
|
||||
return $this->response->setJSON([
|
||||
'status' => 'error',
|
||||
'message' => 'No data found for the given criteria.'
|
||||
])->setStatusCode(ResponseInterface::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Separate domestic
|
||||
$domestic = array_values(array_filter($result, fn($row) => $row['plan_trip_type'] === 'domestic'));
|
||||
|
||||
// Separate international
|
||||
$international = array_values(array_filter($result, fn($row) => $row['plan_trip_type'] === 'international'));
|
||||
|
||||
if(isset($data['export']))
|
||||
{
|
||||
if($data['export'] == 'domestic'){ $exportData = $domestic; }else{ $exportData = $international; }
|
||||
|
||||
if(count($exportData) == 0){ return $this->response->setJSON(['status' => 'failed','message' => 'No Data','data' => [ ]]); }
|
||||
|
||||
return $this->downloadExcel($exportData);
|
||||
}
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => 'success',
|
||||
'message' => 'Data found for the given criteria.',
|
||||
'data' => [
|
||||
'domestic' => $domestic,
|
||||
'international' => $international
|
||||
]
|
||||
])->setStatusCode(ResponseInterface::HTTP_OK);
|
||||
|
||||
} catch (\Throwable $th) {
|
||||
log_message('error', 'misAirReport Exception: ' . $th->getMessage());
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => 'error',
|
||||
'message' => 'Something went wrong while processing the request.'
|
||||
])->setStatusCode(ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);
|
||||
|
||||
} finally {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//excel download
|
||||
public function downloadExcel($data)
|
||||
{
|
||||
|
||||
if (empty($data) || !is_array($data)) {
|
||||
return 'No valid data provided.';
|
||||
}
|
||||
|
||||
// Create Spreadsheet
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
|
||||
// Generate headers from the first row
|
||||
$headers = array_keys($data[0]);
|
||||
$col = 'A';
|
||||
|
||||
foreach ($headers as $header) {
|
||||
$sheet->setCellValue($col . '1', $header);
|
||||
$col++;
|
||||
}
|
||||
|
||||
// Fill data
|
||||
$rowNum = 2;
|
||||
foreach ($data as $row) {
|
||||
$col = 'A';
|
||||
foreach ($headers as $header) {
|
||||
$sheet->setCellValue($col . $rowNum, $row[$header]);
|
||||
$col++;
|
||||
}
|
||||
$rowNum++;
|
||||
}
|
||||
|
||||
// Write to output
|
||||
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
|
||||
|
||||
// Set headers for download
|
||||
$filename = 'dynamic_excel_' . date('YmdHis') . '.xlsx';
|
||||
|
||||
return $this->response
|
||||
->setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
|
||||
->setHeader('Content-Disposition', "attachment;filename=\"$filename\"")
|
||||
->setHeader('Cache-Control', 'max-age=0')
|
||||
->setBody($this->writeToTempFile($writer));
|
||||
}
|
||||
|
||||
private function writeToTempFile($writer): string
|
||||
{
|
||||
$temp_file = tempnam(sys_get_temp_dir(), 'excel_') . '.xlsx';
|
||||
$writer->save($temp_file);
|
||||
return file_get_contents($temp_file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
170
app/Controllers/SamlController.php
Executable file
170
app/Controllers/SamlController.php
Executable file
@ -0,0 +1,170 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
use CodeIgniter\RESTful\ResourceController;
|
||||
use CodeIgniter\Controller;
|
||||
use OneLogin\Saml2\Auth;
|
||||
use Config\SamlSettings;
|
||||
use SimpleXMLElement;
|
||||
|
||||
class SamlController extends ResourceController
|
||||
{
|
||||
protected $format = 'json';
|
||||
private $auth;
|
||||
private $settings;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
helper('common_helper');
|
||||
helper('jwt_helper');
|
||||
$settings = new SamlSettings();
|
||||
|
||||
$config = [
|
||||
'sp' => [
|
||||
'entityId' => $settings->spEntityId,
|
||||
'assertionConsumerService' => [
|
||||
'url' => $settings->spAssertionConsumerServiceUrl,
|
||||
],
|
||||
'singleLogoutService' => [
|
||||
'url' => $settings->spSingleLogoutServiceUrl,
|
||||
],
|
||||
'x509cert' => $settings->spCert,
|
||||
'privateKey' => $settings->spPrivateKey,
|
||||
],
|
||||
'idp' => [
|
||||
'entityId' => $settings->idpEntityId,
|
||||
'singleSignOnService' => [
|
||||
'url' => $settings->idpSSOUrl,
|
||||
],
|
||||
'singleLogoutService' => [
|
||||
'url' => $settings->idpSLOUrl,
|
||||
],
|
||||
'x509cert' => $settings->idpX509Cert,
|
||||
],
|
||||
'security' => [
|
||||
'authnRequestsSigned' => true,
|
||||
'logoutRequestSigned' => true,
|
||||
'wantAssertionsSigned' => true,
|
||||
'signMetadata' => true, // Ensure metadata is signed
|
||||
],
|
||||
];
|
||||
|
||||
$this->auth = new Auth($config);
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
return view('landingpage');
|
||||
}
|
||||
|
||||
|
||||
// Initiate the SSO (Single Sign-On) process
|
||||
public function login()
|
||||
{
|
||||
$this->auth->login();
|
||||
}
|
||||
|
||||
// Handle the Assertion Consumer Service (ACS) endpoint
|
||||
public function acs()
|
||||
{
|
||||
try {
|
||||
$this->auth->processResponse();
|
||||
|
||||
if ($this->auth->isAuthenticated()) {
|
||||
|
||||
|
||||
$samlUserdata = $this->auth->getAttributes();
|
||||
$userProfile['samlNameId'] = $this->auth->getNameId();
|
||||
$userProfile['samlNameIdFormat'] = $this->auth->getNameIdFormat();
|
||||
$userProfile['samlNameidNameQualifier'] = $this->auth->getNameIdNameQualifier();
|
||||
$userProfile['samlNameidSPNameQualifier'] = $this->auth->getNameIdSPNameQualifier();
|
||||
$userProfile['samlSessionIndex'] = $this->auth->getSessionIndex();
|
||||
$userProfile['displayName'] = $samlUserdata['http://schemas.microsoft.com/identity/claims/displayname'][0] ?? 'Unknown';
|
||||
|
||||
$res = checkUserExist($userProfile['displayName'], $userProfile['samlNameId']);
|
||||
|
||||
if($res['status'] == true)
|
||||
{
|
||||
$token = generateJWT($res['data']);
|
||||
|
||||
return $this->respond([ 'status' => 200,'message' => 'Login successful','token' => $token ]);
|
||||
|
||||
}else{
|
||||
return $this->respond([ 'status' => 401,'message' => 'Login Failed','data' => [] ]);
|
||||
}
|
||||
|
||||
} else {
|
||||
return $this->respond([ 'status' => 401,'message' => 'Unauthorized','data' => [] ]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
|
||||
return $this->respond([ 'status' => 500,'message' => $e,'data' => [] ]);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the Single Logout (SLO) process
|
||||
public function slo()
|
||||
{
|
||||
// $this->auth->logout();
|
||||
//Check if the user is authenticated using SAML
|
||||
if ($this->auth->isAuthenticated()) {
|
||||
// Log out from the SAML session
|
||||
$this->auth->logout();
|
||||
return $this->respond([ 'status' => 200,'message' => 'Successfully log out','data' => [] ]);
|
||||
} else {
|
||||
// If user is not authenticated, redirect to login
|
||||
return redirect()->to('/login');
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the logout response
|
||||
public function sls()
|
||||
{
|
||||
try {
|
||||
$this->auth->processSLO();
|
||||
return redirect()->to('/login');
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->to('/login');
|
||||
}
|
||||
}
|
||||
|
||||
public function metadata()
|
||||
{
|
||||
try {
|
||||
// Set the content type to XML
|
||||
header('Content-Type: application/xml');
|
||||
|
||||
// Get the settings from the OneLogin SAML Auth instance
|
||||
$settings = $this->auth->getSettings();
|
||||
|
||||
// Generate SP metadata XML
|
||||
$metadata = $settings->getSPMetadata();
|
||||
|
||||
// Check if there are any errors in the metadata generation
|
||||
$errors = $settings->validateMetadata($metadata);
|
||||
if (!empty($errors)) {
|
||||
// Handle validation errors
|
||||
throw new \Exception('Invalid SP metadata: ' . implode(', ', $errors));
|
||||
}
|
||||
|
||||
// Output the metadata XML directly
|
||||
echo $metadata;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
// Handle exceptions and display an appropriate error message
|
||||
echo "Error generating metadata: " . htmlspecialchars($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check if the user is authenticated
|
||||
public function check()
|
||||
{
|
||||
if ($this->auth->isAuthenticated()) {
|
||||
return json_encode($this->auth->getAttributes());
|
||||
} else {
|
||||
return json_encode(['status' => 'Not authenticated']);
|
||||
}
|
||||
}
|
||||
}
|
||||
23
app/Controllers/SwaggerController.php
Normal file
23
app/Controllers/SwaggerController.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use OpenApi\Annotations as OA;
|
||||
use OpenApi\Generator;
|
||||
|
||||
class SwaggerController extends BaseController
|
||||
{
|
||||
public function view()
|
||||
{
|
||||
// echo 'Hai'; die;
|
||||
return view('swagger/index');
|
||||
}
|
||||
|
||||
public function generate()
|
||||
{
|
||||
header('Content-Type: application/json');
|
||||
$openapi = Generator::scan([APPPATH . 'Controllers', APPPATH . 'Models']);
|
||||
dd($openapi);
|
||||
echo $openapi->toJson();
|
||||
}
|
||||
}
|
||||
147
app/Controllers/TravellerController.php
Normal file
147
app/Controllers/TravellerController.php
Normal file
@ -0,0 +1,147 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use CodeIgniter\RESTful\ResourceController;
|
||||
use App\Models\TravellerModel;
|
||||
|
||||
class TravellerController extends ResourceController
|
||||
{
|
||||
protected $format = 'json';
|
||||
protected $myLogger;
|
||||
protected $travellerModel;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->myLogger = \Config\Services::mylogger();
|
||||
$this->travellerModel = new TravellerModel();
|
||||
}
|
||||
|
||||
// Get all travellers
|
||||
public function index()
|
||||
{
|
||||
$orgId = $this->request->getGet('org_id');
|
||||
|
||||
$for = $this->request->getVar('for');
|
||||
|
||||
if (isset($for) && $for === 'table_view')
|
||||
{
|
||||
$users = $this->travellerModel->where('org_id',$orgId)->findAll();
|
||||
} else {
|
||||
$users = $this->travellerModel->where('org_id',$orgId)->where('is_active',1)->findAll();
|
||||
}
|
||||
|
||||
|
||||
if (!$users) {
|
||||
return $this->failNotFound('No Traveller found');
|
||||
}
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Travellers retrieved successfully',
|
||||
'data' => $users
|
||||
], 200);
|
||||
}
|
||||
|
||||
// Create Traveller
|
||||
public function create()
|
||||
{
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
if ($this->travellerModel->insert($data)) {
|
||||
$travellerId = $this->travellerModel->insertID(); // Get the last inserted ID
|
||||
$traveller = $this->travellerModel->find($travellerId); // Fetch the inserted record
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Traveller added successfully',
|
||||
'data' => $traveller // Returning inserted traveller details
|
||||
], 200);
|
||||
} else {
|
||||
return $this->failServerError('Failed to add traveller');
|
||||
}
|
||||
}
|
||||
|
||||
//Find Traveller
|
||||
public function find()
|
||||
{
|
||||
|
||||
$id = $this->request->getGet('traveller_id');
|
||||
|
||||
$data = $this->travellerModel->where('traveller_id',$id)->find();
|
||||
|
||||
if (!$data) {
|
||||
return $this->failNotFound('No data found');
|
||||
}
|
||||
|
||||
return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
|
||||
}
|
||||
|
||||
|
||||
// Update Traveller
|
||||
public function update($id = null)
|
||||
{
|
||||
if (!$id) {
|
||||
return $this->failNotFound('Traveller ID is required');
|
||||
}
|
||||
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
if ($this->travellerModel->update($id, $data)) {
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Traveller updated successfully'
|
||||
], 200);
|
||||
} else {
|
||||
return $this->failNotFound('Traveller not found or update failed');
|
||||
}
|
||||
}
|
||||
|
||||
// Find by Name (LIKE Search)
|
||||
public function findByName($name)
|
||||
{
|
||||
$travellers = $this->travellerModel->like('name', $name)->findAll();
|
||||
|
||||
if ($travellers) {
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Traveller(s) found',
|
||||
'data' => $travellers
|
||||
], 200);
|
||||
} else {
|
||||
return $this->failNotFound('No traveller found with this name');
|
||||
}
|
||||
}
|
||||
|
||||
// Find by Email
|
||||
public function findByEmail($email)
|
||||
{
|
||||
$traveller = $this->travellerModel->where('email', $email)->first();
|
||||
|
||||
if ($traveller) {
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Traveller found',
|
||||
'data' => $traveller
|
||||
], 200);
|
||||
} else {
|
||||
return $this->failNotFound('No traveller found with this email');
|
||||
}
|
||||
}
|
||||
|
||||
// Find by Mobile
|
||||
public function findByMobile($mobile)
|
||||
{
|
||||
$traveller = $this->travellerModel->where('mobile', $mobile)->first();
|
||||
|
||||
if ($traveller) {
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Traveller found',
|
||||
'data' => $traveller
|
||||
], 200);
|
||||
} else {
|
||||
return $this->failNotFound('No traveller found with this mobile number');
|
||||
}
|
||||
}
|
||||
}
|
||||
951
app/Controllers/UserController.php
Normal file
951
app/Controllers/UserController.php
Normal file
@ -0,0 +1,951 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use CodeIgniter\RESTful\ResourceController;
|
||||
use App\Models\UserModel;
|
||||
use App\Models\MailTemplateModel;
|
||||
use App\Models\UserFrequentFlierInformationModel;
|
||||
use App\Models\UserHotelMembershipModel;
|
||||
use App\Models\UserVisaDetailsModel;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||
|
||||
class UserController extends ResourceController
|
||||
{
|
||||
protected $format = 'json';
|
||||
protected $myLogger;
|
||||
protected $userModel;
|
||||
protected $mailTemplateModel;
|
||||
protected $userFrequentFlierInformationModel;
|
||||
protected $userHotelMembershipModel;
|
||||
protected $userVisaDetailsModel;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->myLogger = \Config\Services::mylogger();
|
||||
$this->userModel = new UserModel();
|
||||
$this->mailTemplateModel = new MailTemplateModel();
|
||||
$this->userFrequentFlierInformationModel = new UserFrequentFlierInformationModel();
|
||||
$this->userHotelMembershipModel = new UserHotelMembershipModel();
|
||||
$this->userVisaDetailsModel = new UserVisaDetailsModel();
|
||||
}
|
||||
|
||||
|
||||
public function index()
|
||||
{
|
||||
$orgId = $this->request->getGet('org_id');
|
||||
$for = $this->request->getGet('for');
|
||||
if(isset($for)){ $active = [0,1]; }else{ $active = [1]; }
|
||||
|
||||
$users = $this->userModel->getUsers($orgId,$active,[1,2,3,4]);
|
||||
|
||||
if (!$users) {
|
||||
return $this->failNotFound('No users found');
|
||||
}
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Users retrieved successfully',
|
||||
'data' => $users
|
||||
]);
|
||||
}
|
||||
|
||||
public function agentList()
|
||||
{
|
||||
$orgId = $this->request->getGet('org_id');
|
||||
$for = $this->request->getGet('for');
|
||||
if(isset($for)){ $active = [0,1]; }else{ $active = [1]; }
|
||||
|
||||
$users = $this->userModel->getUsers($orgId,$active,[5]);
|
||||
|
||||
if (!$users) {
|
||||
return $this->failNotFound('No users found');
|
||||
}
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Users retrieved successfully',
|
||||
'data' => $users
|
||||
]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$rules = [
|
||||
'first_name' => 'required',
|
||||
'email' => 'required|valid_email|is_unique[m_users.email]',
|
||||
];
|
||||
|
||||
|
||||
|
||||
$postData = $this->request->getPost();
|
||||
|
||||
//mailcontent data
|
||||
$mailData = [
|
||||
'first_name' => $postData['first_name'],
|
||||
'last_name' => $postData['last_name'],
|
||||
'email' => $postData['email'],
|
||||
'password' => $postData['password'],
|
||||
'org_id' => env('ORG_id'),
|
||||
'site_url' => env('FE_URL'),
|
||||
'template' => 'user_creation_notification',
|
||||
];
|
||||
|
||||
|
||||
|
||||
if (!$this->validate($rules)) {
|
||||
return $this->failValidationErrors($this->validator->getErrors());
|
||||
}
|
||||
|
||||
// $postData = $this->request->getJSON(true);
|
||||
$data = $this->formatUserData($postData);
|
||||
|
||||
|
||||
// Hash password before inserting into the database
|
||||
if (isset($data['password'])) {
|
||||
$data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
|
||||
}
|
||||
|
||||
$data['org_id'] = env('ORG_id');
|
||||
|
||||
// Handle file upload
|
||||
$file = $this->request->getFile('passport_document');
|
||||
if ($file && $file->isValid() && !$file->hasMoved()) {
|
||||
$newName = $file->getRandomName(); // Generate a unique name
|
||||
$uploadPath = FCPATH.'assets/images/passport';
|
||||
|
||||
// Move file to the specified directory
|
||||
$file->move($uploadPath, $newName);
|
||||
|
||||
// Save file path in database
|
||||
$data['passport_document'] = $uploadPath . '/' . $newName;
|
||||
} else {
|
||||
// return $this->failValidationErrors(['passport_document' => 'Invalid file upload']);
|
||||
}
|
||||
|
||||
try {
|
||||
$insert_id = $this->userModel->insert($data);
|
||||
//insert other user data ( hotal membership, visa details, frequent filler )
|
||||
$this->createOrUpdateUserOtherDetails($insert_id, $data);
|
||||
//trigger Mail
|
||||
sendUserCreationMail($mailData);
|
||||
return $this->respondCreated([
|
||||
'status' => 201,
|
||||
'message' => 'User created successfully',
|
||||
'data' => $postData
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->failServerError('Failed to create user: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function find($id = null)
|
||||
{
|
||||
if (!$id) {
|
||||
return $this->failNotFound('User ID is required');
|
||||
}
|
||||
|
||||
// Fetch user by ID
|
||||
$user = $this->userModel->find($id);
|
||||
|
||||
if (!$user) {
|
||||
return $this->failNotFound('User not found');
|
||||
}
|
||||
|
||||
$user = $this->formatUserDataForEdit($user);
|
||||
$frequentFlierInformation = $this->userFrequentFlierInformationModel->where('user_id', $id)->findAll() ?? [];
|
||||
$hotelMembership = $this->userHotelMembershipModel->where('user_id', $id)->findAll() ?? [];
|
||||
$visaDetails = $this->userVisaDetailsModel->where('user_id', $id)->findAll() ?? [];
|
||||
|
||||
$user['travel_details']['frequent_flier_information'] = $frequentFlierInformation;
|
||||
$user['travel_details']['hotel_membership'] = $hotelMembership;
|
||||
$user['travel_details']['visa_details'] = $visaDetails;
|
||||
|
||||
|
||||
//formate the date to the indian date format
|
||||
$user = $this->convertDateToDBFormat($user, 'd-m-Y');
|
||||
|
||||
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'User retrieved successfully',
|
||||
'data' => $user
|
||||
]);
|
||||
}
|
||||
|
||||
public function update($id = null)
|
||||
{
|
||||
if (!$id) {
|
||||
return $this->failNotFound('User ID is required');
|
||||
}
|
||||
|
||||
$postData = $this->request->getPost();
|
||||
// $postData = $this->request->getJSON(true);
|
||||
$data = $this->formatUserData($postData);
|
||||
|
||||
if (empty($data)) {
|
||||
return $this->failValidationErrors('No data provided for update');
|
||||
}
|
||||
|
||||
// Check if user exists
|
||||
$user = $this->userModel->find($id);
|
||||
if (!$user) {
|
||||
return $this->failNotFound('User not found');
|
||||
}
|
||||
|
||||
// Handle file upload
|
||||
$file = $this->request->getFile('passport_document');
|
||||
if ($file && $file->isValid() && !$file->hasMoved()) {
|
||||
$newName = $file->getRandomName(); // Generate a unique file name
|
||||
$uploadPath = FCPATH.'assets/images/passport';
|
||||
|
||||
// Move file to the directory
|
||||
$file->move($uploadPath, $newName);
|
||||
|
||||
// Delete the old file if it exists
|
||||
if (!empty($user['passport_document']) && file_exists($user['passport_document'])) {
|
||||
unlink($user['passport_document']); // Remove old file
|
||||
}
|
||||
|
||||
// Save the new file path
|
||||
$data['passport_document'] = $uploadPath . '/' . $newName;
|
||||
}
|
||||
|
||||
// Update user details
|
||||
try {
|
||||
unset($data['password']);
|
||||
$this->userModel->update($id, $data);
|
||||
//update other user data ( hotal membership, visa details, frequent filler )
|
||||
$this->createOrUpdateUserOtherDetails($id, $data);
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'User updated successfully',
|
||||
'data' => $postData
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->failServerError('Failed to update user: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function changePassword($id = null)
|
||||
{
|
||||
if (!$id) {
|
||||
return $this->failNotFound('User ID is required');
|
||||
}
|
||||
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
// Fetch user details
|
||||
$user = $this->userModel->find($id);
|
||||
if (!$user) {
|
||||
return $this->failNotFound('User not found');
|
||||
}
|
||||
|
||||
// Hash new password
|
||||
$newPasswordHash = password_hash($data['password'], PASSWORD_DEFAULT);
|
||||
|
||||
// Update password
|
||||
try {
|
||||
$this->userModel->update($id, ['password' => $newPasswordHash]);
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Password changed successfully'
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->failServerError('Failed to change password: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function updateUserStatus($id)
|
||||
{
|
||||
// Fetch user by ID
|
||||
$user = $this->userModel->find($id);
|
||||
|
||||
if (!$user) {
|
||||
return $this->failNotFound('User not found');
|
||||
}
|
||||
|
||||
// Toggle the is_active status
|
||||
$newStatus = $user['is_active'] == 1 ? 0 : 1;
|
||||
|
||||
// Update user status
|
||||
$this->userModel->update($id, ['is_active' => $newStatus]);
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => $newStatus ? 'User activated successfully' : 'User deactivated successfully',
|
||||
'is_active' => $newStatus
|
||||
]);
|
||||
}
|
||||
|
||||
public function roleList()
|
||||
{
|
||||
// Fetch all roles
|
||||
$roles = db_connect()->table('m_role')->orderBy('id', 'asc')->get()->getResultArray();
|
||||
|
||||
// Check roles exist
|
||||
if (!$roles) {
|
||||
log_message('error', 'No roles found in roleList()');
|
||||
return $this->failNotFound('No roles found');
|
||||
}
|
||||
|
||||
log_message('error', 'Roles retrieved successfully in roleList()');
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Roles retrieved successfully',
|
||||
'data' => $roles
|
||||
]);
|
||||
}
|
||||
|
||||
public function verifyUser()
|
||||
{
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
if (empty($data)) {
|
||||
log_message('error', "No data provided for user verification");
|
||||
return $this->failValidationErrors('No data provided for verification');
|
||||
}
|
||||
|
||||
if (!isset($data['email']) || empty($data['email'])) {
|
||||
log_message('error', "Email is missing or empty for user verification");
|
||||
return $this->failValidationErrors('Email is required for user verification');
|
||||
}
|
||||
|
||||
//featch user data for the give email
|
||||
$userData = $this->userModel->where('email', $data['email'])->first();
|
||||
|
||||
if(empty($userData)){
|
||||
log_message('error', "User not found");
|
||||
return $this->failNotFound('User not found');
|
||||
}
|
||||
|
||||
if ($userData['is_active'] == 0) {
|
||||
log_message('error', "User found but not active");
|
||||
return $this->failNotFound('User found but not active, no further action to be made');
|
||||
}
|
||||
|
||||
//generate random number for OTP
|
||||
$temp_password = random_int(100000, 999999);
|
||||
$userData['otp'] = $temp_password;
|
||||
log_message('error', "Generated temp password : ".$temp_password ?? "-");
|
||||
|
||||
//update otp to the given email user
|
||||
$return_value = $this->userModel->where('email', $data['email'])->set('temp_password', $temp_password)->update();
|
||||
log_message('error', "Temp password updated successfully aginst the user email");
|
||||
|
||||
//mail send function
|
||||
$mail_response = send_email($userData['org_id'], $data['email'], 'forgot_password_otp', $userData);
|
||||
// print_r($mail_response);
|
||||
|
||||
$data = [
|
||||
"request_data" => $data,
|
||||
"mail_response" => $mail_response,
|
||||
];
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'User verified successfully. Mail send to the given mail-id',
|
||||
'data' => $data,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function forgotChangePassword()
|
||||
{
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
if (empty($data)) {
|
||||
log_message('error', "No data provided for forgot change password");
|
||||
return $this->failValidationErrors('No data provided for change password');
|
||||
}
|
||||
|
||||
if (!isset($data['email']) || empty($data['email'])) {
|
||||
log_message('error', "email is missing or empty for forgot change password");
|
||||
return $this->failValidationErrors('Email id is required for change password');
|
||||
}
|
||||
|
||||
if (!isset($data['otp']) || empty($data['otp'])) {
|
||||
log_message('error', "Temp password is missing or empty for forgot change password");
|
||||
return $this->failValidationErrors('OTP is required for change password');
|
||||
}
|
||||
|
||||
if (!isset($data['new_password']) || empty($data['new_password'])) {
|
||||
log_message('error', "New password is missing or empty for forgot change password");
|
||||
return $this->failValidationErrors('New password is required for change password');
|
||||
}
|
||||
|
||||
if (!isset($data['confirm_password']) || empty($data['confirm_password'])) {
|
||||
log_message('error', "Confirm password is missing or empty for forgot change password");
|
||||
return $this->failValidationErrors('Confirm password is required for change password');
|
||||
}
|
||||
|
||||
if (!isset($data['confirm_password']) || empty($data['confirm_password'])) {
|
||||
log_message('error', "Confirm password is missing or empty for forgot change password");
|
||||
return $this->failValidationErrors('Confirm password is required for change password');
|
||||
}
|
||||
|
||||
//featch user data for the give email
|
||||
$userData = $this->userModel->where('email', $data['email'])->first();
|
||||
|
||||
if(empty($userData)){
|
||||
log_message('error', "User not found");
|
||||
return $this->failNotFound('User not found');
|
||||
}
|
||||
|
||||
if ($userData['is_active'] == 0) {
|
||||
log_message('error', "User found but not active");
|
||||
return $this->failNotFound('User found but not active, no further action to be made');
|
||||
}
|
||||
|
||||
if($userData['temp_password'] !== $data['otp']){
|
||||
log_message('error', "Invalid OTP");
|
||||
return $this->failValidationErrors('Invalid OTP');
|
||||
}
|
||||
|
||||
if($data['new_password'] !== $data['confirm_password']){
|
||||
log_message('error', "New password as not same as the confirm password");
|
||||
return $this->failValidationErrors('New password as not same as the confirm password');
|
||||
}
|
||||
|
||||
//construct the updated data
|
||||
$update_data = [
|
||||
'password' => password_hash($data['new_password'], PASSWORD_DEFAULT),
|
||||
'temp_password' => null
|
||||
];
|
||||
|
||||
$return_value = $this->userModel->where('user_id', $userData['user_id'])->set($update_data)->update();
|
||||
log_message('error', "Password changed successfully and Temp password reseted successfully aginst the user id");
|
||||
|
||||
return $this->respond([
|
||||
'status' => 200,
|
||||
'message' => 'Password changed successfully.',
|
||||
]);
|
||||
}
|
||||
|
||||
public function createOrUpdateUserOtherDetails($user_id, $data)
|
||||
{
|
||||
|
||||
//insert or update frequent flier information
|
||||
if(!empty($data) && isset($data['frequent_flier_information']) && !empty($data['frequent_flier_information'])){
|
||||
foreach ($data['frequent_flier_information'] as $key => $value) {
|
||||
$value['user_id'] = $user_id;
|
||||
if(isset($value['id']) && !empty($value['id'])){
|
||||
$this->userFrequentFlierInformationModel->update($value['id'], $value);
|
||||
}else{
|
||||
$this->userFrequentFlierInformationModel->insert($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//insert or update hotel membership
|
||||
if(!empty($data) && isset($data['hotel_membership']) && !empty($data['hotel_membership'])){
|
||||
foreach ($data['hotel_membership'] as $key => $value) {
|
||||
$value['user_id'] = $user_id;
|
||||
if(isset($value['id']) && !empty($value['id'])){
|
||||
$this->userHotelMembershipModel->update($value['id'], $value);
|
||||
}else{
|
||||
$this->userHotelMembershipModel->insert($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//insert or update visa details
|
||||
if(!empty($data) && isset($data['visa_details']) && !empty($data['visa_details'])){
|
||||
foreach ($data['visa_details'] as $key => $value) {
|
||||
$value['user_id'] = $user_id;
|
||||
if(isset($value['id']) && !empty($value['id'])){
|
||||
$this->userVisaDetailsModel->update($value['id'], $value);
|
||||
}else{
|
||||
$this->userVisaDetailsModel->insert($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function formatUserData($data)
|
||||
{
|
||||
if (empty($data)) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
if (isset($data['travel_details'])) {
|
||||
|
||||
if (!is_array($data['travel_details'])) {
|
||||
$decoded = json_decode($data['travel_details'], true);
|
||||
if (json_last_error() === JSON_ERROR_NONE) {
|
||||
$data['travel_details'] = $decoded;
|
||||
|
||||
//format the date to the database format
|
||||
$data = $this->convertDateToDBFormat($data);
|
||||
|
||||
} else {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
$data = array_merge($data, $data['travel_details']);
|
||||
unset($data['travel_details']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function formatUserDataForEdit($data)
|
||||
{
|
||||
if (!empty($data)) {
|
||||
|
||||
$travelKeys = [
|
||||
'passport_firstname',
|
||||
'passport_middlename',
|
||||
'passport_lastname',
|
||||
'nationality',
|
||||
'passport_number',
|
||||
'place_of_issue',
|
||||
'passport_document',
|
||||
'date_of_expiry',
|
||||
'd_meal_preference',
|
||||
'd_seat_preference',
|
||||
'd_additonalInfo',
|
||||
'i_meal_preference',
|
||||
'i_seat_preference',
|
||||
'i_additonalInfo',
|
||||
'emergency_contact_number',
|
||||
'date_of_issue',
|
||||
'forex_pre_paid_card_number',
|
||||
'forex_expiry_date',
|
||||
];
|
||||
|
||||
$data['travel_details'] = [];
|
||||
|
||||
foreach ($travelKeys as $key) {
|
||||
if (array_key_exists($key, $data)) {
|
||||
$data['travel_details'][$key] = $data[$key];
|
||||
unset($data[$key]);
|
||||
} else {
|
||||
$data['travel_details'][$key] = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
//Function for date conversion
|
||||
public function convertDateToDBFormat($data, $format = 'Y-m-d')
|
||||
{
|
||||
if (!empty($data)) {
|
||||
|
||||
// Handle date_of_birth
|
||||
if (isset($data['date_of_birth'])) {
|
||||
$dob = trim($data['date_of_birth']);
|
||||
$timestamp = ($dob && $dob !== '0000-00-00' && $dob !== '0000-00-00 00:00:00') ? strtotime($dob) : false;
|
||||
$data['date_of_birth'] = ($timestamp) ? date($format, $timestamp) : null;
|
||||
}
|
||||
|
||||
// Handle delegation_start_date
|
||||
if (isset($data['delegation_start_date'])) {
|
||||
$dob = trim($data['delegation_start_date']);
|
||||
$timestamp = ($dob && $dob !== '0000-00-00' && $dob !== '0000-00-00 00:00:00') ? strtotime($dob) : false;
|
||||
$data['delegation_start_date'] = ($timestamp) ? date($format, $timestamp) : null;
|
||||
}
|
||||
|
||||
// Handle delegation_end_date
|
||||
if (isset($data['delegation_end_date'])) {
|
||||
$dob = trim($data['delegation_end_date']);
|
||||
$timestamp = ($dob && $dob !== '0000-00-00' && $dob !== '0000-00-00 00:00:00') ? strtotime($dob) : false;
|
||||
$data['delegation_end_date'] = ($timestamp) ? date($format, $timestamp) : null;
|
||||
}
|
||||
|
||||
if (!empty($data['travel_details']) && is_array($data['travel_details'])) {
|
||||
|
||||
// Handle date_of_issue
|
||||
if (isset($data['travel_details']['date_of_issue'])) {
|
||||
$doi = trim($data['travel_details']['date_of_issue']);
|
||||
$timestamp = ($doi && $doi !== '0000-00-00' && $doi !== '0000-00-00 00:00:00') ? strtotime($doi) : false;
|
||||
$data['travel_details']['date_of_issue'] = ($timestamp) ? date($format, $timestamp) : null;
|
||||
}
|
||||
|
||||
// Handle date_of_expiry
|
||||
if (isset($data['travel_details']['date_of_expiry'])) {
|
||||
$doe = trim($data['travel_details']['date_of_expiry']);
|
||||
$timestamp = ($doe && $doe !== '0000-00-00' && $doe !== '0000-00-00 00:00:00') ? strtotime($doe) : false;
|
||||
$data['travel_details']['date_of_expiry'] = ($timestamp) ? date($format, $timestamp) : null;
|
||||
}
|
||||
|
||||
// Handle forex_expiry_date
|
||||
if (isset($data['travel_details']['forex_expiry_date'])) {
|
||||
$fed = trim($data['travel_details']['forex_expiry_date']);
|
||||
$timestamp = ($fed && $fed !== '0000-00-00' && $fed !== '0000-00-00 00:00:00') ? strtotime($fed) : false;
|
||||
$data['travel_details']['forex_expiry_date'] = ($timestamp) ? date($format, $timestamp) : null;
|
||||
}
|
||||
|
||||
// Handle visa_details
|
||||
if (!empty($data['travel_details']['visa_details']) && is_array($data['travel_details']['visa_details'])) {
|
||||
foreach ($data['travel_details']['visa_details'] as $key => &$value) {
|
||||
|
||||
// valid_from
|
||||
$from = trim($value['valid_from'] ?? '');
|
||||
$timestamp1 = ($from && $from !== '0000-00-00' && $from !== '0000-00-00 00:00:00') ? strtotime($from) : false;
|
||||
$value['valid_from'] = ($timestamp1) ? date($format, $timestamp1) : null;
|
||||
|
||||
// valid_upto
|
||||
$upto = trim($value['valid_upto'] ?? '');
|
||||
$timestamp2 = ($upto && $upto !== '0000-00-00' && $upto !== '0000-00-00 00:00:00') ? strtotime($upto) : false;
|
||||
$value['valid_upto'] = ($timestamp2) ? date($format, $timestamp2) : null;
|
||||
}
|
||||
unset($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
public function checkDuplicate()
|
||||
{
|
||||
$request = $this->request->getGet();
|
||||
|
||||
// Define supported fields
|
||||
$validFields = ['email', 'mobile_no', 'forex_pre_paid_card_number', 'employee_code', 'passport_number'];
|
||||
|
||||
$conditions = [];
|
||||
$fieldName = null;
|
||||
|
||||
// Determine which field is provided
|
||||
foreach ($validFields as $field) {
|
||||
if (!empty($request[$field])) {
|
||||
$conditions[$field] = $request[$field];
|
||||
$fieldName = $field;
|
||||
break; // only one field allowed at a time
|
||||
}
|
||||
}
|
||||
|
||||
if (!$fieldName) {
|
||||
return $this->response->setJSON([
|
||||
'status' => 'error',
|
||||
'message' => 'One of the following is required: email, mobile_no, forex_pre_paid_card_number, employee_code'
|
||||
])->setStatusCode(400);
|
||||
}
|
||||
|
||||
$builder = $this->userModel->where($fieldName, $conditions[$fieldName]);
|
||||
|
||||
// Optional: exclude user_id
|
||||
if (!empty($request['user_id'])) {
|
||||
$builder->where('user_id !=', $request['user_id']);
|
||||
}
|
||||
|
||||
$user = $builder->first();
|
||||
|
||||
if ($user) {
|
||||
return $this->response->setJSON(['status' => 'exists', 'field' => $fieldName]);
|
||||
} else {
|
||||
return $this->response->setJSON(['status' => 'not', 'field' => $fieldName]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function userUpload()
|
||||
{
|
||||
|
||||
$predefinedHeaders = ['First Name', 'Last Name', 'Email', 'Mobile Number', 'Password' , 'Role' ,'Employee Code','Group Name','First Approver Email'];
|
||||
|
||||
$uploadDir = WRITEPATH . 'uploads/userUploadFiles/';
|
||||
|
||||
// Create folder if not exists
|
||||
createDirectoryWith0777Permission($uploadDir);
|
||||
|
||||
|
||||
$file = $this->request->getFile('user_file');
|
||||
|
||||
if (!isValidUploadedFile($file)) {
|
||||
return $this->response->setJSON([
|
||||
'status' => 'failed',
|
||||
'message' => "Invalid file or file not uploaded.",
|
||||
'data' => ['successfulUsers' => [],'failedUsers' => [] ]
|
||||
]);
|
||||
}
|
||||
|
||||
if (!isAllowedExtension($file, ['xlsx', 'xls'])) {
|
||||
return $this->response->setJSON([
|
||||
'status' => 'failed',
|
||||
'message' => "Only Excel files are allowed.",
|
||||
'data' => ['successfulUsers' => [],'failedUsers' => [] ]
|
||||
]);
|
||||
}
|
||||
|
||||
// Move file temporarily
|
||||
$randomName = $file->getRandomName();
|
||||
$file->move($uploadDir, $randomName);
|
||||
$filePath = $uploadDir . $randomName;
|
||||
|
||||
// Load Excel
|
||||
$spreadsheet = IOFactory::load($filePath);
|
||||
$sheetData = $spreadsheet->getActiveSheet()->toArray(null, true, true, true);
|
||||
|
||||
if (!isExcelNotEmpty($sheetData)) {
|
||||
// before return remove the empty file
|
||||
return $this->response->setJSON([
|
||||
'status' => 'failed',
|
||||
'message' => "Excel sheet is empty or has no data.",
|
||||
'data' => ['successfulUsers' => [],'failedUsers' => [] ]
|
||||
]);
|
||||
}
|
||||
|
||||
// Validate headers
|
||||
// Sanitize headers: remove spaces/special characters and convert to lowercase
|
||||
$headers = array_map(function ($header) {
|
||||
return strtolower(preg_replace('/[^a-zA-Z0-9]/', '', $header));
|
||||
}, array_values($sheetData[1]));
|
||||
|
||||
$predefinedHeaders = array_map(function ($header) {
|
||||
return strtolower(preg_replace('/[^a-zA-Z0-9]/', '', $header));
|
||||
}, $predefinedHeaders);
|
||||
|
||||
|
||||
|
||||
if ($headers != $predefinedHeaders) {
|
||||
//before return remove the empty file
|
||||
return $this->response->setJSON([
|
||||
'status' => 'failed',
|
||||
'message' => "Invalid headers in Excel file.",
|
||||
'data' => ['successfulUsers' => [],'failedUsers' => [] ]
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
unset($sheetData[1]); // Remove header row
|
||||
|
||||
$success = 0 ;
|
||||
$fail = 0 ;
|
||||
$successfulUsers = [];
|
||||
$failedUsers = [];
|
||||
$insertUsers = [];
|
||||
|
||||
$dbHeaders = ['first_name','last_name','email','mobile_no','password','role_id','employee_code','group_id','first_approver_email'];
|
||||
|
||||
$rolesList = $this->userModel->getRolesList();
|
||||
|
||||
$groupsList = $this->userModel->getgroupsList();
|
||||
|
||||
// foreach ($sheetData as $row) {
|
||||
|
||||
// $user = array_combine($dbHeaders, array_values($row));
|
||||
|
||||
// if (!isset($user['email']) || empty($user['email']) || !filter_var($user['email'], FILTER_VALIDATE_EMAIL)) {
|
||||
// $fail++;
|
||||
// $failedUsers [] = $user['email'] ;
|
||||
// continue ;
|
||||
// }
|
||||
|
||||
// $userExists = $this->userModel->userExists($user['email']);
|
||||
|
||||
// if ( !$userExists) {
|
||||
|
||||
// //insert
|
||||
// $user['password_string'] = $user['password'];
|
||||
// $user['password'] = password_hash($user['password'], PASSWORD_DEFAULT);
|
||||
// $user['email'] = filter_var($user['email'], FILTER_SANITIZE_EMAIL);
|
||||
// $user['first_approver_email'] = filter_var($user['first_approver_email'], FILTER_SANITIZE_EMAIL);
|
||||
|
||||
// $role = strtolower(preg_replace('/[^A-Za-z0-9]/', '', $user['role_id']));
|
||||
// $group = strtolower(preg_replace('/[^A-Za-z0-9]/', '', $user['group_id']));
|
||||
|
||||
// $user['role_id'] = $rolesList[$role] ?? '4' ;
|
||||
// $user['group_id'] = $groupsList[$group] ?? Null ;
|
||||
// $user['org_id'] = env('ORG_id');
|
||||
|
||||
|
||||
// $insertUsers [] = $user ;
|
||||
|
||||
// $success++;
|
||||
// $successfulUsers [] = $user['email'] ;
|
||||
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
foreach ($sheetData as $row) {
|
||||
|
||||
$user = array_combine($dbHeaders, array_values($row));
|
||||
$email = $user['email'] ?? 'N/A';
|
||||
|
||||
// Email validation
|
||||
if (!isset($user['email']) || empty($user['email'])) {
|
||||
$fail++;
|
||||
$failedUsers[] = ['data' => $user['first_name'].' '.$user['last_name'], 'reason' => 'Email is missing'];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!filter_var($user['email'], FILTER_VALIDATE_EMAIL)) {
|
||||
$fail++;
|
||||
$failedUsers[] = ['data' => $email, 'reason' => 'Invalid email format'];
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check duplicate
|
||||
$userExists = $this->userModel->userExists($user['email']);
|
||||
if ($userExists) {
|
||||
$fail++;
|
||||
$failedUsers[] = ['data' => $email, 'reason' => 'User already exists'];
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check approver mail valid
|
||||
if (!empty($user['first_approver_email']) && !filter_var($user['first_approver_email'], FILTER_VALIDATE_EMAIL)) {
|
||||
$fail++;
|
||||
$failedUsers[] = ['data' => $user['first_name'].' '.$user['last_name'], 'reason' => 'Invalid first approver email format' ];
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
$role = strtolower(preg_replace('/[^A-Za-z0-9]/', '', $user['role_id']));
|
||||
$group = strtolower(preg_replace('/[^A-Za-z0-9]/', '', $user['group_id']));
|
||||
|
||||
// Sanitize and prepare for insert
|
||||
$user['password_string'] = $user['password'];
|
||||
$user['password'] = password_hash($user['password'], PASSWORD_DEFAULT);
|
||||
$user['email'] = filter_var($user['email'], FILTER_SANITIZE_EMAIL);
|
||||
$user['first_approver_email'] = filter_var($user['first_approver_email'], FILTER_SANITIZE_EMAIL);
|
||||
$user['role_id'] = $rolesList[$role] ?? 4;
|
||||
$user['group_id'] = $groupsList[$group] ?? null;
|
||||
$user['org_id'] = env('ORG_id');
|
||||
|
||||
$insertUsers[] = $user;
|
||||
$success++;
|
||||
$successfulUsers[] = $user['email'];
|
||||
}
|
||||
|
||||
|
||||
$insertedIds = [];
|
||||
|
||||
foreach ($insertUsers as $user) {
|
||||
$insertSuccess = $this->userModel->insert($user);
|
||||
|
||||
if ($insertSuccess) {
|
||||
$insertedIds[] = $this->userModel->getInsertID();
|
||||
|
||||
// Prepare mail content
|
||||
$mailData = [
|
||||
'first_name' => $user['first_name'],
|
||||
'last_name' => $user['last_name'],
|
||||
'email' => $user['email'],
|
||||
'password' => $user['password_string'],
|
||||
'org_id' => env('ORG_id'),
|
||||
'site_url' => env('FE_URL'),
|
||||
'template' => 'user_creation_notification',
|
||||
];
|
||||
|
||||
// Trigger mail
|
||||
sendUserCreationMail($mailData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//since email id directly stored in first_approver_email need to update in first_approver with id
|
||||
|
||||
$this->userModel->usersFirstApproverUpdation($insertedIds);
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => 'success',
|
||||
'message' => "$success users processed successfully, $fail failed.",
|
||||
'data' => [
|
||||
'successfulUsers' => $successfulUsers,
|
||||
'failedUsers' => $failedUsers
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
public function userUploadTemplate()
|
||||
{
|
||||
$uploadDir = WRITEPATH . 'uploads/template';
|
||||
|
||||
createDirectoryWith0777Permission($uploadDir);
|
||||
|
||||
$filePath = WRITEPATH . 'uploads/template/user_file.xlsx';
|
||||
|
||||
if (!file_exists($filePath)) {
|
||||
return $this->response->setStatusCode(404)->setJSON(['error' => 'Template file not found.']);
|
||||
}
|
||||
|
||||
return $this->response->download($filePath, null);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
0
app/Database/Migrations/.gitkeep
Executable file
0
app/Database/Migrations/.gitkeep
Executable file
0
app/Database/Seeds/.gitkeep
Executable file
0
app/Database/Seeds/.gitkeep
Executable file
0
app/Filters/.gitkeep
Executable file
0
app/Filters/.gitkeep
Executable file
56
app/Filters/Cors.php
Normal file
56
app/Filters/Cors.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filters;
|
||||
|
||||
use CodeIgniter\Filters\FilterInterface;
|
||||
use CodeIgniter\HTTP\RequestInterface;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
|
||||
class Cors implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* Do whatever processing this filter needs to do.
|
||||
* By default it should not return anything during
|
||||
* normal execution. However, when an abnormal state
|
||||
* is found, it should return an instance of
|
||||
* CodeIgniter\HTTP\Response. If it does, script
|
||||
* execution will end and that Response will be
|
||||
* sent back to the client, allowing for error pages,
|
||||
* redirects, etc.
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param array|null $arguments
|
||||
*
|
||||
* @return RequestInterface|ResponseInterface|string|void
|
||||
*/
|
||||
public function before(RequestInterface $request, $arguments = null)
|
||||
{
|
||||
// Set CORS headers
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
|
||||
header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With");
|
||||
|
||||
// Handle preflight requests
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
||||
header("HTTP/1.1 200 OK");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows After filters to inspect and modify the response
|
||||
* object as needed. This method does not allow any way
|
||||
* to stop execution of other after filters, short of
|
||||
* throwing an Exception or Error.
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @param array|null $arguments
|
||||
*
|
||||
* @return ResponseInterface|void
|
||||
*/
|
||||
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
|
||||
{
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
35
app/Filters/JwtAuthFilter.php
Normal file
35
app/Filters/JwtAuthFilter.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filters;
|
||||
|
||||
use CodeIgniter\HTTP\RequestInterface;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use CodeIgniter\Filters\FilterInterface;
|
||||
use Firebase\JWT\JWT;
|
||||
use Firebase\JWT\Key;
|
||||
|
||||
class JwtAuthFilter implements FilterInterface
|
||||
{
|
||||
public function before(RequestInterface $request, $arguments = null)
|
||||
{
|
||||
helper('jwt_helper');
|
||||
$header = $request->getHeaderLine('Authorization');
|
||||
|
||||
if (!$header || !preg_match('/Bearer\s(\S+)/', $header, $matches)) {
|
||||
return service('response')->setJSON(['status' => 401, 'message' => 'Token required'])->setStatusCode(401);
|
||||
}
|
||||
|
||||
$decodedToken = validateJWT($matches[1]);
|
||||
|
||||
if (!$decodedToken) {
|
||||
return service('response')->setJSON(['status' => 401, 'message' => 'Invalid or expired token'])->setStatusCode(401);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
|
||||
{
|
||||
// No action needed
|
||||
}
|
||||
}
|
||||
44
app/Filters/SignedUrlFilter.php
Executable file
44
app/Filters/SignedUrlFilter.php
Executable file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filters;
|
||||
|
||||
use CodeIgniter\HTTP\RequestInterface;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use CodeIgniter\Filters\FilterInterface;
|
||||
use Config\Services;
|
||||
class SignedUrlFilter implements FilterInterface
|
||||
{
|
||||
public function before(RequestInterface $request, $arguments = null)
|
||||
{
|
||||
$secretKey = 'your-secret-key'; // Change this to your secret key
|
||||
$expires = $request->getGet('expires');
|
||||
$signature = $request->getGet('signature');
|
||||
|
||||
if (!$expires || !$signature) {
|
||||
return Services::response()->setStatusCode(403)->setBody('Forbidden');
|
||||
}
|
||||
|
||||
if (time() > $expires) {
|
||||
$body = view('expired_link');
|
||||
return Services::response()->setStatusCode(403)->setBody($body);
|
||||
}
|
||||
|
||||
$queryParams = $request->getGet();
|
||||
unset($queryParams['signature']);
|
||||
$route = $request->getPath();
|
||||
$expectedSignature = hash_hmac('sha256', $route . '?' . http_build_query($queryParams), $secretKey);
|
||||
|
||||
if (!hash_equals($expectedSignature, $signature)) {
|
||||
return Services::response()->setStatusCode(403)->setBody('Invalid signature');
|
||||
}
|
||||
|
||||
return true; // Allow the request
|
||||
}
|
||||
|
||||
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
|
||||
{
|
||||
// Do nothing here
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
0
app/Helpers/.gitkeep
Executable file
0
app/Helpers/.gitkeep
Executable file
480
app/Helpers/common_helper.php
Normal file
480
app/Helpers/common_helper.php
Normal file
@ -0,0 +1,480 @@
|
||||
<?php
|
||||
|
||||
use App\Models\OrganizationModel;
|
||||
use App\Models\UserModel;
|
||||
use App\Models\GroupModel;
|
||||
use App\Models\PolicyModel;
|
||||
use App\Models\PolicyDetailsModel;
|
||||
use App\Models\ServiceModel;
|
||||
use App\Models\PlanStatusModel;
|
||||
use App\Models\PlanModel;
|
||||
|
||||
if (!function_exists('getUserByEmail')) {
|
||||
function getUserByEmail($email)
|
||||
{
|
||||
$userModel = new UserModel();
|
||||
$user = $userModel->where('email', $email)->first();
|
||||
|
||||
return $user ? $user : false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('checkUserExist')) {
|
||||
function checkUserExist($first_name, $email)
|
||||
{
|
||||
$userModel = new UserModel();
|
||||
|
||||
// Check if email already exists
|
||||
$user = $userModel->where('email', $email)->first();
|
||||
if ($user) {
|
||||
return ['status' => true,'data' => $user ,'message' => 'User already exists'];
|
||||
}
|
||||
|
||||
// Insert new user
|
||||
$userId = $userModel->insert([
|
||||
'first_name' => $first_name,
|
||||
'email' => $email,
|
||||
'org_id' => env('ORG_id')
|
||||
]);
|
||||
|
||||
if($userId){
|
||||
$user = $userModel->where('user_id', $userId)->first();
|
||||
return ['status' => true,'data' => $user ,'message' => 'User created successfully'];
|
||||
}else{
|
||||
return ['status' => false, 'message' => 'Something wend wrong'];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('getUserPlanCreationRestrictionStatus')) {
|
||||
function getUserPlanCreationRestrictionStatus($user)
|
||||
{
|
||||
if($user['group_id'] != null && ( $user['first_approver'] != null || $user['second_approver'] != null || $user['third_approver'] != null ) )
|
||||
{
|
||||
$groupModel = new GroupModel();
|
||||
$groupData = $groupModel->find($user['group_id']);
|
||||
if($groupData)
|
||||
{
|
||||
if($groupData['domestic_policy_id'] != null && $groupData['international_policy_id'] != null)
|
||||
return 'Both Type Plan Creation Allowed';
|
||||
else if($groupData['domestic_policy_id'] != null)
|
||||
return 'Only Domestic Plan Creation Allowed';
|
||||
else if($groupData['international_policy_id'] != null)
|
||||
return 'Only International Plan Creation Allowed';
|
||||
|
||||
|
||||
}else{
|
||||
return 'Plan Creation Not Allowed';
|
||||
}
|
||||
|
||||
}else{
|
||||
return 'Plan Creation Not Allowed';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!function_exists('isDataChanged')) {
|
||||
function isDataChanged($model, $id, array $newData): bool
|
||||
{
|
||||
// Step 1: Fetch old data from the model
|
||||
$oldData = $model->where('plan_id', $id)->where('is_active', 1)->findAll();
|
||||
|
||||
if (!$oldData) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Step 2: Define keys to exclude
|
||||
$excludeKeys = ['created_by', 'updated_by', 'created_on', 'updated_on'];
|
||||
|
||||
// Step 3: Clean both old and new data arrays
|
||||
$cleanOldData = array_map(function($item) use ($excludeKeys) {
|
||||
foreach ($excludeKeys as $key) {
|
||||
unset($item[$key]);
|
||||
}
|
||||
return $item;
|
||||
}, $oldData);
|
||||
|
||||
$cleanNewData = array_map(function($item) use ($excludeKeys) {
|
||||
foreach ($excludeKeys as $key) {
|
||||
unset($item[$key]);
|
||||
}
|
||||
return $item;
|
||||
}, $newData);
|
||||
|
||||
|
||||
// Step 4: Compare count
|
||||
if (count($cleanOldData) !== count($cleanNewData)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Step 5: Check if there's any difference
|
||||
return $cleanOldData !== $cleanNewData;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!function_exists('isFlightTripDataChanged')) {
|
||||
function isFlightTripDataChanged($model, $id, array $newData): bool
|
||||
{
|
||||
|
||||
$newTripData = [];
|
||||
$flightIds = array_column($newData, 'flight_id');
|
||||
foreach ($newData as $key1 => $value1) {
|
||||
foreach ($value1['trips'] as $key => $value) {
|
||||
array_push($newTripData , $value);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 1: Fetch old data from the model
|
||||
$oldData = $model->whereIn('flight_id', $flightIds)->where('is_active', 1)->findAll();
|
||||
|
||||
|
||||
if (!$oldData) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Step 2: Define keys to exclude
|
||||
$excludeKeys = ['created_by', 'updated_by', 'created_on', 'updated_on'];
|
||||
|
||||
// Step 3: Clean both old and new data arrays
|
||||
$cleanOldData = array_map(function($item) use ($excludeKeys) {
|
||||
foreach ($excludeKeys as $key) {
|
||||
unset($item[$key]);
|
||||
}
|
||||
return $item;
|
||||
}, $oldData);
|
||||
|
||||
$cleanNewData = array_map(function($item) use ($excludeKeys) {
|
||||
foreach ($excludeKeys as $key) {
|
||||
unset($item[$key]);
|
||||
}
|
||||
return $item;
|
||||
}, $newTripData);
|
||||
|
||||
|
||||
// Step 4: Compare count
|
||||
if (count($cleanOldData) !== count($cleanNewData)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Step 5: Check if there's any difference
|
||||
return $cleanOldData !== $cleanNewData;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getDelegatedPlans($org_id, $id)
|
||||
{
|
||||
$userModel = new UserModel();
|
||||
$planModel = new PlanModel();
|
||||
$planStatusModel = new PlanStatusModel();
|
||||
$delegatedUsers = $userModel->where('delegated_to_user_id', $id)
|
||||
->where('is_active', 1)
|
||||
->where('delegation_start_date <=', date('Y-m-d'))
|
||||
->where('delegation_end_date >=', date('Y-m-d'))
|
||||
->findAll();
|
||||
$allPlanData = [];
|
||||
foreach ($delegatedUsers as $user) {
|
||||
|
||||
$userId = $user['user_id'];
|
||||
$startDate = $user['delegation_start_date'];
|
||||
$endDate = $user['delegation_end_date'];
|
||||
|
||||
$a1Data = $planStatusModel->select('plan_id,a1_id as user_id')
|
||||
->where('a1_id',$userId)
|
||||
->where('a1_action','Approval')
|
||||
->where('created_on >=', $startDate)
|
||||
->where('created_on <=', $endDate)
|
||||
->where('is_active',1)
|
||||
->findAll();
|
||||
|
||||
$a2Data = $planStatusModel->select('plan_id,a2_id as user_id')
|
||||
->where('a2_id',$userId)
|
||||
->where('a2_action','Approval')
|
||||
->where('created_on >=', $startDate)
|
||||
->where('created_on <=', $endDate)
|
||||
->where('is_active',1)
|
||||
->findAll();
|
||||
|
||||
$a3Data = $planStatusModel->select('plan_id,a3_id as user_id')
|
||||
->where('a3_id',$userId)
|
||||
->where('a3_action','Approval')
|
||||
->where('is_active',1)
|
||||
->where('created_on >=', $startDate)
|
||||
->where('created_on <=', $endDate)
|
||||
->findAll();
|
||||
|
||||
// Merge results (each record has plan_id + user_id)
|
||||
$merged = array_merge($a1Data, $a2Data, $a3Data);
|
||||
|
||||
// Merge into final array
|
||||
$allPlanData = array_merge($allPlanData, $merged);
|
||||
|
||||
}
|
||||
|
||||
//get already approved data in delegated flow
|
||||
$a1 = $planStatusModel->select('plan_id,a1_id as user_id')->where('a1_action_done_by',$id)->where('a1_action','Approval')->where('is_active',1)->findAll();
|
||||
$a2 = $planStatusModel->select('plan_id,a2_id as user_id')->where('a2_action_done_by',$id)->where('a2_action','Approval')->where('is_active',1)->findAll();
|
||||
$a3 = $planStatusModel->select('plan_id,a3_id as user_id')->where('a3_action_done_by',$id)->where('a3_action','Approval')->where('is_active',1)->findAll();
|
||||
|
||||
//need to discuss with sir
|
||||
// $mergedApprovedArray = array_merge($a1, $a2, $a3);
|
||||
$mergedApprovedArray = [];
|
||||
|
||||
// Merge into main list
|
||||
$allPlanData = array_merge($allPlanData, $mergedApprovedArray);
|
||||
|
||||
// Remove duplicate associative arrays
|
||||
$allPlanData = array_map('unserialize', array_unique(array_map('serialize', $allPlanData)));
|
||||
|
||||
$plansWithUser = [];
|
||||
|
||||
foreach ($allPlanData as $item) {
|
||||
$planId = $item['plan_id'];
|
||||
$userId = $item['user_id'];
|
||||
$userData = $userModel->where('user_id',$userId)->first();
|
||||
$userName = $userData['first_name'].' '.$userData['last_name'];
|
||||
|
||||
$planData = $planModel->getActivePlan($org_id, 'PLAN', null , $planId);
|
||||
|
||||
if ($planData) {
|
||||
$planData['approver_id'] = $userId;
|
||||
$planData['approver_name'] = $userName;
|
||||
$planData['delegater_id'] = $id;
|
||||
$planData['approver_status'] = getApproverCurrentAction( $planData['plan_id'], $userId );
|
||||
$plansWithUser[] = $planData;
|
||||
}
|
||||
}
|
||||
|
||||
return $plansWithUser;
|
||||
|
||||
}
|
||||
|
||||
function normalize_date(string $date): ?string
|
||||
{
|
||||
$date = trim($date);
|
||||
|
||||
// If already valid Y-m-d (e.g., 2025-03-20), return it as-is
|
||||
$yFormat = DateTime::createFromFormat('Y-m-d', $date);
|
||||
if ($yFormat && $yFormat->format('Y-m-d') === $date) {
|
||||
return $date;
|
||||
}
|
||||
|
||||
// Try to convert from d-m-Y (e.g., 20-03-2025)
|
||||
$dFormat = DateTime::createFromFormat('d-m-Y', $date);
|
||||
if ($dFormat) {
|
||||
return $dFormat->format('Y-m-d');
|
||||
}
|
||||
|
||||
// Try from d/m/Y (optional)
|
||||
$slashFormat = DateTime::createFromFormat('d/m/Y', $date);
|
||||
if ($slashFormat) {
|
||||
return $slashFormat->format('Y-m-d');
|
||||
}
|
||||
|
||||
// Unknown format
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!function_exists('format_date_for_client')) {
|
||||
/**
|
||||
* Converts a date from 'Y-m-d' to 'd-m-Y'.
|
||||
*
|
||||
* @param string $date
|
||||
* @return string|null
|
||||
*/
|
||||
function format_date_for_client(string $date): ?string
|
||||
{
|
||||
$dt = DateTime::createFromFormat('Y-m-d', $date);
|
||||
if ($dt) {
|
||||
return $dt->format('d-m-Y');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// if (!function_exists('palnStatusHandler')) {
|
||||
// function palnStatusHandler($plan_id, $service_id, $action)
|
||||
// {
|
||||
|
||||
|
||||
// $planModel = new PlanModel();
|
||||
// $planStatusModel = new PlanStatusModel();
|
||||
// $userModel = new UserModel();
|
||||
// $groupModel = new GroupModel();
|
||||
// $policyModel = new PolicyModel();
|
||||
// $policyDetailsModel = new PolicyDetailsModel();
|
||||
|
||||
// if($action == 'DEL')
|
||||
// {
|
||||
// // Delete status
|
||||
// $planStatusModel->set(['is_active' => 0])->where('plan_id',$plan_id)->where('service_id',$service_id)->where('is_active',1)->update();
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// if($action == 'ADD')
|
||||
// {
|
||||
// //check already created
|
||||
// $status = $planStatusModel->where('plan_id',$plan_id)->where('service_id',$service_id)->where('is_active',1)->first();
|
||||
// if ($status) { return false; }
|
||||
// }
|
||||
|
||||
|
||||
// // Fetch plan data
|
||||
// $planData = $planModel->where('plan_id', $plan_id)->first();
|
||||
// if (!$planData) { return false; }
|
||||
// $userId = $planData['user_id'] ?? $planData['traveller_id'];
|
||||
|
||||
// // Fetch user data
|
||||
// $userData = $userModel->where('user_id', $userId)->first();
|
||||
// if (!$userData) { return false; }
|
||||
// $groupId = $userData['group_id'];
|
||||
// $a1Id = $userData['first_approver'];
|
||||
// $a2Id = $userData['second_approver'];
|
||||
// $a3Id = $userData['third_approver'];
|
||||
|
||||
// // Fetch group data
|
||||
// $groupData = $groupModel->where('group_id', $groupId)->first();
|
||||
// if (!$groupData) { return false; }
|
||||
// $policyId = ($planData['trip_type'] == 1) ? $groupData['domestic_policy_id'] : $groupData['international_policy_id'];
|
||||
|
||||
// // Fetch policy service data
|
||||
// $policyServiceData = $policyDetailsModel->where('policy_id', $policyId)->where('service_id', $service_id)->first();
|
||||
// if (!$policyServiceData) {return false; }
|
||||
// $policyA1Action = $policyServiceData['a1_action'];
|
||||
// $policyA2Action = $policyServiceData['a2_action'];
|
||||
// $policyA3Action = $policyServiceData['a3_action'];
|
||||
// $policyParallelAction = $policyServiceData['parallel_process_from'];
|
||||
|
||||
|
||||
// if($action == 'ADD')
|
||||
// {
|
||||
// $data['plan_id'] = $plan_id;
|
||||
// $data['service_id'] = $service_id;
|
||||
// $data['a1_id'] = $a1Id;
|
||||
// $data['a1_action'] = $policyA1Action;
|
||||
// $data['a2_id'] = $a2Id;
|
||||
// $data['a2_action'] = $policyA2Action;
|
||||
// $data['a3_id'] = $a3Id;
|
||||
// $data['a3_action'] = $policyA3Action;
|
||||
// $data['parallel_process_from'] = $policyParallelAction;
|
||||
// // Insert Status
|
||||
// $planStatusModel->insert($data);
|
||||
// }
|
||||
|
||||
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
if (!function_exists('isValidUploadedFile')) {
|
||||
function isValidUploadedFile($file): bool
|
||||
{
|
||||
return $file && $file->isValid();
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('isAllowedExtension')) {
|
||||
function isAllowedExtension($file, array $allowedExtensions = [] ): bool
|
||||
{
|
||||
$ext = strtolower($file->getClientExtension());
|
||||
|
||||
$result = in_array($ext, $allowedExtensions);
|
||||
|
||||
$result = empty($allowedExtensions) ? true : $result ;
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!function_exists('isExcelNotEmpty')) {
|
||||
function isExcelNotEmpty(array $sheetData): bool
|
||||
{
|
||||
return !empty($sheetData) && count($sheetData) >= 2;
|
||||
}
|
||||
}
|
||||
|
||||
if(!function_exists('createDirectoryWith0777Permission')){
|
||||
|
||||
function createDirectoryWith0777Permission( $uploadDir)
|
||||
{
|
||||
if (!is_dir($uploadDir)) {
|
||||
mkdir($uploadDir, 0777, true); // recursive creation with full permission
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function getAllowedClassForUser($trip_type,$user_id)
|
||||
{
|
||||
|
||||
$userModel = new UserModel();
|
||||
$groupModel = new GroupModel();
|
||||
$policyDetailsModel = new PolicyDetailsModel();
|
||||
$policyDetailsModel = new PolicyDetailsModel();
|
||||
|
||||
$user = $userModel->where('user_id', $user_id)->first();
|
||||
$groupData = $groupModel->find($user['group_id']);
|
||||
|
||||
if($groupData)
|
||||
{
|
||||
if($trip_type == 1) { $policyId = $groupData['domestic_policy_id'];}else{ $policyId = $groupData['international_policy_id'];}
|
||||
if($policyId != null)
|
||||
{
|
||||
$allowedFlightClass = $policyDetailsModel->select('c_policy_details.class, m_dropdown.dropdown_value as allowed_class')
|
||||
->join('m_dropdown', 'dropdown_key = c_policy_details.class AND dropdown = "flight_class"', 'left')
|
||||
->where('policy_id',$policyId)
|
||||
->where('service_id',1)
|
||||
->first();
|
||||
$data['flight'] = $allowedFlightClass['allowed_class'];
|
||||
|
||||
$allowedTrainClass = $policyDetailsModel->select('c_policy_details.class, m_dropdown.dropdown_value as allowed_class')
|
||||
->join('m_dropdown', 'dropdown_key = c_policy_details.class AND dropdown = "train_class"', 'left')
|
||||
->where('policy_id',$policyId)
|
||||
->where('service_id',2)
|
||||
->first();
|
||||
$data['train'] = $allowedTrainClass['allowed_class'];
|
||||
|
||||
$allowedHotelClass = $policyDetailsModel->select('c_policy_details.class, m_dropdown.dropdown_value as allowed_class')
|
||||
->join('m_dropdown', 'dropdown_key = c_policy_details.class AND dropdown = "hotel_class"', 'left')
|
||||
->where('policy_id',$policyId)
|
||||
->where('service_id',5)
|
||||
->first();
|
||||
$data['hotel'] = $allowedHotelClass['allowed_class'];
|
||||
}
|
||||
|
||||
|
||||
return $data;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
37
app/Helpers/jwt_helper.php
Normal file
37
app/Helpers/jwt_helper.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
use Firebase\JWT\JWT;
|
||||
use Firebase\JWT\Key;
|
||||
|
||||
if (!function_exists('generateJWT')) {
|
||||
function generateJWT($userData)
|
||||
{
|
||||
$key = getenv('JWT_SECRET'); // Load secret from .env
|
||||
$issuedAt = time();
|
||||
$expire = $issuedAt + 14400; // Token valid for 4 hour
|
||||
|
||||
$payload = [
|
||||
'iss' => base_url(), // Issuer
|
||||
'iat' => $issuedAt, // Issued at
|
||||
'exp' => $expire, // Expiration time
|
||||
'sub' => $userData['user_id'], // Subject (User ID)
|
||||
'data' => $userData // Additional user data
|
||||
];
|
||||
|
||||
return JWT::encode($payload, $key, 'HS256');
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('validateJWT')) {
|
||||
function validateJWT($token)
|
||||
{
|
||||
$key = getenv('JWT_SECRET');
|
||||
|
||||
try {
|
||||
$decoded = JWT::decode($token, new Key($key, 'HS256'));
|
||||
return (array) $decoded;
|
||||
} catch (\Exception $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
541
app/Helpers/mail_helper.php
Normal file
541
app/Helpers/mail_helper.php
Normal file
@ -0,0 +1,541 @@
|
||||
<?php
|
||||
use App\Controllers\PlanController;
|
||||
use App\Models\OrganizationModel;
|
||||
use App\Models\UserModel;
|
||||
use App\Models\GroupModel;
|
||||
use App\Models\PolicyModel;
|
||||
use App\Models\PolicyDetailsModel;
|
||||
use App\Models\ServiceModel;
|
||||
use App\Models\PlanStatusModel;
|
||||
use App\Models\PlanModel;
|
||||
use App\Models\MailTemplateModel;
|
||||
|
||||
|
||||
|
||||
if (!function_exists('sendPlanCreationMail')) {
|
||||
function sendPlanCreationMail($planId , $mailOn = 'send_mail_to_traveller_and_approver')
|
||||
{
|
||||
$planModel = new PlanModel();
|
||||
$userModel = new UserModel();
|
||||
$organizationModel = new OrganizationModel();
|
||||
$planStatusModel = new PlanStatusModel();
|
||||
|
||||
// Fetch plan data
|
||||
$planData = $planModel->where('plan_id', $planId)->first();
|
||||
if (!$planData) { return false; }
|
||||
$userId = isset($planData['traveller_id']) && !empty($planData['traveller_id']) ? $planData['created_by'] : $planData['user_id'];
|
||||
|
||||
|
||||
// Fetch user data
|
||||
$userData = $userModel->where('user_id', $userId)->first();
|
||||
if (!$userData) { return false; }
|
||||
|
||||
// send mail to traveller
|
||||
if($mailOn == 'send_mail_to_traveller_and_approver')
|
||||
send_email($planData['org_id'] , $userData['email'], 'plan_creation_notification_to_traveller' , $userData , $planData);
|
||||
|
||||
// send mail to approver
|
||||
$action = getPlanApproverAction($planId);
|
||||
|
||||
foreach ($action['approver_data'] as $key => $value) {
|
||||
|
||||
// Skip if not active
|
||||
if ($value['status'] !== 'active') { continue; }
|
||||
// Skip if already completed
|
||||
if ($value['is_action_done'] == 1) { continue; }
|
||||
// Skip if action is None
|
||||
if ($value['action'] === 'None') { continue; }
|
||||
|
||||
if($value['action'] == 'Approval'){ $template = 'plan_creation_approval_notification_to_approver'; }else if($value['action'] == 'Notification'){ $template = 'plan_creation_notification_to_approver'; }
|
||||
|
||||
$userData = $userModel->where('user_id', $value['user_id'])->first();
|
||||
|
||||
$url = urlButton($planId, $value['user_id']);
|
||||
|
||||
send_email($userData['org_id'] , $userData['email'], $template , $userData , $planData, $url);
|
||||
|
||||
// if action is notification update the action status as 1 (done)
|
||||
$parallelProcessValue = $action['parallel_process_from'];
|
||||
if($value['action'] == 'Notification'){
|
||||
|
||||
$planStatusModel->set([ $value['action_done_key'] => 1 ])
|
||||
->where('plan_id', $planId)
|
||||
->where($value['action_key'], 'Notification')
|
||||
->where('is_active', 1)
|
||||
->update();
|
||||
|
||||
if($parallelProcessValue == 2 && $value['action_key'] == 'a1_action')
|
||||
{
|
||||
sendPlanCreationMail($planId , 'send_mail_to_only_approver');
|
||||
}
|
||||
if($parallelProcessValue == 3)
|
||||
{
|
||||
sendPlanCreationMail($planId , 'send_mail_to_only_approver');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//delegation part
|
||||
$delegationUser = $userModel->where('user_id', $value['user_id'])
|
||||
->where('is_active', 1)
|
||||
->where('delegation_start_date <=', date('Y-m-d'))
|
||||
->where('delegation_end_date >=', date('Y-m-d'))
|
||||
->first();
|
||||
if($delegationUser){
|
||||
$delegatedToUserId = $delegationUser['delegated_to_user_id'];
|
||||
|
||||
$delegatedUserData = $userModel->where('user_id', $delegatedToUserId)->first();
|
||||
|
||||
$url = urlButton($planId, $value['user_id'] , $delegatedToUserId);
|
||||
|
||||
send_email($delegatedUserData['org_id'] , $delegatedUserData['email'], $template , $delegatedUserData , $planData, $url);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('sendPlanApprovalOrRejectMail')) {
|
||||
function sendPlanApprovalOrRejectMail($planId,$action)
|
||||
{
|
||||
$planModel = new PlanModel();
|
||||
$userModel = new UserModel();
|
||||
$organizationModel = new OrganizationModel();
|
||||
|
||||
// Fetch plan data
|
||||
$planData = $planModel->where('plan_id', $planId)->first();
|
||||
if (!$planData) { return false; }
|
||||
$userId = isset($planData['traveller_id']) && !empty($planData['traveller_id']) ? $planData['created_by'] : $planData['user_id'];
|
||||
|
||||
// Fetch user data
|
||||
$userData = $userModel->where('user_id', $userId)->first();
|
||||
if (!$userData) { return false; }
|
||||
$groupId = $userData['group_id'];
|
||||
$a1Id = $userData['first_approver'];
|
||||
$a2Id = $userData['second_approver'];
|
||||
$a3Id = $userData['third_approver'];
|
||||
|
||||
// Fetch Organization data
|
||||
$orgData = $organizationModel->where('org_id', $planData['org_id'])->first();
|
||||
|
||||
//current plan status
|
||||
$status = getCurrentPlanStatus($planId);
|
||||
|
||||
$statusHtml = '<h4>Trip Status:</h4>';
|
||||
$statusHtml .= '<ul>';
|
||||
foreach ($status as $key => $value) {
|
||||
|
||||
if (isset($value['a1_status'])) {
|
||||
$statusHtml .= '<li style="margin-bottom: 5px;"><strong>Approver 1:</strong> ' . $value['a1_status'] . '</li>';
|
||||
}
|
||||
|
||||
if (isset($value['a2_status'])) {
|
||||
$statusHtml .= '<li style="margin-bottom: 5px;"><strong>Approver 2:</strong> ' . $value['a2_status'] . '</li>';
|
||||
}
|
||||
|
||||
if (isset($value['a3_status'])) {
|
||||
$statusHtml .= '<li style="margin-bottom: 5px;"><strong>Approver 3:</strong> ' . $value['a3_status'] . '</li>';
|
||||
}
|
||||
}
|
||||
$statusHtml .= '</ul>';
|
||||
$userData['status_details'] = $statusHtml;
|
||||
|
||||
if($action == 'A'){ $template = 'plan_approval_notification_to_traveller'; }else{ $template = 'plan_rejection_notification_to_traveller'; }
|
||||
|
||||
|
||||
// send mail to traveller
|
||||
send_email($orgData['org_id'] , $userData['email'], $template , $userData , $planData);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('sendPlanUpdationMail')) {
|
||||
function sendPlanUpdationMail($planId)
|
||||
{
|
||||
$planModel = new PlanModel();
|
||||
$userModel = new UserModel();
|
||||
$organizationModel = new OrganizationModel();
|
||||
$planStatusModel = new PlanStatusModel();
|
||||
|
||||
// Fetch plan data
|
||||
$planData = $planModel->where('plan_id', $planId)->first();
|
||||
if (!$planData) { return false; }
|
||||
$userId = isset($planData['traveller_id']) && !empty($planData['traveller_id']) ? $planData['created_by'] : $planData['user_id'];
|
||||
|
||||
$currentStatus = $planData['status'];
|
||||
if($currentStatus != 1){
|
||||
$planModel->set(['status'=>1])->where('plan_id', $planId)->update();
|
||||
$planStatusModel->set(['is_a1_action_done'=>0, 'a1_reject_reason'=>null, 'is_a2_action_done'=>0, 'a2_reject_reason'=>null, 'is_a3_action_done'=>0, 'a3_reject_reason'=>null,])->where('plan_id', $planId)->update();
|
||||
}
|
||||
|
||||
// Fetch user data
|
||||
$userData = $userModel->where('user_id', $userId)->first();
|
||||
|
||||
|
||||
// send mail to traveller
|
||||
send_email($planData['org_id'] , $userData['email'], 'plan_updation_notification_to_traveller' , $userData , $planData);
|
||||
|
||||
// send mail to approver
|
||||
$action = getPlanApproverAction($planId);
|
||||
|
||||
foreach ($action['approver_data'] as $key => $value) {
|
||||
|
||||
// Skip if not active
|
||||
if ($value['status'] !== 'active') { continue; }
|
||||
// Skip if already completed
|
||||
if ($value['is_action_done'] == 1) { continue; }
|
||||
// Skip if action is None
|
||||
if ($value['action'] === 'None') { continue; }
|
||||
|
||||
if($value['action'] == 'Approval'){ $template = 'plan_updation_approval_notification_to_approver'; }else if($value['action'] == 'Notification'){ $template = 'plan_updation_notification_to_approver'; }
|
||||
|
||||
$userData = $userModel->where('user_id', $value['user_id'])->first();
|
||||
|
||||
$url = urlButton($planId, $value['user_id']);
|
||||
|
||||
send_email($userData['org_id'] , $userData['email'], $template , $userData , $planData, $url);
|
||||
|
||||
// if action is notification update the action status as 1 (done)
|
||||
$parallelProcessValue = $action['parallel_process_from'];
|
||||
if($value['action'] == 'Notification'){
|
||||
|
||||
$planStatusModel->set([ $value['action_done_key'] => 1 ])
|
||||
->where('plan_id', $planId)
|
||||
->where($value['action_key'], 'Notification')
|
||||
->where('is_active', 1)
|
||||
->update();
|
||||
|
||||
if($parallelProcessValue == 2 && $value['action_key'] == 'a1_action')
|
||||
{
|
||||
sendPlanCreationMail($planId , 'send_mail_to_only_approver');
|
||||
}
|
||||
if($parallelProcessValue == 3)
|
||||
{
|
||||
sendPlanCreationMail($planId , 'send_mail_to_only_approver');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//delegation part
|
||||
$delegationUser = $userModel->where('user_id', $value['user_id'])
|
||||
->where('is_active', 1)
|
||||
->where('delegation_start_date <=', date('Y-m-d'))
|
||||
->where('delegation_end_date >=', date('Y-m-d'))
|
||||
->first();
|
||||
if($delegationUser){
|
||||
$delegatedToUserId = $delegationUser['delegated_to_user_id'];
|
||||
|
||||
$delegatedUserData = $userModel->where('user_id', $delegatedToUserId)->first();
|
||||
|
||||
$url = urlButton($planId, $value['user_id'] , $delegatedToUserId);
|
||||
|
||||
send_email($delegatedUserData['org_id'] , $delegatedUserData['email'], $template , $delegatedUserData , $planData, $url);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('sendUserCreationMail')) {
|
||||
function sendUserCreationMail($mailData)
|
||||
{
|
||||
|
||||
// Fetch Organization data
|
||||
$organizationModel = new OrganizationModel();
|
||||
$orgData = $organizationModel->where('org_id', $mailData['org_id'] )->first();
|
||||
|
||||
// Fetch Template data
|
||||
$mailTemplateModel = new MailTemplateModel();
|
||||
$templateData = $mailTemplateModel->where('org_id', $mailData['org_id'] )->where('template_name', $mailData['template'] )->first();
|
||||
|
||||
//replace the placeholder
|
||||
foreach ($mailData as $key => $value) {
|
||||
$placeHolder = '%'.$key.'%';
|
||||
$templateData['body_html'] = str_replace($placeHolder, $value ?? '', $templateData['body_html']);
|
||||
}
|
||||
|
||||
$subject = $templateData['subject'];
|
||||
$html = $templateData['body_html'];
|
||||
$toEmailId = $mailData['email'];
|
||||
|
||||
$email = \Config\Services::email();
|
||||
$email->initialize([
|
||||
'protocol' => 'smtp',
|
||||
'SMTPHost' => $orgData['mail_host'],
|
||||
'SMTPUser' => $orgData['mail_user_name'],
|
||||
'SMTPPass' => $orgData['mail_password'],
|
||||
'SMTPPort' => (int)$orgData['mail_port'],
|
||||
'mailType' => 'html'
|
||||
]);
|
||||
$email->setFrom($orgData['sender_email'], $orgData['name']);
|
||||
$email->setTo($toEmailId);
|
||||
$email->setSubject($subject);
|
||||
$email->setMessage($html);
|
||||
|
||||
|
||||
|
||||
if ($email->send()) {
|
||||
|
||||
log_message('debug', 'Email Success to ' . $toEmailId);
|
||||
return ['status' => 'success', 'code' => 200, 'message' => 'Email Sent Successfully...', 'data' => $toEmailId];
|
||||
} else {
|
||||
log_message('debug', 'Email sending failed: ' . $email->printDebugger(['headers']));
|
||||
return ['status' => 'failed', 'code' => 404, 'message' => 'Email Sent Failed...', 'data' => $toEmailId];
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('send_email')) {
|
||||
function send_email($org_id , $toEmailId, $template , $userData , $planData = null, $url = null)
|
||||
{
|
||||
try {
|
||||
|
||||
// Fetch Organization data
|
||||
$organizationModel = new OrganizationModel();
|
||||
$orgData = $organizationModel->where('org_id', $org_id )->first();
|
||||
// Fetch Template data
|
||||
$mailTemplateModel = new MailTemplateModel();
|
||||
$templateData = $mailTemplateModel->where('org_id', $org_id )->where('template_name', $template )->first();
|
||||
log_message('info', "Template : ". $template ." , ToMail : ". $toEmailId);
|
||||
|
||||
//replace the placeholder
|
||||
foreach ($userData as $key => $value) {
|
||||
$placeHolder = '%'.$key.'%';
|
||||
$templateData['body_html'] = str_replace($placeHolder, $value ?? '', $templateData['body_html']);
|
||||
}
|
||||
|
||||
if(!empty($planData)){
|
||||
foreach ($planData as $key => $value) {
|
||||
$placeHolder = '%'.$key.'%';
|
||||
$templateData['body_html'] = str_replace($placeHolder, $value ?? '', $templateData['body_html']);
|
||||
}
|
||||
|
||||
if($planData['exceptional_plan_reason'] != null && $planData['exceptional_plan_reason'] != '')
|
||||
{
|
||||
$reasonHtmlString = '<table style="width:100%; border-collapse:collapse; font-family:Arial, sans-serif;">
|
||||
<tr>
|
||||
<td style="text-align:left;background-color:#ffdbdb;color:#960000;padding:7px 15px;font-weight:bold;border-top-left-radius:5px;border-top-right-radius:5px;border-bottom:1px solid #c65e56;">
|
||||
Reason for travel policy exception
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:left;background-color:#fff5f5;color:#960000ab;padding:10px 15px;border-bottom-left-radius:5px;border-bottom-right-radius:5px;">
|
||||
'.$planData['exceptional_plan_reason'].'
|
||||
</td>
|
||||
</tr>
|
||||
</table>';
|
||||
|
||||
$templateData['body_html'] = $templateData['body_html'].''.$reasonHtmlString;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
if($url != null){
|
||||
|
||||
$placeHolder = '%trip_review_link%';
|
||||
$templateData['body_html'] = str_replace($placeHolder, $url , $templateData['body_html']);
|
||||
|
||||
}
|
||||
|
||||
$subject = $templateData['subject'];
|
||||
$html = $templateData['body_html'];
|
||||
|
||||
$email = \Config\Services::email(true);
|
||||
$email->initialize([
|
||||
'protocol' => 'smtp',
|
||||
'SMTPHost' => $orgData['mail_host'],
|
||||
'SMTPUser' => $orgData['mail_user_name'],
|
||||
'SMTPPass' => $orgData['mail_password'],
|
||||
'SMTPPort' => (int)$orgData['mail_port'],
|
||||
'mailType' => 'html'
|
||||
]);
|
||||
$email->setFrom($orgData['sender_email'], $orgData['name']);
|
||||
$email->setTo($toEmailId);
|
||||
$email->setSubject($subject);
|
||||
$email->setMessage($html);
|
||||
|
||||
if(!empty($planData)){
|
||||
$email->attach($planData['pdf_file_path']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Try sending email
|
||||
if ($email->send()) {
|
||||
log_message('info', "[EMAIL SENT] To approver/traveller : {$toEmailId}, Template: {$template}");
|
||||
return ['status' => 'success', 'code' => 200, 'message' => 'Email sent successfully', 'data' => $toEmailId];
|
||||
} else {
|
||||
// Email send failed, log clean debug info
|
||||
$debugInfo = $email->printDebugger(['headers', 'subject', 'body']);
|
||||
log_message('error', "[EMAIL FAILED] To approver/traveller : {$toEmailId}, Template: {$template}\nError:\n" . strip_tags($debugInfo));
|
||||
|
||||
return ['status' => 'failed', 'code' => 500, 'message' => 'Email sending failed', 'data' => $toEmailId];
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
log_message('critical', "[EMAIL EXCEPTION] To approver/traveller : {$toEmailId}, Error: " . $e->getMessage().$e->getLine());
|
||||
return ['status' => 'failed', 'code' => 500, 'message' => 'Exception: ' . $e->getMessage(), 'data' => $toEmailId];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('send_email_agent')) {
|
||||
function send_email_agent($org_id , $plan_id)
|
||||
{
|
||||
try {
|
||||
|
||||
// Fetch Organization data
|
||||
$organizationModel = new OrganizationModel();
|
||||
$orgData = $organizationModel->where('org_id', $org_id )->first();
|
||||
// Fetch Template data
|
||||
$mailTemplateModel = new MailTemplateModel();
|
||||
$templateData = $mailTemplateModel->where('org_id', $org_id )->where('template_name', 'plan_notification_to_agent' )->first();
|
||||
|
||||
//Fetch plan data
|
||||
$planController = new PlanController();
|
||||
$planData = $planController->find($plan_id, 'internal');
|
||||
if (!$planData) {
|
||||
log_message('error', "No plan data found for plan_id: {$plan_id}");
|
||||
return false;
|
||||
}
|
||||
|
||||
$planServices = [];
|
||||
if (count($planData['flight'])) { array_push($planServices, 1); }
|
||||
if (count($planData['train'])) { array_push($planServices, 2); }
|
||||
if (count($planData['bus'])) { array_push($planServices, 3); }
|
||||
if (count($planData['taxi'])) { array_push($planServices, 4); }
|
||||
if (count($planData['accomodation'])) { array_push($planServices, 5); }
|
||||
if (count($planData['forex'])) { array_push($planServices, 6); }
|
||||
if (count($planData['insurance'])) { array_push($planServices, 7); }
|
||||
if (count($planData['visa'])) { array_push($planServices, 8); }
|
||||
if (count($planData['miscellaneous'])) { array_push($planServices, 9); }
|
||||
|
||||
// dd($planServices);
|
||||
|
||||
|
||||
|
||||
//Fetch Agent Data
|
||||
$userModel = new UserModel();
|
||||
$userData = $userModel->where('role_id', 5)->where('is_active', 1)->findAll();
|
||||
if (!$userData) {
|
||||
log_message('error', "User data not found for agent");
|
||||
return false;
|
||||
}
|
||||
|
||||
$email = \Config\Services::email();
|
||||
$email->initialize([
|
||||
'protocol' => 'smtp',
|
||||
'SMTPHost' => $orgData['mail_host'],
|
||||
'SMTPUser' => $orgData['mail_user_name'],
|
||||
'SMTPPass' => $orgData['mail_password'],
|
||||
'SMTPPort' => (int)$orgData['mail_port'],
|
||||
'mailType' => 'html'
|
||||
]);
|
||||
|
||||
foreach ($userData as $key => $value) {
|
||||
$jsonString = $value['agent_supported_service_ids'];
|
||||
|
||||
// Decode JSON string into PHP array
|
||||
$agentService = json_decode($jsonString, true);
|
||||
$agentServiceArray = [];
|
||||
if (is_array($agentService)) {
|
||||
foreach ($agentService as $service) {
|
||||
array_push($agentServiceArray,$service['service_id']);
|
||||
}
|
||||
}
|
||||
|
||||
$common = array_intersect($planServices, $agentServiceArray);
|
||||
|
||||
if (!empty($common)) {
|
||||
|
||||
//send mail to agent
|
||||
$placeHolderData['agent_name'] = $value['first_name'].' '.$value['last_name'];
|
||||
|
||||
foreach ($placeHolderData as $placeHolderkey => $placeHoldervalue) {
|
||||
$placeHolder = '%'.$placeHolderkey.'%';
|
||||
$templateData['body_html'] = str_replace($placeHolder, $placeHoldervalue ?? '', $templateData['body_html']);
|
||||
}
|
||||
|
||||
$subject = $templateData['subject'];
|
||||
$html = $templateData['body_html'];
|
||||
|
||||
//trigger_email_to agent
|
||||
$email->setFrom($orgData['sender_email'], $orgData['name']);
|
||||
$email->setTo($value['email']);
|
||||
$email->setSubject($subject);
|
||||
$email->setMessage($html);
|
||||
|
||||
if(!empty($planData)){
|
||||
$email->attach($planData['pdf_file_path']);
|
||||
}
|
||||
|
||||
if ($email->send()) {
|
||||
|
||||
log_message('debug', 'Email Success to agent plan_id = ' .$plan_id.'email = ' . $value['email']);
|
||||
|
||||
} else {
|
||||
log_message('debug', 'Email sending failed: agent plan_id = ' .$plan_id.'email = ' . $value['email'].'error = '.$email->printDebugger(['headers']));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
log_message('debug', 'Exception occurred while sending email to agent: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('check_mail_config')) {
|
||||
function check_mail_config($to_email, $mail_config = [])
|
||||
{
|
||||
if (empty($mail_config['SMTPHost']) ||
|
||||
empty($mail_config['SMTPUser']) ||
|
||||
empty($mail_config['SMTPPass']) ||
|
||||
empty($mail_config['SMTPPort']) ||
|
||||
empty($mail_config['sender_email']) ) {
|
||||
return json_encode(['status' => 400, 'message' => 'Incomplete Mail Configuration']);
|
||||
}
|
||||
|
||||
|
||||
$email = \Config\Services::email();
|
||||
$email->initialize([
|
||||
'protocol' => 'smtp',
|
||||
'mailType' => 'html',
|
||||
'SMTPHost' => $mail_config['SMTPHost'],
|
||||
'SMTPUser' => $mail_config['SMTPUser'],
|
||||
'SMTPPass' => $mail_config['SMTPPass'],
|
||||
'SMTPPort' => (int)$mail_config['SMTPPort']
|
||||
]);
|
||||
|
||||
$html = '<html><p style="text-align: center;">Test Mail Configuration </p></html>';
|
||||
$email->setFrom($mail_config['sender_email'], '');
|
||||
$email->setTo($to_email);
|
||||
$email->setSubject("Testing Mail Configuration");
|
||||
$email->setMessage($html);
|
||||
|
||||
if ($email->send()) {
|
||||
return json_encode(['status' => 200, 'message' => 'Email Sent Successfully...']);
|
||||
} else {
|
||||
log_message('error', 'Email sending failed: ' . $email->printDebugger(['headers']));
|
||||
return json_encode(['status' => 404, 'message' => 'Email Sent Failed...']);
|
||||
}
|
||||
}
|
||||
}
|
||||
63
app/Helpers/oauth_helper.php
Executable file
63
app/Helpers/oauth_helper.php
Executable file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
// File: app/Helpers/oauth_helper.php
|
||||
|
||||
use Google\Client as GoogleClient;
|
||||
use Google\Service\Oauth2;
|
||||
|
||||
// Check if the function exists, to prevent redeclaration
|
||||
if (!function_exists('googleOauthLogin')) {
|
||||
|
||||
function googleOAuthLogin($oauthToken)
|
||||
{
|
||||
|
||||
// Retrieve configuration values from environment variables
|
||||
// $appName = "710416535204-q948ovmbgs74lpf7so5866qtk8bpjthm.apps.googleusercontent.com";
|
||||
// $clientID = "710416535204-q948ovmbgs74lpf7so5866qtk8bpjthm.apps.googleusercontent.com";
|
||||
// $clientSecret = "18GKZJcIChn1Nore25fLPoT52137";
|
||||
// $redirectUri = "http://localhost/ts_tat/googleoauth";
|
||||
// $scopes = ["https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"];
|
||||
|
||||
$clientID = '696241936560-m2mr272ge7vr2n4q36c22l3d2gdgi90l.apps.googleusercontent.com';
|
||||
$clientSecret = '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';
|
||||
$redirectUri = "http://localhost/ts_tat/googleoauth";
|
||||
$scopes = ["https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"];
|
||||
|
||||
|
||||
// Initialize a new Google client
|
||||
$client = new GoogleClient();
|
||||
$client->setClientId($clientID);
|
||||
$client->setClientSecret($clientSecret);
|
||||
$client->setRedirectUri($redirectUri);
|
||||
$client->addScope($scopes);
|
||||
// $client->setApprovalPrompt('force');
|
||||
$client->setPrompt('consent');
|
||||
$client->setAccessType('offline');
|
||||
|
||||
// Check if an OAuth token is provided
|
||||
if ($oauthToken) {
|
||||
try {
|
||||
// Attempt to fetch the access token with the provided OAuth token
|
||||
$token = $client->fetchAccessTokenWithAuthCode($oauthToken);
|
||||
$client->setAccessToken($token);
|
||||
|
||||
$oauth = new Oauth2($client);
|
||||
|
||||
// Get user information using the OAuth2 service
|
||||
$user_info = $oauth->userinfo->get();
|
||||
return $user_info;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
// Handle exceptions and return an error message
|
||||
return 'Error fetching access token: ' . $e->getMessage();
|
||||
}
|
||||
} else {
|
||||
// If no OAuth token is provided, generate the authentication URL
|
||||
$url = $client->createAuthUrl();
|
||||
// Redirect the user to the authentication URL
|
||||
// return $url;
|
||||
return redirect()->to(filter_var($url, FILTER_SANITIZE_URL));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
740
app/Helpers/status_helper.php
Normal file
740
app/Helpers/status_helper.php
Normal file
@ -0,0 +1,740 @@
|
||||
<?php
|
||||
use App\Controllers\PlanController;
|
||||
use App\Models\OrganizationModel;
|
||||
use App\Models\UserModel;
|
||||
use App\Models\GroupModel;
|
||||
use App\Models\PolicyModel;
|
||||
use App\Models\PolicyDetailsModel;
|
||||
use App\Models\ServiceModel;
|
||||
use App\Models\PlanStatusModel;
|
||||
use App\Models\PlanModel;
|
||||
|
||||
|
||||
if (!function_exists('palnStatusHandler')) {
|
||||
function palnStatusHandler($plan_id , $is_data_edited)
|
||||
{
|
||||
log_message('info', "palnStatusHandler() called for plan_id: {$plan_id}, is_data_edited: {$is_data_edited}");
|
||||
|
||||
$planModel = new PlanModel();
|
||||
$planStatusModel = new PlanStatusModel();
|
||||
$userModel = new UserModel();
|
||||
$groupModel = new GroupModel();
|
||||
$policyModel = new PolicyModel();
|
||||
$policyDetailsModel = new PolicyDetailsModel();
|
||||
$planController = new PlanController();
|
||||
|
||||
$planData = $planController->find($plan_id, 'internal');
|
||||
if (!$planData) {
|
||||
log_message('error', "No plan data found for plan_id: {$plan_id}");
|
||||
return false;
|
||||
}
|
||||
|
||||
$planServices = [];
|
||||
if (count($planData['flight'])) { array_push($planServices, 1); }
|
||||
if (count($planData['train'])) { array_push($planServices, 2); }
|
||||
if (count($planData['bus'])) { array_push($planServices, 3); }
|
||||
if (count($planData['taxi'])) { array_push($planServices, 4); }
|
||||
if (count($planData['accomodation'])) { array_push($planServices, 5); }
|
||||
if (count($planData['forex'])) { array_push($planServices, 6); }
|
||||
if (count($planData['insurance'])) { array_push($planServices, 7); }
|
||||
if (count($planData['visa'])) { array_push($planServices, 8); }
|
||||
if (count($planData['miscellaneous'])) { array_push($planServices, 9); }
|
||||
|
||||
log_message('debug', "Plan services found: " . json_encode($planServices));
|
||||
|
||||
$userId = $planData['user_id'] ?? $planData['traveller_id'];
|
||||
$userData = $userModel->where('user_id', $userId)->first();
|
||||
if (!$userData) {
|
||||
log_message('error', "User data not found for user_id: {$userId}");
|
||||
return false;
|
||||
}
|
||||
|
||||
$groupId = $userData['group_id'];
|
||||
$a1Id = $userData['first_approver'];
|
||||
$a2Id = $userData['second_approver'];
|
||||
$a3Id = $userData['third_approver'];
|
||||
|
||||
$groupData = $groupModel->where('group_id', $groupId)->first();
|
||||
if (!$groupData) {
|
||||
log_message('error', "Group data not found for group_id: {$groupId}");
|
||||
return false;
|
||||
}
|
||||
|
||||
$tripType = $planData['trip_type'];
|
||||
$policyId = ($tripType == 1) ? $groupData['domestic_policy_id'] : $groupData['international_policy_id'];
|
||||
|
||||
$policyData = $policyModel->where('policy_id', $policyId)->first();
|
||||
if (!$policyData) {
|
||||
log_message('error', "Policy data not found for policy_id: {$policyId}");
|
||||
return false;
|
||||
}
|
||||
|
||||
$priorityOrderOfService = json_decode($policyData['services_ids'], true);
|
||||
if (!is_array($priorityOrderOfService)) {
|
||||
log_message('error', "Invalid service priority list in policy_id: {$policyId}");
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($priorityOrderOfService as $key => &$value) {
|
||||
$value['priority'] = $key + 1;
|
||||
}
|
||||
unset($value);
|
||||
|
||||
log_message('debug', "Service priority list: " . json_encode($priorityOrderOfService));
|
||||
|
||||
// Step 1: Filter only services present in current plan
|
||||
$filtered = array_filter($priorityOrderOfService, function ($item) use ($planServices) {
|
||||
return in_array($item['service_id'], $planServices);
|
||||
});
|
||||
|
||||
// Step 2: Sort by priority
|
||||
usort($filtered, function ($a, $b) {
|
||||
return $a['priority'] <=> $b['priority'];
|
||||
});
|
||||
|
||||
$topPriorityService = reset($filtered);
|
||||
if (!$topPriorityService) {
|
||||
log_message('error', "No matching service found for plan_id: {$plan_id}");
|
||||
return false;
|
||||
}
|
||||
|
||||
log_message('info', "Top priority service identified: " . json_encode($topPriorityService));
|
||||
|
||||
$policyServiceDetails = $policyDetailsModel
|
||||
->where('policy_id', $policyId)
|
||||
->where('service_id', $topPriorityService['service_id'])
|
||||
->where('is_active', 1)
|
||||
->first();
|
||||
|
||||
if (!$policyServiceDetails) {
|
||||
log_message('error', "Policy service details not found for service_id: {$topPriorityService['service_id']}, policy_id: {$policyId}");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
$isExceptional = $planData['exceptional_plan_reason'] !== null && $planData['exceptional_plan_reason'] !== '';
|
||||
|
||||
if ($isExceptional) {
|
||||
$policyA1Action = $policyServiceDetails['a1_exceptional_action'];
|
||||
$policyA2Action = $policyServiceDetails['a2_exceptional_action'];
|
||||
$policyA3Action = $policyServiceDetails['a3_exceptional_action'];
|
||||
$policyParallelAction = $policyServiceDetails['exceptional_parallel_process_from'];
|
||||
} else if ($is_data_edited) {
|
||||
$policyA1Action = $policyServiceDetails['a1_amendment_action'];
|
||||
$policyA2Action = $policyServiceDetails['a2_amendment_action'];
|
||||
$policyA3Action = $policyServiceDetails['a3_amendment_action'];
|
||||
$policyParallelAction = $policyServiceDetails['amendment_parallel_process_from'];
|
||||
} else {
|
||||
$policyA1Action = $policyServiceDetails['a1_action'];
|
||||
$policyA2Action = $policyServiceDetails['a2_action'];
|
||||
$policyA3Action = $policyServiceDetails['a3_action'];
|
||||
$policyParallelAction = $policyServiceDetails['parallel_process_from'];
|
||||
}
|
||||
|
||||
|
||||
$data = [
|
||||
'plan_id' => $plan_id,
|
||||
'service_id' => $topPriorityService['service_id'],
|
||||
'a1_id' => $a1Id,
|
||||
'a1_action' => $policyA1Action,
|
||||
'is_a1_action_done' => ($policyA1Action == 'None') ? 1 : 0,
|
||||
'a2_id' => $a2Id,
|
||||
'a2_action' => $policyA2Action,
|
||||
'is_a2_action_done' => ($policyA2Action == 'None') ? 1 : 0,
|
||||
'a3_id' => $a3Id,
|
||||
'a3_action' => $policyA3Action,
|
||||
'is_a3_action_done' => ($policyA3Action == 'None') ? 1 : 0,
|
||||
'parallel_process_from' => $policyParallelAction
|
||||
];
|
||||
|
||||
if ($is_data_edited == false) {
|
||||
log_message('info', "Creating new plan status for plan_id: {$plan_id}");
|
||||
$planStatusModel->insert($data);
|
||||
} else {
|
||||
$oldStatusData = $planStatusModel->where('plan_id', $plan_id)->where('is_active', 1)->first();
|
||||
if ($oldStatusData) {
|
||||
if ($oldStatusData['service_id'] == $topPriorityService['service_id']) {
|
||||
log_message('info', "No status update needed; service_id unchanged for plan_id: {$plan_id}");
|
||||
} else {
|
||||
log_message('info', "Updating plan status for edited plan_id: {$plan_id}. New service_id: {$topPriorityService['service_id']}, Old service_id: {$oldStatusData['service_id']}");
|
||||
$planStatusModel->insert($data);
|
||||
$planStatusModel->set(['is_active' => 0])
|
||||
->where('plan_id', $plan_id)
|
||||
->where('service_id', $oldStatusData['service_id'])
|
||||
->update();
|
||||
}
|
||||
} else {
|
||||
log_message('warning', "Old status data not found for edited plan_id: {$plan_id}");
|
||||
$planStatusModel->insert($data);
|
||||
}
|
||||
}
|
||||
|
||||
log_message('info', "palnStatusHandler() completed for plan_id: {$plan_id}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if (!function_exists('palnStatusHandler')) {
|
||||
// function palnStatusHandler($plan_id , $is_data_edited)
|
||||
// {
|
||||
|
||||
// $planModel = new PlanModel();
|
||||
// $planStatusModel = new PlanStatusModel();
|
||||
// $userModel = new UserModel();
|
||||
// $groupModel = new GroupModel();
|
||||
// $policyModel = new PolicyModel();
|
||||
// $policyDetailsModel = new PolicyDetailsModel();
|
||||
// $planController = new PlanController();
|
||||
|
||||
// $planData = $planController->find($plan_id, 'internal');
|
||||
|
||||
// $planServices = [];
|
||||
// if($planData)
|
||||
// {
|
||||
// if(count($planData['flight'])){ array_push($planServices,1); }
|
||||
// if(count($planData['train'])){ array_push($planServices,2); }
|
||||
// if(count($planData['bus'])){ array_push($planServices,3); }
|
||||
// if(count($planData['taxi'])){ array_push($planServices,4); }
|
||||
// if(count($planData['accomodation'])){ array_push($planServices,5); }
|
||||
// if(count($planData['forex'])){ array_push($planServices,6); }
|
||||
// if(count($planData['insurance'])){ array_push($planServices,7); }
|
||||
// if(count($planData['visa'])){ array_push($planServices,8); }
|
||||
// if(count($planData['miscellaneous'])){ array_push($planServices,9); }
|
||||
|
||||
// }
|
||||
// echo '<pre>';
|
||||
// print_r($planServices);
|
||||
|
||||
|
||||
// // Fetch plan data
|
||||
// if (!$planData) { return false; }
|
||||
// $userId = $planData['user_id'] ?? $planData['traveller_id'];
|
||||
|
||||
// // Fetch user data
|
||||
// $userData = $userModel->where('user_id', $userId)->first();
|
||||
// if (!$userData) { return false; }
|
||||
// $groupId = $userData['group_id'];
|
||||
// $a1Id = $userData['first_approver'];
|
||||
// $a2Id = $userData['second_approver'];
|
||||
// $a3Id = $userData['third_approver'];
|
||||
|
||||
|
||||
// // Fetch group data
|
||||
// $groupData = $groupModel->where('group_id', $groupId)->first();
|
||||
// if (!$groupData) { return false; }
|
||||
// $policyId = ($planData['trip_type'] == 1) ? $groupData['domestic_policy_id'] : $groupData['international_policy_id'];
|
||||
|
||||
// // Fetch policy service data
|
||||
// $policyData = $policyModel->where('policy_id', $policyId)->first();
|
||||
// if (!$policyData) {return false; }
|
||||
|
||||
// $priorityOrderOfService = json_decode($policyData['services_ids'],true);
|
||||
// if (is_array($priorityOrderOfService)) {
|
||||
// foreach ($priorityOrderOfService as $key => &$value) {
|
||||
// $value['priority'] = $key + 1;
|
||||
// }
|
||||
// unset($value); // always break reference after loop
|
||||
// }
|
||||
// echo '<pre>';
|
||||
// print_r($priorityOrderOfService);
|
||||
|
||||
// // Step 1: Filter only services you currently have
|
||||
// $filtered = array_filter($priorityOrderOfService, function($item) use ($planServices) {
|
||||
// return in_array($item['service_id'], $planServices);
|
||||
// });
|
||||
|
||||
// // Step 2: Sort by priority ascending
|
||||
// usort($filtered, function($a, $b) {
|
||||
// return $a['priority'] <=> $b['priority'];
|
||||
// });
|
||||
|
||||
// // Step 3: Get the top priority service
|
||||
// $topPriorityService = reset($filtered);
|
||||
// echo '<pre>';
|
||||
// print_r($topPriorityService); die;
|
||||
|
||||
// $policyServiceDetails = $policyDetailsModel->where('policy_id',$policyId)->where('service_id',$topPriorityService['service_id'])->where('is_active',1)->first();
|
||||
// if (!$policyServiceDetails) { return false; }
|
||||
// $policyA1Action = $policyServiceDetails['a1_action'];
|
||||
// $policyA2Action = $policyServiceDetails['a2_action'];
|
||||
// $policyA3Action = $policyServiceDetails['a3_action'];
|
||||
// $policyParallelAction = $policyServiceDetails['parallel_process_from'];
|
||||
|
||||
|
||||
|
||||
|
||||
// if($is_data_edited == false)//plan Creation
|
||||
// {
|
||||
// $data['plan_id'] = $plan_id;
|
||||
// $data['service_id'] = $topPriorityService['service_id'];
|
||||
// $data['a1_id'] = $a1Id;
|
||||
// $data['a1_action'] = $policyA1Action;
|
||||
// $data['a2_id'] = $a2Id;
|
||||
// $data['a2_action'] = $policyA2Action;
|
||||
// $data['a3_id'] = $a3Id;
|
||||
// $data['a3_action'] = $policyA3Action;
|
||||
// $data['parallel_process_from'] = $policyParallelAction;
|
||||
// // Insert Status
|
||||
// $planStatusModel->insert($data);
|
||||
|
||||
// }else{
|
||||
|
||||
// $oldStatusData = $planStatusModel->where('plan_id',$plan_id)->where('is_active', 1)->first();
|
||||
|
||||
// if($oldStatusData['service_id'] == $topPriorityService['service_id']){ // skip the process
|
||||
|
||||
// }else{ // insert new data
|
||||
|
||||
// //insert new service data
|
||||
// $data['plan_id'] = $plan_id;
|
||||
// $data['service_id'] = $topPriorityService['service_id'];
|
||||
// $data['a1_id'] = $a1Id;
|
||||
// $data['a1_action'] = $policyA1Action;
|
||||
// $data['a2_id'] = $a2Id;
|
||||
// $data['a2_action'] = $policyA2Action;
|
||||
// $data['a3_id'] = $a3Id;
|
||||
// $data['a3_action'] = $policyA3Action;
|
||||
// $data['parallel_process_from'] = $policyParallelAction;
|
||||
// // Insert Status
|
||||
// $planStatusModel->insert($data);
|
||||
|
||||
// //update old service data is_active = 0
|
||||
// $planStatusModel->set(['is_active'=>0])->where('plan_id',$plan_id)->where('service_id',$oldStatusData['service_id'])->update();
|
||||
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
|
||||
// }
|
||||
// }
|
||||
|
||||
if (!function_exists('updatePlanStatus')) {
|
||||
function updatePlanStatus($plan_id)
|
||||
{
|
||||
|
||||
$planStatusModel = new PlanStatusModel();
|
||||
$planModel = new PlanModel();
|
||||
|
||||
$a1 = $planStatusModel->where('plan_id',$plan_id)->where('a1_action','Approval')->where('is_active',1)->findAll();
|
||||
$a1ApproveSum = 0;
|
||||
$a1ApproveCount = 0;
|
||||
if(count($a1))
|
||||
{
|
||||
$a1ApproveSum = array_sum(array_column($a1, 'is_a1_action_done'));
|
||||
$a1ApproveCount = count($a1);
|
||||
}
|
||||
|
||||
$a2 = $planStatusModel->where('plan_id',$plan_id)->where('a2_action','Approval')->where('is_active',1)->findAll();
|
||||
$a2ApproveSum = 0;
|
||||
$a2ApproveCount = 0;
|
||||
if(count($a2))
|
||||
{
|
||||
$a2ApproveSum = array_sum(array_column($a2, 'is_a2_action_done'));
|
||||
$a2ApproveCount = count($a2);
|
||||
}
|
||||
|
||||
|
||||
$a3 = $planStatusModel->where('plan_id',$plan_id)->where('a3_action','Approval')->where('is_active',1)->findAll();
|
||||
$a3ApproveSum = 0;
|
||||
$a3ApproveCount = 0;
|
||||
if(count($a3))
|
||||
{
|
||||
$a3ApproveSum = array_sum(array_column($a3, 'is_a3_action_done'));
|
||||
$a3ApproveCount = count($a3);
|
||||
}
|
||||
|
||||
|
||||
$count = ( $a1ApproveCount + $a2ApproveCount + $a3ApproveCount);
|
||||
$sum = ( $a1ApproveSum + $a2ApproveSum + $a3ApproveSum);
|
||||
|
||||
|
||||
if($count == $sum)
|
||||
{
|
||||
// Approved
|
||||
$planModel->set(['status'=>3])->where('plan_id',$plan_id)->update();
|
||||
//send main to agent
|
||||
send_email_agent(env('ORG_id') , $plan_id);
|
||||
}else if($count != $sum && $sum > 0)
|
||||
{
|
||||
//Partially Approved
|
||||
$planModel->set(['status'=>2])->where('plan_id',$plan_id)->update();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('getCurrentPlanStatus')) {
|
||||
function getCurrentPlanStatus($plan_id)
|
||||
{
|
||||
|
||||
$planStatusModel = new PlanStatusModel();
|
||||
$userModel = new UserModel();
|
||||
$currentStatus = [];
|
||||
|
||||
$a1 = $planStatusModel->where('plan_id',$plan_id)->where('a1_action','Approval')->where('is_active',1)->findAll();
|
||||
|
||||
if(count($a1))
|
||||
{
|
||||
|
||||
$user1 = $userModel->where('user_id', $a1[0]['a1_action_done_by'])->first();
|
||||
if(!$user1){
|
||||
$user1 = $userModel->where('user_id', $a1[0]['a1_id'])->first();
|
||||
}
|
||||
|
||||
$hasRejectReason = !empty(array_filter($a1, fn($row) => !empty($row['a1_reject_reason'])));
|
||||
if($user1)
|
||||
{
|
||||
|
||||
$userId = $user1['user_id'];
|
||||
|
||||
$a1ApproveSum = array_sum(array_column($a1, 'is_a1_action_done'));
|
||||
$a1ApproveCount = count($a1);
|
||||
|
||||
$a1Status['a1_id'] = $userId;
|
||||
if($a1ApproveSum == $a1ApproveCount)
|
||||
{
|
||||
$a1Status['a1_status'] = 'Plan approved by '.$user1['first_name'].' '.$user1['last_name'];
|
||||
}else if($hasRejectReason){
|
||||
$a1Status['a1_status'] = 'Plan rejected by '.$user1['first_name'].' '.$user1['last_name'].', Reason-'.$a1[0]['a1_reject_reason'];
|
||||
}else{
|
||||
$a1Status['a1_status'] = 'Plan approval pending from '.$user1['first_name'].' '.$user1['last_name'];
|
||||
}
|
||||
array_push($currentStatus,$a1Status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
$a2 = $planStatusModel->where('plan_id',$plan_id)->where('a2_action','Approval')->where('is_active',1)->findAll();
|
||||
if(count($a2))
|
||||
{
|
||||
$user2 = $userModel->where('user_id', $a2[0]['a2_action_done_by'])->first();
|
||||
if(!$user2){
|
||||
$user2 = $userModel->where('user_id', $a2[0]['a2_id'])->first();
|
||||
}
|
||||
$hasRejectReason = !empty(array_filter($a2, fn($row) => !empty($row['a2_reject_reason'])));
|
||||
if($user2)
|
||||
{
|
||||
$userId = $user2['user_id'];
|
||||
|
||||
$a2ApproveSum = array_sum(array_column($a2, 'is_a2_action_done'));
|
||||
$a2ApproveCount = count($a2);
|
||||
|
||||
$a2Status['a2_id'] = $userId;
|
||||
if($a2ApproveSum == $a2ApproveCount)
|
||||
{
|
||||
$a2Status['a2_status'] = 'Plan approved by '.$user2['first_name'].' '.$user2['last_name'];
|
||||
}else if($hasRejectReason){
|
||||
$a2Status['a2_status'] = 'Plan rejected by '.$user2['first_name'].' '.$user2['last_name'].', Reason-'.$a2[0]['a2_reject_reason'];
|
||||
}else{
|
||||
$a2Status['a2_status'] = 'Plan approval pending from '.$user2['first_name'].' '.$user2['last_name'];
|
||||
}
|
||||
array_push($currentStatus,$a2Status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$a3 = $planStatusModel->where('plan_id',$plan_id)->where('a3_action','Approval')->where('is_active',1)->findAll();
|
||||
if(count($a3))
|
||||
{
|
||||
$user3 = $userModel->where('user_id', $a3[0]['a3_action_done_by'])->first();
|
||||
if(!$user3){
|
||||
$user3 = $userModel->where('user_id', $a3[0]['a3_id'])->first();
|
||||
}
|
||||
$hasRejectReason = !empty(array_filter($a3, fn($row) => !empty($row['a3_reject_reason'])));
|
||||
if($user3)
|
||||
{
|
||||
$userId = $user3['user_id'];
|
||||
|
||||
$a3ApproveSum = array_sum(array_column($a3, 'is_a3_action_done'));
|
||||
$a3ApproveCount = count($a3);
|
||||
|
||||
$a3Status['a3_id'] = $userId;
|
||||
if($a3ApproveSum == $a3ApproveCount)
|
||||
{
|
||||
$a3Status['a3_status'] = 'Plan approved by '.$user3['first_name'].' '.$user3['last_name'];
|
||||
}else if($hasRejectReason){
|
||||
$a3Status['a3_status'] = 'Plan rejected by '.$user3['first_name'].' '.$user3['last_name'].', Reason-'.$a3[0]['a3_reject_reason'];
|
||||
}else{
|
||||
$a3Status['a3_status'] = 'Plan approval pending from '.$user3['first_name'].' '.$user3['last_name'];
|
||||
}
|
||||
array_push($currentStatus,$a3Status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $currentStatus;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('getPlanApproverAction')) {
|
||||
// function getPlanApproverAction($plan_id , )
|
||||
// {
|
||||
|
||||
// $planStatusModel = new PlanStatusModel();
|
||||
// $userModel = new UserModel();
|
||||
// $result['approver_data'] = [];
|
||||
// $serviceIds = [];
|
||||
|
||||
// $a1 = $planStatusModel->where('plan_id',$plan_id)->whereIn('a1_action',['Approval','Notification'])->where('is_active',1)->findAll();
|
||||
// if(count($a1))
|
||||
// {
|
||||
// $serviceId = array_column($a1, 'service_id');
|
||||
// $serviceIds = array_merge($serviceIds, $serviceId);
|
||||
// $user = $userModel->where('user_id', $a1[0]['a1_id'])->first();
|
||||
// if($user)
|
||||
// {
|
||||
// $approvalCount = 0;
|
||||
// $notificationCount = 0;
|
||||
|
||||
// foreach ($a1 as $item) {
|
||||
// if ($item['a1_action'] === 'Approval') {
|
||||
// $approvalCount++;
|
||||
// } elseif ($item['a1_action'] === 'Notification') {
|
||||
// $notificationCount++;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if($approvalCount != 0)
|
||||
// {
|
||||
// array_push($result['approver_data'] , ['approver'=>1, 'user_id'=>$a1[0]['a1_id'], 'email'=> $user['email'], 'action'=>'Approval', 'is_action_done'=>$a1[0]['is_a1_action_done']] );
|
||||
// }else if($notificationCount != 0){
|
||||
// array_push($result['approver_data'] , ['approver'=>1, 'user_id'=>$a1[0]['a1_id'], 'email'=> $user['email'], 'action'=>'Notification', 'is_action_done'=>$a1[0]['is_a1_action_done']] );
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// $a2 = $planStatusModel->where('plan_id',$plan_id)->whereIn('a2_action',['Approval','Notification'])->where('is_active',1)->findAll();
|
||||
// if(count($a2))
|
||||
// {
|
||||
// $serviceId = array_column($a2, 'service_id');
|
||||
// $serviceIds = array_merge($serviceIds, $serviceId);
|
||||
// $user = $userModel->where('user_id', $a1[0]['a2_id'])->first();
|
||||
// if($user)
|
||||
// {
|
||||
// $approvalCount = 0;
|
||||
// $notificationCount = 0;
|
||||
|
||||
// foreach ($a1 as $item) {
|
||||
// if ($item['a2_action'] === 'Approval') {
|
||||
// $approvalCount++;
|
||||
// } elseif ($item['a2_action'] === 'Notification') {
|
||||
// $notificationCount++;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if($approvalCount != 0)
|
||||
// {
|
||||
// array_push($result['approver_data'] , ['approver'=>2, 'user_id'=>$a1[0]['a2_id'], 'email'=> $user['email'], 'action'=>'Approval', 'is_action_done'=>$a2[0]['is_a2_action_done']] );
|
||||
// }else if($notificationCount != 0){
|
||||
// array_push($result['approver_data'] , ['approver'=>2, 'user_id'=>$a1[0]['a2_id'], 'email'=> $user['email'], 'action'=>'Notification', 'is_action_done'=>$a2[0]['is_a2_action_done']] );
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// $a3 = $planStatusModel->where('plan_id',$plan_id)->whereIn('a3_action',['Approval','Notification'])->where('is_active',1)->findAll();
|
||||
// if(count($a3))
|
||||
// {
|
||||
// $serviceId = array_column($a3, 'service_id');
|
||||
// $serviceIds = array_merge($serviceIds, $serviceId);
|
||||
// $user = $userModel->where('user_id', $a1[0]['a3_id'])->first();
|
||||
// if($user)
|
||||
// {
|
||||
// $approvalCount = 0;
|
||||
// $notificationCount = 0;
|
||||
|
||||
// foreach ($a1 as $item) {
|
||||
// if ($item['a3_action'] === 'Approval') {
|
||||
// $approvalCount++;
|
||||
// } elseif ($item['a3_action'] === 'Notification') {
|
||||
// $notificationCount++;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if($approvalCount != 0)
|
||||
// {
|
||||
// array_push($result['approver_data'] , ['approver'=>3, 'user_id'=>$a1[0]['a3_id'], 'email'=> $user['email'], 'action'=>'Approval', 'is_action_done'=>$a3[0]['is_a3_action_done']] );
|
||||
// }else if($notificationCount != 0){
|
||||
// array_push($result['approver_data'] , ['approver'=>3, 'user_id'=>$a1[0]['a3_id'], 'email'=> $user['email'], 'action'=>'Notification', 'is_action_done'=>$a3[0]['is_a3_action_done']] );
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
|
||||
// $statusData = $planStatusModel->where('plan_id',$plan_id)->where('is_active',1)->first();
|
||||
// $result['parallel_process_from'] = $statusData['parallel_process_from'];
|
||||
|
||||
// return $result;
|
||||
|
||||
// }
|
||||
|
||||
|
||||
function getPlanApproverAction($plan_id)
|
||||
{
|
||||
$planStatusModel = new PlanStatusModel();
|
||||
$userModel = new UserModel();
|
||||
$result = ['approver_data' => []];
|
||||
$serviceIds = [];
|
||||
|
||||
// A1, A2, A3 - handle all same way
|
||||
$approverAction = [
|
||||
['key' => 'a1', 'approver' => 1],
|
||||
['key' => 'a2', 'approver' => 2],
|
||||
['key' => 'a3', 'approver' => 3],
|
||||
];
|
||||
|
||||
foreach ($approverAction as $stage) {
|
||||
$field = $stage['key'];
|
||||
$approverNumber = $stage['approver'];
|
||||
$actionField = "{$field}_action";
|
||||
$idField = "{$field}_id";
|
||||
$doneField = "is_{$field}_action_done";
|
||||
|
||||
$record = $planStatusModel->where('plan_id', $plan_id)
|
||||
->whereIn($actionField, ['Approval', 'Notification', 'None'])
|
||||
->where('is_active', 1)
|
||||
->first();
|
||||
|
||||
if ($record) {
|
||||
$user = $userModel->where('user_id', $record[$idField])->first();
|
||||
if ($user) {
|
||||
$result['approver_data'][] = [
|
||||
'approver' => $approverNumber,
|
||||
'user_id' => $record[$idField],
|
||||
'email' => $user['email'],
|
||||
'action' => $record[$actionField],
|
||||
'is_action_done' => $record[$doneField],
|
||||
'where_key' => $idField,
|
||||
'action_key' => $actionField,
|
||||
'action_done_key' => $doneField,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get parallel process value
|
||||
$statusData = $planStatusModel->where('plan_id', $plan_id)->where('is_active', 1)->first();
|
||||
$result['parallel_process_from'] = $statusData['parallel_process_from'] ?? null;
|
||||
|
||||
|
||||
$parallelFrom = (int) $result['parallel_process_from'];
|
||||
|
||||
foreach ($result['approver_data'] as $key => &$approver) {
|
||||
$approver['status'] = 'pending'; // default
|
||||
|
||||
if ($parallelFrom === 1) {
|
||||
// All parallel
|
||||
$approver['status'] = 'active';
|
||||
} elseif ($parallelFrom === 2) {
|
||||
if ($approver['approver'] === 1) {
|
||||
$approver['status'] = 'active';
|
||||
} elseif (in_array($approver['approver'], [2, 3])) {
|
||||
// Check if approver 1 is done
|
||||
$a1Done = false;
|
||||
foreach ($result['approver_data'] as $a) {
|
||||
if ($a['approver'] === 1 && $a['is_action_done']) {
|
||||
$a1Done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$approver['status'] = $a1Done ? 'active' : 'waiting';
|
||||
}
|
||||
} elseif ($parallelFrom === 3) {
|
||||
// Sequential: 1 -> 2 -> 3
|
||||
$a1Done = false;
|
||||
$a2Done = false;
|
||||
|
||||
foreach ($result['approver_data'] as $a) {
|
||||
if ($a['approver'] === 1 && $a['is_action_done']) $a1Done = true;
|
||||
if ($a['approver'] === 2 && $a['is_action_done']) $a2Done = true;
|
||||
}
|
||||
|
||||
if ($approver['approver'] === 1) {
|
||||
$approver['status'] = 'active';
|
||||
} elseif ($approver['approver'] === 2) {
|
||||
$approver['status'] = $a1Done ? 'active' : 'waiting';
|
||||
} elseif ($approver['approver'] === 3) {
|
||||
$approver['status'] = ($a1Done && $a2Done) ? 'active' : 'waiting';
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($approver); // best practice when using & reference in foreach
|
||||
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (!function_exists('getApproverCurrentAction')) {
|
||||
function getApproverCurrentAction($plan_id,$user_id)
|
||||
{
|
||||
|
||||
$planStatusModel = new PlanStatusModel();
|
||||
$userModel = new UserModel();
|
||||
|
||||
$a1 = $planStatusModel->where('plan_id',$plan_id)->where('a1_id',$user_id)->where('a1_action','Approval')->where('is_active',1)->findAll();
|
||||
if(count($a1))
|
||||
{
|
||||
$hasRejectReason = !empty(array_filter($a1, fn($row) => !empty($row['a1_reject_reason'])));
|
||||
$a1ApproveSum = array_sum(array_column($a1, 'is_a1_action_done'));
|
||||
$a1ApproveCount = count($a1);
|
||||
|
||||
if($a1ApproveSum == $a1ApproveCount)
|
||||
{
|
||||
return 'Approved';
|
||||
}else if($hasRejectReason){
|
||||
return 'Rejected';
|
||||
}else{
|
||||
return 'Approval pending';
|
||||
}
|
||||
}
|
||||
|
||||
$a2 = $planStatusModel->where('plan_id',$plan_id)->where('a2_id',$user_id)->where('a2_action','Approval')->where('is_active',1)->findAll();
|
||||
if(count($a2))
|
||||
{
|
||||
$hasRejectReason = !empty(array_filter($a2, fn($row) => !empty($row['a2_reject_reason'])));
|
||||
$a2ApproveSum = array_sum(array_column($a2, 'is_a2_action_done'));
|
||||
$a2ApproveCount = count($a2);
|
||||
|
||||
if($a2ApproveSum == $a2ApproveCount)
|
||||
{
|
||||
return 'Approved';
|
||||
}else if($hasRejectReason){
|
||||
return 'Rejected';
|
||||
}else{
|
||||
return 'Approval pending';
|
||||
}
|
||||
}
|
||||
|
||||
$a3 = $planStatusModel->where('plan_id',$plan_id)->where('a3_id',$user_id)->where('a3_action','Approval')->where('is_active',1)->findAll();
|
||||
if(count($a3))
|
||||
{
|
||||
$hasRejectReason = !empty(array_filter($a3, fn($row) => !empty($row['a3_reject_reason'])));
|
||||
$a3ApproveSum = array_sum(array_column($a3, 'is_a3_action_done'));
|
||||
$a3ApproveCount = count($a3);
|
||||
|
||||
if($a3ApproveSum == $a3ApproveCount)
|
||||
{
|
||||
return 'Approved';
|
||||
}else if($hasRejectReason){
|
||||
return 'Rejected';
|
||||
}else{
|
||||
return 'Approval pending';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
28
app/Helpers/url_helper.php
Executable file
28
app/Helpers/url_helper.php
Executable file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Config\Services;
|
||||
|
||||
if (!function_exists('generate_signed_url')) {
|
||||
function generate_signed_url($route, $params = [], $expiresIn = 259200)
|
||||
{
|
||||
$secretKey = 'your-secret-key'; // Change this to your secret key
|
||||
$expiresAt = time() + $expiresIn;
|
||||
$params['expires'] = $expiresAt;
|
||||
$signature = hash_hmac('sha256', $route . '?' . http_build_query($params), $secretKey);
|
||||
$params['signature'] = $signature;
|
||||
return base_url($route . '?' . http_build_query($params));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!function_exists('urlButton')) {
|
||||
function urlButton($planId, $userId , $delegationUserId = null )
|
||||
{
|
||||
|
||||
$url = generate_signed_url('review', ['plan_id'=> md5($planId),'user_id'=> $userId,'delegation_user_id'=> $delegationUserId], 259200);
|
||||
|
||||
return '<a href="' . $url . '" target="_blank">Click here to review the trip</a>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
0
app/Language/.gitkeep
Executable file
0
app/Language/.gitkeep
Executable file
4
app/Language/en/Validation.php
Executable file
4
app/Language/en/Validation.php
Executable file
@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
// override core en language system validation or define your own en language validation message
|
||||
return [];
|
||||
0
app/Libraries/.gitkeep
Executable file
0
app/Libraries/.gitkeep
Executable file
0
app/Models/.gitkeep
Executable file
0
app/Models/.gitkeep
Executable file
47
app/Models/AccomodationModel.php
Normal file
47
app/Models/AccomodationModel.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class AccomodationModel extends Model
|
||||
{
|
||||
protected $table = 'c_accomodation';
|
||||
protected $primaryKey = 'accomodation_id';
|
||||
|
||||
protected $allowedFields = [
|
||||
'plan_id',
|
||||
'destination_city',
|
||||
'hotel_name',
|
||||
'class',
|
||||
'checkin_date',
|
||||
'checkin_time',
|
||||
'checkout_date',
|
||||
'checkout_time',
|
||||
'comments',
|
||||
'is_this_exceptional',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'is_active'
|
||||
];
|
||||
|
||||
protected $useTimestamps = false;
|
||||
protected $createdField = 'created_on';
|
||||
protected $updatedField = 'updated_on';
|
||||
|
||||
/**
|
||||
* Get active accommodations
|
||||
*/
|
||||
public function getActiveAccommodations()
|
||||
{
|
||||
return $this->where('is_active', 1)->findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get accommodations for a specific plan
|
||||
*/
|
||||
public function getAccommodationsByPlan($planId)
|
||||
{
|
||||
return $this->where('plan_id', $planId)->findAll();
|
||||
}
|
||||
}
|
||||
30
app/Models/AirlineModel.php
Normal file
30
app/Models/AirlineModel.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class AirlineModel extends Model
|
||||
{
|
||||
protected $table = 'Airlines';
|
||||
protected $primaryKey = 'Airline_Code';
|
||||
protected $useAutoIncrement = false; // Because Airline_Code is not auto-increment
|
||||
|
||||
protected $returnType = 'array';
|
||||
protected $useSoftDeletes = false;
|
||||
|
||||
protected $allowedFields = [
|
||||
'airline',
|
||||
'airline_name',
|
||||
];
|
||||
|
||||
protected $useTimestamps = false;
|
||||
|
||||
// Validation rules (optional)
|
||||
protected $validationRules = [
|
||||
'Airline_Code' => 'required|alpha_numeric|max_length[2]',
|
||||
'Airline_Name' => 'required|max_length[70]',
|
||||
];
|
||||
protected $validationMessages = [];
|
||||
protected $skipValidation = false;
|
||||
}
|
||||
31
app/Models/AirportCodeModel.php
Normal file
31
app/Models/AirportCodeModel.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class AirportCodeModel extends Model
|
||||
{
|
||||
protected $table = 'Airport_Code_State';
|
||||
protected $primaryKey = 'Code';
|
||||
|
||||
protected $useAutoIncrement = false; // Since 'Code' is NOT AUTO_INCREMENT
|
||||
protected $returnType = 'array'; // You can set it to 'object' if you prefer
|
||||
protected $useSoftDeletes = false;
|
||||
|
||||
protected $allowedFields = [
|
||||
'Code',
|
||||
'City',
|
||||
'Airport',
|
||||
'Country_Code',
|
||||
'Country',
|
||||
'State',
|
||||
'Region',
|
||||
'Timezone',
|
||||
'GMTOffset',
|
||||
'DSTOffset',
|
||||
'RawOffset',
|
||||
'is_active'
|
||||
];
|
||||
|
||||
}
|
||||
43
app/Models/BusModel.php
Normal file
43
app/Models/BusModel.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class BusModel extends Model
|
||||
{
|
||||
protected $table = 'c_bus';
|
||||
protected $primaryKey = 'bus_id';
|
||||
|
||||
protected $allowedFields = [
|
||||
'plan_id',
|
||||
'from',
|
||||
'to',
|
||||
'date',
|
||||
'time',
|
||||
'comments',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'is_active'
|
||||
];
|
||||
|
||||
protected $useTimestamps = false;
|
||||
protected $createdField = 'created_on';
|
||||
protected $updatedField = 'updated_on';
|
||||
|
||||
/**
|
||||
* Get active bus bookings
|
||||
*/
|
||||
public function getActiveBuses()
|
||||
{
|
||||
return $this->where('is_active', 1)->findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bus bookings for a specific plan
|
||||
*/
|
||||
public function getBusesByPlan($planId)
|
||||
{
|
||||
return $this->where('plan_id', $planId)->findAll();
|
||||
}
|
||||
}
|
||||
24
app/Models/CostCenterModel.php
Normal file
24
app/Models/CostCenterModel.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class CostCenterModel extends Model
|
||||
{
|
||||
protected $table = 'm_cost_center';
|
||||
protected $primaryKey = 'cost_center_id';
|
||||
|
||||
protected $allowedFields = [
|
||||
'name',
|
||||
'description',
|
||||
'created_on',
|
||||
'created_by',
|
||||
'updated_on',
|
||||
'updated_by',
|
||||
'is_active'
|
||||
];
|
||||
|
||||
protected $useTimestamps = false;
|
||||
protected $returnType = 'array';
|
||||
}
|
||||
28
app/Models/CountryModel.php
Normal file
28
app/Models/CountryModel.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class CountryModel extends Model
|
||||
{
|
||||
protected $table = 'm_country'; // Table name
|
||||
protected $primaryKey = 'country_id'; // Primary key
|
||||
|
||||
// Fields to be allowed in insert or update operations
|
||||
protected $allowedFields = [
|
||||
'country_code','country_name','region','currency','is_active'
|
||||
];
|
||||
|
||||
// Specify the return type of the results
|
||||
protected $returnType = 'array';
|
||||
|
||||
// Define where clause to get active records by default
|
||||
protected $useTimestamps = true;
|
||||
|
||||
public function getActiveCountries()
|
||||
{
|
||||
return $this->where('is_active', 1)->findAll();
|
||||
}
|
||||
}
|
||||
|
||||
29
app/Models/DepartmentModel.php
Normal file
29
app/Models/DepartmentModel.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class DepartmentModel extends Model
|
||||
{
|
||||
protected $table = 'm_department'; // Table name
|
||||
protected $primaryKey = 'department_id'; // Primary key
|
||||
|
||||
// Fields that can be mass assigned
|
||||
protected $allowedFields = [
|
||||
'code','name','description','org_id','head_user_id','created_on','created_by','updated_on','updated_by','is_active',
|
||||
];
|
||||
|
||||
// Specify the return type of the results
|
||||
protected $returnType = 'array';
|
||||
|
||||
// Enable timestamps (if you wish to handle created_at and updated_at automatically)
|
||||
protected $useTimestamps = false; // Set true if using CI4 timestamp features
|
||||
|
||||
|
||||
// Custom method example (e.g., fetching active departments)
|
||||
public function getActiveDepartments()
|
||||
{
|
||||
return $this->where('is_active', 1)->findAll();
|
||||
}
|
||||
}
|
||||
55
app/Models/DropdownModel.php
Normal file
55
app/Models/DropdownModel.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class DropdownModel extends Model
|
||||
{
|
||||
protected $table = 'm_dropdown';
|
||||
// protected $primaryKey = 'dropdown_key';
|
||||
|
||||
protected $allowedFields = [
|
||||
'dropdown',
|
||||
'dropdown_key',
|
||||
'dropdown_value',
|
||||
'created_on',
|
||||
'updated_on',
|
||||
'is_active'
|
||||
];
|
||||
|
||||
protected $useTimestamps = false; // No automatic timestamp handling by CI4
|
||||
|
||||
protected $createdField = 'created_on';
|
||||
protected $updatedField = 'updated_on';
|
||||
|
||||
// Fetch dropdown values by group name
|
||||
public function getDropdownValuesByGroup($group)
|
||||
{
|
||||
return $this->where('dropdown', $group)->where('is_active', 1)->findAll();
|
||||
}
|
||||
|
||||
// Fetch a specific dropdown entry
|
||||
public function getDropdownByKey($key)
|
||||
{
|
||||
return $this->where('dropdown_key', $key)->first();
|
||||
}
|
||||
|
||||
// Insert a new dropdown value
|
||||
public function insertDropdown($data)
|
||||
{
|
||||
return $this->insert($data);
|
||||
}
|
||||
|
||||
// Update a dropdown value
|
||||
public function updateDropdown($key, $data)
|
||||
{
|
||||
return $this->where('dropdown_key', $key)->set($data)->update();
|
||||
}
|
||||
|
||||
// Soft delete (deactivate) a dropdown entry
|
||||
public function deactivateDropdown($key)
|
||||
{
|
||||
return $this->where('dropdown_key', $key)->set(['is_active' => 0])->update();
|
||||
}
|
||||
}
|
||||
62
app/Models/FlightModel.php
Normal file
62
app/Models/FlightModel.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class FlightModel extends Model
|
||||
{
|
||||
protected $table = 'c_flight';
|
||||
protected $primaryKey = 'flight_id';
|
||||
|
||||
protected $allowedFields = [
|
||||
'plan_id',
|
||||
'trip_type',
|
||||
'comments',
|
||||
'visa_available',
|
||||
'is_this_exceptional',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'is_active'
|
||||
];
|
||||
|
||||
protected $useTimestamps = false; // Manual timestamps as per the table design
|
||||
protected $createdField = 'created_on';
|
||||
protected $updatedField = 'updated_on';
|
||||
|
||||
// Get all active flight records
|
||||
public function getActiveFlights()
|
||||
{
|
||||
return $this->where('is_active', 1)->findAll();
|
||||
}
|
||||
|
||||
// Get a specific flight by ID
|
||||
public function getFlightById($flightId)
|
||||
{
|
||||
return $this->where('flight_id', $flightId)->first();
|
||||
}
|
||||
|
||||
// Get flights by plan ID
|
||||
public function getFlightsByPlanId($planId)
|
||||
{
|
||||
return $this->where('plan_id', $planId)->where('is_active', 1)->findAll();
|
||||
}
|
||||
|
||||
// Insert a new flight record
|
||||
public function insertFlight($data)
|
||||
{
|
||||
return $this->insert($data);
|
||||
}
|
||||
|
||||
// Update an existing flight record
|
||||
public function updateFlight($flightId, $data)
|
||||
{
|
||||
return $this->where('flight_id', $flightId)->set($data)->update();
|
||||
}
|
||||
|
||||
// Soft delete (deactivate) a flight record
|
||||
public function deactivateFlight($flightId)
|
||||
{
|
||||
return $this->where('flight_id', $flightId)->set(['is_active' => 0])->update();
|
||||
}
|
||||
}
|
||||
64
app/Models/FlightTripsModel.php
Normal file
64
app/Models/FlightTripsModel.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class FlightTripsModel extends Model
|
||||
{
|
||||
protected $table = 'cc_flight_trips';
|
||||
protected $primaryKey = 'flight_trip_id';
|
||||
|
||||
protected $allowedFields = [
|
||||
'flight_id',
|
||||
'class',
|
||||
'from_place',
|
||||
'to_place',
|
||||
'date',
|
||||
'time',
|
||||
'is_this_exceptional',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'is_active'
|
||||
];
|
||||
|
||||
protected $useTimestamps = false; // Manual timestamps as per the table design
|
||||
protected $createdField = 'created_on';
|
||||
protected $updatedField = 'updated_on';
|
||||
|
||||
// Get all active flight trips
|
||||
public function getActiveTrips()
|
||||
{
|
||||
return $this->where('is_active', 1)->findAll();
|
||||
}
|
||||
|
||||
// Get a specific flight trip by ID
|
||||
public function getTripById($tripId)
|
||||
{
|
||||
return $this->where('flight_trip_id', $tripId)->first();
|
||||
}
|
||||
|
||||
// Get trips by flight ID
|
||||
public function getTripsByFlightId($flightId)
|
||||
{
|
||||
return $this->where('flight_id', $flightId)->where('is_active', 1)->findAll();
|
||||
}
|
||||
|
||||
// Insert a new flight trip
|
||||
public function insertTrip($data)
|
||||
{
|
||||
return $this->insert($data);
|
||||
}
|
||||
|
||||
// Update an existing flight trip
|
||||
public function updateTrip($tripId, $data)
|
||||
{
|
||||
return $this->where('flight_trip_id', $tripId)->set($data)->update();
|
||||
}
|
||||
|
||||
// Soft delete (deactivate) a flight trip
|
||||
public function deactivateTrip($tripId)
|
||||
{
|
||||
return $this->where('flight_trip_id', $tripId)->set(['is_active' => 0])->update();
|
||||
}
|
||||
}
|
||||
26
app/Models/ForexModel.php
Normal file
26
app/Models/ForexModel.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class ForexModel extends Model
|
||||
{
|
||||
protected $table = 'c_forex';
|
||||
protected $primaryKey = 'forex_id';
|
||||
|
||||
|
||||
// Allowed fields for mass assignment
|
||||
protected $allowedFields = [
|
||||
'plan_id', 'start_date', 'end_date', 'country_code', 'duration', 'currency',
|
||||
'perdiem_amount', 'transport', 'accommodation', 'telephone', 'have_card',
|
||||
'card_number', 'deposit_on_card', 'deposit_on_cash', 'delivery_location',
|
||||
'comments', 'created_by', 'updated_by', 'is_active'
|
||||
];
|
||||
|
||||
protected $useTimestamps = false; // Manual timestamps as per the table design
|
||||
protected $createdField = 'created_on';
|
||||
protected $updatedField = 'updated_on';
|
||||
|
||||
|
||||
}
|
||||
28
app/Models/ForexPerdiemModel.php
Normal file
28
app/Models/ForexPerdiemModel.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class ForexPerdiemModel extends Model
|
||||
{
|
||||
protected $table = 'c_forex_perdiem';
|
||||
protected $primaryKey = 'forex_perdiem_id';
|
||||
protected $useAutoIncrement = true;
|
||||
protected $returnType = 'array';
|
||||
protected $allowedFields = [
|
||||
'country_code',
|
||||
'country_name',
|
||||
'currency',
|
||||
'perdiem_amount',
|
||||
'cash_percentage',
|
||||
'card_percentage',
|
||||
'is_active',
|
||||
'created_on',
|
||||
'created_by',
|
||||
'updated_on',
|
||||
'updated_by'
|
||||
];
|
||||
|
||||
|
||||
}
|
||||
33
app/Models/GroupModel.php
Normal file
33
app/Models/GroupModel.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class GroupModel extends Model
|
||||
{
|
||||
protected $table = 'm_group'; // Table name
|
||||
protected $primaryKey = 'group_id'; // Primary key
|
||||
|
||||
|
||||
|
||||
protected $allowedFields = [
|
||||
'name',
|
||||
'description',
|
||||
'domestic_policy_id',
|
||||
'international_policy_id',
|
||||
'created_on',
|
||||
'created_by',
|
||||
'updated_on',
|
||||
'updated_by',
|
||||
'is_active',
|
||||
'org_id'
|
||||
];
|
||||
|
||||
// Enable timestamps
|
||||
protected $useTimestamps = false; // Set true if you use created_at, updated_at
|
||||
protected $createdField = 'created_on'; // Custom created timestamp field
|
||||
protected $updatedField = 'updated_on'; // Custom updated timestamp field
|
||||
|
||||
|
||||
}
|
||||
26
app/Models/HotelModel.php
Normal file
26
app/Models/HotelModel.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class HotelModel extends Model
|
||||
{
|
||||
protected $table = 'm_hotels';
|
||||
protected $primaryKey = 'hotel_id';
|
||||
|
||||
protected $allowedFields = [
|
||||
'hotel_name',
|
||||
'hotel_chain',
|
||||
'country_code',
|
||||
'category',
|
||||
'city',
|
||||
'is_active',
|
||||
'created_on',
|
||||
'created_by',
|
||||
'updated_on',
|
||||
'updated_by'
|
||||
];
|
||||
|
||||
protected $useTimestamps = false;
|
||||
}
|
||||
45
app/Models/InsuranceModel.php
Normal file
45
app/Models/InsuranceModel.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class InsuranceModel extends Model
|
||||
{
|
||||
protected $table = 'c_insurance';
|
||||
protected $primaryKey = 'insurance_id';
|
||||
|
||||
protected $allowedFields = [
|
||||
'plan_id',
|
||||
'start_date',
|
||||
'end_date',
|
||||
'type_of_insurance',
|
||||
'comments',
|
||||
'nominee_name',
|
||||
'nominee_dob',
|
||||
'nominee_relationship',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'is_active'
|
||||
];
|
||||
|
||||
protected $useTimestamps = false;
|
||||
protected $createdField = 'created_on';
|
||||
protected $updatedField = 'updated_on';
|
||||
|
||||
/**
|
||||
* Get active insurance records
|
||||
*/
|
||||
public function getActiveInsurances()
|
||||
{
|
||||
return $this->where('is_active', 1)->findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get insurance records for a specific plan
|
||||
*/
|
||||
public function getInsurancesByPlan($planId)
|
||||
{
|
||||
return $this->where('plan_id', $planId)->findAll();
|
||||
}
|
||||
}
|
||||
28
app/Models/LevelModel.php
Normal file
28
app/Models/LevelModel.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class LevelModel extends Model
|
||||
{
|
||||
protected $table = 'm_level'; // Table name
|
||||
protected $primaryKey = 'level_id'; // Primary key
|
||||
|
||||
// Fields that can be mass assigned
|
||||
protected $allowedFields = [
|
||||
'code','name','description','org_id','policy_id','policy_name','int_policy_id','int_policy_name','group_travel','created_on','created_by','updated_on','updated_by','is_active',
|
||||
];
|
||||
|
||||
// Specify the return type of the results
|
||||
protected $returnType = 'array';
|
||||
|
||||
// Enable timestamps (if you wish to handle created_at and updated_at automatically)
|
||||
protected $useTimestamps = false; // Set true if using CI4 timestamp features
|
||||
|
||||
// Custom method example (e.g., fetching active levels)
|
||||
public function getActiveLevels()
|
||||
{
|
||||
return $this->where('is_active', 1)->findAll();
|
||||
}
|
||||
}
|
||||
34
app/Models/MailTemplateModel.php
Normal file
34
app/Models/MailTemplateModel.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class MailTemplateModel extends Model
|
||||
{
|
||||
protected $table = 'm_mail_template';
|
||||
protected $primaryKey = 'template_id';
|
||||
protected $useAutoIncrement = true;
|
||||
protected $returnType = 'array';
|
||||
protected $useSoftDeletes = false;
|
||||
|
||||
protected $allowedFields = [
|
||||
'org_id',
|
||||
'template_name',
|
||||
'subject',
|
||||
'body_html',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'is_active',
|
||||
'placeholder',
|
||||
];
|
||||
|
||||
protected $useTimestamps = true;
|
||||
protected $createdField = 'created_at';
|
||||
protected $updatedField = 'updated_at';
|
||||
|
||||
// Validation rules (optional)
|
||||
protected $validationRules = [
|
||||
'template_name' => 'required|max_length[45]',
|
||||
];
|
||||
}
|
||||
40
app/Models/MiscellaneousModel.php
Normal file
40
app/Models/MiscellaneousModel.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class MiscellaneousModel extends Model
|
||||
{
|
||||
protected $table = 'c_miscellaneous';
|
||||
protected $primaryKey = 'miscellaneous_id';
|
||||
|
||||
protected $allowedFields = [
|
||||
'plan_id',
|
||||
'special_request',
|
||||
'comments',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'is_active'
|
||||
];
|
||||
|
||||
protected $useTimestamps = false;
|
||||
protected $createdField = 'created_on';
|
||||
protected $updatedField = 'updated_on';
|
||||
|
||||
/**
|
||||
* Get active miscellaneous records
|
||||
*/
|
||||
public function getActiveMiscellaneous()
|
||||
{
|
||||
return $this->where('is_active', 1)->findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get miscellaneous records for a specific plan
|
||||
*/
|
||||
public function getMiscellaneousByPlan($planId)
|
||||
{
|
||||
return $this->where('plan_id', $planId)->findAll();
|
||||
}
|
||||
}
|
||||
50
app/Models/OrganizationModel.php
Normal file
50
app/Models/OrganizationModel.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class OrganizationModel extends Model
|
||||
{
|
||||
protected $table = 'm_organization';
|
||||
protected $primaryKey = 'org_id';
|
||||
protected $useAutoIncrement = true;
|
||||
protected $returnType = 'array';
|
||||
protected $useSoftDeletes = false;
|
||||
|
||||
protected $allowedFields = [
|
||||
'name',
|
||||
'logo',
|
||||
'sender_email',
|
||||
'mail_user_name',
|
||||
'mail_password',
|
||||
'mail_host',
|
||||
'mail_port',
|
||||
'layout_color',
|
||||
'color',
|
||||
'services_ids',
|
||||
'created_on',
|
||||
'created_by',
|
||||
'updated_on',
|
||||
'updated_by',
|
||||
'is_active'
|
||||
];
|
||||
|
||||
// Enable timestamps
|
||||
protected $useTimestamps = false; // Set true if you want CI4 to manage created_at/updated_at fields
|
||||
protected $createdField = 'created_on';
|
||||
protected $updatedField = 'updated_on';
|
||||
|
||||
// Validation rules (optional)
|
||||
protected $validationRules = [
|
||||
'name' => 'required|max_length[100]',
|
||||
'sender_email' => 'valid_email',
|
||||
'mail_port' => 'integer',
|
||||
'layout_color' => 'max_length[10]',
|
||||
'color' => 'max_length[10]',
|
||||
'is_active' => 'in_list[0,1]',
|
||||
];
|
||||
|
||||
protected $validationMessages = [];
|
||||
protected $skipValidation = true;
|
||||
}
|
||||
111
app/Models/PlanModel.php
Normal file
111
app/Models/PlanModel.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class PlanModel extends Model
|
||||
{
|
||||
protected $table = 'm_plan';
|
||||
protected $primaryKey = 'plan_id';
|
||||
|
||||
protected $allowedFields = [
|
||||
'user_id',
|
||||
'traveller_id',
|
||||
'trip_title',
|
||||
'trip_type',
|
||||
'cost_center_id',
|
||||
'is_billable',
|
||||
'purpose_of_travel',
|
||||
'description',
|
||||
'functional_department',
|
||||
'so_number',
|
||||
'status',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'is_active',
|
||||
'org_id',
|
||||
'pdf_file_path',
|
||||
'exceptional_plan_reason'
|
||||
];
|
||||
|
||||
protected $useTimestamps = false; // Manual timestamps as per the table design
|
||||
protected $createdField = 'created_on';
|
||||
protected $updatedField = 'updated_on';
|
||||
|
||||
// Get all active plans
|
||||
public function getActivePlan($org_id , $getBy = null , $user_id = null , $planIds = null)
|
||||
{
|
||||
$data = $this->select( 'm_plan.*,
|
||||
CONCAT_WS(" ", U.first_name, U.last_name) AS user_name,
|
||||
U.employee_code as employee_code,
|
||||
CONCAT_WS(" ", C.first_name, C.last_name) AS plan_created_by,
|
||||
CONCAT_WS(" ", T.first_name, T.last_name) AS traveller_name,
|
||||
TS.status_value,
|
||||
TT.dropdown_value as trip_type_value,
|
||||
IB.dropdown_value as is_billable_value,
|
||||
POT.dropdown_value as purpose_of_travel_value,
|
||||
FD.dropdown_value as functional_department_value,
|
||||
Dep.name as cost_center_value'
|
||||
)
|
||||
->join('m_users U', 'U.user_id = m_plan.user_id ', 'left')
|
||||
->join('m_users C', 'C.user_id = m_plan.created_by ', 'left')
|
||||
->join('m_traveller T', 'T.traveller_id = m_plan.traveller_id ', 'left')
|
||||
->join('m_travel_statuses TS', 'TS.id = m_plan.status ', 'left')
|
||||
->join('m_dropdown TT', 'TT.dropdown_key = m_plan.trip_type AND TT.dropdown = "plan_trip_type"', 'left')
|
||||
->join('m_dropdown IB', 'IB.dropdown_key = m_plan.is_billable AND IB.dropdown = "plan_is_billable"', 'left')
|
||||
->join('m_dropdown POT', 'POT.dropdown_key = m_plan.purpose_of_travel AND POT.dropdown = "plan_purpose_of_travel"', 'left')
|
||||
->join('m_dropdown FD', 'FD.dropdown_key = m_plan.functional_department AND FD.dropdown = "plan_functional_department"', 'left')
|
||||
->join('m_department Dep', 'Dep.department_id = m_plan.cost_center_id ', 'left')
|
||||
->where('m_plan.is_active', 1)->where('m_plan.org_id', $org_id);
|
||||
|
||||
if($getBy == 'ALL' || $getBy == null)
|
||||
{
|
||||
return $data->findAll();
|
||||
}
|
||||
else if($getBy == 'USER')
|
||||
{
|
||||
// return $data->where('m_plan.created_by', $user_id)->findAll();
|
||||
|
||||
return $data
|
||||
->groupStart()
|
||||
->where('m_plan.created_by', $user_id)
|
||||
->orWhere('m_plan.user_id', $user_id)
|
||||
->groupEnd()
|
||||
->findAll();
|
||||
}
|
||||
else if($getBy == 'PLAN')
|
||||
{
|
||||
return $data->where('m_plan.plan_id', $planIds)->first();
|
||||
}
|
||||
else if($getBy == 'APPROVAL')
|
||||
{
|
||||
return $data->whereIn('m_plan.plan_id', $planIds)->findAll();
|
||||
}
|
||||
else if($getBy == 'AGENT')
|
||||
{
|
||||
$data->whereIn('status',[3,5,6]);
|
||||
return $data->whereIn('m_plan.plan_id', $planIds)->findAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Insert a new travel plan
|
||||
public function insertPlan($data)
|
||||
{
|
||||
return $this->insert($data);
|
||||
}
|
||||
|
||||
// Update an existing plan
|
||||
public function updatePlan($planId, $data)
|
||||
{
|
||||
return $this->where('plan_id', $planId)->set($data)->update();
|
||||
}
|
||||
|
||||
// Soft delete (deactivate) a plan
|
||||
public function deactivatePlan($planId)
|
||||
{
|
||||
return $this->where('plan_id', $planId)->set(['is_active' => 0])->update();
|
||||
}
|
||||
}
|
||||
26
app/Models/PlanRemarkModel.php
Normal file
26
app/Models/PlanRemarkModel.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class PlanRemarkModel extends Model
|
||||
{
|
||||
protected $table = 'c_plan_remark';
|
||||
protected $primaryKey = 'id';
|
||||
protected $allowedFields = [
|
||||
'plan_id',
|
||||
'remarks',
|
||||
'created_on',
|
||||
'created_by',
|
||||
'updated_on',
|
||||
'updated_by',
|
||||
'is_active'
|
||||
];
|
||||
|
||||
protected $useTimestamps = true;
|
||||
protected $createdField = 'created_on';
|
||||
protected $updatedField = 'updated_on';
|
||||
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user