From 059e0d95d0c28bc5060e87e146eaf7411f51bf90 Mon Sep 17 00:00:00 2001
From: George Halkiadakis
Date: Thu, 27 Apr 2023 03:47:30 +0300
Subject: skeleton commit; based on an anom project
---
Dockerfile | 167 +
README.md | 191 +
composer.json | 12 +
composer.lock | 149 +
core/README.md | 266 +
core/auth/.gitkeep | 0
core/auth/env.example | 36 +
core/classes/Benchmark.php | 150 +
core/classes/Cart.php | 71 +
core/classes/Database.php | 333 +
core/classes/Registry.php | 135 +
core/classes/Render.php | 358 +
core/classes/Repository.php | 43 +
core/classes/Request.php | 161 +
core/classes/Route.php | 97 +
core/classes/Security.php | 923 +
core/classes/authentication/Core/PasswordTrait.php | 38 +
core/classes/authentication/Core/UserManager.php | 101 +
.../authentication/Core/UserManagerInterface.php | 25 +
core/classes/authentication/Token/UserToken.php | 44 +
.../authentication/Token/UserTokenInterface.php | 18 +
core/classes/authentication/User.php | 116 +
core/classes/authentication/UserInterface.php | 19 +
core/classes/authentication/info.md | 114 +
core/classes/cache/Cache_interface.php | 34 +
core/classes/cache/FileCache.php | 93 +
core/classes/cache/MemcachedCache.php | 37 +
core/classes/cache/RedisCache.php | 69 +
core/classes/session/DatabaseSession.php | 138 +
core/classes/session/DefaultSession.php | 42 +
core/classes/session/FilesSession.php | 138 +
core/classes/session/SessionHandlerInterface.php | 169 +
core/cli/cli-cache.php | 65 +
core/cli/curl-cache.php | 155 +
core/cli/info.md | 23 +
core/cli/micro/setup.php | 120 +
core/cli/micro/term_utilities.php | 44 +
core/config/anom_settings.php | 325 +
core/config/constants.php | 28 +
core/config/init.php | 64 +
core/helpers/autoload.php | 43 +
core/helpers/design_patterns.php | 104 +
core/helpers/error_handling.php | 119 +
data/.gitkeep | 0
docker-compose.redis.yml | 166 +
docker-compose.yml | 53 +
docker/bin/docker-entrypoint.sh | 27 +
docker/bin/optimize.sh | 17 +
docker/config/000-default.conf | 21 +
docker/config/composer-naked.json | 12 +
docker/config/composer-redis.json | 13 +
docker/config/default-ssl.conf | 131 +
docker/config/info.md | 69 +
docker/config/msmtprc.kill | 12 +
docker/config/opcache.ini | 9 +
docker/config/php-ext-xdebug.ini | 24 +
docker/config/php-overrides.ini | 3 +
public/.htaccess | 99 +
public/app/config/.gitkeep | 0
public/app/config/app_constants.php | 171 +
public/app/config/init_routes.php | 12 +
public/app/controllers/.gitkeep | 0
public/app/controllers/Admin.php | 58 +
public/app/controllers/Auth.php | 382 +
public/app/controllers/admin/.gitkeep | 0
public/app/controllers/admin/Course_admin.php | 676 +
public/app/controllers/admin/Users_admin.php | 42 +
public/app/controllers/api/.gitkeep | 0
public/app/controllers/api/Common_api.php | 281 +
public/app/controllers/api/Doc_api.php | 34 +
public/app/controllers/cli/CliContoller.php | 55 +
public/app/controllers/cms/Course.php | 252 +
public/app/extends/.gitkeep | 0
public/app/extends/Cache_service.php | 82 +
public/app/extends/Classroom_manager.php | 106 +
public/app/extends/Classroom_user.php | 121 +
public/app/extends/Send_mail.php | 212 +
public/app/models/.gitkeep | 0
public/app/models/Jorge.php | 172 +
public/app/models/_info.md | 150 +
public/app/models/admin/History_model.php | 34 +
public/app/models/admin/Privilege_model.php | 42 +
public/app/models/admin/User_model.php | 299 +
public/app/models/cms/Course_model.php | 314 +
public/app/models/cms/Media_model.php | 36 +
public/app/models/cms/Page_model.php | 18 +
public/app/models/market/Market_repository.php | 235 +
public/app/models/market/Payment_template.txt | 98 +
.../app/models/market/ProductCategories_model.php | 199 +
public/app/models/market/Product_model.php | 49 +
public/app/models/todo.md | 132 +
public/app/routes/.gitkeep | 0
public/app/routes/api.php | 81 +
public/app/routes/backend.php | 221 +
public/app/routes/frontend.php | 169 +
public/app/routes/user.php | 84 +
public/app/views/.gitkeep | 0
public/app/views/admin/admin-menu.php | 47 +
public/app/views/admin/categories.php | 91 +
public/app/views/admin/edit_lesson.php | 159 +
public/app/views/admin/edit_page.php | 139 +
public/app/views/admin/files.php | 96 +
public/app/views/admin/lessons.php | 126 +
public/app/views/admin/pages.php | 109 +
public/app/views/admin/panel.php | 4 +
public/app/views/admin/privileges.php | 93 +
public/app/views/admin/skeleton.php | 45 +
public/app/views/components/breadcrumbs.php | 30 +
public/app/views/components/courses_menu.php | 97 +
public/app/views/components/footer.php | 240 +
public/app/views/components/header_includes.php | 59 +
public/app/views/components/lessons_list.php | 54 +
public/app/views/components/subcategories.php | 19 +
public/app/views/components/top_bar.php | 40 +
public/app/views/components/user-management.php | 65 +
public/app/views/error/404.php | 65 +
public/app/views/error/general.php | 64 +
public/app/views/group.php | 13 +
public/app/views/item.php | 4 +
public/app/views/simple/Model.php | 887 +
public/app/views/simple/Render.php | 182 +
public/app/views/simple/category.php | 156 +
public/app/views/simple/index.php | 123 +
public/app/views/simple/lorem-dates.php | 18 +
public/app/views/simple/lorem-intros.php | 721 +
public/app/views/simple/lorem-posts.php | 93 +
public/app/views/simple/post.php | 236 +
public/app/views/templates/course.php | 93 +
public/app/views/templates/lesson.php | 82 +
public/app/views/templates/page.php | 64 +
public/app/views/user/login.php | 91 +
public/app/views/user/new-password.php | 65 +
public/app/views/user/registration.php | 120 +
public/app/views/welcome.php | 71 +
public/assets/css/admin.css | 150 +
public/assets/css/class.css | 394 +
public/assets/css/email.css | 478 +
public/assets/css/main.css | 9 +
public/assets/css/normalize.css | 349 +
public/assets/css/overides.css | 148 +
.../Buttons-2.3.6/css/buttons.bootstrap.css | 386 +
.../Buttons-2.3.6/css/buttons.bootstrap.min.css | 1 +
.../Buttons-2.3.6/css/buttons.bootstrap4.css | 430 +
.../Buttons-2.3.6/css/buttons.bootstrap4.min.css | 1 +
.../Buttons-2.3.6/css/buttons.bootstrap5.css | 432 +
.../Buttons-2.3.6/css/buttons.bootstrap5.min.css | 1 +
.../DataTables/Buttons-2.3.6/css/buttons.bulma.css | 429 +
.../Buttons-2.3.6/css/buttons.bulma.min.css | 1 +
.../Buttons-2.3.6/css/buttons.dataTables.css | 560 +
.../Buttons-2.3.6/css/buttons.dataTables.min.css | 1 +
.../Buttons-2.3.6/css/buttons.foundation.css | 371 +
.../Buttons-2.3.6/css/buttons.foundation.min.css | 1 +
.../Buttons-2.3.6/css/buttons.jqueryui.css | 387 +
.../Buttons-2.3.6/css/buttons.jqueryui.min.css | 1 +
.../Buttons-2.3.6/css/buttons.semanticui.css | 409 +
.../Buttons-2.3.6/css/buttons.semanticui.min.css | 1 +
.../js/DataTables/Buttons-2.3.6/css/common.scss | 106 +
.../js/DataTables/Buttons-2.3.6/css/mixins.scss | 228 +
.../Buttons-2.3.6/js/buttons.bootstrap.js | 106 +
.../Buttons-2.3.6/js/buttons.bootstrap.min.js | 4 +
.../Buttons-2.3.6/js/buttons.bootstrap4.js | 106 +
.../Buttons-2.3.6/js/buttons.bootstrap4.min.js | 4 +
.../Buttons-2.3.6/js/buttons.bootstrap5.js | 106 +
.../Buttons-2.3.6/js/buttons.bootstrap5.min.js | 4 +
.../DataTables/Buttons-2.3.6/js/buttons.bulma.js | 117 +
.../Buttons-2.3.6/js/buttons.bulma.min.js | 4 +
.../DataTables/Buttons-2.3.6/js/buttons.colVis.js | 250 +
.../Buttons-2.3.6/js/buttons.colVis.min.js | 5 +
.../Buttons-2.3.6/js/buttons.dataTables.js | 92 +
.../Buttons-2.3.6/js/buttons.dataTables.min.js | 4 +
.../Buttons-2.3.6/js/buttons.foundation.js | 134 +
.../Buttons-2.3.6/js/buttons.foundation.min.js | 4 +
.../DataTables/Buttons-2.3.6/js/buttons.html5.js | 1494 +
.../Buttons-2.3.6/js/buttons.html5.min.js | 8 +
.../Buttons-2.3.6/js/buttons.jqueryui.js | 92 +
.../Buttons-2.3.6/js/buttons.jqueryui.min.js | 4 +
.../DataTables/Buttons-2.3.6/js/buttons.print.js | 238 +
.../Buttons-2.3.6/js/buttons.print.min.js | 5 +
.../Buttons-2.3.6/js/buttons.semanticui.js | 104 +
.../Buttons-2.3.6/js/buttons.semanticui.min.js | 4 +
.../Buttons-2.3.6/js/dataTables.buttons.js | 2538 +
.../Buttons-2.3.6/js/dataTables.buttons.min.js | 4 +
.../ColReorder-1.6.2/css/colReorder.bootstrap.css | 11 +
.../css/colReorder.bootstrap.min.css | 1 +
.../ColReorder-1.6.2/css/colReorder.bootstrap4.css | 11 +
.../css/colReorder.bootstrap4.min.css | 1 +
.../ColReorder-1.6.2/css/colReorder.bootstrap5.css | 11 +
.../css/colReorder.bootstrap5.min.css | 1 +
.../ColReorder-1.6.2/css/colReorder.bulma.css | 11 +
.../ColReorder-1.6.2/css/colReorder.bulma.min.css | 1 +
.../ColReorder-1.6.2/css/colReorder.dataTables.css | 11 +
.../css/colReorder.dataTables.min.css | 1 +
.../ColReorder-1.6.2/css/colReorder.foundation.css | 11 +
.../css/colReorder.foundation.min.css | 1 +
.../ColReorder-1.6.2/css/colReorder.jqueryui.css | 11 +
.../css/colReorder.jqueryui.min.css | 1 +
.../ColReorder-1.6.2/css/colReorder.semanticui.css | 11 +
.../css/colReorder.semanticui.min.css | 1 +
.../ColReorder-1.6.2/js/colReorder.bootstrap.js | 58 +
.../js/colReorder.bootstrap.min.js | 4 +
.../ColReorder-1.6.2/js/colReorder.bootstrap4.js | 58 +
.../js/colReorder.bootstrap4.min.js | 4 +
.../ColReorder-1.6.2/js/colReorder.bootstrap5.js | 92 +
.../js/colReorder.bootstrap5.min.js | 4 +
.../ColReorder-1.6.2/js/colReorder.bulma.js | 58 +
.../ColReorder-1.6.2/js/colReorder.bulma.min.js | 4 +
.../ColReorder-1.6.2/js/colReorder.dataTables.js | 58 +
.../js/colReorder.dataTables.min.js | 4 +
.../ColReorder-1.6.2/js/colReorder.foundation.js | 58 +
.../js/colReorder.foundation.min.js | 4 +
.../ColReorder-1.6.2/js/colReorder.jqueryui.js | 58 +
.../ColReorder-1.6.2/js/colReorder.jqueryui.min.js | 4 +
.../ColReorder-1.6.2/js/colReorder.semanticui.js | 58 +
.../js/colReorder.semanticui.min.js | 4 +
.../ColReorder-1.6.2/js/dataTables.colReorder.js | 1518 +
.../js/dataTables.colReorder.min.js | 4 +
.../DataTables-1.13.4/css/dataTables.bootstrap.css | 416 +
.../css/dataTables.bootstrap.min.css | 1 +
.../css/dataTables.bootstrap4.css | 423 +
.../css/dataTables.bootstrap4.min.css | 1 +
.../css/dataTables.bootstrap5.css | 430 +
.../css/dataTables.bootstrap5.min.css | 5 +
.../DataTables-1.13.4/css/dataTables.bulma.css | 379 +
.../DataTables-1.13.4/css/dataTables.bulma.min.css | 3 +
.../css/dataTables.dataTables.css | 0
.../css/dataTables.dataTables.min.css | 0
.../css/dataTables.foundation.css | 357 +
.../css/dataTables.foundation.min.css | 1 +
.../DataTables-1.13.4/css/dataTables.jqueryui.css | 673 +
.../css/dataTables.jqueryui.min.css | 1 +
.../css/dataTables.semanticui.css | 348 +
.../css/dataTables.semanticui.min.css | 1 +
.../DataTables-1.13.4/css/jquery.dataTables.css | 584 +
.../css/jquery.dataTables.min.css | 1 +
.../DataTables-1.13.4/images/sort_asc.png | Bin 0 -> 160 bytes
.../DataTables-1.13.4/images/sort_asc_disabled.png | Bin 0 -> 148 bytes
.../DataTables-1.13.4/images/sort_both.png | Bin 0 -> 201 bytes
.../DataTables-1.13.4/images/sort_desc.png | Bin 0 -> 158 bytes
.../images/sort_desc_disabled.png | Bin 0 -> 146 bytes
.../DataTables-1.13.4/js/dataTables.bootstrap.js | 200 +
.../js/dataTables.bootstrap.min.js | 4 +
.../DataTables-1.13.4/js/dataTables.bootstrap4.js | 202 +
.../js/dataTables.bootstrap4.min.js | 4 +
.../DataTables-1.13.4/js/dataTables.bootstrap5.js | 212 +
.../js/dataTables.bootstrap5.min.js | 4 +
.../DataTables-1.13.4/js/dataTables.bulma.js | 214 +
.../DataTables-1.13.4/js/dataTables.bulma.min.js | 4 +
.../DataTables-1.13.4/js/dataTables.dataTables.js | 55 +
.../js/dataTables.dataTables.min.js | 4 +
.../DataTables-1.13.4/js/dataTables.foundation.js | 200 +
.../js/dataTables.foundation.min.js | 4 +
.../DataTables-1.13.4/js/dataTables.jqueryui.js | 95 +
.../js/dataTables.jqueryui.min.js | 4 +
.../DataTables-1.13.4/js/dataTables.semanticui.js | 228 +
.../js/dataTables.semanticui.min.js | 4 +
.../DataTables-1.13.4/js/jquery.dataTables.js | 15686 +++
.../DataTables-1.13.4/js/jquery.dataTables.min.js | 4 +
.../DateTime-1.4.0/css/dataTables.dateTime.css | 218 +
.../DateTime-1.4.0/css/dataTables.dateTime.min.css | 1 +
.../DateTime-1.4.0/js/dataTables.dateTime.js | 1708 +
.../DateTime-1.4.0/js/dataTables.dateTime.min.js | 6 +
.../css/fixedColumns.bootstrap.css | 42 +
.../css/fixedColumns.bootstrap.min.css | 1 +
.../css/fixedColumns.bootstrap4.css | 42 +
.../css/fixedColumns.bootstrap4.min.css | 1 +
.../css/fixedColumns.bootstrap5.css | 42 +
.../css/fixedColumns.bootstrap5.min.css | 1 +
.../FixedColumns-4.2.2/css/fixedColumns.bulma.css | 35 +
.../css/fixedColumns.bulma.min.css | 1 +
.../css/fixedColumns.dataTables.css | 19 +
.../css/fixedColumns.dataTables.min.css | 1 +
.../css/fixedColumns.foundation.css | 23 +
.../css/fixedColumns.foundation.min.css | 1 +
.../css/fixedColumns.jqueryui.css | 37 +
.../css/fixedColumns.jqueryui.min.css | 1 +
.../css/fixedColumns.semanticui.css | 46 +
.../css/fixedColumns.semanticui.min.css | 1 +
.../js/dataTables.fixedColumns.js | 613 +
.../js/dataTables.fixedColumns.min.js | 4 +
.../js/fixedColumns.bootstrap.js | 58 +
.../js/fixedColumns.bootstrap.min.js | 4 +
.../js/fixedColumns.bootstrap4.js | 58 +
.../js/fixedColumns.bootstrap4.min.js | 4 +
.../js/fixedColumns.bootstrap5.js | 58 +
.../js/fixedColumns.bootstrap5.min.js | 4 +
.../FixedColumns-4.2.2/js/fixedColumns.bulma.js | 58 +
.../js/fixedColumns.bulma.min.js | 4 +
.../js/fixedColumns.dataTables.js | 58 +
.../js/fixedColumns.dataTables.min.js | 4 +
.../js/fixedColumns.foundation.js | 58 +
.../js/fixedColumns.foundation.min.js | 4 +
.../FixedColumns-4.2.2/js/fixedColumns.jqueryui.js | 58 +
.../js/fixedColumns.jqueryui.min.js | 4 +
.../js/fixedColumns.semanticui.js | 58 +
.../js/fixedColumns.semanticui.min.js | 4 +
.../css/fixedHeader.bootstrap.css | 16 +
.../css/fixedHeader.bootstrap.min.css | 1 +
.../css/fixedHeader.bootstrap4.css | 16 +
.../css/fixedHeader.bootstrap4.min.css | 1 +
.../css/fixedHeader.bootstrap5.css | 16 +
.../css/fixedHeader.bootstrap5.min.css | 1 +
.../FixedHeader-3.3.2/css/fixedHeader.bulma.css | 16 +
.../css/fixedHeader.bulma.min.css | 1 +
.../css/fixedHeader.dataTables.css | 18 +
.../css/fixedHeader.dataTables.min.css | 1 +
.../css/fixedHeader.foundation.css | 16 +
.../css/fixedHeader.foundation.min.css | 1 +
.../FixedHeader-3.3.2/css/fixedHeader.jqueryui.css | 14 +
.../css/fixedHeader.jqueryui.min.css | 1 +
.../css/fixedHeader.semanticui.css | 13 +
.../css/fixedHeader.semanticui.min.css | 1 +
.../FixedHeader-3.3.2/js/dataTables.fixedHeader.js | 1103 +
.../js/dataTables.fixedHeader.min.js | 4 +
.../FixedHeader-3.3.2/js/fixedHeader.bootstrap.js | 58 +
.../js/fixedHeader.bootstrap.min.js | 4 +
.../FixedHeader-3.3.2/js/fixedHeader.bootstrap4.js | 58 +
.../js/fixedHeader.bootstrap4.min.js | 4 +
.../FixedHeader-3.3.2/js/fixedHeader.bootstrap5.js | 58 +
.../js/fixedHeader.bootstrap5.min.js | 4 +
.../FixedHeader-3.3.2/js/fixedHeader.bulma.js | 58 +
.../FixedHeader-3.3.2/js/fixedHeader.bulma.min.js | 4 +
.../FixedHeader-3.3.2/js/fixedHeader.dataTables.js | 58 +
.../js/fixedHeader.dataTables.min.js | 4 +
.../FixedHeader-3.3.2/js/fixedHeader.foundation.js | 58 +
.../js/fixedHeader.foundation.min.js | 4 +
.../FixedHeader-3.3.2/js/fixedHeader.jqueryui.js | 58 +
.../js/fixedHeader.jqueryui.min.js | 4 +
.../FixedHeader-3.3.2/js/fixedHeader.semanticui.js | 58 +
.../js/fixedHeader.semanticui.min.js | 4 +
public/assets/js/DataTables/JSZip-2.5.0/jszip.js | 9155 ++
.../assets/js/DataTables/JSZip-2.5.0/jszip.min.js | 14 +
.../KeyTable-2.8.2/css/keyTable.bootstrap.css | 11 +
.../KeyTable-2.8.2/css/keyTable.bootstrap.min.css | 1 +
.../KeyTable-2.8.2/css/keyTable.bootstrap4.css | 11 +
.../KeyTable-2.8.2/css/keyTable.bootstrap4.min.css | 1 +
.../KeyTable-2.8.2/css/keyTable.bootstrap5.css | 11 +
.../KeyTable-2.8.2/css/keyTable.bootstrap5.min.css | 1 +
.../KeyTable-2.8.2/css/keyTable.bulma.css | 11 +
.../KeyTable-2.8.2/css/keyTable.bulma.min.css | 1 +
.../KeyTable-2.8.2/css/keyTable.dataTables.css | 11 +
.../KeyTable-2.8.2/css/keyTable.dataTables.min.css | 1 +
.../KeyTable-2.8.2/css/keyTable.foundation.css | 11 +
.../KeyTable-2.8.2/css/keyTable.foundation.min.css | 1 +
.../KeyTable-2.8.2/css/keyTable.jqueryui.css | 11 +
.../KeyTable-2.8.2/css/keyTable.jqueryui.min.css | 1 +
.../KeyTable-2.8.2/css/keyTable.semanticui.css | 11 +
.../KeyTable-2.8.2/css/keyTable.semanticui.min.css | 1 +
.../KeyTable-2.8.2/js/dataTables.keyTable.js | 1419 +
.../KeyTable-2.8.2/js/dataTables.keyTable.min.js | 4 +
.../KeyTable-2.8.2/js/keyTable.bootstrap.js | 58 +
.../KeyTable-2.8.2/js/keyTable.bootstrap.min.js | 4 +
.../KeyTable-2.8.2/js/keyTable.bootstrap4.js | 58 +
.../KeyTable-2.8.2/js/keyTable.bootstrap4.min.js | 4 +
.../KeyTable-2.8.2/js/keyTable.bootstrap5.js | 58 +
.../KeyTable-2.8.2/js/keyTable.bootstrap5.min.js | 4 +
.../DataTables/KeyTable-2.8.2/js/keyTable.bulma.js | 58 +
.../KeyTable-2.8.2/js/keyTable.bulma.min.js | 4 +
.../KeyTable-2.8.2/js/keyTable.dataTables.js | 58 +
.../KeyTable-2.8.2/js/keyTable.dataTables.min.js | 4 +
.../KeyTable-2.8.2/js/keyTable.foundation.js | 58 +
.../KeyTable-2.8.2/js/keyTable.foundation.min.js | 4 +
.../KeyTable-2.8.2/js/keyTable.jqueryui.js | 58 +
.../KeyTable-2.8.2/js/keyTable.jqueryui.min.js | 4 +
.../KeyTable-2.8.2/js/keyTable.semanticui.js | 58 +
.../KeyTable-2.8.2/js/keyTable.semanticui.min.js | 4 +
.../Responsive-2.4.1/css/responsive.bootstrap.css | 185 +
.../css/responsive.bootstrap.min.css | 1 +
.../Responsive-2.4.1/css/responsive.bootstrap4.css | 185 +
.../css/responsive.bootstrap4.min.css | 1 +
.../Responsive-2.4.1/css/responsive.bootstrap5.css | 190 +
.../css/responsive.bootstrap5.min.css | 1 +
.../Responsive-2.4.1/css/responsive.bulma.css | 191 +
.../Responsive-2.4.1/css/responsive.bulma.min.css | 1 +
.../Responsive-2.4.1/css/responsive.dataTables.css | 182 +
.../css/responsive.dataTables.min.css | 1 +
.../Responsive-2.4.1/css/responsive.foundation.css | 185 +
.../css/responsive.foundation.min.css | 1 +
.../Responsive-2.4.1/css/responsive.jqueryui.css | 182 +
.../css/responsive.jqueryui.min.css | 1 +
.../Responsive-2.4.1/css/responsive.semanticui.css | 185 +
.../css/responsive.semanticui.min.css | 1 +
.../Responsive-2.4.1/js/dataTables.responsive.js | 1533 +
.../js/dataTables.responsive.min.js | 4 +
.../Responsive-2.4.1/js/responsive.bootstrap.js | 102 +
.../js/responsive.bootstrap.min.js | 4 +
.../Responsive-2.4.1/js/responsive.bootstrap4.js | 102 +
.../js/responsive.bootstrap4.min.js | 4 +
.../Responsive-2.4.1/js/responsive.bootstrap5.js | 118 +
.../js/responsive.bootstrap5.min.js | 4 +
.../Responsive-2.4.1/js/responsive.bulma.js | 104 +
.../Responsive-2.4.1/js/responsive.bulma.min.js | 4 +
.../Responsive-2.4.1/js/responsive.dataTables.js | 58 +
.../js/responsive.dataTables.min.js | 4 +
.../Responsive-2.4.1/js/responsive.foundation.js | 88 +
.../js/responsive.foundation.min.js | 4 +
.../Responsive-2.4.1/js/responsive.jqueryui.js | 80 +
.../Responsive-2.4.1/js/responsive.jqueryui.min.js | 4 +
.../Responsive-2.4.1/js/responsive.semanticui.js | 97 +
.../js/responsive.semanticui.min.js | 4 +
.../RowReorder-1.3.3/css/rowReorder.bootstrap.css | 26 +
.../css/rowReorder.bootstrap.min.css | 1 +
.../RowReorder-1.3.3/css/rowReorder.bootstrap4.css | 26 +
.../css/rowReorder.bootstrap4.min.css | 1 +
.../RowReorder-1.3.3/css/rowReorder.bootstrap5.css | 26 +
.../css/rowReorder.bootstrap5.min.css | 1 +
.../RowReorder-1.3.3/css/rowReorder.bulma.css | 26 +
.../RowReorder-1.3.3/css/rowReorder.bulma.min.css | 1 +
.../RowReorder-1.3.3/css/rowReorder.dataTables.css | 26 +
.../css/rowReorder.dataTables.min.css | 1 +
.../RowReorder-1.3.3/css/rowReorder.foundation.css | 26 +
.../css/rowReorder.foundation.min.css | 1 +
.../RowReorder-1.3.3/css/rowReorder.jqueryui.css | 26 +
.../css/rowReorder.jqueryui.min.css | 1 +
.../RowReorder-1.3.3/css/rowReorder.semanticui.css | 26 +
.../css/rowReorder.semanticui.min.css | 1 +
.../RowReorder-1.3.3/js/dataTables.rowReorder.js | 850 +
.../js/dataTables.rowReorder.min.js | 4 +
.../RowReorder-1.3.3/js/rowReorder.bootstrap.js | 59 +
.../js/rowReorder.bootstrap.min.js | 4 +
.../RowReorder-1.3.3/js/rowReorder.bootstrap4.js | 58 +
.../js/rowReorder.bootstrap4.min.js | 4 +
.../RowReorder-1.3.3/js/rowReorder.bootstrap5.js | 58 +
.../js/rowReorder.bootstrap5.min.js | 4 +
.../RowReorder-1.3.3/js/rowReorder.bulma.js | 58 +
.../RowReorder-1.3.3/js/rowReorder.bulma.min.js | 4 +
.../RowReorder-1.3.3/js/rowReorder.dataTables.js | 58 +
.../js/rowReorder.dataTables.min.js | 4 +
.../RowReorder-1.3.3/js/rowReorder.foundation.js | 58 +
.../js/rowReorder.foundation.min.js | 4 +
.../RowReorder-1.3.3/js/rowReorder.jqueryui.js | 58 +
.../RowReorder-1.3.3/js/rowReorder.jqueryui.min.js | 4 +
.../RowReorder-1.3.3/js/rowReorder.semanticui.js | 58 +
.../js/rowReorder.semanticui.min.js | 4 +
.../Scroller-2.1.1/css/scroller.bootstrap.css | 37 +
.../Scroller-2.1.1/css/scroller.bootstrap.min.css | 1 +
.../Scroller-2.1.1/css/scroller.bootstrap4.css | 37 +
.../Scroller-2.1.1/css/scroller.bootstrap4.min.css | 1 +
.../Scroller-2.1.1/css/scroller.bootstrap5.css | 37 +
.../Scroller-2.1.1/css/scroller.bootstrap5.min.css | 1 +
.../Scroller-2.1.1/css/scroller.bulma.css | 33 +
.../Scroller-2.1.1/css/scroller.bulma.min.css | 1 +
.../Scroller-2.1.1/css/scroller.dataTables.css | 33 +
.../Scroller-2.1.1/css/scroller.dataTables.min.css | 1 +
.../Scroller-2.1.1/css/scroller.foundation.css | 17 +
.../Scroller-2.1.1/css/scroller.foundation.min.css | 1 +
.../Scroller-2.1.1/css/scroller.jqueryui.css | 33 +
.../Scroller-2.1.1/css/scroller.jqueryui.min.css | 1 +
.../Scroller-2.1.1/css/scroller.semanticui.css | 33 +
.../Scroller-2.1.1/css/scroller.semanticui.min.css | 1 +
.../Scroller-2.1.1/js/dataTables.scroller.js | 1353 +
.../Scroller-2.1.1/js/dataTables.scroller.min.js | 4 +
.../Scroller-2.1.1/js/scroller.bootstrap.js | 58 +
.../Scroller-2.1.1/js/scroller.bootstrap.min.js | 4 +
.../Scroller-2.1.1/js/scroller.bootstrap4.js | 58 +
.../Scroller-2.1.1/js/scroller.bootstrap4.min.js | 4 +
.../Scroller-2.1.1/js/scroller.bootstrap5.js | 58 +
.../Scroller-2.1.1/js/scroller.bootstrap5.min.js | 4 +
.../DataTables/Scroller-2.1.1/js/scroller.bulma.js | 58 +
.../Scroller-2.1.1/js/scroller.bulma.min.js | 4 +
.../Scroller-2.1.1/js/scroller.dataTables.js | 58 +
.../Scroller-2.1.1/js/scroller.dataTables.min.js | 4 +
.../Scroller-2.1.1/js/scroller.foundation.js | 58 +
.../Scroller-2.1.1/js/scroller.foundation.min.js | 4 +
.../Scroller-2.1.1/js/scroller.jqueryui.js | 58 +
.../Scroller-2.1.1/js/scroller.jqueryui.min.js | 4 +
.../Scroller-2.1.1/js/scroller.semanticui.js | 58 +
.../Scroller-2.1.1/js/scroller.semanticui.min.js | 4 +
.../Select-1.6.2/css/select.bootstrap.css | 61 +
.../Select-1.6.2/css/select.bootstrap.min.css | 1 +
.../Select-1.6.2/css/select.bootstrap4.css | 61 +
.../Select-1.6.2/css/select.bootstrap4.min.css | 1 +
.../Select-1.6.2/css/select.bootstrap5.css | 64 +
.../Select-1.6.2/css/select.bootstrap5.min.css | 1 +
.../DataTables/Select-1.6.2/css/select.bulma.css | 61 +
.../Select-1.6.2/css/select.bulma.min.css | 1 +
.../Select-1.6.2/css/select.dataTables.css | 61 +
.../Select-1.6.2/css/select.dataTables.min.css | 1 +
.../Select-1.6.2/css/select.foundation.css | 61 +
.../Select-1.6.2/css/select.foundation.min.css | 1 +
.../Select-1.6.2/css/select.jqueryui.css | 61 +
.../Select-1.6.2/css/select.jqueryui.min.css | 1 +
.../Select-1.6.2/css/select.semanticui.css | 61 +
.../Select-1.6.2/css/select.semanticui.min.css | 1 +
.../Select-1.6.2/js/dataTables.select.js | 1366 +
.../Select-1.6.2/js/dataTables.select.min.js | 4 +
.../DataTables/Select-1.6.2/js/select.bootstrap.js | 58 +
.../Select-1.6.2/js/select.bootstrap.min.js | 4 +
.../Select-1.6.2/js/select.bootstrap4.js | 58 +
.../Select-1.6.2/js/select.bootstrap4.min.js | 4 +
.../Select-1.6.2/js/select.bootstrap5.js | 58 +
.../Select-1.6.2/js/select.bootstrap5.min.js | 4 +
.../js/DataTables/Select-1.6.2/js/select.bulma.js | 58 +
.../DataTables/Select-1.6.2/js/select.bulma.min.js | 4 +
.../Select-1.6.2/js/select.dataTables.js | 58 +
.../Select-1.6.2/js/select.dataTables.min.js | 4 +
.../Select-1.6.2/js/select.foundation.js | 58 +
.../Select-1.6.2/js/select.foundation.min.js | 4 +
.../DataTables/Select-1.6.2/js/select.jqueryui.js | 58 +
.../Select-1.6.2/js/select.jqueryui.min.js | 4 +
.../Select-1.6.2/js/select.semanticui.js | 58 +
.../Select-1.6.2/js/select.semanticui.min.js | 4 +
.../css/stateRestore.bootstrap.css | 200 +
.../css/stateRestore.bootstrap.min.css | 1 +
.../css/stateRestore.bootstrap4.css | 231 +
.../css/stateRestore.bootstrap4.min.css | 1 +
.../css/stateRestore.bootstrap5.css | 231 +
.../css/stateRestore.bootstrap5.min.css | 1 +
.../StateRestore-1.2.2/css/stateRestore.bulma.css | 226 +
.../css/stateRestore.bulma.min.css | 1 +
.../css/stateRestore.dataTables.css | 174 +
.../css/stateRestore.dataTables.min.css | 1 +
.../css/stateRestore.foundation.css | 214 +
.../css/stateRestore.foundation.min.css | 1 +
.../css/stateRestore.jqueryui.css | 216 +
.../css/stateRestore.jqueryui.min.css | 1 +
.../css/stateRestore.semanticui.css | 264 +
.../css/stateRestore.semanticui.min.css | 1 +
.../js/dataTables.stateRestore.js | 2365 +
.../js/dataTables.stateRestore.min.js | 4 +
.../js/stateRestore.bootstrap.js | 71 +
.../js/stateRestore.bootstrap.min.js | 4 +
.../js/stateRestore.bootstrap4.js | 70 +
.../js/stateRestore.bootstrap4.min.js | 4 +
.../js/stateRestore.bootstrap5.js | 73 +
.../js/stateRestore.bootstrap5.min.js | 4 +
.../StateRestore-1.2.2/js/stateRestore.bulma.js | 71 +
.../js/stateRestore.bulma.min.js | 4 +
.../js/stateRestore.dataTables.js | 58 +
.../js/stateRestore.dataTables.min.js | 4 +
.../js/stateRestore.foundation.js | 73 +
.../js/stateRestore.foundation.min.js | 4 +
.../StateRestore-1.2.2/js/stateRestore.jqueryui.js | 74 +
.../js/stateRestore.jqueryui.min.js | 4 +
.../js/stateRestore.semanticui.js | 76 +
.../js/stateRestore.semanticui.min.js | 4 +
public/assets/js/DataTables/datatables.css | 1743 +
public/assets/js/DataTables/datatables.js | 94225 +++++++++++++++++++
public/assets/js/DataTables/datatables.min.css | 52 +
public/assets/js/DataTables/datatables.min.js | 257 +
.../assets/js/DataTables/pdfmake-0.1.36/pdfmake.js | 50468 ++++++++++
.../js/DataTables/pdfmake-0.1.36/pdfmake.min.js | 3 +
.../js/DataTables/pdfmake-0.1.36/vfs_fonts.js | 6 +
public/assets/js/admin/categories.js | 288 +
public/assets/js/admin/edit_lesson.js | 600 +
public/assets/js/admin/edit_page.js | 382 +
public/assets/js/admin/files.js | 302 +
public/assets/js/admin/lessons.js | 364 +
public/assets/js/admin/pages.js | 240 +
public/assets/js/admin/panel.js | 1 +
public/assets/js/admin/privileges.js | 291 +
public/assets/js/chart.js/Plugin.Subtitle.js | 221 +
public/assets/js/chart.js/chart.min.js | 10 +
.../js/chart.js/chartjs-plugin-annotation.js | 928 +
.../js/chart.js/chartjs-plugin-datalabels.min.js | 7 +
public/assets/js/classroom.js | 27 +
public/assets/js/cookie.js | 78 +
public/assets/js/edit-post.js | 612 +
public/assets/js/lesson-features.js | 218 +
public/assets/js/manage-category.js | 287 +
public/assets/js/manage-posts.js | 177 +
public/assets/js/manage-tags.js | 163 +
public/assets/js/marked/marked.cjs | 2723 +
public/assets/js/marked/marked.esm.js | 2824 +
public/assets/js/marked/marked.min.js | 6 +
public/assets/js/marked/marked.umd.js | 2729 +
public/assets/js/pdfmake/fonts/Roboto.js | 27 +
.../js/pdfmake/fonts/Roboto/Roboto-Italic.ttf | Bin 0 -> 152384 bytes
.../js/pdfmake/fonts/Roboto/Roboto-Medium.ttf | Bin 0 -> 146884 bytes
.../pdfmake/fonts/Roboto/Roboto-MediumItalic.ttf | Bin 0 -> 152572 bytes
.../js/pdfmake/fonts/Roboto/Roboto-Regular.ttf | Bin 0 -> 146768 bytes
public/assets/js/pdfmake/pdfmake.js | 74980 +++++++++++++++
public/assets/js/pdfmake/pdfmake.js.map | 1 +
public/assets/js/pdfmake/pdfmake.min.js | 3 +
public/assets/js/pdfmake/pdfmake.min.js.map | 1 +
public/assets/js/pdfmake/standard-fonts/Courier.js | 27 +
.../assets/js/pdfmake/standard-fonts/Helvetica.js | 27 +
public/assets/js/pdfmake/standard-fonts/Symbol.js | 21 +
public/assets/js/pdfmake/standard-fonts/Times.js | 27 +
.../js/pdfmake/standard-fonts/ZapfDingbats.js | 21 +
public/assets/js/pdfmake/vfs_fonts.js | 7 +
public/assets/js/select2/css/select2_4.0.6.min.css | 1 +
public/assets/js/select2/i18n/el.js | 3 +
public/assets/js/select2/js/select2_4.0.6.min.js | 1 +
public/favicon.ico | Bin 0 -> 15086 bytes
public/files/.gitkeep | 0
public/index.php | 63 +
sceleton.txt | 79 +
tests/abstract.php | 46 +
tests/algo-hashes.php | 52 +
tests/auth.php | 58 +
tests/code/abstract.php | 46 +
tests/code/bits.php | 51 +
tests/code/echo.php | 43 +
tests/code/exceptions.php | 73 +
tests/code/interface.php | 31 +
tests/code/login.php | 25 +
tests/code/menu.php | 42 +
tests/code/proxy.php | 38 +
tests/code/session.php | 50 +
tests/code/str-replace.php | 5 +
tests/compare/compress.php | 80 +
tests/compare/hashcost.php | 54 +
tests/compare/md5-v-sha1.php | 18 +
tests/compare/memcached-v-filecache.php | 35 +
tests/compare/redis-v-filecache.php | 35 +
tests/compare/serialize-v-jsonencode.php | 35 +
tests/compare/sha1-v-sha256.php | 22 +
tests/dotnet-pass.php | 503 +
tests/mail.php | 2 +
tests/php.php | 2 +
tests/repository.php | 65 +
tests/service/entropy.php | 61 +
tests/service/lorem-md.php | 71 +
tests/service/mailjet.php | 56 +
tests/service/memcached.php | 12 +
tests/service/redis.php | 27 +
tests/userman.php | 27 +
617 files changed, 317157 insertions(+)
create mode 100644 Dockerfile
create mode 100644 README.md
create mode 100644 composer.json
create mode 100644 composer.lock
create mode 100644 core/README.md
create mode 100644 core/auth/.gitkeep
create mode 100644 core/auth/env.example
create mode 100644 core/classes/Benchmark.php
create mode 100644 core/classes/Cart.php
create mode 100644 core/classes/Database.php
create mode 100644 core/classes/Registry.php
create mode 100644 core/classes/Render.php
create mode 100644 core/classes/Repository.php
create mode 100644 core/classes/Request.php
create mode 100644 core/classes/Route.php
create mode 100644 core/classes/Security.php
create mode 100644 core/classes/authentication/Core/PasswordTrait.php
create mode 100644 core/classes/authentication/Core/UserManager.php
create mode 100644 core/classes/authentication/Core/UserManagerInterface.php
create mode 100644 core/classes/authentication/Token/UserToken.php
create mode 100644 core/classes/authentication/Token/UserTokenInterface.php
create mode 100644 core/classes/authentication/User.php
create mode 100644 core/classes/authentication/UserInterface.php
create mode 100644 core/classes/authentication/info.md
create mode 100644 core/classes/cache/Cache_interface.php
create mode 100644 core/classes/cache/FileCache.php
create mode 100644 core/classes/cache/MemcachedCache.php
create mode 100644 core/classes/cache/RedisCache.php
create mode 100644 core/classes/session/DatabaseSession.php
create mode 100644 core/classes/session/DefaultSession.php
create mode 100644 core/classes/session/FilesSession.php
create mode 100644 core/classes/session/SessionHandlerInterface.php
create mode 100644 core/cli/cli-cache.php
create mode 100755 core/cli/curl-cache.php
create mode 100644 core/cli/info.md
create mode 100644 core/cli/micro/setup.php
create mode 100644 core/cli/micro/term_utilities.php
create mode 100644 core/config/anom_settings.php
create mode 100644 core/config/constants.php
create mode 100644 core/config/init.php
create mode 100644 core/helpers/autoload.php
create mode 100644 core/helpers/design_patterns.php
create mode 100644 core/helpers/error_handling.php
create mode 100644 data/.gitkeep
create mode 100644 docker-compose.redis.yml
create mode 100644 docker-compose.yml
create mode 100644 docker/bin/docker-entrypoint.sh
create mode 100644 docker/bin/optimize.sh
create mode 100644 docker/config/000-default.conf
create mode 100644 docker/config/composer-naked.json
create mode 100644 docker/config/composer-redis.json
create mode 100644 docker/config/default-ssl.conf
create mode 100644 docker/config/info.md
create mode 100644 docker/config/msmtprc.kill
create mode 100644 docker/config/opcache.ini
create mode 100644 docker/config/php-ext-xdebug.ini
create mode 100644 docker/config/php-overrides.ini
create mode 100644 public/.htaccess
create mode 100644 public/app/config/.gitkeep
create mode 100644 public/app/config/app_constants.php
create mode 100644 public/app/config/init_routes.php
create mode 100644 public/app/controllers/.gitkeep
create mode 100644 public/app/controllers/Admin.php
create mode 100644 public/app/controllers/Auth.php
create mode 100644 public/app/controllers/admin/.gitkeep
create mode 100644 public/app/controllers/admin/Course_admin.php
create mode 100644 public/app/controllers/admin/Users_admin.php
create mode 100644 public/app/controllers/api/.gitkeep
create mode 100644 public/app/controllers/api/Common_api.php
create mode 100644 public/app/controllers/api/Doc_api.php
create mode 100644 public/app/controllers/cli/CliContoller.php
create mode 100644 public/app/controllers/cms/Course.php
create mode 100644 public/app/extends/.gitkeep
create mode 100644 public/app/extends/Cache_service.php
create mode 100644 public/app/extends/Classroom_manager.php
create mode 100644 public/app/extends/Classroom_user.php
create mode 100644 public/app/extends/Send_mail.php
create mode 100644 public/app/models/.gitkeep
create mode 100644 public/app/models/Jorge.php
create mode 100644 public/app/models/_info.md
create mode 100644 public/app/models/admin/History_model.php
create mode 100644 public/app/models/admin/Privilege_model.php
create mode 100644 public/app/models/admin/User_model.php
create mode 100644 public/app/models/cms/Course_model.php
create mode 100644 public/app/models/cms/Media_model.php
create mode 100644 public/app/models/cms/Page_model.php
create mode 100644 public/app/models/market/Market_repository.php
create mode 100644 public/app/models/market/Payment_template.txt
create mode 100644 public/app/models/market/ProductCategories_model.php
create mode 100644 public/app/models/market/Product_model.php
create mode 100644 public/app/models/todo.md
create mode 100644 public/app/routes/.gitkeep
create mode 100644 public/app/routes/api.php
create mode 100644 public/app/routes/backend.php
create mode 100644 public/app/routes/frontend.php
create mode 100644 public/app/routes/user.php
create mode 100644 public/app/views/.gitkeep
create mode 100644 public/app/views/admin/admin-menu.php
create mode 100644 public/app/views/admin/categories.php
create mode 100644 public/app/views/admin/edit_lesson.php
create mode 100644 public/app/views/admin/edit_page.php
create mode 100644 public/app/views/admin/files.php
create mode 100644 public/app/views/admin/lessons.php
create mode 100644 public/app/views/admin/pages.php
create mode 100644 public/app/views/admin/panel.php
create mode 100644 public/app/views/admin/privileges.php
create mode 100644 public/app/views/admin/skeleton.php
create mode 100644 public/app/views/components/breadcrumbs.php
create mode 100644 public/app/views/components/courses_menu.php
create mode 100644 public/app/views/components/footer.php
create mode 100644 public/app/views/components/header_includes.php
create mode 100644 public/app/views/components/lessons_list.php
create mode 100644 public/app/views/components/subcategories.php
create mode 100644 public/app/views/components/top_bar.php
create mode 100644 public/app/views/components/user-management.php
create mode 100644 public/app/views/error/404.php
create mode 100644 public/app/views/error/general.php
create mode 100644 public/app/views/group.php
create mode 100644 public/app/views/item.php
create mode 100644 public/app/views/simple/Model.php
create mode 100644 public/app/views/simple/Render.php
create mode 100644 public/app/views/simple/category.php
create mode 100644 public/app/views/simple/index.php
create mode 100644 public/app/views/simple/lorem-dates.php
create mode 100644 public/app/views/simple/lorem-intros.php
create mode 100644 public/app/views/simple/lorem-posts.php
create mode 100644 public/app/views/simple/post.php
create mode 100644 public/app/views/templates/course.php
create mode 100644 public/app/views/templates/lesson.php
create mode 100644 public/app/views/templates/page.php
create mode 100644 public/app/views/user/login.php
create mode 100644 public/app/views/user/new-password.php
create mode 100644 public/app/views/user/registration.php
create mode 100644 public/app/views/welcome.php
create mode 100644 public/assets/css/admin.css
create mode 100644 public/assets/css/class.css
create mode 100644 public/assets/css/email.css
create mode 100644 public/assets/css/main.css
create mode 100644 public/assets/css/normalize.css
create mode 100644 public/assets/css/overides.css
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/css/buttons.bootstrap.css
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/css/buttons.bootstrap.min.css
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/css/buttons.bootstrap4.css
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/css/buttons.bootstrap4.min.css
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/css/buttons.bootstrap5.css
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/css/buttons.bootstrap5.min.css
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/css/buttons.bulma.css
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/css/buttons.bulma.min.css
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/css/buttons.dataTables.css
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/css/buttons.dataTables.min.css
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/css/buttons.foundation.css
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/css/buttons.foundation.min.css
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/css/buttons.jqueryui.css
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/css/buttons.jqueryui.min.css
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/css/buttons.semanticui.css
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/css/buttons.semanticui.min.css
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/css/common.scss
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/css/mixins.scss
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.bootstrap.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.bootstrap.min.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.bootstrap4.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.bootstrap4.min.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.bootstrap5.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.bootstrap5.min.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.bulma.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.bulma.min.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.colVis.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.colVis.min.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.dataTables.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.dataTables.min.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.foundation.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.foundation.min.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.html5.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.html5.min.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.jqueryui.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.jqueryui.min.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.print.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.print.min.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.semanticui.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/buttons.semanticui.min.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/dataTables.buttons.js
create mode 100644 public/assets/js/DataTables/Buttons-2.3.6/js/dataTables.buttons.min.js
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/css/colReorder.bootstrap.css
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/css/colReorder.bootstrap.min.css
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/css/colReorder.bootstrap4.css
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/css/colReorder.bootstrap4.min.css
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/css/colReorder.bootstrap5.css
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/css/colReorder.bootstrap5.min.css
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/css/colReorder.bulma.css
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/css/colReorder.bulma.min.css
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/css/colReorder.dataTables.css
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/css/colReorder.dataTables.min.css
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/css/colReorder.foundation.css
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/css/colReorder.foundation.min.css
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/css/colReorder.jqueryui.css
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/css/colReorder.jqueryui.min.css
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/css/colReorder.semanticui.css
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/css/colReorder.semanticui.min.css
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/js/colReorder.bootstrap.js
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/js/colReorder.bootstrap.min.js
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/js/colReorder.bootstrap4.js
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/js/colReorder.bootstrap4.min.js
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/js/colReorder.bootstrap5.js
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/js/colReorder.bootstrap5.min.js
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/js/colReorder.bulma.js
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/js/colReorder.bulma.min.js
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/js/colReorder.dataTables.js
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/js/colReorder.dataTables.min.js
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/js/colReorder.foundation.js
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/js/colReorder.foundation.min.js
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/js/colReorder.jqueryui.js
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/js/colReorder.jqueryui.min.js
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/js/colReorder.semanticui.js
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/js/colReorder.semanticui.min.js
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/js/dataTables.colReorder.js
create mode 100644 public/assets/js/DataTables/ColReorder-1.6.2/js/dataTables.colReorder.min.js
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/css/dataTables.bootstrap.css
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/css/dataTables.bootstrap.min.css
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/css/dataTables.bootstrap4.css
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/css/dataTables.bootstrap4.min.css
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/css/dataTables.bootstrap5.css
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/css/dataTables.bootstrap5.min.css
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/css/dataTables.bulma.css
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/css/dataTables.bulma.min.css
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/css/dataTables.dataTables.css
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/css/dataTables.dataTables.min.css
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/css/dataTables.foundation.css
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/css/dataTables.foundation.min.css
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/css/dataTables.jqueryui.css
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/css/dataTables.jqueryui.min.css
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/css/dataTables.semanticui.css
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/css/dataTables.semanticui.min.css
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/css/jquery.dataTables.css
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/css/jquery.dataTables.min.css
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/images/sort_asc.png
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/images/sort_asc_disabled.png
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/images/sort_both.png
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/images/sort_desc.png
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/images/sort_desc_disabled.png
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/js/dataTables.bootstrap.js
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/js/dataTables.bootstrap.min.js
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/js/dataTables.bootstrap4.js
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/js/dataTables.bootstrap4.min.js
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/js/dataTables.bootstrap5.js
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/js/dataTables.bootstrap5.min.js
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/js/dataTables.bulma.js
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/js/dataTables.bulma.min.js
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/js/dataTables.dataTables.js
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/js/dataTables.dataTables.min.js
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/js/dataTables.foundation.js
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/js/dataTables.foundation.min.js
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/js/dataTables.jqueryui.js
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/js/dataTables.jqueryui.min.js
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/js/dataTables.semanticui.js
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/js/dataTables.semanticui.min.js
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/js/jquery.dataTables.js
create mode 100644 public/assets/js/DataTables/DataTables-1.13.4/js/jquery.dataTables.min.js
create mode 100644 public/assets/js/DataTables/DateTime-1.4.0/css/dataTables.dateTime.css
create mode 100644 public/assets/js/DataTables/DateTime-1.4.0/css/dataTables.dateTime.min.css
create mode 100644 public/assets/js/DataTables/DateTime-1.4.0/js/dataTables.dateTime.js
create mode 100644 public/assets/js/DataTables/DateTime-1.4.0/js/dataTables.dateTime.min.js
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/css/fixedColumns.bootstrap.css
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/css/fixedColumns.bootstrap.min.css
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/css/fixedColumns.bootstrap4.css
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/css/fixedColumns.bootstrap4.min.css
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/css/fixedColumns.bootstrap5.css
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/css/fixedColumns.bootstrap5.min.css
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/css/fixedColumns.bulma.css
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/css/fixedColumns.bulma.min.css
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/css/fixedColumns.dataTables.css
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/css/fixedColumns.dataTables.min.css
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/css/fixedColumns.foundation.css
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/css/fixedColumns.foundation.min.css
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/css/fixedColumns.jqueryui.css
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/css/fixedColumns.jqueryui.min.css
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/css/fixedColumns.semanticui.css
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/css/fixedColumns.semanticui.min.css
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/js/dataTables.fixedColumns.js
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/js/dataTables.fixedColumns.min.js
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/js/fixedColumns.bootstrap.js
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/js/fixedColumns.bootstrap.min.js
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/js/fixedColumns.bootstrap4.js
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/js/fixedColumns.bootstrap4.min.js
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/js/fixedColumns.bootstrap5.js
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/js/fixedColumns.bootstrap5.min.js
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/js/fixedColumns.bulma.js
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/js/fixedColumns.bulma.min.js
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/js/fixedColumns.dataTables.js
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/js/fixedColumns.dataTables.min.js
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/js/fixedColumns.foundation.js
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/js/fixedColumns.foundation.min.js
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/js/fixedColumns.jqueryui.js
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/js/fixedColumns.jqueryui.min.js
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/js/fixedColumns.semanticui.js
create mode 100644 public/assets/js/DataTables/FixedColumns-4.2.2/js/fixedColumns.semanticui.min.js
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/css/fixedHeader.bootstrap.css
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/css/fixedHeader.bootstrap.min.css
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/css/fixedHeader.bootstrap4.css
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/css/fixedHeader.bootstrap4.min.css
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/css/fixedHeader.bootstrap5.css
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/css/fixedHeader.bootstrap5.min.css
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/css/fixedHeader.bulma.css
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/css/fixedHeader.bulma.min.css
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/css/fixedHeader.dataTables.css
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/css/fixedHeader.dataTables.min.css
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/css/fixedHeader.foundation.css
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/css/fixedHeader.foundation.min.css
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/css/fixedHeader.jqueryui.css
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/css/fixedHeader.jqueryui.min.css
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/css/fixedHeader.semanticui.css
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/css/fixedHeader.semanticui.min.css
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/js/dataTables.fixedHeader.js
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/js/dataTables.fixedHeader.min.js
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/js/fixedHeader.bootstrap.js
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/js/fixedHeader.bootstrap.min.js
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/js/fixedHeader.bootstrap4.js
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/js/fixedHeader.bootstrap4.min.js
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/js/fixedHeader.bootstrap5.js
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/js/fixedHeader.bootstrap5.min.js
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/js/fixedHeader.bulma.js
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/js/fixedHeader.bulma.min.js
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/js/fixedHeader.dataTables.js
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/js/fixedHeader.dataTables.min.js
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/js/fixedHeader.foundation.js
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/js/fixedHeader.foundation.min.js
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/js/fixedHeader.jqueryui.js
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/js/fixedHeader.jqueryui.min.js
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/js/fixedHeader.semanticui.js
create mode 100644 public/assets/js/DataTables/FixedHeader-3.3.2/js/fixedHeader.semanticui.min.js
create mode 100644 public/assets/js/DataTables/JSZip-2.5.0/jszip.js
create mode 100644 public/assets/js/DataTables/JSZip-2.5.0/jszip.min.js
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/css/keyTable.bootstrap.css
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/css/keyTable.bootstrap.min.css
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/css/keyTable.bootstrap4.css
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/css/keyTable.bootstrap4.min.css
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/css/keyTable.bootstrap5.css
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/css/keyTable.bootstrap5.min.css
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/css/keyTable.bulma.css
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/css/keyTable.bulma.min.css
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/css/keyTable.dataTables.css
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/css/keyTable.dataTables.min.css
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/css/keyTable.foundation.css
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/css/keyTable.foundation.min.css
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/css/keyTable.jqueryui.css
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/css/keyTable.jqueryui.min.css
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/css/keyTable.semanticui.css
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/css/keyTable.semanticui.min.css
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/js/dataTables.keyTable.js
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/js/dataTables.keyTable.min.js
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/js/keyTable.bootstrap.js
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/js/keyTable.bootstrap.min.js
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/js/keyTable.bootstrap4.js
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/js/keyTable.bootstrap4.min.js
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/js/keyTable.bootstrap5.js
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/js/keyTable.bootstrap5.min.js
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/js/keyTable.bulma.js
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/js/keyTable.bulma.min.js
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/js/keyTable.dataTables.js
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/js/keyTable.dataTables.min.js
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/js/keyTable.foundation.js
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/js/keyTable.foundation.min.js
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/js/keyTable.jqueryui.js
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/js/keyTable.jqueryui.min.js
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/js/keyTable.semanticui.js
create mode 100644 public/assets/js/DataTables/KeyTable-2.8.2/js/keyTable.semanticui.min.js
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/css/responsive.bootstrap.css
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/css/responsive.bootstrap.min.css
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/css/responsive.bootstrap4.css
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/css/responsive.bootstrap4.min.css
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/css/responsive.bootstrap5.css
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/css/responsive.bootstrap5.min.css
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/css/responsive.bulma.css
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/css/responsive.bulma.min.css
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/css/responsive.dataTables.css
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/css/responsive.dataTables.min.css
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/css/responsive.foundation.css
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/css/responsive.foundation.min.css
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/css/responsive.jqueryui.css
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/css/responsive.jqueryui.min.css
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/css/responsive.semanticui.css
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/css/responsive.semanticui.min.css
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/js/dataTables.responsive.js
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/js/dataTables.responsive.min.js
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/js/responsive.bootstrap.js
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/js/responsive.bootstrap.min.js
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/js/responsive.bootstrap4.js
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/js/responsive.bootstrap4.min.js
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/js/responsive.bootstrap5.js
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/js/responsive.bootstrap5.min.js
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/js/responsive.bulma.js
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/js/responsive.bulma.min.js
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/js/responsive.dataTables.js
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/js/responsive.dataTables.min.js
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/js/responsive.foundation.js
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/js/responsive.foundation.min.js
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/js/responsive.jqueryui.js
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/js/responsive.jqueryui.min.js
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/js/responsive.semanticui.js
create mode 100644 public/assets/js/DataTables/Responsive-2.4.1/js/responsive.semanticui.min.js
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/css/rowReorder.bootstrap.css
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/css/rowReorder.bootstrap.min.css
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/css/rowReorder.bootstrap4.css
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/css/rowReorder.bootstrap4.min.css
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/css/rowReorder.bootstrap5.css
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/css/rowReorder.bootstrap5.min.css
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/css/rowReorder.bulma.css
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/css/rowReorder.bulma.min.css
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/css/rowReorder.dataTables.css
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/css/rowReorder.dataTables.min.css
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/css/rowReorder.foundation.css
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/css/rowReorder.foundation.min.css
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/css/rowReorder.jqueryui.css
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/css/rowReorder.jqueryui.min.css
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/css/rowReorder.semanticui.css
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/css/rowReorder.semanticui.min.css
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/js/dataTables.rowReorder.js
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/js/dataTables.rowReorder.min.js
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/js/rowReorder.bootstrap.js
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/js/rowReorder.bootstrap.min.js
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/js/rowReorder.bootstrap4.js
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/js/rowReorder.bootstrap4.min.js
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/js/rowReorder.bootstrap5.js
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/js/rowReorder.bootstrap5.min.js
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/js/rowReorder.bulma.js
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/js/rowReorder.bulma.min.js
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/js/rowReorder.dataTables.js
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/js/rowReorder.dataTables.min.js
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/js/rowReorder.foundation.js
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/js/rowReorder.foundation.min.js
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/js/rowReorder.jqueryui.js
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/js/rowReorder.jqueryui.min.js
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/js/rowReorder.semanticui.js
create mode 100644 public/assets/js/DataTables/RowReorder-1.3.3/js/rowReorder.semanticui.min.js
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/css/scroller.bootstrap.css
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/css/scroller.bootstrap.min.css
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/css/scroller.bootstrap4.css
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/css/scroller.bootstrap4.min.css
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/css/scroller.bootstrap5.css
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/css/scroller.bootstrap5.min.css
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/css/scroller.bulma.css
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/css/scroller.bulma.min.css
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/css/scroller.dataTables.css
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/css/scroller.dataTables.min.css
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/css/scroller.foundation.css
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/css/scroller.foundation.min.css
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/css/scroller.jqueryui.css
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/css/scroller.jqueryui.min.css
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/css/scroller.semanticui.css
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/css/scroller.semanticui.min.css
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/js/dataTables.scroller.js
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/js/dataTables.scroller.min.js
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/js/scroller.bootstrap.js
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/js/scroller.bootstrap.min.js
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/js/scroller.bootstrap4.js
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/js/scroller.bootstrap4.min.js
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/js/scroller.bootstrap5.js
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/js/scroller.bootstrap5.min.js
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/js/scroller.bulma.js
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/js/scroller.bulma.min.js
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/js/scroller.dataTables.js
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/js/scroller.dataTables.min.js
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/js/scroller.foundation.js
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/js/scroller.foundation.min.js
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/js/scroller.jqueryui.js
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/js/scroller.jqueryui.min.js
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/js/scroller.semanticui.js
create mode 100644 public/assets/js/DataTables/Scroller-2.1.1/js/scroller.semanticui.min.js
create mode 100644 public/assets/js/DataTables/Select-1.6.2/css/select.bootstrap.css
create mode 100644 public/assets/js/DataTables/Select-1.6.2/css/select.bootstrap.min.css
create mode 100644 public/assets/js/DataTables/Select-1.6.2/css/select.bootstrap4.css
create mode 100644 public/assets/js/DataTables/Select-1.6.2/css/select.bootstrap4.min.css
create mode 100644 public/assets/js/DataTables/Select-1.6.2/css/select.bootstrap5.css
create mode 100644 public/assets/js/DataTables/Select-1.6.2/css/select.bootstrap5.min.css
create mode 100644 public/assets/js/DataTables/Select-1.6.2/css/select.bulma.css
create mode 100644 public/assets/js/DataTables/Select-1.6.2/css/select.bulma.min.css
create mode 100644 public/assets/js/DataTables/Select-1.6.2/css/select.dataTables.css
create mode 100644 public/assets/js/DataTables/Select-1.6.2/css/select.dataTables.min.css
create mode 100644 public/assets/js/DataTables/Select-1.6.2/css/select.foundation.css
create mode 100644 public/assets/js/DataTables/Select-1.6.2/css/select.foundation.min.css
create mode 100644 public/assets/js/DataTables/Select-1.6.2/css/select.jqueryui.css
create mode 100644 public/assets/js/DataTables/Select-1.6.2/css/select.jqueryui.min.css
create mode 100644 public/assets/js/DataTables/Select-1.6.2/css/select.semanticui.css
create mode 100644 public/assets/js/DataTables/Select-1.6.2/css/select.semanticui.min.css
create mode 100644 public/assets/js/DataTables/Select-1.6.2/js/dataTables.select.js
create mode 100644 public/assets/js/DataTables/Select-1.6.2/js/dataTables.select.min.js
create mode 100644 public/assets/js/DataTables/Select-1.6.2/js/select.bootstrap.js
create mode 100644 public/assets/js/DataTables/Select-1.6.2/js/select.bootstrap.min.js
create mode 100644 public/assets/js/DataTables/Select-1.6.2/js/select.bootstrap4.js
create mode 100644 public/assets/js/DataTables/Select-1.6.2/js/select.bootstrap4.min.js
create mode 100644 public/assets/js/DataTables/Select-1.6.2/js/select.bootstrap5.js
create mode 100644 public/assets/js/DataTables/Select-1.6.2/js/select.bootstrap5.min.js
create mode 100644 public/assets/js/DataTables/Select-1.6.2/js/select.bulma.js
create mode 100644 public/assets/js/DataTables/Select-1.6.2/js/select.bulma.min.js
create mode 100644 public/assets/js/DataTables/Select-1.6.2/js/select.dataTables.js
create mode 100644 public/assets/js/DataTables/Select-1.6.2/js/select.dataTables.min.js
create mode 100644 public/assets/js/DataTables/Select-1.6.2/js/select.foundation.js
create mode 100644 public/assets/js/DataTables/Select-1.6.2/js/select.foundation.min.js
create mode 100644 public/assets/js/DataTables/Select-1.6.2/js/select.jqueryui.js
create mode 100644 public/assets/js/DataTables/Select-1.6.2/js/select.jqueryui.min.js
create mode 100644 public/assets/js/DataTables/Select-1.6.2/js/select.semanticui.js
create mode 100644 public/assets/js/DataTables/Select-1.6.2/js/select.semanticui.min.js
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/css/stateRestore.bootstrap.css
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/css/stateRestore.bootstrap.min.css
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/css/stateRestore.bootstrap4.css
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/css/stateRestore.bootstrap4.min.css
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/css/stateRestore.bootstrap5.css
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/css/stateRestore.bootstrap5.min.css
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/css/stateRestore.bulma.css
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/css/stateRestore.bulma.min.css
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/css/stateRestore.dataTables.css
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/css/stateRestore.dataTables.min.css
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/css/stateRestore.foundation.css
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/css/stateRestore.foundation.min.css
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/css/stateRestore.jqueryui.css
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/css/stateRestore.jqueryui.min.css
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/css/stateRestore.semanticui.css
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/css/stateRestore.semanticui.min.css
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/js/dataTables.stateRestore.js
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/js/dataTables.stateRestore.min.js
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/js/stateRestore.bootstrap.js
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/js/stateRestore.bootstrap.min.js
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/js/stateRestore.bootstrap4.js
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/js/stateRestore.bootstrap4.min.js
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/js/stateRestore.bootstrap5.js
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/js/stateRestore.bootstrap5.min.js
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/js/stateRestore.bulma.js
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/js/stateRestore.bulma.min.js
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/js/stateRestore.dataTables.js
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/js/stateRestore.dataTables.min.js
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/js/stateRestore.foundation.js
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/js/stateRestore.foundation.min.js
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/js/stateRestore.jqueryui.js
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/js/stateRestore.jqueryui.min.js
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/js/stateRestore.semanticui.js
create mode 100644 public/assets/js/DataTables/StateRestore-1.2.2/js/stateRestore.semanticui.min.js
create mode 100644 public/assets/js/DataTables/datatables.css
create mode 100644 public/assets/js/DataTables/datatables.js
create mode 100644 public/assets/js/DataTables/datatables.min.css
create mode 100644 public/assets/js/DataTables/datatables.min.js
create mode 100644 public/assets/js/DataTables/pdfmake-0.1.36/pdfmake.js
create mode 100644 public/assets/js/DataTables/pdfmake-0.1.36/pdfmake.min.js
create mode 100644 public/assets/js/DataTables/pdfmake-0.1.36/vfs_fonts.js
create mode 100644 public/assets/js/admin/categories.js
create mode 100644 public/assets/js/admin/edit_lesson.js
create mode 100644 public/assets/js/admin/edit_page.js
create mode 100644 public/assets/js/admin/files.js
create mode 100644 public/assets/js/admin/lessons.js
create mode 100644 public/assets/js/admin/pages.js
create mode 100644 public/assets/js/admin/panel.js
create mode 100644 public/assets/js/admin/privileges.js
create mode 100644 public/assets/js/chart.js/Plugin.Subtitle.js
create mode 100644 public/assets/js/chart.js/chart.min.js
create mode 100644 public/assets/js/chart.js/chartjs-plugin-annotation.js
create mode 100644 public/assets/js/chart.js/chartjs-plugin-datalabels.min.js
create mode 100644 public/assets/js/classroom.js
create mode 100644 public/assets/js/cookie.js
create mode 100644 public/assets/js/edit-post.js
create mode 100644 public/assets/js/lesson-features.js
create mode 100644 public/assets/js/manage-category.js
create mode 100644 public/assets/js/manage-posts.js
create mode 100644 public/assets/js/manage-tags.js
create mode 100644 public/assets/js/marked/marked.cjs
create mode 100644 public/assets/js/marked/marked.esm.js
create mode 100644 public/assets/js/marked/marked.min.js
create mode 100644 public/assets/js/marked/marked.umd.js
create mode 100644 public/assets/js/pdfmake/fonts/Roboto.js
create mode 100644 public/assets/js/pdfmake/fonts/Roboto/Roboto-Italic.ttf
create mode 100644 public/assets/js/pdfmake/fonts/Roboto/Roboto-Medium.ttf
create mode 100644 public/assets/js/pdfmake/fonts/Roboto/Roboto-MediumItalic.ttf
create mode 100644 public/assets/js/pdfmake/fonts/Roboto/Roboto-Regular.ttf
create mode 100644 public/assets/js/pdfmake/pdfmake.js
create mode 100644 public/assets/js/pdfmake/pdfmake.js.map
create mode 100644 public/assets/js/pdfmake/pdfmake.min.js
create mode 100644 public/assets/js/pdfmake/pdfmake.min.js.map
create mode 100644 public/assets/js/pdfmake/standard-fonts/Courier.js
create mode 100644 public/assets/js/pdfmake/standard-fonts/Helvetica.js
create mode 100644 public/assets/js/pdfmake/standard-fonts/Symbol.js
create mode 100644 public/assets/js/pdfmake/standard-fonts/Times.js
create mode 100644 public/assets/js/pdfmake/standard-fonts/ZapfDingbats.js
create mode 100644 public/assets/js/pdfmake/vfs_fonts.js
create mode 100644 public/assets/js/select2/css/select2_4.0.6.min.css
create mode 100644 public/assets/js/select2/i18n/el.js
create mode 100644 public/assets/js/select2/js/select2_4.0.6.min.js
create mode 100644 public/favicon.ico
create mode 100644 public/files/.gitkeep
create mode 100644 public/index.php
create mode 100644 sceleton.txt
create mode 100755 tests/abstract.php
create mode 100755 tests/algo-hashes.php
create mode 100755 tests/auth.php
create mode 100755 tests/code/abstract.php
create mode 100755 tests/code/bits.php
create mode 100755 tests/code/echo.php
create mode 100755 tests/code/exceptions.php
create mode 100755 tests/code/interface.php
create mode 100755 tests/code/login.php
create mode 100644 tests/code/menu.php
create mode 100755 tests/code/proxy.php
create mode 100755 tests/code/session.php
create mode 100755 tests/code/str-replace.php
create mode 100755 tests/compare/compress.php
create mode 100755 tests/compare/hashcost.php
create mode 100755 tests/compare/md5-v-sha1.php
create mode 100755 tests/compare/memcached-v-filecache.php
create mode 100755 tests/compare/redis-v-filecache.php
create mode 100755 tests/compare/serialize-v-jsonencode.php
create mode 100755 tests/compare/sha1-v-sha256.php
create mode 100755 tests/dotnet-pass.php
create mode 100755 tests/mail.php
create mode 100755 tests/php.php
create mode 100755 tests/repository.php
create mode 100755 tests/service/entropy.php
create mode 100755 tests/service/lorem-md.php
create mode 100644 tests/service/mailjet.php
create mode 100755 tests/service/memcached.php
create mode 100755 tests/service/redis.php
create mode 100755 tests/userman.php
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..adb4c79
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,167 @@
+FROM php:8.1-apache as builder
+
+# ARG MODE="PRODUCTION"
+ARG MODE="debug"
+
+
+# mailhog (fake mail) configuration
+# ------------------------------------------------------------------------------
+# RUN apt-get update &&\
+# apt-get install --no-install-recommends --assume-yes --quiet ca-certificates curl git &&\
+# rm -rf /var/lib/apt/lists/*
+# RUN curl -Lsf 'https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz' | tar -C '/usr/local' -xvzf -
+# ENV PATH /usr/local/go/bin:$PATH
+# RUN go get github.com/mailhog/mhsendmail
+# RUN cp /root/go/bin/mhsendmail /usr/bin/mhsendmail
+# RUN echo 'sendmail_path = /usr/bin/mhsendmail --smtp-addr mailhog:1025' > /usr/local/etc/php/php.ini
+
+
+# msmtp (real mail) configuration
+# ------------------------------------------------------------------------------
+# RUN apt-get update && apt-get install -y msmtp && apt-get clean && rm -r /var/lib/apt/lists/*
+# configure sendmail
+# RUN { \
+# echo "php_admin_value[sendmail_path] = $(which msmtp) -ti "; \
+# } >> /usr/local/etc/php-fpm.d/www.conf
+
+
+
+
+
+# setup apache
+# ------------------------------------------------------------------------------
+
+# enable apache mod_rewrite and headers
+RUN a2enmod rewrite
+RUN a2enmod headers
+
+# install pdo and mysql for php
+RUN docker-php-ext-install pdo pdo_mysql mysqli
+
+# copy application code
+# ------------------------------------------------------------------------------
+
+# Copy local code to the container image.
+COPY public /var/www/public
+
+# Copy core files behind public
+COPY core /var/www/core
+
+# Copy storage folder structure behind public
+COPY storage /var/www/storage
+
+# Copy configuration files for the container (application based)
+COPY docker /var/www/docker
+COPY tests /var/www/tests
+COPY composer.json /var/www/
+
+
+# Install Composer
+# ------------------------------------------------------------------------------
+
+# Install Composer with required libraries
+RUN apt-get update --fix-missing
+RUN DEBIAN_FRONTEND=noninteractive apt-get install git unzip wget -y
+RUN curl -sS https://getcomposer.org/installer -o composer-setup.php
+RUN php composer-setup.php --install-dir=/usr/local/bin --filename=composer
+RUN rm composer-setup.php
+
+
+# Add Greek locales to server
+# ------------------------------------------------------------------------------
+WORKDIR /
+RUN apt-get install -y locales
+RUN sed -i 's/^# *\(el_GR\)/\1/' /etc/locale.gen
+RUN locale-gen
+
+
+# Manage permitions in specific (writable) directories
+# ------------------------------------------------------------------------------
+# (make local storage directories writable)
+RUN chown -R www-data:www-data /var/www
+RUN chmod -R 757 /var/www/storage
+RUN chown -R www-data:www-data /var/www/public/files
+RUN chmod -R 757 /var/www/public/files
+
+# change apache's default-root to /var/www/public
+RUN sed -ri -e 's!/var/www/html!/var/www/public!g' /etc/apache2/sites-available/*.conf
+
+
+# Use the PORT environment variable in Apache configuration files.
+RUN sed -i 's/80/${PORT}/g' /etc/apache2/sites-available/000-default.conf /etc/apache2/ports.conf
+
+# Override with custom settings
+# TODO: COPY config/php-ini-overrides.ini $PHP_INI_DIR/conf.d/
+
+
+# Instal Memcached
+# ------------------------------------------------------------------------------
+# RUN apt-get update && apt-get install -y libmemcached-dev zlib1g-dev && pecl install memcached-3.2.0 && docker-php-ext-enable memcached
+# CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
+
+
+# Install and setup cron
+# ------------------------------------------------------------------------------
+# RUN apt-get update && apt-get install cron -y
+# RUN crontab -l | { cat; echo "10 * * * * /usr/local/bin/php /var/www/core/cli/cache-categories.php"; } | crontab -
+# or? RUN crontab -l | { cat; echo "10 * * * * php /var/www/core/cli/cache-categories.php"; } | crontab -
+# ... or copy cronjobs file into/as /etc/cron.d/cron ; then RUN crontab /etc/cron.d/cron
+# ... do that while on entrypoint
+# (+) run once after ex. 4 minutes
+
+
+
+# Install XDebug (only for develop/debud modes)
+# ------------------------------------------------------------------------------
+RUN apt-get install -y apt-utils \
+ && pecl install xdebug \
+ && docker-php-ext-enable xdebug
+
+COPY docker/config/php-ext-xdebug.ini /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
+RUN touch /usr/local/etc/php/xdebug.log
+RUN chown www-data:www-data /usr/local/etc/php/xdebug.log
+RUN chmod 664 /usr/local/etc/php/xdebug.log
+
+
+
+# Prepare the entrypoint as in the original image
+# ------------------------------------------------------------------------------
+RUN cp /var/www/docker/bin/docker-entrypoint.sh /usr/local/bin
+RUN chmod a+x /usr/local/bin/docker-entrypoint.sh
+
+ENTRYPOINT []
+
+
+# TODO:
+## Enable OPcache and JIT on production
+# ------------------------------------------------------------------------------
+## set environemt variable
+
+# RUN load OPcache and JIT from script
+### if [ "${MODE}" = "PRODUCTION" ]; then
+### docker-php-ext-install opcache
+### docker-php-ext-install opcache
+### mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
+
+### chk: https://stackoverflow.com/questions/68308209/docker-compose-failed-to-solve-rpc-error-code-unknown-desc-failed-to-comp
+
+# TODO:
+# Enable JIT
+
+### fi
+
+
+
+# TODO:
+## Enable OPcache and JIT on production
+# ------------------------------------------------------------------------------
+### optimize.sh
+### #!/bin/bash -x
+###
+### if test ["$1" == "PRODUCTION"] ; then
+### docker-php-ext-install opcache
+### docker-php-ext-install opcache
+### install and enable JIT
+### else
+### maybe install some dev-tool
+### fi
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8e7a43c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,191 @@
+# x-anom
+(another MVC framework)
+
+
+
+## pre-Check
+
+Update ```~./container/config/composer-copy.json``` according to
+```~./composer.json``` or vice-versa. You actualy need just one of them;
+if pulling the project into a server (bare-metar/vps/shared etc) you only
+need the first; if pulling into container you need the second/
+
+
+On a Linux system you can also create a link from the one file to the other
+(then you need to use ralative paths on autoload.classmap section).
+
+When deploying on PRODUCTION make sure that all development routes are deleted
+and debuging messages are disabled.
+
+
+
+
+## Build
+
+ docker build -t x-anom .
+
+Force build without using cache:
+
+ docker build --no-cache -t x-anom .
+
+
+
+
+## Run
+
+ docker-compose up
+
+Force rebuild; then run:
+
+ docker-compose up --build
+
+
+
+
+## Remove builded containers
+
+ docker-compose down
+
+
+
+
+## While developing...
+
+By default autoloading is handled by Composer (this is highly recommended).
+While developing your application (or the framework itself) you will need to
+update the autoloading of your new classes. To do so, attach a shell, change
+to ```/var/www``` directory and run ```composer dump-autoload```
+
+ cd /var/www
+
+ composer dump-autoload
+
+If Composer is not an option and you use the framework's autoload implementation
+(enabling ```define('AUTOLOADER' , '../core/helpers/autoload.php');```),
+do not forger to update the (new) paths to your new classes in the ```CLASSPATHS```
+array . Both ```AUTOLOADER``` and ```CLASSPATHS``` definitions can be found
+into ```core/confing/anom_settings.php``` file.
+
+
+
+
+## XDebug
+
+anom comes with most configuration of XDebug ready; all you need is
+
+1. on Doockerfile: uncoomment the commands under XDebug section
+
+2. on docker-compose.yml: uncomment the services.web.extra_hosts section
+
+3. you may need configure your ide to listen onto XDebuger host port
+
+example:
+for vscode you need to add a ~./.vscode/launch.json file like this:
+
+ {
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Listen for Xdebug",
+ "type": "php",
+ "request": "launch",
+ "port": 9003,
+ "pathMappings": {
+ "/var/www/public": "${workspaceRoot}/public"
+ }
+ }
+ ]
+ }
+
+
+
+
+## Customization
+
+The project includes several almost-ready-to-use technologies;
+You can enable / customize / disable / configure all these with a few edits.
+
+Each time you change the configuration of your environment, do not forget to set the
+related parameters on the main configuration file (```/core/config/anom_settings.php)```
+and/or define environmental variables or credentials to the ```/core/auth/.env``` file.
+
+NOTE: #1
+We assume that you use composer; if not, then whatever composer does you have to
+make it manually (copy dependency files and setup the autoloader's paths).
+
+NOTE: #2
+There is no need to use both Redis and Memcached, thus I have not test if these
+two caching technologies will work together using the proposed comfiguration.
+
+
+
+#### Redis
+
+To enable Redis...
+
+Onto docker-compose.yml:
+
+1. Uncomment the lines of 'redis' section; Your Redis-server host name will be the one that is specified in the container_name field (default: redis)
+
+2. Uncomment the networks subsections; web-server and Redis-server will communicate through a bridge network
+
+3. With composer:
+
+Include predis/redis into your project's requirements using ```/docker/config/composer-redis.json```
+as your composer.json file -or- install it via:
+
+ composer require predis/predis
+
+
+
+#### Memcached
+
+To host the Memcached service:
+
+1. Onto docker-compose.yml: uncomment the lines of 'memcached' section; Memcached-server host name will be the one that is specified in the container_name field (default: anomemcached)
+
+2. Onto Dockerfile: uncomment the lines under subsection 'Install Memcached'
+
+
+
+* TODO: Maria database
+
+
+* TODO: Adminer
+(https://stackoverflow.com/questions/33631085/how-to-use-adminer-with-composer-autoload-php)
+
+
+* TODO: phpMyAdmin
+
+
+* Apache
+
+
+* Opcache and JIT
+
+
+TODO:
+
+## Staging
+
+#### Build
+
+#### Deploy
+
+
+## Production
+
+### Build
+
+### Deploy
+
+! Run the above commands ONLY when you need to manually deploy the app to Cloud Run, otherwise everything is automated using Cloud Builds
+
+
+
+
+## Notes
+
+* '~./' refers to the root of the project
+
+* Furhter documentation about the framework can be found in ~./core/README.md
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..22b1d93
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,12 @@
+{
+ "require": {
+ "phpmailer/phpmailer": "^6.8",
+ "erusev/parsedown": "^1.7"
+ },
+ "autoload": {
+ "classmap": [
+ "public/app",
+ "core/classes"
+ ]
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..a48cbdf
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,149 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "da78e21983526d7429f27126efb61469",
+ "packages": [
+ {
+ "name": "erusev/parsedown",
+ "version": "1.7.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/erusev/parsedown.git",
+ "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/erusev/parsedown/zipball/cb17b6477dfff935958ba01325f2e8a2bfa6dab3",
+ "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3",
+ "shasum": ""
+ },
+ "require": {
+ "ext-mbstring": "*",
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "Parsedown": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Emanuil Rusev",
+ "email": "hello@erusev.com",
+ "homepage": "http://erusev.com"
+ }
+ ],
+ "description": "Parser for Markdown.",
+ "homepage": "http://parsedown.org",
+ "keywords": [
+ "markdown",
+ "parser"
+ ],
+ "support": {
+ "issues": "https://github.com/erusev/parsedown/issues",
+ "source": "https://github.com/erusev/parsedown/tree/1.7.x"
+ },
+ "time": "2019-12-30T22:54:17+00:00"
+ },
+ {
+ "name": "phpmailer/phpmailer",
+ "version": "v6.8.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHPMailer/PHPMailer.git",
+ "reference": "df16b615e371d81fb79e506277faea67a1be18f1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/df16b615e371d81fb79e506277faea67a1be18f1",
+ "reference": "df16b615e371d81fb79e506277faea67a1be18f1",
+ "shasum": ""
+ },
+ "require": {
+ "ext-ctype": "*",
+ "ext-filter": "*",
+ "ext-hash": "*",
+ "php": ">=5.5.0"
+ },
+ "require-dev": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.7.2",
+ "doctrine/annotations": "^1.2.6 || ^1.13.3",
+ "php-parallel-lint/php-console-highlighter": "^1.0.0",
+ "php-parallel-lint/php-parallel-lint": "^1.3.2",
+ "phpcompatibility/php-compatibility": "^9.3.5",
+ "roave/security-advisories": "dev-latest",
+ "squizlabs/php_codesniffer": "^3.7.1",
+ "yoast/phpunit-polyfills": "^1.0.4"
+ },
+ "suggest": {
+ "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
+ "ext-openssl": "Needed for secure SMTP sending and DKIM signing",
+ "greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication",
+ "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
+ "league/oauth2-google": "Needed for Google XOAUTH2 authentication",
+ "psr/log": "For optional PSR-3 debug logging",
+ "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)",
+ "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PHPMailer\\PHPMailer\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-2.1-only"
+ ],
+ "authors": [
+ {
+ "name": "Marcus Bointon",
+ "email": "phpmailer@synchromedia.co.uk"
+ },
+ {
+ "name": "Jim Jagielski",
+ "email": "jimjag@gmail.com"
+ },
+ {
+ "name": "Andy Prevost",
+ "email": "codeworxtech@users.sourceforge.net"
+ },
+ {
+ "name": "Brent R. Matzelle"
+ }
+ ],
+ "description": "PHPMailer is a full-featured email creation and transfer class for PHP",
+ "support": {
+ "issues": "https://github.com/PHPMailer/PHPMailer/issues",
+ "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.8.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/Synchro",
+ "type": "github"
+ }
+ ],
+ "time": "2023-03-06T14:43:22+00:00"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": [],
+ "platform-dev": [],
+ "plugin-api-version": "2.3.0"
+}
diff --git a/core/README.md b/core/README.md
new file mode 100644
index 0000000..8dee940
--- /dev/null
+++ b/core/README.md
@@ -0,0 +1,266 @@
+## x-anom
+### X is ANOther Mvc
+
+x-anom is an Object-Oriented MVC php-framework.
+
+Main advantages of the framework:
+
+* It is super-light and fast;
+* Core has almost zero dependences and contains almost anything you need to start and optimize a server-based web-application.
+* It is extensible especialy if you use Composer (which is recommended, though not required)
+* Handles security; and as long as you write code using secure practices, it will be secure
+* It's easy to configure, easy to code, easy to use
+
+
+
+### Requirements
+
+* PHP 8+
+* Some webserver (Apache/Nginx)
+* Some SQL server (MySQL/MariaDB/Postgress)
+* Basic knowledge of php and SQL
+
+
+
+
+### What is included
+
+Core components:
+
+
+#### Router
+
+Routes request to the appropriate Controller
+- matches static paths
+- matches dynamic paths through regex expressions
+- takes care of request-method
+
+
+#### Controller and Model
+
+(just write your Controller and Model classes)
+
+
+#### View (rendering engine)
+
+Usually you just need to call the render_view(template, data) function.
+For templating we use the php short-tag syntax.
+
+main functions:
+
+* load_template( template, data)
+
+* render_view( view_file , data )
+
+* load_asset( type, assets_array )
+
+* set_headers( content_type, ttl, more_array )
+
+* render_text( data, content_type, ttl )
+
+* reply_json( data, ttl )
+
+
+#### Class autoloader
+
+Composer is recomende;
+but if is not available this one will do the job
+
+
+#### Caching
+
+* File Caching mechanism
+
+* Redis Cache
+
+* Memcached Caching
+
+
+#### Session Management
+
+* DefaultSession: psevdo-handler with passthrough methods
+
+* FileSession: custom file-based session handler
+
+* DatabaseSession: database session handler
+
+
+
+#### More
+
+* Proxy design pattern
+
+* Error handling
+
+* Repository
+
+* Cli interface (*summarizes anom*)
+
+
+
+
+
+### Other features
+
+* Docker ready
+
+You can run the framework as is in a Docker environment;
+Also. you can edit just a bit the configuration files to customize the project
+to support various technologies; Check the README file in the project's root
+folder to find out more.
+
+
+
+### What is not included
+
+* It lacks a query builder (SQL is easy and very powerful); do not forget to use prepared statements for all your SQL queries.
+
+* TODO: User-Role based administration class.
+
+* TODO: Shoping-Cart class.
+
+
+
+## Life (and death) of a Client_Request–Server_reply session
+
+1. THE REQUEST: client makes a request -> request arives to the server -> .htaccess sends the request to the index.php
+
+2. index loads Configuration (constants.php + config.php) and AUTOLOADER in order load classes easily
+
+3. index loads init.php -> after initialization the APP is READY -> index loads the routes; Route::run() -> the APP is RUNNING
+
+4. Router resolves the request pattern and calls a Controller
+
+5. (if needed) Controller asks data from the Model; then responds a reply to the client using **render** functions -> APP dies
+
+
+
+## Direcrtory structure
+
+NOTE: directory structure needs updata, but the main structure ramains untouched.
+
+ .
+ |-- container * for docker/container configuration
+ | |-- bin * scripts
+ | `-- config * settings
+ |
+ |-- core * core code
+ | |-- auth * authentication and credentials
+ | |
+ | |-- config * application parametres
+ | | |-- config.php
+ | | |-- constants.php
+ | | |-- credentials.php
+ | | `-- init.php
+ | |
+ | |-- classes * core classes
+ | | |-- cacher
+ | | |-- Benchmark.php
+ | | |-- Database.php
+ | | |-- Route.php
+ | | |-- Security.php
+ | | `-- Session.php
+ | |
+ | `-- helpers * core helpers
+ | |-- autoload.php
+ | |-- error-handling.php
+ | `-- render.php
+ |
+ |-- data * folder for batch data-imports to database
+ |
+ |-- public ** PUBLIC directory
+ | |-- app * APP
+ | | |-- Controllers * Controllers
+ | | | |-- Art.php
+ | | | `-- ...
+ | | |
+ | | |-- Models * Models
+ | | | |-- Art_model.php
+ | | | `-- ...
+ | | |
+ | | |-- Views * Views
+ | | | |-- group.php
+ | | | `-- item.php
+ | | |
+ | | `-- routes.php * application routes
+ | |
+ | `-- cache * Caching folder
+ |
+ `-- vendor * Vendor classes and autoloader
+ |-- composer
+ `-- ...
+
+
+
+
+## Naming Conventions and good practices
+
+1. Keep Controllers, Models, Views in their folders
+
+2. Organize View elements in subfolders
+
+3. Controller and Model names shall be camelcased;
+ - fist letter should be Uppercase;
+ - classes shall be named exactly as their filenames
+
+4. Model names shall be suffixed with _model
+
+5. Comment every-single Controller/Model/class and comment every method
+
+6. On Views (php templates) use php short-tags when possible
+ - Views are about rendering data; avoid complex-logic
+ - [if/else], [foreach] and some flag/temp [variables] sould be fair enough
+
+7. All of the above rules are strongly recommended (although not obligatory);
+
+
+
+## Notes and brainstorming
+
+### for template system check
+ https://css-tricks.com/php-is-a-ok-for-templating/
+
+### for rendering system you may check volt too
+ https://docs.phalcon.io/4.0/en/volt
+
+
+
+## Brainstorming
+
+* take care of various hacks
+ chk: https://stackoverflow.com/questions/1996122/how-to-prevent-xss-with-html-php
+
+* HTML to MarkDown!
+ chk: https://github.com/thephpleague/html-to-markdown
+
+
+
+
+
+VIEW data
+
+-> ceo -> title
+ -> description
+ -> keywords
+ -> ...
+
+-> content -> view : view_filename
+ -> key : some_variable_name
+ -> data : the_data
+
+
+
+
+## Knowledge Requirements
+
+## Tools of work
+
+None of the following tools is necessary, but they will help very very-much.
+
+- Composer
+
+- Docker
+
+- Code editor
+
+- Coffee + Nicotine
diff --git a/core/auth/.gitkeep b/core/auth/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/core/auth/env.example b/core/auth/env.example
new file mode 100644
index 0000000..fd47dd8
--- /dev/null
+++ b/core/auth/env.example
@@ -0,0 +1,36 @@
+ENVIRONMENT='development'
+
+# MySQL connection
+# --- -- -- - - -
+DB_NAME=
+DB_USER=
+DB_PASS=
+PDO_HOST=
+
+# mailhog
+# == testting/fake email service
+# --- -- -- - - -
+# MAIL_HOST=mailhog_server
+# MAIL_PORT=1025
+# MAIL_USERNAME=
+# MAIL_PASSWORD=
+# MAIL_ENCRYPTION=
+
+# SMTP setup
+# == read mail server
+# --- -- -- - - -
+MAIL_MAILER=smtp
+MAIL_HOST=
+MAIL_PORT=465
+MAIL_USERNAME=
+MAIL_PASSWORD=
+MAIL_ENCRYPTION=ssl
+NO_REPLY_EMAIL=noreply@...
+REPLY_TO_EMAIL=webmaster@r...
+MAIL_FROM_NAME=Classroom
+
+# redis cache server
+# --- -- -- - - -
+# REDIS_HOST=redis
+# REDIS_PASSWORD=
+# REDIS_PORT=6379
\ No newline at end of file
diff --git a/core/classes/Benchmark.php b/core/classes/Benchmark.php
new file mode 100644
index 0000000..a7e93ea
--- /dev/null
+++ b/core/classes/Benchmark.php
@@ -0,0 +1,150 @@
+';
+ $close = '
';
+ $divider = ":";
+ $prefix = '';
+ $suffix = '
';
+ break;
+ case 'code':
+ $open = '';
+ $close = '';
+ $divider = ": ";
+ $prefix = '';
+ $suffix = '
';
+ break;
+ case 'comment':
+ default:
+ $open = '';
+ $divider = ":";
+ $prefix = '';
+ $suffix = '';
+ break;
+ }
+
+ echo $prefix;
+
+ // TIME REPORT
+ // ---------------------------------------------------------------------
+ echo "\n\n{$open} Timings {$close}";
+
+ // valid from php 7.3
+ // $start = self::$timeSpots[ array_key_first(self::$timespots) ];
+ // $end = self::$timeSpots[ array_key_last(self::$timespots) ];
+ $start = self::$timeSpots['start'];
+ $end = self::$timeSpots['end'];
+ $all_dt = number_format($end - $start , 4)*1000 ." ms";
+
+
+
+ // if more than 2 timespots
+ // echo dt between each spot
+ if (count(self::$timeSpots) > 2) {
+
+ // calculate dt between spots
+ $time_results = array();
+ $prev_key = '';
+ $prev_time = 0;
+ foreach(self::$timeSpots as $key => $t) {
+ if (!$prev_time) {
+ $prev_time = $t;
+ $prev_key = $key;
+ }
+ else {
+ $dt = number_format($t - $prev_time , 4)*1000 ." ms";
+ $time_results[] = array(
+ 'part' => "{$prev_key}[..{$key}]", ///$key,
+ 'dt' => $dt
+ );
+ $prev_key = $key; //// "{$prev_key}[..{$key}]";
+ $prev_time = $t;
+ }
+ }
+
+ // echo timings
+ foreach ($time_results as $key => $val) {
+ echo "\n\t{$open} {$val['part']} {$divider} {$val['dt']} {$close}";
+ }
+ }
+
+ // echo total time
+ echo "\n\t{$open} total {$divider} {$all_dt} {$close}";
+
+
+ // MEMORY REPORT
+ // ---------------------------------------------------------------------
+ echo "\n\n{$open} Memory Usage {$close}";
+
+ if (count(self::$memoryUse) > 2) {
+
+ foreach (self::$memoryUse as $key => $val) {
+ echo "\n\t{$open} {$key} {$divider} {$val}MB {$close}";
+ }
+
+ } else {
+ echo "\n\t{$open} memory usage {$divider} ". round(memory_get_usage()/(1024*1024),2) ."MB {$close}";
+ }
+
+ echo $suffix;
+
+ }
+
+ }
+}
diff --git a/core/classes/Cart.php b/core/classes/Cart.php
new file mode 100644
index 0000000..4e6f585
--- /dev/null
+++ b/core/classes/Cart.php
@@ -0,0 +1,71 @@
+uid], 10)
+ //
+ // oranize in results = [
+ // {
+ // oid,
+ // prods: [
+ // {
+ // pid,
+ // prodlabel,
+ // count
+ // },
+ // ...
+ // ]
+ // },
+ // ...,
+ // ]
+ //
+ // return $results
+
+ }
+}
+
+
+
+/* ---
+orders:
+ : id
+ : uid (user id)
+
+order_products
+ : id
+ : oid (order id)
+ : pid (product id)
+ -- */
\ No newline at end of file
diff --git a/core/classes/Database.php b/core/classes/Database.php
new file mode 100644
index 0000000..8cac479
--- /dev/null
+++ b/core/classes/Database.php
@@ -0,0 +1,333 @@
+throw_errors = PRODUCTION ? false : true;
+
+ if (null == $this->connection) {
+ try {
+ $this->connection = new PDO(
+ "mysql:" . PDO_HOST . ";" . "dbname=" . DB_NAME,
+ DB_USER,
+ DB_PASS,
+ array(
+ PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'",
+ PDO::MYSQL_ATTR_LOCAL_INFILE => true
+ )
+ );
+
+ // handle error reporting
+ if ($this->throw_errors) {
+ $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+ }
+ $this->setTimezone();
+
+ } catch (PDOException $exc) { handle_exception($exc); }
+ }
+ # return $this->connection;
+ }
+
+
+ /** disconnect
+ * CHECK: not sure if needed
+ */
+ public function disconnect()
+ {
+ $this->connection = null;
+ }
+
+
+ /** set Timezone
+ * (Self-explanatory)
+ */
+ public function setTimezone($timezone = DB_TIMEZONE) {
+ // $this->connection->prepare($timezone)->execute();
+ }
+
+
+ /** lastInsertID
+ * returns the ID of last inserted record
+ */
+ public function lastInsertID()
+ {
+ return $this->connection->lastInsertId();
+ }
+
+
+ /** query
+ * ---
+ * set and execute a query safely;
+ * save results as associative array; DO NOT RETURN RESULTS
+ *
+ * @param $sql (string): SQL query
+ * @param $args (array): array of values to bind into SQL
+ * @param $pypass (boolean): flag to bypass security check
+ *
+ * @return $this (database handler)
+ */
+ public function query($sql, $args=[])
+ {
+ try {
+
+ $stmt = $this->connection->prepare($sql);
+
+ if ($args == []) {
+ $result = $stmt->execute();
+
+ } else {
+ $result = $stmt->execute($args);
+
+ }
+
+ $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
+
+ $this->result = $result;
+
+ return $this;
+
+ } catch (PDOException $exc) { handle_exception($exc); }
+
+ }
+
+
+ /** getAll
+ * ---
+ * return all resulted records
+ * use it after db->query();
+ */
+ public function getAll()
+ {
+ return ($this->result === null) ? false : $this->result;
+ }
+
+
+ /** getFirst
+ * ---
+ * get first row of the resulted query;
+ * used when one row is expected
+ * ex. $db->query('SELECT * FROM users WHERE id = :id',['id'=>1])->getFirst();
+ */
+ public function getFirst()
+ {
+ if (($this->result === null) || ($this->result == [])) {
+ return false;
+
+ } else { return $this->result[0]; }
+ }
+
+
+ /** getOnly
+ * ---
+ * return the first column value of the first row
+ * used when only one value is needed
+ * ex. $db->query('SELECT Count(id) FROM table',[])->getOnly();
+ */
+ public function getOnly()
+ {
+ if (($this->result === null) || ($this->result == [])) {
+ return false;
+
+ } else { return array_values($this->result[0])[0]; }
+ }
+
+
+ /** runQuery
+ * --- (shortcut method)
+ * execute a query safely;
+ * return results as associative array
+ * @param $sql (string): SQL query
+ * @param $args (array): array of values to bind into SQL
+ * @param $pypass (boolean): flag to bypass security check
+ */
+ public function runQuery($sql, $args=[])
+ {
+ return $this->query($sql, $args)->getAll();
+ }
+
+
+ /** runLimitQuery( sql, args, limit=100, offset = null )
+ * set LIMIT / OFFSET clauses in a secure way
+ * @param $sql (string): SQL query
+ * @param $args (array): array of values to bind into SQL
+ * @param $limit (int): LIMIT number
+ * @param $offset (int): OFFSET number
+ */
+ public function runLimitQuery($sql, $args, $limit = 100, $offset = null)
+ {
+ $limitStr = $offsetStr = "";
+
+ // construct LIMIT clause
+ if (is_int($limit)) {
+ $limitStr = " LIMIT {$limit}";
+
+ // construct OFFSET clause (when a LIMIT pre-exists)
+ if (is_int($offset)) {
+ $offsetStr =" OFFSET {$offset}";
+ }
+ }
+
+ $sql = $sql . $limitStr . $offsetStr;
+
+ return $this->runQuery($sql, $args);
+ }
+
+
+ /** insert
+ * @param $table (string): name of table
+ * @param $values: an associative of (fieldName => value) pairs
+ *
+ * example call:
+ * ---
+ * $db->insert('products',
+ * [
+ * 'title' => 'My Dark Chocolate 200g',
+ * 'text' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit ...',
+ * 'isFood' => 1,
+ * 'isToxic' => 0
+ * ]
+ * );
+ *
+ * ...which prepares the SQL query:
+ * INSERT INTO products (title, text, isFood, isToxic)
+ * VALUES (:title, :text, :isFood, :isToxic)
+ *
+ * ...and injects the values: [ :title => 'My Dark Chocolate 200g' , ... ]
+ */
+ public function insert($table, array $values)
+ {
+ $fieldSets = [];
+ $valueSets = [];
+ $bindSets = [];
+
+ foreach($values as $key => $val) {
+ $fieldSets[] = $key;
+ $valueSets[] =':'. $key;
+ $bindSets[':'. $key] = $val;
+ }
+
+ $sql = "INSERT INTO {$table} (". implode(', ', $fieldSets) .")
+ VALUES (". implode(', ', $valueSets) .")";
+
+ return $this->runQuery($sql, $bindSets);
+ }
+
+
+ /** update
+ * @param $table (string): name of table
+ * @param $values: an associative of (fieldName => value) pairs
+ * @param $id: an associative of (fieldName => value) index fields
+ *
+ * example call:
+ * ---
+ * $db->update('products',
+ * [ 'title' => 'My Chocolate','isFood' => 1 ],
+ * [ 'id' => 123 ]
+ * );
+ *
+ * ...which prepares the SQL query:
+ * UPDATE products SET `title` = :title, `isFood` = :isFood WHERE id = :id
+ *
+ * ...and injects: [':title'=> 'My Chocolate' , ':isFood'=> 1 , ':id'=> 123]
+ */
+ public function update( $table, array $values, array $identity)
+ {
+ $fieldSets = []; // array of field names
+ $idSets = []; // array of data-holders
+ $bindSets = []; // array of data-bindings
+
+ foreach($values as $key => $val) {
+ $fieldSets[] = "{$key} = :{$key}";
+ $bindSets[':'. $key] = $val;
+ }
+
+ foreach($identity as $key => $val) {
+ $idSets = "{$key} = :{$key}";
+ $bindSets[':'. $key] = $val;
+ }
+
+ $sql = "UPDATE {$table} SET ". implode(', ', $fieldSets)
+ ." WHERE ". implode(" AND ", $idSets);
+
+ return $this->runQuery($sql, $bindsArray);
+ }
+
+
+ /** multiInsert( table, fields , values )
+ * Construct a multiple-insert clause
+ *
+ * @param $table (string): name of table
+ * @param $fields (array): array with field-names
+ * @param $values (array): array of value-arrays
+ *
+ * example call:
+ * ---
+ * $db->multiInsert('order_products',
+ * [ 'orderID', 'productID', 'unitPrice', 'quantity', 'note' ],
+ * [
+ * [ 124, 102030, 1.25, 5, '' ],
+ * [ 124, 102040, 10.50, 2, 'some note about product #102040' ],
+ * [ 124, 102050, 7.20, 3, '' ],
+ * [ 124, 102060, 3.25, 1, 'some other note' ]
+ * ]
+ * );
+ */
+ public function multiInsert($table, array $fieldsArray, array $valuesArray)
+ {
+ if (count($fieldsArray) != count($valuesArray[0])) {
+ throw new Exception('Fields and value arrays don\'t match.');
+ }
+
+ // setup fieldsSet
+ // ex. "(Title, Price, Status)"
+ $fieldsSet = ' (`'. implode(
+ '`, `', // make sure fieldnames are not SQL-bound terms
+ str_replace('`', '', $fieldsArray) // clean fieldnames
+ ) .'`) ';
+
+ // setup holders array and bind-values array
+ // ex. "(:Title1, :Price1, :Status1), (:Title2, :Price2, :Status2), ...",
+ $holdersArray = [];
+ $bindsArray = [];
+ $counter = 1;
+ foreach($valuesArray as $key => $rowArray) {
+ $rowHolders = [];
+
+ foreach($itemArray as $key => $val) {
+ $rowHolders = ':'. $fieldsArray[$key] . $counter;
+ $bindsArray[ ':'. $fieldsArray[$key] . $counter ] = $val;
+ }
+ $holdersArray[] = '('. implode(', ', $rowHolders ) .')';
+ $counter++;
+ }
+
+ $sql = "INSERT INTO {$table}" . $fieldsSet
+ . ' VALUES '. impload(', ', $holdersArray);
+
+ return $this->runQuery($sql, $bindsArray);
+ }
+
+}
diff --git a/core/classes/Registry.php b/core/classes/Registry.php
new file mode 100644
index 0000000..047fd54
--- /dev/null
+++ b/core/classes/Registry.php
@@ -0,0 +1,135 @@
+";
+ }
+
+ }
+
+ /** parse_sections
+ * ---
+ * parse a group of views (sections)
+ * @param $sections: an array of sections
+ *
+ * each section group is an array with view, key and data properties
+ * + view: defines the view template/file
+ * + key: the variable name that view uses to parse data OR empty-string*
+ * * if key is an empty then $data should be an array (which
+ * includes all [variable-name:data] pairs utilized by the view)
+ * + data: holds the actual data
+ */
+
+ public static function sections($sections) {
+
+ foreach($sections as $sect) {
+
+ if ($sect['key'] == '') {
+ self::view( $sect['view'], $sect['data'] );
+
+ } else {
+ self::view( $sect['view'], [ $sect['key'] => $sect['data']] );
+ }
+ }
+ }
+
+
+ /** render function
+ * ---
+ * uses php's short-tag syntax for templating system
+ * extract data into template
+ * @param $view: view-template filename
+ * @param $data: data to embed into view-template
+ * @param $sanitize: of true then sanitize data.
+ * important NOTE: data is an array [key => value]
+ */
+ public static function view($view, $data=[], $sanitize = false) {
+
+ $file = VIEWS_DIRECTORY . $view . '.php';
+
+ if (file_exists($file)) {
+ if (!defined('OUTPUT_STARTED')) define('OUTPUT_STARTED', 1);
+
+ extract( $sanitize ? self::sanitize_output($data) : $data );
+ require( $file );
+
+ } else if (!PRODUCTION) {
+
+ echo "";
+ }
+
+ }
+
+
+ /** render asap
+ * ---
+ * render_view then output code
+ * so that client will get html to render
+ * while server calculates next html
+ */
+ public static function asap($view, $data, $sanitize = false) {
+ self::view($view, $data, $sanitize);
+ ob_flush();
+ }
+
+
+ /** render text
+ * ---
+ * This function simply echoes text
+ * with Content-Type and Cache Headers
+ * @param $data : the text to echo
+ * @param $cType : Content-Type header
+ * @param $ttl : cache-contol headers; if false response is not-cached; else (int) chache for $ttl seconds
+ */
+ public static function text( $data, $contentType = 'text/html; charset=UTF-8', $ttl = false ) {
+ header('Content-Type: '. $contentType);
+ if ($ttl) {
+ $ts = gmdate("D, d M Y H:i:s", time() + $ttl) . " GMT";
+ header("Expires: {$ts}");
+ header("Pragma: cache");
+ header("Cache-Control: max-age={$ttl}");
+
+ } else {
+ $ts = gmdate("D, d M Y H:i:s") . " GMT";
+ header("Expires: {$ts}");
+ header("Last-Modified: {$ts}");
+ header("Pragma: no-cache");
+ header("Cache-Control: no-cache, must-revalidate");
+ }
+ echo htmlspecialchars($data);
+ }
+
+
+ /** reply_json
+ * ---
+ * transform a php-array to json and echo to client
+ * Can be used for API calls
+ *
+ * @param $data : the php array)
+ * @param $ttl : cache-contol headers; if false response is not-cached; else chache for $ttl seconds
+ */
+ public static function json( $data, $ttl = false ) {
+ header('Content-Type: application/json');
+ if ($ttl) {
+ $ts = gmdate("D, d M Y H:i:s", time() + $ttl) . " GMT";
+ header("Expires: {$ts}");
+ header("Pragma: cache");
+ header("Cache-Control: max-age={$ttl}");
+
+ } else {
+ $ts = gmdate("D, d M Y H:i:s") . " GMT";
+ header("Expires: {$ts}");
+ header("Last-Modified: {$ts}");
+ header("Pragma: no-cache");
+ header("Cache-Control: no-cache, must-revalidate");
+ }
+ echo json_encode($data, JSON_UNESCAPED_UNICODE);
+
+ // NOTE:
+ // after Rendering a JSON ...
+ // you probably do not need to export anything else;
+ die();
+ }
+
+
+
+
+ // HELPER FUNCTIONS
+ // -----------------------------------------------------------------------------
+
+
+ /** link asset
+ * ---
+ * the function defines the assets (css or js)
+ * to be loaded on the client (creates the HTML)
+ * @param $type : type of asset [css|js]
+ * @param $assetIDs : an array of ('assetID' => 'paramaters')
+ *
+ * example calls:
+ * load_asset('css', ['main' => 'media="all"', 'filters' => 'media="all"']);
+ * load_asset( 'js', ['jquery' => '', 'lazyloader' => 'async']);
+ */
+ public static function asset( $type, $assetIDs, $paramatres = '' ) {
+
+ $code = ""; // code to return
+
+ // make sure $assetIDs is array (for coding simplicity)
+ if (!is_array($assetIDs)) {
+ $assetIDs = [ $assetIDs ];
+ }
+
+ // check asset type and construct all asset inserts
+ switch ($type) {
+
+ case 'font':
+ foreach($assetIDs as $asset) {
+ $code .= "\n\t";
+ }
+ break;
+
+ case 'js':
+ foreach($assetIDs as $asset) {
+ $code .= "\n\t";
+ }
+ break;
+
+ case 'css':
+ default:
+ foreach($assetIDs as $asset) {
+ $code .= "\n\t";
+ }
+ }
+
+ echo $code;
+ }
+
+
+ /** sanitize_output (recursive)
+ * ---
+ * Sanitizes data that are about to rendered
+ * (usually when render_view() is called).
+ *
+ * NOTE:
+ * mitigates XSS attachs
+ *
+ * @param $data: (array)
+ */
+ public static function sanitize_output($data) {
+ //// check https://stackoverflow.com/questions/2002710/php-how-to-perform-htmlspecialchar-on-an-array-of-arrays
+
+ //// $output = array_map("myFunc", $data);
+
+ global $secure;
+
+ $output = array();
+ foreach($data as $key => $val) {
+
+ if (is_string($val)) {
+ $output[$key] = htmlspecialchars(self::remove_invisible_characters($val));
+
+ } else if (is_array($val)) {
+ $output[$key] = self::sanitize_output($val);
+
+ } else {
+ $output[$key] = $val;
+ }
+ }
+ return $output;
+ }
+
+
+ /** remove_invisible_characters()
+ * ---
+ * @used by sanitize_output()
+ */
+ public static function remove_invisible_characters($str, $url_encoded = TRUE)
+ {
+ $non_displayables = array();
+
+ // every control character except newline (dec 10),
+ // carriage return (dec 13) and horizontal tab (dec 09)
+ if ($url_encoded) {
+ $non_displayables[] = '/%0[0-8bcef]/i'; // url encoded 00-08, 11, 12, 14, 15
+ $non_displayables[] = '/%1[0-9a-f]/i'; // url encoded 16-31
+ $non_displayables[] = '/%7f/i'; // url encoded 127
+ }
+
+ $non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'; // 00-08, 11, 12, 14-31, 127
+
+ do {
+ $str = preg_replace($non_displayables, '', $str, -1, $count);
+ } while ($count);
+
+ return $str;
+ }
+
+
+ /** html
+ * ---
+ * outputs code as html
+ *
+ * @param $str (string)
+ * @return html5 (string)
+ */
+ public static function html($str) {
+ if (!isset($str) || $str== null) return;
+ if (($str == '') || is_numeric($str)) return $str;
+ return htmlspecialchars_decode($str, ENT_QUOTES|ENT_HTML5);
+ }
+
+
+ /** set_headers
+ * ---
+ * set custom response-Headers
+ *
+ * @param $contentType
+ * @param $ttl: int or false)
+ * @param $more: array of (content-type => content-value) pairs
+ */
+ public static function set_headers($contentType = 'text/html; charset=UTF-8', $ttl = false, $more = [] ) {
+
+ // handle common content-type shorcuts
+ switch ($contentType) {
+ case 'text':
+ case 'html':
+ $contentType = 'text/html; charset=UTF-8';
+ break;
+ case 'json':
+ $contentType = 'application/json; charset=utf-8';
+ break;
+ case 'js':
+ $contentType = 'application/javascript; charset=utf-8';
+ break;
+ case 'css':
+ $contentType = 'text/css';
+ break;
+ default:
+ // $contentType stays as-is
+ break;
+ }
+
+ // send headers
+ header('Content-Type: '. $contentType);
+ if ($ttl) {
+ $ts = gmdate("D, d M Y H:i:s", time() + $ttl) . " GMT";
+ header("Expires: {$ts}");
+ header("Pragma: cache");
+ header("Cache-Control: max-age={$ttl}");
+
+ } else {
+ $ts = gmdate("D, d M Y H:i:s") . " GMT";
+ header("Expires: {$ts}");
+ header("Last-Modified: {$ts}");
+ header("Pragma: no-cache");
+ header("Cache-Control: no-cache, must-revalidate");
+ }
+
+ // send more headers
+ if ($more != []) {
+ foreach($more as $header => $value) {
+ header($header .': '. $value);
+ }
+ }
+
+ }
+
+
+ /** render file
+ *
+ */
+ public static function file($path, $madia_type)
+ {
+ $content = file_get_contents($path);
+ header("Content-Type: {$media_type}");
+ echo $content;
+ }
+
+
+}
\ No newline at end of file
diff --git a/core/classes/Repository.php b/core/classes/Repository.php
new file mode 100644
index 0000000..c01d0c1
--- /dev/null
+++ b/core/classes/Repository.php
@@ -0,0 +1,43 @@
+URL = $_SERVER['REQUEST_URI'];
+ $this->PATH = (!empty($parsed['path'])) ? urldecode($parsed['path']) : '';
+ $this->QUERY = (!empty($parsed['query'])) ? urldecode($parsed['query']) : false;
+ $this->HOST = $_SERVER['HTTP_HOST'];
+ $this->PORT = $_SERVER['SERVER_PORT'];
+ $this->TIME = $_SERVER['REQUEST_TIME'];
+ $this->IP = $_SERVER['REMOTE_ADDR'];
+
+ $this->METHOD = strtolower($_SERVER['REQUEST_METHOD']);
+
+ $this->GET = $_GET; // $_GET should only used
+ // to request data or specify options (never to perform
+ // system-changes) thus should not need any validation;
+ // * If (for any reason) you requide $_GET sanitization
+ // enable it later on the method's code
+
+ $this->FILES = $_FILES; // TODO: sanitize the files array
+
+ // $this->INTERFACE = php_sapi_name();
+
+ $this->AGENT = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown';
+ $this->SIGNATURE = sha1(
+ $_SERVER['HTTP_USER_AGENT'] ?? 'unknown'
+ . $_SERVER['HTTP_ACCEPT'] ?? ''
+ . $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? ''
+ . $_SERVER['HTTP_ACCEPT_ENCODING'] ?? ''
+ );
+
+ // sanitize user input
+ // if (isset($_GET)) { $this->GET = $this->sanitize($_GET); }
+ $this->GET = $this->sanitize($_GET);
+ if (isset($_POST)) { $this->POST = $this->sanitize($_POST); }
+ if (isset($_COOKIE)) { $this->COOKIE = $this->sanitize($_COOKIE); }
+
+ // check anti-CSRF token if needed
+ // (again, GET requests should not need CSRF cheking)
+ if (in_array($this->METHOD, ['post', 'put', 'patch', 'delete'])) {
+ // TODO: only if CSRF protection enabled...
+ $this->checkCsrfToken();
+ }
+
+ }
+
+
+ /**
+ * Check:
+ *
+ * 1.
+ * https://dev.to/anastasionico/good-practices-how-to-sanitize-validate-and-escape-in-php-3-methods-139b
+ *
+ * 2.
+ * https://benhoyt.com/writings/dont-sanitize-do-escape/
+ *
+ */
+ private function sanitize($array)
+ {
+ // TODO:
+ // ...
+ return $array;
+ }
+
+
+ public function checkCsrfToken()
+ {
+ // TODO:
+ // ...
+ // if SCRF-token is not valideted, serve 403
+ return true;
+ }
+
+
+
+
+ public function isAjax(): bool
+ {
+ // check headers 'XMLHttpRequest' == $this->headers->get('X-Requested-With');
+ }
+
+
+ public function isSecure(): bool
+ {
+ // chech if HTTPS
+ }
+
+
+ public function hasSession(): bool
+ {
+ // chech if Session exist
+ }
+
+
+ /**
+ * Get the user making the request.
+ *
+ * @param string|null $guard
+ * @return mixed
+ */
+ public function user($guard = null)
+ {
+ // return call_user_func($this->getUserResolver(), $guard);
+ }
+
+ public function getUserResolver()
+ {
+ // return $this->userResolver ?: function () {
+ //
+ // };
+ }
+
+ /**
+ * Set the user resolver callback.
+ *
+ * @param \Closure $callback
+ * @return $this
+ */
+ public function setUserResolver(Closure $callback)
+ {
+ // $this->userResolver = $callback;
+ // return $this;
+ }
+
+
+
+}
+
diff --git a/core/classes/Route.php b/core/classes/Route.php
new file mode 100644
index 0000000..072723c
--- /dev/null
+++ b/core/classes/Route.php
@@ -0,0 +1,97 @@
+ $expression,
+ 'function' => $function,
+ 'method' => strtolower($method)
+ ));
+ }
+
+
+ /** notFound($function)
+ * ---
+ * @param $function : call back function to be executed
+ */
+ public static function notFound($function)
+ {
+ self::$notFound = $function;
+ }
+
+
+ /** run()
+ * ---
+ * Parse request ; Find mathing route ;
+ * then call route's function
+ * usualy a Controller::method([poarametres])
+ */
+ public static function run(Request $request)
+ {
+ // $request = Registry::get('REQUEST');
+ $path = $request->PATH; // request path
+ $method = $request->METHOD; // request method
+
+ $path_match_found = false;
+ $route_match_found = false;
+
+ foreach(self::$routes as $route) {
+
+ // If method matched check the path
+ if ($route['method'] == $method || $method == 'any') {
+
+ // Add 'find string start' automatically
+ $route['expression'] = '^'.$route['expression'];
+
+ // Add 'find string end' automatically
+ $route['expression'] = $route['expression'].'$';
+
+ // Check path match
+ if (preg_match('#'. $route['expression'] .'#', $path, $matches)) {
+
+ $route_match_found = true;
+
+ array_shift($matches); // Always remove first element. This contains the whole string
+
+ call_user_func_array($route['function'], $matches);
+ break; // Do not check other routes
+
+ }
+ }
+ }
+
+ // No matching route was found
+ if (!$route_match_found) {
+ header("HTTP/1.0 404 Not Found");
+ if (self::$notFound) {
+ call_user_func_array(self::$notFound, []);
+ }
+ }
+
+ }
+
+}
diff --git a/core/classes/Security.php b/core/classes/Security.php
new file mode 100644
index 0000000..61979db
--- /dev/null
+++ b/core/classes/Security.php
@@ -0,0 +1,923 @@
+', '<', '>',
+ "'", '"', '&', '$', '#',
+ '{', '}', '[', ']', '=',
+ ';', '?', '%20', '%22',
+ '%3c', // <
+ '%253c', // <
+ '%3e', // >
+ '%0e', // >
+ '%28', // (
+ '%29', // )
+ '%2528', // (
+ '%26', // &
+ '%24', // $
+ '%3f', // ?
+ '%3b', // ;
+ '%3d' // =
+ );
+
+ public $charset = 'UTF-8'; // Character set @var (string) Will be overridden by the constructor.
+
+ protected $_xss_hash; // XSS Hash: @var (string) Random Hash for protecting URLs.
+
+ protected $_csrf_hash; // CSRF Hash: @var (string) Random hash for Cross Site Request Forgery protection cookie
+
+ // CSRF Expire time @var (int)
+ // Expiration time for Cross Site Request Forgery protection cookie.
+ protected $_csrf_expire = 7200; // defaults to 2hours (=7200 seconds)
+
+ // CSRF Token name: @var (string) Token name for Cross Site Request Forgery protection cookie.
+ protected $_csrf_token_name = 'pi_csrf_token';
+
+ // CSRF Cookie name: @var (string) Cookie name for Cross Site Request Forgery protection cookie.
+ protected $_csrf_cookie_name = 'pi_csrf_token';
+
+ // List of never allowed strings @var (array)
+ protected $_never_allowed_str = array(
+ 'document.cookie' => '[removed]',
+ '(document).cookie' => '[removed]',
+ 'document.write' => '[removed]',
+ '(document).write' => '[removed]',
+ '.parentNode' => '[removed]',
+ '.innerHTML' => '[removed]',
+ '-moz-binding' => '[removed]',
+ '' => '-->',
+ ' '<![CDATA[',
+ '' => '<comment>',
+ '<%' => '<%'
+ );
+
+ // List of never allowed regex replacements @var (array)
+ protected $_never_allowed_regex = array(
+ 'javascript\s*:',
+ '(\(?document\)?|\(?window\)?(\.document)?)\.(location|on\w*)',
+ 'expression\s*(\(|&\#40;)', // CSS and IE
+ 'vbscript\s*:', // IE, surprise!
+ 'wscript\s*:', // IE
+ 'jscript\s*:', // IE
+ 'vbs\s*:', // IE
+ 'Redirect\s+30\d',
+ "([\"'])?data\s*:[^\\1]*?base64[^\\1]*?,[^\\1]*?\\1?"
+ );
+
+
+ /** Class constructor
+ * ---
+ * @return void
+ */
+ public function __construct($charset = 'UTF-8')
+ {
+ $this->charset = $charset;
+
+ /* ---
+ // Is CSRF protection enabled?
+ if (CSRF_PROTCTION') && ! is_cli())
+ { --*/
+ /**************
+ // CSRF config
+ foreach (array('csrf_expire', 'csrf_token_name', 'csrf_cookie_name') as $key)
+ {
+ //// if (NULL !== ($val = config_item($key)))
+ //// {
+ $this->{'_'.$key} = $val;
+ //// }
+ }
+
+ // Append application specific cookie prefix
+ //// if ($cookie_prefix = config_item('cookie_prefix'))
+ //// {
+ $this->_csrf_cookie_name = $cookie_prefix . $this->_csrf_cookie_name;
+ //// }
+
+ // Set the CSRF hash
+ $this->_csrf_set_hash();
+ $this->csrf_verify();
+ ***************/
+ /* ---
+ } --*/
+
+ //// log_message('info', 'Security Class Initialized');
+ }
+
+
+ /** CSRF Verify
+ * ---
+ * @return Security
+ */
+ public function csrf_verify()
+ {
+ // If it's not a POST request we will set the CSRF cookie
+ if (strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST')
+ {
+ return $this->csrf_set_cookie();
+ }
+
+ /// // Check if URI has been whitelisted from CSRF checks
+ /// if ($exclude_uris = config_item('csrf_exclude_uris'))
+ /// {
+ /// $uri = load_class('URI', 'core');
+ /// foreach ($exclude_uris as $excluded)
+ /// {
+ /// if (preg_match('#^'.$excluded.'$#i'.(UTF8_ENABLED ? 'u' : ''), $uri->uri_string()))
+ /// {
+ /// return $this;
+ /// }
+ /// }
+ /// }
+
+ // Check CSRF token validity, but don't error on mismatch just yet - we'll want to regenerate
+ $valid = isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name])
+ && is_string($_POST[$this->_csrf_token_name]) && is_string($_COOKIE[$this->_csrf_cookie_name])
+ && hash_equals($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]);
+
+ // We kill this since we're done and we don't want to pollute the _POST array
+ unset($_POST[$this->_csrf_token_name]);
+
+ // Regenerate on every submission?
+ if (config_item('csrf_regenerate'))
+ {
+ // Nothing should last forever
+ unset($_COOKIE[$this->_csrf_cookie_name]);
+ $this->_csrf_hash = NULL;
+ }
+
+ $this->_csrf_set_hash();
+ $this->csrf_set_cookie();
+
+ if ($valid !== TRUE)
+ {
+ $this->csrf_show_error();
+ }
+
+ log_message('info', 'CSRF token verified');
+ return $this;
+ }
+
+
+ /** CSRF Set Cookie
+ * ---
+ * @codeCoverageIgnore
+ * @return Security
+ */
+ public function csrf_set_cookie()
+ {
+ $expire = time() + $this->_csrf_expire;
+ $secure_cookie = (bool) config_item('cookie_secure');
+
+ if ($secure_cookie && ! is_https())
+ {
+ return FALSE;
+ }
+
+ // php7.3+
+ setcookie(
+ $this->_csrf_cookie_name,
+ $this->_csrf_hash,
+ array(
+ 'expires' => $expire,
+ 'path' => config_item('cookie_path'),
+ 'domain' => config_item('cookie_domain'),
+ 'secure' => $secure_cookie,
+ 'httponly' => config_item('cookie_httponly'),
+ 'samesite' => 'Strict'
+ )
+ );
+
+ log_message('info', 'CSRF cookie sent');
+
+ return $this;
+ }
+
+
+ /** Show CSRF Error
+ * --
+ * @return void
+ */
+ public function csrf_show_error()
+ {
+ show_error('The action you have requested is not allowed.', 403);
+ }
+
+
+ /** Get CSRF Hash
+ * ---
+ * @see CI_Security::$_csrf_hash
+ * @return string CSRF hash
+ */
+ public function get_csrf_hash()
+ {
+ return $this->_csrf_hash;
+ }
+
+
+ /** Get CSRF Token Name
+ * ---
+ * @see CI_Security::$_csrf_token_name
+ * @return string CSRF token name
+ */
+ public function get_csrf_token_name()
+ {
+ return $this->_csrf_token_name;
+ }
+
+
+ /** XSS Clean
+ * ---
+ * Sanitizes data so that Cross Site Scripting Hacks can be
+ * prevented. This method does a fair amount of work but
+ * it is extremely thorough, designed to prevent even the
+ * most obscure XSS attempts. Nothing is ever 100% foolproof,
+ * of course, but I haven't been able to get anything passed
+ * the filter.
+ *
+ * Note: Should only be used to deal with data upon submission.
+ * It's not something that should be used for general
+ * runtime processing.
+ *
+ * @link http://channel.bitflux.ch/wiki/XSS_Prevention
+ * Based in part on some code and ideas from Bitflux.
+ *
+ * @link http://ha.ckers.org/xss.html
+ * To help develop this script I used this great list of
+ * vulnerabilities along with a few other hacks I've
+ * harvested from examining vulnerabilities in other programs.
+ *
+ * @param string|string[] $str Input data
+ * @param bool $is_image Whether the input is an image
+ * @return string
+ */
+ public function xss_clean($str, $is_image = FALSE)
+ {
+ // Is the string an array?
+ if (is_array($str))
+ {
+ foreach ($str as $key => &$value)
+ {
+ $str[$key] = $this->xss_clean($value);
+ }
+
+ return $str;
+ }
+
+ // Remove Invisible Characters
+ $str = remove_invisible_characters($str);
+
+ // URL Decode
+ // Just in case stuff like this is submitted:
+ // Google
+ // NOTE: Use rawurldecode() so it does not remove plus signs
+ if (stripos($str, '%') !== false)
+ {
+ do
+ {
+ $oldstr = $str;
+ $str = rawurldecode($str);
+ $str = preg_replace_callback('#%(?:\s*[0-9a-f]){2,}#i', array($this, '_urldecodespaces'), $str);
+ }
+ while ($oldstr !== $str);
+ unset($oldstr);
+ }
+
+ // Convert character entities to ASCII
+ // ---
+ // This permits our tests below to work reliably.
+ // We only convert entities that are within tags since
+ // these are the ones that will pose security problems.
+ $str = preg_replace_callback("/[^a-z0-9>]+[a-z0-9]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str);
+ $str = preg_replace_callback('/<\w+.*/si', array($this, '_decode_entity'), $str);
+
+ // Remove Invisible Characters Again!
+ $str = remove_invisible_characters($str);
+
+
+ // Convert all tabs to spaces
+ // ---
+ // This prevents strings like this: ja vascript
+ // NOTE: we deal with spaces between characters later.
+ // NOTE: preg_replace was found to be amazingly slow here on
+ // large blocks of data, so we use str_replace.
+ $str = str_replace("\t", ' ', $str);
+
+ // Capture converted string for later comparison
+ $converted_string = $str;
+
+ // Remove Strings that are never allowed
+ $str = $this->_do_never_allowed($str);
+
+
+ // Makes PHP tags safe
+ // NOTE: XML tags are inadvertently replaced too:
+ // '), array('<?', '?>'), $str);
+ }
+
+ // Compact any exploded words
+ // ---
+ // This corrects words like: j a v a s c r i p t
+ // These words are compacted back to their correct state.
+ $words = array(
+ 'javascript', 'expression', 'vbscript', 'jscript', 'wscript',
+ 'vbs', 'script', 'base64', 'applet', 'alert', 'document',
+ 'write', 'cookie', 'window', 'confirm', 'prompt', 'eval'
+ );
+
+ foreach ($words as $word)
+ {
+ $word = implode('\s*', str_split($word)).'\s*';
+
+ // We only want to do this when it is followed by a non-word character
+ // That way valid stuff like "dealer to" does not become "dealerto"
+ $str = preg_replace_callback('#('.substr($word, 0, -3).')(\W)#is', array($this, '_compact_exploded_words'), $str);
+ }
+
+
+ // Remove disallowed Javascript in links or img tags
+ // We used to do some version comparisons and use of stripos(),
+ // but it is dog slow compared to these simplified non-capturing
+ // preg_match(), especially if the pattern exists in the string
+ //
+ // Note: It was reported that not only space characters, but all in
+ // the following pattern can be parsed as separators between a tag name
+ // and its attributes: [\d\s"\'`;,\/\=\(\x00\x0B\x09\x0C]
+ // ... however, remove_invisible_characters() above already strips the
+ // hex-encoded ones, so we'll skip them below.
+ do
+ {
+ $original = $str;
+
+ if (preg_match('/]+([^>]*?)(?:>|$)#si', array($this, '_js_link_removal'), $str);
+ }
+
+ if (preg_match('/
]*?)(?:\s?/?>|$)#si', array($this, '_js_img_removal'), $str);
+ }
+
+ if (preg_match('/script|xss/i', $str))
+ {
+ $str = preg_replace('#*(?:script|xss).*?>#si', '[removed]', $str);
+ }
+ }
+ while ($original !== $str);
+ unset($original);
+
+
+ // Sanitize naughty HTML elements
+ // ---
+ // If a tag containing any of the words in the list
+ // below is found, the tag gets converted to entities.
+ // So this: