summaryrefslogtreecommitdiff
path: root/public/app
diff options
context:
space:
mode:
authorGeorge Halkiadakis <gchalkiadakis@sklavenitis.co.gr>2023-04-24 04:36:57 +0300
committerGeorge Halkiadakis <gchalkiadakis@sklavenitis.co.gr>2023-04-24 04:36:57 +0300
commit17d243371c43847e9dbdeb21395afc0e8f5437ae (patch)
tree7dfe75fe664826f2b1575d13f09e75a500b605fb /public/app
parent74f1c04022328280b996dde0b7089e13d96acf70 (diff)
downloadclassroom-17d243371c43847e9dbdeb21395afc0e8f5437ae.tar.gz
classroom-17d243371c43847e9dbdeb21395afc0e8f5437ae.tar.bz2
classroom-17d243371c43847e9dbdeb21395afc0e8f5437ae.zip
edit lesson: putting all together; media with privile level
Diffstat (limited to 'public/app')
-rw-r--r--public/app/controllers/Auth.php7
-rw-r--r--public/app/controllers/admin/Course_admin.php282
-rw-r--r--public/app/controllers/cms/Course.php36
-rw-r--r--public/app/models/cms/Course_model.php11
-rw-r--r--public/app/routes/backend.php77
-rw-r--r--public/app/routes/frontend.php8
-rw-r--r--public/app/views/admin/admin-menu.php6
-rw-r--r--public/app/views/admin/edit_lesson.php2
-rw-r--r--public/app/views/admin/files.php96
-rw-r--r--public/app/views/admin/panel.php4
-rw-r--r--public/app/views/components/header_includes.php5
11 files changed, 506 insertions, 28 deletions
diff --git a/public/app/controllers/Auth.php b/public/app/controllers/Auth.php
index d7b0c3b..b00843c 100644
--- a/public/app/controllers/Auth.php
+++ b/public/app/controllers/Auth.php
@@ -322,6 +322,13 @@ class Auth {
}
+ public static function is_admin()
+ {
+ $manager = new Classroom_manager();
+ return ($manager->isGranted([1,2,3]));
+ }
+
+
}
diff --git a/public/app/controllers/admin/Course_admin.php b/public/app/controllers/admin/Course_admin.php
index ef9ef0e..d1048b7 100644
--- a/public/app/controllers/admin/Course_admin.php
+++ b/public/app/controllers/admin/Course_admin.php
@@ -98,6 +98,167 @@ class Course_admin {
}
+ ## -------------------------------------------------------------------------
+ ##
+ ## LESSON METHODS
+ ##
+ ## -------------------------------------------------------------------------
+
+
+ /** get_lesson
+ *
+ * @param $id (int) : lesson's id
+ */
+ public static function get_lesson($id)
+ {
+ // get (first) lesson with id = $id; render as json
+ Render::json(Registry::use('database')->query(
+ "SELECT lesson.*,
+ ( SELECT
+ CONCAT('[', GROUP_CONCAT(JSON_OBJECT(
+ 'id', media.id,
+ 'label', media.label,
+ 'type', media.type,
+ 'path', media.path )),
+ ']')
+ FROM media
+ LEFT JOIN lesson_media ON lesson_media.media_id = media.id
+ WHERE lesson_media.lesson_id = :id
+ ) AS medias_json,
+ lesson_privilege.privilege_id
+ FROM lesson
+ LEFT JOIN lesson_privilege ON lesson_privilege.lesson_id = lesson.id
+ WHERE lesson.id = :id",
+ [ ':id' => $id]
+ )->getFirst());
+ }
+
+
+ /** add_lesson
+ * insert a new lesson
+ *
+ * all parametres are passed via $_POST array
+ *
+ * POST @param title
+ * POST @param course_id
+ * POST @param intro
+ * POST @param body
+ * POST @param published
+ */
+ public static function add_lesson()
+ {
+ $post = Registry::get('REQUEST')->POST;
+
+ // insert lesson content into daabase
+ $id = Registry::use('database')->query(
+ "INSERT INTO lesson (title, course_id, intro, `body`, `status`)
+ VALUES (:title, :courseid, :intro, :body, :status)",
+ [
+ ':title' => $post['title'],
+ ':courseid' => $post['course_id'],
+ ':intro' => $post['intro'],
+ ':body' => $post['body'],
+ 'status' => $post['status']
+ ]
+ )->lastInsertID();
+
+ // set lesson privileges to database
+ Registry::use('database')->runQuery(
+ "INSERT INTO lesson_privilege (lesson_id, privilege_id)
+ VALUES (:lesson_id, :privilege_id)",
+ [
+ ':lesson_id' => $id,
+ ':privilege_id' => $post['privilege_id']
+ ]
+ );
+
+ // update media's privileges
+ 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']);
+
+ return true;
+ }
+
+
+ public static function update_lesson()
+ {
+ $post = Registry::get('REQUEST')->POST;
+
+ // print_r($post); die();
+
+ // update lesson's content
+ Registry::use('database')->query(
+ "UPDATE lesson
+ SET title = :title,
+ course_id = :courseid,
+ intro = :intro, `body` = :body,
+ `status` = :status
+ WHERE id = :id",
+ [
+ ':id' => $post['id'],
+ ':title' => $post['title'],
+ ':courseid' => $post['course_id'],
+ ':intro' => $post['intro'],
+ ':body' => $post['body'],
+ ':status' => $post['status']
+ ]
+ );
+
+ // update lesson's privileges
+ Registry::use('database')->runQuery(
+ "UPDATE lesson_privilege SET privilege_id = :privilege_id
+ WHERE lesson_id = :lesson_id",
+ [
+ ':lesson_id' => $post['id'],
+ ':privilege_id' => $post['privilege_id']
+ ]
+ );
+
+ // 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(
+ "DELETE from lesson_media WHERE lesson_id = :lesson",
+ [ ':lesson' => $post['id'] ]
+ );
+
+ // update lesson's media files
+ self::create_medias_for_lesson($post['media'], $post['id'], $post['privilege_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;
+ }
+
## -------------------------------------------------------------------------
@@ -107,18 +268,66 @@ class Course_admin {
## -------------------------------------------------------------------------
+ /** files
+ * echo all files
+ * @return (array)
+ */
+ public static function files()
+ {
+ return proxy( // cache-get files
+ [\app\models\cms\Course_model::class, 'files'],
+ [], CACHE_ROOT_TTL
+ );
+ }
+
+
/** upload_file
* upload the file to the file system
*
* the method reads the POST and FILES array
* to retrieve all needed parametres
*
- * + $_FILES[file]
- * + $_POST[folder] : lesson's ID
- * + $_POST[reference] : reference type
+ * FILES @param file
+ * POST @param folder : lesson's ID or somthing random
+ * POST @param reference : reference type
+ * POST @param
*/
public static function upload_file()
{
+ $request = Registry::get('REQUEST');
+
+ $uploaded = self::upload_to_fs(); // upload file to file-system
+
+ if ($uploaded['success']) {
+
+ $media_id = self::define_media([ // define media in database; get id
+ 'title' => $request->POST['title'],
+ 'type' => $uploaded['type'],
+ 'path' => $uploaded['path']
+ ]);
+
+ Render::json([ // render results as json
+ 'success' => true,
+ 'id' => $media_id,
+ 'title' => $request->POST['title'],
+ 'path' => $uploaded['path'],
+ 'type' => $uploaded['type']
+ ]);
+
+ } else {
+ Render::json(['success' => false ]);
+ }
+ }
+
+
+ /** upload to fs
+ * upload file to File-System
+ *
+ * POST @param folder
+ * FILES @param file
+ */
+ private static function upload_to_fs()
+ {
$post = Registry::get('REQUEST')->POST;
$files = Registry::get('REQUEST')->FILES;
@@ -181,7 +390,7 @@ class Course_admin {
if (move_uploaded_file($files["file"]["tmp_name"], $store_filename)) {
return [
'success' => true,
- 'path' => $store_filename,
+ 'path' => $relative_filename,
'type' => $mime_type
];
@@ -207,22 +416,61 @@ class Course_admin {
*
* create a record in media table
*
- * @param $data
+ * @param $data (array): [title => , path => , type => mime-type]
* @return id (int): id of created media record
*/
- public static function define_media($data)
+ private static function define_media($data)
{
- $sql = "INSERT INTO wiki_media (`title`, `type`, `path`)
- VALUES (:title, :mimetype, :filepath)";
- $stmt = $this->pdo->prepare($sql);
- $stmt->execute([
- 'title' => $data['title'],
- 'mimetype' => $data['type'],
- 'filepath' => $data['path']
- ]);
- $inserted_id = $this->pdo->lastInsertId();
-
- return $inserted_id;
+ $request = Registry::get('REQUEST');
+
+ $media_id = Registry::use('database')->query(
+ "INSERT INTO media (label, `type`, `path`)
+ VALUES (:label, :mimetype, :filepath)",
+ [
+ 'label' => $data['title'],
+ 'mimetype' => $data['type'],
+ 'filepath' => $data['path']
+ ]
+ )->lastInsertID();
+ return $media_id;
+ }
+
+
+ /** create media for post
+ *
+ * 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)
+ */
+ private static function create_medias_for_lesson($medias, $lesson_id)
+ {
+ foreach($medias as $key => $medi) {
+ self::link_media_to_lesson($medi, $lesson_id); // link to lesson
+ }
+ return true;
+ }
+
+
+ /** link one media-file to a specific post
+ *
+ * NOTE:
+ * the method does not check if media is linked already
+ * so be sure that the pair of (media_id,post_id) not exist
+ *
+ * @param $media_id (int)
+ * @param $lesson_id (int)
+ */
+ private static function link_media_to_lesson( $media_id, $lesson_id )
+ {
+ Registry::use('database')->runQuery(
+ "INSERT INTO lesson_media (lesson_id, media_id)
+ VALUES (:lesson, :media)",
+ [
+ 'lesson' => $lesson_id,
+ 'media' => $media_id,
+ ]
+ );
+ return true;
}
diff --git a/public/app/controllers/cms/Course.php b/public/app/controllers/cms/Course.php
new file mode 100644
index 0000000..b671a5f
--- /dev/null
+++ b/public/app/controllers/cms/Course.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace app\controllers\cms;
+
+use Registry;
+use Render;
+use app\controllers\Auth;
+use app\models\cms\Course_model;
+
+class Course {
+
+ /** serve file by file_path
+ * (request is valid only for admin users)
+ *
+ * @param $file_path (string): relative file path
+ * GET @param type (string) : media-type of file
+ */
+ public static function serve_file($file_path)
+ {
+ // check privileges
+ if (Auth::is_admin()) { // TODO: -OR- has prvivilege
+
+ $media_type = Registry::get('REQUEST')->GET['type']; // get media-type
+ $real_path = MEDIA_STORAGE_ROOT . $file_path; // construct real path
+
+ if (!file_exists($real_path)) {
+ Render::view('error/404');
+
+ } else {
+ Render::file($real_path, $media_type);
+ }
+
+ }
+ }
+
+} \ 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 4740a4f..3d0ac1c 100644
--- a/public/app/models/cms/Course_model.php
+++ b/public/app/models/cms/Course_model.php
@@ -216,5 +216,16 @@ class Course_model {
}
+ /** files
+ * return all files
+ * @param void
+ * @return array
+ */
+ public static function files()
+ {
+ return Registry::use('database')->runQuery("SELECT * from media", []);
+ }
+
+
}
diff --git a/public/app/routes/backend.php b/public/app/routes/backend.php
index 704d161..7f4717d 100644
--- a/public/app/routes/backend.php
+++ b/public/app/routes/backend.php
@@ -4,6 +4,25 @@ use app\controllers\Auth;
use app\controllers\admin\Course_admin;
use app\models\admin\Privilege_model;
+
+// admin panel
+// ---
+Route::add('/admin', function () {
+ 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
+ Render::view('admin/skeleton', [
+ 'title' => 'Διαχείριση Classroom',
+ 'action' => 'panel',
+ ]);
+});
+
+
// admin lessons
// ---
Route::add('/admin/lessons', function () {
@@ -15,7 +34,7 @@ Route::add('/admin/lessons', function () {
});
-// admin categories (=courses)
+// admin categories (=courses) /////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// manage categories page
@@ -54,7 +73,7 @@ Route::add('/admin/api/categories/update', function () {
);
-// admin privileges
+// admin privileges ////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// manage privileges page
@@ -84,8 +103,12 @@ Route::add('/admin/api/privileges', function () {
-// new lesson
+// admin lesson ////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
+
+
+// new lesson
+// ---
Route::add('/admin/edit_lesson', function () {
Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
Render::view('admin/skeleton', [
@@ -94,18 +117,55 @@ Route::add('/admin/edit_lesson', function () {
]);
});
-// new lesson
-// -----------------------------------------------------------------------------
+// edit lesson (give lesson-id)
+// ---
Route::add('/admin/edit_lesson/([0-9]*)', function ($id) {
Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
Render::view('admin/skeleton', [
- 'title' => 'Νέο Μάθημα',
+ 'title' => 'Επεξεργασία Μαθήματος',
'action' => 'edit_lesson',
'id' => intval($id)
]);
});
+// ajax: get lesson
+// ---
+Route::add('/admin/api/lesson/([0-9]*)', function ($id) {
+ Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
+ Course_admin::get_lesson($id);
+});
+
+
+Route::add('/admin/api/lesson/add', function () {
+ Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
+ Course_admin::add_lesson();
+}, 'post');
+
+
+Route::add('/admin/api/lesson/update', function () {
+ Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
+ Course_admin::update_lesson();
+}, 'post');
+
+
+
+// admin files /////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+Route::add('/admin/files', function () {
+ Auth::allowRoles([1, 2, 3]);
+ Render::view('admin/skeleton', [
+ 'title' => 'Διαχείριση Μέσων (media)',
+ 'action' => 'files',
+ ]);
+});
+// ajax: get lesson
+// ---
+Route::add('/admin/api/files', function () {
+ Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
+ Render::json(Course_admin::files());
+});
// ajax: file-upload
// ---
@@ -113,3 +173,8 @@ Route::add('/admin/api/file_upload', function () {
Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles
Render::json(Course_admin::upload_file());
}, 'post');
+
+
+
+
+
diff --git a/public/app/routes/frontend.php b/public/app/routes/frontend.php
index dde0fcd..898b23a 100644
--- a/public/app/routes/frontend.php
+++ b/public/app/routes/frontend.php
@@ -2,6 +2,7 @@
use app\controllers\Auth;
use app\controllers\Classroom_user;
+use app\controllers\cms\Course;
use app\models\cms\Course_model;
// Home/Welcome
@@ -65,6 +66,13 @@ Route::add('/about/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)/([0-9a-zA-Z-_]*)',
);
+// serve file
+// ---
+Route::add('/serve/file/([0-9a-zA-Z-_\.\/]*)', function ($path) {
+ Course::serve_file($path);
+});
+
+
/** URL-format Proposal:
* -----------------------------------------------------------------------------
*
diff --git a/public/app/views/admin/admin-menu.php b/public/app/views/admin/admin-menu.php
index 92c2f54..b783b39 100644
--- a/public/app/views/admin/admin-menu.php
+++ b/public/app/views/admin/admin-menu.php
@@ -17,10 +17,12 @@
*/
$admin_options = [
+ 'panel' => 'Διαχείριση',
'edit_lesson' => 'Νέο Μάθημα',
'lessons' => 'Μαθήματα',
'categories' => 'Κεφάλαια',
- 'pages' => 'Σελίδες',
+ // 'pages' => 'Σελίδες',
+ 'files' => 'Αρχεία',
'privileges' => 'Πρόσβαση',
'users' => 'Χρήστες'
];
@@ -28,8 +30,6 @@ $admin_options = [
<div class="top-bar">
- <span class="btn btn-warning">Admin</span>
-
<?php foreach($admin_options as $opt => $label) : ?>
<?php if (($opt == $action) & (!$id)) : ?>
diff --git a/public/app/views/admin/edit_lesson.php b/public/app/views/admin/edit_lesson.php
index 7d74c38..ef875b4 100644
--- a/public/app/views/admin/edit_lesson.php
+++ b/public/app/views/admin/edit_lesson.php
@@ -16,7 +16,7 @@
<div><h5><?=$action_title?></h5></div>
<div>
<button type="button" class="btn pull-right"
- data-toggle="modal" data-target="#editorModal" data-action="preview">
+ data-bs-toggle="modal" data-bs-target="#editorModal" data-action="preview">
<i class="fas fa-search"></i> &nbsp; Προεπισκόπηση
</button>
</div>
diff --git a/public/app/views/admin/files.php b/public/app/views/admin/files.php
new file mode 100644
index 0000000..c6d2771
--- /dev/null
+++ b/public/app/views/admin/files.php
@@ -0,0 +1,96 @@
+ <!-- title bar -->
+ <div class="title-bar">
+ <div><h5>Διαχείριση Επιπέδων Πρόσβασης</h5></div>
+ <div>
+ <!-- Button trigger modal
+ <button type="button" class="btn pull-right"
+ data-bs-toggle="modal" data-bs-target="#managePrivileges" data-id="0">
+ <i class="fas fa-plus"></i> &nbsp; Νέο Επίπεδο
+ </button>
+ -->
+ </div>
+</div>
+
+<div class="manage">
+ <div class="row">
+ <div class="col-md-12">
+
+ <div id="files">
+
+ <table id="dt-files" class="table table-responsive dt-table" style="width:100%">
+ <thead>
+ <th class="dt-id">α/α</th>
+ <th class="dt-label">Περιγραφή</th>
+ <th class="dt-path">Διαδρομή</th>
+ <th class="dt-type">Media-Type</th>
+ <th class="dt-privilege">Πρόσβαση</th>
+ <th class="dt-actions"></th>
+ </thead>
+ </table>
+
+ </div>
+
+
+ </div>
+ </div>
+</div><!-- /manage -->
+
+
+
+<!-- MODAL for new/edit category -->
+<!-- NOTE: tabindex="-1" removed, ref:https://github.com/select2/select2-bootstrap-theme/issues/41 -->
+<div class="modal fade" id="manageFiles" aria-labelledby="myModalLabel" aria-hidden="true">
+ <div class="modal-dialog modal-lg" role="document">
+ <div class="modal-content">
+
+ <form method="post" action="">
+
+ <div class="modal-header">
+ <h4 class="modal-title" id="myModalLabel">Πρόσβαση αρχείου</h4>
+ <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
+ </div><!-- /modal-header -->
+
+ <!-- modal-body -->
+ <div class="modal-body">
+
+ <!-- form fields -->
+
+ <div class="row form-group">
+ <label class="control-label col-sm-12" for="label">Κατηγορία Επιπέδου Πρόσβασης</label>
+ <div class="col-sm-12">
+ <input class="form-control form-control-sm" type="text" name="label" value="" required="">
+ </div>
+ </div>
+
+ <div class="row form-group">
+ <label class="control-label col-sm-12" for="included_id">Κατηγορία Επιπέδου Πρόσβασης</label>
+ <div class="col-sm-12">
+ <select class="form-control form-control-sm form-select form-select-sm" id="privilege_id" name="privilege_id" required></select>
+ </div>
+ </div>
+
+ <div class="row form-group">
+ <input type="hidden" name="id" value="0"><!-- action = (0) ? 'new' : 'edit' -->
+ </div>
+
+
+ </div><!-- /modal body -->
+
+ <div class="modal-footer">
+ <div class="row form-actions">
+
+ <div class="col">
+ <button type="button" class="btn btn-default js-modal-close col-sm-12" data-bs-dismiss="modal">Κλείσιμο</button>
+ </div>
+ <div class="col">
+ <button class="btn btn-success col-sm-12" type="submit">Καταχώριση</button>
+ </div>
+
+ </div>
+ </div><!-- /modal-footer -->
+
+ </form><!-- /form -->
+
+ </div>
+ </div>
+</div>
diff --git a/public/app/views/admin/panel.php b/public/app/views/admin/panel.php
new file mode 100644
index 0000000..59b8cba
--- /dev/null
+++ b/public/app/views/admin/panel.php
@@ -0,0 +1,4 @@
+<br/>
+<br/>
+<br/>
+<h4>Admin panel</h4> \ No newline at end of file
diff --git a/public/app/views/components/header_includes.php b/public/app/views/components/header_includes.php
index e5e51cd..62dc616 100644
--- a/public/app/views/components/header_includes.php
+++ b/public/app/views/components/header_includes.php
@@ -49,7 +49,10 @@
<script src="https://cdn.datatables.net/v/bs5/jszip-2.5.0/dt-1.13.4/b-2.3.6/b-colvis-2.3.6/b-html5-2.3.6/b-print-2.3.6/cr-1.6.2/date-1.4.0/fc-4.2.2/fh-3.3.2/kt-2.8.2/r-2.4.1/rr-1.3.3/sc-2.1.1/sl-1.6.2/sr-1.2.2/datatables.min.js"></script>
<!-- select2 js -->
- <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
+ <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
+
+ <!-- marked -->
+ <script src="/assets/js/marked/marked.min.js"></script>
<?php endif ?>