diff options
| author | George Halkiadakis <gchalkiadakis@sklavenitis.co.gr> | 2023-04-22 13:15:14 +0300 |
|---|---|---|
| committer | George Halkiadakis <gchalkiadakis@sklavenitis.co.gr> | 2023-04-22 13:15:14 +0300 |
| commit | 74f1c04022328280b996dde0b7089e13d96acf70 (patch) | |
| tree | 5488a13587f6a86aa631ecbbb370efb143a9610f /public | |
| parent | a647a6180e6f2b0a3c3aaddc40bc2dcf5f396429 (diff) | |
| download | classroom-74f1c04022328280b996dde0b7089e13d96acf70.tar.gz classroom-74f1c04022328280b996dde0b7089e13d96acf70.tar.bz2 classroom-74f1c04022328280b996dde0b7089e13d96acf70.zip | |
edit lesson: media handling
Diffstat (limited to 'public')
| -rw-r--r-- | public/app/config/app_constants.php | 3 | ||||
| -rw-r--r-- | public/app/controllers/admin/Course_admin.php | 136 | ||||
| -rw-r--r-- | public/app/routes/backend.php | 25 | ||||
| -rw-r--r-- | public/app/views/admin/categories.php | 10 | ||||
| -rw-r--r-- | public/app/views/admin/edit_lesson.php | 12 | ||||
| -rw-r--r-- | public/assets/css/overides.css | 4 | ||||
| -rw-r--r-- | public/assets/js/admin/categories.js | 2 | ||||
| -rw-r--r-- | public/assets/js/admin/edit_lesson.js | 45 | ||||
| -rw-r--r-- | public/files/.gitkeep | 0 |
9 files changed, 196 insertions, 41 deletions
diff --git a/public/app/config/app_constants.php b/public/app/config/app_constants.php index 0d04dc2..529d04a 100644 --- a/public/app/config/app_constants.php +++ b/public/app/config/app_constants.php @@ -4,7 +4,7 @@ // Default Values (user-privileges and user-roles) -// read ini file id exist +// read ini file if exist // --- -- -- - - - if (file_exists("../core/auth/.env")) { $env = parse_ini_file("../core/auth/.env"); @@ -12,6 +12,7 @@ if (file_exists("../core/auth/.env")) { + // CENTRAL DEFAULTS //////////////////////////////////////////////////////////// // ----------------------------------------------------------------------------- diff --git a/public/app/controllers/admin/Course_admin.php b/public/app/controllers/admin/Course_admin.php index 0e34e00..ef9ef0e 100644 --- a/public/app/controllers/admin/Course_admin.php +++ b/public/app/controllers/admin/Course_admin.php @@ -9,6 +9,13 @@ use app\models\cms\Course_model; class Course_admin { + ## ------------------------------------------------------------------------- + ## + ## COURSE (category) METHODS + ## + ## ------------------------------------------------------------------------- + + /** breadcrumbs * --- * responds to ajax GET: /admin/api/categories @@ -90,4 +97,133 @@ class Course_admin { ]; } + + + + ## ------------------------------------------------------------------------- + ## + ## FILE METHODS + ## + ## ------------------------------------------------------------------------- + + + /** 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 + */ + public static function upload_file() + { + $post = Registry::get('REQUEST')->POST; + $files = Registry::get('REQUEST')->FILES; + + + // Checks before uploading the file + //////////////////////////////////////////////////////////////////////// + + // ** 1: file is upladed to temporary folder --------------------------- + if (! is_uploaded_file($files['file']['tmp_name'])) { + return ['success' => false]; // bye! + } + + // ** 2: File belongs to the allowed MIME types ------------------------ + $allowed_file_types = array( + 'application/pdf', + 'image/png', 'image/jpeg', + 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + ); + // Recomended MIME type checking via mime_content_type(): + $mime_type = mime_content_type($files['file']['tmp_name']); + if (! in_array($mime_type, $allowed_file_types)) { // File type NOT allowed ... + return ['success' => false]; // bye! + } + + $file_name = $files['file']['name']; + $file_type = $files['file']['type']; // do not take it for granted + $file_size = $files['file']['size']; + $file_tmp = $files['file']['tmp_name']; + + $bare_name = pathinfo($file_name, PATHINFO_FILENAME); + $file_ext = pathinfo($file_name, PATHINFO_EXTENSION); + + + // ** 3: filename or size checks may be added -------------------------- + if ($file_name == "") { + return ['success' => false]; // bye! + } + + + // READY to finaly save/upload the file to CDN ///////////////////////// + + $folder = MEDIA_STORAGE_ROOT . $post['folder']; + if (!file_exists($folder)) { // create folder if not exists + mkdir($folder, 0757, true); + } + + // print_r([ + // 'dir' => $folder, + // 'file' => $bare_name, + // 'ext' => $file_ext, + // 'type' => $file_type + // ]); die(); + + $relative_filename = $post['folder'] + .'/' + . strtolower(self::clear_file_name($bare_name) .'.'. $file_ext); + $store_filename = MEDIA_STORAGE_ROOT . $relative_filename; + + if (move_uploaded_file($files["file"]["tmp_name"], $store_filename)) { + return [ + 'success' => true, + 'path' => $store_filename, + 'type' => $mime_type + ]; + + } else { return ['success' => false]; } + + } + + + /** clear_file_name + * replace greek characters and strip symbols + */ + private static function clear_file_name($str) + { + $el = mb_split( "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωάέήίόύώϊϋς ", ""); + $en = str_split("ABGDEZHUIKLMNJOPRSTYFXCVabgdezhuiklmnjoprstyfxcvaehioyviys-"); + $strip = str_split("!@#$%^&*()+~`[]{};'/<>?=\""); + + return str_replace($strip, '', str_replace($el, $en, $str)); + } + + + /** define_media + * + * create a record in media table + * + * @param $data + * @return id (int): id of created media record + */ + public 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; + } + + }
\ No newline at end of file diff --git a/public/app/routes/backend.php b/public/app/routes/backend.php index 88bf4b8..704d161 100644 --- a/public/app/routes/backend.php +++ b/public/app/routes/backend.php @@ -15,7 +15,7 @@ Route::add('/admin/lessons', function () { }); -// admin cateogies +// admin categories (=courses) // ----------------------------------------------------------------------------- // manage categories page @@ -23,7 +23,7 @@ Route::add('/admin/lessons', function () { Route::add('/admin/categories', function () { Auth::allowRoles([1, 2, 3]); Render::view('admin/skeleton', [ - 'title' => 'Διαχείριση Κατηγοριών', + 'title' => 'Διαχείριση Κεφαλαίων', 'action' => 'categories', ]); }); @@ -39,16 +39,14 @@ Route::add('/admin/api/categories', function () { // ajax: add new category (course) // --- -Route::add('/admin/api/category/add', function () { - Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles - Course_admin::add_course(); - }, - 'post' -); +Route::add('/admin/api/categories/add', function () { + Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles + Course_admin::add_course(); +}, 'post'); // ajax: edit category (course) // --- -Route::add('/admin/api/category/update', function () { +Route::add('/admin/api/categories/update', function () { Auth::allowRoles([1, 2, 3]); // allow few admin-panel roles Course_admin::update_course(); }, @@ -106,3 +104,12 @@ Route::add('/admin/edit_lesson/([0-9]*)', function ($id) { 'id' => intval($id) ]); }); + + + +// ajax: file-upload +// --- +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/views/admin/categories.php b/public/app/views/admin/categories.php index 91acec1..26fd5a2 100644 --- a/public/app/views/admin/categories.php +++ b/public/app/views/admin/categories.php @@ -5,7 +5,7 @@ <!-- Button trigger modal --> <button type="button" class="btn pull-right" data-bs-toggle="modal" data-bs-target="#manageCategory" data-id="0"> - <i class="fas fa-plus"></i> Νέα Κατηγορία + <i class="fas fa-plus"></i> Νέο Κεφάλαιο </button> </div> </div> @@ -18,7 +18,7 @@ <table id="dt-categories" class="table table-responsive dt-table" style="width:100%"> <thead> - <th class="dt-breadcrumb">Κατηγορία</th> + <th class="dt-breadcrumb">Κατηγορία/Κεφάλαιο</th> <th class="dt-actions"></th> </thead> </table> @@ -72,12 +72,12 @@ </div><!-- /modal body --> <div class="modal-footer"> - <div class="row"> + <div class="row" style="width: 50%;"> <div class="form-actions"> - <div class="col-xs-4"> + <div class="col-4"> <button type="button" class="btn btn-default js-modal-close col-sm-12" data-bs-dismiss="modal">Κλείσιμο</button> </div> - <div class="col-xs-8"> + <div class="col-8"> <button class="btn btn-success col-sm-12" type="submit">Καταχώριση</button> </div> </div> diff --git a/public/app/views/admin/edit_lesson.php b/public/app/views/admin/edit_lesson.php index 4ea8104..7d74c38 100644 --- a/public/app/views/admin/edit_lesson.php +++ b/public/app/views/admin/edit_lesson.php @@ -96,7 +96,7 @@ <!-- Button trigger modal --> <button type="button" class="btn btn-sm btn-success pull-right over-bar" - data-toggle="modal" data-target="#editorModal" data-action="upload_file"> + data-bs-toggle="modal" data-bs-target="#editorModal" data-action="upload_file"> <i class="fas fa-plus"></i> Προσθήκη </button> @@ -146,4 +146,14 @@ </div> </div><!-- /manage --> + + +<!-- MODAL for file uploads and preview --> +<div class="modal fade" id="editorModal" aria-labelledby="myModalLabel" aria-hidden="true"> + <div class="modal-dialog modal-lg" role="document"> + <div class="modal-content"> + <!-- content will be dynamic --> + </div> + </div> +</div> diff --git a/public/assets/css/overides.css b/public/assets/css/overides.css index c2ca07d..568164b 100644 --- a/public/assets/css/overides.css +++ b/public/assets/css/overides.css @@ -65,7 +65,7 @@ html, body { font-family: "Roboto Slab", serif; font-weight: 400; } ul.select2-results__options li { font-size: 14px; padding: 4px 8px; } -.admin-container .modal-footer .form-actions { display: flex; } +.admin-container .modal-footer .form-actions { display: flex; gap: 8px; } .admin-container .title-bar h5 { margin-bottom: 0; color: #333; } @@ -106,6 +106,6 @@ ul.select2-results__options li { font-size: 14px; padding: 4px 8px; } */ .admin-container .edit-post textarea[name=body] { height: calc(100vh - 420px); } /* almost all avialable height */ -.admin-container .edit-post textarea[name=intro] { height: 73px ;} /* almost 3 (half-)lines */ +.admin-container .edit-post textarea[name=intro] { height: 94px ;} /* almost 3 (half-)lines */ diff --git a/public/assets/js/admin/categories.js b/public/assets/js/admin/categories.js index 90eede3..e4d2955 100644 --- a/public/assets/js/admin/categories.js +++ b/public/assets/js/admin/categories.js @@ -272,7 +272,7 @@ $(document).ready(function() { }; // select action url (add or update) - var request = '/admin/api/category/' + ((data.id == 0) ? 'add' : 'update'); + var request = '/admin/api/categories/' + ((data.id == 0) ? 'add' : 'update'); // send POST request $.post(request, data) diff --git a/public/assets/js/admin/edit_lesson.js b/public/assets/js/admin/edit_lesson.js index a9355ae..ba31470 100644 --- a/public/assets/js/admin/edit_lesson.js +++ b/public/assets/js/admin/edit_lesson.js @@ -23,7 +23,7 @@ var files = []; // array of { id:.., title:.., type:.., path:.. } records // var tags = []; // array of integers -const files_root = 'https://cdn.sklavenitis.co.gr/'; // files root firectory +const files_root = '/media/'; // files root firectory var pageUrl = new URL(window.location.href); @@ -65,12 +65,12 @@ function course_record(id) { const modal_header = (title) => { return [ '<div class="modal-header">', - '<button type="button" class="close" data-dismiss="modal" aria-label="Close">', - '<span aria-hidden="true">×</span>', - '</button>', '<h4 class="modal-title" id="myModalLabel">', title, '</h4>', + '<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">', + '<span aria-hidden="true"></span>', + '</button>', '</div>' ].join('\n'); } @@ -91,34 +91,34 @@ const upload_file_form = () => { '<div class="row">', - '<div class="form-group col-md-7">', + '<div class="col-7"><div class="form-group">', '<label class="control-label" for="file">Εισαγωγή Αρχείου</label>', '<input class="form-control" type="file" id="file" name="file" required="">', - '</div>', + '</div></div>', - '<div class="form-group col-md-5">', + '<div class="col-5"><div class="form-group">', '<label class="control-label" for="category_id">Είδος</label>', - '<select class="form-control" id="reference" name="reference" required="">', + '<select class="form-control form-select" id="reference" name="reference" required="">', '<option"></option>', '<option value="1">Παραπομπή (εμφανίζεται)</option>', '<option value="0">Βοηθητικό αρχείο (κρυφό)</option>', '</select>', - '</div>', + '</div></div>', '</div>', '</div>', '<div class="modal-footer">', - '<div class="row">', + '<div class="row" style="width: 50%;">', '<div class="form-actions">', - '<div class="col-lg-3 col-lg-offset-6 col-md-4 col-md-offset-4 col-xs-6">', - '<buton type="button" class="btn btn-default js-modal-close col-xs-12" data-dismiss="modal">', + '<div class="col col-4">', + '<buton type="button" class="btn btn-default js-modal-close col-12" data-bs-dismiss="modal">', 'Κλείσιμο', '</button>', '</div>', - '<div class="col-lg-3 col-md-4 col-xs-6">', - '<button class="btn btn-success col-xs-12" type="submit">Καταχώριση</button>', + '<div class="col-8">', + '<button class="btn btn-success col-12" type="submit">Καταχώριση</button>', '</div>', '</div>', '</div>', @@ -145,10 +145,10 @@ const preview_article = (title, intro, body) => { '</div>', '</div>', '<div class="modal-footer">', - '<div class="row">', + '<div class="row" style="width: 50%;">', '<div class="form-actions">', - '<div class="col-md-4 col-md-offset-4 col-xs-6 col-xs-offset-3">', - '<buton type="button" class="btn btn-default js-modal-close col-xs-12" data-dismiss="modal">', + '<div class="col-md-4 col-md-offset-4 col-6 col-offset-3">', + '<buton type="button" class="btn btn-default js-modal-close col-12" data-bs-dismiss="modal">', 'Κλείσιμο', '</button>', '</div>', @@ -420,12 +420,13 @@ $(document).ready(function() { var data = { id: parseInt($('.edit-post form input[name=id]').val()), title: $('.edit-post form input[name=title]').val(), - category_id: parseInt($('#category_id').select2('data')[0].id), + course_id: parseInt($('#course_id').select2('data')[0].id), intro: $('.edit-post form textarea[name=intro]').val(), body: $('.edit-post form textarea[name=body]').val(), status: (($('input[name=status]').is(":checked")) ? 1 : 0), - tags: old_tags, - new_tags: new_tags, + privilege_id: parseInt($('#privilege_id').select2('data')[0].id), + // tags: old_tags, + // new_tags: new_tags, media: attachments }; @@ -594,7 +595,7 @@ $(document).ready(function() { // post the form (via ajax) $.ajax({ - url: '/wiki/ajax?action=file_upload', + url: '/admin/api/file_upload', type: 'POST', data: fd, contentType: false, @@ -615,7 +616,7 @@ $(document).ready(function() { $('#editorModal').modal('hide'); } else { - console('File not uploaded'); + console.log('File not uploaded'); } } }); diff --git a/public/files/.gitkeep b/public/files/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/public/files/.gitkeep |
