From 546daa78721e6abdbc89afcecc158118c2239865 Mon Sep 17 00:00:00 2001
From: George Halkiadakis
Date: Wed, 26 Apr 2023 21:43:02 +0300
Subject: alfa.3 version; backend designer and front-end embeder enabled
---
public/app/controllers/admin/Course_admin.php | 267 +++++++++++++++---
public/app/controllers/cms/Course.php | 38 ++-
public/app/extends/Cache_service.php | 33 +++
public/app/models/cms/Course_model.php | 22 ++
public/app/routes/backend.php | 85 ++++--
public/app/routes/frontend.php | 8 +-
public/app/views/admin/admin-menu.php | 2 +-
public/app/views/admin/edit_page.php | 139 ++++++++++
public/app/views/admin/pages.php | 109 ++++++++
public/app/views/components/footer.php | 240 ++++++++++++++++
public/app/views/components/lessons_list.php | 49 ++--
public/app/views/error/general.php | 3 +-
public/app/views/templates/course.php | 11 +
public/app/views/templates/lesson.php | 10 +
public/app/views/templates/page.php | 64 +++++
public/app/views/welcome.php | 11 +
public/assets/css/class.css | 34 ++-
public/assets/css/overides.css | 27 +-
public/assets/js/admin/edit_lesson.js | 149 +++++-----
public/assets/js/admin/edit_page.js | 382 ++++++++++++++++++++++++++
public/assets/js/admin/pages.js | 240 ++++++++++++++++
public/assets/js/lesson-features.js | 55 +++-
tests/code/menu.php | 42 +++
23 files changed, 1849 insertions(+), 171 deletions(-)
create mode 100644 public/app/views/admin/edit_page.php
create mode 100644 public/app/views/admin/pages.php
create mode 100644 public/app/views/components/footer.php
create mode 100644 public/app/views/templates/page.php
create mode 100644 public/assets/js/admin/edit_page.js
create mode 100644 public/assets/js/admin/pages.js
create mode 100644 tests/code/menu.php
diff --git a/public/app/controllers/admin/Course_admin.php b/public/app/controllers/admin/Course_admin.php
index 72ddc79..f68ead2 100644
--- a/public/app/controllers/admin/Course_admin.php
+++ b/public/app/controllers/admin/Course_admin.php
@@ -168,11 +168,12 @@ class Course_admin {
);
if (isset($post['media'])) {
- // update media's privileges
+ // update media's privileges; NOTE: media table
self::update_medias_privileges($post['media'], $post['privilege_id']);
- // set lesson's media files
- self::create_medias_for_lesson($post['media'], $id, $post['privilege_id']);
+ // set lesson's media files; NOTE: lesson_media table
+ // ERROR: self::create_medias_for_lesson($post['media'], $id, $post['privilege_id']);
+ self::create_medias_for_lesson($post['media'], $id);
}
return true;
@@ -226,41 +227,13 @@ class Course_admin {
if (isset($post['media'])) {
// update lesson's media files
- self::create_medias_for_lesson($post['media'], $post['id'], $post['privilege_id']);
+ // ERROR: self::create_medias_for_lesson($post['media'], $post['id'], $post['privilege_id']);
+ self::create_medias_for_lesson($post['media'], $post['id']);
}
return true;
}
- /** update medias privileges
- *
- * @param $medias (array) : array of media id(s)
- * @param $privilege (int) : privilege id
- * @return true (always)
- */
- private static function update_medias_privileges($medias, $privilege)
- {
- // create WHERE IN (LIST) holders and params for prepare statement
- $params = [ ':privilege' => $privilege];
- $holders = [];
- foreach($medias as $key => $media) {
- $params[':id'.$key] = $media;
- $holders[] = ':id'.$key;
- }
- $list = '('. implode(',', $holders) .')';
-
- // print_r(['params' => $params, 'list' => $list]); die();
-
- Registry::use('database')->runQuery(
- "UPDATE media SET privilege_id = :privilege
- WHERE id IN {$list}",
- $params
- );
-
- return true;
- }
-
-
## -------------------------------------------------------------------------
##
@@ -271,6 +244,7 @@ class Course_admin {
/** files
* echo all files
+ *
* @return (array)
*/
public static function files()
@@ -434,11 +408,12 @@ class Course_admin {
}
- /** create media for post
+ /** create media for lesson
+ *
+ * links lesson to each media-file of the media `id`s array
*
- * links post to each media-file of the media `id`s array
* @param $media (array): a list of media-file `id`s
- * @param $post_id (int)
+ * @param $lesson_id (int)
*/
private static function create_medias_for_lesson($medias, $lesson_id)
{
@@ -449,6 +424,22 @@ class Course_admin {
}
+ /** create media for page
+ *
+ * links page to each media-file of the media `id`s array
+ *
+ * @param $media (array): a list of media-file `id`s
+ * @param $page_id (int)
+ */
+ private static function create_medias_for_page($medias, $page_id)
+ {
+ foreach($medias as $key => $medi) {
+ self::link_media_to_page($medi, $page_id); // link to page
+ }
+ return true;
+ }
+
+
/** link one media-file to a specific post
*
* NOTE:
@@ -471,5 +462,209 @@ class Course_admin {
return true;
}
+ /** link one media-file to a specific page
+ *
+ * NOTE:
+ * the method does not check if media is linked already
+ * so be sure that the pair of (media_id, page_id) not exist
+ *
+ * @param $media_id (int)
+ * @param $page_id (int)
+ */
+ private static function link_media_to_page( $media_id, $page_id )
+ {
+ Registry::use('database')->runQuery(
+ "INSERT INTO page_media (page_id, media_id)
+ VALUES (:page, :media)",
+ [
+ 'page' => $page_id,
+ 'media' => $media_id,
+ ]
+ );
+ return true;
+ }
+
+
+ /** update medias privileges
+ *
+ * UPDATE media SET privige WHERE IN {list}
+ *
+ * @param $medias (array) : array of media id(s)
+ * @param $privilege (int) : privilege id
+ * @return true (always)
+ */
+ private static function update_medias_privileges($medias, $privilege)
+ {
+ // create WHERE IN (LIST) holders and params for prepare statement
+ $params = [ ':privilege' => $privilege];
+ $holders = [];
+ foreach($medias as $key => $media) {
+ $params[':id'.$key] = $media;
+ $holders[] = ':id'.$key;
+ }
+ $list = '('. implode(',', $holders) .')';
+
+ // print_r(['params' => $params, 'list' => $list]); die();
+
+ Registry::use('database')->runQuery(
+ "UPDATE media SET privilege_id = :privilege
+ WHERE id IN {$list}",
+ $params
+ );
+
+ return true;
+ }
+
+
+
+
+
+
+ ## -------------------------------------------------------------------------
+ ##
+ ## PAGE METHODS
+ ##
+ ## -------------------------------------------------------------------------
+
+
+ /** all pages
+ *
+ */
+ public static function all_pages()
+ {
+ Render::json(Registry::use('database')->runQuery(
+ "SELECT * FROM page", []
+ ));
+ }
+
+
+ /** get_page
+ *
+ * @param $id (int) : page's id
+ */
+ public static function get_page($id)
+ {
+ // get (first) page with id = $id; render as json
+ Render::json(Registry::use('database')->query(
+ "SELECT page.*,
+ ( SELECT
+ CONCAT('[', GROUP_CONCAT(JSON_OBJECT(
+ 'id', media.id,
+ 'label', media.label,
+ 'type', media.type,
+ 'path', media.path )),
+ ']')
+ FROM media
+ LEFT JOIN page_media ON page_media.media_id = media.id
+ WHERE page_media.page_id = :id
+ ) AS medias_json
+ FROM page
+ WHERE page.id = :id",
+ [ ':id' => $id]
+ )->getFirst());
+ }
+
+
+ /** add_page
+ * insert a new page
+ *
+ * all parametres are passed via $_POST array
+ *
+ * POST @param title
+ * POST @param body
+ * POST @param status (int): 0 = draft , 1 = published
+ */
+ public static function add_page()
+ {
+ $post = Registry::get('REQUEST')->POST;
+
+ // insert page content into daabase
+ $id = Registry::use('database')->query(
+ "INSERT INTO page (title, `body`, `status`)
+ VALUES (:title, :body, :status)",
+ [
+ ':title' => $post['title'],
+ ':body' => $post['body'],
+ 'status' => $post['status']
+ ]
+ )->lastInsertID();
+
+
+ if (isset($post['media'])) {
+ // update media's privileges;
+ // NOTE: media table; pages have public files (privilege_id=0)
+ self::update_medias_privileges($post['media'], 0);
+
+ // set page's media files
+ // NOTE: page_media table
+ self::create_medias_for_page($post['media'], $id);
+ }
+
+ self::update_pages_cache(); // update pages cache
+
+ return true;
+ }
+
+
+ /** update_page
+ *
+ * POST @param id (int)
+ * POST @param title
+ * POST @param body
+ * POST @param status (int): 0 = draft , 1 = published
+ */
+ public static function update_page()
+ {
+ $post = Registry::get('REQUEST')->POST;
+
+ // print_r($post); die();
+
+ // update page's content
+ Registry::use('database')->query(
+ "UPDATE page
+ SET title = :title, `body` = :body, `status` = :status
+ WHERE id = :id",
+ [
+ ':id' => $post['id'],
+ ':title' => $post['title'],
+ ':body' => $post['body'],
+ ':status' => $post['status']
+ ]
+ );
+
+ if (isset($post['media'])) {
+ // update media's privileges
+ self::update_medias_privileges($post['media'], 0);
+ }
+
+ // remove all old page's links to media files
+ Registry::use('database')->runQuery(
+ "DELETE from page_media WHERE page_id = :page",
+ [ ':page' => $post['id'] ]
+ );
+
+ if (isset($post['media'])) {
+ // update page's media files
+ self::create_medias_for_page($post['media'], $post['id']);
+ }
+
+ self::update_pages_cache(); // update pages cache
+
+ return true;
+ }
+
+
+ /** update pages cache
+ * --- -- -- - - -
+ * Forces re-caching of pages tree
+ * Shall run if anything changes to courses
+ *
+ * @param void
+ * @return (array): ['tree' => ..., 'breadcrumbs' => ... ]
+ */
+ public static function update_pages_cache()
+ {
+ return Cache_service::pages_list(PROXY_IGNORE_CACHE);
+ }
}
\ No newline at end of file
diff --git a/public/app/controllers/cms/Course.php b/public/app/controllers/cms/Course.php
index a1de9c1..c795ab9 100644
--- a/public/app/controllers/cms/Course.php
+++ b/public/app/controllers/cms/Course.php
@@ -131,7 +131,9 @@ class Course {
'categories' => $tree,
'breadcrumbs' => $breadcrumbs,
'lessons' => $lessons,
- 'course_path' => $course_path
+ 'course_path' => $course_path,
+ // needed by footer
+ 'entity' => Cache_service::pages_list()
]);
}
@@ -174,6 +176,12 @@ class Course {
}
$course_path[] = intval($course_id);
+ // NOTE: CRITICAL:
+ // do not pass Class::method directly to the eported variables
+ // $entity = Cache_service::pages_list();
+
+ // var_dump($entity); die();
+
// then Render
// --- -- -- - - -
Render::view('templates/lesson', [
@@ -185,7 +193,9 @@ class Course {
// needed for side panel and breadcrunbs
'categories' => $tree,
'breadcrumbs' => $breadcrumbs,
- 'course_path' => $course_path
+ 'course_path' => $course_path,
+ // needed by footer
+ 'entity' => Cache_service::pages_list()
]);
} else { // user is not authorized
@@ -202,7 +212,31 @@ class Course {
}
+ /** 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 page($id)
+ {
+ $id = intval($id); // lesson id
+
+ $pages = Cache_service::pages_list();
+ $page = $pages[$id];
+
+ // then Render
+ // --- -- -- - - -
+ Render::view('templates/page', [
+ // main content
+ 'id' => $id,
+ 'page' => $page,
+ // needed by footer
+ 'entity' => $pages
+ ]);
+ }
diff --git a/public/app/extends/Cache_service.php b/public/app/extends/Cache_service.php
index 9aac1d0..52311f3 100644
--- a/public/app/extends/Cache_service.php
+++ b/public/app/extends/Cache_service.php
@@ -45,5 +45,38 @@ class Cache_service
);
}
+ public static function pages_list( $options = 0 )
+ {
+ return proxy(
+ [\app\models\cms\Course_model::class, 'pages'],
+ [], CACHE_ROOT_TTL,
+ $options
+ );
+ }
+
+
+ /** entity
+ *
+ * create and retrieve a cached array of some entity
+ *
+ * @param $entiry (string|method): method of the main CMS model
+ * NOTE: CRITICAL: method must exist in the main CMS model
+ */
+ public static function entity( $entity, $options = 0 )
+ {
+ $allowed_methods = [ // to make sure method existence
+ 'page',
+ 'course',
+ 'lesson',
+ ];
+
+ // TODO: needs testing before release
+ // return proxy(
+ // [\app\models\admin\Course_model::class, $entity],
+ // [], CACHE_ROOT_TTL,
+ // $options
+ // );
+ }
+
}
\ No newline at end of file
diff --git a/public/app/models/cms/Course_model.php b/public/app/models/cms/Course_model.php
index 54f49cf..6614993 100644
--- a/public/app/models/cms/Course_model.php
+++ b/public/app/models/cms/Course_model.php
@@ -288,5 +288,27 @@ class Course_model {
}
+ /** pages
+ *
+ * return all pages as array;
+ * array key of each item shall be the page-id
+ *
+ * @param void
+ * @return array
+ */
+ public static function pages()
+ {
+ $result = [];
+ $pages = Registry::use('database')->runQuery("SELECT * FROM page", []);
+ foreach($pages as $key => $page) {
+ $result[ $page['id'] ] = [
+ 'title' => $page['title'],
+ 'body' => $page['body'],
+ 'status' => $page['status']
+ ];
+ }
+ // print_r($result); die();
+ return $result;
+ }
}
diff --git a/public/app/routes/backend.php b/public/app/routes/backend.php
index ed02295..2bbd056 100644
--- a/public/app/routes/backend.php
+++ b/public/app/routes/backend.php
@@ -31,18 +31,6 @@ Route::add('/admin/panel', function () { // admin panel #2
});
-// admin lessons
-////////////////////////////////////////////////////////////////////////////////
-
-Route::add('/admin/lessons', function () { // request admin-lessons page
- Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
- Render::view('admin/skeleton', [
- 'title' => 'Διαχείριση Μαθημάτων',
- 'action' => 'lessons',
- ]);
-});
-
-
// admin categories (=courses)
////////////////////////////////////////////////////////////////////////////////
@@ -55,8 +43,6 @@ Route::add('/admin/categories', function () { // manage categories page
]);
});
-
-
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();
@@ -99,11 +85,17 @@ Route::add('/admin/api/privileges', function () {
-// admin lesson
+// admin lessons
////////////////////////////////////////////////////////////////////////////////
+Route::add('/admin/lessons', function () { // request admin-lessons page
+ Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
+ Render::view('admin/skeleton', [
+ 'title' => 'Διαχείριση Μαθημάτων',
+ 'action' => 'lessons',
+ ]);
+});
-// ---
Route::add('/admin/edit_lesson', function () { // new lesson form
Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
Render::view('admin/skeleton', [
@@ -130,13 +122,13 @@ Route::add('/admin/api/lesson/([0-9]*)', function ($id) { // ajax: get les
Route::add('/admin/api/lesson/add', function () { // ajax: add lesson
Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
- Course_admin::add_lesson();
+ Render::json(['success' => Course_admin::add_lesson()]);
}, 'post');
Route::add('/admin/api/lesson/update', function () { // ajax: update lesson
Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
- Course_admin::update_lesson();
+ Render::json(['success' => Course_admin::update_lesson()]);
}, 'post');
@@ -146,6 +138,7 @@ Route::add('/admin/api/lessons', function () { // ajax: get all lessons
});
+
// admin files
////////////////////////////////////////////////////////////////////////////////
@@ -170,3 +163,59 @@ Route::add('/admin/api/file_upload', function () {
Render::json(Course_admin::upload_file());
}, 'post');
+
+
+
+// admin page
+////////////////////////////////////////////////////////////////////////////////
+
+Route::add('/admin/pages', function () { // request admin-lessons page
+ Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
+ Render::view('admin/skeleton', [
+ 'title' => 'Διαχείριση Σελίδων',
+ 'action' => 'pages',
+ ]);
+});
+
+
+Route::add('/admin/edit_page', function () { // new page form
+ Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
+ Render::view('admin/skeleton', [
+ 'title' => 'Νέα Σελίδα',
+ 'action' => 'edit_page',
+ ]);
+});
+
+Route::add('/admin/edit_page/([0-9]*)', function ($id) { // edit page form
+ Auth::allowRoles([1, 2, 3]);
+ Render::view('admin/skeleton', [
+ 'title' => 'Επεξεργασία Σελίδας',
+ 'action' => 'edit_page',
+ 'id' => intval($id)
+ ]);
+});
+
+
+Route::add('/admin/api/page/([0-9]*)', function ($id) { // ajax: get page
+ Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
+ Course_admin::get_page($id);
+});
+
+
+Route::add('/admin/api/page/add', function () { // ajax: add page
+ Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
+ Render::json(['success' => Course_admin::add_page()]);
+}, 'post');
+
+
+Route::add('/admin/api/page/update', function () { // ajax: update page
+ Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
+ Render::json(['success' => Course_admin::update_page()]);
+}, 'post');
+
+
+Route::add('/admin/api/pages', function () { // ajax: get all pages
+ Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
+ Course_admin::all_pages();
+});
+
diff --git a/public/app/routes/frontend.php b/public/app/routes/frontend.php
index 33fe401..601641f 100644
--- a/public/app/routes/frontend.php
+++ b/public/app/routes/frontend.php
@@ -12,7 +12,8 @@ use app\extends\Cache_service;
Route::add('/', function() {
Render::view('welcome', [
- 'categories' => Cache_service::courses_struct()['tree']
+ 'categories' => Cache_service::courses_struct()['tree'],
+ 'entity' => Cache_service::pages_list()
]);
// need redirect?... header('Location: /some/default/url', true, 302);
});
@@ -40,6 +41,11 @@ Route::add('/lesson/([0-9]*)', // request lesson by lesson-id
function($id) { Course::lesson($id); }
);
+Route::add('/page/([0-9]*)', // request lesson by lesson-id
+ function($id) { Course::page($id); }
+);
+
+
Route::add('/serve/file/([0-9a-zA-Z-_\.\/]*)', // serve file by path
function ($path) { Course::serve_file($path); } // (also ?type= is sent)
);
diff --git a/public/app/views/admin/admin-menu.php b/public/app/views/admin/admin-menu.php
index b783b39..52e8522 100644
--- a/public/app/views/admin/admin-menu.php
+++ b/public/app/views/admin/admin-menu.php
@@ -21,7 +21,7 @@ $admin_options = [
'edit_lesson' => 'Νέο Μάθημα',
'lessons' => 'Μαθήματα',
'categories' => 'Κεφάλαια',
- // 'pages' => 'Σελίδες',
+ 'pages' => 'Σελίδες',
'files' => 'Αρχεία',
'privileges' => 'Πρόσβαση',
'users' => 'Χρήστες'
diff --git a/public/app/views/admin/edit_page.php b/public/app/views/admin/edit_page.php
new file mode 100644
index 0000000..46c47bc
--- /dev/null
+++ b/public/app/views/admin/edit_page.php
@@ -0,0 +1,139 @@
+
+
+
+
+
=$action_title?>
+
+
+ Προεπισκόπηση
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/app/views/admin/pages.php b/public/app/views/admin/pages.php
new file mode 100644
index 0000000..dd8f954
--- /dev/null
+++ b/public/app/views/admin/pages.php
@@ -0,0 +1,109 @@
+
+
+
Διαχείριση Μαθημάτων
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/app/views/components/footer.php b/public/app/views/components/footer.php
new file mode 100644
index 0000000..7cd4a5a
--- /dev/null
+++ b/public/app/views/components/footer.php
@@ -0,0 +1,240 @@
+#footer>row`
+ *
+ *
+ * Each sub-structure has 2-5 properties:
+ *
+ * @var title (string) : title of the sub-section
+ * @var entity (string) : type of entity (ex: page/lesson/etc; TODO: method of CMS_model?)
+ * @var list (array) : list of entity id(s)
+ * @var template (string) : template that is used to draw the listed pages' info
+ * @var width (string) : class that relates to sub-structure's width
+ *
+ * NOTE:
+ * designer parsing and rendering can be a quite expensive proccess
+ * thus it is strongly recommented to use cached entities
+ *
+ *
+ * Example structure:
+ {
+ "class" : "row", # container class
+ "struct" : [
+ { # block 1
+ "title" : "",
+ "entity" : "page",
+ "list" : [2, 1, 3], # pages to be listed
+ "template" : "list", # list page titles with link to the pages
+ "width" : "col-md-4"
+ },
+ {
+ "template" : "null", # list nothing
+ "width" : "col-md-3"
+ },
+ {
+ "entity" : "page",
+ "list" : [4], # list content of page 4;
+ "template" : "content", # set title to page-title
+ "width" : "col-md-5"
+ }
+
+ TODO: (wish)
+ ,{
+ "template": "struct",
+ "struct" : [
+ {
+ title, entity, list, template, width
+ },
+ ...
+ ]
+ }
+ ]
+ }
+ *
+ * brainstormin: (TODO:)
+ * use some document-describe stucture like the one on the pdfmake js-library
+ * -----------------------------------------------------------------------------
+ */
+
+
+/** check imported variables / data
+ * -----------------------------------------------------------------------------
+ */
+if (!isset($designer)) {
+
+ // default designer (and first case-study)
+ $designer = '{
+ "class" : "row",
+ "struct" : [
+ {
+ "title" : "Πληροφορίες",
+ "entity" : "page",
+ "list" : [2, 1, 3, 4],
+ "template" : "list",
+ "width" : "col-md-4 no-list-mark"
+ },
+ {
+ "entity" : "page",
+ "list" : [6],
+ "template" : "content",
+ "width" : "col-md-3 no-list-mark"
+ },
+ {
+ "entity" : "page",
+ "list" : [5],
+ "template" : "content",
+ "width" : "col-md-5 no-list-mark"
+ }
+ ]
+ }';
+}
+
+// $entity list shall be passed
+// entity link url shall be passed
+
+
+/** templating functions
+ * -----------------------------------------------------------------------------
+ */
+
+/** List template
+ * --- -- -- - - -
+ *
+ * lists entity titles with links
+ * in a `ul>li` html-structure
+ *
+ * @param $title
+ * @param $list
+ * @param $container
+ */
+function list_template($title, $list, $container, $entity) {
+
+ $result = '
+
'. $title .'
+
';
+
+ foreach($list as $id) {
+
+ if ($entity[$id]['status'] == 1) { // if entity is published
+ $result .= '
+
+
+ ' . $entity[$id]['title'] .'
+
+ ';
+ }
+
+ }
+ return $result . ' ';
+}
+
+/** content_template
+ *
+ * lists whole title and content of entity
+ *
+ * @param $list
+ * @param $container
+ */
+function content_template($list, $container, $entity) {
+
+ $parsedown = new Parsedown();
+
+ $result = '';
+}
+
+
+/** ready to start the proccessing
+ * -----------------------------------------------------------------------------
+ */
+
+// decode ...
+$parse = json_decode($designer);
+
+/** then start parse-proccessing ...
+ * -----------------------------------------------------------------------------
+ */
+?>
+
+
+
+
+
+ struct as $section ) {
+
+ switch ($section->template) {
+
+ case 'list':
+ echo list_template(
+ $section->title,
+ $section->list,
+ $section->width,
+ $entity
+ );
+ break;
+
+ case 'content':
+ echo content_template(
+ $section->list,
+ $section->width,
+ $entity
+ );
+ break;
+
+ default: // ex. 'null'
+
+ echo '
+
'. $section->title.'
+ ';
+ }
+
+ }
+ ?>
+
+
+
+
diff --git a/public/app/views/components/lessons_list.php b/public/app/views/components/lessons_list.php
index 46c1f7e..a778d59 100644
--- a/public/app/views/components/lessons_list.php
+++ b/public/app/views/components/lessons_list.php
@@ -16,40 +16,39 @@
* -----------------------------------------------------------------------------
*/
?>
-
-
-
-
+
-
- =$post['date']?>
-
+
+
-
+
+ =$post['date']?>
+
-
+
-
-
(επίπεδο πρόσβασης =$post['privilege_id']?>)
-
+
-
-
=$post['course_id']?>
-
+
+
(επίπεδο πρόσβασης =$post['privilege_id']?>)
+
-
-
=$post['intro']?>
-
+
+
=$post['course_id']?>
+
+
+
+
=$post['intro']?>
+
-
+
-
-
+
+
-
+
-
\ No newline at end of file
diff --git a/public/app/views/error/general.php b/public/app/views/error/general.php
index 0a27e56..6ed984b 100644
--- a/public/app/views/error/general.php
+++ b/public/app/views/error/general.php
@@ -55,8 +55,7 @@
= isset($title) ? $title : PAGE_404_TITLE ?>
- Oops!
- —
+
= $message ?? "" ?>
diff --git a/public/app/views/templates/course.php b/public/app/views/templates/course.php
index 39e177f..1d212b8 100644
--- a/public/app/views/templates/course.php
+++ b/public/app/views/templates/course.php
@@ -76,6 +76,17 @@
+
+
+
+ $entity ]);
+ ?>
+
+
+
+
+
+ 0,
+ 'label' => '',
+ 'parents' => []
+ ]);
+ ?>
+
+
+
+
+
+
+
+
+
+ =$page['title']?>
+
+
+
+
+ text($page['body']);
+
+ ?>
+
+
+
+
+
+
+
+
+
+
+ $entity ]);
+ ?>
+
+
+
+
+
+
+
diff --git a/public/app/views/templates/lesson.php b/public/app/views/templates/lesson.php
index 3baafd0..0867cd3 100644
--- a/public/app/views/templates/lesson.php
+++ b/public/app/views/templates/lesson.php
@@ -65,6 +65,16 @@
+
+
+
+ $entity ]);
+ ?>
+
+
+
diff --git a/public/app/views/templates/page.php b/public/app/views/templates/page.php
new file mode 100644
index 0000000..6afe45e
--- /dev/null
+++ b/public/app/views/templates/page.php
@@ -0,0 +1,64 @@
+
+
+