First Commit

This commit is contained in:
mikael-zakaria 2025-08-15 11:38:41 +07:00
parent fd7948d4fb
commit e79a923290
457 changed files with 7255 additions and 77258 deletions

130
.gitignore vendored
View File

@ -1,4 +1,126 @@
/* #-------------------------
!app/ # Operating Specific Junk Files
!public/ #-------------------------
!.gitignore
# OS X
.DS_Store
.AppleDouble
.LSOverride
# OS X Thumbnails
._*
# Windows image file caches
Thumbs.db
ehthumbs.db
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
# Linux
*~
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
#-------------------------
# Environment Files
#-------------------------
# These should never be under version control,
# as it poses a security risk.
.env
.vagrant
Vagrantfile
#-------------------------
# Temporary Files
#-------------------------
writable/cache/*
!writable/cache/index.html
writable/logs/*
!writable/logs/index.html
writable/session/*
!writable/session/index.html
writable/uploads/*
!writable/uploads/index.html
writable/debugbar/*
!writable/debugbar/index.html
php_errors.log
#-------------------------
# User Guide Temp Files
#-------------------------
user_guide_src/build/*
user_guide_src/cilexer/build/*
user_guide_src/cilexer/dist/*
user_guide_src/cilexer/pycilexer.egg-info/*
#-------------------------
# Test Files
#-------------------------
tests/coverage*
# Don't save phpunit under version control.
phpunit
#-------------------------
# Composer
#-------------------------
vendor/
#-------------------------
# IDE / Development Files
#-------------------------
# Modules Testing
_modules/*
# phpenv local config
.php-version
# Jetbrains editors (PHPStorm, etc)
.idea/
*.iml
# NetBeans
/nbproject/
/build/
/nbbuild/
/dist/
/nbdist/
/nbactions.xml
/nb-configuration.xml
/.nb-gradle/
# Sublime Text
*.tmlanguage.cache
*.tmPreferences.cache
*.stTheme.cache
*.sublime-workspace
*.sublime-project
.phpintel
/api/
# Visual Studio Code
.vscode/
/results/
/phpunit*.xml

View File

@ -1,6 +1,7 @@
MIT License The MIT License (MIT)
Copyright (c) 2022 Ephox Corporation DBA Tiny Technologies, Inc. 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 Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@ -9,13 +10,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in
copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
SOFTWARE. THE SOFTWARE.

68
README.md Normal file
View File

@ -0,0 +1,68 @@
# CodeIgniter 4 Application Starter
## 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 a composer-installable app starter.
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.
## Installation & updates
`composer create-project codeigniter4/appstarter` then `composer update` whenever
there is a new release of the framework.
When updating, check the release notes to see if there are any changes you might need to apply
to your `app` folder. The affected files can be copied or merged from
`vendor/codeigniter4/framework/app`.
## Setup
Copy `env` to `.env` and tailor for your app, specifically the baseURL
and any database settings.
## 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.
## 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

View File

@ -4,12 +4,12 @@
* The goal of this file is to allow developers a location * The goal of this file is to allow developers a location
* where they can overwrite core procedural functions and * where they can overwrite core procedural functions and
* replace them with their own. This file is loaded during * replace them with their own. This file is loaded during
* the bootstrap process and is called during the frameworks * the bootstrap process and is called during the framework's
* execution. * execution.
* *
* This can be looked at as a `master helper` file that is * This can be looked at as a `master helper` file that is
* loaded early on, and may also contain additional functions * loaded early on, and may also contain additional functions
* that you'd like to use throughout your entire application * that you'd like to use throughout your entire application
* *
* @see: https://codeigniter4.github.io/CodeIgniter4/ * @see: https://codeigniter.com/user_guide/extending/common.html
*/ */

View File

@ -3,7 +3,6 @@
namespace Config; namespace Config;
use CodeIgniter\Config\BaseConfig; use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Session\Handlers\FileHandler;
class App extends BaseConfig class App extends BaseConfig
{ {
@ -12,34 +11,36 @@ class App extends BaseConfig
* Base Site URL * Base Site URL
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* *
* URL to your CodeIgniter root. Typically this will be your base URL, * URL to your CodeIgniter root. Typically, this will be your base URL,
* WITH a trailing slash: * WITH a trailing slash:
* *
* http://example.com/ * E.g., http://example.com/
*
* If this is not set then CodeIgniter will try guess the protocol, domain
* and path to your installation. However, you should always configure this
* explicitly and never rely on auto-guessing, especially in production
* environments.
*
* @var string
*/ */
//public $baseURL = 'http://localhost:8080/'; public string $baseURL = 'http://localhost:8080/';
public $baseURL = '';
/**
* 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 * Index File
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* *
* Typically this will be your index.php file, unless you've renamed it to * Typically, this will be your `index.php` file, unless you've renamed it to
* something else. If you are using mod_rewrite to remove the page set this * something else. If you have configured your web server to remove this file
* variable so that it is blank. * from your site URIs, set this variable to an empty string.
*
* @var string
*/ */
//public $indexPage = 'index.php'; public string $indexPage = 'index.php';
public $indexPage = '';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -50,15 +51,37 @@ class App extends BaseConfig
* URI string. The default setting of 'REQUEST_URI' works for most servers. * 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: * If your links do not seem to work, try one of the other delicious flavors:
* *
* 'REQUEST_URI' Uses $_SERVER['REQUEST_URI'] * 'REQUEST_URI': Uses $_SERVER['REQUEST_URI']
* 'QUERY_STRING' Uses $_SERVER['QUERY_STRING'] * 'QUERY_STRING': Uses $_SERVER['QUERY_STRING']
* 'PATH_INFO' Uses $_SERVER['PATH_INFO'] * 'PATH_INFO': Uses $_SERVER['PATH_INFO']
* *
* WARNING: If you set this to 'PATH_INFO', URIs will always be URL-decoded! * WARNING: If you set this to 'PATH_INFO', URIs will always be URL-decoded!
*
* @var string
*/ */
public $uriProtocol = 'REQUEST_URI'; 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~%.:_\-';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -69,10 +92,8 @@ class App extends BaseConfig
* is viewing the site from. It affects the language strings and other * is viewing the site from. It affects the language strings and other
* strings (like currency markers, numbers, etc), that your program * strings (like currency markers, numbers, etc), that your program
* should run under for this request. * should run under for this request.
*
* @var string
*/ */
public $defaultLocale = 'en'; public string $defaultLocale = 'en';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -83,10 +104,8 @@ class App extends BaseConfig
* language to use based on the value of the Accept-Language header. * language to use based on the value of the Accept-Language header.
* *
* If false, no automatic detection will be performed. * If false, no automatic detection will be performed.
*
* @var bool
*/ */
public $negotiateLocale = false; public bool $negotiateLocale = false;
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -97,9 +116,11 @@ class App extends BaseConfig
* by the application in descending order of priority. If no match is * by the application in descending order of priority. If no match is
* found, the first locale will be used. * found, the first locale will be used.
* *
* @var string[] * IncomingRequest::setLocale() also uses this list.
*
* @var list<string>
*/ */
public $supportedLocales = ['en']; public array $supportedLocales = ['en'];
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -109,9 +130,10 @@ class App extends BaseConfig
* The default timezone that will be used in your application to display * The default timezone that will be used in your application to display
* dates with the date helper, and can be retrieved through app_timezone() * dates with the date helper, and can be retrieved through app_timezone()
* *
* @var string * @see https://www.php.net/manual/en/timezones.php for list of timezones
* supported by PHP.
*/ */
public $appTimezone = 'Asia/Jakarta'; public string $appTimezone = 'UTC';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -122,211 +144,20 @@ class App extends BaseConfig
* that require a character set to be provided. * that require a character set to be provided.
* *
* @see http://php.net/htmlspecialchars for a list of supported charsets. * @see http://php.net/htmlspecialchars for a list of supported charsets.
*
* @var string
*/ */
public $charset = 'UTF-8'; public string $charset = 'UTF-8';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* URI PROTOCOL * Force Global Secure Requests
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* *
* If true, this will force every request made to this application to be * 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 * 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 * secure, the user will be redirected to a secure version of the page
* and the HTTP Strict Transport Security header will be set. * and the HTTP Strict Transport Security (HSTS) header will be set.
*
* @var bool
*/ */
public $forceGlobalSecureRequests = false; public bool $forceGlobalSecureRequests = false;
/**
* --------------------------------------------------------------------------
* 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 string
*/
public $sessionDriver = FileHandler::class;
/**
* --------------------------------------------------------------------------
* Session Cookie Name
* --------------------------------------------------------------------------
*
* The session cookie name, must contain only [0-9a-z_-] characters
*
* @var string
*/
public $sessionCookieName = '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.
*
* @var int
*/
//public $sessionExpiration = 7200;
public $sessionExpiration = 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!
*
* @var string
*/
public $sessionSavePath = 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.
*
* @var bool
*/
public $sessionMatchIP = false;
/**
* --------------------------------------------------------------------------
* Session Time to Update
* --------------------------------------------------------------------------
*
* How many seconds between CI regenerating the session ID.
*
* @var int
*/
public $sessionTimeToUpdate = 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.
*
* @var bool
*/
public $sessionRegenerateDestroy = false;
/**
* --------------------------------------------------------------------------
* Cookie Prefix
* --------------------------------------------------------------------------
*
* Set a cookie name prefix if you need to avoid collisions.
*
* @var string
*
* @deprecated use Config\Cookie::$prefix property instead.
*/
public $cookiePrefix = '';
/**
* --------------------------------------------------------------------------
* Cookie Domain
* --------------------------------------------------------------------------
*
* Set to `.your-domain.com` for site-wide cookies.
*
* @var string
*
* @deprecated use Config\Cookie::$domain property instead.
*/
public $cookieDomain = '';
/**
* --------------------------------------------------------------------------
* Cookie Path
* --------------------------------------------------------------------------
*
* Typically will be a forward slash.
*
* @var string
*
* @deprecated use Config\Cookie::$path property instead.
*/
public $cookiePath = '/';
/**
* --------------------------------------------------------------------------
* Cookie Secure
* --------------------------------------------------------------------------
*
* Cookie will only be set if a secure HTTPS connection exists.
*
* @var bool
*
* @deprecated use Config\Cookie::$secure property instead.
*/
public $cookieSecure = false;
/**
* --------------------------------------------------------------------------
* Cookie HttpOnly
* --------------------------------------------------------------------------
*
* Cookie will only be accessible via HTTP(S) (no JavaScript).
*
* @var bool
*
* @deprecated use Config\Cookie::$httponly property instead.
*/
public $cookieHTTPOnly = 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`, `$cookieSecure` must also be set.
*
* @var string|null
*
* @deprecated use Config\Cookie::$samesite property instead.
*/
public $cookieSameSite = 'Lax';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -335,117 +166,21 @@ class App extends BaseConfig
* *
* If your server is behind a reverse proxy, you must whitelist the proxy * If your server is behind a reverse proxy, you must whitelist the proxy
* IP addresses from which CodeIgniter should trust headers such as * IP addresses from which CodeIgniter should trust headers such as
* HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify * X-Forwarded-For or Client-IP in order to properly identify
* the visitor's IP address. * the visitor's IP address.
* *
* You can use both an array or a comma-separated list of proxy addresses, * You need to set a proxy IP address or IP address with subnets and
* as well as specifying whole subnets. Here are a few examples: * the HTTP header for the client IP address.
* *
* Comma-separated: '10.0.1.200,192.168.5.0/24' * Here are some examples:
* Array: ['10.0.1.200', '192.168.5.0/24'] * [
* '10.0.1.200' => 'X-Forwarded-For',
* '192.168.5.0/24' => 'X-Real-IP',
* ]
* *
* @var string|string[] * @var array<string, string>
*/ */
public $proxyIPs = ''; public array $proxyIPs = [];
/**
* --------------------------------------------------------------------------
* CSRF Token Name
* --------------------------------------------------------------------------
*
* The token name.
*
* @deprecated Use `Config\Security` $tokenName property instead of using this property.
*
* @var string
*/
public $CSRFTokenName = 'csrf_test_name';
/**
* --------------------------------------------------------------------------
* CSRF Header Name
* --------------------------------------------------------------------------
*
* The header name.
*
* @deprecated Use `Config\Security` $headerName property instead of using this property.
*
* @var string
*/
public $CSRFHeaderName = 'X-CSRF-TOKEN';
/**
* --------------------------------------------------------------------------
* CSRF Cookie Name
* --------------------------------------------------------------------------
*
* The cookie name.
*
* @deprecated Use `Config\Security` $cookieName property instead of using this property.
*
* @var string
*/
public $CSRFCookieName = 'csrf_cookie_name';
/**
* --------------------------------------------------------------------------
* CSRF Expire
* --------------------------------------------------------------------------
*
* The number in seconds the token should expire.
*
* @deprecated Use `Config\Security` $expire property instead of using this property.
*
* @var int
*/
public $CSRFExpire = 7200;
/**
* --------------------------------------------------------------------------
* CSRF Regenerate
* --------------------------------------------------------------------------
*
* Regenerate token on every submission?
*
* @deprecated Use `Config\Security` $regenerate property instead of using this property.
*
* @var bool
*/
public $CSRFRegenerate = true;
/**
* --------------------------------------------------------------------------
* CSRF Redirect
* --------------------------------------------------------------------------
*
* Redirect to previous page with error on failure?
*
* @deprecated Use `Config\Security` $redirect property instead of using this property.
*
* @var bool
*/
public $CSRFRedirect = true;
/**
* --------------------------------------------------------------------------
* CSRF SameSite
* --------------------------------------------------------------------------
*
* Setting for CSRF SameSite cookie token. Allowed values are:
* - None
* - Lax
* - Strict
* - ''
*
* Defaults to `Lax` as recommended in this link:
*
* @see https://portswigger.net/web-security/csrf/samesite-cookies
*
* @deprecated `Config\Cookie` $samesite property is used.
*
* @var string
*/
public $CSRFSameSite = 'Lax';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -462,8 +197,6 @@ class App extends BaseConfig
* *
* @see http://www.html5rocks.com/en/tutorials/security/content-security-policy/ * @see http://www.html5rocks.com/en/tutorials/security/content-security-policy/
* @see http://www.w3.org/TR/CSP/ * @see http://www.w3.org/TR/CSP/
*
* @var bool
*/ */
public $CSPEnabled = false; public bool $CSPEnabled = false;
} }

View File

@ -14,6 +14,9 @@ use CodeIgniter\Config\AutoloadConfig;
* *
* NOTE: If you use an identical key in $psr4 or $classmap, then * NOTE: If you use an identical key in $psr4 or $classmap, then
* the values in this file will overwrite the framework's values. * 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.
*/ */
class Autoload extends AutoloadConfig class Autoload extends AutoloadConfig
{ {
@ -25,24 +28,17 @@ class Autoload extends AutoloadConfig
* their location on the file system. These are used by the autoloader * their location on the file system. These are used by the autoloader
* to locate files the first time they have been instantiated. * to locate files the first time they have been instantiated.
* *
* The '/app' and '/system' directories are already mapped for you. * The 'Config' (APPPATH . 'Config') and 'CodeIgniter' (SYSTEMPATH) are
* you may change the name of the 'App' namespace if you wish, * 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, * 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. * else you will need to modify all of those classes for this to work.
* *
* Prototype: * @var array<string, list<string>|string>
*```
* $psr4 = [
* 'CodeIgniter' => SYSTEMPATH,
* 'App' => APPPATH
* ];
*```
*
* @var array<string, string>
*/ */
public $psr4 = [ public $psr4 = [
APP_NAMESPACE => APPPATH, // For custom app namespace APP_NAMESPACE => APPPATH,
'Config' => APPPATH . 'Config',
]; ];
/** /**
@ -56,11 +52,9 @@ class Autoload extends AutoloadConfig
* were being autoloaded through a namespace. * were being autoloaded through a namespace.
* *
* Prototype: * Prototype:
*```
* $classmap = [ * $classmap = [
* 'MyClass' => '/path/to/class/file.php' * 'MyClass' => '/path/to/class/file.php'
* ]; * ];
*```
* *
* @var array<string, string> * @var array<string, string>
*/ */
@ -75,13 +69,24 @@ class Autoload extends AutoloadConfig
* or for loading functions. * or for loading functions.
* *
* Prototype: * Prototype:
* ```
* $files = [ * $files = [
* '/path/to/my/file.php', * '/path/to/my/file.php',
* ]; * ];
* ```
* *
* @var array<int, string> * @var list<string>
*/ */
public $files = []; public $files = [];
/**
* -------------------------------------------------------------------
* Helpers
* -------------------------------------------------------------------
* Prototype:
* $helpers = [
* 'form',
* ];
*
* @var list<string>
*/
public $helpers = [];
} }

View File

@ -7,8 +7,10 @@
| In development, we want to show as many errors as possible to help | 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 | make sure they don't make it to production. And save us hours of
| painful debugging. | painful debugging.
|
| If you set 'display_errors' to '1', CI4's detailed error report will show.
*/ */
error_reporting(-1); error_reporting(E_ALL);
ini_set('display_errors', '1'); ini_set('display_errors', '1');
/* /*

View File

@ -6,9 +6,13 @@
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Don't show ANY in production environments. Instead, let the system catch | Don't show ANY in production environments. Instead, let the system catch
| it and display a generic error message. | 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'); ini_set('display_errors', '0');
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED);
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------

View File

@ -1,5 +1,11 @@
<?php <?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 cant use it for your development.
*/
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| ERROR DISPLAY | ERROR DISPLAY
@ -8,7 +14,7 @@
| make sure they don't make it to production. And save us hours of | make sure they don't make it to production. And save us hours of
| painful debugging. | painful debugging.
*/ */
error_reporting(-1); error_reporting(E_ALL);
ini_set('display_errors', '1'); ini_set('display_errors', '1');
/* /*

View File

@ -15,8 +15,6 @@ class CURLRequest extends BaseConfig
* *
* If true, all the options won't be reset between requests. * If true, all the options won't be reset between requests.
* It may cause an error request with unnecessary headers. * It may cause an error request with unnecessary headers.
*
* @var bool
*/ */
public $shareOptions = true; public bool $shareOptions = false;
} }

View File

@ -2,6 +2,7 @@
namespace Config; namespace Config;
use CodeIgniter\Cache\CacheInterface;
use CodeIgniter\Cache\Handlers\DummyHandler; use CodeIgniter\Cache\Handlers\DummyHandler;
use CodeIgniter\Cache\Handlers\FileHandler; use CodeIgniter\Cache\Handlers\FileHandler;
use CodeIgniter\Cache\Handlers\MemcachedHandler; use CodeIgniter\Cache\Handlers\MemcachedHandler;
@ -19,10 +20,8 @@ class Cache extends BaseConfig
* *
* The name of the preferred handler that should be used. If for some reason * 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. * it is not available, the $backupHandler will be used in its place.
*
* @var string
*/ */
public $handler = 'file'; public string $handler = 'file';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -32,43 +31,8 @@ class Cache extends BaseConfig
* The name of the handler that will be used in case the first one is * 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 * unreachable. Often, 'file' is used here since the filesystem is
* always available, though that's not always practical for the app. * always available, though that's not always practical for the app.
*
* @var string
*/ */
public $backupHandler = 'dummy'; public string $backupHandler = 'dummy';
/**
* --------------------------------------------------------------------------
* Cache Directory Path
* --------------------------------------------------------------------------
*
* The path to where cache files should be stored, if using a file-based
* system.
*
* @var string
*
* @deprecated Use the driver-specific variant under $file
*/
public $storePath = WRITEPATH . 'cache/';
/**
* --------------------------------------------------------------------------
* Cache Include Query String
* --------------------------------------------------------------------------
*
* Whether to take the URL query string into consideration when generating
* output cache files. Valid options are:
*
* false = Disabled
* true = Enabled, take all query parameters into account.
* Please be aware that this may result in numerous cache
* files generated for the same page over and over again.
* array('q') = Enabled, but only take into account the specified list
* of query parameters.
*
* @var bool|string[]
*/
public $cacheQueryString = false;
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -77,10 +41,8 @@ class Cache extends BaseConfig
* *
* This string is added to all cache item names to help avoid collisions * This string is added to all cache item names to help avoid collisions
* if you run multiple applications with the same cache engine. * if you run multiple applications with the same cache engine.
*
* @var string
*/ */
public $prefix = ''; public string $prefix = '';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -92,10 +54,8 @@ class Cache extends BaseConfig
* WARNING: This is not used by framework handlers where 60 seconds is * 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 * hard-coded, but may be useful to projects and modules. This will replace
* the hard-coded value in a future release. * the hard-coded value in a future release.
*
* @var int
*/ */
public $ttl = 60; public int $ttl = 60;
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -105,22 +65,22 @@ class Cache extends BaseConfig
* A string of reserved characters that will not be allowed in keys or tags. * A string of reserved characters that will not be allowed in keys or tags.
* Strings that violate this restriction will cause handlers to throw. * Strings that violate this restriction will cause handlers to throw.
* Default: {}()/\@: * Default: {}()/\@:
* Note: The default set is required for PSR-6 compliance.
* *
* @var string * NOTE: The default set is required for PSR-6 compliance.
*/ */
public $reservedCharacters = '{}()/\@:'; public string $reservedCharacters = '{}()/\@:';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* File settings * File settings
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*
* Your file storage preferences can be specified below, if you are using * Your file storage preferences can be specified below, if you are using
* the File driver. * the File driver.
* *
* @var array<string, int|string|null> * @var array{storePath?: string, mode?: int}
*/ */
public $file = [ public array $file = [
'storePath' => WRITEPATH . 'cache/', 'storePath' => WRITEPATH . 'cache/',
'mode' => 0640, 'mode' => 0640,
]; ];
@ -129,14 +89,15 @@ class Cache extends BaseConfig
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* Memcached settings * Memcached settings
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
*
* Your Memcached servers can be specified below, if you are using * Your Memcached servers can be specified below, if you are using
* the Memcached drivers. * the Memcached drivers.
* *
* @see https://codeigniter.com/user_guide/libraries/caching.html#memcached * @see https://codeigniter.com/user_guide/libraries/caching.html#memcached
* *
* @var array<string, boolean|int|string> * @var array{host?: string, port?: int, weight?: int, raw?: bool}
*/ */
public $memcached = [ public array $memcached = [
'host' => '127.0.0.1', 'host' => '127.0.0.1',
'port' => 11211, 'port' => 11211,
'weight' => 1, 'weight' => 1,
@ -147,12 +108,13 @@ class Cache extends BaseConfig
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* Redis settings * Redis settings
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
*
* Your Redis server can be specified below, if you are using * Your Redis server can be specified below, if you are using
* the Redis or Predis drivers. * the Redis or Predis drivers.
* *
* @var array<string, int|string|null> * @var array{host?: string, password?: string|null, port?: int, timeout?: int, database?: int}
*/ */
public $redis = [ public array $redis = [
'host' => '127.0.0.1', 'host' => '127.0.0.1',
'password' => null, 'password' => null,
'port' => 6379, 'port' => 6379,
@ -168,9 +130,9 @@ class Cache extends BaseConfig
* This is an array of cache engine alias' and class names. Only engines * This is an array of cache engine alias' and class names. Only engines
* that are listed here are allowed to be used. * that are listed here are allowed to be used.
* *
* @var array<string, string> * @var array<string, class-string<CacheInterface>>
*/ */
public $validHandlers = [ public array $validHandlers = [
'dummy' => DummyHandler::class, 'dummy' => DummyHandler::class,
'file' => FileHandler::class, 'file' => FileHandler::class,
'memcached' => MemcachedHandler::class, 'memcached' => MemcachedHandler::class,
@ -178,4 +140,23 @@ class Cache extends BaseConfig
'redis' => RedisHandler::class, 'redis' => RedisHandler::class,
'wincache' => WincacheHandler::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;
} }

View File

@ -77,18 +77,3 @@ defined('EXIT_USER_INPUT') || define('EXIT_USER_INPUT', 7); // invalid u
defined('EXIT_DATABASE') || define('EXIT_DATABASE', 8); // database error 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_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 defined('EXIT__AUTO_MAX') || define('EXIT__AUTO_MAX', 125); // highest automatically-assigned error code
/**
* @deprecated Use \CodeIgniter\Events\Events::PRIORITY_LOW instead.
*/
define('EVENT_PRIORITY_LOW', 200);
/**
* @deprecated Use \CodeIgniter\Events\Events::PRIORITY_NORMAL instead.
*/
define('EVENT_PRIORITY_NORMAL', 100);
/**
* @deprecated Use \CodeIgniter\Events\Events::PRIORITY_HIGH instead.
*/
define('EVENT_PRIORITY_HIGH', 10);

View File

@ -21,58 +21,52 @@ class ContentSecurityPolicy extends BaseConfig
/** /**
* Default CSP report context * Default CSP report context
*
* @var bool
*/ */
public $reportOnly = false; public bool $reportOnly = false;
/** /**
* Specifies a URL where a browser will send reports * Specifies a URL where a browser will send reports
* when a content security policy is violated. * when a content security policy is violated.
*
* @var string|null
*/ */
public $reportURI; public ?string $reportURI = null;
/** /**
* Instructs user agents to rewrite URL schemes, changing * Instructs user agents to rewrite URL schemes, changing
* HTTP to HTTPS. This directive is for websites with * HTTP to HTTPS. This directive is for websites with
* large numbers of old URLs that need to be rewritten. * large numbers of old URLs that need to be rewritten.
*
* @var bool
*/ */
public $upgradeInsecureRequests = false; public bool $upgradeInsecureRequests = false;
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Sources allowed // Sources allowed
// Note: once you set a policy to 'none', it cannot be further restricted // NOTE: once you set a policy to 'none', it cannot be further restricted
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** /**
* Will default to self if not overridden * Will default to self if not overridden
* *
* @var string|string[]|null * @var list<string>|string|null
*/ */
public $defaultSrc; public $defaultSrc;
/** /**
* Lists allowed scripts' URLs. * Lists allowed scripts' URLs.
* *
* @var string|string[] * @var list<string>|string
*/ */
public $scriptSrc = 'self'; public $scriptSrc = 'self';
/** /**
* Lists allowed stylesheets' URLs. * Lists allowed stylesheets' URLs.
* *
* @var string|string[] * @var list<string>|string
*/ */
public $styleSrc = 'self'; public $styleSrc = 'self';
/** /**
* Defines the origins from which images can be loaded. * Defines the origins from which images can be loaded.
* *
* @var string|string[] * @var list<string>|string
*/ */
public $imageSrc = 'self'; public $imageSrc = 'self';
@ -81,14 +75,14 @@ class ContentSecurityPolicy extends BaseConfig
* *
* Will default to self if not overridden * Will default to self if not overridden
* *
* @var string|string[]|null * @var list<string>|string|null
*/ */
public $baseURI; public $baseURI;
/** /**
* Lists the URLs for workers and embedded frame contents * Lists the URLs for workers and embedded frame contents
* *
* @var string|string[] * @var list<string>|string
*/ */
public $childSrc = 'self'; public $childSrc = 'self';
@ -96,21 +90,21 @@ class ContentSecurityPolicy extends BaseConfig
* Limits the origins that you can connect to (via XHR, * Limits the origins that you can connect to (via XHR,
* WebSockets, and EventSource). * WebSockets, and EventSource).
* *
* @var string|string[] * @var list<string>|string
*/ */
public $connectSrc = 'self'; public $connectSrc = 'self';
/** /**
* Specifies the origins that can serve web fonts. * Specifies the origins that can serve web fonts.
* *
* @var string|string[] * @var list<string>|string
*/ */
public $fontSrc; public $fontSrc;
/** /**
* Lists valid endpoints for submission from `<form>` tags. * Lists valid endpoints for submission from `<form>` tags.
* *
* @var string|string[] * @var list<string>|string
*/ */
public $formAction = 'self'; public $formAction = 'self';
@ -120,7 +114,7 @@ class ContentSecurityPolicy extends BaseConfig
* and `<applet>` tags. This directive can't be used in * and `<applet>` tags. This directive can't be used in
* `<meta>` tags and applies only to non-HTML resources. * `<meta>` tags and applies only to non-HTML resources.
* *
* @var string|string[]|null * @var list<string>|string|null
*/ */
public $frameAncestors; public $frameAncestors;
@ -128,61 +122,55 @@ class ContentSecurityPolicy extends BaseConfig
* The frame-src directive restricts the URLs which may * The frame-src directive restricts the URLs which may
* be loaded into nested browsing contexts. * be loaded into nested browsing contexts.
* *
* @var array|string|null * @var list<string>|string|null
*/ */
public $frameSrc; public $frameSrc;
/** /**
* Restricts the origins allowed to deliver video and audio. * Restricts the origins allowed to deliver video and audio.
* *
* @var string|string[]|null * @var list<string>|string|null
*/ */
public $mediaSrc; public $mediaSrc;
/** /**
* Allows control over Flash and other plugins. * Allows control over Flash and other plugins.
* *
* @var string|string[] * @var list<string>|string
*/ */
public $objectSrc = 'self'; public $objectSrc = 'self';
/** /**
* @var string|string[]|null * @var list<string>|string|null
*/ */
public $manifestSrc; public $manifestSrc;
/** /**
* Limits the kinds of plugins a page may invoke. * Limits the kinds of plugins a page may invoke.
* *
* @var string|string[]|null * @var list<string>|string|null
*/ */
public $pluginTypes; public $pluginTypes;
/** /**
* List of actions allowed. * List of actions allowed.
* *
* @var string|string[]|null * @var list<string>|string|null
*/ */
public $sandbox; public $sandbox;
/** /**
* Nonce tag for style * Nonce tag for style
*
* @var string
*/ */
public $styleNonceTag = '{csp-style-nonce}'; public string $styleNonceTag = '{csp-style-nonce}';
/** /**
* Nonce tag for script * Nonce tag for script
*
* @var string
*/ */
public $scriptNonceTag = '{csp-script-nonce}'; public string $scriptNonceTag = '{csp-script-nonce}';
/** /**
* Replace nonce tag automatically * Replace nonce tag automatically
*
* @var bool
*/ */
public $autoNonce = true; public bool $autoNonce = true;
} }

View File

@ -13,10 +13,8 @@ class Cookie extends BaseConfig
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* *
* Set a cookie name prefix if you need to avoid collisions. * Set a cookie name prefix if you need to avoid collisions.
*
* @var string
*/ */
public $prefix = 'ci4_'; public string $prefix = '';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -37,10 +35,8 @@ class Cookie extends BaseConfig
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* *
* Typically will be a forward slash. * Typically will be a forward slash.
*
* @var string
*/ */
public $path = '/'; public string $path = '/';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -48,10 +44,8 @@ class Cookie extends BaseConfig
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* *
* Set to `.your-domain.com` for site-wide cookies. * Set to `.your-domain.com` for site-wide cookies.
*
* @var string
*/ */
public $domain = ''; public string $domain = '';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -59,10 +53,8 @@ class Cookie extends BaseConfig
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* *
* Cookie will only be set if a secure HTTPS connection exists. * Cookie will only be set if a secure HTTPS connection exists.
*
* @var bool
*/ */
public $secure = false; public bool $secure = false;
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -70,11 +62,8 @@ class Cookie extends BaseConfig
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* *
* Cookie will only be accessible via HTTP(S) (no JavaScript). * Cookie will only be accessible via HTTP(S) (no JavaScript).
*
* @var bool
*/ */
//public $httponly = true; public bool $httponly = true;
public $httponly = false;
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -96,9 +85,9 @@ class Cookie extends BaseConfig
* (empty string) means default SameSite attribute set by browsers (`Lax`) * (empty string) means default SameSite attribute set by browsers (`Lax`)
* will be set on cookies. If set to `None`, `$secure` must also be set. * will be set on cookies. If set to `None`, `$secure` must also be set.
* *
* @var string * @var ''|'Lax'|'None'|'Strict'
*/ */
public $samesite = 'Lax'; public string $samesite = 'Lax';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -111,10 +100,8 @@ class Cookie extends BaseConfig
* If this is set to `true`, cookie names should be compliant of RFC 2616's * If this is set to `true`, cookie names should be compliant of RFC 2616's
* list of allowed characters. * list of allowed characters.
* *
* @var bool
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#attributes * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#attributes
* @see https://tools.ietf.org/html/rfc2616#section-2.2 * @see https://tools.ietf.org/html/rfc2616#section-2.2
*/ */
public $raw = false; public bool $raw = false;
} }

105
app/Config/Cors.php Normal file
View 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,
];
}

View File

@ -1,19 +0,0 @@
<?php
namespace Config;
class CustomValidation{
public function validateLogin(string $str, string $fields, array $data){
$email = $data['email'];
$db = \Config\Database::connect();
$sql = "SELECT userid, password FROM users WHERE email_1='$email'";
$query = $db->query($sql);
$user = $query->getRow();
if(!$user) return false;
return password_verify($data['password'], $user->password );
}
}

View File

@ -10,54 +10,159 @@ use CodeIgniter\Database\Config;
class Database extends Config class Database extends Config
{ {
/** /**
* The directory that holds the Migrations * The directory that holds the Migrations and Seeds directories.
* and Seeds directories.
*
* @var string
*/ */
public $filesPath = APPPATH . 'Database' . DIRECTORY_SEPARATOR; public string $filesPath = APPPATH . 'Database' . DIRECTORY_SEPARATOR;
/** /**
* Lets you choose which connection group to * Lets you choose which connection group to use if no other is specified.
* use if no other is specified.
*
* @var string
*/ */
public $defaultGroup = 'default'; public string $defaultGroup = 'default';
/** /**
* The default database connection. * The default database connection.
* *
* @var array * @var array<string, mixed>
*/ */
public $default = [ public array $default = [
'DSN' => '', 'DSN' => '',
'hostname' => 'localhost', 'hostname' => 'localhost',
'username' => 'root', 'username' => '',
'password' => '', 'password' => '',
'database' => 'crm', 'database' => '',
'DBDriver' => 'MySQLi', 'DBDriver' => 'MySQLi',
'DBPrefix' => '', 'DBPrefix' => '',
'pConnect' => false, 'pConnect' => false,
//'DBDebug' => (ENVIRONMENT !== 'production'),
'DBDebug' => true, 'DBDebug' => true,
'charset' => 'utf8', 'charset' => 'utf8mb4',
'DBCollat' => 'utf8_general_ci', 'DBCollat' => 'utf8mb4_general_ci',
'swapPre' => '', 'swapPre' => '',
'encrypt' => false, 'encrypt' => false,
'compress' => false, 'compress' => false,
'strictOn' => false, 'strictOn' => false,
'failover' => [], 'failover' => [],
'port' => 3306, '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 * This database connection is used when running PHPUnit database tests.
* running PHPUnit database tests.
* *
* @var array * @var array<string, mixed>
*/ */
public $tests = [ public array $tests = [
'DSN' => '', 'DSN' => '',
'hostname' => '127.0.0.1', 'hostname' => '127.0.0.1',
'username' => '', 'username' => '',
@ -66,10 +171,9 @@ class Database extends Config
'DBDriver' => 'SQLite3', 'DBDriver' => 'SQLite3',
'DBPrefix' => 'db_', // Needed to ensure we're working correctly with prefixes live. DO NOT REMOVE FOR CI DEVS 'DBPrefix' => 'db_', // Needed to ensure we're working correctly with prefixes live. DO NOT REMOVE FOR CI DEVS
'pConnect' => false, 'pConnect' => false,
//'DBDebug' => (ENVIRONMENT !== 'production'),
'DBDebug' => true, 'DBDebug' => true,
'charset' => 'utf8', 'charset' => 'utf8',
'DBCollat' => 'utf8_general_ci', 'DBCollat' => '',
'swapPre' => '', 'swapPre' => '',
'encrypt' => false, 'encrypt' => false,
'compress' => false, 'compress' => false,
@ -77,6 +181,12 @@ class Database extends Config
'failover' => [], 'failover' => [],
'port' => 3306, 'port' => 3306,
'foreignKeys' => true, 'foreignKeys' => true,
'busyTimeout' => 1000,
'dateFormat' => [
'date' => 'Y-m-d',
'datetime' => 'Y-m-d H:i:s',
'time' => 'H:i:s',
],
]; ];
public function __construct() public function __construct()

View File

@ -9,7 +9,7 @@ class DocTypes
* *
* @var array<string, string> * @var array<string, string>
*/ */
public $list = [ public array $list = [
'xhtml11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">', '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-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-trans' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
@ -30,4 +30,14 @@ class DocTypes
'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-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">', '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;
} }

View File

@ -6,143 +6,116 @@ use CodeIgniter\Config\BaseConfig;
class Email extends BaseConfig class Email extends BaseConfig
{ {
/** public string $fromEmail = '';
* @var string public string $fromName = '';
*/ public string $recipients = '';
public $fromEmail;
/**
* @var string
*/
public $fromName;
/**
* @var string
*/
public $recipients;
/** /**
* The "user agent" * The "user agent"
*
* @var string
*/ */
public $userAgent = 'CodeIgniter'; public string $userAgent = 'CodeIgniter';
/** /**
* The mail sending protocol: mail, sendmail, smtp * The mail sending protocol: mail, sendmail, smtp
*
* @var string
*/ */
public $protocol = 'smtp'; public string $protocol = 'mail';
/** /**
* The server path to Sendmail. * The server path to Sendmail.
*
* @var string
*/ */
//public $mailPath = '/usr/sbin/sendmail'; public string $mailPath = '/usr/sbin/sendmail';
public $SMTPHost = 'mail.services.summit.co.id'; /**
public $SMTPUser = 'noreply@services.summit.co.id'; * SMTP Server Hostname
public $SMTPPass = 'Summit2020'; */
public $SMTPPort = 587; public string $SMTPHost = '';
//public $SMTPCrypto = 'ssl';
/**
* SMTP Username
*/
public string $SMTPUser = '';
/**
* SMTP Password
*/
public string $SMTPPass = '';
/**
* SMTP Port
*/
public int $SMTPPort = 25;
/** /**
* SMTP Timeout (in seconds) * SMTP Timeout (in seconds)
*
* @var int
*/ */
public $SMTPTimeout = 30; public int $SMTPTimeout = 5;
/** /**
* Enable persistent SMTP connections * Enable persistent SMTP connections
*
* @var bool
*/ */
public $SMTPKeepAlive = false; public bool $SMTPKeepAlive = false;
/** /**
* SMTP Encryption. Either tls or ssl * SMTP Encryption.
* *
* @var string * @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 * Enable word-wrap
*
* @var bool
*/ */
public $wordWrap = true; public bool $wordWrap = true;
/** /**
* Character count to wrap at * Character count to wrap at
*
* @var int
*/ */
public $wrapChars = 76; public int $wrapChars = 76;
/** /**
* Type of mail, either 'text' or 'html' * Type of mail, either 'text' or 'html'
*
* @var string
*/ */
public $mailType = 'html'; public string $mailType = 'text';
/** /**
* Character set (utf-8, iso-8859-1, etc.) * Character set (utf-8, iso-8859-1, etc.)
*
* @var string
*/ */
public $charset = 'UTF-8'; public string $charset = 'UTF-8';
/** /**
* Whether to validate the email address * Whether to validate the email address
*
* @var bool
*/ */
public $validate = false; public bool $validate = false;
/** /**
* Email Priority. 1 = highest. 5 = lowest. 3 = normal * Email Priority. 1 = highest. 5 = lowest. 3 = normal
*
* @var int
*/ */
public $priority = 3; public int $priority = 3;
/** /**
* Newline character. (Use “\r\n” to comply with RFC 822) * Newline character. (Use “\r\n” to comply with RFC 822)
*
* @var string
*/ */
public $CRLF = "\r\n"; public string $CRLF = "\r\n";
/** /**
* Newline character. (Use “\r\n” to comply with RFC 822) * Newline character. (Use “\r\n” to comply with RFC 822)
*
* @var string
*/ */
public $newline = "\r\n"; public string $newline = "\r\n";
/** /**
* Enable BCC Batch Mode. * Enable BCC Batch Mode.
*
* @var bool
*/ */
public $BCCBatchMode = false; public bool $BCCBatchMode = false;
/** /**
* Number of emails in each BCC batch * Number of emails in each BCC batch
*
* @var int
*/ */
public $BCCBatchSize = 200; public int $BCCBatchSize = 200;
/** /**
* Enable notify message from server * Enable notify message from server
*
* @var bool
*/ */
//public $DSN = true; public bool $DSN = false;
public $DSN = false;
} }

View File

@ -20,10 +20,8 @@ class Encryption extends BaseConfig
* If you use the Encryption class you must set an encryption key (seed). * 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. * You need to ensure it is long enough for the cipher and mode you plan to use.
* See the user guide for more info. * See the user guide for more info.
*
* @var string
*/ */
public $key = ''; public string $key = '';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -35,10 +33,8 @@ class Encryption extends BaseConfig
* Available drivers: * Available drivers:
* - OpenSSL * - OpenSSL
* - Sodium * - Sodium
*
* @var string
*/ */
public $driver = 'OpenSSL'; public string $driver = 'OpenSSL';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -49,10 +45,8 @@ class Encryption extends BaseConfig
* before it is encrypted. This value should be greater than zero. * before it is encrypted. This value should be greater than zero.
* *
* See the user guide for more information on padding. * See the user guide for more information on padding.
*
* @var int
*/ */
public $blockSize = 16; public int $blockSize = 16;
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -60,8 +54,39 @@ class Encryption extends BaseConfig
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* *
* HMAC digest to use, e.g. 'SHA512' or 'SHA256'. Default value is 'SHA512'. * HMAC digest to use, e.g. 'SHA512' or 'SHA256'. Default value is 'SHA512'.
*
* @var string
*/ */
public $digest = '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';
} }

View File

@ -4,6 +4,7 @@ namespace Config;
use CodeIgniter\Events\Events; use CodeIgniter\Events\Events;
use CodeIgniter\Exceptions\FrameworkException; use CodeIgniter\Exceptions\FrameworkException;
use CodeIgniter\HotReloader\HotReloader;
/* /*
* -------------------------------------------------------------------- * --------------------------------------------------------------------
@ -22,7 +23,7 @@ use CodeIgniter\Exceptions\FrameworkException;
* Events::on('create', [$myInstance, 'myMethod']); * Events::on('create', [$myInstance, 'myMethod']);
*/ */
Events::on('pre_system', static function () { Events::on('pre_system', static function (): void {
if (ENVIRONMENT !== 'testing') { if (ENVIRONMENT !== 'testing') {
if (ini_get('zlib.output_compression')) { if (ini_get('zlib.output_compression')) {
throw FrameworkException::forEnabledZlibOutputCompression(); throw FrameworkException::forEnabledZlibOutputCompression();
@ -43,6 +44,12 @@ Events::on('pre_system', static function () {
*/ */
if (CI_DEBUG && ! is_cli()) { if (CI_DEBUG && ! is_cli()) {
Events::on('DBQuery', 'CodeIgniter\Debug\Toolbar\Collectors\Database::collect'); Events::on('DBQuery', 'CodeIgniter\Debug\Toolbar\Collectors\Database::collect');
Services::toolbar()->respond(); 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();
});
}
} }
}); });

View File

@ -3,6 +3,10 @@
namespace Config; namespace Config;
use CodeIgniter\Config\BaseConfig; use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Debug\ExceptionHandler;
use CodeIgniter\Debug\ExceptionHandlerInterface;
use Psr\Log\LogLevel;
use Throwable;
/** /**
* Setup how the exception handler works. * Setup how the exception handler works.
@ -17,10 +21,8 @@ class Exceptions extends BaseConfig
* through Services::Log. * through Services::Log.
* *
* Default: true * Default: true
*
* @var bool
*/ */
public $log = true; public bool $log = true;
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -29,9 +31,9 @@ class Exceptions extends BaseConfig
* Any status codes here will NOT be logged if logging is turned on. * Any status codes here will NOT be logged if logging is turned on.
* By default, only 404 (Page Not Found) exceptions are ignored. * By default, only 404 (Page Not Found) exceptions are ignored.
* *
* @var array * @var list<int>
*/ */
public $ignoreCodes = [404]; public array $ignoreCodes = [404];
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -41,10 +43,8 @@ class Exceptions extends BaseConfig
* directories that hold the views used to generate errors. * directories that hold the views used to generate errors.
* *
* Default: APPPATH.'Views/errors' * Default: APPPATH.'Views/errors'
*
* @var string
*/ */
public $errorViewPath = APPPATH . 'Views/errors'; public string $errorViewPath = APPPATH . 'Views/errors';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -54,7 +54,53 @@ class Exceptions extends BaseConfig
* In order to specify 2 levels, use "/" to separate. * In order to specify 2 levels, use "/" to separate.
* ex. ['server', 'setup/password', 'secret_token'] * ex. ['server', 'setup/password', 'secret_token']
* *
* @var array * @var list<string>
*/ */
public $sensitiveDataInTrace = []; 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);
}
} }

View File

@ -10,23 +10,28 @@ use CodeIgniter\Config\BaseConfig;
class Feature extends BaseConfig class Feature extends BaseConfig
{ {
/** /**
* Enable multiple filters for a route or not. * Use improved new auto routing instead of the legacy version.
*
* If you enable this:
* - CodeIgniter\CodeIgniter::handleRequest() uses:
* - CodeIgniter\Filters\Filters::enableFilters(), instead of enableFilter()
* - CodeIgniter\CodeIgniter::tryToRouteIt() uses:
* - CodeIgniter\Router\Router::getFilters(), instead of getFilter()
* - CodeIgniter\Router\Router::handle() uses:
* - property $filtersInfo, instead of $filterInfo
* - CodeIgniter\Router\RouteCollection::getFiltersForRoute(), instead of getFilterForRoute()
*
* @var bool
*/ */
public $multipleFilters = false; public bool $autoRoutesImproved = true;
/** /**
* Use improved new auto routing instead of the default legacy version. * Use filter execution order in 4.4 or before.
*/ */
public bool $autoRoutesImproved = false; 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;
} }

View File

@ -2,47 +2,86 @@
namespace Config; namespace Config;
use CodeIgniter\Config\BaseConfig; use CodeIgniter\Config\Filters as BaseFilters;
use CodeIgniter\Filters\Cors;
use CodeIgniter\Filters\CSRF; use CodeIgniter\Filters\CSRF;
use CodeIgniter\Filters\DebugToolbar; use CodeIgniter\Filters\DebugToolbar;
use CodeIgniter\Filters\ForceHTTPS;
use CodeIgniter\Filters\Honeypot; use CodeIgniter\Filters\Honeypot;
use CodeIgniter\Filters\InvalidChars; use CodeIgniter\Filters\InvalidChars;
use CodeIgniter\Filters\PageCache;
use CodeIgniter\Filters\PerformanceMetrics;
use CodeIgniter\Filters\SecureHeaders; use CodeIgniter\Filters\SecureHeaders;
class Filters extends BaseConfig class Filters extends BaseFilters
{ {
/** /**
* Configures aliases for Filter classes to * Configures aliases for Filter classes to
* make reading things nicer and simpler. * make reading things nicer and simpler.
* *
* @var array * @var array<string, class-string|list<class-string>>
*
* [filter_name => classname]
* or [filter_name => [classname1, classname2, ...]]
*/ */
public $aliases = [ public array $aliases = [
'csrf' => CSRF::class, 'csrf' => CSRF::class,
'toolbar' => DebugToolbar::class, 'toolbar' => DebugToolbar::class,
'honeypot' => Honeypot::class, 'honeypot' => Honeypot::class,
'invalidchars' => InvalidChars::class, 'invalidchars' => InvalidChars::class,
'secureheaders' => SecureHeaders::class, 'secureheaders' => SecureHeaders::class,
'forcehttps' => ForceHTTPS::class,
'pagecache' => PageCache::class,
'performance' => PerformanceMetrics::class,
'auth' => \App\Filters\Auth::class, 'auth' => \App\Filters\Auth::class,
'cors' => \App\Filters\Cors::class,
]; ];
/** /**
* List of filter aliases that are always * List of special required filters.
* applied before and after every request.
* *
* @var array * 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 $globals = [ public array $required = [
'before' => [ 'before' => [
'auth' => [ 'except' => [ 'auth' => [ 'except' => [
'auth/*' 'auth/*', 'lqms/*', 'key/*', 'api/*'
]] ]]
// 'honeypot', // 'honeypot',
// 'csrf', // 'csrf',
// 'invalidchars', // 'invalidchars',
], ],
'after' => [ 'after' => [
'toolbar', '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{
* before: array<string, array{except: list<string>|string}>|list<string>,
* after: array<string, array{except: list<string>|string}>|list<string>
* }
*/
public array $globals = [
'before' => [
// 'honeypot',
// 'csrf',
// 'invalidchars',
],
'after' => [
// 'honeypot', // 'honeypot',
// 'secureheaders', // 'secureheaders',
], ],
@ -53,15 +92,15 @@ class Filters extends BaseConfig
* particular HTTP method (GET, POST, etc.). * particular HTTP method (GET, POST, etc.).
* *
* Example: * Example:
* 'post' => ['foo', 'bar'] * 'POST' => ['foo', 'bar']
* *
* If you use this, you should disable auto-routing because auto-routing * If you use this, you should disable auto-routing because auto-routing
* permits any HTTP method to access a controller. Accessing the controller * permits any HTTP method to access a controller. Accessing the controller
* with a method you dont expect could bypass the filter. * with a method you don't expect could bypass the filter.
* *
* @var array * @var array<string, list<string>>
*/ */
public $methods = []; public array $methods = [];
/** /**
* List of filter aliases that should run on any * List of filter aliases that should run on any
@ -70,9 +109,7 @@ class Filters extends BaseConfig
* Example: * Example:
* 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']] * 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']]
* *
* @var array * @var array<string, array<string, list<string>>>
*/ */
public $filters = [ public array $filters = [];
];
} }

View File

@ -4,6 +4,9 @@ namespace Config;
use CodeIgniter\Config\ForeignCharacters as BaseForeignCharacters; use CodeIgniter\Config\ForeignCharacters as BaseForeignCharacters;
/**
* @immutable
*/
class ForeignCharacters extends BaseForeignCharacters class ForeignCharacters extends BaseForeignCharacters
{ {
} }

View File

@ -3,7 +3,6 @@
namespace Config; namespace Config;
use CodeIgniter\Config\BaseConfig; use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Format\FormatterInterface;
use CodeIgniter\Format\JSONFormatter; use CodeIgniter\Format\JSONFormatter;
use CodeIgniter\Format\XMLFormatter; use CodeIgniter\Format\XMLFormatter;
@ -22,9 +21,9 @@ class Format extends BaseConfig
* These formats are only checked when the data passed to the respond() * These formats are only checked when the data passed to the respond()
* method is an array. * method is an array.
* *
* @var string[] * @var list<string>
*/ */
public $supportedResponseFormats = [ public array $supportedResponseFormats = [
'application/json', 'application/json',
'application/xml', // machine-readable XML 'application/xml', // machine-readable XML
'text/xml', // human-readable XML 'text/xml', // human-readable XML
@ -41,7 +40,7 @@ class Format extends BaseConfig
* *
* @var array<string, string> * @var array<string, string>
*/ */
public $formatters = [ public array $formatters = [
'application/json' => JSONFormatter::class, 'application/json' => JSONFormatter::class,
'application/xml' => XMLFormatter::class, 'application/xml' => XMLFormatter::class,
'text/xml' => XMLFormatter::class, 'text/xml' => XMLFormatter::class,
@ -57,21 +56,9 @@ class Format extends BaseConfig
* *
* @var array<string, int> * @var array<string, int>
*/ */
public $formatterOptions = [ public array $formatterOptions = [
'application/json' => JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES, 'application/json' => JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES,
'application/xml' => 0, 'application/xml' => 0,
'text/xml' => 0, 'text/xml' => 0,
]; ];
/**
* A Factory method to return the appropriate formatter for the given mime type.
*
* @return FormatterInterface
*
* @deprecated This is an alias of `\CodeIgniter\Format\Format::getFormatter`. Use that instead.
*/
public function getFormatter(string $mime)
{
return Services::format()->getFormatter($mime);
}
} }

View File

@ -23,9 +23,13 @@ class Generators extends BaseConfig
* *
* YOU HAVE BEEN WARNED! * YOU HAVE BEEN WARNED!
* *
* @var array<string, string> * @var array<string, array<string, string>|string>
*/ */
public $views = [ 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:command' => 'CodeIgniter\Commands\Generators\Views\command.tpl.php',
'make:config' => 'CodeIgniter\Commands\Generators\Views\config.tpl.php', 'make:config' => 'CodeIgniter\Commands\Generators\Views\config.tpl.php',
'make:controller' => 'CodeIgniter\Commands\Generators\Views\controller.tpl.php', 'make:controller' => 'CodeIgniter\Commands\Generators\Views\controller.tpl.php',

View File

@ -8,36 +8,35 @@ class Honeypot extends BaseConfig
{ {
/** /**
* Makes Honeypot visible or not to human * Makes Honeypot visible or not to human
*
* @var bool
*/ */
public $hidden = true; public bool $hidden = true;
/** /**
* Honeypot Label Content * Honeypot Label Content
*
* @var string
*/ */
public $label = 'Fill This Field'; public string $label = 'Fill This Field';
/** /**
* Honeypot Field Name * Honeypot Field Name
*
* @var string
*/ */
public $name = 'honeypot'; public string $name = 'honeypot';
/** /**
* Honeypot HTML Template * Honeypot HTML Template
*
* @var string
*/ */
public $template = '<label>{label}</label><input type="text" name="{name}" value=""/>'; public string $template = '<label>{label}</label><input type="text" name="{name}" value="">';
/** /**
* Honeypot container * Honeypot container
* *
* @var string * If you enabled CSP, you can remove `style="display:none"`.
*/ */
public $container = '<div style="display:none">{template}</div>'; 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';
} }

View File

@ -10,25 +10,21 @@ class Images extends BaseConfig
{ {
/** /**
* Default handler used if no other handler is specified. * Default handler used if no other handler is specified.
*
* @var string
*/ */
public $defaultHandler = 'gd'; public string $defaultHandler = 'gd';
/** /**
* The path to the image library. * The path to the image library.
* Required for ImageMagick, GraphicsMagick, or NetPBM. * Required for ImageMagick, GraphicsMagick, or NetPBM.
*
* @var string
*/ */
public $libraryPath = '/usr/local/bin/convert'; public string $libraryPath = '/usr/local/bin/convert';
/** /**
* The available handler classes. * The available handler classes.
* *
* @var array<string, string> * @var array<string, string>
*/ */
public $handlers = [ public array $handlers = [
'gd' => GDHandler::class, 'gd' => GDHandler::class,
'imagick' => ImageMagickHandler::class, 'imagick' => ImageMagickHandler::class,
]; ];

View File

@ -2,8 +2,9 @@
namespace Config; namespace Config;
use CodeIgniter\Config\BaseConfig; use Kint\Parser\ConstructablePluginInterface;
use Kint\Renderer\Renderer; use Kint\Renderer\Rich\TabPluginInterface;
use Kint\Renderer\Rich\ValuePluginInterface;
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -15,7 +16,7 @@ use Kint\Renderer\Renderer;
* *
* @see https://kint-php.github.io/kint/ for details on these settings. * @see https://kint-php.github.io/kint/ for details on these settings.
*/ */
class Kint extends BaseConfig class Kint
{ {
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -23,20 +24,31 @@ class Kint extends BaseConfig
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
*/ */
/**
* @var list<class-string<ConstructablePluginInterface>|ConstructablePluginInterface>|null
*/
public $plugins; public $plugins;
public $maxDepth = 6;
public $displayCalledFrom = true; public int $maxDepth = 6;
public $expanded = false; public bool $displayCalledFrom = true;
public bool $expanded = false;
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| RichRenderer Settings | RichRenderer Settings
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
*/ */
public $richTheme = 'aante-light.css'; public string $richTheme = 'aante-light.css';
public $richFolder = false; public bool $richFolder = false;
public $richSort = Renderer::SORT_FULL;
/**
* @var array<string, class-string<ValuePluginInterface>>|null
*/
public $richObjectPlugins; public $richObjectPlugins;
/**
* @var array<string, class-string<TabPluginInterface>>|null
*/
public $richTabPlugins; public $richTabPlugins;
/* /*
@ -44,8 +56,8 @@ class Kint extends BaseConfig
| CLI Settings | CLI Settings
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
*/ */
public $cliColors = true; public bool $cliColors = true;
public $cliForceUTF8 = false; public bool $cliForceUTF8 = false;
public $cliDetectWidth = true; public bool $cliDetectWidth = true;
public $cliMinWidth = 40; public int $cliMinWidth = 40;
} }

View File

@ -2,8 +2,9 @@
namespace Config; namespace Config;
use CodeIgniter\Log\Handlers\FileHandler;
use CodeIgniter\Config\BaseConfig; use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Log\Handlers\FileHandler;
use CodeIgniter\Log\Handlers\HandlerInterface;
class Logger extends BaseConfig class Logger extends BaseConfig
{ {
@ -36,9 +37,9 @@ class Logger extends BaseConfig
* For a live site you'll usually enable Critical or higher (3) to be logged otherwise * For a live site you'll usually enable Critical or higher (3) to be logged otherwise
* your log files will fill up very fast. * your log files will fill up very fast.
* *
* @var array|int * @var int|list<int>
*/ */
public $threshold = 4; public $threshold = (ENVIRONMENT === 'production') ? 4 : 9;
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -47,10 +48,8 @@ class Logger extends BaseConfig
* *
* Each item that is logged has an associated date. You can use PHP date * Each item that is logged has an associated date. You can use PHP date
* codes to set your own date formatting * codes to set your own date formatting
*
* @var string
*/ */
public $dateFormat = 'Y-m-d H:i:s'; public string $dateFormat = 'Y-m-d H:i:s';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -60,7 +59,7 @@ class Logger extends BaseConfig
* The logging system supports multiple actions to be taken when something * The logging system supports multiple actions to be taken when something
* is logged. This is done by allowing for multiple Handlers, special classes * is logged. This is done by allowing for multiple Handlers, special classes
* designed to write the log to their chosen destinations, whether that is * designed to write the log to their chosen destinations, whether that is
* a file on the server, a cloud-based service, or even taking actions such * a file on the getServer, a cloud-based service, or even taking actions such
* as emailing the dev team. * as emailing the dev team.
* *
* Each handler is defined by the class name used for that handler, and it * Each handler is defined by the class name used for that handler, and it
@ -75,17 +74,15 @@ class Logger extends BaseConfig
* Handlers are executed in the order defined in this array, starting with * Handlers are executed in the order defined in this array, starting with
* the handler on top and continuing down. * the handler on top and continuing down.
* *
* @var array * @var array<class-string<HandlerInterface>, array<string, int|list<string>|string>>
*/ */
public $handlers = [ public array $handlers = [
/* /*
* -------------------------------------------------------------------- * --------------------------------------------------------------------
* File Handler * File Handler
* -------------------------------------------------------------------- * --------------------------------------------------------------------
*/ */
FileHandler::class => [ FileHandler::class => [
// The log levels that this handler will handle. // The log levels that this handler will handle.
'handles' => [ 'handles' => [
'critical', 'critical',
@ -103,7 +100,7 @@ class Logger extends BaseConfig
* An extension of 'php' allows for protecting the log files via basic * An extension of 'php' allows for protecting the log files via basic
* scripting, when they are to be stored under a publicly accessible directory. * scripting, when they are to be stored under a publicly accessible directory.
* *
* Note: Leaving it blank will default to 'log'. * NOTE: Leaving it blank will default to 'log'.
*/ */
'fileExtension' => '', 'fileExtension' => '',

View File

@ -15,10 +15,8 @@ class Migrations extends BaseConfig
* *
* You should enable migrations whenever you intend to do a schema migration * You should enable migrations whenever you intend to do a schema migration
* and disable it back when you're done. * and disable it back when you're done.
*
* @var bool
*/ */
public $enabled = true; public bool $enabled = true;
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -27,13 +25,9 @@ class Migrations extends BaseConfig
* *
* This is the name of the table that will store the current migrations state. * 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 * When migrations runs it will store in a database table which migration
* level the system is at. It then compares the migration level in this * files have already been run.
* table to the $config['migration_version'] if they are not the same it
* will migrate up. This must be set.
*
* @var string
*/ */
public $table = 'migrations'; public string $table = 'migrations';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -42,14 +36,15 @@ class Migrations extends BaseConfig
* *
* This is the format that will be used when creating new migrations * This is the format that will be used when creating new migrations
* using the CLI command: * using the CLI command:
* > php spark migrate:create * > php spark make:migration
* *
* Typical formats: * NOTE: if you set an unsupported format, migration runner will not find
* your migration files.
*
* Supported formats:
* - YmdHis_ * - YmdHis_
* - Y-m-d-His_ * - Y-m-d-His_
* - Y_m_d_His_ * - Y_m_d_His_
*
* @var string
*/ */
public $timestampFormat = 'Y-m-d-His_'; public string $timestampFormat = 'Y-m-d-His_';
} }

View File

@ -3,8 +3,6 @@
namespace Config; namespace Config;
/** /**
* Mimes
*
* This file contains an array of mime types. It is used by the * This file contains an array of mime types. It is used by the
* Upload class to help identify allowed file types. * Upload class to help identify allowed file types.
* *
@ -21,9 +19,9 @@ class Mimes
/** /**
* Map of extensions to mime types. * Map of extensions to mime types.
* *
* @var array * @var array<string, list<string>|string>
*/ */
public static $mimes = [ public static array $mimes = [
'hqx' => [ 'hqx' => [
'application/mac-binhex40', 'application/mac-binhex40',
'application/mac-binhex', 'application/mac-binhex',
@ -55,6 +53,8 @@ class Mimes
'lzh' => 'application/octet-stream', 'lzh' => 'application/octet-stream',
'exe' => [ 'exe' => [
'application/octet-stream', 'application/octet-stream',
'application/vnd.microsoft.portable-executable',
'application/x-dosexec',
'application/x-msdownload', 'application/x-msdownload',
], ],
'class' => 'application/octet-stream', 'class' => 'application/octet-stream',
@ -478,6 +478,8 @@ class Mimes
'application/sla', 'application/sla',
'application/vnd.ms-pki.stl', 'application/vnd.ms-pki.stl',
'application/x-navistyle', 'application/x-navistyle',
'model/stl',
'application/octet-stream',
], ],
]; ];

View File

@ -4,6 +4,12 @@ namespace Config;
use CodeIgniter\Modules\Modules as BaseModules; use CodeIgniter\Modules\Modules as BaseModules;
/**
* Modules Configuration.
*
* NOTE: This class is required prior to Autoloader instantiation,
* and does not extend BaseConfig.
*/
class Modules extends BaseModules class Modules extends BaseModules
{ {
/** /**
@ -31,6 +37,29 @@ class Modules extends BaseModules
*/ */
public $discoverInComposer = true; 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 * Auto-Discovery Rules
@ -41,7 +70,7 @@ class Modules extends BaseModules
* *
* If it is not listed, only the base application elements will be used. * If it is not listed, only the base application elements will be used.
* *
* @var string[] * @var list<string>
*/ */
public $aliases = [ public $aliases = [
'events', 'events',

30
app/Config/Optimize.php Normal file
View File

@ -0,0 +1,30 @@
<?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.
*/
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;
}

View File

@ -20,7 +20,7 @@ class Pager extends BaseConfig
* *
* @var array<string, string> * @var array<string, string>
*/ */
public $templates = [ public array $templates = [
'default_full' => 'CodeIgniter\Pager\Views\default_full', 'default_full' => 'CodeIgniter\Pager\Views\default_full',
'default_simple' => 'CodeIgniter\Pager\Views\default_simple', 'default_simple' => 'CodeIgniter\Pager\Views\default_simple',
'default_head' => 'CodeIgniter\Pager\Views\default_head', 'default_head' => 'CodeIgniter\Pager\Views\default_head',
@ -32,8 +32,6 @@ class Pager extends BaseConfig
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* *
* The default number of results shown in a single page. * The default number of results shown in a single page.
*
* @var int
*/ */
public $perPage = 20; public int $perPage = 20;
} }

View File

@ -22,10 +22,8 @@ class Paths
* *
* This must contain the name of your "system" folder. Include * This must contain the name of your "system" folder. Include
* the path if the folder is not in the same directory as this file. * the path if the folder is not in the same directory as this file.
*
* @var string
*/ */
public $systemDirectory = __DIR__ . '/../../system'; public string $systemDirectory = __DIR__ . '/../../vendor/codeigniter4/framework/system';
/** /**
* --------------------------------------------------------------- * ---------------------------------------------------------------
@ -38,10 +36,8 @@ class Paths
* you do, use a full server path. * you do, use a full server path.
* *
* @see http://codeigniter.com/user_guide/general/managing_apps.html * @see http://codeigniter.com/user_guide/general/managing_apps.html
*
* @var string
*/ */
public $appDirectory = __DIR__ . '/..'; public string $appDirectory = __DIR__ . '/..';
/** /**
* --------------------------------------------------------------- * ---------------------------------------------------------------
@ -53,10 +49,8 @@ class Paths
* need write permission to a single place that can be tucked away * need write permission to a single place that can be tucked away
* for maximum security, keeping it out of the app and/or * for maximum security, keeping it out of the app and/or
* system directories. * system directories.
*
* @var string
*/ */
public $writableDirectory = __DIR__ . '/../../writable'; public string $writableDirectory = __DIR__ . '/../../writable';
/** /**
* --------------------------------------------------------------- * ---------------------------------------------------------------
@ -64,10 +58,8 @@ class Paths
* --------------------------------------------------------------- * ---------------------------------------------------------------
* *
* This variable must contain the name of your "tests" directory. * This variable must contain the name of your "tests" directory.
*
* @var string
*/ */
public $testsDirectory = __DIR__ . '/../../tests'; public string $testsDirectory = __DIR__ . '/../../tests';
/** /**
* --------------------------------------------------------------- * ---------------------------------------------------------------
@ -78,8 +70,6 @@ class Paths
* contains the view files used by your application. By * contains the view files used by your application. By
* default this is in `app/Views`. This value * default this is in `app/Views`. This value
* is used when no value is provided to `Services::renderer()`. * is used when no value is provided to `Services::renderer()`.
*
* @var string
*/ */
public $viewDirectory = __DIR__ . '/../Views'; public string $viewDirectory = __DIR__ . '/../Views';
} }

View File

@ -19,7 +19,7 @@ class Publisher extends BasePublisher
* result in a PublisherException. Files that do no fit the * result in a PublisherException. Files that do no fit the
* pattern will cause copy/merge to fail. * pattern will cause copy/merge to fail.
* *
* @var array<string,string> * @var array<string, string>
*/ */
public $restrictions = [ public $restrictions = [
ROOTPATH => '*', ROOTPATH => '*',

View File

@ -1,26 +1,23 @@
<?php <?php
namespace Config; use CodeIgniter\Router\RouteCollection;
// Create a new instance of our RouteCollection class. /**
$routes = Services::routes(); * @var RouteCollection $routes
*/
// Load the system's routing file first, so that the app and ENVIRONMENT
// can override as needed.
if (is_file(SYSTEMPATH . 'Config/Routes.php')) {
require SYSTEMPATH . 'Config/Routes.php';
}
/* /*
* -------------------------------------------------------------------- * --------------------------------------------------------------------
* Router Setup * Router Setup
* -------------------------------------------------------------------- * --------------------------------------------------------------------
*/ */
$routes->setDefaultNamespace('App\Controllers');
$routes->setDefaultController('Dashboard'); // $routes->setDefaultNamespace('App\Controllers');
$routes->setDefaultMethod('index'); // $routes->setDefaultController('Dashboard');
$routes->setTranslateURIDashes(false); // $routes->setDefaultMethod('index');
$routes->set404Override(); // $routes->setTranslateURIDashes(false);
// $routes->set404Override();
// The Auto Routing (Legacy) is very dangerous. It is easy to create vulnerable apps // The Auto Routing (Legacy) is very dangerous. It is easy to create vulnerable apps
// where controller filters or CSRF protection are bypassed. // where controller filters or CSRF protection are bypassed.
// If you don't want to define all routes, please use the Auto Routing (Improved). // If you don't want to define all routes, please use the Auto Routing (Improved).
@ -35,7 +32,6 @@ $routes->set404Override();
// We get a performance increase by specifying the default // We get a performance increase by specifying the default
// route since we don't have to scan directories. // route since we don't have to scan directories.
$routes->match(['get','post'], '/auth/login', 'Auth::login'); $routes->match(['get','post'], '/auth/login', 'Auth::login');
$routes->match(['get','post'], '/auth/setPass', 'Auth::setPass'); $routes->match(['get','post'], '/auth/setPass', 'Auth::setPass');
$routes->get( '/auth/logout', 'Auth::logout'); $routes->get( '/auth/logout', 'Auth::logout');
@ -99,11 +95,18 @@ $routes->match(['get','post'],'/productalias/create', 'ProductAlias::create');
$routes->match(['get','post'],'/productcatalog', 'ProductCatalog::index'); $routes->match(['get','post'],'/productcatalog', 'ProductCatalog::index');
$routes->match(['get','post'],'/productcatalog/edit/(:num)', 'ProductCatalog::edit/$1'); $routes->match(['get','post'],'/productcatalog/edit/(:num)', 'ProductCatalog::edit/$1');
$routes->match(['get','post'],'/productcatalog/create', 'ProductCatalog::create'); $routes->match(['get','post'],'/productcatalog/create', 'ProductCatalog::create');
// producttemp
$routes->get('/producttemp', 'ProductTemp::index');
$routes->get('/producttemp/getdata/(:num)', 'ProductTemp::getdata/$1');
$routes->post('/producttemp/edit', 'ProductTemp::edit');
$routes->post('/producttemp/validate', 'ProductTemp::validateItem');
$routes->post('/producttemp/delete/(:num)', 'ProductTemp::deleteItem/$1');
//unitgroup //unitgroup
$routes->match(['get','post'], '/unitgroup/', 'UnitGroup::index'); $routes->match(['get','post'], '/unitgroup/', 'UnitGroup::index');
$routes->match(['get','post'], '/unitgroup/edit/(:num)', 'UnitGroup::edit/$1'); $routes->match(['get','post'], '/unitgroup/edit/(:num)', 'UnitGroup::edit/$1');
$routes->match(['get','post'], '/unitgroup/create', 'UnitGroup::edit/0'); $routes->match(['get','post'], '/unitgroup/create', 'UnitGroup::edit/0');
$routes->get('/unitgroup/toggle/(:num)', 'UnitGroup::toggle/$1');
// products // products
$routes->match(['get','post'],'/products', 'Products::index'); $routes->match(['get','post'],'/products', 'Products::index');
@ -115,6 +118,7 @@ $routes->match(['get','post'],'/products/movesite/(:num)', 'Products::movesite/$
$routes->match(['get','post'],'/products/changeowner/(:num)', 'Products::changeowner/$1'); $routes->match(['get','post'],'/products/changeowner/(:num)', 'Products::changeowner/$1');
$routes->match(['get','post'],'/products/upgrade/(:num)', 'Products::upgrade/$1'); $routes->match(['get','post'],'/products/upgrade/(:num)', 'Products::upgrade/$1');
$routes->post('/products/log/delete', 'Products::productslog_delete'); $routes->post('/products/log/delete', 'Products::productslog_delete');
$routes->get('/products/export', 'Products::exportdata');
// users // users
$routes->get('/users', 'Users::index'); $routes->get('/users', 'Users::index');
$routes->get('/users/view/(:num)', 'Users::view/$1'); $routes->get('/users/view/(:num)', 'Users::view/$1');
@ -144,8 +148,10 @@ $routes->match(['get','post'],'/acttext/create', 'ActText::create');
$routes->match(['get','post'],'/acttext/edit/(:num)', 'ActText::edit/$1'); $routes->match(['get','post'],'/acttext/edit/(:num)', 'ActText::edit/$1');
// activities // activities
$routes->match(['get','post'],'/activities/', 'Activities::index'); $routes->match(['get','post'],'/activities/', 'Activities::index');
$routes->get('/activities/index/getproduct/(:num)', 'Activities::index_getproduct/$1'); // $routes->get('/activities/index/getproduct/(:num)', 'Activities::index_getproduct/$1');
$routes->get('/activities/index/getproduct/(:any)/(:any)', 'Activities::index_getproduct/$1/$2');
$routes->get('/activities/detail/(:num)', 'Activities::detail/$1'); $routes->get('/activities/detail/(:num)', 'Activities::detail/$1');
$routes->get('/activities/servicereport/(:num)', 'Activities::servicereport/$1');
$routes->get('/activities/suspend/(:num)', 'Activities::suspend/$1'); $routes->get('/activities/suspend/(:num)', 'Activities::suspend/$1');
$routes->get('/activities/disable/(:num)', 'Activities::disable/$1'); $routes->get('/activities/disable/(:num)', 'Activities::disable/$1');
// $routes->get('/activities/delete/(:num)', 'Activities::delete/$1'); // $routes->get('/activities/delete/(:num)', 'Activities::delete/$1');
@ -222,6 +228,40 @@ $routes->match(['get','post'],'/invtrans/create', 'InvTrans::edit/0');
$routes->match(['get','post'],'/invtrans/edit/(:any)', 'InvTrans::edit/$1'); $routes->match(['get','post'],'/invtrans/edit/(:any)', 'InvTrans::edit/$1');
$routes->match(['get','post'],'/invtrans/user/(:any)', 'InvTrans::index_user/$1'); $routes->match(['get','post'],'/invtrans/user/(:any)', 'InvTrans::index_user/$1');
$routes->match(['get','post'],'/invtrans/reportusage/', 'InvTrans::reportusage/$1'); $routes->match(['get','post'],'/invtrans/reportusage/', 'InvTrans::reportusage/$1');
//LQMS
/*
$routes->match(['get','post'],'/lqms', 'Lqms::index');
$routes->post('/lqms/postdata', 'Lqms::postdata');
$routes->get('/lqms/log_clear', 'Lqms::log_clear');
$routes->get('/lqms/log/delete/(:any)', 'Lqms::log_delete/$1');
*/
/*
// Kanban
$routes->get('/kanban', 'Kanban::index');
$routes->get('/kanban/view/(:any)', 'Kanban::view/$1');
$routes->match(['get','post'],'/kanban/board/create/', 'Kanban::board_edit/0');
$routes->match(['get','post'],'/kanban/board/edit/(:any)', 'Kanban::board_edit/$1');
$routes->match(['get','post'],'/kanban/list/edit/(:any)', 'Kanban::list_edit/$1');
$routes->match(['get','post'],'/kanban/card/create/(:any)', 'Kanban::card_edit/$1/0');
$routes->match(['get','post'],'/kanban/card/edit/(:any)/(:any)', 'Kanban::card_edit/$1/$2');
$routes->get('/kanban/card/move/(:any)/(:any)', 'Kanban::card_move/$1/$2');
*/
// Key
$routes->group('', ['filter' => 'cors'], function($routes) {
$routes->get('/key/key', 'Key::index');
$routes->post('/key/data', 'Key::data');
});
// REST API
// $routes->get('/api/getProductList', 'Api::getProductList');
$routes->get('/api/getProductAlias', 'Api::getProductAlias');
$routes->get('/api/getProductSites', 'Api::getProductSites');
//CLQMS
// $routes->get('/clqms', 'Clqms::index'); // for CLQMS Inst select
/* /*
* -------------------------------------------------------------------- * --------------------------------------------------------------------
* Additional Routing * Additional Routing
@ -235,6 +275,6 @@ $routes->match(['get','post'],'/invtrans/reportusage/', 'InvTrans::reportusage/$
* You will have access to the $routes object within that file without * You will have access to the $routes object within that file without
* needing to reload it. * needing to reload it.
*/ */
if (is_file(APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php')) { // if (is_file(APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php')) {
require APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php'; // require APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php';
} // }

140
app/Config/Routing.php Normal file
View 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;
}

View File

@ -15,7 +15,7 @@ class Security extends BaseConfig
* *
* @var string 'cookie' or 'session' * @var string 'cookie' or 'session'
*/ */
public $csrfProtection = 'cookie'; public string $csrfProtection = 'cookie';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -23,10 +23,8 @@ class Security extends BaseConfig
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* *
* Randomize the CSRF Token for added security. * Randomize the CSRF Token for added security.
*
* @var bool
*/ */
public $tokenRandomize = false; public bool $tokenRandomize = false;
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -34,10 +32,8 @@ class Security extends BaseConfig
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* *
* Token name for Cross Site Request Forgery protection. * Token name for Cross Site Request Forgery protection.
*
* @var string
*/ */
public $tokenName = 'csrf_test_name'; public string $tokenName = 'csrf_test_name';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -45,10 +41,8 @@ class Security extends BaseConfig
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* *
* Header name for Cross Site Request Forgery protection. * Header name for Cross Site Request Forgery protection.
*
* @var string
*/ */
public $headerName = 'X-CSRF-TOKEN'; public string $headerName = 'X-CSRF-TOKEN';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -56,10 +50,8 @@ class Security extends BaseConfig
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* *
* Cookie name for Cross Site Request Forgery protection. * Cookie name for Cross Site Request Forgery protection.
*
* @var string
*/ */
public $cookieName = 'csrf_cookie_name'; public string $cookieName = 'csrf_cookie_name';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -69,10 +61,8 @@ class Security extends BaseConfig
* Expiration time for Cross Site Request Forgery protection cookie. * Expiration time for Cross Site Request Forgery protection cookie.
* *
* Defaults to two hours (in seconds). * Defaults to two hours (in seconds).
*
* @var int
*/ */
public $expires = 7200; public int $expires = 7200;
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -80,10 +70,8 @@ class Security extends BaseConfig
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* *
* Regenerate CSRF Token on every submission. * Regenerate CSRF Token on every submission.
*
* @var bool
*/ */
public $regenerate = true; public bool $regenerate = true;
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -92,26 +80,7 @@ class Security extends BaseConfig
* *
* Redirect to previous page with error on failure. * Redirect to previous page with error on failure.
* *
* @var bool * @see https://codeigniter4.github.io/userguide/libraries/security.html#redirection-on-failure
*/ */
public $redirect = true; public bool $redirect = (ENVIRONMENT === 'production');
/**
* --------------------------------------------------------------------------
* CSRF SameSite
* --------------------------------------------------------------------------
*
* Setting for CSRF SameSite cookie token.
*
* Allowed values are: None - Lax - Strict - ''.
*
* Defaults to `Lax` as recommended in this link:
*
* @see https://portswigger.net/web-security/csrf/samesite-cookies
*
* @var string
*
* @deprecated `Config\Cookie` $samesite property is used.
*/
public $samesite = 'Lax';
} }

127
app/Config/Session.php Normal file
View 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;
}

View File

@ -31,9 +31,9 @@ class Toolbar extends BaseConfig
* List of toolbar collectors that will be called when Debug Toolbar * List of toolbar collectors that will be called when Debug Toolbar
* fires up and collects data from. * fires up and collects data from.
* *
* @var string[] * @var list<class-string>
*/ */
public $collectors = [ public array $collectors = [
Timers::class, Timers::class,
Database::class, Database::class,
Logs::class, Logs::class,
@ -49,12 +49,10 @@ class Toolbar extends BaseConfig
* Collect Var Data * Collect Var Data
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* *
* If set to false var data from the views will not be colleted. Usefull to * 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. * avoid high memory usage when there are lots of data passed to the view.
*
* @var bool
*/ */
public $collectVarData = true; public bool $collectVarData = true;
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -64,10 +62,8 @@ class Toolbar extends BaseConfig
* `$maxHistory` sets a limit on the number of past requests that are stored, * `$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 * 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. * 0 (zero) to not have any history stored, or -1 for unlimited history.
*
* @var int
*/ */
public $maxHistory = 20; public int $maxHistory = 20;
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -76,10 +72,8 @@ class Toolbar extends BaseConfig
* *
* The full path to the the views that are used by the toolbar. * The full path to the the views that are used by the toolbar.
* This MUST have a trailing slash. * This MUST have a trailing slash.
*
* @var string
*/ */
public $viewsPath = SYSTEMPATH . 'Debug/Toolbar/Views/'; public string $viewsPath = SYSTEMPATH . 'Debug/Toolbar/Views/';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
@ -92,8 +86,37 @@ class Toolbar extends BaseConfig
* with hundreds of queries. * with hundreds of queries.
* *
* `$maxQueries` defines the maximum amount of queries that will be stored. * `$maxQueries` defines the maximum amount of queries that will be stored.
*
* @var int
*/ */
public $maxQueries = 100; 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',
];
} }

