├── .gitignore ├── LICENSE ├── README.md ├── app ├── .htaccess ├── Common.php ├── Config │ ├── App.php │ ├── Autoload.php │ ├── Boot │ │ ├── development.php │ │ ├── production.php │ │ └── testing.php │ ├── Cache.php │ ├── Constants.php │ ├── ContentSecurityPolicy.php │ ├── Database.php │ ├── DocTypes.php │ ├── Email.php │ ├── Encryption.php │ ├── Events.php │ ├── Exceptions.php │ ├── Filters.php │ ├── ForeignCharacters.php │ ├── Format.php │ ├── Honeypot.php │ ├── Images.php │ ├── Kint.php │ ├── Logger.php │ ├── Migrations.php │ ├── Mimes.php │ ├── Modules.php │ ├── Pager.php │ ├── Paths.php │ ├── Routes.php │ ├── Services.php │ ├── Toolbar.php │ ├── UserAgents.php │ ├── Validation.php │ └── View.php ├── Controllers │ ├── BaseController.php │ ├── Chat.php │ ├── Dashboard.php │ ├── Home.php │ ├── Server.php │ └── Users.php ├── Database │ ├── Migrations │ │ ├── .gitkeep │ │ ├── 20121031100537_add_users.php │ │ └── 2020-04-24-174346_add_connections.php │ └── Seeds │ │ └── .gitkeep ├── Filters │ ├── .gitkeep │ ├── Auth.php │ ├── Noauth.php │ └── UsersCheck.php ├── Helpers │ └── .gitkeep ├── Language │ └── .gitkeep ├── Libraries │ ├── .gitkeep │ └── Chat.php ├── Models │ ├── .gitkeep │ ├── ConnectionsModel.php │ └── UserModel.php ├── ThirdParty │ └── .gitkeep ├── Validation │ └── UserRules.php ├── Views │ ├── chat.php │ ├── dashboard.php │ ├── errors │ │ ├── cli │ │ │ ├── error_404.php │ │ │ ├── error_exception.php │ │ │ └── production.php │ │ └── html │ │ │ ├── debug.css │ │ │ ├── debug.js │ │ │ ├── error_404.php │ │ │ ├── error_exception.php │ │ │ └── production.php │ ├── login.php │ ├── profile.php │ ├── register.php │ ├── templates │ │ ├── footer.php │ │ └── header.php │ └── welcome_message.php └── index.html ├── builds ├── composer.json ├── contributing.md ├── env ├── license.txt ├── phpunit.xml.dist ├── public ├── .htaccess ├── assets │ ├── css │ │ └── style.css │ └── img │ │ ├── alex.jpg │ │ ├── jon.jpg │ │ └── mary.jpg ├── favicon.ico ├── index.php └── robots.txt ├── spark ├── tests ├── README.md ├── _support │ ├── Autoloader │ │ └── UnnamespacedClass.php │ ├── Commands │ │ ├── AbstractInfo.php │ │ └── AppInfo.php │ ├── Config │ │ ├── BadRegistrar.php │ │ ├── Registrar.php │ │ └── Routes.php │ ├── Controllers │ │ └── Popcorn.php │ ├── Database │ │ ├── Migrations │ │ │ ├── 20160428212500_Create_test_tables.php │ │ │ └── 2020-02-22-222222_example_migration.php │ │ └── Seeds │ │ │ ├── AnotherSeeder.php │ │ │ ├── CITestSeeder.php │ │ │ └── ExampleSeeder.php │ ├── DatabaseTestCase.php │ ├── Files │ │ ├── able │ │ │ ├── apple.php │ │ │ ├── fig_3.php │ │ │ └── prune_ripe.php │ │ └── baker │ │ │ └── banana.php │ ├── HTTP │ │ └── Files │ │ │ ├── CookiesHolder.txt │ │ │ └── tmp │ │ │ ├── fileA.txt │ │ │ └── fileB.txt │ ├── Images │ │ ├── EXIFsamples │ │ │ ├── down-mirrored.jpg │ │ │ ├── down.jpg │ │ │ ├── left-mirrored.jpg │ │ │ ├── left.jpg │ │ │ ├── right-mirrored.jpg │ │ │ ├── right.jpg │ │ │ ├── up-mirrored.jpg │ │ │ └── up.jpg │ │ ├── Steveston_dusk.JPG │ │ ├── ci-logo.gif │ │ ├── ci-logo.jpeg │ │ └── ci-logo.png │ ├── Language │ │ ├── SecondMockLanguage.php │ │ ├── ab-CD │ │ │ └── Allin.php │ │ ├── ab │ │ │ └── Allin.php │ │ ├── en-ZZ │ │ │ └── More.php │ │ ├── en │ │ │ ├── Allin.php │ │ │ ├── Core.php │ │ │ └── More.php │ │ └── ru │ │ │ └── Language.php │ ├── Libraries │ │ └── ConfigReader.php │ ├── Log │ │ └── Handlers │ │ │ └── TestHandler.php │ ├── MigrationTestMigrations │ │ └── Database │ │ │ └── Migrations │ │ │ ├── 2018-01-24-102300_Another_migration.py │ │ │ ├── 2018-01-24-102301_Some_migration.php │ │ │ └── 2018-01-24-102302_Another_migration.php │ ├── Models │ │ ├── EntityModel.php │ │ ├── EventModel.php │ │ ├── ExampleModel.php │ │ ├── JobModel.php │ │ ├── SecondaryModel.php │ │ ├── SimpleEntity.php │ │ ├── UserModel.php │ │ ├── ValidErrorsModel.php │ │ └── ValidModel.php │ ├── RESTful │ │ ├── Worker.php │ │ └── Worker2.php │ ├── Services.php │ ├── SessionTestCase.php │ ├── SomeEntity.php │ ├── Validation │ │ ├── TestRules.php │ │ └── uploads │ │ │ └── phpUxc0ty │ ├── View │ │ ├── SampleClass.php │ │ └── Views │ │ │ ├── simple.php │ │ │ └── simpler.php │ └── coverage.txt ├── database │ └── ExampleDatabaseTest.php ├── session │ └── ExampleSessionTest.php └── unit │ └── HealthTest.php └── writable ├── .htaccess ├── cache └── index.html ├── logs └── index.html ├── session └── index.html └── uploads └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | #------------------------- 2 | # Operating Specific Junk Files 3 | #------------------------- 4 | 5 | # OS X 6 | .DS_Store 7 | .AppleDouble 8 | .LSOverride 9 | 10 | # OS X Thumbnails 11 | ._* 12 | 13 | # Windows image file caches 14 | Thumbs.db 15 | ehthumbs.db 16 | Desktop.ini 17 | 18 | # Recycle Bin used on file shares 19 | $RECYCLE.BIN/ 20 | 21 | # Windows Installer files 22 | *.cab 23 | *.msi 24 | *.msm 25 | *.msp 26 | 27 | # Windows shortcuts 28 | *.lnk 29 | 30 | # Linux 31 | *~ 32 | 33 | # KDE directory preferences 34 | .directory 35 | 36 | # Linux trash folder which might appear on any partition or disk 37 | .Trash-* 38 | 39 | #------------------------- 40 | # Environment Files 41 | #------------------------- 42 | # These should never be under version control, 43 | # as it poses a security risk. 44 | .env 45 | .vagrant 46 | Vagrantfile 47 | 48 | #------------------------- 49 | # Temporary Files 50 | #------------------------- 51 | writable/cache/* 52 | !writable/cache/index.html 53 | 54 | writable/logs/* 55 | !writable/logs/index.html 56 | 57 | writable/session/* 58 | !writable/session/index.html 59 | 60 | writable/uploads/* 61 | !writable/uploads/index.html 62 | 63 | writable/debugbar/* 64 | 65 | php_errors.log 66 | 67 | #------------------------- 68 | # User Guide Temp Files 69 | #------------------------- 70 | user_guide_src/build/* 71 | user_guide_src/cilexer/build/* 72 | user_guide_src/cilexer/dist/* 73 | user_guide_src/cilexer/pycilexer.egg-info/* 74 | 75 | #------------------------- 76 | # Test Files 77 | #------------------------- 78 | tests/coverage* 79 | 80 | # Don't save phpunit under version control. 81 | phpunit 82 | 83 | #------------------------- 84 | # Composer 85 | #------------------------- 86 | vendor/ 87 | composer.lock 88 | 89 | #------------------------- 90 | # IDE / Development Files 91 | #------------------------- 92 | 93 | # Modules Testing 94 | _modules/* 95 | 96 | # phpenv local config 97 | .php-version 98 | 99 | # Jetbrains editors (PHPStorm, etc) 100 | .idea/ 101 | *.iml 102 | 103 | # Netbeans 104 | nbproject/ 105 | build/ 106 | nbbuild/ 107 | dist/ 108 | nbdist/ 109 | nbactions.xml 110 | nb-configuration.xml 111 | .nb-gradle/ 112 | 113 | # Sublime Text 114 | *.tmlanguage.cache 115 | *.tmPreferences.cache 116 | *.stTheme.cache 117 | *.sublime-workspace 118 | *.sublime-project 119 | .phpintel 120 | /api/ 121 | 122 | # Visual Studio Code 123 | .vscode/ 124 | 125 | /results/ 126 | /phpunit*.xml 127 | /.phpunit.*.cache 128 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 CodeIgniter 4 web framework 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CodeIgniter 4 Real Time Chat Application 2 | This are the project files used in YouTube tutorial 3 | > https://www.youtube.com/watch?v=9qIIjv17IgQ 4 | 5 | ### 1. Download & Install 6 | Once cloned, open terminal and navigate inside the project folder, then run: 7 | > composer install 8 | 9 | ### 2. Setup 10 | Create a new database. DO NOT create any tables yet. Create .env file (a duplicate of 'env' sample file) and uncomment default.database block. Then also change the database connection details, after that run in your terminal: 11 | > php spark migrate 12 | 13 | This will create the tables that are required for the CodeIgniter 4 Chat Tutorial 14 | 15 | ### 3. Register users 16 | Tables in your database are empty, so you will have to create users yourself through the registration form. 17 | 18 | ### 4. Enjoy the tutorial. 19 | -------------------------------------------------------------------------------- /app/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | Require all denied 3 | 4 | 5 | Deny from all 6 | 7 | -------------------------------------------------------------------------------- /app/Common.php: -------------------------------------------------------------------------------- 1 | SYSPATH 50 | * `]; 51 | */ 52 | $psr4 = [ 53 | 'App' => APPPATH, // To ensure filters, etc still found, 54 | APP_NAMESPACE => APPPATH, // For custom namespace 55 | 'Config' => APPPATH . 'Config', 56 | ]; 57 | 58 | /** 59 | * ------------------------------------------------------------------- 60 | * Class Map 61 | * ------------------------------------------------------------------- 62 | * The class map provides a map of class names and their exact 63 | * location on the drive. Classes loaded in this manner will have 64 | * slightly faster performance because they will not have to be 65 | * searched for within one or more directories as they would if they 66 | * were being autoloaded through a namespace. 67 | * 68 | * Prototype: 69 | * 70 | * $Config['classmap'] = [ 71 | * 'MyClass' => '/path/to/class/file.php' 72 | * ]; 73 | */ 74 | $classmap = []; 75 | 76 | //-------------------------------------------------------------------- 77 | // Do Not Edit Below This Line 78 | //-------------------------------------------------------------------- 79 | 80 | $this->psr4 = array_merge($this->psr4, $psr4); 81 | $this->classmap = array_merge($this->classmap, $classmap); 82 | 83 | unset($psr4, $classmap); 84 | } 85 | 86 | //-------------------------------------------------------------------- 87 | 88 | } 89 | -------------------------------------------------------------------------------- /app/Config/Boot/development.php: -------------------------------------------------------------------------------- 1 | '127.0.0.1', 82 | 'port' => 11211, 83 | 'weight' => 1, 84 | 'raw' => false, 85 | ]; 86 | 87 | /* 88 | | ------------------------------------------------------------------------- 89 | | Redis settings 90 | | ------------------------------------------------------------------------- 91 | | Your Redis server can be specified below, if you are using 92 | | the Redis or Predis drivers. 93 | | 94 | */ 95 | public $redis = [ 96 | 'host' => '127.0.0.1', 97 | 'password' => null, 98 | 'port' => 6379, 99 | 'timeout' => 0, 100 | 'database' => 0, 101 | ]; 102 | 103 | /* 104 | |-------------------------------------------------------------------------- 105 | | Available Cache Handlers 106 | |-------------------------------------------------------------------------- 107 | | 108 | | This is an array of cache engine alias' and class names. Only engines 109 | | that are listed here are allowed to be used. 110 | | 111 | */ 112 | public $validHandlers = [ 113 | 'dummy' => \CodeIgniter\Cache\Handlers\DummyHandler::class, 114 | 'file' => \CodeIgniter\Cache\Handlers\FileHandler::class, 115 | 'memcached' => \CodeIgniter\Cache\Handlers\MemcachedHandler::class, 116 | 'predis' => \CodeIgniter\Cache\Handlers\PredisHandler::class, 117 | 'redis' => \CodeIgniter\Cache\Handlers\RedisHandler::class, 118 | 'wincache' => \CodeIgniter\Cache\Handlers\WincacheHandler::class, 119 | ]; 120 | } 121 | -------------------------------------------------------------------------------- /app/Config/Constants.php: -------------------------------------------------------------------------------- 1 | '', 34 | 'hostname' => 'localhost', 35 | 'username' => '', 36 | 'password' => '', 37 | 'database' => '', 38 | 'DBDriver' => 'MySQLi', 39 | 'DBPrefix' => '', 40 | 'pConnect' => false, 41 | 'DBDebug' => (ENVIRONMENT !== 'production'), 42 | 'cacheOn' => false, 43 | 'cacheDir' => '', 44 | 'charset' => 'utf8', 45 | 'DBCollat' => 'utf8_general_ci', 46 | 'swapPre' => '', 47 | 'encrypt' => false, 48 | 'compress' => false, 49 | 'strictOn' => false, 50 | 'failover' => [], 51 | 'port' => 3306, 52 | ]; 53 | 54 | /** 55 | * This database connection is used when 56 | * running PHPUnit database tests. 57 | * 58 | * @var array 59 | */ 60 | public $tests = [ 61 | 'DSN' => '', 62 | 'hostname' => '127.0.0.1', 63 | 'username' => '', 64 | 'password' => '', 65 | 'database' => ':memory:', 66 | 'DBDriver' => 'SQLite3', 67 | 'DBPrefix' => 'db_', // Needed to ensure we're working correctly with prefixes live. DO NOT REMOVE FOR CI DEVS 68 | 'pConnect' => false, 69 | 'DBDebug' => (ENVIRONMENT !== 'production'), 70 | 'cacheOn' => false, 71 | 'cacheDir' => '', 72 | 'charset' => 'utf8', 73 | 'DBCollat' => 'utf8_general_ci', 74 | 'swapPre' => '', 75 | 'encrypt' => false, 76 | 'compress' => false, 77 | 'strictOn' => false, 78 | 'failover' => [], 79 | 'port' => 3306, 80 | ]; 81 | 82 | //-------------------------------------------------------------------- 83 | 84 | public function __construct() 85 | { 86 | parent::__construct(); 87 | 88 | // Ensure that we always set the database group to 'tests' if 89 | // we are currently running an automated test suite, so that 90 | // we don't overwrite live data on accident. 91 | if (ENVIRONMENT === 'testing') 92 | { 93 | $this->defaultGroup = 'tests'; 94 | 95 | // Under Travis-CI, we can set an ENV var named 'DB_GROUP' 96 | // so that we can test against multiple databases. 97 | if ($group = getenv('DB')) 98 | { 99 | if (is_file(TESTPATH . 'travis/Database.php')) 100 | { 101 | require TESTPATH . 'travis/Database.php'; 102 | 103 | if (! empty($dbconfig) && array_key_exists($group, $dbconfig)) 104 | { 105 | $this->tests = $dbconfig[$group]; 106 | } 107 | } 108 | } 109 | } 110 | } 111 | 112 | //-------------------------------------------------------------------- 113 | 114 | } 115 | -------------------------------------------------------------------------------- /app/Config/DocTypes.php: -------------------------------------------------------------------------------- 1 | '', 14 | 'xhtml1-strict' => '', 15 | 'xhtml1-trans' => '', 16 | 'xhtml1-frame' => '', 17 | 'xhtml-basic11' => '', 18 | 'html5' => '', 19 | 'html4-strict' => '', 20 | 'html4-trans' => '', 21 | 'html4-frame' => '', 22 | 'mathml1' => '', 23 | 'mathml2' => '', 24 | 'svg10' => '', 25 | 'svg11' => '', 26 | 'svg11-basic' => '', 27 | 'svg11-tiny' => '', 28 | 'xhtml-math-svg-xh' => '', 29 | 'xhtml-math-svg-sh' => '', 30 | 'xhtml-rdfa-1' => '', 31 | 'xhtml-rdfa-2' => '', 32 | ]; 33 | } 34 | -------------------------------------------------------------------------------- /app/Config/Email.php: -------------------------------------------------------------------------------- 1 | 0) 26 | { 27 | \ob_end_flush(); 28 | } 29 | 30 | \ob_start(function ($buffer) { 31 | return $buffer; 32 | }); 33 | } 34 | 35 | /* 36 | * -------------------------------------------------------------------- 37 | * Debug Toolbar Listeners. 38 | * -------------------------------------------------------------------- 39 | * If you delete, they will no longer be collected. 40 | */ 41 | if (ENVIRONMENT !== 'production') 42 | { 43 | Events::on('DBQuery', 'CodeIgniter\Debug\Toolbar\Collectors\Database::collect'); 44 | Services::toolbar()->respond(); 45 | } 46 | }); 47 | -------------------------------------------------------------------------------- /app/Config/Exceptions.php: -------------------------------------------------------------------------------- 1 | \CodeIgniter\Filters\CSRF::class, 11 | 'toolbar' => \CodeIgniter\Filters\DebugToolbar::class, 12 | 'honeypot' => \CodeIgniter\Filters\Honeypot::class, 13 | 'auth' => \App\Filters\Auth::class, 14 | 'noauth' => \App\Filters\Noauth::class, 15 | 'userscheck' => \App\Filters\UsersCheck::class, 16 | ]; 17 | 18 | // Always applied before every request 19 | public $globals = [ 20 | 'before' => [ 21 | 'userscheck' 22 | //'honeypot' 23 | // 'csrf', 24 | ], 25 | 'after' => [ 26 | 'toolbar', 27 | //'honeypot' 28 | ], 29 | ]; 30 | 31 | // Works on all of a particular HTTP method 32 | // (GET, POST, etc) as BEFORE filters only 33 | // like: 'post' => ['CSRF', 'throttle'], 34 | public $methods = []; 35 | 36 | // List filter aliases and any before/after uri patterns 37 | // that they should run on, like: 38 | // 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']], 39 | public $filters = []; 40 | } 41 | -------------------------------------------------------------------------------- /app/Config/ForeignCharacters.php: -------------------------------------------------------------------------------- 1 | \CodeIgniter\Format\JSONFormatter::class, 39 | 'application/xml' => \CodeIgniter\Format\XMLFormatter::class, 40 | 'text/xml' => \CodeIgniter\Format\XMLFormatter::class, 41 | ]; 42 | 43 | //-------------------------------------------------------------------- 44 | 45 | /** 46 | * A Factory method to return the appropriate formatter for the given mime type. 47 | * 48 | * @param string $mime 49 | * 50 | * @return \CodeIgniter\Format\FormatterInterface 51 | */ 52 | public function getFormatter(string $mime) 53 | { 54 | if (! array_key_exists($mime, $this->formatters)) 55 | { 56 | throw new \InvalidArgumentException('No Formatter defined for mime type: ' . $mime); 57 | } 58 | 59 | $class = $this->formatters[$mime]; 60 | 61 | if (! class_exists($class)) 62 | { 63 | throw new \BadMethodCallException($class . ' is not a valid Formatter.'); 64 | } 65 | 66 | return new $class(); 67 | } 68 | 69 | //-------------------------------------------------------------------- 70 | 71 | } 72 | -------------------------------------------------------------------------------- /app/Config/Honeypot.php: -------------------------------------------------------------------------------- 1 | {label}'; 34 | } 35 | -------------------------------------------------------------------------------- /app/Config/Images.php: -------------------------------------------------------------------------------- 1 | \CodeIgniter\Images\Handlers\GDHandler::class, 29 | 'imagick' => \CodeIgniter\Images\Handlers\ImageMagickHandler::class, 30 | ]; 31 | } 32 | -------------------------------------------------------------------------------- /app/Config/Kint.php: -------------------------------------------------------------------------------- 1 | [ 88 | 89 | /* 90 | * The log levels that this handler will handle. 91 | */ 92 | 'handles' => [ 93 | 'critical', 94 | 'alert', 95 | 'emergency', 96 | 'debug', 97 | 'error', 98 | 'info', 99 | 'notice', 100 | 'warning', 101 | ], 102 | 103 | /* 104 | * The default filename extension for log files. 105 | * An extension of 'php' allows for protecting the log files via basic 106 | * scripting, when they are to be stored under a publicly accessible directory. 107 | * 108 | * Note: Leaving it blank will default to 'log'. 109 | */ 110 | 'fileExtension' => '', 111 | 112 | /* 113 | * The file system permissions to be applied on newly created log files. 114 | * 115 | * IMPORTANT: This MUST be an integer (no quotes) and you MUST use octal 116 | * integer notation (i.e. 0700, 0644, etc.) 117 | */ 118 | 'filePermissions' => 0644, 119 | ], 120 | 121 | /** 122 | * The ChromeLoggerHandler requires the use of the Chrome web browser 123 | * and the ChromeLogger extension. Uncomment this block to use it. 124 | */ 125 | // 'CodeIgniter\Log\Handlers\ChromeLoggerHandler' => [ 126 | // /* 127 | // * The log levels that this handler will handle. 128 | // */ 129 | // 'handles' => ['critical', 'alert', 'emergency', 'debug', 130 | // 'error', 'info', 'notice', 'warning'], 131 | // ] 132 | ]; 133 | } 134 | -------------------------------------------------------------------------------- /app/Config/Migrations.php: -------------------------------------------------------------------------------- 1 | php spark migrate:create 41 | | 42 | | Typical formats: 43 | | YmdHis_ 44 | | Y-m-d-His_ 45 | | Y_m_d_His_ 46 | | 47 | */ 48 | public $timestampFormat = 'Y-m-d-His_'; 49 | 50 | } 51 | -------------------------------------------------------------------------------- /app/Config/Modules.php: -------------------------------------------------------------------------------- 1 | enabled) 59 | { 60 | return false; 61 | } 62 | 63 | $alias = strtolower($alias); 64 | 65 | return in_array($alias, $this->activeExplorers); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/Config/Pager.php: -------------------------------------------------------------------------------- 1 | 'CodeIgniter\Pager\Views\default_full', 22 | 'default_simple' => 'CodeIgniter\Pager\Views\default_simple', 23 | 'default_head' => 'CodeIgniter\Pager\Views\default_head', 24 | ]; 25 | 26 | /* 27 | |-------------------------------------------------------------------------- 28 | | Items Per Page 29 | |-------------------------------------------------------------------------- 30 | | 31 | | The default number of results shown in a single page. 32 | | 33 | */ 34 | public $perPage = 20; 35 | } 36 | -------------------------------------------------------------------------------- /app/Config/Paths.php: -------------------------------------------------------------------------------- 1 | setDefaultNamespace('App\Controllers'); 19 | $routes->setDefaultController('Users'); 20 | $routes->setDefaultMethod('index'); 21 | $routes->setTranslateURIDashes(false); 22 | $routes->set404Override(); 23 | $routes->setAutoRoute(true); 24 | 25 | /** 26 | * -------------------------------------------------------------------- 27 | * Route Definitions 28 | * -------------------------------------------------------------------- 29 | */ 30 | 31 | // We get a performance increase by specifying the default 32 | // route since we don't have to scan directories. 33 | $routes->get('/', 'Users::index', ['filter' => 'noauth']); 34 | $routes->get('logout', 'Users::logout'); 35 | $routes->match(['get','post'],'register', 'Users::register', ['filter' => 'noauth']); 36 | $routes->match(['get','post'],'profile', 'Users::profile',['filter' => 'auth']); 37 | $routes->get('dashboard', 'Dashboard::index',['filter' => 'auth']); 38 | $routes->get('chat', 'Chat::index',['filter' => 'auth']); 39 | 40 | /** 41 | * -------------------------------------------------------------------- 42 | * Additional Routing 43 | * -------------------------------------------------------------------- 44 | * 45 | * There will often be times that you need additional routing and you 46 | * need to it be able to override any defaults in this file. Environment 47 | * based routes is one such time. require() additional route files here 48 | * to make that happen. 49 | * 50 | * You will have access to the $routes object within that file without 51 | * needing to reload it. 52 | */ 53 | if (file_exists(APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php')) 54 | { 55 | require APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php'; 56 | } 57 | -------------------------------------------------------------------------------- /app/Config/Services.php: -------------------------------------------------------------------------------- 1 | 'Windows 10', 18 | 'windows nt 6.3' => 'Windows 8.1', 19 | 'windows nt 6.2' => 'Windows 8', 20 | 'windows nt 6.1' => 'Windows 7', 21 | 'windows nt 6.0' => 'Windows Vista', 22 | 'windows nt 5.2' => 'Windows 2003', 23 | 'windows nt 5.1' => 'Windows XP', 24 | 'windows nt 5.0' => 'Windows 2000', 25 | 'windows nt 4.0' => 'Windows NT 4.0', 26 | 'winnt4.0' => 'Windows NT 4.0', 27 | 'winnt 4.0' => 'Windows NT', 28 | 'winnt' => 'Windows NT', 29 | 'windows 98' => 'Windows 98', 30 | 'win98' => 'Windows 98', 31 | 'windows 95' => 'Windows 95', 32 | 'win95' => 'Windows 95', 33 | 'windows phone' => 'Windows Phone', 34 | 'windows' => 'Unknown Windows OS', 35 | 'android' => 'Android', 36 | 'blackberry' => 'BlackBerry', 37 | 'iphone' => 'iOS', 38 | 'ipad' => 'iOS', 39 | 'ipod' => 'iOS', 40 | 'os x' => 'Mac OS X', 41 | 'ppc mac' => 'Power PC Mac', 42 | 'freebsd' => 'FreeBSD', 43 | 'ppc' => 'Macintosh', 44 | 'linux' => 'Linux', 45 | 'debian' => 'Debian', 46 | 'sunos' => 'Sun Solaris', 47 | 'beos' => 'BeOS', 48 | 'apachebench' => 'ApacheBench', 49 | 'aix' => 'AIX', 50 | 'irix' => 'Irix', 51 | 'osf' => 'DEC OSF', 52 | 'hp-ux' => 'HP-UX', 53 | 'netbsd' => 'NetBSD', 54 | 'bsdi' => 'BSDi', 55 | 'openbsd' => 'OpenBSD', 56 | 'gnu' => 'GNU/Linux', 57 | 'unix' => 'Unknown Unix OS', 58 | 'symbian' => 'Symbian OS', 59 | ]; 60 | 61 | // The order of this array should NOT be changed. Many browsers return 62 | // multiple browser types so we want to identify the sub-type first. 63 | public $browsers = [ 64 | 'OPR' => 'Opera', 65 | 'Flock' => 'Flock', 66 | 'Edge' => 'Spartan', 67 | 'Chrome' => 'Chrome', 68 | // Opera 10+ always reports Opera/9.80 and appends Version/ to the user agent string 69 | 'Opera.*?Version' => 'Opera', 70 | 'Opera' => 'Opera', 71 | 'MSIE' => 'Internet Explorer', 72 | 'Internet Explorer' => 'Internet Explorer', 73 | 'Trident.* rv' => 'Internet Explorer', 74 | 'Shiira' => 'Shiira', 75 | 'Firefox' => 'Firefox', 76 | 'Chimera' => 'Chimera', 77 | 'Phoenix' => 'Phoenix', 78 | 'Firebird' => 'Firebird', 79 | 'Camino' => 'Camino', 80 | 'Netscape' => 'Netscape', 81 | 'OmniWeb' => 'OmniWeb', 82 | 'Safari' => 'Safari', 83 | 'Mozilla' => 'Mozilla', 84 | 'Konqueror' => 'Konqueror', 85 | 'icab' => 'iCab', 86 | 'Lynx' => 'Lynx', 87 | 'Links' => 'Links', 88 | 'hotjava' => 'HotJava', 89 | 'amaya' => 'Amaya', 90 | 'IBrowse' => 'IBrowse', 91 | 'Maxthon' => 'Maxthon', 92 | 'Ubuntu' => 'Ubuntu Web Browser', 93 | 'Vivaldi' => 'Vivaldi', 94 | ]; 95 | 96 | public $mobiles = [ 97 | // legacy array, old values commented out 98 | 'mobileexplorer' => 'Mobile Explorer', 99 | // 'openwave' => 'Open Wave', 100 | // 'opera mini' => 'Opera Mini', 101 | // 'operamini' => 'Opera Mini', 102 | // 'elaine' => 'Palm', 103 | 'palmsource' => 'Palm', 104 | // 'digital paths' => 'Palm', 105 | // 'avantgo' => 'Avantgo', 106 | // 'xiino' => 'Xiino', 107 | 'palmscape' => 'Palmscape', 108 | // 'nokia' => 'Nokia', 109 | // 'ericsson' => 'Ericsson', 110 | // 'blackberry' => 'BlackBerry', 111 | // 'motorola' => 'Motorola' 112 | 113 | // Phones and Manufacturers 114 | 'motorola' => 'Motorola', 115 | 'nokia' => 'Nokia', 116 | 'palm' => 'Palm', 117 | 'iphone' => 'Apple iPhone', 118 | 'ipad' => 'iPad', 119 | 'ipod' => 'Apple iPod Touch', 120 | 'sony' => 'Sony Ericsson', 121 | 'ericsson' => 'Sony Ericsson', 122 | 'blackberry' => 'BlackBerry', 123 | 'cocoon' => 'O2 Cocoon', 124 | 'blazer' => 'Treo', 125 | 'lg' => 'LG', 126 | 'amoi' => 'Amoi', 127 | 'xda' => 'XDA', 128 | 'mda' => 'MDA', 129 | 'vario' => 'Vario', 130 | 'htc' => 'HTC', 131 | 'samsung' => 'Samsung', 132 | 'sharp' => 'Sharp', 133 | 'sie-' => 'Siemens', 134 | 'alcatel' => 'Alcatel', 135 | 'benq' => 'BenQ', 136 | 'ipaq' => 'HP iPaq', 137 | 'mot-' => 'Motorola', 138 | 'playstation portable' => 'PlayStation Portable', 139 | 'playstation 3' => 'PlayStation 3', 140 | 'playstation vita' => 'PlayStation Vita', 141 | 'hiptop' => 'Danger Hiptop', 142 | 'nec-' => 'NEC', 143 | 'panasonic' => 'Panasonic', 144 | 'philips' => 'Philips', 145 | 'sagem' => 'Sagem', 146 | 'sanyo' => 'Sanyo', 147 | 'spv' => 'SPV', 148 | 'zte' => 'ZTE', 149 | 'sendo' => 'Sendo', 150 | 'nintendo dsi' => 'Nintendo DSi', 151 | 'nintendo ds' => 'Nintendo DS', 152 | 'nintendo 3ds' => 'Nintendo 3DS', 153 | 'wii' => 'Nintendo Wii', 154 | 'open web' => 'Open Web', 155 | 'openweb' => 'OpenWeb', 156 | 157 | // Operating Systems 158 | 'android' => 'Android', 159 | 'symbian' => 'Symbian', 160 | 'SymbianOS' => 'SymbianOS', 161 | 'elaine' => 'Palm', 162 | 'series60' => 'Symbian S60', 163 | 'windows ce' => 'Windows CE', 164 | 165 | // Browsers 166 | 'obigo' => 'Obigo', 167 | 'netfront' => 'Netfront Browser', 168 | 'openwave' => 'Openwave Browser', 169 | 'mobilexplorer' => 'Mobile Explorer', 170 | 'operamini' => 'Opera Mini', 171 | 'opera mini' => 'Opera Mini', 172 | 'opera mobi' => 'Opera Mobile', 173 | 'fennec' => 'Firefox Mobile', 174 | 175 | // Other 176 | 'digital paths' => 'Digital Paths', 177 | 'avantgo' => 'AvantGo', 178 | 'xiino' => 'Xiino', 179 | 'novarra' => 'Novarra Transcoder', 180 | 'vodafone' => 'Vodafone', 181 | 'docomo' => 'NTT DoCoMo', 182 | 'o2' => 'O2', 183 | 184 | // Fallback 185 | 'mobile' => 'Generic Mobile', 186 | 'wireless' => 'Generic Mobile', 187 | 'j2me' => 'Generic Mobile', 188 | 'midp' => 'Generic Mobile', 189 | 'cldc' => 'Generic Mobile', 190 | 'up.link' => 'Generic Mobile', 191 | 'up.browser' => 'Generic Mobile', 192 | 'smartphone' => 'Generic Mobile', 193 | 'cellphone' => 'Generic Mobile', 194 | ]; 195 | 196 | // There are hundreds of bots but these are the most common. 197 | public $robots = [ 198 | 'googlebot' => 'Googlebot', 199 | 'msnbot' => 'MSNBot', 200 | 'baiduspider' => 'Baiduspider', 201 | 'bingbot' => 'Bing', 202 | 'slurp' => 'Inktomi Slurp', 203 | 'yahoo' => 'Yahoo', 204 | 'ask jeeves' => 'Ask Jeeves', 205 | 'fastcrawler' => 'FastCrawler', 206 | 'infoseek' => 'InfoSeek Robot 1.0', 207 | 'lycos' => 'Lycos', 208 | 'yandex' => 'YandexBot', 209 | 'mediapartners-google' => 'MediaPartners Google', 210 | 'CRAZYWEBCRAWLER' => 'Crazy Webcrawler', 211 | 'adsbot-google' => 'AdsBot Google', 212 | 'feedfetcher-google' => 'Feedfetcher Google', 213 | 'curious george' => 'Curious George', 214 | 'ia_archiver' => 'Alexa Crawler', 215 | 'MJ12bot' => 'Majestic-12', 216 | 'Uptimebot' => 'Uptimebot', 217 | ]; 218 | } 219 | -------------------------------------------------------------------------------- /app/Config/Validation.php: -------------------------------------------------------------------------------- 1 | 'CodeIgniter\Validation\Views\list', 31 | 'single' => 'CodeIgniter\Validation\Views\single', 32 | ]; 33 | 34 | //-------------------------------------------------------------------- 35 | // Rules 36 | //-------------------------------------------------------------------- 37 | } 38 | -------------------------------------------------------------------------------- /app/Config/View.php: -------------------------------------------------------------------------------- 1 | session = \Config\Services::session(); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /app/Controllers/Chat.php: -------------------------------------------------------------------------------- 1 | table('connections'); 25 | $builder->where(['c_id >' => 0])->delete(); 26 | 27 | $server->run(); 28 | 29 | } 30 | 31 | //-------------------------------------------------------------------- 32 | 33 | } 34 | -------------------------------------------------------------------------------- /app/Controllers/Users.php: -------------------------------------------------------------------------------- 1 | request->getMethod() == 'post') { 15 | //let's do the validation here 16 | $rules = [ 17 | 'email' => 'required|min_length[6]|max_length[50]|valid_email', 18 | 'password' => 'required|min_length[8]|max_length[255]|validateUser[email,password]', 19 | ]; 20 | 21 | $errors = [ 22 | 'password' => [ 23 | 'validateUser' => 'Email or Password don\'t match' 24 | ] 25 | ]; 26 | 27 | if (! $this->validate($rules, $errors)) { 28 | $data['validation'] = $this->validator; 29 | }else{ 30 | $model = new UserModel(); 31 | 32 | $user = $model->where('email', $this->request->getVar('email')) 33 | ->first(); 34 | 35 | $this->setUserSession($user); 36 | //$session->setFlashdata('success', 'Successful Registration'); 37 | return redirect()->to('dashboard'); 38 | 39 | } 40 | } 41 | 42 | echo view('templates/header', $data); 43 | echo view('login'); 44 | echo view('templates/footer'); 45 | } 46 | 47 | private function setUserSession($user){ 48 | $data = [ 49 | 'id' => $user['id'], 50 | 'firstname' => $user['firstname'], 51 | 'lastname' => $user['lastname'], 52 | 'email' => $user['email'], 53 | 'isLoggedIn' => true, 54 | ]; 55 | 56 | session()->set($data); 57 | return true; 58 | } 59 | 60 | public function register(){ 61 | $data = []; 62 | helper(['form']); 63 | 64 | if ($this->request->getMethod() == 'post') { 65 | //let's do the validation here 66 | $rules = [ 67 | 'firstname' => 'required|min_length[3]|max_length[20]', 68 | 'lastname' => 'required|min_length[3]|max_length[20]', 69 | 'email' => 'required|min_length[6]|max_length[50]|valid_email|is_unique[users.email]', 70 | 'password' => 'required|min_length[8]|max_length[255]', 71 | 'password_confirm' => 'matches[password]', 72 | ]; 73 | 74 | if (! $this->validate($rules)) { 75 | $data['validation'] = $this->validator; 76 | }else{ 77 | $model = new UserModel(); 78 | 79 | $newData = [ 80 | 'firstname' => $this->request->getVar('firstname'), 81 | 'lastname' => $this->request->getVar('lastname'), 82 | 'email' => $this->request->getVar('email'), 83 | 'password' => $this->request->getVar('password'), 84 | ]; 85 | $model->save($newData); 86 | $session = session(); 87 | $session->setFlashdata('success', 'Successful Registration'); 88 | return redirect()->to('/'); 89 | 90 | } 91 | } 92 | 93 | 94 | echo view('templates/header', $data); 95 | echo view('register'); 96 | echo view('templates/footer'); 97 | } 98 | 99 | public function profile(){ 100 | 101 | $data = []; 102 | helper(['form']); 103 | $model = new UserModel(); 104 | 105 | if ($this->request->getMethod() == 'post') { 106 | //let's do the validation here 107 | $rules = [ 108 | 'firstname' => 'required|min_length[3]|max_length[20]', 109 | 'lastname' => 'required|min_length[3]|max_length[20]', 110 | ]; 111 | 112 | if($this->request->getPost('password') != ''){ 113 | $rules['password'] = 'required|min_length[8]|max_length[255]'; 114 | $rules['password_confirm'] = 'matches[password]'; 115 | } 116 | 117 | 118 | if (! $this->validate($rules)) { 119 | $data['validation'] = $this->validator; 120 | }else{ 121 | 122 | $newData = [ 123 | 'id' => session()->get('id'), 124 | 'firstname' => $this->request->getPost('firstname'), 125 | 'lastname' => $this->request->getPost('lastname'), 126 | ]; 127 | if($this->request->getPost('password') != ''){ 128 | $newData['password'] = $this->request->getPost('password'); 129 | } 130 | $model->save($newData); 131 | 132 | session()->setFlashdata('success', 'Successfuly Updated'); 133 | return redirect()->to('/profile'); 134 | 135 | } 136 | } 137 | 138 | $data['user'] = $model->where('id', session()->get('id'))->first(); 139 | echo view('templates/header', $data); 140 | echo view('profile'); 141 | echo view('templates/footer'); 142 | } 143 | 144 | public function logout(){ 145 | session()->destroy(); 146 | return redirect()->to('/'); 147 | } 148 | 149 | //-------------------------------------------------------------------- 150 | 151 | } 152 | -------------------------------------------------------------------------------- /app/Database/Migrations/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexlancer/Codeigniter-4-Chat-Tutorial/e90ddda1f94369adb50009af454b2ab625d88f73/app/Database/Migrations/.gitkeep -------------------------------------------------------------------------------- /app/Database/Migrations/20121031100537_add_users.php: -------------------------------------------------------------------------------- 1 | forge->addField([ 8 | 'id' => [ 9 | 'type' => 'INT', 10 | 'unsigned' => TRUE, 11 | 'auto_increment' => TRUE 12 | ], 13 | 'firstname' => [ 14 | 'type' => 'VARCHAR', 15 | 'constraint' => '50', 16 | ], 17 | 'lastname' => [ 18 | 'type' => 'VARCHAR', 19 | 'constraint' => '50', 20 | ], 21 | 'email' => [ 22 | 'type' => 'VARCHAR', 23 | 'constraint' => '50', 24 | ], 25 | 'password' => [ 26 | 'type' => 'VARCHAR', 27 | 'constraint' => '255', 28 | ], 29 | 'created_at' => [ 30 | 'type' => 'DATETIME', 31 | // 'default' => 'current_timestamp()', 32 | ], 33 | 'updated_at' => [ 34 | 'type' => 'DATETIME', 35 | // 'default' => 'current_timestamp()', 36 | ] 37 | ]); 38 | $this->forge->addKey('id', TRUE); 39 | $this->forge->createTable('users'); 40 | } 41 | 42 | public function down() 43 | { 44 | $this->forge->dropTable('users'); 45 | } 46 | } -------------------------------------------------------------------------------- /app/Database/Migrations/2020-04-24-174346_add_connections.php: -------------------------------------------------------------------------------- 1 | forge->addField([ 10 | 'c_id' => [ 11 | 'type' => 'INT', 12 | 'unsigned' => TRUE, 13 | 'auto_increment' => TRUE 14 | ], 15 | 'c_resource_id' => [ 16 | 'type' => 'INT', 17 | ], 18 | 'c_user_id' => [ 19 | 'type' => 'INT', 20 | ], 21 | 'c_name' => [ 22 | 'type' => 'VARCHAR', 23 | 'constraint' => '50', 24 | ], 25 | 26 | ]); 27 | $this->forge->addKey('c_id', TRUE); 28 | $this->forge->createTable('connections'); 29 | } 30 | 31 | public function down() 32 | { 33 | $this->forge->dropTable('connections'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/Database/Seeds/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexlancer/Codeigniter-4-Chat-Tutorial/e90ddda1f94369adb50009af454b2ab625d88f73/app/Database/Seeds/.gitkeep -------------------------------------------------------------------------------- /app/Filters/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexlancer/Codeigniter-4-Chat-Tutorial/e90ddda1f94369adb50009af454b2ab625d88f73/app/Filters/.gitkeep -------------------------------------------------------------------------------- /app/Filters/Auth.php: -------------------------------------------------------------------------------- 1 | get('isLoggedIn')){ 13 | return redirect()->to('/'); 14 | } 15 | 16 | } 17 | 18 | //-------------------------------------------------------------------- 19 | 20 | public function after(RequestInterface $request, ResponseInterface $response) 21 | { 22 | // Do something here 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/Filters/Noauth.php: -------------------------------------------------------------------------------- 1 | get('isLoggedIn')){ 13 | return redirect()->to('/dashboard'); 14 | } 15 | 16 | } 17 | 18 | //-------------------------------------------------------------------- 19 | 20 | public function after(RequestInterface $request, ResponseInterface $response) 21 | { 22 | // Do something here 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/Filters/UsersCheck.php: -------------------------------------------------------------------------------- 1 | getSegment(1) == 'users'){ 16 | if($uri->getSegment(2) == '') 17 | $segment = '/'; 18 | else 19 | $segment = '/'.$uri->getSegment(2); 20 | 21 | return redirect()->to($segment); 22 | 23 | } 24 | } 25 | 26 | //-------------------------------------------------------------------- 27 | 28 | public function after(RequestInterface $request, ResponseInterface $response) 29 | { 30 | // Do something here 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Helpers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexlancer/Codeigniter-4-Chat-Tutorial/e90ddda1f94369adb50009af454b2ab625d88f73/app/Helpers/.gitkeep -------------------------------------------------------------------------------- /app/Language/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexlancer/Codeigniter-4-Chat-Tutorial/e90ddda1f94369adb50009af454b2ab625d88f73/app/Language/.gitkeep -------------------------------------------------------------------------------- /app/Libraries/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexlancer/Codeigniter-4-Chat-Tutorial/e90ddda1f94369adb50009af454b2ab625d88f73/app/Libraries/.gitkeep -------------------------------------------------------------------------------- /app/Libraries/Chat.php: -------------------------------------------------------------------------------- 1 | clients = new \SplObjectStorage; 14 | } 15 | 16 | public function onOpen(ConnectionInterface $conn) { 17 | // Store the new connection to send messages to later 18 | 19 | // ws://localhost:8080/?access_token=12312313 20 | $uriQuery = $conn->httpRequest->getUri()->getQuery(); //access_token=12312313 21 | $uriQueryArr = explode('=',$uriQuery); //$uriQueryArr[1] 22 | $userModel = new UserModel(); 23 | $conModel = new ConnectionsModel(); 24 | 25 | $user = $userModel->find($uriQueryArr[1]); 26 | $conn->user = $user; 27 | $this->clients->attach($conn); 28 | 29 | $conModel->where('c_user_id', $user['id'])->delete(); 30 | $conData = [ 31 | 'c_user_id' => $user['id'], 32 | 'c_resource_id' => $conn->resourceId, 33 | 'c_name' => $user['firstname'] 34 | ]; 35 | 36 | $conModel->save($conData); 37 | 38 | $users = $conModel->findAll(); 39 | $users = ['users' => $users]; 40 | 41 | foreach ($this->clients as $client) { 42 | $client->send(json_encode($users)); 43 | } 44 | 45 | 46 | echo "New connection! ({$conn->resourceId})\n"; 47 | } 48 | 49 | public function onMessage(ConnectionInterface $from, $msg) { 50 | $numRecv = count($this->clients) - 1; 51 | echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n" 52 | , $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's'); 53 | 54 | foreach ($this->clients as $client) { 55 | if ($from !== $client) { 56 | 57 | $data = [ 58 | 'message' => $msg, 59 | 'author' => $from->user['firstname'], 60 | 'time' => date('H:i') 61 | ]; 62 | // The sender is not the receiver, send to each client connected 63 | $client->send(json_encode($data)); 64 | 65 | } 66 | } 67 | } 68 | 69 | public function onClose(ConnectionInterface $conn) { 70 | // The connection is closed, remove it, as we can no longer send it messages 71 | $this->clients->detach($conn); 72 | 73 | $conModel = new ConnectionsModel(); 74 | $conModel->where('c_resource_id', $conn->resourceId)->delete(); 75 | $users = $conModel->findAll(); 76 | $users = ['users' => $users]; 77 | foreach ($this->clients as $client) { 78 | $client->send(json_encode($users)); 79 | } 80 | 81 | echo "Connection {$conn->resourceId} has disconnected\n"; 82 | } 83 | 84 | public function onError(ConnectionInterface $conn, \Exception $e) { 85 | echo "An error has occurred: {$e->getMessage()}\n"; 86 | 87 | $conn->close(); 88 | } 89 | } -------------------------------------------------------------------------------- /app/Models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexlancer/Codeigniter-4-Chat-Tutorial/e90ddda1f94369adb50009af454b2ab625d88f73/app/Models/.gitkeep -------------------------------------------------------------------------------- /app/Models/ConnectionsModel.php: -------------------------------------------------------------------------------- 1 | passwordHash($data); 16 | $data['data']['created_at'] = date('Y-m-d H:i:s'); 17 | 18 | return $data; 19 | } 20 | 21 | protected function beforeUpdate(array $data){ 22 | $data = $this->passwordHash($data); 23 | $data['data']['updated_at'] = date('Y-m-d H:i:s'); 24 | return $data; 25 | } 26 | 27 | protected function passwordHash(array $data){ 28 | if(isset($data['data']['password'])) 29 | $data['data']['password'] = password_hash($data['data']['password'], PASSWORD_DEFAULT); 30 | 31 | return $data; 32 | } 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /app/ThirdParty/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexlancer/Codeigniter-4-Chat-Tutorial/e90ddda1f94369adb50009af454b2ab625d88f73/app/ThirdParty/.gitkeep -------------------------------------------------------------------------------- /app/Validation/UserRules.php: -------------------------------------------------------------------------------- 1 | where('email', $data['email']) 11 | ->first(); 12 | 13 | if(!$user) 14 | return false; 15 | 16 | return password_verify($data['password'], $user['password']); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Views/chat.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Chat 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Send 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /app/Views/dashboard.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hello, = session()->get('firstname') ?> 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/Views/errors/cli/error_404.php: -------------------------------------------------------------------------------- 1 | 4 | Message: = $message, "\n"; ?> 5 | Filename: = $exception->getFile(), "\n"; ?> 6 | Line Number: = $exception->getLine(); ?> 7 | 8 | 9 | 10 | Backtrace: 11 | getTrace() as $error): ?> 12 | 13 | = trim('-' . $error['line'] . ' - ' . $error['file'] . '::' . $error['function']) . "\n" ?> 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/Views/errors/cli/production.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 404 Page Not Found 6 | 7 | 70 | 71 | 72 | 73 | 404 - File Not Found 74 | 75 | 76 | 77 | = esc($message) ?> 78 | 79 | Sorry! Cannot seem to find the page you were looking for. 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /app/Views/errors/html/production.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Whoops! 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | Whoops! 18 | 19 | We seem to have hit a snag. Please try again later... 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/Views/login.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Login 6 | 7 | get('success')): ?> 8 | 9 | = session()->get('success') ?> 10 | 11 | 12 | 13 | 14 | Email address 15 | 16 | 17 | 18 | Password 19 | 20 | 21 | 22 | 23 | 24 | = $validation->listErrors() ?> 25 | 26 | 27 | 28 | 29 | 30 | Login 31 | 32 | 33 | Don't have an account yet? 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /app/Views/profile.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | = $user['firstname'].' '.$user['lastname'] ?> 6 | 7 | get('success')): ?> 8 | 9 | = session()->get('success') ?> 10 | 11 | 12 | 13 | 14 | 15 | 16 | First Name 17 | 18 | 19 | 20 | 21 | 22 | Last Name 23 | 24 | 25 | 26 | 27 | 28 | Email address 29 | 30 | 31 | 32 | 33 | 34 | Password 35 | 36 | 37 | 38 | 39 | 40 | Confirm Password 41 | 42 | 43 | 44 | 45 | 46 | 47 | = $validation->listErrors() ?> 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | Update 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /app/Views/register.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Register 6 | 7 | 8 | 9 | 10 | 11 | First Name 12 | 13 | 14 | 15 | 16 | 17 | Last Name 18 | 19 | 20 | 21 | 22 | 23 | Email address 24 | 25 | 26 | 27 | 28 | 29 | Password 30 | 31 | 32 | 33 | 34 | 35 | Confirm Password 36 | 37 | 38 | 39 | 40 | 41 | 42 | = $validation->listErrors() ?> 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | Register 51 | 52 | 53 | Already have an account 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /app/Views/templates/footer.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
76 | 77 | = esc($message) ?> 78 | 79 | Sorry! Cannot seem to find the page you were looking for. 80 | 81 |
We seem to have hit a snag. Please try again later...