summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--composer.json3
-rw-r--r--composer.lock651
-rw-r--r--core/cli/cli-cache.php65
-rwxr-xr-xcore/cli/curl-cache.php155
-rw-r--r--core/cli/info.md23
-rw-r--r--docker/config/composer-naked.json3
-rw-r--r--docker/config/composer-redis.json4
-rw-r--r--public/app/config/.gitkeep0
-rw-r--r--public/app/controllers/.gitkeep0
-rw-r--r--public/app/controllers/Auth.php28
-rw-r--r--public/app/controllers/admin/Course_admin.php12
-rw-r--r--public/app/controllers/cli/CliContoller.php48
-rw-r--r--public/app/controllers/cms/Course.php86
-rw-r--r--public/app/extends/.gitkeep0
-rw-r--r--public/app/extends/Cache_service.php16
-rw-r--r--public/app/models/.gitkeep0
-rw-r--r--public/app/models/cms/Course_model.php22
-rw-r--r--public/app/routes/.gitkeep0
-rw-r--r--public/app/routes/backend.php113
-rw-r--r--public/app/routes/frontend.php209
-rw-r--r--public/app/views/.gitkeep0
-rw-r--r--public/app/views/components/breadcrumbs.php2
-rw-r--r--public/app/views/components/lessons_list.php4
-rw-r--r--public/app/views/components/subcategories.php3
-rw-r--r--public/app/views/components/top_bar.php25
-rw-r--r--public/app/views/error/404.php1
-rw-r--r--public/app/views/error/general.php16
-rw-r--r--public/app/views/templates/course.php2
-rw-r--r--public/app/views/templates/lesson.php72
-rw-r--r--public/assets/css/class.css15
-rw-r--r--public/assets/css/overides.css8
-rw-r--r--public/assets/js/admin/edit_lesson.js17
-rw-r--r--public/assets/js/lesson-features.js (renamed from public/assets/js/post-features.js)50
33 files changed, 745 insertions, 908 deletions
diff --git a/composer.json b/composer.json
index dd8061e..22b1d93 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,7 @@
{
"require": {
- "phpmailer/phpmailer": "^6.8"
+ "phpmailer/phpmailer": "^6.8",
+ "erusev/parsedown": "^1.7"
},
"autoload": {
"classmap": [
diff --git a/composer.lock b/composer.lock
index b7c2f98..a48cbdf 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,368 +4,33 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "b3dacac13073b78ee8cc0715dbe88e27",
+ "content-hash": "da78e21983526d7429f27126efb61469",
"packages": [
{
- "name": "guzzlehttp/guzzle",
- "version": "7.5.0",
+ "name": "erusev/parsedown",
+ "version": "1.7.4",
"source": {
"type": "git",
- "url": "https://github.com/guzzle/guzzle.git",
- "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba"
+ "url": "https://github.com/erusev/parsedown.git",
+ "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba",
- "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba",
+ "url": "https://api.github.com/repos/erusev/parsedown/zipball/cb17b6477dfff935958ba01325f2e8a2bfa6dab3",
+ "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3",
"shasum": ""
},
"require": {
- "ext-json": "*",
- "guzzlehttp/promises": "^1.5",
- "guzzlehttp/psr7": "^1.9 || ^2.4",
- "php": "^7.2.5 || ^8.0",
- "psr/http-client": "^1.0",
- "symfony/deprecation-contracts": "^2.2 || ^3.0"
- },
- "provide": {
- "psr/http-client-implementation": "1.0"
- },
- "require-dev": {
- "bamarni/composer-bin-plugin": "^1.8.1",
- "ext-curl": "*",
- "php-http/client-integration-tests": "^3.0",
- "phpunit/phpunit": "^8.5.29 || ^9.5.23",
- "psr/log": "^1.1 || ^2.0 || ^3.0"
- },
- "suggest": {
- "ext-curl": "Required for CURL handler support",
- "ext-intl": "Required for Internationalized Domain Name (IDN) support",
- "psr/log": "Required for using the Log middleware"
- },
- "type": "library",
- "extra": {
- "bamarni-bin": {
- "bin-links": true,
- "forward-command": false
- },
- "branch-alias": {
- "dev-master": "7.5-dev"
- }
- },
- "autoload": {
- "files": [
- "src/functions_include.php"
- ],
- "psr-4": {
- "GuzzleHttp\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Graham Campbell",
- "email": "hello@gjcampbell.co.uk",
- "homepage": "https://github.com/GrahamCampbell"
- },
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- },
- {
- "name": "Jeremy Lindblom",
- "email": "jeremeamia@gmail.com",
- "homepage": "https://github.com/jeremeamia"
- },
- {
- "name": "George Mponos",
- "email": "gmponos@gmail.com",
- "homepage": "https://github.com/gmponos"
- },
- {
- "name": "Tobias Nyholm",
- "email": "tobias.nyholm@gmail.com",
- "homepage": "https://github.com/Nyholm"
- },
- {
- "name": "Márk Sági-Kazár",
- "email": "mark.sagikazar@gmail.com",
- "homepage": "https://github.com/sagikazarmark"
- },
- {
- "name": "Tobias Schultze",
- "email": "webmaster@tubo-world.de",
- "homepage": "https://github.com/Tobion"
- }
- ],
- "description": "Guzzle is a PHP HTTP client library",
- "keywords": [
- "client",
- "curl",
- "framework",
- "http",
- "http client",
- "psr-18",
- "psr-7",
- "rest",
- "web service"
- ],
- "support": {
- "issues": "https://github.com/guzzle/guzzle/issues",
- "source": "https://github.com/guzzle/guzzle/tree/7.5.0"
- },
- "funding": [
- {
- "url": "https://github.com/GrahamCampbell",
- "type": "github"
- },
- {
- "url": "https://github.com/Nyholm",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle",
- "type": "tidelift"
- }
- ],
- "time": "2022-08-28T15:39:27+00:00"
- },
- {
- "name": "guzzlehttp/promises",
- "version": "1.5.2",
- "source": {
- "type": "git",
- "url": "https://github.com/guzzle/promises.git",
- "reference": "b94b2807d85443f9719887892882d0329d1e2598"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598",
- "reference": "b94b2807d85443f9719887892882d0329d1e2598",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5"
- },
- "require-dev": {
- "symfony/phpunit-bridge": "^4.4 || ^5.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.5-dev"
- }
- },
- "autoload": {
- "files": [
- "src/functions_include.php"
- ],
- "psr-4": {
- "GuzzleHttp\\Promise\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Graham Campbell",
- "email": "hello@gjcampbell.co.uk",
- "homepage": "https://github.com/GrahamCampbell"
- },
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- },
- {
- "name": "Tobias Nyholm",
- "email": "tobias.nyholm@gmail.com",
- "homepage": "https://github.com/Nyholm"
- },
- {
- "name": "Tobias Schultze",
- "email": "webmaster@tubo-world.de",
- "homepage": "https://github.com/Tobion"
- }
- ],
- "description": "Guzzle promises library",
- "keywords": [
- "promise"
- ],
- "support": {
- "issues": "https://github.com/guzzle/promises/issues",
- "source": "https://github.com/guzzle/promises/tree/1.5.2"
- },
- "funding": [
- {
- "url": "https://github.com/GrahamCampbell",
- "type": "github"
- },
- {
- "url": "https://github.com/Nyholm",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises",
- "type": "tidelift"
- }
- ],
- "time": "2022-08-28T14:55:35+00:00"
- },
- {
- "name": "guzzlehttp/psr7",
- "version": "2.4.4",
- "source": {
- "type": "git",
- "url": "https://github.com/guzzle/psr7.git",
- "reference": "3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf",
- "reference": "3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf",
- "shasum": ""
- },
- "require": {
- "php": "^7.2.5 || ^8.0",
- "psr/http-factory": "^1.0",
- "psr/http-message": "^1.0",
- "ralouphie/getallheaders": "^3.0"
- },
- "provide": {
- "psr/http-factory-implementation": "1.0",
- "psr/http-message-implementation": "1.0"
- },
- "require-dev": {
- "bamarni/composer-bin-plugin": "^1.8.1",
- "http-interop/http-factory-tests": "^0.9",
- "phpunit/phpunit": "^8.5.29 || ^9.5.23"
- },
- "suggest": {
- "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
- },
- "type": "library",
- "extra": {
- "bamarni-bin": {
- "bin-links": true,
- "forward-command": false
- },
- "branch-alias": {
- "dev-master": "2.4-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "GuzzleHttp\\Psr7\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Graham Campbell",
- "email": "hello@gjcampbell.co.uk",
- "homepage": "https://github.com/GrahamCampbell"
- },
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- },
- {
- "name": "George Mponos",
- "email": "gmponos@gmail.com",
- "homepage": "https://github.com/gmponos"
- },
- {
- "name": "Tobias Nyholm",
- "email": "tobias.nyholm@gmail.com",
- "homepage": "https://github.com/Nyholm"
- },
- {
- "name": "Márk Sági-Kazár",
- "email": "mark.sagikazar@gmail.com",
- "homepage": "https://github.com/sagikazarmark"
- },
- {
- "name": "Tobias Schultze",
- "email": "webmaster@tubo-world.de",
- "homepage": "https://github.com/Tobion"
- },
- {
- "name": "Márk Sági-Kazár",
- "email": "mark.sagikazar@gmail.com",
- "homepage": "https://sagikazarmark.hu"
- }
- ],
- "description": "PSR-7 message implementation that also provides common utility methods",
- "keywords": [
- "http",
- "message",
- "psr-7",
- "request",
- "response",
- "stream",
- "uri",
- "url"
- ],
- "support": {
- "issues": "https://github.com/guzzle/psr7/issues",
- "source": "https://github.com/guzzle/psr7/tree/2.4.4"
- },
- "funding": [
- {
- "url": "https://github.com/GrahamCampbell",
- "type": "github"
- },
- {
- "url": "https://github.com/Nyholm",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
- "type": "tidelift"
- }
- ],
- "time": "2023-03-09T13:19:02+00:00"
- },
- {
- "name": "mailjet/mailjet-apiv3-php",
- "version": "v1.5.8",
- "source": {
- "type": "git",
- "url": "https://github.com/mailjet/mailjet-apiv3-php.git",
- "reference": "747518ce0eebf64d27e9903441a255c85472a139"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/mailjet/mailjet-apiv3-php/zipball/747518ce0eebf64d27e9903441a255c85472a139",
- "reference": "747518ce0eebf64d27e9903441a255c85472a139",
- "shasum": ""
- },
- "require": {
- "ext-json": "*",
- "guzzlehttp/guzzle": "^7.4.4",
- "php": "^7.2|^8.0",
- "psr/http-client": "^1.0"
+ "ext-mbstring": "*",
+ "php": ">=5.3.0"
},
"require-dev": {
- "mockery/mockery": "^1.4",
- "php-coveralls/php-coveralls": "^2.0",
- "phpunit/phpunit": "^8|^9"
+ "phpunit/phpunit": "^4.8.35"
},
"type": "library",
"autoload": {
"psr-0": {
- "Mailjet": "src/"
+ "Parsedown": ""
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -374,25 +39,22 @@
],
"authors": [
{
- "name": "Mailjet",
- "email": "dev@mailjet.com",
- "homepage": "https://dev.mailjet.com"
+ "name": "Emanuil Rusev",
+ "email": "hello@erusev.com",
+ "homepage": "http://erusev.com"
}
],
- "description": "PHP wrapper for the Mailjet API",
- "homepage": "https://github.com/mailjet/mailjet-apiv3-php/",
+ "description": "Parser for Markdown.",
+ "homepage": "http://parsedown.org",
"keywords": [
- "Mailjet",
- "api",
- "email",
- "php",
- "v3"
+ "markdown",
+ "parser"
],
"support": {
- "issues": "https://github.com/mailjet/mailjet-apiv3-php/issues",
- "source": "https://github.com/mailjet/mailjet-apiv3-php/tree/v1.5.8"
+ "issues": "https://github.com/erusev/parsedown/issues",
+ "source": "https://github.com/erusev/parsedown/tree/1.7.x"
},
- "time": "2022-10-15T16:24:08+00:00"
+ "time": "2019-12-30T22:54:17+00:00"
},
{
"name": "phpmailer/phpmailer",
@@ -473,277 +135,6 @@
}
],
"time": "2023-03-06T14:43:22+00:00"
- },
- {
- "name": "psr/http-client",
- "version": "1.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/http-client.git",
- "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
- "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
- "shasum": ""
- },
- "require": {
- "php": "^7.0 || ^8.0",
- "psr/http-message": "^1.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Http\\Client\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
- }
- ],
- "description": "Common interface for HTTP clients",
- "homepage": "https://github.com/php-fig/http-client",
- "keywords": [
- "http",
- "http-client",
- "psr",
- "psr-18"
- ],
- "support": {
- "source": "https://github.com/php-fig/http-client/tree/master"
- },
- "time": "2020-06-29T06:28:15+00:00"
- },
- {
- "name": "psr/http-factory",
- "version": "1.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/http-factory.git",
- "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
- "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
- "shasum": ""
- },
- "require": {
- "php": ">=7.0.0",
- "psr/http-message": "^1.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Http\\Message\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
- }
- ],
- "description": "Common interfaces for PSR-7 HTTP message factories",
- "keywords": [
- "factory",
- "http",
- "message",
- "psr",
- "psr-17",
- "psr-7",
- "request",
- "response"
- ],
- "support": {
- "source": "https://github.com/php-fig/http-factory/tree/master"
- },
- "time": "2019-04-30T12:38:16+00:00"
- },
- {
- "name": "psr/http-message",
- "version": "1.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/http-message.git",
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Http\\Message\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
- }
- ],
- "description": "Common interface for HTTP messages",
- "homepage": "https://github.com/php-fig/http-message",
- "keywords": [
- "http",
- "http-message",
- "psr",
- "psr-7",
- "request",
- "response"
- ],
- "support": {
- "source": "https://github.com/php-fig/http-message/tree/master"
- },
- "time": "2016-08-06T14:39:51+00:00"
- },
- {
- "name": "ralouphie/getallheaders",
- "version": "3.0.3",
- "source": {
- "type": "git",
- "url": "https://github.com/ralouphie/getallheaders.git",
- "reference": "120b605dfeb996808c31b6477290a714d356e822"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
- "reference": "120b605dfeb996808c31b6477290a714d356e822",
- "shasum": ""
- },
- "require": {
- "php": ">=5.6"
- },
- "require-dev": {
- "php-coveralls/php-coveralls": "^2.1",
- "phpunit/phpunit": "^5 || ^6.5"
- },
- "type": "library",
- "autoload": {
- "files": [
- "src/getallheaders.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Ralph Khattar",
- "email": "ralph.khattar@gmail.com"
- }
- ],
- "description": "A polyfill for getallheaders.",
- "support": {
- "issues": "https://github.com/ralouphie/getallheaders/issues",
- "source": "https://github.com/ralouphie/getallheaders/tree/develop"
- },
- "time": "2019-03-08T08:55:37+00:00"
- },
- {
- "name": "symfony/deprecation-contracts",
- "version": "v3.2.1",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/deprecation-contracts.git",
- "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
- "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "3.3-dev"
- },
- "thanks": {
- "name": "symfony/contracts",
- "url": "https://github.com/symfony/contracts"
- }
- },
- "autoload": {
- "files": [
- "function.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "A generic function and convention to trigger deprecation notices",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.1"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2023-03-01T10:25:55+00:00"
}
],
"packages-dev": [],
diff --git a/core/cli/cli-cache.php b/core/cli/cli-cache.php
new file mode 100644
index 0000000..57d8090
--- /dev/null
+++ b/core/cli/cli-cache.php
@@ -0,0 +1,65 @@
+#!/usr/local/bin/php
+<?php
+
+/** cli-cache
+ * regenerates/refreshes caches.
+ * ------------------------------------------------------
+ *
+ * The sctipt implements a micro-anom application
+ * that queries directry the project's models.
+ *
+ * Advantages vs curl-cache:
+ * ---
+ * + Runs out of the web/apache interface;
+ * + Has less requirements, uses less total resources;
+ * + Avoids the typical block/waiting/receiving delays;
+ * + (theoretically) it is a faster implementation
+ *
+ * ------------------------------------------------------
+ */
+$t0 = microtime(true); // time benchmark
+
+require_once 'micro/term_utilities.php'; // terminal colors
+
+echo textColor("\nInterface: ", NORMAL) . textColor(php_sapi_name(), GREEN). "\n";
+
+
+/** anom-Cli app initialization
+ * ------------------------------------------------------
+ */
+define('MINI_APP_BASE', __DIR__.'/');
+echo "Base directory is ". textColor(MINI_APP_BASE, GREEN) ."\n";
+
+require_once MINI_APP_BASE.'/micro/setup.php';
+echo "System is ready;\n";
+
+
+
+try {
+ # your code goes here ------------------------------------------------------
+
+
+ // Re-create category_products tree Cache
+ app\controllers\cli\CliContoller::cacheCategoriesTree();
+
+ $categories = app\controllers\cli\CliContoller::getCategories();
+
+
+ foreach($categories as $key => $category) {
+
+ echo textColor( textWidth($category['Title'], 72), NORMAL);
+ app\controllers\cli\CliContoller::cacheCategoryByUrl($category['FullFriendlyUrl']);
+ }
+
+ # end of script ------------------------------------------------------------
+
+} catch(Exception $e) { // Basic error handling
+ echo 'Caught exception: ', textColor($e->getMessage(), ERROR), "\n";
+ die();
+}
+
+
+$dt = number_format( microtime(true) - $t0 , 0) ."sec";
+
+// echo ending...
+echo textColor("\nOperation Completed {$dt}\n\n", NORMAL);
diff --git a/core/cli/curl-cache.php b/core/cli/curl-cache.php
new file mode 100755
index 0000000..6ab2e93
--- /dev/null
+++ b/core/cli/curl-cache.php
@@ -0,0 +1,155 @@
+#!/usr/local/bin/php
+<?php
+
+/** curl-cache
+ * regenerates/refreshes caches
+ * ------------------------------------------------------
+ *
+ * This scipt makes requests to the project's web API,
+ * These API calls SHOULD be impemented to cache some
+ * resource-expensive queries, so in result the script
+ * shall manage to create cache.
+ *
+ * NOTE:
+ * The script does not implement the anom framerork
+ * and it is provided for documentation puproses.
+ *
+ * ------------------------------------------------------
+ */
+
+// some defines and an into message
+// -----------------------------------------------------------------------------
+
+require_once 'micro/term_utilities.php'; // terminal utilites
+
+define('API_ROOT','http://127.0.0.1:8080/api/');
+
+define('BATCH_LENGTH', 3); // see notes later on the script
+
+
+
+echo "\033[32mInterface: ". php_sapi_name() ."\033[39m\n\n";
+
+$t0 = microtime(true);
+
+/** supplumentary functions (curl)
+ * -----------------------------------------------------------------------------
+ */
+
+/** single Curl get call
+ *
+ * @param $call (string): url that needs to be called
+ *
+ */
+function singleCurl($call) {
+ $cSRC = curl_init(); // create curl resource for SouRCe end-point
+ curl_setopt($cSRC, CURLOPT_URL, API_ROOT.$call); // set url
+ curl_setopt($cSRC, CURLOPT_RETURNTRANSFER, 1); //return the transfer as a string
+ $output = curl_exec($cSRC); // $output contains the output string in json format
+ curl_close($cSRC); // close curl resource to free up system resources
+
+ $json = json_decode( $output ); // decode json to php array
+
+ if (!$json->success) {
+ echo "\033[91mError reading " . $call ."\n\033[39m";
+ return false;
+ }
+
+ return $json;
+}
+
+/** multiple curl get calls
+ *
+ * @param $array: an array of urls to be called
+ *
+ */
+function multiCurl($array) {
+
+ $multiCurl = array(); // array of curl handlers
+ $result = array(); // data to be returned
+ $mh = curl_multi_init(); // multi handler
+ $module = array(); // array of module names / 1:1 to $result array
+
+ foreach ($array as $i => $category) {
+ $module[$i] = $category->ID; // guid (module name)
+ $fetchURL = API_ROOT .'url/'. $category->FullFriendlyUrl;
+ $multiCurl[$i] = curl_init();
+ curl_setopt($multiCurl[$i], CURLOPT_URL,$fetchURL);
+ curl_setopt($multiCurl[$i], CURLOPT_HEADER,0);
+ curl_setopt($multiCurl[$i], CURLOPT_RETURNTRANSFER,1);
+ curl_multi_add_handle($mh, $multiCurl[$i]);
+ }
+
+ $index=null;
+
+ do {
+ curl_multi_exec($mh,$index);
+ } while($index > 0);
+
+ foreach($multiCurl as $k => $ch) {
+ $result[$k] = curl_multi_getcontent($ch);
+ curl_multi_remove_handle($mh, $ch);
+ }
+ curl_multi_close($mh); // close multi-curl
+}
+
+// force printing string with specified length
+function forceLen($str, $len = 72) {
+ $space = " ";
+ for($i = 0 ; $i<$len ; $i++) $space .= ".";
+ return mb_substr($str.$space, 0, $len-1) ." ";
+}
+
+
+/** main procedure
+ * -----------------------------------------------------------------------------
+ */
+
+echo "\033[39mReading Tree of product categories...\n";
+$tree = singleCurl('tree'); // ask for categories tree
+
+if ($tree !==false) echo "\033[32mCategories tree is cached\033[39m\n\n";
+
+$categories = singleCurl('category');
+
+// request every category to create cache if not exist
+// send requests in small batches to avoid enormous server-stress
+echo "\033[39mRequesting re-Cache for every category\033[39m\n";
+echo "\033[33mPlease Wait...\n\n";
+
+$buffer = []; // buffer array
+$counter = 0; // counter to track items in buffer
+foreach($categories->result as $category) {
+
+ echo "\033[39m". forceLen($category->Title) ."\033[33m"."Sent.\n\033[39m";
+
+ $counter++;
+
+ // try several batch lengths to establish the ideal one that produces
+ // results in a smooth quite fase rthm, without stressing the server;
+ // so that visitors can navigate the production site white the script
+ // is running;
+ // for my testing this number is 3-5. I set the cou 3 items give fast results without stressing the server
+ // so "if ($counter > 2) { ... " is the smoothest option
+ if ($counter > 2) {
+ multiCurl($buffer);
+ $counter = 0;
+ $buffer = [];
+ }
+
+ $buffer[] = $category;
+
+}
+
+multiCurl($buffer); // run once more for the last non-filled buffer
+
+$dt = number_format( microtime(true) - $t0 , 1) ."sec";
+
+// echo ending...
+echo "\n\033[32mOperation Completed \033[39m({$dt})\n\n";
+echo "\033[39m"; // back to default color;
+
+
+// check
+// http://www.idein.it/joomla/14-docker-php-apache-with-crontab
+?> \ No newline at end of file
diff --git a/core/cli/info.md b/core/cli/info.md
new file mode 100644
index 0000000..39f8c11
--- /dev/null
+++ b/core/cli/info.md
@@ -0,0 +1,23 @@
+# cli
+
+This section is used to setup an anom micro-framework for the cli-interface.
+The cli interface is commonly used to support and optimize the whole app.
+
+A cli script may run manualy, for example using...
+
+ php cli-cache.php
+
+although...
+
+it is recommended to run periodically using the cron service:
+
+ 15 * * * * php path/to/cli-cache.php
+
+or ...
+
+when a docker instanse of the project fires up; for example including
+the following line of code inside the docker/bin/docker-entrypoint.sh
+(runs the script after 5 minutes delay to make sure that the instance
+is up and running)
+
+ at -f /var/www/core/cli/refresh-cache.php -t now +5 minutes
diff --git a/docker/config/composer-naked.json b/docker/config/composer-naked.json
index 7e0bf82..171c35e 100644
--- a/docker/config/composer-naked.json
+++ b/docker/config/composer-naked.json
@@ -1,6 +1,7 @@
{
"require": {
- "phpmailer/phpmailer": "^6.8"
+ "phpmailer/phpmailer": "^6.8",
+ "erusev/parsedown": "^1.7"
},
"autoload": {
"classmap": [
diff --git a/docker/config/composer-redis.json b/docker/config/composer-redis.json
index 606c658..facb782 100644
--- a/docker/config/composer-redis.json
+++ b/docker/config/composer-redis.json
@@ -1,6 +1,8 @@
{
"require": {
- "predis/predis": "^2.0"
+ "predis/predis": "^2.0",
+ "phpmailer/phpmailer": "^6.8",
+ "erusev/parsedown": "^1.7"
},
"autoload": {
"classmap": [
diff --git a/public/app/config/.gitkeep b/public/app/config/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/public/app/config/.gitkeep
diff --git a/public/app/controllers/.gitkeep b/public/app/controllers/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/public/app/controllers/.gitkeep
diff --git a/public/app/controllers/Auth.php b/public/app/controllers/Auth.php
index 0570a5e..8af7513 100644
--- a/public/app/controllers/Auth.php
+++ b/public/app/controllers/Auth.php
@@ -180,7 +180,11 @@ class Auth {
}
-
+ /** is_connected
+ * checks if the user is connected
+ *
+ * @return true|false
+ */
public static function is_connected()
{
$manager = new Classroom_manager();
@@ -193,13 +197,17 @@ class Auth {
return $user;
} else {
- echo 'user is not connected';
+ // user is not connected;
return false;
}
}
-
+ /** logout
+ *
+ * performs a secure logout;
+ * regenerates session; deletes cookies;
+ */
public static function logout()
{
$userManager = new Classroom_manager();
@@ -232,7 +240,7 @@ class Auth {
return true; // permision 0 is always granted
}
- if ($user = $this->is_connected() === flase) { // if not connected
+ if ($user = self::is_connected() === false) { // if not connected
return false; // then no other permition is granted
}
@@ -340,6 +348,18 @@ class Auth {
}
+ /** hasValidRole
+ * like allowRoles() but dowes not stop execution
+ *
+ * @return true|false
+ */
+ public static function hasValidRole($allowed)
+ {
+ $manager = new Classroom_manager();
+ return ($manager->isGranted($allowed));
+ }
+
+
public static function in_admin_group()
{
$manager = new Classroom_manager();
diff --git a/public/app/controllers/admin/Course_admin.php b/public/app/controllers/admin/Course_admin.php
index c2e06f2..72ddc79 100644
--- a/public/app/controllers/admin/Course_admin.php
+++ b/public/app/controllers/admin/Course_admin.php
@@ -213,8 +213,10 @@ class Course_admin {
]
);
- // update media's privileges
- self::update_medias_privileges($post['media'], $post['privilege_id']);
+ if (isset($post['media'])) {
+ // update media's privileges
+ self::update_medias_privileges($post['media'], $post['privilege_id']);
+ }
// remove all old lesson's links to media files
Registry::use('database')->runQuery(
@@ -222,8 +224,10 @@ class Course_admin {
[ ':lesson' => $post['id'] ]
);
- // update lesson's media files
- self::create_medias_for_lesson($post['media'], $post['id'], $post['privilege_id']);
+ if (isset($post['media'])) {
+ // update lesson's media files
+ self::create_medias_for_lesson($post['media'], $post['id'], $post['privilege_id']);
+ }
return true;
}
diff --git a/public/app/controllers/cli/CliContoller.php b/public/app/controllers/cli/CliContoller.php
index 310e2ae..4549b50 100644
--- a/public/app/controllers/cli/CliContoller.php
+++ b/public/app/controllers/cli/CliContoller.php
@@ -4,9 +4,11 @@ namespace app\controllers\cli;
/** CliContoller
*
- * Re-generate cashes of commonly used entities
- * like: product categories and trendy products
- * (proxy calls make use of PROXY_IGNORE_CACHE)
+ * A typical cli constoller; this one is used to
+ * re-generate cashes of commonly used entities
+ * with expensive queries like (ex:) categories;
+ *
+ * Proxy calls make use of PROXY_IGNORE_CACHE
*
* CliController calls Model methods who create
* cashed data with the exact same arguments as
@@ -14,8 +16,8 @@ namespace app\controllers\cli;
* the Model::method(arguments) triplete creates
* the same keys as via the web interface.
*
- * NOTE: Only Cli interface is allowed
- * [if (php_sapi_name() != 'cli') return false;]
+ * NOTE: Only Cli interface is allowed¨
+ * `if (php_sapi_name() != 'cli') return false;`
*
* The Cli-interfaced script can run manualy or
* (most usual scenario) scheduled via a cron job
@@ -37,12 +39,12 @@ class CliContoller
if (php_sapi_name() != 'cli') return false;
# PROXY call:
- # MARKET \ ProductCategories_model::tree():
+ # CMS \ Course_model::courses_struct():
# + Refresh Cache
# --------------------------------------
echo textColor("Creating category_products tree Cache ... ", \NORMAL);
$reply = proxy(
- [\app\models\market\ProductCategories_model::class, 'tree'],
+ [\app\models\cms\Course_model::class, 'courses_struct'],
[], \CACHE_ROOT_TTL,
\PROXY_IGNORE_CACHE
);
@@ -50,36 +52,4 @@ class CliContoller
}
-
- public static function getProductCategories()
- {
- return \Registry::use('database')->runQuery(
- "SELECT * FROM product_categories",
- []
- );
- }
-
-
-
- /** (re-) cacheCategoryByUrl( url )
- * regenerate cache of a category_product
- * by category's friendly url
- * @param $url (string): the category's friendly url
- */
- public static function cacheCategoryByUrl(string $url)
- {
- // Only Cli interface is allowed
- if (php_sapi_name() != 'cli') return false;
-
- # PROXY call:
- # MARKET \ ProductCategories_model::tree():
- # + Refresh Cache
- # --------------------------------------
- $reply = proxy(
- [\app\models\market\ProductCategories_model::class, 'categoryFromUrl'],
- [ $url ], \CACHE_CATEGORY_TTL,
- \PROXY_IGNORE_CACHE
- );
- echo ($reply == false) ? textColor("Failed\n", \FAIL) : textColor("Done!\n", \SUCCESS);
- }
} \ No newline at end of file
diff --git a/public/app/controllers/cms/Course.php b/public/app/controllers/cms/Course.php
index 7e53d3a..0edc832 100644
--- a/public/app/controllers/cms/Course.php
+++ b/public/app/controllers/cms/Course.php
@@ -21,7 +21,7 @@ class Course {
* shortcut method for checking access authorization
*
* returns true if user belogns to the admin group
- * or has the specified permition/privilege
+ * OR has the specified permition/privilege
*
* @param $privilege_id (int)
*
@@ -35,7 +35,7 @@ class Course {
{
return (
Auth::in_admin_group()
- || Auth::has_Permition([ $privilege_id ])
+ || Auth::hasPermition([ $privilege_id ])
);
}
@@ -99,24 +99,32 @@ class Course {
* -------------------------------------------------------------------------
*/
+ /** course
+ * prepare and render the course view
+ *
+ * @param $id : course id
+ */
+ public static function course($id)
+ {
+ $id = intval($id); // course id
- public static function course($id)
- {
+ // collect all data needed for course view
+ // --- -- -- - - -
$cache = Cache_service::courses_struct();
$tree = $cache['tree'];
$breadcrumbs = $cache['breadcrumbs'];
$lessons = Course_model::lessons_of_course(intval($id));
- $id = intval($id);
-
- // print_r($breadcrumbs); die();
// find parent_ids of current category (to open the menu tree)
+ // ---
$course_path = [];
foreach($breadcrumbs[$id]['parents'] as $key => $parent) {
$course_path[] = intval($parent['id']);
}
- $course_path[] = intval($id);
+ $course_path[] = $id;
+ // then Render
+ // --- -- -- - - -
Render::view('templates/course', [
'id' => $id,
'title' => $breadcrumbs[ $id ]['rec']['label'],
@@ -125,19 +133,73 @@ class Course {
'lessons' => $lessons,
'course_path' => $course_path
]);
- }
+ }
+ /** LESSONS
+ * ------------------------------------------------------------------------
+ */
+ /** lesson
+ *
+ * check if user is authorized to view the content;
+ * if so, prepare and render the lesson view
+ *
+ * @param $id : lesson id
+ */
+ public static function lesson($id)
+ {
+ $id = intval($id); // lesson id
- /** LESSONS
- * ------------------------------------------------------------------------
- */
+ $lesson = Course_model::lesson($id); // get lesson
+ $course_id = $lesson['course_id']; // get course id
+ $pri_id = $lesson['privilege_id']; // privilege needed
+ if (self::is_admin_or_permited($pri_id)) {
+ // collect all data needed for course view
+ // --- -- -- - - -
+ $cache = Cache_service::courses_struct();
+ $tree = $cache['tree'];
+ $breadcrumbs = $cache['breadcrumbs'];
+
+ // find parent_ids of current category (to open the menu tree)
+ // ---
+ $course_path = [];
+ foreach($breadcrumbs[$course_id]['parents'] as $key => $parent) {
+ $course_path[] = intval($parent['id']);
+ }
+ $course_path[] = intval($course_id);
+
+ // then Render
+ // --- -- -- - - -
+ Render::view('templates/lesson', [
+ // main content
+ 'id' => $id,
+ 'course_id' => $course_id,
+ 'title' => $lesson['title'],
+ 'lesson' => $lesson,
+ // needed for side panel and breadcrunbs
+ 'categories' => $tree,
+ 'breadcrumbs' => $breadcrumbs,
+ 'course_path' => $course_path
+ ]);
+
+ } else { // user is not authorized
+ Render::view('error/general', [
+ 'title' => 'Δεν έχετε πρόσβαση',
+ 'message' => 'Θα πρέπει να αγοράσετε το πακέτο πρόσβασης '
+ . $pri_id
+ .' για να δείτε το περιεχόμενο!
+ <br><br>
+ Αγόρασε τώρα το <button class="btn">πακέτο πρόσβασης '. $pri_id .'</button>'
+ ]);
+ }
+
+ }
diff --git a/public/app/extends/.gitkeep b/public/app/extends/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/public/app/extends/.gitkeep
diff --git a/public/app/extends/Cache_service.php b/public/app/extends/Cache_service.php
index e44cc8e..9aac1d0 100644
--- a/public/app/extends/Cache_service.php
+++ b/public/app/extends/Cache_service.php
@@ -10,15 +10,19 @@ use app\models\admin\Privilege_model;
* class that gathers common source-expensive queries
* and helps for performance optimization
*
+ * when forcing cache creation the following option is used:
+ * $options = PROXY_IGNORE_CACHE
+ *
*/
class Cache_service
{
public static function courses_struct( $options = 0 )
{
- return proxy( // cache-get categories
+ return proxy( // cache-get courses
[\app\models\cms\Course_model::class, 'courses_struct'],
- [], CACHE_ROOT_TTL, $options
+ [], CACHE_ROOT_TTL,
+ $options
);
}
@@ -26,7 +30,8 @@ class Cache_service
{
return proxy(
[\app\models\cms\Course_model::class, 'files'],
- [], CACHE_ROOT_TTL, $options
+ [], CACHE_ROOT_TTL,
+ $options
);
}
@@ -35,11 +40,10 @@ class Cache_service
{
return proxy(
[\app\models\admin\Privilege_model::class, 'privileges'],
- [], CACHE_ROOT_TTL, $options
+ [], CACHE_ROOT_TTL,
+ $options
);
}
-
-
} \ No newline at end of file
diff --git a/public/app/models/.gitkeep b/public/app/models/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/public/app/models/.gitkeep
diff --git a/public/app/models/cms/Course_model.php b/public/app/models/cms/Course_model.php
index d8a8a0e..6378226 100644
--- a/public/app/models/cms/Course_model.php
+++ b/public/app/models/cms/Course_model.php
@@ -244,9 +244,8 @@ class Course_model {
/** lessons of course
*
- * @param $course_id
+ * @param $id (int) : course_id
*/
-
public static function lessons_of_course($id)
{
// TODO: order results in some way
@@ -254,11 +253,28 @@ class Course_model {
return Registry::use('database')->runQuery(
"SELECT lesson.*, lesson_privilege.privilege_id FROM lesson
LEFT JOIN lesson_privilege ON lesson_privilege.lesson_id = lesson.id
- WHERE lesson.status = 1 AND lesson.course_id = :id",
+ WHERE lesson.status = 1 AND lesson.course_id = :id
+ ORDER BY lesson_privilege.privilege_id ASC",
[':id' => $id]
);
}
+ /** lesson
+ *
+ * @param $id (int) : lesson id
+ */
+ public static function lesson($id)
+ {
+ // TODO: order results in some way
+
+ return Registry::use('database')->query(
+ "SELECT lesson.*, lesson_privilege.privilege_id FROM lesson
+ LEFT JOIN lesson_privilege ON lesson_privilege.lesson_id = lesson.id
+ WHERE lesson.status = 1 AND lesson.id = :id",
+ [':id' => $id]
+ )->getFirst();
+ }
+
/** files
diff --git a/public/app/routes/.gitkeep b/public/app/routes/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/public/app/routes/.gitkeep
diff --git a/public/app/routes/backend.php b/public/app/routes/backend.php
index 475f52b..ed02295 100644
--- a/public/app/routes/backend.php
+++ b/public/app/routes/backend.php
@@ -5,17 +5,25 @@ use app\controllers\admin\Course_admin;
use app\models\admin\Privilege_model;
use app\extends\Cache_service;
+
+/** admin pages
+ * -----------------------------------------------------------------------------
+ * NOTE:
+ * All adminitration routes MUST INCLUDE an Auth::allowRoles() check
+ */
+
// admin panel
-// ---
-Route::add('/admin', function () {
+////////////////////////////////////////////////////////////////////////////////
+
+Route::add('/admin', function () { // admin panel
Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
Render::view('admin/skeleton', [
'title' => 'Διαχείριση Classroom',
'action' => 'panel',
]);
});
-Route::add('/admin/panel', function () {
- Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
+Route::add('/admin/panel', function () { // admin panel #2
+ Auth::allowRoles([1, 2, 3]);
Render::view('admin/skeleton', [
'title' => 'Διαχείριση Classroom',
'action' => 'panel',
@@ -24,8 +32,9 @@ Route::add('/admin/panel', function () {
// admin lessons
-// ---
-Route::add('/admin/lessons', function () {
+////////////////////////////////////////////////////////////////////////////////
+
+Route::add('/admin/lessons', function () { // request admin-lessons page
Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
Render::view('admin/skeleton', [
'title' => 'Διαχείριση Μαθημάτων',
@@ -34,12 +43,11 @@ Route::add('/admin/lessons', function () {
});
-// admin categories (=courses) /////////////////////////////////////////////////
-// -----------------------------------------------------------------------------
+// admin categories (=courses)
+////////////////////////////////////////////////////////////////////////////////
-// manage categories page
-// ---
-Route::add('/admin/categories', function () {
+
+Route::add('/admin/categories', function () { // manage categories page
Auth::allowRoles([1, 2, 3]);
Render::view('admin/skeleton', [
'title' => 'Διαχείριση Κεφαλαίων',
@@ -48,37 +56,29 @@ Route::add('/admin/categories', function () {
});
-// ajax: get all categories (courses; with breadcrumbs)
-// ---
-Route::add('/admin/api/categories', function () {
+
+Route::add('/admin/api/categories', function () { // ajax: get all courses; with breadcrumbs
Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
Course_admin::breadcrumbs();
});
-
-// ajax: add new category (course)
-// ---
-Route::add('/admin/api/categories/add', function () {
- Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
+Route::add('/admin/api/categories/add', function () { // ajax: add new category (course)
+ Auth::allowRoles([1, 2, 3]);
Course_admin::add_course();
}, 'post');
-// ajax: edit category (course)
-// ---
-Route::add('/admin/api/categories/update', function () {
- Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
- Course_admin::update_course();
- },
- 'post'
-);
+Route::add('/admin/api/categories/update', function () { // ajax: edit category (course)
+ Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
+ Course_admin::update_course();
+},
+'post');
-// admin privileges ////////////////////////////////////////////////////////////
-// -----------------------------------------------------------------------------
+// admin privileges
+////////////////////////////////////////////////////////////////////////////////
-// manage privileges page
-// ---
-Route::add('/admin/privileges', function () {
+
+Route::add('/admin/privileges', function () { // manage privileges page
Auth::allowRoles([1, 2, 3]);
Render::view('admin/skeleton', [
'title' => 'Διαχείριση Δικαιωμάτων Πρόσβασης',
@@ -88,7 +88,6 @@ Route::add('/admin/privileges', function () {
// ajax: get all privileges (courses; with breadcrumbs)
// use proxy (cache results); send as json
-// ---
Route::add('/admin/api/privileges', function () {
Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
Render::json( Cache_service::privileges_hierarchy() );
@@ -100,13 +99,12 @@ Route::add('/admin/api/privileges', function () {
-// admin lesson ////////////////////////////////////////////////////////////////
-// -----------------------------------------------------------------------------
+// admin lesson
+////////////////////////////////////////////////////////////////////////////////
-// new lesson
// ---
-Route::add('/admin/edit_lesson', function () {
+Route::add('/admin/edit_lesson', function () { // new lesson form
Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
Render::view('admin/skeleton', [
'title' => 'Νέο Μάθημα',
@@ -114,10 +112,8 @@ Route::add('/admin/edit_lesson', function () {
]);
});
-// edit lesson (give lesson-id)
-// ---
-Route::add('/admin/edit_lesson/([0-9]*)', function ($id) {
- Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
+Route::add('/admin/edit_lesson/([0-9]*)', function ($id) { // edit lesson form
+ Auth::allowRoles([1, 2, 3]);
Render::view('admin/skeleton', [
'title' => 'Επεξεργασία Μαθήματος',
'action' => 'edit_lesson',
@@ -125,39 +121,35 @@ Route::add('/admin/edit_lesson/([0-9]*)', function ($id) {
]);
});
-// ajax: get lesson
-// ---
-Route::add('/admin/api/lesson/([0-9]*)', function ($id) {
+
+Route::add('/admin/api/lesson/([0-9]*)', function ($id) { // ajax: get lesson
Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
Course_admin::get_lesson($id);
});
-// ajax: add lesson
-// ---
-Route::add('/admin/api/lesson/add', function () {
+
+Route::add('/admin/api/lesson/add', function () { // ajax: add lesson
Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
Course_admin::add_lesson();
}, 'post');
-// ajax: update lesson
-// ---
-Route::add('/admin/api/lesson/update', function () {
+
+Route::add('/admin/api/lesson/update', function () { // ajax: update lesson
Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
Course_admin::update_lesson();
}, 'post');
-// ajax: get all lessons
-// ---
-Route::add('/admin/api/lessons', function () {
+
+Route::add('/admin/api/lessons', function () { // ajax: get all lessons
Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
Course_admin::all_lessons();
});
-// admin files /////////////////////////////////////////////////////////////////
+// admin files
////////////////////////////////////////////////////////////////////////////////
-Route::add('/admin/files', function () {
+Route::add('/admin/files', function () { // admin-files panel
Auth::allowRoles([1, 2, 3]);
Render::view('admin/skeleton', [
'title' => 'Διαχείριση Μέσων (media)',
@@ -165,10 +157,9 @@ Route::add('/admin/files', function () {
]);
});
-// ajax: get lesson
-// ---
-Route::add('/admin/api/files', function () {
- Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
+
+Route::add('/admin/api/files', function () { // ajax: get lesson
+ Auth::allowRoles([1, 2, 3]);
Render::json(Course_admin::files());
});
@@ -179,7 +170,3 @@ Route::add('/admin/api/file_upload', function () {
Render::json(Course_admin::upload_file());
}, 'post');
-
-
-
-
diff --git a/public/app/routes/frontend.php b/public/app/routes/frontend.php
index f9e74db..33fe401 100644
--- a/public/app/routes/frontend.php
+++ b/public/app/routes/frontend.php
@@ -6,22 +6,45 @@ use app\controllers\cms\Course;
use app\models\cms\Course_model;
use app\extends\Cache_service;
+
// Home/Welcome
-// ---
-Route::add('/', function() { // echo 'Welcome!'; });
- Render::view('welcome', [ // cache categories (while retrieving)
+////////////////////////////////////////////////////////////////////////////////
+
+Route::add('/', function() {
+ Render::view('welcome', [
'categories' => Cache_service::courses_struct()['tree']
]);
- // header('Location: /some/default/url', true, 302);
+ // need redirect?... header('Location: /some/default/url', true, 302);
});
-// Error Pages
-// ---
-Route::notFound( function() {
+// Error pages
+////////////////////////////////////////////////////////////////////////////////
+
+Route::notFound( function() { // 404 error page
header("HTTP/1.0 404 Not Found");
Render::view('error/404', ['message' => 'nobody knows it (but you got a secret smile;)']);
-}); // 404
+});
+
+
+
+// Common content
+////////////////////////////////////////////////////////////////////////////////
+
+
+Route::add('/course/([0-9]*)', // request course by course-id
+ function($id) { Course::course($id); }
+);
+
+Route::add('/lesson/([0-9]*)', // request lesson by lesson-id
+ function($id) { Course::lesson($id); }
+);
+
+Route::add('/serve/file/([0-9a-zA-Z-_\.\/]*)', // serve file by path
+ function ($path) { Course::serve_file($path); } // (also ?type= is sent)
+);
+
+
@@ -42,36 +65,8 @@ Route::notFound( function() {
-// Resolve urls
-// --- -- -- - - -
-Route::add('/course/([0-9]*)',
- function($id) { Course::course($id); }
-);
-
-Route::add('/lesson/([0-9a-f]*)/([0-9a-zA-Z-_]*)',
- function($ticket, $lesson) { Lesson::show([$lesson, $ticket]); }
-);
-
-Route::add('/media/([0-9a-f]*)/([0-9a-zA-Z-_]*)/([0-9]*)/',
- function($ticket, $type, $id) { Media::serve([$type, $id, $ticket]); }
-);
-
-
-// 4-th level paths belong to products
-// ---
-Route::add('/about/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)',
- function($a, $b, $c) { Page::show([$a, $b, $c]); }
-);
-
-
-// serve file
-// ---
-Route::add('/serve/file/([0-9a-zA-Z-_\.\/]*)', function ($path) {
- Course::serve_file($path);
-});
-
-/** URL-format Proposal:
+/** URL-format Proposals and common Route regex solutions
* -----------------------------------------------------------------------------
*
* Page (almost-static content):
@@ -88,80 +83,82 @@ Route::add('/serve/file/([0-9a-zA-Z-_\.\/]*)', function ($path) {
*
* Category
* /{category}/[ {subcategory}[ /{group}]]
-Route::add('/([0-9a-zA-Z-_]*)', function($a) { Category::url([$a]); };
-Route::add('/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)', function($a, $b) { Category::url([$a, $b]); });
-Route::add('/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)', function($a, $b, $c) { Category::url([$a, $b, $c]); });
- * -----------------------------------------------------------------------------
- */
-
+# Route::add('/([0-9a-zA-Z-_]*)', function($a) { Category::url([$a]); };
+# Route::add('/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)', function($a, $b) { Category::url([$a, $b]); });
+# Route::add('/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)', function($a, $b, $c) { Category::url([$a, $b, $c]); });
+ *
+ * othet routes used in some user-cases
-/* EXAMPLES (use it for brainsrtorming)
+# Route::add('/lesson/([0-9a-f]*)/([0-9a-zA-Z-_]*)',
+# function($ticket, $lesson) { Lesson::show([$lesson, $ticket]); }
+# );
+#
+# Route::add('/media/([0-9a-f]*)/([0-9a-zA-Z-_]*)/([0-9]*)/',
+# function($ticket, $type, $id) { Media::serve([$type, $id, $ticket]); }
+# );
+ *
+ * 4-th level paths belong to products
+# Route::add('/about/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)',
+# function($a, $b, $c) { Page::show([$a, $b, $c]); }
+# );
+ *
+ *
+ * OTHER EXAMPLES (use it for brainsrtorming)
* -----------------------------------------------------------------------------
*
- // Typical Use
- // ---
- Route::add('/art', function() { Art::blah(); });
- Route::add('/art/db', function() { Art::fromDatabase(); });
- Route::add('/art/([0-9]*)', function($id) { Art::getInfo($id); });
-
-
- // Get-Post route example
- // ---
- Route::add('/contact-form', function() {
- echo '<form method="post"><input type="text" name="test" /><input type="submit" value="send" /></form>';
- }, 'get');
+ *
+# // Typical Use
+# // ---
+# Route::add('/art', function() { Art::blah(); });
+# Route::add('/art/db', function() { Art::fromDatabase(); });
+# Route::add('/art/([0-9]*)', function($id) { Art::getInfo($id); });
+ *
+ * Get-Post route example
+# Route::add('/contact-form', function() {
+# echo '<form method="post"><input type="text" name="test" /><input type="submit" value="send" /></form>';
+# }, 'get');
Route::add('/contact-form', function() {
echo 'Hey! The form has been sent:<br/>'; print_r($_POST);
}, 'post');
-
-
- // Accept number as parameter
- // ---
- Route::add('/foo/([0-9]*)/bar', function($var1) {
- // echo $var1.' is a number!';
+ *
+ * Accept number as parameter
+# Route::add('/foo/([0-9]*)/bar', function($var1) {
+# // echo $var1.' is a number!';
echo "{$var1} is a number!";
- });
-
-
- // About pages
- // ---
- Route::add('/about/([0-9a-zA-Z-_]*)', function($page) {
- InfoPage::render('about/'.page);
- });
-
-
- // handle a request like: /foo/123/bar/3254-lefki-zaxari-marata-1kg
- // where first-numeric-part of last-uri-section (3254) is the product number
- // ---
- Route::add('/foo/([0-9]*)/bar/([0-9]*)-([0-9a-zA-Z-_]*)', function($num, $id, $name) {
- echo $num .' is some nomber, id = '. $id .' and label = '. $name;
- });
-
-
- // handle a request like: /zaxares-glykantika/lefki-zaxari-year-2022-45678
- // where last-numeric-part of last-uri-section (45678) is the product number
- // ---
- Route::add('/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)-([0-9]*)',
- function($category, $subcategory, $group, $label, $id) {
- Shop::product([$$category, $subcategory, $group, $label], $id);
- });
-
-
- // last chance to resolve (some friendly url)
- // ---
- Route::add('/([0-9a-zA-Z-_]*)', function($a) { Resolve::uri([$a]); });
- Route::add('/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)', function($a, $b) { Resolve::uri([$a, $b]); });
- Route::add('/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)', function($a, $b, $c) { Resolve::uri([$a, $b, $c]); });
-
-
- // Product page
- // handle a request like: /pantopoleio/zaxares/lefki-zaxari/lefki-zaxari-year-2022-45678
- // where last-numeric-part of last-uri-section (45678) is the product number
- // ---
- Route::add('/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)-([0-9]*)',
- function($category, $subcategory, $group, $label, $id) {
- Shop::product([$$category, $subcategory, $group, $label], $id);
- });
-* ------------------------------------------------------------------------------
-*/
+# });
+ *
+ * About pages
+# Route::add('/about/([0-9a-zA-Z-_]*)', function($page) {
+# InfoPage::render('about/'.page);
+# });
+ *
+ * handle a request like: /foo/123/bar/3254-lefki-zaxari-marata-1kg
+ * where first-numeric-part of last-uri-section (3254) is the product number
+# Route::add('/foo/([0-9]*)/bar/([0-9]*)-([0-9a-zA-Z-_]*)', function($num, $id, $name) {
+# echo $num .' is some nomber, id = '. $id .' and label = '. $name;
+# });
+ *
+ * handle a request like: /zaxares-glykantika/lefki-zaxari-year-2022-45678
+ * where last-numeric-part of last-uri-section (45678) is the product number
+# Route::add('/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)-([0-9]*)',
+# function($category, $subcategory, $group, $label, $id) {
+# Shop::product([$$category, $subcategory, $group, $label], $id);
+# });
+ *
+ * last chance to resolve (some friendly url)
+# Route::add('/([0-9a-zA-Z-_]*)', function($a) { Resolve::uri([$a]); });
+# Route::add('/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)', function($a, $b) { Resolve::uri([$a, $b]); });
+# Route::add('/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)', function($a, $b, $c) { Resolve::uri([$a, $b, $c]); });
+ *
+ *
+ * Product page
+ * handle a request like: /pantopoleio/zaxares/lefki-zaxari/lefki-zaxari-year-2022-45678
+ * where last-numeric-part of last-uri-section (45678) is the product number
+# Route::add('/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)-([0-9]*)',
+# function($category, $subcategory, $group, $label, $id) {
+# Shop::product([$$category, $subcategory, $group, $label], $id);
+# });
+ *
+ * ------------------------------------------------------------------------------
+ */
diff --git a/public/app/views/.gitkeep b/public/app/views/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/public/app/views/.gitkeep
diff --git a/public/app/views/components/breadcrumbs.php b/public/app/views/components/breadcrumbs.php
index 90b4af9..59c0fca 100644
--- a/public/app/views/components/breadcrumbs.php
+++ b/public/app/views/components/breadcrumbs.php
@@ -9,8 +9,8 @@
* @param $parents : array of parent nodes
* -----------------------------------------------------------------------------
*/
-?>
+?>
<div class="breadcrumb">
<!-- home -->
<a href="/">Classroom</a>
diff --git a/public/app/views/components/lessons_list.php b/public/app/views/components/lessons_list.php
index 1c59164..46c1f7e 100644
--- a/public/app/views/components/lessons_list.php
+++ b/public/app/views/components/lessons_list.php
@@ -33,6 +33,10 @@
<a href="/lesson/<?=$post['id']?>"><?=$post['title']?></a>
</h3>
+ <?php if (in_array('level', $fieldset)) : ?>
+ <p class="getegory">(επίπεδο πρόσβασης <?=$post['privilege_id']?>)</p>
+ <?php endif; ?>
+
<?php if (in_array('category', $fieldset)) : ?>
<p class="category"><?=$post['course_id']?></p>
<?php endif; ?>
diff --git a/public/app/views/components/subcategories.php b/public/app/views/components/subcategories.php
index 58f53fa..5c05a94 100644
--- a/public/app/views/components/subcategories.php
+++ b/public/app/views/components/subcategories.php
@@ -2,7 +2,8 @@
<?php if ($breadcrumbs[ $id ]['childs'] != []) : ?>
- <h5>Υποκατηγορίες</h5>
+ <h5>Υποκεφάλαια</h5>
+
<div class="category-childs">
<?php foreach($breadcrumbs[ $id ]['childs'] as $key => $child) : ?>
diff --git a/public/app/views/components/top_bar.php b/public/app/views/components/top_bar.php
index 0e6e437..eaffe76 100644
--- a/public/app/views/components/top_bar.php
+++ b/public/app/views/components/top_bar.php
@@ -1,8 +1,31 @@
+<?php
+/** top bar
+ * -----------------------------------------------------------------------------
+ *
+ * rendrers breadcrumbs and user menu
+ *
+ * imported variables
+ * ---
+ * @param $id : category_id of last level
+ * @param $label : category title of last level
+ * @param $parents : array of parent nodes
+ * -----------------------------------------------------------------------------
+ */
+
+// initialize variables needed if not passed
+// (needed while requiring breadcrumbs)
+if (!isset($id)) {
+ $id = 0;
+ $label = "";
+ $parents = [];
+}
+
+?>
<div class="top-bar">
<?php // breadcrumbs
////////////////////////////////////////////////////////////////////////
- Render::template("components/breadcrumbs", [
+ Render::view("components/breadcrumbs", [
'id' => $id,
'label' => $label,
'parents' => $parents
diff --git a/public/app/views/error/404.php b/public/app/views/error/404.php
index 89c35cc..4bbf083 100644
--- a/public/app/views/error/404.php
+++ b/public/app/views/error/404.php
@@ -26,6 +26,7 @@
text-align: center; justify-center: center;
opacity: .33;
}
+ .btn { font-size: 18px; padding: 4px 12px; }
</style>
</head>
<body>
diff --git a/public/app/views/error/general.php b/public/app/views/error/general.php
index 74566a4..0a27e56 100644
--- a/public/app/views/error/general.php
+++ b/public/app/views/error/general.php
@@ -1,10 +1,19 @@
<?php
/** general message template
+ * -----------------------------------------------------------------------------
+ * renders an error with custom title and message
+ *
+ * passed values:
*
- * passed:
- * @var $title (string): page title
- * @var $message (string): message
+ * optional @var $title (string): title
+ * optional @var $message (string): message
+ *
+ * NOTE:
+ * if title and/or message are not passed, then defaults are used
+ *
+ * -----------------------------------------------------------------------------
*/
+
?><!DOCTYPE html>
<html lang="en">
<head>
@@ -39,6 +48,7 @@
opacity: .33;
font-size: .87em
}
+ .btn { font-size: 18px; padding: 4px 12px; }
</style>
</head>
<body>
diff --git a/public/app/views/templates/course.php b/public/app/views/templates/course.php
index 9d42297..39e177f 100644
--- a/public/app/views/templates/course.php
+++ b/public/app/views/templates/course.php
@@ -63,7 +63,7 @@
////////////////////////////////////////////////////
Render::view("components/lessons_list", [
'lessons' => $lessons,
- 'fieldset' => ['intro'] // ['intro', 'date']
+ 'fieldset' => ['intro', 'level'] // ['intro', 'date']
]);
?>
<?php endif; ?>
diff --git a/public/app/views/templates/lesson.php b/public/app/views/templates/lesson.php
new file mode 100644
index 0000000..3baafd0
--- /dev/null
+++ b/public/app/views/templates/lesson.php
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title><?=SITE_TITLE?> - <?=$title?></title>
+
+ <?php // header includes
+ ////////////////////////////////////////////////////////////////////////
+ Render::view('components/header_includes');
+ ?>
+
+</head>
+<body class="classroom">
+
+ <?php // top-bar
+ ////////////////////////////////////////////////////////////////////////
+ Render::view('components/top_bar', [
+ 'id' => $id,
+ 'label' => $breadcrumbs[ $course_id ]['rec']['label'],
+ 'parents' => $breadcrumbs[ $course_id ]['parents']
+ ]);
+ ?>
+
+
+<div class="main-content container">
+ <div class="row">
+
+ <div class="col col-md-5 col-lg-4 d-sm-none d-md-block side-bar">
+
+ <?php // tree of courses
+ ////////////////////////////////////////////////////////////////////////
+ Render::view('components/courses_menu', [
+ 'categories' => $categories,
+ 'open_path' => $course_path
+ ]);
+ ?>
+
+ </div>
+
+ <div class="col col-sm-12 col-md-7 col-lg-8 lesson-view">
+
+ <!-- Lesson Title -->
+ <h3>
+ <?=$title?>
+ </h3>
+
+ <!-- intro -->
+ <?php if ($lesson['intro'] != "") : ?>
+ <p class="intro"><?=$lesson['intro']?></p>
+ <?php endif; ?>
+
+ <!-- body -->
+ <div class="article-body">
+ <?php
+
+ $parsedown = new Parsedown();
+ echo $parsedown->text($lesson['body']);
+
+ ?>
+ </div>
+
+
+ </div>
+
+ </div>
+ </div>
+
+
+ <script src="/assets/js/classroom.js"></script>
+ <script src="/assets/js/lesson-features.js"></script>
+</body>
+</html>
diff --git a/public/assets/css/class.css b/public/assets/css/class.css
index a65bfa2..f132241 100644
--- a/public/assets/css/class.css
+++ b/public/assets/css/class.css
@@ -156,7 +156,7 @@
-.classroom .post img { max-width: 100%; }
+.classroom .lesson-view img { max-width: 100%; }
@@ -199,7 +199,7 @@
}
/* --- post: medias -- */
-
+/* DEPRICATED: not needed
.classroom .content--wrapper .medias {
padding: 2em 0 1em;
border-top: 1px solid var(--class-grey-background);
@@ -212,6 +212,7 @@
font-size: 12px;
color: #999;
}
+*/
/* --- post: tags --- */
@@ -308,18 +309,20 @@
-.classroom .post h2 { padding-bottom: 0; }
+.classroom .lesson-view h2 { padding-bottom: 0; font-size: 24px; }
+
+.classroom .lesson-view h2 span { float:right; margin-right: -3em;}
-.classroom .post h2 span { float:right; margin-right: -3em;}
+.classroom .lesson-view pre { padding: 1em; background: #f5f5f6;}
-.classroom .post .intro {
+.classroom .lesson-view .intro {
font-style: italic;
font-size: 18px;
color: var(--class-blue-dark);
padding-bottom: 1em;
}
-.classroom .post .post--date {
+.classroom .lesson-view .post--date {
padding: 0;
color: var(--class-blue);
}
diff --git a/public/assets/css/overides.css b/public/assets/css/overides.css
index e3d5e1b..c0f6bd9 100644
--- a/public/assets/css/overides.css
+++ b/public/assets/css/overides.css
@@ -128,4 +128,10 @@ ul.select2-results__options li { font-size: 14px; padding: 4px 8px; }
.admin-container .edit-post .post-media ul li:last-child { border-bottom: none ;}
.admin-container .edit-post .post-media ul li:hover { background: #eee; }
-.edit-post .post-media li .btn-xs { font-size: 14px; width: 24px; height: 24px; padding:0; } \ No newline at end of file
+.edit-post .post-media li .btn-xs { font-size: 14px; width: 24px; height: 24px; padding:0; }
+
+.classroom .edit-post textarea[name=body] {
+ min-height:320px;
+ font-family: Consolas, 'Ubuntu Mono','Courier New', Courier, monospace;
+ color: #333;
+ } \ No newline at end of file
diff --git a/public/assets/js/admin/edit_lesson.js b/public/assets/js/admin/edit_lesson.js
index 89e464f..fbcfabc 100644
--- a/public/assets/js/admin/edit_lesson.js
+++ b/public/assets/js/admin/edit_lesson.js
@@ -201,11 +201,14 @@ $(document).ready(function() {
$('input[name=id]').val(lesson.id); // id
$('input[name=title]').val(lesson.title); // title
$('textarea[name=intro]').val(lesson.intro); // intro
- $('textarea[name=body]').val(lesson.body); // body
- $('input[name=status]').prop( // status
- 'checked',
- ((lesson.status==1)? true : false))
- .trigger('change');
+ $('textarea[name=body]').val(lesson.body); // body
+ $('select[name=status]').val(
+ (lesson.status == 0) ? '0' : "one"
+ ).trigger('change');
+ // $('input[name=status]').prop( // status
+ // 'checked',
+ // ((lesson.status==1)? true : false))
+ // .trigger('change');
// $('#post-info').html('Δημιουργία: '+post.creation_date+'<br>Τελευταία Ενημέρωση: '+ post.update_date);
@@ -408,8 +411,8 @@ $(document).ready(function() {
// send POST (ajax) request
$.post(request, data)
.done(function( data ) {
- console.log(data);
- //window.location.href = '/admin/lessons'; // seems ok; bach to articles
+ // console.log(data);
+ window.location.href = '/admin/lessons'; // seems ok; bach to articles
});
});
diff --git a/public/assets/js/post-features.js b/public/assets/js/lesson-features.js
index ca2928c..369c8f7 100644
--- a/public/assets/js/post-features.js
+++ b/public/assets/js/lesson-features.js
@@ -1,6 +1,5 @@
-const valid_modals = [ // supported sort-code keys
- 'product',
- 'store'
+const valid_codeblocks = [ // supported sort-code keys
+ 'youtube'
];
@@ -16,6 +15,20 @@ const symbol_escapes = [
];
+var youtube_template = ( id => {
+ return '<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/'+ id +'?rel=0&controls=0" title="YouTube video player" frameborder="0" allow="clipboard-write; encrypted-media; picture-in-picture; web-share" allowfullscreen></iframe>'
+});
+
+/*
+
+
+<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/6EA-MIYY1bg?controls=0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
+
+
+
+*/
+
+
/** inject_codeblocks
* --- -- -- - - -
*
@@ -43,17 +56,20 @@ function inject_codeblocks(code) {
// parse (every) match
// NOTE:
// match array has 3 items; example:
- // match[0] : `{{store=247; Pasalimani Market}}`
- // match[1] : `store=247; Pasalimani Market`
+ // match[0] : `{{youtube=6EA-MIYY1bg}}`
+ // match[1] : `youtube=6EA-MIYY1bg`
// match[3] : the (source) code string
- let blockparts = unescaped_str( match[1] ).split(';');
- let main_unit = blockparts[0].replaceAll(' ','').split('=');
- let target = main_unit[0].toLowerCase();
- let id = main_unit[1];
- let label = escaped_str(blockparts[1]);
- if (valid_modals.includes(target)) {
- let codeblock = `<a href="#" data-toggle="modal" data-target="#view-${target}" data-id="${id}" class="modal-toggler js-get_${target}">${label}</a>`;
+ let blockparts = unescaped_str( match[1] ).trim().split('=');
+ let target = blockparts[0].toLowerCase();
+ let id = blockparts[1];
+ // let label = escaped_str(blockparts[1]);
+ if (valid_codeblocks.includes(target)) {
+
+ if (target == 'youtube') {
+ var codeblock = youtube_template(id);
+ }
output = output.replaceAll(match[0], codeblock);
+
}
});
@@ -80,15 +96,15 @@ $(document).ready(function() {
/** translate short-codes to code-blocks
* -------------------------------------------------------------------------
*/
- var content = $('.content .article-body').html(); // get code with shorts
- $('.content .article-body').html( inject_codeblocks(content) ); // put code with blocks
+ var content = $('.main-content .article-body').html(); // get code with shorts
+ $('.main-content .article-body').html( inject_codeblocks(content) ); // put code with blocks
/** modal listeners
* -------------------------------------------------------------------------
*/
-
+/* DEPRICATED: not needed
// open store modal listener
// --- -- -- - - -
$(document).on('click', '.js-get_store', function (e) {
@@ -144,5 +160,5 @@ $(document).ready(function() {
});
});
-
-}); \ No newline at end of file
+*/
+});