View File

@ -23,7 +23,7 @@ class UserAgents extends BaseConfig
* *
* @var array<string, string> * @var array<string, string>
*/ */
public $platforms = [ public array $platforms = [
'windows nt 10.0' => 'Windows 10', 'windows nt 10.0' => 'Windows 10',
'windows nt 6.3' => 'Windows 8.1', 'windows nt 6.3' => 'Windows 8.1',
'windows nt 6.2' => 'Windows 8', 'windows nt 6.2' => 'Windows 8',
@ -78,7 +78,7 @@ class UserAgents extends BaseConfig
* *
* @var array<string, string> * @var array<string, string>
*/ */
public $browsers = [ public array $browsers = [
'OPR' => 'Opera', 'OPR' => 'Opera',
'Flock' => 'Flock', 'Flock' => 'Flock',
'Edge' => 'Spartan', 'Edge' => 'Spartan',
@ -119,7 +119,7 @@ class UserAgents extends BaseConfig
* *
* @var array<string, string> * @var array<string, string>
*/ */
public $mobiles = [ public array $mobiles = [
// legacy array, old values commented out // legacy array, old values commented out
'mobileexplorer' => 'Mobile Explorer', 'mobileexplorer' => 'Mobile Explorer',
// 'openwave' => 'Open Wave', // 'openwave' => 'Open Wave',
@ -228,7 +228,7 @@ class UserAgents extends BaseConfig
* *
* @var array<string, string> * @var array<string, string>
*/ */
public $robots = [ public array $robots = [
'googlebot' => 'Googlebot', 'googlebot' => 'Googlebot',
'msnbot' => 'MSNBot', 'msnbot' => 'MSNBot',
'baiduspider' => 'Baiduspider', 'baiduspider' => 'Baiduspider',

View File

@ -3,12 +3,10 @@
namespace Config; namespace Config;
use CodeIgniter\Config\BaseConfig; use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Validation\CreditCardRules; use CodeIgniter\Validation\StrictRules\CreditCardRules;
use CodeIgniter\Validation\FileRules; use CodeIgniter\Validation\StrictRules\FileRules;
use CodeIgniter\Validation\FormatRules; use CodeIgniter\Validation\StrictRules\FormatRules;
use CodeIgniter\Validation\Rules; use CodeIgniter\Validation\StrictRules\Rules;
//use Validation\CustomValidation;
class Validation extends BaseConfig class Validation extends BaseConfig
{ {
@ -20,14 +18,13 @@ class Validation extends BaseConfig
* Stores the classes that contain the * Stores the classes that contain the
* rules that are available. * rules that are available.
* *
* @var string[] * @var list<string>
*/ */
public $ruleSets = [ public array $ruleSets = [
Rules::class, Rules::class,
FormatRules::class, FormatRules::class,
FileRules::class, FileRules::class,
CreditCardRules::class, CreditCardRules::class,
CustomValidation::class
]; ];
/** /**
@ -36,7 +33,7 @@ class Validation extends BaseConfig
* *
* @var array<string, string> * @var array<string, string>
*/ */
public $templates = [ public array $templates = [
'list' => 'CodeIgniter\Validation\Views\list', 'list' => 'CodeIgniter\Validation\Views\list',
'single' => 'CodeIgniter\Validation\Views\single', 'single' => 'CodeIgniter\Validation\Views\single',
]; ];
@ -44,16 +41,4 @@ class Validation extends BaseConfig
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Rules // Rules
// -------------------------------------------------------------------- // --------------------------------------------------------------------
public function validateLogin(string $str, string $fields, array $data){
$email = $data['email'];
$db = \Config\Database::connect();
$sql = "SELECT userid, password FROM users WHERE email_1='$email'";
$query = $db->query($sql);
$user = $query->getRow();
if(!$user) return false;
return password_verify($data['password'], $user->password );
}
} }

View File

@ -5,6 +5,10 @@ namespace Config;
use CodeIgniter\Config\View as BaseView; use CodeIgniter\Config\View as BaseView;
use CodeIgniter\View\ViewDecoratorInterface; use CodeIgniter\View\ViewDecoratorInterface;
/**
* @phpstan-type parser_callable (callable(mixed): mixed)
* @phpstan-type parser_callable_string (callable(mixed): mixed)&string
*/
class View extends BaseView class View extends BaseView
{ {
/** /**
@ -30,7 +34,8 @@ class View extends BaseView
* { title|esc(js) } * { title|esc(js) }
* { created_on|date(Y-m-d)|esc(attr) } * { created_on|date(Y-m-d)|esc(attr) }
* *
* @var array * @var array<string, string>
* @phpstan-var array<string, parser_callable_string>
*/ */
public $filters = []; public $filters = [];
@ -39,7 +44,8 @@ class View extends BaseView
* by the core Parser by creating aliases that will be replaced with * by the core Parser by creating aliases that will be replaced with
* any callable. Can be single or tag pair. * any callable. Can be single or tag pair.
* *
* @var array * @var array<string, callable|list<string>|string>
* @phpstan-var array<string, list<parser_callable_string>|parser_callable_string|parser_callable>
*/ */
public $plugins = []; public $plugins = [];
@ -50,7 +56,7 @@ class View extends BaseView
* *
* All classes must implement CodeIgniter\View\ViewDecoratorInterface * All classes must implement CodeIgniter\View\ViewDecoratorInterface
* *
* @var class-string<ViewDecoratorInterface>[] * @var list<class-string<ViewDecoratorInterface>>
*/ */
public array $decorators = []; public array $decorators = [];
} }

View File

@ -15,10 +15,22 @@ class Activities extends Controller {
function __construct() { function __construct() {
$this->data['medias'] = array('WA'=>'Whatsapp', 'PH'=> 'Phone', 'VB' => 'Verbal', 'LT'=>'Letter', 'CRM'=>'Direct CRM', 'SKP'=>'Skype'); $this->data['medias'] = array('WA'=>'Whatsapp', 'PH'=> 'Phone', 'VB' => 'Verbal', 'LT'=>'Letter', 'CRM'=>'Direct CRM', 'SKP'=>'Skype');
$this->data['actions'] = array('r'=>'Remote', 'p'=> 'Phone', 'o'=>'On site'); $this->data['actions'] = array('r'=>'Remote', 'p'=> 'Phone', 'o'=>'On site');
$this->data['userpos'] = array(''=>'ALL', 'IT'=> 'IT', 'IVD'=>'IVD', 'PS'=>'Product Specialist'); $this -> data['userpos'] = array(
'' => 'ALL',
'TSO' => 'ALL - TSO',
'IT' => 'IT',
'IVD' => 'IVD',
'IVDT' => 'IVD - Barat',
'IVDH' => 'IVD - Tengah',
'IVDR' => 'IVD - Timur',
'MT' => 'Marketing',
'PS' => 'Product Specialist',
);
$this->data['stats'] = array('O'=>'Open', 'A'=>'Accepted', 'P'=>'Pending', 'C'=> 'Close', 'S' => 'Suspend', 'D' => 'Disable'); $this->data['stats'] = array('O'=>'Open', 'A'=>'Accepted', 'P'=>'Pending', 'C'=> 'Close', 'S' => 'Suspend', 'D' => 'Disable');
$this->data['actbys'] = array( 'P'=>'Product ( Equipment / System )' , 'V'=> 'Vendor', 'C'=>'Consumables / Reagent', 'O'=>'Other'); $this->data['actbys'] = array( 'P'=>'Product ( Equipment / System )' , 'V'=> 'Vendor', 'C'=>'Consumables / Reagent', 'O'=>'Other');
$this->data['exports'] = array('P'=>'PDF', 'E'=> 'Excel'); $this->data['exports'] = array('P'=>'PDF', 'E'=> 'Excel');
$this->data['acttypes'] = array(1=>'Incident Report', 2=> 'Change Request', 3=>'Project', 4=>'Support', 5=>'Maintenance', 6=>'Training', 7=>'Refurbish', 9=>'Training Customer/TSO');
// invtrans // invtrans
$this->data['itx_apprtypes'] = array('W'=>'Warranty', 'U'=> 'User'); $this->data['itx_apprtypes'] = array('W'=>'Warranty', 'U'=> 'User');
$this->data['itx_conditions'] = array('N'=>'New', 'U'=> 'Used', 'R'=>'Refurbished'); $this->data['itx_conditions'] = array('N'=>'New', 'U'=> 'Used', 'R'=>'Refurbished');
@ -32,7 +44,7 @@ class Activities extends Controller {
$data = array(); $data = array();
$db = \Config\Database::connect(); $db = \Config\Database::connect();
$sql = "SELECT * FROM sites"; $sql = "SELECT * FROM sites WHERE enddate IS NULL";
$query = $db->query($sql); $query = $db->query($sql);
$results = $query->getResultArray(); $results = $query->getResultArray();
$data['sites'] = $results; $data['sites'] = $results;
@ -54,6 +66,8 @@ class Activities extends Controller {
$data['actbys'] = $this->data['actbys']; $data['actbys'] = $this->data['actbys'];
$data['stats'] = $this->data['stats']; $data['stats'] = $this->data['stats'];
$data['acttypes'] = $this->data['acttypes'];
$data['actions'] = $this->data['actions'];
if( $this->request->getPost('opendate') == '' ){ $opendate = date("Y-m-01"); } if( $this->request->getPost('opendate') == '' ){ $opendate = date("Y-m-01"); }
else { $opendate = $this->request->getPost('opendate'); } else { $opendate = $this->request->getPost('opendate'); }
@ -68,6 +82,8 @@ class Activities extends Controller {
$detail_activity = $this->request->getPost('detail_activity'); $detail_activity = $this->request->getPost('detail_activity');
$productaliasid = $this->request->getPost('productaliasid'); $productaliasid = $this->request->getPost('productaliasid');
$actbys = $this->request->getPost('actbys'); $actbys = $this->request->getPost('actbys');
$acttypes = $this->request->getPost('acttypes');
$actions = $this->request->getPost('actions');
if($siteid != '') { if($siteid != '') {
$sql = "SELECT p.*, pc.`productname`, p.`productnumber` $sql = "SELECT p.*, pc.`productname`, p.`productnumber`
@ -91,8 +107,17 @@ class Activities extends Controller {
if($sub == 'IT'){ $filterquery .= " and up.userposid in (3,5) "; } if($sub == 'IT'){ $filterquery .= " and up.userposid in (3,5) "; }
if($sub == 'IVD'){ $filterquery .= " and up.userposid in (2,4) "; } if($sub == 'IVD'){ $filterquery .= " and up.userposid in (2,4) "; }
if($sub == 'PS'){ $filterquery .= " and up.userposid in (6,14) "; } if($sub == 'PS'){ $filterquery .= " and up.userposid in (6,14) "; }
if($detail_activity != ''){$filterquery .= " and ad.textvalue LIKE '%$detail_activity%' "; } if($detail_activity != '') {
$column_detail_activity = ", ad.*";
$join_detail_activity = " left join actdetail ad on a.actid=ad.actid ";
$filterquery .= " and ad.textvalue LIKE '%$detail_activity%' ";
} else {
$column_detail_activity = "";
$join_detail_activity = "";
}
if($actbys != ''){$filterquery .= " and a.actby = '$actbys'";} if($actbys != ''){$filterquery .= " and a.actby = '$actbys'";}
if($acttypes != ''){$filterquery .= " and a.acttypeid = $acttypes";}
if($actions != ''){$filterquery .= " and a.action = '$actions'";}
$areaquery = ''; $areaquery = '';
if($areaid != ''){ $areaquery .= " and a.siteid in ( select siteid from v_siteaccount where areaid='$areaid' ) "; } if($areaid != ''){ $areaquery .= " and a.siteid in ( select siteid from v_siteaccount where areaid='$areaid' ) "; }
@ -113,10 +138,13 @@ class Activities extends Controller {
$data['areaid'] = $areaid; $data['areaid'] = $areaid;
$data['detail_activity'] = $detail_activity; $data['detail_activity'] = $detail_activity;
$data['actby'] = $actbys; $data['actby'] = $actbys;
$data['acttype'] = $acttypes;
$data['action'] = $actions;
$sql = "SELECT s.sitename, pc.productname, v.vendorname ,u.firstname as username,uc.firstname as creator_name, up.userposid, at.fulltext, a.*, ad.* $sql = "SELECT s.sitename, pc.productname, v.vendorname ,u.firstname as username,uc.firstname as creator_name, up.userposid, at.fulltext, a.*
$column_detail_activity
FROM `activities` a FROM `activities` a
left join actdetail ad on a.actid=ad.actid $join_detail_activity
left join sites s on s.siteid=a.siteid left join sites s on s.siteid=a.siteid
left join products p on a.productid=p.productid left join products p on a.productid=p.productid
left join productcatalog pc on pc.catalogid=p.catalogid left join productcatalog pc on pc.catalogid=p.catalogid
@ -133,6 +161,30 @@ class Activities extends Controller {
OR ( a.activitystatus='P' $filterquery ) OR ( a.activitystatus='P' $filterquery )
GROUP BY a.actid GROUP BY a.actid
order by field(a.activitystatus,'O','C','R'), a.closedate desc, a.reportdate desc"; order by field(a.activitystatus,'O','C','R'), a.closedate desc, a.reportdate desc";
// $sql = "SELECT s.sitename, pc.productname, v.vendorname, u.firstname AS username, up.userposid, at.fulltext, a.*
// -- ,ad.*
// FROM
// activities a
// -- LEFT JOIN actdetail ad ON a.actid = ad.actid
// LEFT JOIN sites s ON s.siteid = a.siteid
// LEFT JOIN products p ON a.productid = p.productid
// LEFT JOIN productcatalog pc ON pc.catalogid = p.catalogid
// LEFT JOIN vendors v ON v.vendorid = a.vendorid
// LEFT JOIN productalias pa ON pa.productaliasid = pc.productaliasid
// LEFT JOIN users u ON u.userid = a.userid_owner
// LEFT JOIN userposition up ON up.userposid = u.userposid
// LEFT JOIN acttype at ON at.acttypeid = a.acttypeid
// WHERE (
// a.closedate BETWEEN '$opendate 00:00:00' AND '$closedate 23:59:59'
// $filterquery $areaquery
// OR ( a.activitystatus in ('O','P') $filterquery $areaquery )
// )
// GROUP BY a.actid
// ORDER BY
// FIELD(a.activitystatus, 'O', 'C', 'R'),
// a.closedate DESC,
// a.reportdate DESC;";
//echo "$sql"; //echo "$sql";
$query = $db->query($sql); $query = $db->query($sql);
$result = $query->getResultArray(); $result = $query->getResultArray();
@ -142,12 +194,52 @@ class Activities extends Controller {
return view('activities_index', $data); return view('activities_index', $data);
} }
public function index_getproduct($siteid=null){ // public function index_getproduct($siteid=null){
// $db = \Config\Database::connect();
// $sql = "SELECT p.*, pc.`productname`, p.`productnumber`
// FROM products p
// LEFT JOIN productcatalog pc ON pc.`catalogid`=p.`catalogid`
// WHERE p.siteid=$siteid and productaliasid<>0 order by pc.productname";
// $query = $db->query($sql);
// $results = $query->getResultArray();
// $option = "<option value=''>--</option>";
// foreach ($results as $data) {
// $qproductid = $data['productid'];
// $qproductname = $data['productname'];
// $qproductnumber = $data['productnumber'];
// $qproductlocationenddate = $data['locationenddate'];
// if($qproductlocationenddate == NULL){
// $option .= "<option value='$qproductid'>$qproductname ( SN# $qproductnumber )</option>\r\n";
// //$option .= "$qproductid $qproductname $qproductnumber<br/>";
// }
// }
// //echo "$option";
// return $option;
// }
public function index_getproduct($siteid, $productaliasid){
$db = \Config\Database::connect(); $db = \Config\Database::connect();
$sql = "SELECT p.*, pc.`productname`, p.`productnumber`
FROM products p // Kondisi untuk tiap form
LEFT JOIN productcatalog pc ON pc.`catalogid`=p.`catalogid` if ($siteid == 'none' && $productaliasid != 'none') {
WHERE p.siteid=$siteid and productaliasid<>0 order by pc.productname"; $query = "WHERE pa.productaliasid=$productaliasid";
} else if ($siteid != 'none' && $productaliasid == 'none') {
$query = "WHERE p.siteid=$siteid";
} else {
$query = "WHERE pa.productaliasid=$productaliasid and p.siteid=$siteid";
}
$sql = "SELECT p.*, pc.productname FROM productalias pa
LEFT JOIN productcatalog pc ON pa.productaliasid = pc.productaliasid
LEFT JOIN products p ON pc.catalogid = p.catalogid
LEFT JOIN sites s ON p.siteid = s.siteid
$query ORDER BY pc.productname";
// Kondisi apabila kedua form kosong
if ($siteid == 'none' && $productaliasid == 'none') {
return "<option value=''>--</option>";
}
$query = $db->query($sql); $query = $db->query($sql);
$results = $query->getResultArray(); $results = $query->getResultArray();
$option = "<option value=''>--</option>"; $option = "<option value=''>--</option>";
@ -227,7 +319,7 @@ class Activities extends Controller {
$sql = " SELECT u.*, c.`productname`, c.catalognumber FROM unitgroup u $sql = " SELECT u.*, c.`productname`, c.catalognumber FROM unitgroup u
LEFT JOIN productcatalog c ON u.`catalogid`=c.`catalogid` LEFT JOIN productcatalog c ON u.`catalogid`=c.`catalogid`
WHERE c.productaliasid<>0"; WHERE c.productaliasid<>0 AND u.`enddate` IS NULL";
$query = $db->query($sql); $query = $db->query($sql);
$results = $query->getResultArray(); $results = $query->getResultArray();
$data['unitgroup'] = $results; $data['unitgroup'] = $results;
@ -281,6 +373,7 @@ class Activities extends Controller {
'acttextid' => $this->request->getVar('acttextid'), 'acttextid' => $this->request->getVar('acttextid'),
'textvalue' => $this->request->getVar('textvalue') 'textvalue' => $this->request->getVar('textvalue')
]; ];
$actby = $this->request->getVar('actby'); $actby = $this->request->getVar('actby');
if($actby == 'P') { if($actby == 'P') {
$data['new_value']['productid'] = $this->request->getVar('productid'); $data['new_value']['productid'] = $this->request->getVar('productid');
@ -299,6 +392,20 @@ class Activities extends Controller {
if($this->validate($rules)) { if($this->validate($rules)) {
$db = \Config\Database::connect(); $db = \Config\Database::connect();
if($actid == 0) { if($actid == 0) {
// Cek apakah ada duplikasi data
$exists = $db->table('activities')
->where('subject', $data['new_value']['subject'])
->where('siteid', $data['new_value']['siteid'])
->where('reportdate', $data['new_value']['reportdate'])
->where('opendate', $data['new_value']['opendate'])
->where('closedate', $data['new_value']['closedate'])
->where('userid_creator', $data['new_value']['userid_creator'])
->get()->getRow();
if ($exists) { // Jika ada maka Redirect
return redirect()->to('/activities');
}
// Create Activities // Create Activities
$activitiesModel = new ActivitiesModel(); $activitiesModel = new ActivitiesModel();
$activitiesModel->set('createdate', 'NOW()', FALSE); $activitiesModel->set('createdate', 'NOW()', FALSE);
@ -324,6 +431,31 @@ class Activities extends Controller {
$activitiesModel = new ActivitiesModel(); $activitiesModel = new ActivitiesModel();
$activitiesModel->update($actid,$data['new_value']); $activitiesModel->update($actid,$data['new_value']);
// clear other act by
if($actby == 'P') { // product
$sql = "update activities set vendorid=null where actid='$actid'";
$query = $db->query($sql);
$sql = "delete from actconsumables where actid='$actid'";
$query = $db->query($sql);
} elseif($actby == 'V') { // vendor
$sql = "update activities set productid=null where actid='$actid'";
$query = $db->query($sql);
$sql = "delete from actconsumables where actid='$actid'";
$query = $db->query($sql);
} elseif($actby == 'C') { // consumables
$sql = "update activities set productid=null where actid='$actid'";
$query = $db->query($sql);
$sql = "update activities set vendorid=null where actid='$actid'";
$query = $db->query($sql);
} else { // other
$sql = "update activities set productid=null where actid='$actid'";
$query = $db->query($sql);
$sql = "update activities set vendorid=null where actid='$actid'";
$query = $db->query($sql);
$sql = "delete from actconsumables where actid='$actid'";
$query = $db->query($sql);
}
// Apabila Act Status Diubah Maka Kondisi berikut dijalankan // Apabila Act Status Diubah Maka Kondisi berikut dijalankan
$tb_actstatus_log = $db->table('actstatus_log'); $tb_actstatus_log = $db->table('actstatus_log');
$actstatus_old = $tb_actstatus_log->select('activitystatus')->where('activityid', $actid)->orderBy('logdate', 'DESC')->get()->getRowArray(); $actstatus_old = $tb_actstatus_log->select('activitystatus')->where('activityid', $actid)->orderBy('logdate', 'DESC')->get()->getRowArray();
@ -363,7 +495,7 @@ class Activities extends Controller {
} }
} }
// actcon // act by consumables
$actconid_delete = $this->request->getVar('actconid_delete'); $actconid_delete = $this->request->getVar('actconid_delete');
if($actconid_delete != '') { if($actconid_delete != '') {
$actconid_del = explode(' ',$actconid_delete); $actconid_del = explode(' ',$actconid_delete);
@ -448,7 +580,9 @@ class Activities extends Controller {
$sql = "SELECT p.*, pc.`productname`, p.`productnumber` $sql = "SELECT p.*, pc.`productname`, p.`productnumber`
FROM products p FROM products p
LEFT JOIN productcatalog pc ON pc.`catalogid`=p.`catalogid` LEFT JOIN productcatalog pc ON pc.`catalogid`=p.`catalogid`
WHERE p.siteid=$siteid and productaliasid<>0 order by pc.productname"; LEFT JOIN producttype pt ON pt.`producttypeid`= pc.`producttypeid`
WHERE p.siteid=$siteid and productaliasid<>0
ORDER BY FIELD(pt.producttypeid, 20, 19, 21, 12, 10, 14, 11, 13, 4, 3) DESC, pc.productname";
$query = $db->query($sql); $query = $db->query($sql);
$results = $query->getResultArray(); $results = $query->getResultArray();
$data['products'] = $results; $data['products'] = $results;
@ -517,7 +651,7 @@ class Activities extends Controller {
} }
} }
public function act_content($actid, $filter_email=false) { public function act_content($actid, $filter_email=false) { // Parameter Ke-2 Untuk Email
$db = \Config\Database::connect(); $db = \Config\Database::connect();
$sql = "select a.*, v.vendorname, v2.vendorname as vendorname_2, u.firstname, u.lastname, atyp.fulltext, atyp.acttypecode, s.sitename, pc.productname, c.firstname as cfname, c.lastname as clname, p.productnumber $sql = "select a.*, v.vendorname, v2.vendorname as vendorname_2, u.firstname, u.lastname, atyp.fulltext, atyp.acttypecode, s.sitename, pc.productname, c.firstname as cfname, c.lastname as clname, p.productnumber
from activities a from activities a
@ -545,12 +679,13 @@ class Activities extends Controller {
} }
$data['stats'] = $this->data['stats']; $data['stats'] = $this->data['stats'];
$filter_email = $filter_email === true ? ' AND ad.acttextid NOT IN(3) ' : ' '; // Filter Tidak Menampilkan Internal Note
$filter_internalnote = $filter_email === true ? ' AND ad.acttextid NOT IN(3) ' : ' ';
$sql = "SELECT ad.*, ate.`fulltext` AS acttextname $sql = "SELECT ad.*, ate.`fulltext` AS acttextname
FROM actdetail ad FROM actdetail ad
LEFT JOIN acttext ate ON ate.`acttextid`=ad.`acttextid` LEFT JOIN acttext ate ON ate.`acttextid`=ad.`acttextid`
WHERE ad.actid=$actid $filter_email WHERE ad.actid=$actid $filter_internalnote -- Filter Email
ORDER BY CASE ORDER BY CASE
WHEN ad.acttextid = 1 THEN 1 WHEN ad.acttextid = 1 THEN 1
WHEN ad.acttextid = 5 THEN 5 WHEN ad.acttextid = 5 THEN 5
@ -571,10 +706,22 @@ class Activities extends Controller {
$data['activities'][0]['action'] = $actions[$data['activities'][0]['action']]; $data['activities'][0]['action'] = $actions[$data['activities'][0]['action']];
} }
$data['itx_purposes'] = $this->data['itx_purposes'];
// Filter Email Hanya Menampilkan Replace Saja ke Customers
if ($filter_email === true){
$sql = "SELECT pc.`catalognumber`, pc.`productname`, i.`lotnumber`, i.qty, u.unit FROM invtrans i $sql = "SELECT pc.`catalognumber`, pc.`productname`, i.`lotnumber`, i.qty, u.unit FROM invtrans i
LEFT JOIN unitgroup u ON u.`unitgroupid`=i.`unitgroupid` LEFT JOIN unitgroup u ON u.`unitgroupid`=i.`unitgroupid`
LEFT JOIN productcatalog pc ON pc.`catalogid`=u.`catalogid` LEFT JOIN productcatalog pc ON pc.`catalogid`=u.`catalogid`
where i.actid='$actid'"; WHERE i.actid='$actid' AND i.`purpose` IN ('PR', 'PB', 'PU', 'PF')
GROUP BY pc.`catalognumber` ORDER BY i.itxid";
} else {
$sql = "SELECT pc.`catalognumber`, pc.`productname`, i.`lotnumber`, i.qty, i.`purpose`, u.unit FROM invtrans i
LEFT JOIN unitgroup u ON u.`unitgroupid`=i.`unitgroupid`
LEFT JOIN productcatalog pc ON pc.`catalogid`=u.`catalogid`
WHERE i.actid='$actid'";
}
$query = $db->query($sql); $query = $db->query($sql);
$result = $query->getResultArray(); $result = $query->getResultArray();
$data['invtrans'] = $result; $data['invtrans'] = $result;
@ -599,6 +746,57 @@ class Activities extends Controller {
return view('activities_detail', $data); return view('activities_detail', $data);
} }
public function servicereport($actid){
$db = \Config\Database::connect();
$data['actid'] = $actid;
$sql = "select a.*, v.vendorname, v2.vendorname as vendorname_2, u.firstname, u.lastname, atyp.fulltext,
atyp.acttypecode, s.sitename, pc.productname, c.firstname as cfname, c.lastname as clname, p.productnumber
from activities a
left join users u on a.userid_owner=u.userid
left join acttype atyp on a.acttypeid=atyp.acttypeid
left join sites s on a.siteid=s.siteid
left join products p on a.productid=p.productid
left join productcatalog pc on p.catalogid=pc.catalogid
left join vendors v on v.vendorid=pc.vendorid
left join vendors v2 on v2.vendorid=a.vendorid
left join contacts c on a.contactid=c.contactid
where actid='$actid'";
$query = $db->query($sql);
$result = $query->getResultArray();
$data['activities'] = $result;
$sql = "SELECT ad.*, ate.`fulltext` AS acttextname
FROM actdetail ad
LEFT JOIN acttext ate ON ate.`acttextid`=ad.`acttextid`
WHERE ad.actid=$actid
ORDER BY CASE
WHEN ad.acttextid = 1 THEN 1
WHEN ad.acttextid = 5 THEN 5
WHEN ad.acttextid = 2 THEN 2
WHEN ad.acttextid = 3 THEN 3
WHEN ad.acttextid = 6 THEN 4
WHEN ad.acttextid = 34 THEN 5
WHEN ad.acttextid = 4 THEN 99
ELSE 6 END";
$query = $db->query($sql);
$result = $query->getResultArray();
$data['actdetails'] = $result;
$sql = "SELECT pc.`catalognumber`, pc.`productname`, i.`lotnumber`, i.qty, u.unit, i.purpose FROM invtrans i
LEFT JOIN unitgroup u ON u.`unitgroupid`=i.`unitgroupid`
LEFT JOIN productcatalog pc ON pc.`catalogid`=u.`catalogid`
WHERE i.actid='$actid' AND i.`purpose` IN ('PR', 'PB', 'PU', 'PF')
GROUP BY pc.`catalognumber` ORDER BY i.itxid";
$query = $db->query($sql);
$result = $query->getResultArray();
$data['invtrans'] = $result;
$data['purposes'] = $this->data['itx_purposes'];
return view('activities_servicereport', $data);
}
public function count(){ public function count(){
$db = \Config\Database::connect(); $db = \Config\Database::connect();
$opendate = date("Y-m-01"); $opendate = date("Y-m-01");
@ -610,10 +808,17 @@ class Activities extends Controller {
$pos = $this->request->getPost('pos'); $pos = $this->request->getPost('pos');
$sql_pos = ''; $sql_pos = '';
$sql_dept = ''; $sql_dept = '';
if($pos == 'IVD') { $sql_dept = 'AND u.userdeptid = 1'; $sql_pos = 'AND u.userposid in (1,2,4)'; }
if($pos == 'TSO') { $sql_dept = 'AND u.userdeptid = 1';}
elseif($pos == 'IVD') { $sql_dept = 'AND u.userdeptid = 1'; $sql_pos = 'AND u.userposid in (1,2,4)'; }
elseif($pos == 'IVDR') {$sql_dept = 'AND u.userdeptid = 1'; $sql_pos = 'AND u.userposid in (1,2,4) AND (u.userid = 2 OR u.reportto = 2)'; } //Timur
elseif($pos == 'IVDH') {$sql_dept = 'AND u.userdeptid = 1'; $sql_pos = 'AND u.userposid in (1,2,4) AND (u.userid = 10 OR u.reportto = 10)'; } //Tengah
elseif($pos == 'IVDT') {$sql_dept = 'AND u.userdeptid = 1'; $sql_pos = 'AND u.userposid in (1,2,4) AND (u.userid = 3 OR u.reportto = 3)'; } //Barat
elseif($pos == 'IT') {$sql_dept = 'AND u.userdeptid = 1'; $sql_pos = 'AND u.userposid in (1,3,5)'; } elseif($pos == 'IT') {$sql_dept = 'AND u.userdeptid = 1'; $sql_pos = 'AND u.userposid in (1,3,5)'; }
elseif($pos == 'PS') {$sql_dept = 'AND u.userdeptid = 2'; $sql_pos = 'AND u.userposid in (6,14)'; } elseif($pos == 'PS') {$sql_dept = 'AND u.userdeptid = 2'; $sql_pos = 'AND u.userposid in (6,14)'; }
$sql = "SELECT u.firstname, u.lastname, u.userdeptid, u.userid, elseif($pos == 'MT') {$sql_dept = 'AND u.userdeptid = 2'; $sql_pos = 'AND u.userposid in (6,14)'; }
$sql = "SELECT u.firstname, u.lastname, u.userdeptid, u.userid, u.userposid,
SUM(CASE WHEN aty.acttypecode='CR' THEN 1 ELSE 0 END) AS CR, SUM(CASE WHEN aty.acttypecode='CR' THEN 1 ELSE 0 END) AS CR,
SUM(CASE WHEN aty.acttypecode='IR' THEN 1 ELSE 0 END) AS IR, SUM(CASE WHEN aty.acttypecode='IR' THEN 1 ELSE 0 END) AS IR,
SUM(CASE WHEN aty.acttypecode='MN' THEN 1 ELSE 0 END) AS MN, SUM(CASE WHEN aty.acttypecode='MN' THEN 1 ELSE 0 END) AS MN,
@ -760,7 +965,7 @@ class Activities extends Controller {
$message = $this->request->getVar('message'); $message = $this->request->getVar('message');
$attachment = $this->request->getVar('attachment'); $attachment = $this->request->getVar('attachment');
$attachments = explode(',',$attachment); $attachments = explode(',',$attachment);
/*
$email->setFrom('noreply@services.summit.co.id', 'SUMMIT CRM'); $email->setFrom('noreply@services.summit.co.id', 'SUMMIT CRM');
$email->setReplyTo($replyto); $email->setReplyTo($replyto);
$email->setTo(cleanmail($to)); $email->setTo(cleanmail($to));
@ -774,21 +979,53 @@ class Activities extends Controller {
$email->attach($attachment); $email->attach($attachment);
} }
} }
$email->send(); //$email->set_newline("\r\n");
/* //$email->send();
echo "<script type='text/javascript'>";
echo "window.close();";
echo "</script>";
*/
# debugging email CI4 # debugging email CI4
//$email->send(FALSE); //$email->send(FALSE);
$myfile = fopen("log.txt", "a+") or die("Unable to open file!");
if ( $email->send(FALSE) ) {
fwrite($myfile, "\nemail sent success");
} else {
fwrite($myfile, "\n".$email->printDebugger() );
}
fclose($myfile);
*/
$tos = join(",",$to); $tos = join(",",$to);
if(isset($cc)) { $ccs = join(",",$cc); } else { $ccs = ''; } if(isset($cc)) { $ccs = join(",",$cc); } else { $ccs = ''; }
if(isset($bcc)) { $bccs = join(",",$bcc); } else { $bccs = ''; } if(isset($bcc)) { $bccs = join(",",$bcc); } else { $bccs = ''; }
$sql = "insert into actsend_log (actid, replyto, emailto, emailcc, emailbcc, logdate) values ( '$actid', '$replyto', '$tos', '$ccs', '$bccs', NOW() )"; $sql = "insert into actsend_log (actid, replyto, emailto, emailcc, emailbcc, logdate) values ( '$actid', '$replyto', '$tos', '$ccs', '$bccs', NOW() )";
//echo "$sql";
$query = $db->query($sql); $query = $db->query($sql);
//return $email->printDebugger();
$data = [
'replyto' => $replyto,
'to' => $tos,
'cc' => $ccs,
'bcc' => $bccs,
'subject' => $subject,
'message' => $message,
'attachment' => $attachment,
];
$jsonData = json_encode($data);
//print_r($jsonData);
//$url = 'http://localhost/work/phpmailer/server.php';
$url = 'https://sadewa.services-summit.my.id/server.php';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type:application/json']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if(curl_errno($ch)) { echo 'Curl error: '.curl_error($ch); }
//echo "sending email";
//echo "$jsonData <br/>";
//echo "<pre>$response</pre>";
curl_close($ch);
/*
$myfile = fopen("log.txt", "a+") or die("Unable to open file!");
fwrite($myfile,$response);
fclose($myfile);
*/
return redirect()->to('activities/'); return redirect()->to('activities/');
} else { } else {
return view('activities_compose', $data); return view('activities_compose', $data);

55
app/Controllers/Api.php Normal file
View File

@ -0,0 +1,55 @@
<?php
namespace App\Controllers;
class Api extends BaseController {
// getProductList for CLQMS
// public function getProductList() {
// $db = \Config\Database::connect();
// $sql = "SELECT p.`productid`, s.`sitename`, pc.`productname`, p.`productnumber` FROM products p
// LEFT JOIN sites s ON p.`siteid`=s.`siteid`
// LEFT JOIN productcatalog pc ON p.`catalogid`=pc.`catalogid`
// WHERE pc.`producttypeid`=3 AND p.`locationenddate` IS NULL";
// $query = $db->query($sql);
// $data = $query->getResultArray();
// if(count($data)==0) { $data = array('status' => 'error', 'message' => 'No data found'); }
// else {
// header('Content-Type: application/json');
// echo json_encode($data);
// }
// }
public function getProductAlias() {
$db = \Config\Database::connect();
$sql = "SELECT productaliasid, productaliastext
FROM productalias order by productaliasid";
$query = $db->query($sql);
$data = $query->getResultArray();
if(count($data)==0) { $data = array('status' => 'error', 'message' => 'No data found'); }
else {
header('Content-Type: application/json');
echo json_encode($data);
}
}
public function getProductSites() {
$db = \Config\Database::connect();
$sql = "SELECT pc.productaliasid, p.productnumber, s.sitename
FROM products p
LEFT JOIN productcatalog pc on pc.catalogid=p.catalogid
LEFT JOIN sites s on s.siteid=p.siteid
WHERE pc.productaliasid IN (18,19,20,21,60) ORDER BY pc.productaliasid";
$query = $db->query($sql);
$data = $query->getResultArray();
if (count($data) === 0) {
return $this->response->setJSON([
'status' => 'error',
'message' => 'No data found'
]);
}
return $this->response->setJSON($data);
}
}

View File

@ -33,12 +33,18 @@ abstract class BaseController extends Controller
* class instantiation. These helpers will be available * class instantiation. These helpers will be available
* to all other controllers that extend BaseController. * to all other controllers that extend BaseController.
* *
* @var array * @var list<string>
*/ */
protected $helpers = []; protected $helpers = [];
/** /**
* Constructor. * 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) public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{ {
@ -47,6 +53,6 @@ abstract class BaseController extends Controller
// Preload any models, libraries, etc, here. // Preload any models, libraries, etc, here.
// E.g.: $this->session = \Config\Services::session(); // E.g.: $this->session = service('session');
} }
} }

47
app/Controllers/Clqms.php Normal file
View File

@ -0,0 +1,47 @@
<?php
namespace App\Controllers;
class Clqms extends BaseController {
private function getProductList() {
$curl = curl_init();
curl_setopt_array($curl, array(
//CURLOPT_URL => 'http://summitcrm.local/api/getProductList',
CURLOPT_URL => 'https://clqms.services-summit.my.id/api/getProductList',
#CURLOPT_URL => 'http://clqms-server.local/api/getProductList',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
));
$response = curl_exec($curl);
curl_close($curl);
$data = json_decode($response, true);
return $data;
}
public function index() {
$db = \Config\Database::connect();
// get data from clqms
$data['clqms_products'] = $this->getProductList();
// query products data from crm
$qproductid = '';
foreach ($data['clqms_products'] as $qdata) {
$qproductid .= $qdata['productid'].",";
}
$qproductid = rtrim($qproductid,',');
$sql = "SELECT p.productid, pc.productname, s.`sitename`, p.`productnumber` FROM products p
LEFT JOIN productcatalog pc ON pc.`catalogid`=p.`catalogid`
LEFT JOIN sites s ON s.`siteid`=p.`siteid`
WHERE p.productid IN ($qproductid)";
$query = $db->query($sql);
$data['products'] = $query->getResultArray();
return view('clqms_index', $data);
}
}

View File

@ -111,8 +111,8 @@ class Dashboard extends BaseController {
where where
(( a.closedate between '$opendate 00:00:00' and '$closedate 23:59:59') (( a.closedate between '$opendate 00:00:00' and '$closedate 23:59:59')
OR ( a.reportdate between '$opendate 00:00:00' and '$closedate 23:59:59') OR ( a.reportdate between '$opendate 00:00:00' and '$closedate 23:59:59')
OR ( a.activitystatus='O') OR ( a.activitystatus='O' and a.opendate >= DATE_SUB(CURDATE(), INTERVAL 3 MONTH))
OR (a.activitystatus = 'P')) OR (a.activitystatus = 'P' and a.opendate >= DATE_SUB(CURDATE(), INTERVAL 3 MONTH)))
AND (a.activitystatus <> 'S') AND (a.activitystatus <> 'S')
order by field(a.activitystatus,'O','C','R'), a.closedate desc, a.reportdate desc"; order by field(a.activitystatus,'O','C','R'), a.closedate desc, a.reportdate desc";
$query = $db->query($sql); $query = $db->query($sql);

View File

@ -116,7 +116,7 @@ class InvTrans extends BaseController {
$data['conditions'] = $this->data['itx_conditions']; $data['conditions'] = $this->data['itx_conditions'];
$sql = "SELECT u.*, c.`productname`, c.catalognumber FROM unitgroup u $sql = "SELECT u.*, c.`productname`, c.catalognumber FROM unitgroup u
LEFT JOIN productcatalog c ON u.`catalogid`=c.`catalogid`"; LEFT JOIN productcatalog c ON u.`catalogid`=c.`catalogid` WHERE u.`enddate` IS NULL";
$query = $db->query($sql); $query = $db->query($sql);
$results = $query->getResultArray(); $results = $query->getResultArray();
$data['unitgroup'] = $results; $data['unitgroup'] = $results;

249
app/Controllers/Kanban.php Normal file
View File

@ -0,0 +1,249 @@
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
class Kanban extends BaseController {
protected $data = array();
function __construct() {
$this->data['card_priorities'] = array( 'L' => 'Low', 'M' => 'Medium', 'H'=>'High' );
}
public function index() {
$db = \Config\Database::connect();
$sql = "SELECT b.boardid, b.`boardname` FROM kb_boarduser bu
LEFT JOIN kb_boards b ON bu.`boardid`=b.`boardid`
WHERE bu.`userid`=".$_SESSION['userid']." order by b.createdate desc";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['boards'] = $results;
return view('kb_index',$data);
}
public function view($boardid) {
$db = \Config\Database::connect();
// get board data
$sql = "SELECT * FROM kb_boards where boardid=$boardid";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['boards'] = $results;
// lists
$sql = "SELECT * FROM kb_lists where boardid=$boardid order by listindex";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['lists'] = $results;
// cards
$sql = "SELECT u.`firstname`,u.`lastname`, c.* FROM kb_cards c
JOIN users u ON c.`owner_userid`=u.userid
WHERE c.listid IN (SELECT listid FROM kb_lists WHERE boardid='$boardid')";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['cards'] = $results;
$data['card_priorities'] = $this->data['card_priorities'];
return view('kb_view',$data);
}
public function board_edit($boardid) {
$db = \Config\Database::connect();
$sql = "select * from users where enddate is null";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['users'] = $results;
$data['boardid'] = $boardid;
if($boardid != 0) {
$sql = "select * from kb_boards where boardid=$boardid";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['boards'] = $results;
$sql = "select * from kb_lists where boardid=$boardid order by listindex";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['lists'] = $results;
$sql = "select userid from kb_boarduser where boardid=$boardid";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['boarduser'] = $results;
}
if ($this->request->getMethod() === 'post') {
$data = $this->request->getVar();
$boardid = $data['boardid'];
$boardname = $data['boardname'];
$admin_userid = $data['admin_userid'];
$boarduser = $data['boarduser'];
$nboarduser = implode( ',', $boarduser);
$listid_delete = $data['listid_delete'];
if(isset($data['lists'])) {
$lists = $data['lists'];
$listid = $data['listid'];
}
$rules = [
'boardname' => 'required',
'admin_userid' => 'required',
'lists' => 'required'
];
if($this->validate($rules)) {
if($boardid == 0) {
//new board
// board query
$sql = "insert into kb_boards(boardname, admin_userid, createdate) values ( '$boardname', '$admin_userid', NOW() )";
//echo "<br/>$sql";
$query = $db->query($sql);
$boardid = $db->insertID();
//$boardid = "1";
//echo "<br/>$boardid";
// boarduser query
$quser = '';
foreach($boarduser as $quserid ) { $quser .= "($boardid, $quserid),"; }
$quser = rtrim($quser, ',');
$sql = "insert ignore into kb_boarduser(boardid, userid) values $quser";
$query = $db->query($sql);
//echo "<br/>$sql";
// list query
$qlist = '';
foreach($lists as $qlistindex => $qlistname) {
$qlistname = $qlistname;
$qlist .= "('$qlistname', $qlistindex, $boardid, NOW()),";
}
$sql = "insert into kb_lists(listname, listindex, boardid,createdate) values $qlist";
$sql = rtrim($sql, ',');
//echo "<br/>$sql";
$query = $db->query($sql);
return view('form_success');
} else { // edit board
/*
echo "<pre>";
print_r($data);
echo "</pre>";
*/
// board query
$sql = "update kb_boards set boardname='$boardname', admin_userid='$admin_userid' where boardid=$boardid ";
//echo "<br/>$sql";
$query = $db->query($sql);
// boarduser query
$sql = "delete from kb_boarduser where boardid=$boardid and userid not in ($nboarduser)";
//echo "<br/>$sql";
$query = $db->query($sql);
$quser = '';
foreach($boarduser as $quserid ) { $quser .= "($boardid, $quserid),"; }
$quser = rtrim($quser, ',');
$sql = "insert ignore into kb_boarduser (boardid, userid) values $quser";
//echo "<br/>$sql";
$query = $db->query($sql);
// list query
// delete
if( $data['listid_delete'] != '' ) {
$listid_del = $data['listid_delete'];
$sql = "delete from kb_lists where listid in ($listid_del)";
//echo "<br/>$sql";
$query = $db->query($sql);
}
// insert and update
$qlist = '';
foreach($lists as $qlistindex => $qlistname) {
$qlistid = $listid[$qlistindex];
if($qlistid == 0) { $qlist .= "('$qlistname', $qlistindex, $boardid, NOW()),"; }
else {
$sql = "update kb_lists set listname='$qlistname', listindex=$qlistindex where listid=$qlistid";
//echo "<br/>$sql";
$query = $db->query($sql);
}
}
if($qlist != '') {
$sql = "insert into kb_lists(listname, listindex, boardid,createdate) values $qlist";
$sql = rtrim($sql, ',');
//echo "<br/>$sql";
$query = $db->query($sql);
}
return view('form_success');
}
} else { return view('kb_board_edit', $data); }
} else {
return view('kb_board_edit', $data);
}
}
public function list_edit($listid) {
$db = \Config\Database::connect();
$data['listid'] = $listid;
$sql = "select * from kb_lists where listid='$listid'";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['lists'] = $results;
if ($this->request->getMethod() === 'post') {
$data = $this->request->getVar();
$listname = $data['listname'];
$sql = "update kb_lists set listname='$listname' where listid='$listid'";
$query = $db->query($sql);
return view('form_success');
}
return view('kb_list_edit', $data);
}
public function card_edit($listid, $cardid) {
$db = \Config\Database::connect();
$data['listid'] = $listid;
$data['cardid'] = $cardid;
$data['card_priorities'] = $this->data['card_priorities'];
$sql = "select * from users where enddate is null";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['users'] = $results;
$sql = "select * from kb_lists where boardid=(select boardid from kb_lists where listid=$listid)";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['lists'] = $results;
if($cardid != 0) {
$sql = "select * from kb_cards where cardid=$cardid";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['cards'] = $results;
}
if ($this->request->getMethod() === 'post') {
$data = $this->request->getVar();
$listid = $data['listid'];
$cardid = $data['cardid'];
$cardtext = $data['cardtext'];
$owner_userid = $data['owner_userid'];
$priority = $data['priority'];
$creator_userid = $_SESSION['userid'];
$rules = [
'cardtext' => 'required'
];
if($this->validate($rules)) {
if($cardid == 0) {
//new card
$sql = "insert into kb_cards(listid, priority, cardtext, owner_userid, creator_userid, createdate) values ( '$listid', '$priority', '$cardtext', '$owner_userid', '$creator_userid', NOW() )";
$query = $db->query($sql);
return view('form_success');
} else {
$sql = "update kb_cards set listid=$listid, priority='$priority', cardtext='$cardtext', owner_userid='$owner_userid' where cardid=$cardid";
$query = $db->query($sql);
return view('form_success');
}
} else {
}
}
return view('kb_card_edit', $data);
}
public function card_move($listid, $cardid) {
$db = \Config\Database::connect();
echo "card $cardid, list $listid";
$sql = "update kb_cards set listid=$listid where cardid=$cardid";
$query = $db->query($sql);
}
}

124
app/Controllers/Key.php Normal file
View File

@ -0,0 +1,124 @@
<?php
namespace App\Controllers;
use App\Controllers\BaseController;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\API\ResponseTrait;
use App\Models\ProductTempModel;
use DateTime;
class Key extends BaseController
{
use ResponseTrait;
public function index() {
$publicKeyPath = WRITEPATH . 'key/public_key.pem';
if (file_exists($publicKeyPath)) {
//$publicKey = trim(file_get_contents($publicKeyPath));
$publicKey = file_get_contents($publicKeyPath);
return $this->respond([
'publicKey' => $publicKey
]);
} else {
return $this->failNotFound('Public key not found');
}
}
public function data() {
$productTempModel = new ProductTempModel;
$rawData = $this->request->getBody();
$result = json_decode($rawData, true);
$encryptedKeyIv = $result['encryptedKeyIv'];
$encryptedKeyIv = base64_decode($encryptedKeyIv);
$encryptedData = $result['encryptedData'];
$clientChecksum = $result['checksum'];
$privateKeyPath = WRITEPATH . 'key/private_key.pem';
$privateKey = file_get_contents($privateKeyPath);
$privateKeyResource = openssl_pkey_get_private($privateKey);
$decryptedMessage = '';
$result = openssl_private_decrypt($encryptedKeyIv, $decryptedMessage, $privateKeyResource, OPENSSL_PKCS1_OAEP_PADDING);
if ($result) {
$aesKey = substr($decryptedMessage, 0, 32);
$aesIv = substr($decryptedMessage, 32, 16);
$decryptedBytes = openssl_decrypt($encryptedData, 'aes-256-cbc', $aesKey, 0, $aesIv);
$serverChecksum = hash('sha256', $decryptedBytes);
$decryptedData = json_decode($decryptedBytes, true);
$locationStartDate = $decryptedData['locationstartdate'];
$warrantyStartDate = DateTime::createFromFormat('Ymd', $locationStartDate);
if ($warrantyStartDate) {
$warrantyEndDate = clone $warrantyStartDate;
$warrantyEndDate->modify('+1 year');
$formattedWarrantyEndDate = $warrantyEndDate->format('Y-m-d');
} else {
$formattedWarrantyEndDate = null;
}
if ($clientChecksum !== $serverChecksum) {
return $this->fail('Checksum check failed');
} else {
$logQuery = [];
$db = \Config\Database::connect();
$db->transStart();
foreach ($decryptedData['items'] as $value) {
$data = [
'productnumber' => $value['productnumber'],
'productname' => $value['productname'],
'catalognumber' => $value['catalognumber'],
'siteid' => 1,
'locationstartdate' => $locationStartDate,
'locationenddate' => NULL,
'installationdate' => NULL,
'warrantystartdate' => $locationStartDate,
'warrantyenddate' => $formattedWarrantyEndDate,
'active' => 'N',
'owner' => 1,
'statusservice' => 2,
'statusparts' => '',
'userid' => 'SES^' . $decryptedData['userid'],
'reference' => $decryptedData['reference'],
'logdate' => $decryptedData['logdate'],
];
if ($productTempModel->save($data)) {
$logQuery[] = [
'item' => $value['catalognumber'],
'status' => 'success',
'message' => 'Item saved successfully'
];
} else {
$errors = $productTempModel->errors();
$logQuery[] = [
'item' => $value['catalognumber'],
'status' => 'fail',
'message' => 'Failed to save item',
'errors' => $errors
];
$db->transRollback();
return $this->response->setJSON([
'success' => false,
'message' => 'Failed to insert all items. Transaction rolled back.',
'results' => $logQuery
]);
}
}
$db->transCommit();
return $this->response->setJSON([
'success' => true,
'message' => 'Processing completed',
'results' => $logQuery
]);
}
}
}
}

46
app/Controllers/Lqms.php Normal file
View File

@ -0,0 +1,46 @@
<?php
namespace App\Controllers;
use CodeIgniter\API\ResponseTrait;
use CodeIgniter\Controller;
class Lqms extends BaseController {
use ResponseTrait;
public function index() {
$db = \Config\Database::connect();
$sql = "SELECT * FROM lqms_log LimiT 0,30";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['logs'] = $results;
return view('lqms_index', $data);
}
public function postData() {
$db = \Config\Database::connect();
$post = $this->request->getJSON();
$sql = "insert into lqms_log(message) values(".$db->escape(json_encode($post)).")";
$query = $db->query($sql);
$data['post'] = $post;
echo "$sql";
//return $this->respond($data);
/*
echo "<pre>";
print_r(json_encode($post));
echo "</pre>";
*/
}
public function log_clear() {
$db = \Config\Database::connect();
$sql = "DELETE FROM lqms_log";
$query = $db->query($sql);
}
public function log_delete($mesid=null) {
$db = \Config\Database::connect();
$sql = "DELETE FROM lqms_log where mesid=$mesid";
$query = $db->query($sql);
}
}

View File

@ -106,7 +106,7 @@ class ProductCatalog extends Controller {
$data['productalias'] = $results; $data['productalias'] = $results;
if ($this->request->getMethod() === 'post') { if ($this->request->getMethod() === 'post') {
$rules = [ $rules = [
'catalognumber' => 'required', 'catalognumber' => 'required|is_unique[productcatalog.catalognumber]',
'productname' => 'required', 'productname' => 'required',
'producttypeid' => 'required', 'producttypeid' => 'required',
'vendorid' => 'required' 'vendorid' => 'required'

View File

@ -0,0 +1,150 @@
<?php
namespace App\Controllers;
use App\Controllers\BaseController;
use CodeIgniter\HTTP\ResponseInterface;
use App\Models\ProductsModel;
use App\Models\ProductTempModel;
use App\Models\ProductCatalogModel;
class ProductTemp extends BaseController
{
public function index() {
$productsModel = new ProductsModel();
$productTempModel = new ProductTempModel();
$productTypeIds = [3, 10, 11, 12, 13, 14, 21];
$productTemps = $productTempModel
->select('producttemp.*, productcatalog.producttypeid')
->join('productcatalog', 'producttemp.catalognumber = productcatalog.catalognumber')
->whereIn('productcatalog.producttypeid', $productTypeIds)
->where('producttemp.logdate >=', date('Y-m-d', strtotime('-30 days')))
->where('producttemp.logdate <=', date('Y-m-d', strtotime('+3 days')))
->findAll();
$merged_data = [];
foreach ($productTemps as $productTemp) {
$productnumber = $productTemp['productnumber'];
$catalognumber = $productTemp['catalognumber'];
$duplicates = $productsModel
->select('products.*, productcatalog.catalognumber')
->join('productcatalog', 'products.catalogid = productcatalog.catalogid')
->where('products.productnumber', $productnumber)
->where('productcatalog.catalognumber', $catalognumber)
->findAll();
if ($duplicates) {
$productTemp['duplicates'] = $duplicates;
} else {
$productTemp['duplicates'] = null;
}
$merged_data[] = $productTemp;
}
$data['products'] = $merged_data;
// dd($data);
return view('producttemp_index', $data);
}
public function getdata($id) {
$model = new ProductTempModel();
$result = $model->find($id);
if ($result) {
return $this->response->setJSON($result);
} else {
return $this->response->setStatusCode(404)->setJSON(['error' => 'Data not found']);
}
}
public function edit() {
$id = $this->request->getPost('edit-productid');
$data = [
'productnumber' => $this->request->getPost('edit-productnumber'),
'productname' => $this->request->getPost('edit-productname'),
'catalognumber' => $this->request->getPost('edit-catalognumber'),
'locationstartdate' => $this->request->getPost('edit-locationstartdate') ?: null,
'locationenddate' => $this->request->getPost('edit-locationenddate') ?: null,
'warrantystartdate' => $this->request->getPost('edit-warrantystartdate') ?: null,
'warrantyenddate' => $this->request->getPost('edit-warrantyenddate') ?: null,
'active' => $this->request->getPost('edit-active'),
'statusservice' => $this->request->getPost('edit-statusservice'),
'statusparts' => $this->request->getPost('edit-statusparts'),
];
// dd($data);
$model = new ProductTempModel();
$model->update($id, $data);
return redirect()->to('/producttemp')->with('success', 'Product updated');
}
public function deleteItem($productid) {
$model = new ProductTempModel();
$result = $model->find($productid);
if($result) {
$model->delete($productid);
return redirect()->to('/producttemp')->with('success', 'Product deleted');
}
}
public function validateItem() {
$productTempModel = new ProductTempModel();
$productsModel = new ProductsModel();
$productCatalogModel = new ProductCatalogModel();
$productTempId = $this->request->getPost('producttemp-productid');
$productId = $this->request->getPost('product-productid') ?? null;
$dataProductTemp = $productTempModel->find($productTempId);
$catalognumber = $dataProductTemp['catalognumber'];
$productCatalogData = $productCatalogModel->where('catalognumber', $catalognumber)->first();
if ($productId) {
if ($productCatalogData) {
$data = [
'productnumber' => $dataProductTemp['productnumber'],
// 'productname' => $dataProductTemp['productname'],
'catalogid' => $productCatalogData['catalogid'],
'siteid' => $dataProductTemp['siteid'],
'locationstartdate' => $dataProductTemp['locationstartdate'],
'locationenddate' => $dataProductTemp['locationenddate'],
'warrantystartdate' => $dataProductTemp['warrantystartdate'],
'warrantyenddate' => $dataProductTemp['warrantyenddate'],
'productowner' => $dataProductTemp['owner'],
];
$productsModel->update($productId, $data);
$productTempModel->delete($productTempId);
session()->setFlashdata('success', 'Product updated in product table!');
} else {
session()->setFlashdata('error', 'Data not exist on Product Catalog table');
}
} else {
if ($productCatalogData) {
$data = [
'productnumber' => $dataProductTemp['productnumber'],
// 'productname' => $dataProductTemp['productname'],
'catalogid' => $productCatalogData['catalogid'],
'siteid' => $dataProductTemp['siteid'],
'locationstartdate' => $dataProductTemp['locationstartdate'],
'locationenddate' => $dataProductTemp['locationenddate'],
'warrantystartdate' => $dataProductTemp['warrantystartdate'],
'warrantyenddate' => $dataProductTemp['warrantyenddate'],
'productowner' => $dataProductTemp['owner'],
'createdate' => date('Y-m-d'),
];
$productsModel->insert($data);
$productTempModel->delete($productTempId);
session()->setFlashdata('success', 'Product moved to product table!');
} else {
session()->setFlashdata('error', 'Data not exist on Product Catalog table');
}
}
return redirect()->to('/producttemp');
}
}

View File

@ -14,6 +14,28 @@ class Products extends BaseController {
$this->data['productowners'] = array('S'=>'Summit', 'C'=> 'Customer', 'O' => 'Other'); $this->data['productowners'] = array('S'=>'Summit', 'C'=> 'Customer', 'O' => 'Other');
} }
// Get Data Dari CLQMS untuk MEAN Jumlah Test Selama 6 Bulan
private function getPatresCount($pr_number_link) {
if ($pr_number_link != "") {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://clqms.services-summit.my.id/api_service/count_patres'.$pr_number_link,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
));
$response = curl_exec($curl);
curl_close($curl);
$data = json_decode($response, true);
return $data;
}
}
public function index() { public function index() {
$db = \Config\Database::connect(); $db = \Config\Database::connect();
@ -58,11 +80,16 @@ class Products extends BaseController {
$where = 0; $where = 0;
$sql = "SELECT p.productid, pc.productname, p.productnumber, p.createdate, s.sitename, pt.producttypeid, pt.texts $sql = "SELECT p.productid, p.installationdate ,pc.productname, pc.productaliasid, p.productnumber, s.sitename, pt.producttypeid, pt.texts,
z.zonename as city, z2.zonename as prov
FROM products p FROM products p
left join productcatalog pc on pc.catalogid=p.catalogid left join productcatalog pc on pc.catalogid=p.catalogid
left join producttype pt on pt.producttypeid=pc.producttypeid left join producttype pt on pt.producttypeid=pc.producttypeid
left join sites s on s.siteid=p.siteid"; left join sites s on s.siteid=p.siteid
left join accounts a on a.accountid=s.accountid
left join zones z on z.zoneid=a.zoneid
left join zones z2 on z2.zoneid=z.parentzoneid
";
if($productaliasid != 0) { if($productaliasid != 0) {
if($where == 0) { $sql .=" where "; $where++; } if($where == 0) { $sql .=" where "; $where++; }
@ -88,10 +115,25 @@ class Products extends BaseController {
$sql.= "$sitenamequery"; $sql.= "$sitenamequery";
} }
$sql.=" ORDER BY p.installationdate DESC ";
$data['sql']=$sql; $data['sql']=$sql;
$query = $db->query($sql); $query = $db->query($sql);
$results = $query->getResultArray(); $results = $query->getResultArray();
$data['products'] = $results; $data['products'] = $results;
// // Untuk CLQMS Patres Count Rata-Rata Bulanan
// $pr_number_link = "";
// foreach ($data['products'] as $value) {
// // 20 adalah kode TMS-30i
// if ($value['productaliasid'] == '20') {
// $pr_number_link .= "/" . $value['productnumber'];
// }
// }
// if ($pr_number_link != "") {
// $data['testCountCLQMS'] = $this->getPatresCount($pr_number_link);
// }
} }
return view('products_index', $data); return view('products_index', $data);
} }
@ -138,7 +180,7 @@ class Products extends BaseController {
$results = $query->getResultArray(); $results = $query->getResultArray();
$data['productcatalog'] = $results; $data['productcatalog'] = $results;
$sql = "select * from sites"; $sql = "select * from sites where enddate is null";
$query = $db->query($sql); $query = $db->query($sql);
$results = $query->getResultArray(); $results = $query->getResultArray();
$data['sites'] = $results; $data['sites'] = $results;
@ -222,6 +264,7 @@ class Products extends BaseController {
$data['productowners'] = $this->data['productowners']; $data['productowners'] = $this->data['productowners'];
if ($this->request->getMethod() === 'post') { if ($this->request->getMethod() === 'post') {
$rules = [ $rules = [
'productid' => 'required', 'productid' => 'required',
'siteid' => 'required', 'siteid' => 'required',
@ -230,24 +273,30 @@ class Products extends BaseController {
'productowner' => 'required', 'productowner' => 'required',
]; ];
$data['new_value'] = [ $data['new_value'] = [
'productnumb' => $this->request->getVar('productnumb'),
'productnam' => $this->request->getVar('productnam'),
'productid' => $this->request->getVar('productid'), 'productid' => $this->request->getVar('productid'),
'siteid' => $this->request->getVar('siteid'), 'siteid' => $this->request->getVar('siteid'),
'oldlocationenddate' => $this->request->getVar('oldlocationenddate'), 'oldlocationenddate' => $this->request->getVar('oldlocationenddate'),
'newlocationstartdate' => $this->request->getVar('newlocationstartdate'), 'newlocationstartdate' => $this->request->getVar('newlocationstartdate'),
'productowner' => $this->request->getVar('productowner') 'productowner' => $this->request->getVar('productowner')
]; ];
if($this->validate($rules)){ if($this->validate($rules)){
$productid = $data['new_value']['productid']; $productid = $data['new_value']['productid'];
$siteid = $data['new_value']['siteid']; $siteid = $data['new_value']['siteid'];
$oldlocationenddate = $data['new_value']['oldlocationenddate']; $oldlocationenddate = $data['new_value']['oldlocationenddate'];
$newlocationstartdate = $data['new_value']['newlocationstartdate']; $newlocationstartdate = $data['new_value']['newlocationstartdate'];
$productowner = $data['new_value']['productowner']; $productowner = $data['new_value']['productowner'];
// products_log // products_log
$sql = "INSERT INTO products_log $sql = "INSERT INTO products_log
(productid, siteid, catalogid, locationstartdate, locationenddate, installationdate, warrantystartdate, warrantyenddate, productowner, productserviceid, statuspart, logdate ) (productid, siteid, catalogid, locationstartdate, locationenddate, installationdate, warrantystartdate, warrantyenddate, productowner, productserviceid, statuspart, logdate )
SELECT productid, siteid,catalogid, locationstartdate, '$oldlocationenddate', installationdate, warrantystartdate, warrantyenddate, productowner, productserviceid, statuspart, NOW() SELECT productid, siteid,catalogid, locationstartdate, '$oldlocationenddate', installationdate, warrantystartdate, warrantyenddate, productowner, productserviceid, statuspart, NOW()
FROM products WHERE productid='$productid'"; FROM products WHERE productid='$productid'";
$query = $db->query($sql); $query = $db->query($sql);
// products // products
$sql = "update products set siteid='$siteid', locationstartdate='$newlocationstartdate', productowner='$productowner' where productid='$productid'"; $sql = "update products set siteid='$siteid', locationstartdate='$newlocationstartdate', productowner='$productowner' where productid='$productid'";
$query = $db->query($sql); $query = $db->query($sql);
@ -399,4 +448,79 @@ class Products extends BaseController {
$query = $db->query($sql); $query = $db->query($sql);
//echo "$sql"; //echo "$sql";
} }
public function exportdata() {
$db = \Config\Database::connect();
$productaliasid = $this->request->getGet('productaliasid');
$areaid = $this->request->getGet('areaid');
$producttypeid = $this->request->getGet('producttypeid');
$sitename = $this->request->getGet('sitename');
$areaquery = '';
if($areaid != '') { $areaquery = " s.siteid in (select siteid from v_siteaccount where areaid='$areaid') "; }
$producttypequery = '';
if($producttypeid != '') { $producttypequery = " pt.producttypeid='$producttypeid' "; }
$sitenamequery = '';
if($sitename!= '') {
$sitename = strtolower($sitename);
$sitenamequery= " lower(s.sitename) like '%$sitename%' ";
}
$where = 0;
$sql = "SELECT a2.accountname, p.statuspart, ps.productservicetext, p.productid, pc.productname, p.productnumber, pc.catalognumber, pt.texts as type_name, pc.manufacturer, s.sitename,
z.zonename as city, z2.zonename as prov, p.installationdate, p.locationstartdate, p.locationenddate, p.warrantystartdate, p.warrantyenddate
FROM products p
left join productcatalog pc on pc.catalogid=p.catalogid
-- left join accoun pc2 on pc2.catalogid=p.accountid_productowner
left join producttype pt on pt.producttypeid=pc.producttypeid
left join productservice ps on ps.productserviceid=p.productserviceid
left join sites s on s.siteid=p.siteid
left join accounts a on a.accountid=s.accountid
left join accounts a2 on a2.accountid=p.accountid_productowner
left join zones z on z.zoneid=a.zoneid
left join zones z2 on z2.zoneid=z.parentzoneid
";
if($productaliasid != 0) {
if($where == 0) { $sql .=" where "; $where++; }
else { $sql .=" and "; }
$sql.= "pc.productaliasid='$productaliasid'";
}
if($areaquery != '') {
if($where == 0) { $sql .=" where "; $where++; }
else { $sql .=" and "; }
$sql.= "$areaquery";
}
if($producttypequery != '') {
if($where == 0) { $sql .=" where "; $where++; }
else { $sql .=" and "; }
$sql.= "$producttypequery";
}
if($sitenamequery != '') {
if($where == 0) { $sql .=" where "; $where++; }
else { $sql .=" and "; }
$sql.= "$sitenamequery";
}
$sql.=" ORDER BY p.installationdate DESC";
$data['sql']=$sql;
$query = $db->query($sql);
$results = $query->getResultArray();
$data['products'] = $results;
return view('products_export_excel', $data);
}
} }

View File

@ -32,7 +32,7 @@ class Sites extends BaseController {
public function view($siteid = null) { public function view($siteid = null) {
$db = \Config\Database::connect(); $db = \Config\Database::connect();
$sql = "SELECT s.`siteid`, s.`sitename`, a.`accountname`, $sql = "SELECT s.`siteid`, s.`sitename`, a.`accountname`, a.`initial`,
concat(u.`firstname`,' ',u.lastname) as marketing, s.createdate concat(u.`firstname`,' ',u.lastname) as marketing, s.createdate
FROM sites s FROM sites s
LEFT JOIN accounts a ON a.`accountid`=s.`accountid` LEFT JOIN accounts a ON a.`accountid`=s.`accountid`
@ -64,7 +64,7 @@ class Sites extends BaseController {
} }
//$sql = "SELECT accountid, accountname FROM accounts WHERE parentaccount='0'"; //$sql = "SELECT accountid, accountname FROM accounts WHERE parentaccount='0'";
$sql = "SELECT accountid, accountname FROM accounts"; $sql = "SELECT accountid, accountname, initial FROM accounts";
$query = $db->query($sql); $query = $db->query($sql);
$results = $query->getResultArray(); $results = $query->getResultArray();
$data['accounts'] = $results; $data['accounts'] = $results;
@ -88,6 +88,7 @@ class Sites extends BaseController {
'userid' => $this->request->getVar('userid'), 'userid' => $this->request->getVar('userid'),
'userstartdate' => $this->request->getVar('startdate'), 'userstartdate' => $this->request->getVar('startdate'),
]; ];
if($this->validate($rules)){ if($this->validate($rules)){
// User yang sudah ada // User yang sudah ada
@ -180,6 +181,8 @@ class Sites extends BaseController {
$userid = $results[0]['userid']; $userid = $results[0]['userid'];
$userstartdate = $results[0]['userstartdate']; $userstartdate = $results[0]['userstartdate'];
// Kondisi untuk form marketing jika diisi
if ($userid != 0) {
// Get Full Name Form User // Get Full Name Form User
$sql = "SELECT CONCAT(firstname, ' ', lastname) as fullname FROM users WHERE userid = $userid"; $sql = "SELECT CONCAT(firstname, ' ', lastname) as fullname FROM users WHERE userid = $userid";
$query = $db->query($sql); $query = $db->query($sql);
@ -195,7 +198,7 @@ class Sites extends BaseController {
$sitesLogModel = new SitesLogModel(); $sitesLogModel = new SitesLogModel();
$sitesLogModel->set('createdate', 'NOW()', FALSE); $sitesLogModel->set('createdate', 'NOW()', FALSE);
$sitesLogModel->insert($data['log_sites']); $sitesLogModel->insert($data['log_sites']);
}
return view('form_success'); return view('form_success');
} }
} else { } else {

View File

@ -53,7 +53,7 @@ class UnitGroup extends BaseController {
return view('form_success'); return view('form_success');
} else { } else {
$model = new UnitGroupModel(); $model = new UnitGroupModel();
$model->set('createdate', 'NOW()', FALSE); $model->set('logdate', 'NOW()', FALSE);
$model->insert($data['new_value']); $model->insert($data['new_value']);
return view('form_success'); return view('form_success');
} }
@ -64,4 +64,15 @@ class UnitGroup extends BaseController {
} }
return view('unitgroup_editor', $data); return view('unitgroup_editor', $data);
} }
public function toggle($unitgroupid = 0) {
$db = \Config\Database::connect();
$sql = "update unitgroup set enddate=
case when enddate is not null then null
else NOW()
end
where unitgroupid ='$unitgroupid'";
if($db->query($sql)) { return view('form_success'); }
else { return view('form_fail'); }
}
} }

26
app/Filters/Cors.php Normal file
View File

@ -0,0 +1,26 @@
<?php namespace App\Filters;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Filters\FilterInterface;
class Cors implements FilterInterface
{
public function before(RequestInterface $request, $arguments = null)
{
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, X-CSRF-TOKEN');
// Handle preflight requests
// if ($request->getMethod() === 'options') {
// header('HTTP/1.1 200 OK');
// exit();
// }
}
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
// No actions required after the request
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace App\Models;
use CodeIgniter\Model;
class ProductTempModel extends Model
{
protected $table = 'producttemp';
protected $primaryKey = 'productid';
protected $allowedFields = ['productnumber','productname','catalognumber','siteid','locationstartdate','locationenddate','installationdate','warrantystartdate','warrantyenddate','active','owner','statusservice','statusparts','userid','reference','logdate'];
}

View File

@ -5,5 +5,5 @@ use CodeIgniter\Model;
class UnitGroupModel extends Model { class UnitGroupModel extends Model {
protected $table = 'unitgroup'; protected $table = 'unitgroup';
protected $primaryKey = 'unitgroupid'; protected $primaryKey = 'unitgroupid';
protected $allowedFields = [ 'unitgroupcode', 'catalogid', 'unit', 'quantity', 'baseunit', 'logdate' ]; protected $allowedFields = [ 'unitgroupcode', 'catalogid', 'unit', 'quantity', 'baseunit', 'logdate', 'enddate' ];
} }

View File

@ -1,15 +0,0 @@
<?php
namespace App\Validation;
use App\Models\UsersModel;
class Usersrules {
public function validateUser(string $str, string $fields, array $data) {
$model = new UsersModel();
$user = $model->where('email_1', $data['email'])->first();
if (!$user) { return false; }
return password_verify($data['password'], $user['password']);
}
}

View File

@ -68,7 +68,7 @@ if(!isset($areaid)) {$areaid = '';}
<div class="table-responsive"> <div class="table-responsive">
<table id="myTable" class="table display table-striped border"> <table id="myTable" class="table display table-striped border">
<thead> <thead>
<th>Name</th> <th>Initial</th> <th>Parent</th> <th>Area</th> <th>Create date</th> <th></th> <th>Name</th> <th>Parent</th> <th>Area</th> <th>Create date</th> <th></th>
</thead> </thead>
<tbody> <tbody>
<?php <?php
@ -98,7 +98,7 @@ if(!isset($areaid)) {$areaid = '';}
} }
?> ?>
<tr <?=$classend;?>> <tr <?=$classend;?>>
<td><?=$accountname;?></td> <td><?=$initial;?></td> <td><?=$parentname;?></td> <td><?=$areaname;?></td> <td><?=$createdate;?></td> <td><?=$accountname;?></td> <td><?=$parentname;?></td> <td><?=$areaname;?></td> <td><?=$createdate;?></td>
<td> <td>
<button type='button' class='btn btn-success btn-sm openViewAccount' data-accountid='<?=$accountid;?>'><i class="fas fa-eye"></i> View</button> <button type='button' class='btn btn-success btn-sm openViewAccount' data-accountid='<?=$accountid;?>'><i class="fas fa-eye"></i> View</button>
<a class='btn btn-warning btn-sm' href='accounts/edit/<?=$accountid;?>' <a class='btn btn-warning btn-sm' href='accounts/edit/<?=$accountid;?>'

View File

@ -2,6 +2,7 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?php <?php
$data = $userinfo; $data = $userinfo;
$username = $data['firstname'].' '.$data['lastname']; $username = $data['firstname'].' '.$data['lastname'];
$offaddress = $data['offaddress']; $offaddress = $data['offaddress'];
@ -10,6 +11,7 @@ $email_1 = $data['email_1'];
$content .= "<br/> $content .= "<br/>
<p> <p>
Terimakasih<br/>
Salam,<br/> Salam,<br/>
$username<br/> $username<br/>
<br/> <br/>
@ -18,8 +20,6 @@ $offaddress<br/>
Phone : $offphone<br/> Phone : $offphone<br/>
Email : $email_1<br/> Email : $email_1<br/>
<br/> <br/>
Terimakasih<br/>
<br/>
</p> </p>
"; ";
$emailoption = ''; $emailoption = '';

View File

@ -18,6 +18,12 @@ $action = $activities[0]['action'];
$subject = $activities[0]['subject']; $subject = $activities[0]['subject'];
$acttypecode = $activities[0]['acttypecode']; $acttypecode = $activities[0]['acttypecode'];
if(isset($invtrans[0]['purpose'])) {
$purposecolumn = "<th>Purpose</th>";
} else {
$purposecolumn = " ";
}
?> ?>
<style> <style>
p { margin:0; font-family: Arial, sans-serif; line-height:1.5;} p { margin:0; font-family: Arial, sans-serif; line-height:1.5;}
@ -72,7 +78,7 @@ if(count($invtrans) != 0 ) {
?> ?>
<b>Transaction</b> <b>Transaction</b>
<table> <table>
<tr> <th>Catalog#</th> <th>Product</th> <th>Lot#</th> <th>Qty.</th> <th>Unit</th> </tr> <tr> <th>Catalog#</th> <th>Product</th> <th>Lot#</th> <th>Qty.</th> <th>Unit</th> <?= $purposecolumn; ?> </tr>
<?php <?php
foreach($invtrans as $qdata) { foreach($invtrans as $qdata) {
$catalognumber = $qdata['catalognumber']; $catalognumber = $qdata['catalognumber'];
@ -80,7 +86,15 @@ foreach($invtrans as $qdata) {
$lotnumber = $qdata['lotnumber']; $lotnumber = $qdata['lotnumber'];
$qty = $qdata['qty']; $qty = $qdata['qty'];
$unit = $qdata['unit']; $unit = $qdata['unit'];
if(isset($qdata['purpose'])) {
$purpose = $qdata['purpose'];
$purposetext = $purpose == '' ? $purpose : $itx_purposes[$purpose];
echo "<tr> <td>$catalognumber</td> <td>$productname</td> <td>$lotnumber</td> <td>$qty</td> <td>$unit</td> <td>$purposetext</td> </tr>";
} else {
echo "<tr> <td>$catalognumber</td> <td>$productname</td> <td>$lotnumber</td> <td>$qty</td> <td>$unit</td> </tr>"; echo "<tr> <td>$catalognumber</td> <td>$productname</td> <td>$lotnumber</td> <td>$qty</td> <td>$unit</td> </tr>";
}
} }
?> ?>
</table> </table>

View File

@ -1,7 +1,6 @@
<?= $this->extend('layouts/main.php') ?> <?= $this->extend('layouts/main.php') ?>
<?= $this->section('content') ?> <?= $this->section('content') ?>
<div class="page-wrapper"> <div class="page-wrapper">
<div class="container-fluid"> <div class="container-fluid">
<div class="row page-titles"> <div class="row page-titles">
@ -33,9 +32,13 @@
<span class="input-group-text d-flex align-items-center justify-content-center" style="width: 80px;">Pos</span> <span class="input-group-text d-flex align-items-center justify-content-center" style="width: 80px;">Pos</span>
<select class="form-control form-control-sm" name="pos" > <select class="form-control form-control-sm" name="pos" >
<?php <?php
$i=0;
foreach($userpos as $qid => $qname) { foreach($userpos as $qid => $qname) {
$i++;
if(in_array($i,[2,8,9])){echo "<option disabled class='bg-secondary'> </option>";}
if($qid == $pos) { echo "<option value='$qid' selected>$qname</option>"; } if($qid == $pos) { echo "<option value='$qid' selected>$qname</option>"; }
else { echo "<option value='$qid'>$qname</option>"; } else { echo "<option value='$qid' >$qname</option>"; }
} }
?> ?>
</select> </select>
@ -59,6 +62,7 @@
<table id="myTable" class="table small display border"> <table id="myTable" class="table small display border">
<thead class="table-info"> <thead class="table-info">
<tr> <tr>
<th class='text-center' style="width:2%;">-</th>
<th style="width:40%;">Name</th> <th style="width:40%;">Name</th>
<th>CR</th> <th>CR</th>
<th>IR</th> <th>IR</th>
@ -72,7 +76,36 @@
</thead> </thead>
<tbody> <tbody>
<?php foreach($count as $row) : ?> <?php foreach($count as $row) : ?>
<tr <?php if( session()->get('userid') == $row['userid'] ) {echo "style='background-color:#d3e9eb;'";} ?>> <?php
if ( in_array($row['userposid'], ["2", "4"])) {
$tdClass = "style='background-color:#fec10729;'";
$tdContent = '<small>IVD</small>';
} elseif ( in_array($row['userposid'], ["3", "5"])) {
$tdClass = "style='background-color:#feeae475;'";
$tdContent = '<small>IT</small>';
} elseif ( in_array($row['userposid'], ["6", "9"])) {
$tdClass = "style='background-color:#cdf3cc8c;'";
$tdContent = '<small>MKT</small>';
} elseif ( in_array($row['userposid'], ["10", "14"])) {
$tdClass = "style='background-color:#1269cf2b;'";
$tdContent = '<small>PS</small>';
} else {
$tdClass = '';
$tdContent = '<small> </small>';
}
?>
<tr <?php if( session()->get('userid') == $row['userid'] ) {echo $tdClass;} ?>>
<?php if( session()->get('userid') == $row['userid'] ) { ?>
<td class="text-center px-2">
<?php echo $tdContent; ?>
</td>
<?php } else { ?>
<td class="text-center px-2" <?php echo $tdClass; ?>>
<?php echo $tdContent; ?>
</td>
<?php } ?>
<td><?= $row['firstname'] . ' ' . $row['lastname'];?></td> <td><?= $row['firstname'] . ' ' . $row['lastname'];?></td>
<td><?= $row['CR'];?></td> <td><?= $row['CR'];?></td>
<td><?= $row['IR'];?></td> <td><?= $row['IR'];?></td>

View File

@ -127,8 +127,7 @@ if(isset($data)) {
</div> </div>
<div class='form-group col-12 col-lg-6'> <div class='form-group col-12 col-lg-6'>
<label for="actby" class="form-label border-start border-5 border-primary ps-1">Activity by</label> <label for="actby" class="form-label border-start border-5 border-primary ps-1">Activity by</label>
<?php if($actid!='0') { echo "<input type='hidden' name='actby' value='$actby'>"; }?> <select name="actby" id="actby" class="form-select form-select-sm">
<select name="actby" id="actby" class="form-select form-select-sm" <?php if($actby!='') { echo 'disabled'; } ?>>
<option value="">-- Choose one --</option> <option value="">-- Choose one --</option>
<?php <?php
foreach ($actbys as $qid => $qvalue) { foreach ($actbys as $qid => $qvalue) {
@ -216,7 +215,7 @@ if(isset($data)) {
<div class="col-12 col-md-6"> <div class="col-12 col-md-6">
<div class="form-group"> <div class="form-group">
<label for="refer" class="form-label border-start border-5 border-primary ps-1">Referred incident ID</label> <label for="refer" class="form-label border-start border-5 border-primary ps-1">Referred incident ID</label>
<input type="text" class="form-control form-control-sm" name="actid_ref" id="refer" value='<?=$actid_ref;?>' <?php if($activitystatus!='R') echo "disabled";?> > <input type="text" class="form-control form-control-sm" name="actid_ref" id="refer" value='<?=$actid_ref;?>'>
</div> </div>
</div> </div>
</div> </div>
@ -610,6 +609,13 @@ config = {
autosave_ask_before_unload: true, autosave_ask_before_unload: true,
autosave_interval: '30s', autosave_interval: '30s',
automatic_uploads: false, automatic_uploads: false,
setup: function (editor) {
editor.on('keydown', function (e) {
if (e.keyCode === 33 || e.keyCode === 34) {
e.preventDefault();
}
});
}
}; };
tinymce.init(config); tinymce.init(config);
@ -668,18 +674,6 @@ $('.closedate').change(function() {
$('.itxdate').val(this.value); $('.itxdate').val(this.value);
}) })
// disable refer ketika bukan refer
function changestatus() {
var status = document.getElementById('status');
var refer = document.getElementById('refer');
if( status.value == 'R' ) {
refer.disabled = false;
} else {
refer.value = '';
refer.disabled = true;
}
}
//InvTrans //InvTrans
function deleteRow(btn, itxid) { function deleteRow(btn, itxid) {
if(confirm('Are you sure?')) { if(confirm('Are you sure?')) {

View File

@ -7,15 +7,21 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title> <title>Document</title>
<link href="<?=base_url();?>/assets/style.css" rel="stylesheet"> <link href="<?=base_url();?>/assets/style.css" rel="stylesheet">
<!-- <script>
function closeWindow() {
setTimeout(function() {
window.close();
}, 500); // 2000 milliseconds = 2 seconds
}
</script> -->
</head> </head>
<body class='bg-white'> <body class='bg-white' onload="closeWindow()">
<h4 class="mt-2 text-center fw-bold"> Data Activity Periode <?=$opendate . ' to ' . $closedate;?> </h4> <h4 class="mt-2 text-center fw-bold"> Data Activity Periode <?=$opendate . ' to ' . $closedate;?> </h4>
<div class='text-center'> <div class='text-center'>
<button class='btn btn-success' onclick="exportToExcel()">Simpan Excel</button> <button id='saveButton' class='btn btn-success' onclick="exportToExcel()">Simpan Excel</button>
</div> </div>
<div class="row p-5"> <div class="row p-5">
@ -162,6 +168,12 @@
</div> </div>
<script src="<?=base_url();?>/assets/xlsx.mini.min.js"></script> <script src="<?=base_url();?>/assets/xlsx.mini.min.js"></script>
<script> <script>
window.onload = function() {
document.getElementById('saveButton').click();
window.close();
}
function exportToExcel() { function exportToExcel() {
const data = document.getElementById("myTable"); const data = document.getElementById("myTable");
var ws = XLSX.utils.table_to_sheet(data); var ws = XLSX.utils.table_to_sheet(data);

View File

@ -219,18 +219,57 @@
</div> </div>
</div> </div>
<div class="row">
<div class="col-sm-6 mb-2">
<div class="input-group input-group-sm">
<span class="input-group-text d-flex align-items-center justify-content-center" style="width: 80px;">Action</span>
<div class="col">
<select name="actions" class="form-select form-select-sm select2" id="actions" >
<option value="" selected >--</option>
<?php
foreach ($actions as $qid => $qvalue) {
if($qid == $action) { echo "<option value='$qid' selected>$qvalue</option>"; }
else { echo "<option value='$qid'>$qvalue</option>"; }
}
?>
</select>
</div>
</div>
</div>
<div class="col-sm-6 mb-2">
<div class="input-group input-group-sm">
<span class="input-group-text d-flex align-items-center justify-content-center" style="width: 80px;">Act Type</span>
<div class="col">
<select name="acttypes" class="form-select form-select-sm select2" id="acttypes" >
<option value="" selected >--</option>
<?php
foreach ($acttypes as $qid => $qvalue) {
if($qid == $acttype) { echo "<option value='$qid' selected>$qvalue</option>"; }
else { echo "<option value='$qid'>$qvalue</option>"; }
}
?>
</select>
</div>
</div>
</div>
</div>
<div class="row"> <div class="row">
<div class="col-sm-12 mb-2"> <div class="col-sm-12 mb-2">
<div class="input-group input-group-sm"> <div class="input-group input-group-sm">
<span class="input-group-text d-flex align-items-center justify-content-center" style="width: 100px;">Search Detail</span> <span class="input-group-text d-flex align-items-center justify-content-center" style="width: 100px;">Search Detail</span>
<div class="col"> <div class="col">
<input type="text" name="detail_activity" value="<?= $detail_activity; ?>" class="form-control" placeholder="Masukkan kata atau kalimat yang ada pada Detail Activity. Misal : mengirimkan modul training CL900i"> <input type="text" name="detail_activity" value="<?= $detail_activity; ?>" class="form-control" placeholder="Misal : mengirimkan modul training CL900i">
<!-- <input type="text" class="form-control" placeholder="Lagi maintenis !" disabled /> -->
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<button type="submit" class="btn btn-success btn-sm text-white float-end"> <i class="fa fa-check"></i> Submit</button> <button type="submit" class="btn btn-success btn-sm text-white float-end"> <i class="fa fa-check"></i> &nbsp;Submit</button>
</div> </div>
</div> </div>
</div> </div>
@ -245,7 +284,8 @@
<div class="col-12"> <div class="col-12">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<!-- <button class="btn btn-success btn-xs text-white float-end" onclick="exportToExcel()"> <i class="fa fa-file-excel"></i> EXCEL </button> --> <button class="btn btn-success btn-xs text-white float-end" onclick="exportToExcel()"> <i class="fa fa-file-excel"></i> &nbsp;EXCEL </button>
<div class="table-responsive"> <div class="table-responsive">
<table id="myTable" class="table small display border"> <table id="myTable" class="table small display border">
<thead class="table-info"> <thead class="table-info">
@ -257,7 +297,7 @@
<th style="width: 10%;">Subject</th> <th style="width: 10%;">Subject</th>
<th style="width: 1%;">Status</th> <th style="width: 1%;">Status</th>
<th style="width: 7%;">Open/Close</th> <th style="width: 7%;">Open/Close</th>
<th style="width: 2%;">Creator/Owner</th> <th style="width: 2%;">Owner</th>
<th style="width: 2%;">Mail</th> <th style="width: 2%;">Mail</th>
<th style="width: 7%;">Action</th> <th style="width: 7%;">Action</th>
</tr> </tr>
@ -290,7 +330,9 @@
case "4": echo "SP"; break; case "4": echo "SP"; break;
case "5": echo "MN"; break; case "5": echo "MN"; break;
case "6": echo "TR"; break; case "6": echo "TR"; break;
case "7": echo "RF"; break; } case "7": echo "RF"; break;
case "9": echo "TC"; break;
}
?> ?>
</td> </td>
<td><?=$row['sitename'];?></td> <td><?=$row['sitename'];?></td>
@ -323,7 +365,7 @@
?> ?>
</td> </td>
<td>Open : <?= $opendate; ?> <br> Close : <?= $closedate; ?></td> <td>Open : <?= $opendate; ?> <br> Close : <?= $closedate; ?></td>
<td>Creator : <?= $row['creator_name']; ?> <br> Owner : <?= $row['username']; ?></td> <td><?= $row['username']; ?></td>
<td style='vertical-align:middle;line-height:1em;'> <td style='vertical-align:middle;line-height:1em;'>
<i class='fa-regular fa-envelope fa-2xl'></i> <i class='fa-regular fa-envelope fa-2xl'></i>
<?php <?php
@ -334,7 +376,20 @@
<td> <td>
<select name="action" class="form-select form-select-sm" onchange="action(this)"> <select name="action" class="form-select form-select-sm" onchange="action(this)">
<option value="" selected> - </option> <option value="" selected> - </option>
<option value="activities/edit/<?= $row['actid']?>">Edit</option> <?php
if ( $closedate != '') {
$close = strtotime($closedate);
$now = time();
$value = $now - $close;
if ( ($value < 2592000) ) { echo "<option value=\"activities/edit/".$row['actid']."\">Edit</option>"; } // 30 days to mars
else if (in_array(session()->get('userid'), ['10', '5', '3', '2', '36', '9', '15', '12'])) {
echo "<option value=\"activities/edit/".$row['actid']."\">Edit</option>";
}
} else {
echo "<option value=\"activities/edit/".$row['actid']."\">Edit</option>";
}
?>
<option value="activities/compose/<?= $row['actid']?>">Send</option> <option value="activities/compose/<?= $row['actid']?>">Send</option>
<?php if( session()->get('level') == '0' || session()->get('level') == '1') { ?> <?php if( session()->get('level') == '0' || session()->get('level') == '1') { ?>
@ -355,6 +410,7 @@
<?php } ?> <?php } ?>
<!-- <option value="invtransactions/create/<?= $row['actid']?>">Sparepart Usage</option> --> <!-- <option value="invtransactions/create/<?= $row['actid']?>">Sparepart Usage</option> -->
<!-- <option value="activities/delete/<?= $row['actid']?>">Delete</option> --> <!-- <option value="activities/delete/<?= $row['actid']?>">Delete</option> -->
<option value="activities/servicereport/<?= $row['actid']?>">Service Report</option>
</select> </select>
</td> </td>
</tr> </tr>
@ -378,8 +434,9 @@ function action(e){
if( window.confirm("Are you sure?") ) { if( window.confirm("Are you sure?") ) {
window.location = (e.value); window.location = (e.value);
} }
} } else if (e.value.substr(0,25) == 'activities/servicereport/') {
else { window.location = (e.value); } window.open('<?=base_url()?>/'+e.value, '_blank');
} else { window.location = (e.value); }
} }
$('.areaid').change(function() { $('.areaid').change(function() {
@ -409,32 +466,53 @@ $(".alert-dismissible")
}); });
<!-- SCRIPT EXPORT TABLE TO EXCEL --> <!-- SCRIPT EXPORT TABLE TO EXCEL -->
// function exportToExcel() { function exportToExcel() {
// const data = document.getElementById("myTable"); const data = document.getElementById("myTable");
// var ws = XLSX.utils.table_to_sheet(data); var ws = XLSX.utils.table_to_sheet(data);
// /* hide kolom ke 9 */ /* hide kolom ke 9 */
// ws["!cols"] = []; ws["!cols"] = [];
// ws["!cols"][8] = { hidden: true }; ws["!cols"][8] = { hidden: true };
// var wb = XLSX.utils.book_new(); var wb = XLSX.utils.book_new();
// XLSX.utils.book_append_sheet(wb, ws, "Sheet 1"); XLSX.utils.book_append_sheet(wb, ws, "Sheet 1");
// XLSX.writeFile(wb, "ActivityList.xlsx"); XLSX.writeFile(wb, "ActivityList.xlsx");
// } }
// ajax get product // // ajax get product
$('#siteid').change(function() { // $('#siteid').change(function() {
var siteid=$('#siteid').val(); // var siteid=$('#siteid').val();
$.get("<?=base_url();?>/activities/index/getproduct/"+siteid, function(data) { // $.get("<?=base_url();?>/activities/index/getproduct/"+siteid, function(data) {
//console.log(data); // //console.log(data);
$('#productid').val(''); // $('#productid').val('');
$('#productid').html(data); // $('#productid').html(data);
// $('.select2').select2({
// theme: 'bootstrap-5',
// width: '100%'
// });
// })
// })
// ajax get product by site and productalias
$('#siteid, #product').change(function() {
let siteid = $('#siteid').val();
if (siteid === '') {
siteid = 'none';
}
let productid=$('#product').val();
if (productid === '') {
productid = 'none';
}
$.get("<?=base_url();?>/activities/index/getproduct/"+siteid+"/"+productid, function(data) {
console.log(data);
$('#productid').empty().html(data);
$('.select2').select2({ $('.select2').select2({
theme: 'bootstrap-5', theme: 'bootstrap-5',
width: '100%' width: '100%'
}); });
}) });
}) });
</script> </script>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -0,0 +1,114 @@
<?php
$opendate = new DateTime($activities[0]['opendate']);
$opendate = $opendate->format('Y-m-d H:i');
$closedate = new DateTime($activities[0]['closedate']);
$closedate = $closedate->format('Y-m-d H:i');
$subject = $activities[0]['subject'];
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" type="image/png" sizes="16x16" href="<?=base_url();?>/assets/favicon.png">
<title>Summit CRM</title>
<link href="<?=base_url();?>/assets/font-awesome-640/css/all.min.css" rel="stylesheet">
<link href="<?=base_url();?>/assets/style.css" rel="stylesheet">
<style>
body { width:210mm; height:296mm; padding:5mm; font-size:11pt; background-color:#fff;}
main { height:260mm; }
th,td { padding:0.5mm; }
th {text-align:center;}
table {width:100%; margin-top:5mm; }
ul,p,ol { margin:0; }
.no-overflow { white-space:nowrap; }
</style>
</head>
<body class='A4'>
<main>
<div class='row'>
<div class='col'>
<img src='<?=base_url();?>/assets/images/logo.png'>
</div>
<div class='col text-end'>
<h3>SERVICE REPORT</h3>
Report# <?=$actid;?>
</div>
</div>
<!-- Act Info -->
<table>
<tr>
<td>Customer </td> <td> : </td> <td><?=$activities[0]['sitename'];?></td>
<td>Service requested by </td> <td> : </td> <td><?=$activities[0]['reportfrom'];?></td>
</tr>
<tr>
<td>Model</td> <td> : </td> <td><?=$activities[0]['productname'];?></td>
<td>Service Open </td> <td> : </td> <td><?=$opendate;?></td>
</tr>
<tr>
<td>Sw. Version</td> <td> : </td> <td><?=$activities[0]['swversion'];?></td>
<td>Service Close </td> <td> : </td> <td><?=$closedate;?></td>
</tr>
<tr>
<td>Serial#</td> <td> : </td> <td><?=$activities[0]['productnumber'];?></td>
</tr>
</table>
<br />
<!-- Act Detail -->
<table>
<tr>
<td>Subject</td> <td> : </td> <td><?=$subject;?></td>
</tr>
<?php
foreach($actdetails as $data) {
$acttextname = $data['acttextname'];
$textvalue = $data['textvalue'];
echo "<tr> <td class='align-top'>$acttextname</td> <td class='align-top'> : </td> <td>$textvalue</td> </tr>";
}
?>
</table>
<!-- Spare Part TRX -->
<p>Spare Part Usage :</p>
<table class='table-bordered' style='margin:0;'>
<colgroup>
<col style='width:15%'>
<col style='width:30%'>
<col style='width:10%'>
<col style='width:5%'>
<col style='width:10%'>
<col style='width:20%'>
</colgroup>
<tr> <th>Catalog#</th> <th>Product</th> <th>Lot#</th> <th>Qty.</th> <th>Unit</th> <th>Purpose</th> </tr>
<?php
foreach($invtrans as $data) {
$catalognumber = $data['catalognumber'];
$productname = $data['productname'];
$lotnumber = $data['lotnumber'];
$qty = $data['qty'];
$unit = $data['unit'];
$purpose = $purposes[$data['purpose']];
echo "<tr> <td>$catalognumber</td> <td>$productname</td> <td>$lotnumber</td> <td>$qty</td> <td>$unit</td> <td>$purpose</td> </tr>";
}
?>
</table>
</main>
<footer>
<div class='row mb-3'>
<div class='col text-center' style='text-decoration:overline;'>
Technical Support
</div>
<div class='col text-center' style='text-decoration:overline;'>
Customer
</div>
</div>
<p class='text-center'>
PT. SUMBERMITRA AGUNGJAYA<br/>
Gading Bukit Indah Blok H/3, Kelapa Gading Permai, Jakarta 14240<br/>
Telp : 62-21-4516728, Fax : 62-21-45840240
</p>
</footer>
</body>
</html>

54
app/Views/clqms_index.php Normal file
View File

@ -0,0 +1,54 @@
<?= $this->extend('layouts/main.php') ?>
<?= $this->section('content') ?>
<?php
$crm_products = array();
foreach($products as $data) {
$crm_products[$data['productid']] ['productname'] = $data['productname'];
$crm_products[$data['productid']] ['sitename'] = $data['sitename'];
$crm_products[$data['productid']] ['productnumber'] = $data['productnumber'];
}
?>
<div class="page-wrapper">
<div class="container-fluid">
<div class="row page-titles">
<div class="col-md-5 align-self-center">
<h4 class="text-themecolor">Product / Instrument List</h4>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<div class="table-responsive">
<table id="myTable" class="table display table-striped border">
<thead>
<th></th> <th>Site</th> <th>Products</th> <th></th>
</thead>
<tbody>
<?php
foreach($clqms_products as $data) {
$qproductid = $data['productid'];
$qsitename = $crm_products[$qproductid]['sitename'];
$qproductname = $crm_products[$qproductid]['productname'];
$qproductnumber = $crm_products[$qproductid]['productnumber'];
$qprodinstid = $data['prodinstid'];
echo "<tr> <td>$qproductid</td> <td>$qsitename</td> <td>$qproductname ($qproductnumber)</td>
<td><a href='https://clqms.services-summit.my.id/prodinst/detail/$qprodinstid' class='btn btn-sm btn-info' target='_blank'>View</a></td>
</tr>";
}
?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<?= $this->endSection() ?>

View File

@ -0,0 +1,17 @@
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">View Product</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div id="viewModalContent" class="p-4 fs-6">
<div class="d-flex align-items-center">
<strong role="status" id="loading-text">Fetching data . . .</strong>
<div class="spinner-border ms-auto" id="spinner" aria-hidden="true"></div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,13 @@
<!-- Offcanvas -->
<div class="offcanvas offcanvas-end w-75" tabindex="-1" id="offcanvasRight" aria-labelledby="offcanvasRightLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="offcanvasRightLabel">Edit Product</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<div class="d-flex align-items-center">
<strong role="status" id="loading-text">Fetching data . . .</strong>
<div class="spinner-border ms-auto" id="spinner" aria-hidden="true"></div>
</div>
</div>
</div>

View File

@ -63,6 +63,8 @@
else if($activitystatus == "C") { echo "<button type='button' class='btn btn-sm btn-danger'>Closed</button>"; } else if($activitystatus == "C") { echo "<button type='button' class='btn btn-sm btn-danger'>Closed</button>"; }
else if($activitystatus == "R") { echo "<button type='button' class='btn btn-sm btn-info'>Refer</button>"; } else if($activitystatus == "R") { echo "<button type='button' class='btn btn-sm btn-info'>Refer</button>"; }
else if($activitystatus == "P") { echo "<button type='button' class='btn btn-sm btn-light'>Pending</button>"; } else if($activitystatus == "P") { echo "<button type='button' class='btn btn-sm btn-light'>Pending</button>"; }
else if($activitystatus == "S") { echo "<button type='button' class='btn btn-sm btn-warning'>Suspend</button>"; }
else if($activitystatus == "D") { echo "<button type='button' class='btn btn-sm btn-secondary'>Disable</button>"; }
?> ?>
</td> </td>
<td>Open : <?= $opendate; ?> <br> Close : <?= $closedate; ?></td> <td>Open : <?= $opendate; ?> <br> Close : <?= $closedate; ?></td>
@ -127,6 +129,8 @@
else if($activitystatus == "C") { echo "<button type='button' class='btn btn-sm btn-danger'>Closed</button>"; } else if($activitystatus == "C") { echo "<button type='button' class='btn btn-sm btn-danger'>Closed</button>"; }
else if($activitystatus == "R") { echo "<button type='button' class='btn btn-sm btn-info'>Refer</button>"; } else if($activitystatus == "R") { echo "<button type='button' class='btn btn-sm btn-info'>Refer</button>"; }
else if($activitystatus == "P") { echo "<button type='button' class='btn btn-sm btn-light'>Pending</button>"; } else if($activitystatus == "P") { echo "<button type='button' class='btn btn-sm btn-light'>Pending</button>"; }
else if($activitystatus == "S") { echo "<button type='button' class='btn btn-sm btn-warning'>Suspend</button>"; }
else if($activitystatus == "D") { echo "<button type='button' class='btn btn-sm btn-secondary'>Disable</button>"; }
?> ?>
</td> </td>
<td>Open : <?= $opendate; ?> <br> Close : <?= $closedate; ?></td> <td>Open : <?= $opendate; ?> <br> Close : <?= $closedate; ?></td>
@ -191,6 +195,8 @@
else if($activitystatus == "C") { echo "<button type='button' class='btn btn-sm btn-danger'>Closed</button>"; } else if($activitystatus == "C") { echo "<button type='button' class='btn btn-sm btn-danger'>Closed</button>"; }
else if($activitystatus == "R") { echo "<button type='button' class='btn btn-sm btn-info'>Refer</button>"; } else if($activitystatus == "R") { echo "<button type='button' class='btn btn-sm btn-info'>Refer</button>"; }
else if($activitystatus == "P") { echo "<button type='button' class='btn btn-sm btn-light'>Pending</button>"; } else if($activitystatus == "P") { echo "<button type='button' class='btn btn-sm btn-light'>Pending</button>"; }
else if($activitystatus == "S") { echo "<button type='button' class='btn btn-sm btn-warning'>Suspend</button>"; }
else if($activitystatus == "D") { echo "<button type='button' class='btn btn-sm btn-secondary'>Disable</button>"; }
?> ?>
</td> </td>
<td>Open : <?= $opendate; ?> <br> Close : <?= $closedate; ?></td> <td>Open : <?= $opendate; ?> <br> Close : <?= $closedate; ?></td>
@ -255,6 +261,8 @@
else if($activitystatus == "C") { echo "<button type='button' class='btn btn-sm btn-danger'>Closed</button>"; } else if($activitystatus == "C") { echo "<button type='button' class='btn btn-sm btn-danger'>Closed</button>"; }
else if($activitystatus == "R") { echo "<button type='button' class='btn btn-sm btn-info'>Refer</button>"; } else if($activitystatus == "R") { echo "<button type='button' class='btn btn-sm btn-info'>Refer</button>"; }
else if($activitystatus == "P") { echo "<button type='button' class='btn btn-sm btn-light'>Pending</button>"; } else if($activitystatus == "P") { echo "<button type='button' class='btn btn-sm btn-light'>Pending</button>"; }
else if($activitystatus == "S") { echo "<button type='button' class='btn btn-sm btn-warning'>Suspend</button>"; }
else if($activitystatus == "D") { echo "<button type='button' class='btn btn-sm btn-secondary'>Disable</button>"; }
?> ?>
</td> </td>
<td>Open : <?= $opendate; ?> <br> Close : <?= $closedate; ?></td> <td>Open : <?= $opendate; ?> <br> Close : <?= $closedate; ?></td>

View File

@ -55,6 +55,7 @@
<div class="col-12"> <div class="col-12">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<button class='btn btn-sm btn-info' onclick='exportToExcel()'>Export to excel</button>
<div class="table-responsive"> <div class="table-responsive">
<table id="myTable" class="table small display border"> <table id="myTable" class="table small display border">
<thead class="table-info"> <thead class="table-info">
@ -74,10 +75,12 @@
$origin = $data['origin']; $origin = $data['origin'];
$dest = $data['dest']; $dest = $data['dest'];
if($actid != $actid1) { if($actid != $actid1) {
echo "<tr class='border-primary p-3'> <td colspan='6'>$actid - $subject ($username)</td> </tr>"; echo "
<tr><td colspan='7'></td></tr>
<tr class='border-primary p-3'> <td colspan='6'>$actid - $subject ($username)</td> </tr>";
$actid1 = $actid; $actid1 = $actid;
} }
echo "<tr> <td>$catalognumber</td> <td>$productname</td> <td>$qty</td> <td>$unit</td> <td>$lotnumber</td> <td>$origin</td> <td>$dest</td> </tr>"; echo "<tr> <td>$catalognumber</td> <td>$productname</td> <td>$qty</td> <td>$unit</td> <td>$lotnumber</td> <td>$origin</td> <td>$dest</td>";
} }
?> ?>
</tbody> </tbody>
@ -103,6 +106,14 @@ $(function () {
}); });
}); });
function exportToExcel() {
var tableElement = document.getElementById("myTable");
var wb = XLSX.utils.book_new();
var ws = XLSX.utils.table_to_sheet(tableElement);
XLSX.utils.book_append_sheet(wb, ws, "My Data");
XLSX.writeFile(wb, "reportTransactions.xlsx");
}
</script> </script>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -0,0 +1,180 @@
<?= $this->extend('layouts/main.php') ?>
<?= $this->section('content') ?>
<link href='assets/dragula.min.css' rel='stylesheet' type='text/css' />
<style>
.kanban_cards { margin: 5px 0;padding:5px; color:black; background-color:rgba(0,0,0,10%); }
.kanban { min-height:250px; }
hr{ margin:0;}
.btn-xs { font-size:75%; padding:3px; pointer-events: none; }
.kanban_header,.kanban_footer { font-size:80%; }
h4 select {font-size:80%;}
</style>
<div class='page-wrapper'>
<div class="container-fluid">
<div class="row page-titles mb-2">
<div class="col-md-5 align-self-center">
<h4 class="text-themecolor">
Kanban Board
<select class='input-sm'>
<option selected>-</option>
<option>Project LQMS</option>
</select>
<button type='button' class='btn btn-sm btn-success'>Go</button>
</h4>
</div>
</div>
<div class='row'>
<div class='col'>
<div class="dropdown">
<button class="btn btn-info btn-sm dropdown-toggle mb-2" type="button" data-bs-toggle="dropdown">New</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">New Card</a></li>
<li><a class="dropdown-item" href="#">New List</a></li>
<li><a class="dropdown-item" href="#">New Board</a></li>
</ul>
</div>
</div>
<div class='col text-end'>
<button class="btn btn-dark text-white btn-sm" type="button">Show archived</button>
</div>
</div>
<div class='row'>
<div class='col'>
<div class='card'>
<div class='card-body'>
<h5 class='card-title'>To-Do </h5>
<hr/>
<div id='kanban_todo' class='col kanban'>
<div class='kanban_cards'>
<div class='row kanban_header'>
<div class='col text-start'><span class='btn btn-xs btn-primary'>Low</span></div>
<div class='col text-end'><i class='fas fa-pencil text-end'></i></div>
</div>
<pre>TOS mengambil data dari alat user</pre>
<hr>
<div class='row kanban_footer'>
<div class='col text-start'>2024-05-10</div>
<div class='col text-end'>ADH / APP</div>
</div>
</div>
<div class='kanban_cards'>
<div class='row kanban_header'>
<div class='col text-start'><span class='btn btn-xs btn-primary'>Low</span></div>
<div class='col text-end'><i class='fas fa-pencil text-end'></i></div>
</div>
<pre>Data apalagi yang akan diambil dan query nya</pre>
<hr>
<div class='row kanban_footer'>
<div class='col text-start'>2024-05-10</div>
<div class='col text-end'>ADH / APP</div>
</div>
</div>
<div class='kanban_cards'>
<div class='row kanban_header'>
<div class='col text-start'><span class='btn btn-xs btn-primary'>Low</span></div>
<div class='col text-end'><i class='fas fa-pencil text-end'></i></div>
</div>
<pre>Buat rest client / aplikasi pengirim data dari masing2 pc</pre>
<hr>
<div class='row kanban_footer'>
<div class='col text-start'>2024-05-10</div>
<div class='col text-end'>MZAK</div>
</div>
</div>
<div class='kanban_cards'>
<div class='row kanban_header'>
<div class='col text-start'><span class='btn btn-xs btn-primary'>Low</span></div>
<div class='col text-end'><i class='fas fa-pencil text-end'></i></div>
</div>
<pre>Front-end LQMS</pre>
<hr>
<div class='row kanban_footer'>
<div class='col text-start'>2024-05-10</div>
<div class='col text-end'></div>
</div>
</div>
<div class='kanban_cards'>
<div class='row kanban_header'>
<div class='col text-start'><span class='btn btn-xs btn-primary'>Low</span></div>
<div class='col text-end'><i class='fas fa-pencil text-end'></i></div>
</div>
<pre>Back-end LQMS</pre>
<hr>
<div class='row kanban_footer'>
<div class='col text-start'>2024-05-10</div>
<div class='col text-end'></div>
</div>
</div>
<div class='kanban_cards'>
<div class='row kanban_header'>
<div class='col text-start'><span class='btn btn-xs btn-primary'>Low</span></div>
<div class='col text-end'><i class='fas fa-pencil text-end'></i></div>
</div>
<pre>Persiapan infrastruktur / hardware / software</pre>
<hr>
<div class='row kanban_footer'>
<div class='col text-start'>2024-05-10</div>
<div class='col text-end'></div>
</div>
</div>
<div class='kanban_cards'>
<div class='row kanban_header'>
<div class='col text-start'><span class='btn btn-xs btn-primary'>Low</span></div>
<div class='col text-end'><i class='fas fa-pencil text-end'></i></div>
</div>
<pre>Security</pre>
<hr>
<div class='row kanban_footer'>
<div class='col text-start'>2024-05-10</div>
<div class='col text-end'></div>
</div>
</div>
<div class='kanban_cards'>
<div class='row kanban_header'>
<div class='col text-start'><span class='btn btn-xs btn-primary'>Low</span></div>
<div class='col text-end'><i class='fas fa-pencil text-end'></i></div>
</div>
<pre>Enkripsi JSON</pre>
<hr>
<div class='row kanban_footer'>
<div class='col text-start'>2024-05-10</div>
<div class='col text-end'></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class='col'>
<div class='card'>
<div class='card-body'>
<h5 class='card-title'>In Progress</h5>
<hr/>
<div id='kanban_inprogress' class='col kanban'>
</div>
</div>
</div>
</div>
<div class='col'>
<div class='card'>
<div class='card-body'>
<h5 class='card-title'>Done</h5>
<hr/>
<div id='kanban_done' class='col kanban'>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script src='assets/dragula.min.js'></script>
<script>
dragula([document.getElementById('kanban_todo'), document.getElementById('kanban_inprogress'), document.getElementById('kanban_done')]);
</script>
<?= $this->endSection() ?>

217
app/Views/kb_board_edit.php Normal file
View File

@ -0,0 +1,217 @@
<?= $this->extend('layouts/form.php') ?>
<?= $this->section('content') ?>
<?php
$boardname = '';
$admin_userid = '';
if(isset($boards)) {
$boardname = $boards[0]['boardname'];
$admin_userid = $boards[0]['admin_userid'];
foreach($boarduser as $userid) {
$qboarduser[]=$userid['userid'];
}
}
?>
<div class="form-body">
<h3 class="card-title">Board Editor</h3>
<hr>
<?php
if(isset($validation)) {
?>
<div class='alert alert-danger alert-dismissible'>
<?= $validation->listErrors(); ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"> <span aria-hidden="true"></span> </button>
</div>
<?php
}
?>
<form method='POST' id='myForm'>
<input type='hidden' name='boardid' value='<?=$boardid;?>'/>
<div class='row mb-3'>
<div class='col-2'>Board name</div>
<div class='col-10'><input class='form-control form-control-sm' type='text' name='boardname' value='<?=$boardname;?>' /></div>
</div>
<div class='row mb-3'>
<div class='col-2'>Board admin</div>
<div class='col-10'>
<select class='form-control form-control-sm select2' type='text' name='admin_userid' />
<?php
foreach($users as $data) {
$quserid = $data['userid'];
$qusername = $data['firstname'].' '.$data['lastname'];
if($admin_userid!='') {
if($quserid == $admin_userid) { echo "<option value='$quserid' selected>$qusername</option>"; }
else { echo "<option value='$quserid'>$qusername</option>"; }
} else {
if($quserid == $_SESSION['userid']) { echo "<option value='$quserid' selected>$qusername</option>"; }
else { echo "<option value='$quserid'>$qusername</option>"; }
}
}
?>
</select>
</div>
</div>
<div class='row mb-3'>
<div class='col-2'>Board users</div>
<div class='col-10'>
<select id='boarduser' class='form-control form-control-sm' type='text' name='boarduser[]' multiple />
<?php
foreach($users as $data) {
$userid = $data['userid'];
$username = $data['firstname'].' '.$data['lastname'];
if(isset($boarduser)) {
if(in_array($userid,$qboarduser)) { echo "<option value='$userid' selected>$username</option>"; }
else { echo "<option value='$userid'>$username</option>"; }
} else {
if($userid == $_SESSION['userid']) { echo "<option value='$userid' selected>$username</option>"; }
else { echo "<option value='$userid'>$username</option>"; }
}
}
?>
</select>
</div>
</div>
<h4>Board List</h4>
<input id='listid_delete' type='hidden' name='listid_delete' value=''>
<div class='row '>
<div class='col-2'>New List</div>
<div class='col-10'>
<div class='input-group'>
<input id='listname' class='form-control form-control-sm' placeholder='new list name ...' />
<div class='input-group-append'>
<button class="btn btn-sm btn-success" type="button" onclick='list_add()'> <i class="fa-solid fa-plus"></i> </button>
</div>
</div>
</div>
</div>
<table class='table'>
<tbody id='listTable'>
<?php
if(isset($lists)) {
foreach($lists as $list) {
$qlistname = $list['listname'];
$qlistid = $list['listid'];
?>
<tr>
<td class='input-group'>
<input class='form-control form-control-sm' type='text' name='lists[]' value='<?=$qlistname;?>' /> <input type='hidden' name='listid[]' value='<?=$qlistid;?>'>
<button type='button' class='btn btn-sm btn-dark text-white mx-1' onclick='rowDn(this)'><i class='fa-solid fa-down-long'></i></button>
<button type='button' class='btn btn-sm btn-dark text-white mx-1' onclick='rowUp(this)'><i class='fa-solid fa-up-long'></i></button>
<button type='button' class='btn btn-sm btn-danger mx-1' onclick='list_del(this, 0)'> <i class='fa-solid fa-x'></i> </button>
</td>
</tr>
<?php
}
}
?>
</tbody>
</table>
<button type="button" class="btn btn-dark float-start" onclick="window.close()">Cancel</button>
<button type="submit" class="btn btn-success text-white float-end"> <i class="fa fa-check"></i> Submit</button>
</form>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script>
function list_del(e, listid) {
if(confirm('Are you sure?')) {
e.parentNode.parentNode.remove();
var listid = listid.toString();
if(listid != 0) {
var d = $('#listid_delete');
d.val(d.val()+' '+listid);
console.log(d.val());
}
}
}
// add new list
function list_add() {
var newList = $('#listname');
console.log(newList.val());
// add new row on table
/*
var newRow = "<tr> <td><input class='form-control form-control-sm' type='text' name='lists[]' value='"+newList.val()+"' /> <input type='hidden' name='listid[]' value='0'> </td>"+
"<td> <button type='button' class='btn btn-sm btn-dark text-white' onclick='rowDn(this)'><i class='fa-solid fa-down-long'></i></button> "+
"<button type='button' class='btn btn-sm btn-dark text-white' onclick='rowUp(this)'><i class='fa-solid fa-up-long'></i></button> "+
"<button type='button' class='btn btn-sm btn-danger' onclick='list_del(this, 0)'> <i class='fa-solid fa-x'></i> </button> </td> </tr> \r\n";
*/
var newRow = "<tr> <td class='input-group'>"+
"<input class='form-control form-control-sm' type='text' name='lists[]' value='"+newList.val()+"' /> <input type='hidden' name='listid[]' value='0'>"+
"<button type='button' class='btn btn-sm btn-dark text-white' onclick='rowDn(this)'><i class='fa-solid fa-down-long'></i></button> "+
"<button type='button' class='btn btn-sm btn-dark text-white' onclick='rowUp(this)'><i class='fa-solid fa-up-long'></i></button> "+
"<button type='button' class='btn btn-sm btn-danger' onclick='list_del(this, 0)'> <i class='fa-solid fa-x'></i> </button> </td> </tr> \r\n";
if(newList.val() != '') {
$("#listTable").append(newRow);
newList.val('');
}
}
function rowUp(row){
var row = row.parentNode.parentNode;
var tableBody = row.parentNode;
var previousRow = row.previousElementSibling;
if (previousRow) { tableBody.insertBefore(row,previousRow); }
}
function rowDn(row){
var row = row.parentNode.parentNode;
var tableBody = row.parentNode;
var nextRow = row.nextElementSibling;
if (nextRow) { tableBody.insertBefore(nextRow,row); }
}
$(document).ready(function () {
var AllowClear = $.fn.select2.amd.require('select2/selection/allowClear');
var _handleKeyboardClearOriginal = AllowClear.prototype._handleKeyboardClear;
AllowClear.prototype._handleKeyboardClear = function(_, evt, container) {
if (this.$element.prop('multiple')) { return; }
_handleKeyboardClearOriginal.call(this, _, evt, container);
};
$('#boarduser').select2({
tags: true,
tokenSeparators: [',', ' '],
closeOnSelect: true,
allowClear: true,
placeholder: '',
});
$(".up").click(function() {
var row = $(this).parent().parent(); // Get the parent row
var previousRow = row.prev(); // Get the previous row
if (previousRow.length) {
row.insertBefore(previousRow);
} else {
alert("This row is already at the top!");
}
});
$(".down").click(function() {
var row = $(this).parent().parent(); // Get the parent row
var nextRow = row.next(); // Get the next row
if (nextRow.length) {
nextRow.insertBefore(row);
} else {
alert("This row is already at the bottom!");
}
});
// prevent enter
document.getElementById("myForm").addEventListener("keydown", function(event) {
if (event.key === "Enter") { event.preventDefault(); }
});
// enter list_add
document.getElementById("listname").addEventListener("keydown", function(event) {
if (event.key === "Enter") { event.preventDefault(); list_add(); }
});
});
</script>
<?= $this->endSection() ?>

View File

@ -0,0 +1,83 @@
<?= $this->extend('layouts/form.php') ?>
<?= $this->section('content') ?>
<?php
$cardtext = '';
$owner_userid = '';
$priority = '';
if(isset($cards)) {
$priority = $cards[0]['priority'];
$listid = $cards[0]['listid'];
$cardtext = $cards[0]['cardtext'];
$owner_userid = $cards[0]['owner_userid'];
}
?>
<div class="form-body">
<h3 class="card-title">Card Editor <button class="btn btn-danger fa fa-x float-end" onclick="window.close()"></button> </h3>
<hr>
<?php
if(isset($validation)) {
?>
<div class='alert alert-danger alert-dismissible'>
<?= $validation->listErrors(); ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"> <span aria-hidden="true"></span> </button>
</div>
<?php
}
?>
<form method='POST' id='myForm'>
<input type='hidden' name='cardid' value='<?=$cardid;?>'/>
<div class='row mb-3'>
<div class='col-2'>List</div>
<div class='col-4'>
<select class='form-control form-control-sm select2' type='text' name='listid' />
<?php
foreach($lists as $data) {
$qlistid = $data['listid'];
$qlistname = $data['listname'];
if($listid == $qlistid) { echo "<option value='$qlistid' selected>$qlistname</option>"; }
else { echo "<option value='$qlistid'>$qlistname</option>"; }
}
?>
</select>
</div>
<div class='col-3 text-end'>Priority</div>
<div class='col-3'>
<select class='form-control form-control-sm select2' type='text' name='priority' />
<?php
foreach($card_priorities as $qindex => $qvalue) {
if($qindex == $priority) { echo "<option value='$qindex' selected>$qvalue</option>"; }
else { echo "<option value='$qindex'>$qvalue</option>"; }
}
?>
</select>
</div>
</div>
<div class='row mb-3'>
<div class='col-2'>Card Owner</div>
<div class='col-10'>
<select class='form-control form-control-sm select2' type='text' name='owner_userid' />
<?php
foreach($users as $data) {
$userid = $data['userid'];
$username = $data['firstname'].' '.$data['lastname'];
if($owner_userid != '') {
if($userid == $owner_userid) { echo "<option value='$userid' selected>$username</option>"; }
else { echo "<option value='$userid'>$username</option>"; }
} else {
if($userid == $_SESSION['userid']) { echo "<option value='$userid' selected>$username</option>"; }
else { echo "<option value='$userid'>$username</option>"; }
}
}
?>
</select>
</div>
</div>
<div class='row mb-3'>
<div class='col-2'>Card text</div>
<div class='col-10'><textarea class='form-control' name='cardtext'><?=$cardtext;?></textarea></div>
</div>
<button type="submit" class="btn btn-success text-white float-start"> <i class="fa fa-check"></i> Submit</button>
</form>
</div>
<?= $this->endSection() ?>

27
app/Views/kb_index.php Normal file
View File

@ -0,0 +1,27 @@
<?= $this->extend('layouts/main.php') ?>
<?= $this->section('content') ?>
<div class='page-wrapper'>
<div class="container-fluid">
<div class="row page-titles mb-2">
<div class="col align-self-center">
<h4 class="text-themecolor">
Kanban Board
</h4>
</div>
</div>
<div class='input-group mb-2'>
<select class='input-sm' onchange="document.location.href = this.value">
<option value='#'>Select a board ...</option>
<?php
foreach($boards as $qdata) {
$boardid = $qdata['boardid'];
$boardname = $qdata['boardname'];
echo "<option value='".base_url()."/kanban/view/$boardid'>$boardname</option>";
}
?>
</select>
</div>
</div>
</div>
<?= $this->endSection() ?>

View File

@ -0,0 +1,32 @@
<?= $this->extend('layouts/form.php') ?>
<?= $this->section('content') ?>
<?php
$listname = '';
if(isset($lists)) {
$listname = $lists[0]['listname'];
}
?>
<div class="form-body">
<h3 class="card-title">List Editor <button class="btn btn-danger fa fa-x float-end" onclick="window.close()"></button> </h3>
<hr>
<?php
if(isset($validation)) {
?>
<div class='alert alert-danger alert-dismissible'>
<?= $validation->listErrors(); ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"> <span aria-hidden="true"></span> </button>
</div>
<?php
}
?>
<form method='POST' id='myForm'>
<input type='hidden' name='listid' value='<?=$listid;?>'/>
<div class='row mb-3'>
<div class='col-2'>List Name</div>
<div class='col-10'><input type='text' class='form-control form-control-sm' name='listname' value='<?=$listname;?>'></div>
</div>
<button type="submit" class="btn btn-success text-white float-start"> <i class="fa fa-check"></i> Submit</button>
</form>
</div>
<?= $this->endSection() ?>

137
app/Views/kb_view.php Normal file
View File

@ -0,0 +1,137 @@
<?= $this->extend('layouts/main.php') ?>
<?= $this->section('content') ?>
<?php
$boardname = $boards[0]['boardname'];
$boardid = $boards[0]['boardid'];
// sorting card by list
?>
<link href='<?=base_url();?>/assets/dragula.min.css' rel='stylesheet' type='text/css' />
<style>
.kanban_cards { margin: 5px 0;padding:5px; color:black; background-color:rgba(0,0,0,10%); }
.kanban { min-height:250px; }
hr{ margin:0;}
.btn-xs { font-size:75%; padding:3px; pointer-events: none; }
.kanban_header,.kanban_footer { font-size:80%; }
h4 select {font-size:80%;}
</style>
<div class='page-wrapper'>
<div class="container-fluid">
<div class="row page-titles mb-2">
<div class="col align-self-center">
<h4 class="text-themecolor">
Kanban Board - <?=$boardname;?>
</h4>
</div>
<div class="col text-end">
<div class="dropdown">
<button class="btn btn-dark text-white btn-sm dropdown-toggle mb-2" type="button" data-bs-toggle="dropdown"> <i class="fa-solid fa-gear"></i> </button>
<ul class="dropdown-menu">
<li><button class="dropdown-item" onclick="window.open('<?=base_url();?>/kanban/card/create/<?=$lists[0]['listid'];?>','_blank','width=800,height=500')" >New Card</button></li>
<li><button class="dropdown-item" onclick="window.open('<?=base_url();?>/kanban/board/edit/<?=$boardid;?>','_blank','width=800,height=500')" >Edit Board</button></li>
</ul>
</div>
</div>
</div>
<div class='row'>
<?php
$qdragula = '';
foreach($lists as $list) {
$qlistid = $list['listid'];
$qlistname = $list['listname'];
$qnlistname = str_replace(' ','',$qlistname);
$qdragula .= "document.getElementById('kanban_$qnlistname'),";
?>
<div class='col'>
<div class='card'>
<div class='card-body'>
<div class='row'>
<div class='col'> <h5 class='card-title'><?=$qlistname;?></h5> </div>
<div class='col text-end'>
<div class="dropdown">
<button class="btn btn-info btn-sm dropdown-toggle mb-2" type="button" data-bs-toggle="dropdown"> <i class="fa-solid fa-gear"></i> </button>
<ul class="dropdown-menu">
<li><button class="dropdown-item" onclick="window.open('<?=base_url();?>/kanban/card/create/<?=$qlistid;?>','_blank','width=800, height=500')">New Card</button></li>
<li><button class="dropdown-item" onclick="window.open('<?=base_url();?>/kanban/list/edit/<?=$qlistid;?>','_blank','width=800, height=500')">Edit List</button></li>
</ul>
</div>
</div>
</div>
<hr/>
<div id='kanban_<?=$qnlistname;?>' class='col kanban' data-listid='<?=$qlistid;?>'>
<!--
<div class='kanban_cards'>
<div class='row kanban_header'>
<div class='col text-start'><span class='btn btn-xs btn-primary'>Low</span></div>
<div class='col text-end'><i class='fas fa-pencil text-end'></i></div>
</div>
<pre>TOS mengambil data dari alat user</pre>
<hr>
<div class='row kanban_footer'>
<div class='col text-start'>2024-05-10</div>
<div class='col text-end'>ADH / APP</div>
</div>
</div>
-->
<?php
foreach($cards as $card) {
$qcardid = $card['cardid'];
$qcardtext = $card['cardtext'];
$qpriority = $card_priorities[$card['priority']];
$quser = $card['firstname'].' '.$card['lastname'];
$qcreatedate = $card['createdate'];
$qcard_listid = $card['listid'];
if($qlistid == $qcard_listid) {
?>
<div class='kanban_cards' data-cardid='<?=$qcardid;?>'>
<div class='row kanban_header'>
<div class='col text-start'><span class='btn btn-xs btn-primary'><?=$qpriority;?></span></div>
<div class='col text-end'>
<div class="dropdown">
<i class="fa-solid fa-gear" data-bs-toggle="dropdown"></i>
<ul class="dropdown-menu">
<li><button class="dropdown-item" onclick="window.open('<?=base_url();?>/kanban/card/edit/<?=$qlistid;?>/<?=$qcardid;?>','_blank','width=800, height=500')">Edit Card</button></li>
<li><button class="dropdown-item">Archive Card</button></li>
</ul>
</div>
</div>
</div>
<pre><?=$qcardtext;?></pre>
<hr>
<div class='row kanban_footer'>
<div class='col text-start'><?=$qcreatedate;?></div>
<div class='col text-end'><?=$quser?></div>
</div>
</div>
<?php
}
}
?>
</div>
</div>
</div>
</div>
<?php
}
$qdragula = rtrim($qdragula, ',');
?>
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script src='<?=base_url();?>/assets/dragula.min.js'></script>
<script>
const xhttp = new XMLHttpRequest();
//dragula([document.getElementById('kanban_todo'), document.getElementById('kanban_inprogress'), document.getElementById('kanban_done')]);
dragula([<?=$qdragula;?>])
.on('drop', function(el, target) {
cardid = el.getAttribute('data-cardid');
listid = target.getAttribute('data-listid');
xhttp.open("GET", "<?=base_url();?>/kanban/card/move/"+listid+"/"+cardid);
xhttp.send();
});
</script>
<?= $this->endSection() ?>

View File

@ -7,15 +7,16 @@
?> ?>
<li class="nav-small-cap">--- MAIN MENU</li> <li class="nav-small-cap">--- MAIN MENU</li>
<li> <a class="waves-effect waves-dark" href='<?=base_url();?>' aria-expanded="false"> <i class="fas fa-tachometer-alt"></i> <span class='hide-menu'>Dashboard</span></a></li> <li> <a class="waves-effect waves-dark" href='<?=base_url();?>' aria-expanded="false"> <i class="fas fa-tachometer-alt"></i> <span class='hide-menu'>Dashboard</span></a></li>
<li> <a class="has-arrow waves-effect waves-dark" href='javascript:void(0)' aria-expanded="false"> <i class="fas fa-cow"></i> <span class="hide-menu">Activity</span></a>
<ul aria-expanded="true" class="collapse">
<!-- <!--
<li> <li> <a class="has-arrow waves-effect waves-dark" href='javascript:void(0)' aria-expanded="false"> <i class="fa-solid fa-clapperboard"></i> <span class='hide-menu'>Kanban</span></a>
<a href='<?=base_url();?>/activities/create' onclick="window.open(this.href, 'Create Site','width=900,height=600,toolbar=1,resizable=0'); return false;"> <ul aria-expanded="true" class="collapse">
New Activity <li><a href='#' onclick="window.open('<?=base_url();?>/kanban/board/create', '_blank', 'width=800,height=500')">New Board</a></li>
</a> <li><a href="<?=base_url();?>/kanban/" >Board List</a></li>
</ul>
</li> </li>
--> -->
<li> <a class="has-arrow waves-effect waves-dark" href='javascript:void(0)' aria-expanded="false"> <i class="fas fa-cow"></i> <span class="hide-menu">Activity</span></a>
<ul aria-expanded="true" class="collapse">
<li><a href="<?=base_url();?>/activities/create" >New Activity</a></li> <li><a href="<?=base_url();?>/activities/create" >New Activity</a></li>
<li><a href="<?=base_url();?>/activities">Activity List</a></li> <li><a href="<?=base_url();?>/activities">Activity List</a></li>
<li><a href="<?=base_url();?>/activities/count">Activity Count</a></li> <li><a href="<?=base_url();?>/activities/count">Activity Count</a></li>
@ -36,6 +37,7 @@
</ul> </ul>
</li> </li>
<li> <a class="waves-effect waves-dark" href='<?=base_url();?>/guidebook' aria-expanded="false"> <i class="fa-solid fa-book"></i><span class='hide-menu'>Guidebook</span> </a> </li> <li> <a class="waves-effect waves-dark" href='<?=base_url();?>/guidebook' aria-expanded="false"> <i class="fa-solid fa-book"></i><span class='hide-menu'>Guidebook</span> </a> </li>
<li> <a class="waves-effect waves-dark" href='https://clqms.services-summit.my.id/' aria-expanded="false"> <i class="fa-solid fa-microscope"></i><span class='hide-menu'>CLQMS</span> </a> </li>
<li class="nav-small-cap">--- Master Data</li> <li class="nav-small-cap">--- Master Data</li>
<li> <a class="has-arrow waves-effect waves-dark" href="javascript:void(0)" aria-expanded="false"> <i class="fas fa-user"></i><span class="hide-menu">User</span></a> <li> <a class="has-arrow waves-effect waves-dark" href="javascript:void(0)" aria-expanded="false"> <i class="fas fa-user"></i><span class="hide-menu">User</span></a>
@ -60,6 +62,7 @@
<li><a href="<?=base_url();?>/productservice">Product Service</a></li> <li><a href="<?=base_url();?>/productservice">Product Service</a></li>
<li><a href="<?=base_url();?>/productcatalog">Product Catalog</a></li> <li><a href="<?=base_url();?>/productcatalog">Product Catalog</a></li>
<li><a href="<?=base_url();?>/productalias">Product Alias</a></li> <li><a href="<?=base_url();?>/productalias">Product Alias</a></li>
<li><a href="<?=base_url();?>/producttemp">Product Temp</a></li>
<li><a href="<?=base_url();?>/unitgroup">Unit Group</a></li> <li><a href="<?=base_url();?>/unitgroup">Unit Group</a></li>
<li><a href="<?=base_url();?>/products">Products</a></li> <li><a href="<?=base_url();?>/products">Products</a></li>
</ul> </ul>
@ -121,6 +124,7 @@
</ul> </ul>
</li> </li>
<li> <a class="waves-effect waves-dark" href='<?=base_url();?>/guidebook' aria-expanded="false"> <i class="fa-solid fa-book"></i><span class='hide-menu'>Guidebook</span> </a> </li> <li> <a class="waves-effect waves-dark" href='<?=base_url();?>/guidebook' aria-expanded="false"> <i class="fa-solid fa-book"></i><span class='hide-menu'>Guidebook</span> </a> </li>
<li> <a class="waves-effect waves-dark" href='https://clqms.services-summit.my.id/' aria-expanded="false"> <i class="fa-solid fa-microscope"></i><span class='hide-menu'>CLQMS</span> </a> </li>
<?php <?php
} else if( session()->get('level') == '4' ) { // PS } else if( session()->get('level') == '4' ) { // PS
/* /*
@ -183,6 +187,7 @@
</ul> </ul>
</li> </li>
<li> <a class="waves-effect waves-dark" href='<?=base_url();?>/guidebook' aria-expanded="false"> <i class="fa-solid fa-book"></i><span class='hide-menu'>Guidebook</span> </a> </li> <li> <a class="waves-effect waves-dark" href='<?=base_url();?>/guidebook' aria-expanded="false"> <i class="fa-solid fa-book"></i><span class='hide-menu'>Guidebook</span> </a> </li>
<li> <a class="waves-effect waves-dark" href='https://clqms.services-summit.my.id/' aria-expanded="false"> <i class="fa-solid fa-microscope"></i><span class='hide-menu'>CLQMS</span> </a> </li>
<?php <?php
} else { // TSO IVD } else { // TSO IVD
?> ?>
@ -213,6 +218,7 @@
<li><a href="<?=base_url();?>/bugs/count">Bug Count</a></li> <li><a href="<?=base_url();?>/bugs/count">Bug Count</a></li>
</ul> </ul>
<li> <a class="waves-effect waves-dark" href='<?=base_url();?>/guidebook' aria-expanded="false"> <i class="fa-solid fa-book"></i><span class='hide-menu'>Guidebook</span> </a> </li> <li> <a class="waves-effect waves-dark" href='<?=base_url();?>/guidebook' aria-expanded="false"> <i class="fa-solid fa-book"></i><span class='hide-menu'>Guidebook</span> </a> </li>
<li> <a class="waves-effect waves-dark" href='https://clqms.services-summit.my.id/' aria-expanded="false"> <i class="fa-solid fa-microscope"></i><span class='hide-menu'>CLQMS</span> </a> </li>
<?php <?php
} }
?> ?>

View File

@ -11,6 +11,7 @@
<link href="<?=base_url();?>/assets/style.css" rel="stylesheet"> <link href="<?=base_url();?>/assets/style.css" rel="stylesheet">
<link href="<?=base_url();?>/assets/select2/select2.min.css" rel="stylesheet"> <link href="<?=base_url();?>/assets/select2/select2.min.css" rel="stylesheet">
<link href="<?=base_url();?>/assets/select2/select2-bootstrap-5-theme.min.css" rel="stylesheet"> <link href="<?=base_url();?>/assets/select2/select2-bootstrap-5-theme.min.css" rel="stylesheet">
<link href="<?=base_url();?>/assets/font-awesome-640/css/all.min.css" rel="stylesheet">
<style> <style>
.select2-results__option { font-size: 0.75rem !important; margin: 5px !important; padding: 5px !important; } .select2-results__option { font-size: 0.75rem !important; margin: 5px !important; padding: 5px !important; }
li.select2-selection__choice { background-color : #000 !important; padding:5px !improtant; } li.select2-selection__choice { background-color : #000 !important; padding:5px !improtant; }
@ -49,8 +50,6 @@
<script src="<?=base_url();?>/assets/perfect-scrollbar.jquery.min.js"></script> <script src="<?=base_url();?>/assets/perfect-scrollbar.jquery.min.js"></script>
<script src="<?=base_url();?>/assets/app.js"></script> <script src="<?=base_url();?>/assets/app.js"></script>
<?= $this->renderSection('script'); ?> <?= $this->renderSection('script'); ?>
<script> <script>$('.select2').select2();</script>
$('.select2').select2();
</script>
</body> </body>
</html> </html>

77
app/Views/lqms_index.php Normal file
View File

@ -0,0 +1,77 @@
<?= $this->extend('layouts/main.php') ?>
<?= $this->section('content') ?>
<div class="page-wrapper">
<div class="container-fluid">
<div class="row page-titles">
<div class="col-md-5 align-self-center">
<h4 class="text-themecolor">LQMS REST-Server Message Log</h4>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<p><button class='btn btn-sm btn-danger' type='button' onclick='deleteLog()'>clear all</button> </p>
<div class="table-responsive">
<table class="table display table-striped border">
<tbody>
<?php
foreach($logs as $log) {
$mesid = $log['mesid'];
$message = $log['message'];
$mesdate = $log['mesdate'];
//$json = json_decode($message);
echo "<tr> <td><button class='btn btn-sm btn-warning' type='button' onclick='deleteMes(this, $mesid)'>delete</button><br/><pre>$message</pre></td> </tr>";
}
?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script>
function deleteLog() {
if (confirm("Are you sure?")) {
var url = "<?=base_url();?>/lqms/log_clear";
console.log(url);
$.ajax({
url: url,
method: "GET",
success: function(data) {
console.log("Data:", data);
alert('please refresh this browser.');
},
error: function( textStatus, errorThrown) {
console.error("Error:", textStatus, errorThrown);
}
});
} else {
console.log("Request canceled by user.");
}
}
function deleteMes(btn, mesid) {
//console.log(this);
var tableRow = btn.parentNode.parentNode;
tableRow.parentNode.removeChild(tableRow);
var url = "<?=base_url();?>/lqms/log/delete/"+mesid;
//console.log(url);
$.ajax({
url: url,
method: "GET",
success: function(data) { console.log("Data:", data); },
error: function( textStatus, errorThrown) { console.error("Error:", textStatus, errorThrown); }
});
}
</script>
<?= $this->endSection() ?>

View File

@ -0,0 +1,100 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="<?=base_url();?>/assets/style.css" rel="stylesheet">
<!-- <script>
function closeWindow() {
setTimeout(function() {
window.close();
}, 500); // 2000 milliseconds = 2 seconds
}
</script> -->
</head>
<body class='bg-white' onload="closeWindow()">
<h4 class="mt-2 text-center fw-bold"> Data Activity Periode </h4>
<div class='text-center'>
<button id='saveButton' class='btn btn-success' onclick="exportToExcel()">Simpan Excel</button>
</div>
<div class="row p-5">
<div class="col-12">
<div class="table-responsive">
<table id="myTable" class="table table-bordered">
<thead>
<tr>
<th scope="col">No</th>
<th scope="col">Product ID</th>
<th scope="col">Product Name</th>
<th scope="col">Product Number</th>
<th scope="col">Catalog Number</th>
<th scope="col">Product Owner</th>
<th scope="col">Status Service</th>
<th scope="col">Status Parts</th>
<th scope="col">Type</th>
<th scope="col">Manufacturer</th>
<th scope="col">Site Name</th>
<th scope="col">City</th>
<th scope="col">Province</th>
<th scope="col">Installation Date</th>
<th scope="col">Start Date</th>
<th scope="col">End Date</th>
<th scope="col">Warranty Start</th>
<th scope="col">Warranty End</th>
<th scope="col">Active</th>
</tr>
</thead>
<tbody>
<?php foreach ($products as $index => $item): ?>
<tr>
<td><?= $index + 1 ?></td>
<td><?= htmlspecialchars($item['productid'] ?? '') ?></td>
<td><?= htmlspecialchars($item['productname'] ?? '') ?></td>
<td><?= htmlspecialchars($item['productnumber'] ?? '') ?></td>
<td><?= htmlspecialchars($item['catalognumber'] ?? '') ?></td>
<td><?= htmlspecialchars($item['accountname'] ?? '') ?></td>
<td><?= htmlspecialchars($item['service'] ?? '') ?></td>
<td><?= htmlspecialchars($item['statuspart'] ?? '') ?></td>
<td><?= htmlspecialchars($item['type_name'] ?? '') ?></td>
<td><?= htmlspecialchars($item['manufacturer'] ?? '') ?></td>
<td><?= htmlspecialchars($item['sitename'] ?? '') ?></td>
<td><?= htmlspecialchars($item['city'] ?? '') ?></td>
<td><?= htmlspecialchars($item['prov'] ?? '') ?></td>
<td><?= htmlspecialchars($item['installationdate'] ?? '') ?></td>
<td><?= htmlspecialchars($item['locationstartdate'] ?? '') ?></td>
<td><?= htmlspecialchars($item['locationenddate'] ?? '') ?></td>
<td><?= htmlspecialchars($item['warrantystartdate'] ?? '') ?></td>
<td><?= htmlspecialchars($item['warrantyenddate'] ?? '') ?></td>
<td><?= htmlspecialchars($item['locationenddate'] == '' ? 'Yes' : 'No' ) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<script src="<?=base_url();?>/assets/xlsx.mini.min.js"></script>
<script>
function exportToExcel() {
const data = document.getElementById("myTable");
var ws = XLSX.utils.table_to_sheet(data);
var wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Sheet 1");
XLSX.writeFile(wb, "ProductsList.xlsx");
}
window.onload = function() {
document.getElementById('saveButton').click();
window.close();
}
</script>
</body>
</html>

View File

@ -31,7 +31,7 @@ if(!isset($sitename)) { $sitename=''; }
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group"> <div class="form-group">
<label for="open" class="form-label border-start border-5 border-primary ps-1">Product Alias</label> <label for="open" class="form-label border-start border-5 border-primary ps-1">Product Alias</label>
<select name='productaliasid' class='form-select form-select-sm select2' > <select name='productaliasid' id='productaliasid' class='form-select form-select-sm select2' >
<option value='0'>-</option> <option value='0'>-</option>
<?php <?php
foreach($productalias as $data) { foreach($productalias as $data) {
@ -47,7 +47,7 @@ if(!isset($sitename)) { $sitename=''; }
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group"> <div class="form-group">
<label class="form-label border-start border-5 border-primary ps-1">Area</label> <label class="form-label border-start border-5 border-primary ps-1">Area</label>
<select name='areaid' class='form-select form-select-sm'> <select name='areaid' id='areaid' class='form-select form-select-sm'>
<option value=''>-</option> <option value=''>-</option>
<?php <?php
foreach($areas as $data) { foreach($areas as $data) {
@ -65,7 +65,7 @@ if(!isset($sitename)) { $sitename=''; }
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group"> <div class="form-group">
<label class="form-label border-start border-5 border-primary ps-1">Product Type</label> <label class="form-label border-start border-5 border-primary ps-1">Product Type</label>
<select name='producttypeid' class='form-select form-select-sm'> <select name='producttypeid' id='producttypeid' class='form-select form-select-sm'>
<option value=''>-</option> <option value=''>-</option>
<?php <?php
foreach($producttype as $data) { foreach($producttype as $data) {
@ -81,7 +81,7 @@ if(!isset($sitename)) { $sitename=''; }
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group"> <div class="form-group">
<label class="form-label border-start border-5 border-primary ps-1">Sitename</label> <label class="form-label border-start border-5 border-primary ps-1">Sitename</label>
<input type='text' class='form-control form-control-sm' name='sitename' value='<?=$sitename;?>'/> <input type='text' class='form-control form-control-sm' name='sitename' id='sitename' value='<?=$sitename;?>'/>
</div> </div>
</div> </div>
</div> </div>
@ -97,10 +97,12 @@ if(!isset($sitename)) { $sitename=''; }
<div class="col-12"> <div class="col-12">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<button onclick="exportToExcel()" class="btn btn-success btn-xs text-white float-end"> <i class="fa fa-file-excel"></i> &nbsp;EXCEL </button>
<div class="table-responsive"> <div class="table-responsive">
<table id="myTable" class="table display table-striped border"> <table id="myTable" class="table display table-striped border">
<thead> <thead class="text-center">
<th>ID</th> <th>Site</th> <th>Product Name</th> <th>Create Date</th> <th>Action</th> <th>ID</th> <th>Site</th> <th>Province</th> <th>Kab/Kota</th> <th>Product Name</th> <th>Install Date</th> <th>Monthly Production</th> <th>Action</th>
</thead> </thead>
<tbody> <tbody>
<?php <?php
@ -109,15 +111,61 @@ if(!isset($sitename)) { $sitename=''; }
$sitename = $data['sitename']; $sitename = $data['sitename'];
$productname = $data['productname']; $productname = $data['productname'];
$productnumber = $data['productnumber']; $productnumber = $data['productnumber'];
if( $data['createdate'] != '' ) { $productaliasid = $data['productaliasid'];
$city = $data['city'];
$prov = $data['prov'];
if( $data['installationdate'] != '' ) {
$installationdate = $data['installationdate'];
$date = new DateTime($installationdate);
$installationdate = $date->format('M d, Y');
} else { $installationdate = ''; }
/* if( $data['createdate'] != '' ) {
$createdate = date('d-m-Y', strtotime($data['createdate'])); $createdate = date('d-m-Y', strtotime($data['createdate']));
} else { $createdate = ''; } } else { $createdate = ''; } */
?> ?>
<tr> <tr>
<td><?=$productid;?></td> <td><?=$sitename;?></td> <td><?=$productid;?></td>
<td><?=$sitename;?></td>
<td><?=$prov;?></td>
<td><?=$city;?></td>
<td><?=$productname;?><?php if(isset($productnumber)) { echo "<br/>SN : $productnumber" ;} ?></td> <td><?=$productname;?><?php if(isset($productnumber)) { echo "<br/>SN : $productnumber" ;} ?></td>
<td><?=$createdate;?></td> <td><?=$installationdate;?></td>
<td class='text-end'>
<!-- Untuk CLQMS -->
<td class="text-end">
<?php if ($productaliasid == '20') { ?>
<div class="text-end col-12 mb-1">
<span class="badge bg-danger fw-bold fs-7">
Dalam Perbaikan
</span>
<?php
// if (isset($testCountCLQMS)) {
// foreach ($testCountCLQMS as $key => $value) {
// if ($key == $productnumber) {
// $valueF = (float) $value;
// $valueF = $valueF / 6;
// $valueF = round($valueF, 1);
// $formatted_number = number_format($valueF, 1, '.', ',');
// echo "<span class='badge bg-danger fw-bold fs-4'>";
// echo "$formatted_number";
// echo " </span> ";
// }
// }
// }
?>
</div>
<div class="col-12 text-end">
<span class="badge bg-info fw-bold fs-7">
Dalam Perbaikan
</span>
</div>
<?php } ?>
</td>
<td class='text-center'>
<div class='row'> <div class='row'>
<div class='col'> <div class='col'>
<button type='button' class='btn btn-success btn-sm openViewProduct' data-productid='<?=$productid;?>'><i class="fas fa-eye"></i> View</button> <button type='button' class='btn btn-success btn-sm openViewProduct' data-productid='<?=$productid;?>'><i class="fas fa-eye"></i> View</button>
@ -138,6 +186,7 @@ if(!isset($sitename)) { $sitename=''; }
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@ -185,5 +234,68 @@ function action(e){
//console.log(e.value); //console.log(e.value);
window.open(e.value); window.open(e.value);
} }
// function exportToExcel() {
// // Ambil seluruh data dari DataTables
// const table = $('#myTable').DataTable();
// const allData = table.rows().data().toArray(); // Mengambil semua data dalam bentuk array
// // Ambil nama kolom dari header tabel
// const headers = [];
// $('#myTable thead th').each(function () {
// headers.push($(this).text()); // Ambil teks header
// });
// // Buat elemen tabel baru untuk ekspor
// const tempTable = document.createElement("table");
// // Tambahkan header ke tabel sementara
// const headerRow = tempTable.insertRow();
// headers.forEach((header) => {
// const cell = headerRow.insertCell();
// cell.textContent = header; // Isi header
// });
// // Fungsi untuk menghapus HTML
// function removeHtmlTags(input) {
// return input.replace(/<\/?[^>]+(>|$)/g, ""); // Hapus semua elemen HTML
// }
// // Tambahkan data baris ke tabel sementara
// allData.forEach((rowData) => {
// const row = tempTable.insertRow();
// rowData.forEach((cellData) => {
// const cell = row.insertCell();
// // Hapus elemen HTML dari data
// let processedValue = removeHtmlTags(cellData);
// cell.textContent = processedValue; // Isi data sel
// });
// });
// // Konversi tabel sementara ke worksheet
// var ws = XLSX.utils.table_to_sheet(tempTable);
// // Modifikasi jika diperlukan (contoh: menyembunyikan kolom ke-7)
// ws["!cols"] = [];
// ws["!cols"][7] = { hidden: true }; // Sembunyikan kolom ke-7
// // Ekspor ke Excel
// var wb = XLSX.utils.book_new();
// XLSX.utils.book_append_sheet(wb, ws, "Sheet 1");
// XLSX.writeFile(wb, "ActivityList.xlsx");
// }
function exportToExcel() {
const productaliasid = $('#productaliasid').val();
const areaid = $('#areaid').val();
const producttypeid = $('#producttypeid').val();
const sitename = $('#sitename').val();
const url = `<?=base_url();?>/products/export?productaliasid=${encodeURIComponent(productaliasid)}&areaid=${encodeURIComponent(areaid)}&producttypeid=${encodeURIComponent(producttypeid)}&sitename=${encodeURIComponent(sitename)}`;
window.open(url, '_blank');
}
</script> </script>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -7,7 +7,7 @@ $productnumber = '';
$siteid = ''; $siteid = '';
$newlocationstartdate = ''; $newlocationstartdate = '';
$oldlocationenddate = ''; $oldlocationenddate = '';
$installationdate = ''; // $installationdate = '';
$productowner = ''; $productowner = '';
if(isset($products)) { $data = $products[0]; } if(isset($products)) { $data = $products[0]; }
if(isset($new_value)) { $data = $new_value; } if(isset($new_value)) { $data = $new_value; }
@ -16,23 +16,46 @@ if(isset($data)) {
$siteid = $data['siteid']; $siteid = $data['siteid'];
if(isset($data['newlocationstartdate'])) { $newlocationstartdate = $data['newlocationstartdate']; } if(isset($data['newlocationstartdate'])) { $newlocationstartdate = $data['newlocationstartdate']; }
if(isset($data['oldlocationenddate'])) { $oldlocationenddate = $data['oldlocationenddate']; } if(isset($data['oldlocationenddate'])) { $oldlocationenddate = $data['oldlocationenddate']; }
$installationdate = $data['installationdate'];
// if (isset($data['installationdate'])) {
// $installationdate = $data['installationdate'];
// }
// $installationdate = $data['installationdate'];
$productowner = $data['productowner']; $productowner = $data['productowner'];
// $productnumber = $data['productnumber'];
if (isset($data['productnumber'])) {
$productnumber = $data['productnumber']; $productnumber = $data['productnumber'];
} else {
// Handle case when 'installationdate' key is not present
$productnumber = $new_value['productnumb'];
}
// $productname = $data['productname'];
if (isset($data['productname'])) {
$productname = $data['productname']; $productname = $data['productname'];
} else {
$productname = '';
// Handle case when 'installationdate' key is not present
$productname = $new_value['productnam'];
}
} }
?> ?>
<div class="form-body"> <div class="form-body">
<h3 class="card-title">Product Moving</h3> <h3 class="card-title">Product Moving</h3>
<hr> <hr>
<?php <?php
if(isset($validation)) { if(isset($validation)) {
?> ?>
<div class='alert alert-danger alert-dismissible'> <div class='alert alert-danger alert-dismissible'>
<?= $validation->listErrors(); ?> <?= $validation->listErrors(); ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"> <span aria-hidden="true"></span> </button> <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"> <span aria-hidden="true"></span> </button>
</div> </div>
<?php <?php
} }
?> ?>
@ -41,12 +64,12 @@ if(isset($data)) {
<input type='hidden' name='productid' value='<?=$productid;?>'/> <input type='hidden' name='productid' value='<?=$productid;?>'/>
<div class="form-group row"> <div class="form-group row">
<label class="col-3 col-form-label">Product# (SN.)</label> <label class="col-3 col-form-label">Product# (SN.)</label>
<div class="col-9"><input class="form-control" type="text" value="<?=$productnumber;?>" disabled></div> <div class="col-9"><input class="form-control" type="text" name='productnumb' value="<?=$productnumber;?>" readonly></div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-3 col-form-label">Catalog</label> <label class="col-3 col-form-label">Catalog</label>
<div class="col-9"><input class="form-control" type="text" value="<?=$productname;?>" disabled></div> <div class="col-9"><input class="form-control" type="text" name='productnam' value="<?=$productname;?>" readonly></div>
</div> </div>
<div class="form-group row"> <div class="form-group row">

View File

@ -0,0 +1,140 @@
<?= $this->extend('layouts/main.php') ?>
<?= $this->section('content') ?>
<script src="<?= base_url('assets/js/swal.js'); ?>"></script>
<div class="page-wrapper">
<?php $session = \Config\Services::session(); ?>
<?php if ($session->getFlashdata('success') || $session->getFlashdata('error')): ?>
<script>
const Toast = Swal.mixin({
toast: true,
position: "top-end",
showConfirmButton: false,
timer: 3000,
timerProgressBar: true,
didOpen: (toast) => {
toast.onmouseenter = Swal.stopTimer;
toast.onmouseleave = Swal.resumeTimer;
}
});
const icon = <?= $session->getFlashdata('success') ? "'success'" : ($session->getFlashdata('error') ? "'error'" : "''") ?>;
Toast.fire({
icon: icon,
title: "<?= $session->getFlashdata('success') ? $session->getFlashdata('success') : $session->getFlashdata('error') ?>",
});
</script>
<?php endif; ?>
<div class="container-fluid">
<div class="row page-titles">
<h4 class="text-themecolor">Products Temp</h4>
</div>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<div class="table-responsive" style="min-height: 70vh;">
<table id="myTable" class="table">
<thead>
<tr>
<th>No.</th>
<th>Catalog number</th>
<th>Product name</th>
<th>Product number</th>
<th>Location start date</th>
<th>Reference</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php $no = 1;?>
<?php foreach ($products as $value) : ?>
<tr>
<td><?= $no++; ?></td>
<td><?= $value['catalognumber']; ?></td>
<td><?= $value['productname']; ?></td>
<td><?= $value['productnumber']; ?></td>
<td><?= $value['locationstartdate']; ?></td>
<td><?= $value['reference']; ?></td>
<td>
<div class="d-flex gap-3">
<form id="validate-<?= $value['productid']?>" method="post" action="<?= base_url('producttemp/validate'); ?>" class="d-flex align-items-center">
<input type="hidden" name="producttemp-productid" value="<?= $value['productid']?>">
<?php if ($value['duplicates']): ?>
<?php foreach ($value['duplicates'] as $duplicate): ?>
<input type="hidden" name="product-productid" value="<?= $duplicate['productid']; ?>">
<?php endforeach; ?>
<?php endif; ?>
<button type="submit" class="btn btn-success btn-sm text-white border border-1 fw-medium" style="padding: 3px 7px; font-size: 0.75rem;" data-productid="<?= $value['productid']; ?>" onclick="confirmModal('validate','validate-<?= $value['productid']?>')">Validate</button>
</form>
<div class="dropdown">
<a class="btn btn-light border border-1" style="padding: 3px 7px; font-size: 0.75rem;" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<b>...</b>
</a>
<ul class="dropdown-menu" style="min-width: fit-content;">
<li>
<a class="dropdown-item d-flex justify-content-between gap-3 view-button" style="opacity: 85%;" href="#" data-productid="<?= $value['productid']; ?>" data-bs-toggle="modal" data-bs-target="#exampleModal">
<span>View</span>
<span><i class="fa-solid fa-eye"></i></span>
</a>
</li>
<li>
<a class="dropdown-item d-flex justify-content-between gap-3 edit-button" style="opacity: 85%;" href="#" data-productid="<?= $value['productid']; ?>" data-bs-toggle="offcanvas" data-bs-target="#offcanvasRight" aria-controls="offcanvasRight">
<span>Edit</span>
<span><i class="fa-solid fa-pen-to-square"></i></span>
</a>
</li>
<form id="delete-<?= $value['productid']; ?>" method="post" action="<?= base_url('producttemp/delete/' . $value['productid']); ?>">
<button type="submit" class="dropdown-item d-flex justify-content-between gap-3" style="opacity: 85%;" onclick="confirmModal('delete', 'delete-<?= $value['productid']; ?>')">
<span>Delete</span>
<span><i class="fa-solid fa-trash-can"></i></span>
</button>
</form>
</ul>
</div>
</div>
</td>
</tr>
<?php if ($value['duplicates']): ?>
<?php foreach ($value['duplicates'] as $duplicate): ?>
<tr>
<td>&#128161;</td>
<td><?php echo $duplicate['catalognumber']; ?></td>
<td></td>
<td><?php echo $duplicate['productnumber']; ?></td>
<td><?php echo $duplicate['locationstartdate']; ?></td>
<td></td>
<td></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<?= view('components/modal') ?>
<?= view('components/offcanvas') ?>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script>
$(function () {
$('#myTable').DataTable({
"order" : []
});
});
</script>
<script src="<?= base_url('assets/js/just-validate.production.min.js'); ?>"></script>
<script src="<?= base_url('assets/js/data2.js'); ?>"></script>
<script src="<?= base_url('assets/js/confirmswal.js'); ?>"></script>
<script src="<?= base_url('assets/js/validate.js'); ?>"></script>
<?= $this->endSection() ?>

View File

@ -47,8 +47,16 @@ if(isset($data)) {
foreach ($accounts as $data) { foreach ($accounts as $data) {
$qaccountid = $data['accountid']; $qaccountid = $data['accountid'];
$qaccountname = $data['accountname']; $qaccountname = $data['accountname'];
if ($qaccountid == $accountid) { echo "<option value='$qaccountid' selected>$qaccountname</option>"; }
else { echo "<option value='$qaccountid'>$qaccountname</option>"; } $qaccountinitial = $data['initial'];
if ($qaccountinitial != null) {
$qaccountinitial = " (" . $qaccountinitial . ")";
} else {
$qaccountinitial = "";
}
if ($qaccountid == $accountid) { echo "<option value='$qaccountid' selected>$qaccountname $qaccountinitial</option>"; }
else { echo "<option value='$qaccountid'>$qaccountname $qaccountinitial</option>"; }
} }
?> ?>
</select> </select>

View File

@ -62,6 +62,12 @@ if(!isset($sitename)) {$sitename = '';}
$siteid = $data['siteid']; $siteid = $data['siteid'];
$sitename = $data['sitename']; $sitename = $data['sitename'];
$accountname = $data['accountname']; $accountname = $data['accountname'];
$initial = $data['initial'];
if ($initial != null) {
$initial = "(" . $initial . ")";
} else {
$initial = "";
}
$toggletext = "<a class='btn btn-danger btn-sm crm-confirmation' href='sites/toggle/$siteid'> <i class='fas fa-trash-alt'></i> Disable </a>"; $toggletext = "<a class='btn btn-danger btn-sm crm-confirmation' href='sites/toggle/$siteid'> <i class='fas fa-trash-alt'></i> Disable </a>";
if( $data['createdate'] != '' ) { if( $data['createdate'] != '' ) {
@ -73,7 +79,7 @@ if(!isset($sitename)) {$sitename = '';}
} }
?> ?>
<tr> <tr>
<td><?=$siteid;?></td> <td><?=$sitename;?></td> <td><?=$accountname;?></td> <td><?=$createdate;?></td> <td><?=$siteid;?></td> <td><?=$sitename;?></td> <td><?=$accountname;?> <?=$initial;?></td> <td><?=$createdate;?></td>
<td> <td>
<button type='button' class='btn btn-success btn-sm openViewSite' data-siteid='<?=$siteid;?>'><i class="fas fa-eye"></i> View</button> <button type='button' class='btn btn-success btn-sm openViewSite' data-siteid='<?=$siteid;?>'><i class="fas fa-eye"></i> View</button>
<a class='btn btn-warning btn-sm' href='sites/edit/<?=$siteid;?>' <a class='btn btn-warning btn-sm' href='sites/edit/<?=$siteid;?>'

View File

@ -4,6 +4,12 @@ $siteid = $data['siteid'];
$accountname = $data['accountname']; $accountname = $data['accountname'];
$sitename = $data['sitename']; $sitename = $data['sitename'];
$marketing = $data['marketing']; $marketing = $data['marketing'];
$initial = $data['initial'];
if ($initial != null) {
$initial = "(" . $initial . ")";
} else {
$initial = "";
}
$createdate = date('d-m-Y', strtotime($data['createdate'])); $createdate = date('d-m-Y', strtotime($data['createdate']));
$data_log = $sites_log; $data_log = $sites_log;
?> ?>
@ -16,7 +22,7 @@ $data_log = $sites_log;
<div class='col-3'>Site ID</div> <div class='col-9'>: <?=$siteid;?></div> <div class='col-3'>Site ID</div> <div class='col-9'>: <?=$siteid;?></div>
</div> </div>
<div class='row'> <div class='row'>
<div class='col-3'>Account Name</div> <div class='col-9'>: <?=$accountname;?></div> <div class='col-3'>Account Name</div> <div class='col-9'>: <?=$accountname;?> <?=$initial;?></div>
</div> </div>
<div class='row'> <div class='row'>
<div class='col-3'>Site Name</div> <div class='col-9'>: <?=$sitename;?></div> <div class='col-3'>Site Name</div> <div class='col-9'>: <?=$sitename;?></div>

View File

@ -63,18 +63,32 @@
$quantity = $data['quantity']; $quantity = $data['quantity'];
$unit = $data['unit']; $unit = $data['unit'];
$baseunit = $data['baseunit']; $baseunit = $data['baseunit'];
if( $data['logdate'] != '' ) { if( $data['enddate'] != '' ) {
$logdate = date('d-m-Y', strtotime($data['logdate'])); $enddate = date('d-m-Y', strtotime($data['enddate']));
} else { $createdate = ''; } } else { $enddate = ''; }
if( $enddate != '' ) {
$classend = 'class="bg-danger"';
$toggletext = "<a class='btn btn-success btn-sm' href='unitgroup/toggle/$unitgroupid'
onclick=\"window.open(this.href, 'form','width=400,height=300,toolbar=1,resizable=0'); return false;\">
<i class='fa-solid fa-check'></i> Enable
</a>";
} else {
$toggletext = "<a class='btn btn-danger btn-sm' href='unitgroup/toggle/$unitgroupid'
onclick=\"window.open(this.href, 'form','width=400,height=300,toolbar=1,resizable=0'); return false;\">
<i class='fas fa-trash-alt'></i> Disable
</a>";
}
?> ?>
<tr>
<tr <?php echo $enddate == '' ? '' : " class='bg-danger' "; ?> >
<td><?=$unitgroupcode;?></td> <td><?=$productname;?></td> <td><?=$unit;?></td> <td><?=$quantity;?></td> <td><?=$baseunit;?></td> <td><?=$unitgroupcode;?></td> <td><?=$productname;?></td> <td><?=$unit;?></td> <td><?=$quantity;?></td> <td><?=$baseunit;?></td>
<td> <td>
<a class='btn btn-warning btn-sm' href='unitgroup/edit/<?=$unitgroupid;?>' <a class='btn btn-warning btn-sm' href='unitgroup/edit/<?=$unitgroupid;?>'
onclick="window.open(this.href, 'Catalog Editor','width=900,height=600,toolbar=1,resizable=0'); return false;"> onclick="window.open(this.href, 'Catalog Editor','width=900,height=600,toolbar=1,resizable=0'); return false;">
<i class="fas fa-pencil-alt"></i> Edit <i class="fas fa-pencil-alt"></i> Edit
</a> </a>
<?//=$toggletext;?> <?=$toggletext;?>
</td> </td>
</tr> </tr>
<?php } ?> <?php } ?>

125
builds Normal file
View File

@ -0,0 +1,125 @@
#!/usr/bin/env php
<?php
define('LATEST_RELEASE', '^4.0');
define('GITHUB_URL', 'https://github.com/codeigniter4/codeigniter4');
/*
* --------------------------------------------------------------------
* Stability Toggle
* --------------------------------------------------------------------
* Use this script to toggle the CodeIgniter dependency between the
* latest stable release and the most recent development update.
*
* Usage: php builds [release|development]
*/
// Determine the requested stability
if (empty($argv[1]) || ! in_array($argv[1], ['release', 'development'], true)) {
echo 'Usage: php builds [release|development]' . PHP_EOL;
exit;
}
$dev = $argv[1] === 'development';
$modified = [];
// Locate each file and update it for the requested stability
$file = __DIR__ . DIRECTORY_SEPARATOR . 'composer.json';
if (is_file($file)) {
$contents = file_get_contents($file);
if ((string) $contents !== '') {
$array = json_decode($contents, true);
if (is_array($array)) {
if ($dev) {
$array['minimum-stability'] = 'dev';
$array['prefer-stable'] = true;
$array['repositories'] ??= [];
$found = false;
foreach ($array['repositories'] as $repository) {
if ($repository['url'] === GITHUB_URL) {
$found = true;
break;
}
}
if (! $found) {
$array['repositories'][] = [
'type' => 'vcs',
'url' => GITHUB_URL,
];
}
$array['require']['codeigniter4/codeigniter4'] = 'dev-develop';
unset($array['require']['codeigniter4/framework']);
} else {
unset($array['minimum-stability']);
if (isset($array['repositories'])) {
foreach ($array['repositories'] as $i => $repository) {
if ($repository['url'] === GITHUB_URL) {
unset($array['repositories'][$i]);
break;
}
}
if (empty($array['repositories'])) {
unset($array['repositories']);
}
}
$array['require']['codeigniter4/framework'] = LATEST_RELEASE;
unset($array['require']['codeigniter4/codeigniter4']);
}
file_put_contents($file, json_encode($array, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL);
$modified[] = $file;
} else {
echo 'Warning: Unable to decode composer.json! Skipping...' . PHP_EOL;
}
} else {
echo 'Warning: Unable to read composer.json! Skipping...' . PHP_EOL;
}
}
$files = [
__DIR__ . DIRECTORY_SEPARATOR . 'app/Config/Paths.php',
__DIR__ . DIRECTORY_SEPARATOR . 'phpunit.xml.dist',
__DIR__ . DIRECTORY_SEPARATOR . 'phpunit.xml',
];
foreach ($files as $file) {
if (is_file($file)) {
$contents = file_get_contents($file);
if ($dev) {
$contents = str_replace('vendor/codeigniter4/framework', 'vendor/codeigniter4/codeigniter4', $contents);
} else {
$contents = str_replace('vendor/codeigniter4/codeigniter4', 'vendor/codeigniter4/framework', $contents);
}
file_put_contents($file, $contents);
$modified[] = $file;
}
}
if ($modified === []) {
echo 'No files modified.' . PHP_EOL;
} else {
echo 'The following files were modified:' . PHP_EOL;
foreach ($modified as $file) {
echo " * {$file}" . PHP_EOL;
}
echo 'Run `composer update` to sync changes with your vendor folder.' . PHP_EOL;
}

43
composer.json Normal file
View File

@ -0,0 +1,43 @@
{
"name": "codeigniter4/appstarter",
"description": "CodeIgniter4 starter app",
"license": "MIT",
"type": "project",
"homepage": "https://codeigniter.com",
"support": {
"forum": "https://forum.codeigniter.com/",
"source": "https://github.com/codeigniter4/CodeIgniter4",
"slack": "https://codeigniterchat.slack.com"
},
"require": {
"php": "^8.1",
"codeigniter4/framework": "^4.0"
},
"require-dev": {
"fakerphp/faker": "^1.9",
"mikey179/vfsstream": "^1.6",
"phpunit/phpunit": "^10.5.16"
},
"autoload": {
"psr-4": {
"App\\": "app/",
"Config\\": "app/Config/"
},
"exclude-from-classmap": [
"**/Database/Migrations/**"
]
},
"autoload-dev": {
"psr-4": {
"Tests\\Support\\": "tests/_support"
}
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true
},
"scripts": {
"test": "phpunit"
}
}

2087
composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

69
env Normal file
View File

@ -0,0 +1,69 @@
#--------------------------------------------------------------------
# Example Environment Configuration file
#
# This file can be used as a starting point for your own
# custom .env files, and contains most of the possible settings
# available in a default install.
#
# By default, all of the settings are commented out. If you want
# to override the setting, you must un-comment it by removing the '#'
# at the beginning of the line.
#--------------------------------------------------------------------
#--------------------------------------------------------------------
# ENVIRONMENT
#--------------------------------------------------------------------
# CI_ENVIRONMENT = production
#--------------------------------------------------------------------
# APP
#--------------------------------------------------------------------
# app.baseURL = ''
# If you have trouble with `.`, you could also use `_`.
# app_baseURL = ''
# app.forceGlobalSecureRequests = false
# app.CSPEnabled = false
#--------------------------------------------------------------------
# DATABASE
#--------------------------------------------------------------------
# database.default.hostname = localhost
# database.default.database = ci4
# database.default.username = root
# database.default.password = root
# database.default.DBDriver = MySQLi
# database.default.DBPrefix =
# database.default.port = 3306
# If you use MySQLi as tests, first update the values of Config\Database::$tests.
# database.tests.hostname = localhost
# database.tests.database = ci4_test
# database.tests.username = root
# database.tests.password = root
# database.tests.DBDriver = MySQLi
# database.tests.DBPrefix =
# database.tests.charset = utf8mb4
# database.tests.DBCollat = utf8mb4_general_ci
# database.tests.port = 3306
#--------------------------------------------------------------------
# ENCRYPTION
#--------------------------------------------------------------------
# encryption.key =
#--------------------------------------------------------------------
# SESSION
#--------------------------------------------------------------------
# session.driver = 'CodeIgniter\Session\Handlers\FileHandler'
# session.savePath = null
#--------------------------------------------------------------------
# LOGGER
#--------------------------------------------------------------------
# logger.threshold = 4

63
phpunit.xml.dist Normal file
View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
bootstrap="vendor/codeigniter4/framework/system/Test/bootstrap.php"
backupGlobals="false"
beStrictAboutOutputDuringTests="true"
colors="true"
columns="max"
failOnRisky="true"
failOnWarning="true"
cacheDirectory="build/.phpunit.cache">
<coverage
includeUncoveredFiles="true"
pathCoverage="false"
ignoreDeprecatedCodeUnits="true"
disableCodeCoverageIgnore="true">
<report>
<clover outputFile="build/logs/clover.xml"/>
<html outputDirectory="build/logs/html"/>
<php outputFile="build/logs/coverage.serialized"/>
<text outputFile="php://stdout" showUncoveredFiles="false"/>
</report>
</coverage>
<testsuites>
<testsuite name="App">
<directory>./tests</directory>
</testsuite>
</testsuites>
<logging>
<testdoxHtml outputFile="build/logs/testdox.html"/>
<testdoxText outputFile="build/logs/testdox.txt"/>
<junit outputFile="build/logs/logfile.xml"/>
</logging>
<source>
<include>
<directory suffix=".php">./app</directory>
</include>
<exclude>
<directory suffix=".php">./app/Views</directory>
<file>./app/Config/Routes.php</file>
</exclude>
</source>
<php>
<server name="app.baseURL" value="http://example.com/"/>
<server name="CODEIGNITER_SCREAM_DEPRECATIONS" value="0"/>
<!-- Directory containing phpunit.xml -->
<const name="HOMEPATH" value="./"/>
<!-- Directory containing the Paths config file -->
<const name="CONFIGPATH" value="./app/Config/"/>
<!-- Directory containing the front controller (index.php) -->
<const name="PUBLICPATH" value="./public/"/>
<!-- Database configuration -->
<!-- Uncomment to provide your own database for testing
<env name="database.tests.hostname" value="localhost"/>
<env name="database.tests.database" value="tests"/>
<env name="database.tests.username" value="tests_user"/>
<env name="database.tests.password" value=""/>
<env name="database.tests.DBDriver" value="MySQLi"/>
<env name="database.tests.DBPrefix" value="tests_"/>
-->
</php>
</phpunit>

110
preload.php Normal file
View File

@ -0,0 +1,110 @@
<?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.
*/
use CodeIgniter\Boot;
use Config\Paths;
/*
*---------------------------------------------------------------
* Sample file for Preloading
*---------------------------------------------------------------
* See https://www.php.net/manual/en/opcache.preloading.php
*
* How to Use:
* 0. Copy this file to your project root folder.
* 1. Set the $paths property of the preload class below.
* 2. Set opcache.preload in php.ini.
* php.ini:
* opcache.preload=/path/to/preload.php
*/
// Load the paths config file
require __DIR__ . '/app/Config/Paths.php';
// Path to the front controller
define('FCPATH', __DIR__ . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR);
class preload
{
/**
* @var array Paths to preload.
*/
private array $paths = [
[
'include' => __DIR__ . '/vendor/codeigniter4/framework/system', // Change this path if using manual installation
'exclude' => [
// Not needed if you don't use them.
'/system/Database/OCI8/',
'/system/Database/Postgre/',
'/system/Database/SQLite3/',
'/system/Database/SQLSRV/',
// Not needed for web apps.
'/system/Database/Seeder.php',
'/system/Test/',
'/system/CLI/',
'/system/Commands/',
'/system/Publisher/',
'/system/ComposerScripts.php',
// Not Class/Function files.
'/system/Config/Routes.php',
'/system/Language/',
'/system/bootstrap.php',
'/system/util_bootstrap.php',
'/system/rewrite.php',
'/Views/',
// Errors occur.
'/system/ThirdParty/',
],
],
];
public function __construct()
{
$this->loadAutoloader();
}
private function loadAutoloader(): void
{
$paths = new Paths();
require rtrim($paths->systemDirectory, '\\/ ') . DIRECTORY_SEPARATOR . 'Boot.php';
Boot::preload($paths);
}
/**
* Load PHP files.
*/
public function load(): void
{
foreach ($this->paths as $path) {
$directory = new RecursiveDirectoryIterator($path['include']);
$fullTree = new RecursiveIteratorIterator($directory);
$phpFiles = new RegexIterator(
$fullTree,
'/.+((?<!Test)+\.php$)/i',
RecursiveRegexIterator::GET_MATCH,
);
foreach ($phpFiles as $key => $file) {
foreach ($path['exclude'] as $exclude) {
if (str_contains($file[0], $exclude)) {
continue 2;
}
}
require_once $file[0];
echo 'Loaded: ' . $file[0] . "\n";
}
}
}
}
(new preload())->load();

Some files were not shown because too many files have changed in this diff Show More