summaryrefslogtreecommitdiff
path: root/public
diff options
context:
space:
mode:
Diffstat (limited to 'public')
-rw-r--r--public/app/controllers/Auth.php48
-rw-r--r--public/app/controllers/Product.php52
-rw-r--r--public/app/controllers/Resolve.php91
-rw-r--r--public/app/controllers/admin/Course_admin.php33
-rw-r--r--public/app/controllers/cms/Course.php116
-rw-r--r--public/app/extends/Cache_service.php45
-rw-r--r--public/app/models/cms/Course_model.php45
-rw-r--r--public/app/routes/backend.php7
-rw-r--r--public/app/routes/frontend.php10
-rw-r--r--public/app/views/components/breadcrumbs.php6
-rw-r--r--public/app/views/components/lessons_list.php51
-rw-r--r--public/app/views/components/subcategories.php18
-rw-r--r--public/app/views/components/top_bar.php6
-rw-r--r--public/app/views/templates/course.php82
-rw-r--r--public/assets/css/class.css11
-rw-r--r--public/assets/js/admin/files.js48
-rw-r--r--public/assets/js/admin/lessons.js158
17 files changed, 523 insertions, 304 deletions
diff --git a/public/app/controllers/Auth.php b/public/app/controllers/Auth.php
index b00843c..0570a5e 100644
--- a/public/app/controllers/Auth.php
+++ b/public/app/controllers/Auth.php
@@ -186,7 +186,7 @@ class Auth {
$manager = new Classroom_manager();
if ($manager->hasUserToken()) {
- echo 'user is connected';
+ // user is connected;
$token = $manager->getUserToken();
$user = $token->getUser();
@@ -226,9 +226,19 @@ class Auth {
* to access the source
*
*/
- public static function hasPermition($permit = [])
+ public static function hasPermition($permit = [0])
{
- if ($permit == []) return true;
+ if (in_array(0, $permit)) { // permision 0 means public
+ return true; // permision 0 is always granted
+ }
+
+ if ($user = $this->is_connected() === flase) { // if not connected
+ return false; // then no other permition is granted
+ }
+
+ if ($user instanceof UserInterface) {
+ return ( !empty( array_intersect($permit, $user->getPrivileges()) ) );
+ }
}
@@ -243,11 +253,11 @@ class Auth {
* example:
* [
* [
- * role => ['editor','designer']
+ * role => [2, 3]
* permition => ['10', '12', '18']
* ],
* [
- * role => ['admin' , 'developερ']
+ * role => [1 , 4]
* ],
* [
* permition => [ 3 ]
@@ -256,12 +266,12 @@ class Auth {
*
* defines (and parses to) a requirements rule of:
* [
- * user should be editor or designer
- * and have permition 10 or 12 or 18
+ * user should be creator or editor
+ * _AND_ have permition 10 or 12 or 18
* ]
* OR
* [
- * user should be an administratoe or developer
+ * user should be an administrator or developer
* ]
* OR
* [
@@ -274,17 +284,25 @@ class Auth {
{
$authorized = false;
foreach($requirements as $required) {
- if ( (self::isGranted($required['role'] ?? []))
- && (self::hasPermition($required['permition'] ?? [])) ) {
- $authorized = true;
+
+ if (isset($required['role'])) { // if a role is required
+ if ( (self::isGranted($required['role'])) // authorize both role
+ && (self::hasPermition($required['permition'] ?? [ 0 ])) ) { // and permition
+ // $authorized = true;
+ return true;
+ }
+
+ } else { // else, if not is not required
+ if (self::hasPermition($required['permition'] ?? [ 0 ])) { // authorize permition
+ // $authorized = true;
+ return true;
+ }
}
}
return $authorized;
}
-
-
public static function forgot_pass()
{
}
@@ -322,10 +340,10 @@ class Auth {
}
- public static function is_admin()
+ public static function in_admin_group()
{
$manager = new Classroom_manager();
- return ($manager->isGranted([1,2,3]));
+ return ($manager->isGranted([1, 2, 3]));
}
diff --git a/public/app/controllers/Product.php b/public/app/controllers/Product.php
deleted file mode 100644
index 0193ed9..0000000
--- a/public/app/controllers/Product.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-
-namespace app\controllers;
-
-use app\models\market\Product_model;
-use app\models\market\ProductCategories_model;
-
-class Product {
-
- public static function fromUrl($url, $pathArr)
- {
- $product = proxy([\app\models\market\Product_model::class, 'fromUrl'],
- [ $url ], CACHE_PRODUCT_TTL
- );
-
- // TODO:
- // verify path, else redirect
-
- if ($product === false) {
- header("HTTP/1.0 404 Not Found");
- render_view('error/404', ['message' => 'Of all the things I\'ve lost, I miss my mind the most.']);
- return ;
- }
-
- // render page
- load_template('products', [ 'data' => [
- 'title' => $product['Title'],
- 'seo' => [],
- 'tree' => proxy(
- [\app\models\market\ProductCategories_model::class, 'tree'],
- [], CACHE_ROOT_TTL
- ),
- 'hierarchyPath' => explode('.', substr($product['Hierarchy'], 1, -1)),
- 'sections' => [
- [
- 'view' => 'content/product_list/Product_List_Filters',
- 'key' => 'filters',
- 'data' => []
- ],
- [
- 'view' => 'content/product/product_details',
- 'key' => 'product',
- 'data' => $product
- ]
- ]
- ]
- ]);
-
- }
-
-
-}
diff --git a/public/app/controllers/Resolve.php b/public/app/controllers/Resolve.php
deleted file mode 100644
index 7b9222c..0000000
--- a/public/app/controllers/Resolve.php
+++ /dev/null
@@ -1,91 +0,0 @@
-<?php
-
-namespace app\controllers;
-
-use \Benchmark;
-
-/** Resolve class
- * will resolve ambiguous utl-request patterns
- * ---
- * Then it can route the request to some controller;
- * Alternatively it can proccess the request via Models
- * and initiate the View engine
- */
-class Resolve {
-
- public static function url($array)
- {
- $fullUrl = implode('/', $array);
- $url = $array[count($array) - 1];
-
-
- if (!PRODUCTION) Benchmark::add_spot('proxy-page');
-
- // proxying check if page with this url
- $page = proxy(
- [\app\models\cms\Page_model::class, 'fromUrl'],
- [ $fullUrl ], CACHE_ROOT_TTL,
- PROXY_CACHE_ERRORS
- );
- // if page exist, construct page
- if ($page !== false) {
- // page exists, render page
- load_template('base', [ 'page' => [
- 'title' => $page['Title'],
- 'seo' => [],
- 'sections' => [
- [
- 'view' => 'content/static',
- 'key' => 'page',
- 'data' => $page
- ]
- ]
- ]
- ]);
- return ;
- }
-
-
- if (!PRODUCTION) Benchmark::add_spot('proxy-category');
-
- // proxying check if products category with this url
- $category = proxy(
- [\app\models\market\ProductCategories_model::class, 'categoryFromUrl'],
- [ $fullUrl ], CACHE_CATEGORY_TTL
- );
- // if category exist, construct category
- if ($category !== false) {
- // render page
- load_template('products', [ 'data' => [
- 'title' => $category['Title'],
- 'seo' => [],
- 'tree' => proxy(
- [\app\models\market\ProductCategories_model::class, 'tree'],
- [], CACHE_ROOT_TTL
- ),
- 'hierarchyPath' => explode('.', substr($category['Hierarchy'], 1, -1)),
- 'sections' => [
- [
- 'view' => 'content/product_list/Product_List_Filters',
- 'key' => 'filters',
- 'data' => $category
- ],
- [
- 'view' => 'content/product_list/product_list',
- 'key' => 'products',
- 'data' => $category['products']
- ]
- ]
- ]
- ]);
- return ;
- }
-
-
- // not page nor category?: reply 404
- header("HTTP/1.0 404 Not Found");
- render_view('error/404', ['message' => 'Say something I\'m givin\' up on you.']);
-
- }
-
-} \ No newline at end of file
diff --git a/public/app/controllers/admin/Course_admin.php b/public/app/controllers/admin/Course_admin.php
index bb4deb0..c2e06f2 100644
--- a/public/app/controllers/admin/Course_admin.php
+++ b/public/app/controllers/admin/Course_admin.php
@@ -5,6 +5,7 @@ namespace app\controllers\admin;
use Registry;
use Render;
use app\models\cms\Course_model;
+use app\extends\Cache_service;
class Course_admin {
@@ -22,15 +23,7 @@ class Course_admin {
*/
public static function breadcrumbs()
{
- $tree = proxy( // cache-get categories
- [\app\models\cms\Course_model::class, 'category_tree'],
- [], CACHE_ROOT_TTL
- );
- $breadcrumbs = proxy( // cache-get breadcrumbs
- [\app\models\cms\Course_model::class, 'breadcrumbs'],
- [$tree], CACHE_ROOT_TTL
- );
- Render::json($breadcrumbs); // send as json
+ Render::json( Cache_service::courses_struct()['breadcrumbs'] );
}
/** add course
@@ -75,26 +68,15 @@ class Course_admin {
/** update courses cache
* --- -- -- - - -
+ * Forces re-caching of courses tree
* Shall run if anything changes to courses
*
* @param void
- * @return (array): the two course caches
+ * @return (array): ['tree' => ..., 'breadcrumbs' => ... ]
*/
public static function update_courses_cache()
{
- $tree = proxy( // cache-get categories
- [\app\models\cms\Course_model::class, 'category_tree'],
- [], CACHE_ROOT_TTL, PROXY_IGNORE_CACHE
- );
- $breadcrumbs = proxy( // cache-get breadcrumbs
- [\app\models\cms\Course_model::class, 'breadcrumbs'],
- [$tree], CACHE_ROOT_TTL, PROXY_IGNORE_CACHE
- );
-
- return [
- 'tree' => $tree,
- 'breadcrumbs' => $breadcrumbs
- ];
+ return Cache_service::courses_struct(PROXY_IGNORE_CACHE);
}
@@ -289,10 +271,7 @@ class Course_admin {
*/
public static function files()
{
- return proxy( // cache-get files
- [\app\models\cms\Course_model::class, 'files'],
- [], CACHE_ROOT_TTL
- );
+ return Cache_service::files_attributes();
}
diff --git a/public/app/controllers/cms/Course.php b/public/app/controllers/cms/Course.php
index b671a5f..7e53d3a 100644
--- a/public/app/controllers/cms/Course.php
+++ b/public/app/controllers/cms/Course.php
@@ -6,9 +6,45 @@ use Registry;
use Render;
use app\controllers\Auth;
use app\models\cms\Course_model;
+use app\extends\Cache_service;
class Course {
+
+ /** PERMITION
+ * -------------------------------------------------------------------------
+ */
+
+
+ /** is admin or permited
+ *
+ * shortcut method for checking access authorization
+ *
+ * returns true if user belogns to the admin group
+ * or has the specified permition/privilege
+ *
+ * @param $privilege_id (int)
+ *
+ * NOTE:
+ * unlike the other authorization methods ...
+ * $privilege_id is NOT an array but a single privilege id
+ *
+ * @return true|false
+ */
+ private static function is_admin_or_permited( $privilege_id)
+ {
+ return (
+ Auth::in_admin_group()
+ || Auth::has_Permition([ $privilege_id ])
+ );
+ }
+
+
+
+ /** FILES
+ * -------------------------------------------------------------------------
+ */
+
/** serve file by file_path
* (request is valid only for admin users)
*
@@ -17,8 +53,10 @@ class Course {
*/
public static function serve_file($file_path)
{
- // check privileges
- if (Auth::is_admin()) { // TODO: -OR- has prvivilege
+ $file = self::get_file_attributes($file_path);
+
+ // if user is authorized
+ if (is_admin_or_permited($file['privilege_id'])) {
$media_type = Registry::get('REQUEST')->GET['type']; // get media-type
$real_path = MEDIA_STORAGE_ROOT . $file_path; // construct real path
@@ -33,4 +71,78 @@ class Course {
}
}
+
+ /** get_file_attributes
+ *
+ * returns attributes of a file
+ * (medias are proxied for speed optimization)
+ *
+ * @param $path (string) : file path
+ * @return $file attributes --or-- false
+ */
+ private static function get_file_attributes($path)
+ {
+ $medias = Cache_service::files_attributes();
+
+ foreach($medias as $key => $medi) {
+ if ($medi['path'] == $path) {
+ return $medi;
+ }
+ }
+
+ return false;
+ }
+
+
+
+ /** COURSES
+ * -------------------------------------------------------------------------
+ */
+
+
+ public static function course($id)
+ {
+ $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);
+
+ Render::view('templates/course', [
+ 'id' => $id,
+ 'title' => $breadcrumbs[ $id ]['rec']['label'],
+ 'categories' => $tree,
+ 'breadcrumbs' => $breadcrumbs,
+ 'lessons' => $lessons,
+ 'course_path' => $course_path
+ ]);
+ }
+
+
+
+
+
+
+ /** LESSONS
+ * ------------------------------------------------------------------------
+ */
+
+
+
+
+
+
+
+
+
+
} \ No newline at end of file
diff --git a/public/app/extends/Cache_service.php b/public/app/extends/Cache_service.php
new file mode 100644
index 0000000..e44cc8e
--- /dev/null
+++ b/public/app/extends/Cache_service.php
@@ -0,0 +1,45 @@
+<?php
+namespace app\extends;
+
+use app\models\cms\Course_model;
+use app\models\admin\Privilege_model;
+
+/** Cache service
+ * -----------------------------------------------------------------------------
+ *
+ * class that gathers common source-expensive queries
+ * and helps for performance optimization
+ *
+ */
+class Cache_service
+{
+
+ public static function courses_struct( $options = 0 )
+ {
+ return proxy( // cache-get categories
+ [\app\models\cms\Course_model::class, 'courses_struct'],
+ [], CACHE_ROOT_TTL, $options
+ );
+ }
+
+ public static function files_attributes( $options = 0 )
+ {
+ return proxy(
+ [\app\models\cms\Course_model::class, 'files'],
+ [], CACHE_ROOT_TTL, $options
+ );
+ }
+
+
+ public static function privileges_hierarchy( $options = 0 )
+ {
+ return proxy(
+ [\app\models\admin\Privilege_model::class, 'privileges'],
+ [], 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 3d0ac1c..d8a8a0e 100644
--- a/public/app/models/cms/Course_model.php
+++ b/public/app/models/cms/Course_model.php
@@ -6,6 +6,10 @@ use \Registry;
class Course_model {
+ /** COURSES
+ * -------------------------------------------------------------------------
+ */
+
/** get all categories
*
* raw table data (simplest SELECT)
@@ -19,6 +23,21 @@ class Course_model {
);
}
+ /** courses struct
+ *
+ * a super array with almost any info needed about courses
+ *
+ * @return (array) ['tree' => ..., 'breadcrumbs' => ... ]
+ */
+ public static function courses_struct()
+ {
+ $tree = self::category_tree();
+ return [
+ 'tree' => $tree,
+ 'breadcrumbs' => self::breadcrumbs($tree)
+ ];
+ }
+
/** constuct a category_tree
*
@@ -216,6 +235,32 @@ class Course_model {
}
+
+
+ /** LESSONS
+ * -------------------------------------------------------------------------
+ */
+
+
+ /** lessons of course
+ *
+ * @param $course_id
+ */
+
+ public static function lessons_of_course($id)
+ {
+ // TODO: order results in some way
+
+ 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",
+ [':id' => $id]
+ );
+ }
+
+
+
/** files
* return all files
* @param void
diff --git a/public/app/routes/backend.php b/public/app/routes/backend.php
index 5d6189d..475f52b 100644
--- a/public/app/routes/backend.php
+++ b/public/app/routes/backend.php
@@ -3,7 +3,7 @@
use app\controllers\Auth;
use app\controllers\admin\Course_admin;
use app\models\admin\Privilege_model;
-
+use app\extends\Cache_service;
// admin panel
// ---
@@ -91,10 +91,7 @@ Route::add('/admin/privileges', function () {
// ---
Route::add('/admin/api/privileges', function () {
Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
- Render::json( proxy(
- [\app\models\admin\Privilege_model::class, 'privileges'],
- [], CACHE_ROOT_TTL
- ));
+ Render::json( Cache_service::privileges_hierarchy() );
});
// add privilege
diff --git a/public/app/routes/frontend.php b/public/app/routes/frontend.php
index 898b23a..f9e74db 100644
--- a/public/app/routes/frontend.php
+++ b/public/app/routes/frontend.php
@@ -4,15 +4,13 @@ use app\controllers\Auth;
use app\controllers\Classroom_user;
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)
- 'categories' => proxy(
- [\app\models\cms\Course_model::class, 'category_tree'],
- [], CACHE_ROOT_TTL
- )
+ 'categories' => Cache_service::courses_struct()['tree']
]);
// header('Location: /some/default/url', true, 302);
});
@@ -46,8 +44,8 @@ Route::notFound( function() {
// Resolve urls
// --- -- -- - - -
-Route::add('/course/([0-9a-zA-Z-_]*)',
- function($label) { Course::show([$label]); }
+Route::add('/course/([0-9]*)',
+ function($id) { Course::course($id); }
);
Route::add('/lesson/([0-9a-f]*)/([0-9a-zA-Z-_]*)',
diff --git a/public/app/views/components/breadcrumbs.php b/public/app/views/components/breadcrumbs.php
index 471cfb6..90b4af9 100644
--- a/public/app/views/components/breadcrumbs.php
+++ b/public/app/views/components/breadcrumbs.php
@@ -5,7 +5,7 @@
* imported variables
* ---
* @param $id : category_id of last level
- * @param $title : category title of last level
+ * @param $label : category title of last level
* @param $parents : array of parent nodes
* -----------------------------------------------------------------------------
*/
@@ -18,13 +18,13 @@
<!-- parent nodes -->
<?php if ($id != 0) : ?>
<?php foreach($parents as $node) : ?>
- <i class="fas fa-angle-right"></i> <a href="/wiki/category?id=<?=$node['id']?>"><?=$node['title']?></a>
+ <i class="fas fa-angle-right"></i> <a href="/course/<?=$node['id']?>"><?=$node['label']?></a>
<?php endforeach; ?>
<?php endif; ?>
<!-- last (current) node -->
<?php if ($id != 0) : ?>
- <i class="fas fa-angle-right"></i> <a href="/wiki/category?id=<?=$id?>"><?=$title?></a>
+ <i class="fas fa-angle-right"></i> <a href="/course/<?=$id?>"><?=$label?></a>
<?php endif; ?>
</div> \ No newline at end of file
diff --git a/public/app/views/components/lessons_list.php b/public/app/views/components/lessons_list.php
new file mode 100644
index 0000000..1c59164
--- /dev/null
+++ b/public/app/views/components/lessons_list.php
@@ -0,0 +1,51 @@
+<?php
+/** lessons list
+ * -----------------------------------------------------------------------------
+ *
+ * imported variables:
+ * ---
+ * @param $lessons : array of lessons
+ * @param $fieldset : array of optional fields to show [category, intro, date]
+ *
+ * example call:
+ * ---
+ * Render::template("sections/articles_list.php",[
+ * 'articles' => $category_tree,
+ * 'fieldset' => ['date', 'intro']
+ * ])
+ * -----------------------------------------------------------------------------
+ */
+?>
+<div class="row">
+
+ <?php foreach($lessons as $post) : ?>
+
+ <!-- <div class="col-xl-4 col-lg-6"> -->
+ <div class="post-card">
+
+ <?php if (in_array('date', $fieldset)) : ?>
+ <?=$post['date']?>
+ <?php endif; ?>
+
+ <div class="post-card--content">
+
+ <h3>
+ <a href="/lesson/<?=$post['id']?>"><?=$post['title']?></a>
+ </h3>
+
+ <?php if (in_array('category', $fieldset)) : ?>
+ <p class="category"><?=$post['course_id']?></p>
+ <?php endif; ?>
+
+ <?php if (in_array('intro', $fieldset) && $post['intro']) : ?>
+ <p class="intro"><?=$post['intro']?></p>
+ <?php endif; ?>
+
+ </div>
+
+ </div>
+ <!-- </div> -->
+
+ <?php endforeach; ?>
+
+</div> \ No newline at end of file
diff --git a/public/app/views/components/subcategories.php b/public/app/views/components/subcategories.php
new file mode 100644
index 0000000..58f53fa
--- /dev/null
+++ b/public/app/views/components/subcategories.php
@@ -0,0 +1,18 @@
+<!-- Sub-Categories -->
+
+<?php if ($breadcrumbs[ $id ]['childs'] != []) : ?>
+
+ <h5>Υποκατηγορίες</h5>
+ <div class="category-childs">
+
+ <?php foreach($breadcrumbs[ $id ]['childs'] as $key => $child) : ?>
+
+ <a href="/course/<?=$child['id']?>" class="btn btn-light">
+ <?=$child['label']?>
+ </a>
+
+ <?php endforeach; ?>
+
+ </div>
+
+<?php endif; ?> \ No newline at end of file
diff --git a/public/app/views/components/top_bar.php b/public/app/views/components/top_bar.php
index ed96e35..0e6e437 100644
--- a/public/app/views/components/top_bar.php
+++ b/public/app/views/components/top_bar.php
@@ -3,9 +3,9 @@
<?php // breadcrumbs
////////////////////////////////////////////////////////////////////////
Render::template("components/breadcrumbs", [
- 'id' => 0,
- 'title' => '',
- 'parents' => []
+ 'id' => $id,
+ 'label' => $label,
+ 'parents' => $parents
]);
?>
diff --git a/public/app/views/templates/course.php b/public/app/views/templates/course.php
new file mode 100644
index 0000000..9d42297
--- /dev/null
+++ b/public/app/views/templates/course.php
@@ -0,0 +1,82 @@
+<!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[ $id ]['rec']['label'],
+ 'parents' => $breadcrumbs[ $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 course-view">
+
+ <!-- Category Title -->
+ <h3>
+ <?=$breadcrumbs[ $id ]['rec']['label']?>
+ </h3>
+
+
+ <!-- Sub-Categories -->
+ <?php
+ Render::view('components/subcategories',[
+ 'id' => $id,
+ 'breadcrumbs' => $breadcrumbs
+ ])
+ ?>
+
+
+ <!-- Articles List -->
+ <?php if ($lessons) : ?>
+
+ <h5>Μαθήματα</h5>
+
+ <?php // list of posts/articles
+ ////////////////////////////////////////////////////
+ Render::view("components/lessons_list", [
+ 'lessons' => $lessons,
+ 'fieldset' => ['intro'] // ['intro', 'date']
+ ]);
+ ?>
+ <?php endif; ?>
+
+
+
+
+ </div>
+
+ </div>
+ </div>
+
+
+ <script src="/assets/js/classroom.js"></script>
+</body>
+</html>
diff --git a/public/assets/css/class.css b/public/assets/css/class.css
index 6ee2c04..a65bfa2 100644
--- a/public/assets/css/class.css
+++ b/public/assets/css/class.css
@@ -164,8 +164,8 @@
* -----------------------------------------------------------------------------
*/
-.classroom .breadcrumb { counter-reset: var(--class-blue); }
-.classroom .breadcrumb i.fas { padding: 0 6px; }
+.classroom .breadcrumb a { counter-reset: var(--class-blue); font-size: 14px; }
+.classroom .breadcrumb i.fas { padding-top: 7px; font-size: 12px; }
@@ -229,11 +229,12 @@
+.classroom .course-view h5 { padding-top: 2em; }
/** sub-categories on category page
* -----------------------------------------------------------------------------
*/
-
+/*
.classroom .category-childs { margin: 1em; padding: 1em; }
.classroom .category-childs a {
@@ -253,7 +254,7 @@
text-decoration: none;
}
-
+*/
@@ -274,7 +275,7 @@
flex-grow: 1;
width: calc(100% - 90px);
}
-.classroom .post-card h3 { padding: 0; margin: 0; border: none; }
+.classroom .post-card h3 { padding: 0; margin: 0; border: none; font-size: 20px; }
.classroom .post-card h3 a { display: block; }
.classroom .post-card h3 a:hover { color: #f47920; }
.classroom .post-card .category { color: #566; }
diff --git a/public/assets/js/admin/files.js b/public/assets/js/admin/files.js
index bfb0c73..e100b30 100644
--- a/public/assets/js/admin/files.js
+++ b/public/assets/js/admin/files.js
@@ -1,6 +1,6 @@
// Globals
// -----------------------------------------------------------------------------
-var privileges = [];
+var privileges = [ { id: 0, label: 'Δημόσιο' } ];
var files = [];
var table;
@@ -34,16 +34,36 @@ if (!Array.prototype.indexOf)
};
}
+
+// function for sorting an array by 'label' attribute
+// --- -- -- - - -
+function compare_label (a,b) {
+ if ( a.label < b.label ) { return -1; }
+ if ( a.label > b.label ) { return 1; }
+ return 0;
+}
+
+
// return file record by file-id
// --- -- -- - - -
function privilege_record(id) {
var record = 0;
- files.forEach(el => { if (el.id == id) record = el; });
-
+ files.forEach(el => { if (el.id == id) record = el; });
return record;
}
+/** privilege(id)
+ * label of privilege with
+ * @param id (int)
+ */
+function privilege_(id) {
+ let reply = false;
+ privileges.forEach( pri => { if (pri.id == id) reply = pri.label; });
+ return reply;
+}
+
+
// create actions html (edit and delete buttons)
// --- -- -- - - -
function create_actions_html(id) {
@@ -106,6 +126,7 @@ $(document).ready(function() {
path: el.path,
type: el.type,
privilege_id: ((el.privilege_id == null) ? 0 : el.privilege_id),
+ privilege: privilege_( ((el.privilege_id == null) ? 0 : el.privilege_id) ),
actions: create_actions_html(el.id)
});
});
@@ -127,7 +148,7 @@ $(document).ready(function() {
{ data: 'label' },
{ data: 'path' },
{ data: 'type' },
- { data: 'privilege_id' },
+ { data: 'privilege' },
{ data: 'actions' }
]
});
@@ -138,7 +159,24 @@ $(document).ready(function() {
});
}
- init_table(); // init table on first run
+
+
+
+ $.getJSON( "/admin/api/privileges" )
+ .done( function( response ) {
+
+ // construct provileges data
+ // ---
+ response.forEach( el => {
+ privileges.push({
+ id: el.id,
+ label: el.label
+ });
+ });
+ privileges.sort( compare_label ); // sort categories by breadcrumb
+
+ init_table(); // init table on first run
+ });
diff --git a/public/assets/js/admin/lessons.js b/public/assets/js/admin/lessons.js
index 8391f4d..1a08875 100644
--- a/public/assets/js/admin/lessons.js
+++ b/public/assets/js/admin/lessons.js
@@ -1,7 +1,7 @@
// Globals
// -----------------------------------------------------------------------------
var categories = [];
-var privileges = [];
+var privileges = [ { id: 0, label: 'Δημόσιο' } ];
var lessons = [];
var table;
@@ -36,9 +36,6 @@ if (!Array.prototype.indexOf)
}
-// Supplamentary functions
-// -----------------------------------------------------------------------------
-
// function for sorting an array by 'label' attribute
// --- -- -- - - -
function compare_label (a,b) {
@@ -65,25 +62,45 @@ function lesson_record(id) {
return record;
}
+/** course(id)
+ * label of course with
+ * @param id (int)
+ */
+function course_(id) {
+ let reply = false;
+ categories.forEach( cat => { if (cat.id == id) reply = cat.label; })
+ return reply;
+}
-// return children of parent
-// --- -- -- - - -
-function childs_of_parents(list) {
- // if 'list' is integer then make it an one-item list
- parents = (Number.isInteger(list)) ? [ list ] : list;
-
- var childs = [];
-
- if (parents.length == 0) { return []; }
-
- parents.forEach( pid => {
- categories.forEach( el => { if (el.parent == pid) childs.push(el.id)});
- });
+/** privilege(id)
+ * label of privilege with
+ * @param id (int)
+ */
+function privilege_(id) {
+ let reply = false;
+ privileges.forEach( pri => { if (pri.id == id) reply = pri.label; });
+ return reply;
+}
- var grandchilds = childs_of_parents(childs);
- return childs.concat(grandchilds);
-}
+//// return children of parent
+//// --- -- -- - - -
+//function childs_of_parents(list) {
+// // if 'list' is integer then make it an one-item list
+// parents = (Number.isInteger(list)) ? [ list ] : list;
+//
+// var childs = [];
+//
+// if (parents.length == 0) { return []; }
+//
+// parents.forEach( pid => {
+// categories.forEach( el => { if (el.parent == pid) childs.push(el.id)});
+// });
+//
+// var grandchilds = childs_of_parents(childs);
+//
+// return childs.concat(grandchilds);
+//}
// create actions html (edit and delete buttons)
@@ -132,6 +149,7 @@ $(document).ready(function() {
// ...
$("#privilege_id").select2({
placeholder: 'Επίπεδο Πρόσβασης',
+ dropdownParent: $('#manageLessons'),
width: '100%'
});
@@ -168,7 +186,9 @@ $(document).ready(function() {
id: parseInt(el.id),
title: el.title,
course_id: el.course_id,
+ course: course_(el.course_id),
privilege_id: el.privilege_id,
+ privilege: privilege_(el.privilege_id),
actions: create_actions_html(el)
});
});
@@ -188,8 +208,8 @@ $(document).ready(function() {
columns: [
{ data: 'id' },
{ data: 'title' },
- { data: 'course_id' },
- { data: 'privilege_id' },
+ { data: 'course' },
+ { data: 'privilege' },
{ data: 'actions' }
]
});
@@ -269,89 +289,47 @@ $(document).ready(function() {
* ... prepare the manage-category form
* ... update select2 with possible parents
*/
- $('#manageCategory').on('show.bs.modal', event => {
+ $('#manageLesson').on('show.bs.modal', event => {
var button = $(event.relatedTarget); // Button that triggered the modal
var id = parseInt( button.data('id') ); // category_id from data-id
// var modal = $(this); // modal object
- // update modal literature
- // ---
- $('#manageCategory .modal-title').html( // modal title
- (id) ? 'Ενημέρωση Κατηγορίας' : 'Δημιουργία Κατηγορίας'
- );
- $('#manageCategory form input[name=id]').val( id ); // category id (hidden)
- $('#manageCategory form input[name=label]').val( // category label
- (id) ? category_record(id).label : ""
- );
- prepare_parents_element(id); // prepare <select> for parents
+ //// update modal literature
+ //// ---
+ //$('#manageCategory .modal-title').html( // modal title
+ // (id) ? 'Ενημέρωση Κατηγορίας' : 'Δημιουργία Κατηγορίας'
+ //);
+ //$('#manageCategory form input[name=id]').val( id ); // category id (hidden)
+ //$('#manageCategory form input[name=label]').val( // category label
+ // (id) ? category_record(id).label : ""
+ //);
+ //prepare_parents_element(id); // prepare <select> for parents
})
-// /** prepare_parents_element()
-// * ---
-// * @param id (int) : id of selected category
-// * -> Get all posible parents
-// * -> call set_parent_options() to render the options
-// */
-// function prepare_parents_element(id) {
-// var parents = [];
-//
-// if (id) { // get all possible parents
-//
-// // id-category and subcategories are fobiden parents
-// var forbiden = childs_of_parents(id);
-// forbiden.push(id);
-//
-// // filter catogories adn prepare parents
-// categories.forEach( el => {
-// if (!forbiden.includes(el.id)) {
-// parents.push({
-// id: el.id,
-// breadcrumb: el.breadcrumb,
-// });
-// }
-// });
-// set_parent_options(parents, category_record(id).parent);
-//
-//
-// } else { // new record; all categories are possible parrents
-// categories.forEach( el => {
-// parents.push({
-// id: el.id,
-// breadcrumb: el.breadcrumb,
-// });
-// })
-// set_parent_options(parents, -1);
-// }
-// }
/** set_parent_options()
+ *
* -> create options for parents <select>
* -> choose selected parent
+ *
+ * NOTE:
+ * the targer <select> should be a select2 control
+ *
* @param parents (array): array of parents
* @param selected (int): selected parent
*/
- function set_select_options(parents, selected) {
- // sort parents by breadcrumb
- parents.sort( compare_breadcrumb );
+ function set_parent_options(selector, list, selected_value = false) {
- // remove any olded options from select2
- $('#parent_id option').each(function() { $(this).remove(); });
-
- // first option is the root category
- $('#parent_id').append('<option value="0">Root</option>')
-
- // add all other parent options
- parents.forEach( i => {
- $('#parent_id').append(`<option value="${i.id}">${i.breadcrumb}</option>`);
- });
-
- if (selected == -1) { // new category; remove any parent pre-selection
- $('#parent_id').val(null).trigger('change');
-
- } else { // category exists; choose selected parent
- $('#parent_id').val(selected).trigger('change');
+ list.forEach( li => { // attach options into <select> control
+ selector.append(`<option value="${li.id}">${li.label}</option>`);
+ });
+
+ if (selected_value !== false) { // mark selected option(s)
+ selector.val(selected_value).trigger('change');
+ }
+ else { selector.val(null).trigger('change'); }
}
- }
+