diff --git a/.github/workflows/moodle-ci.yml b/.github/workflows/moodle-ci.yml index 0ddfcae..bad0136 100644 --- a/.github/workflows/moodle-ci.yml +++ b/.github/workflows/moodle-ci.yml @@ -4,7 +4,7 @@ on: [push, pull_request] jobs: test: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest services: postgres: @@ -16,7 +16,7 @@ jobs: - 5432:5432 options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 3 mariadb: - image: mariadb:10.6.7 + image: mariadb:10.6 env: MYSQL_USER: 'root' MYSQL_ALLOW_EMPTY_PASSWORD: "true" @@ -29,11 +29,11 @@ jobs: matrix: include: - php: '8.3' - moodle-branch: 'MOODLE_405_STABLE' - database: 'pgsql' - - php: '8.2' moodle-branch: 'MOODLE_405_STABLE' database: 'mariadb' + - php: '8.3' + moodle-branch: 'MOODLE_405_STABLE' + database: 'pgsql' steps: - name: Check out repository code diff --git a/classes/output/general_action_bar.php b/classes/output/general_action_bar.php new file mode 100644 index 0000000..9908bfd --- /dev/null +++ b/classes/output/general_action_bar.php @@ -0,0 +1,303 @@ +. + +namespace local_learningtools\output; + +use moodle_url; +use core\output\select_menu; +use core\output\comboboxsearch; + +/** + * Renderable class for the general action bar in the gradebook pages. + * + * This class is responsible for rendering the general navigation select menu in the gradebook pages. + * + * @package local_learningtools + * @copyright 2021 bdecent gmbh + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class general_action_bar { + + /** @var moodle_url $activeurl The URL that should be set as active in the URL selector element. */ + protected $activeurl; + + /** + * The type of the current gradebook page (report, settings, import, export, scales, outcomes, letters). + * + * @var string $activetype + */ + protected $activetype; + + /** @var string $activeplugin The plugin of the current gradebook page (grader, fullview, ...). */ + protected $activeplugin; + + /** + * Summary of context + * @var \context + */ + protected $context; + + /** + * Course id. + * @var int + */ + protected $courseid; + + /** + * Section id. + * @var int + */ + protected $sectionid; + + /** + * Activity + * @var int + */ + protected $activity; + + /** + * The class constructor. + * + * @param \context $context The context object. + * @param moodle_url $activeurl The URL that should be set as active in the URL selector element. + * @param string $activetype The type of the current gradebook page (report, settings, import, export, scales, + * outcomes, letters). + * @param string $activeplugin The plugin of the current gradebook page (grader, fullview, ...). + * @param int $courseid Course ID. + * @param int $sectionid Section ID. + * @param int $activity Activity ID. + */ + public function __construct(\context $context, moodle_url $activeurl, string $activetype, string $activeplugin, int $courseid, + int $sectionid, int $activity) { + $this->activeurl = $activeurl; + $this->activetype = $activetype; + $this->activeplugin = $activeplugin; + $this->context = $context; + $this->courseid = $courseid; + $this->sectionid = $sectionid; + $this->activity = $activity; + } + + /** + * Export the data for the mustache template. + * + * @param \renderer_base $output renderer to be used to render the action bar elements. + * @return array + */ + public function export_for_template(\renderer_base $output): array { + global $USER, $DB; + $selectmenu = $this->get_action_selector(); + + if (is_null($selectmenu)) { + return []; + } + + $collapsemenudirection = right_to_left() ? 'dropdown-menu-left' : 'dropdown-menu-right'; + + $collapse = new comboboxsearch( + true, + get_string('collapsedcolumns', 'gradereport_grader', 0), + null, + 'collapse-columns', + 'collapsecolumn', + 'collapsecolumndropdown p-3 flex-column ' . $collapsemenudirection, + null, + true, + get_string('aria:dropdowncolumns', 'gradereport_grader'), + 'collapsedcolumns' + ); + + $course = get_course($this->courseid); + + $sections = $this->get_sections(); + $activities = $this->get_activities(); + + $viewpageurl = new moodle_url('/local/learningtools/ltool/note/view.php', ['id' => $this->courseid]); + + $collapsedcolumns = [ + 'classes' => 'd-none', + 'content' => $collapse->export_for_template($output), + 'viewpageurl' => $viewpageurl->out(false), + 'sections' => !empty($sections) ? $sections : [], + 'activities' => !empty($activities) ? $activities : [], + ]; + + return [ + 'generalnavselector' => $selectmenu->export_for_template($output), + 'collapsedcolumns' => $collapsedcolumns, + ]; + } + + /** + * Returns the template for the action bar. + * + * @return string + */ + public function get_template(): string { + return 'local_learningtools/tertiary_navigation'; + } + + /** + * Returns the URL selector object. + * + * @return \select_menu|null The URL select object. + */ + private function get_action_selector(): ?select_menu { + if ($this->context->contextlevel !== CONTEXT_COURSE) { + return null; + } + + $courseid = $this->context->instanceid; + $menus = []; + + // Get all available learning tool subplugins. + $subplugins = local_learningtools_get_subplugins(); + + // Add each subplugin to the menus. + foreach ($subplugins as $shortname => $toolobj) { + + // Check if user has capability to view this tool. + if ($shortname == 'note') { + // Get tool-specific URL if the tool has a navigation method. + if (method_exists($toolobj, 'get_navigation_url')) { + $toolurl = $toolobj->get_navigation_url($courseid); + } else { + // Default URL pattern for tools. + $toolurl = new moodle_url('/local/learningtools/ltool/'.$shortname.'/view.php', + ['id' => $courseid]); + } + + // Get tool name. + $toolname = get_string('toolname', 'ltool_'.$shortname); + + // Add to menus. + $menus[$toolurl->out(false)] = $toolname; + } + } + + $selectmenu = new select_menu('learningtoolsselect', $menus, $this->activeurl->out(false)); + $selectmenu->set_label(get_string('learningtools', 'local_learningtools'), ['class' => 'sr-only']); + + return $selectmenu; + } + + /** + * Get the related sections. + * + * @return array + */ + public function get_sections() { + global $USER, $DB; + $course = get_course($this->courseid); + $data = []; + + $sql = "SELECT n.*, cm.id as cmid, m.name as modulename + FROM {ltool_note_data} n + LEFT JOIN {course_modules} cm ON cm.id = n.coursemodule + LEFT JOIN {modules} m ON m.id = cm.module + WHERE n.course = :courseid AND n.pagetype = :pagetype + AND n.userid = :userid + ORDER BY n.timecreated DESC"; + $params = [ + 'courseid' => $this->courseid, + 'userid' => $USER->id, + 'pagetype' => 'course-view-section-' . $course->format, + ]; + + $notes = $DB->get_records_sql($sql, $params); + + foreach ($notes as $note) { + $sectionurl = new \moodle_url($note->pageurl); + $sectionid = $sectionurl->get_param('id'); + + if (!isset($data[$sectionid])) { + $section = $DB->get_record('course_sections', ['course' => $this->courseid, 'id' => $sectionid]); + if ($section) { + $sectionname = $section->name ?: ( + $section->section == 0 + ? get_string('general') + : get_string('section', 'local_learningtools') . ' ' . $section->section + ); + + $filterurl = new \moodle_url('/local/learningtools/ltool/note/view.php', [ + 'id' => $this->courseid, + 'sectionid' => $section->id, + 'filter' => 'section', + ]); + + $data[$sectionid] = [ + 'sectionname' => $sectionname, + 'sectionid' => $section->id, + 'filterurl' => $filterurl->out(false), + 'selected' => ($section->id == $this->sectionid) ? "selected" : "", + ]; + } + } + } + + return array_values($data); // Re-index to return a clean list. + } + + /** + * Gets the activity selected record. + * @return array course activity selector records. + */ + public function get_activities() { + global $DB, $USER; + + $sql = "SELECT lnd.coursemodule, lnd.course + FROM {ltool_note_data} lnd + LEFT JOIN {course_modules} cm ON cm.id = lnd.coursemodule + WHERE cm.deletioninprogress = 0 + AND lnd.course = :course + AND lnd.coursemodule != 0 + AND lnd.userid = :userid"; + + $params = [ + 'course' => $this->courseid, + 'userid' => $USER->id, + ]; + + if (!empty($this->sectionid)) { + $sql .= " AND cm.section = :sectionid"; + $params['sectionid'] = $this->sectionid; + } + + $sql .= " GROUP BY lnd.coursemodule, lnd.course"; + + $records = $DB->get_records_sql($sql, $params); + $data = []; + + if (!empty($records)) { + foreach ($records as $record) { + $record->courseid = $record->course; + $list['mod'] = local_learningtools_get_module_name($record); + $filterurl = new moodle_url('/local/learningtools/ltool/note/view.php', ['id' => $this->courseid, + 'activity' => $record->coursemodule, + 'filter' => 'activity']); + $list['filterurl'] = $filterurl->out(false); + if ($record->coursemodule == $this->activity) { + $list['selected'] = "selected"; + } else { + $list['selected'] = ""; + } + $data[] = $list; + } + + } + return $data; + } +} diff --git a/classes/output/renderer.php b/classes/output/renderer.php new file mode 100644 index 0000000..b6a9810 --- /dev/null +++ b/classes/output/renderer.php @@ -0,0 +1,44 @@ +. + +/** + * Renderer for learning tools + * + * @package local_learningtools + * @copyright 2023 Your Name + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace local_learningtools\output; + +use plugin_renderer_base; +use stdClass; + +/** + * Renderer class for learning tools. + */ +class renderer extends plugin_renderer_base { + /** + * Renders the action bar for a given page. + * + * @param general_action_bar $actionbar + * @return string The HTML output + */ + public function render_action_bar(general_action_bar $actionbar): string { + $data = $actionbar->export_for_template($this); + return $this->render_from_template($actionbar->get_template(), $data); + } +} diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php index 199b17a..15fe838 100644 --- a/classes/privacy/provider.php +++ b/classes/privacy/provider.php @@ -34,7 +34,7 @@ class provider implements \core_privacy\local\metadata\null_provider { * * @return string */ - public static function get_reason() : string { + public static function get_reason(): string { return 'privacy:metadata'; } diff --git a/db/access.php b/db/access.php index bea176b..e19fcee 100644 --- a/db/access.php +++ b/db/access.php @@ -22,13 +22,13 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); -$capabilities = array( - 'local/learningtools:studentcontroller' => array( +$capabilities = [ + 'local/learningtools:studentcontroller' => [ 'riskbitmask' => RISK_SPAM, 'captype' => 'read', 'contextlevel' => CONTEXT_COURSE, - 'archetypes' => array( - 'student' => CAP_ALLOW - ) - ) -); + 'archetypes' => [ + 'student' => CAP_ALLOW, + ], + ], +]; diff --git a/lang/en/local_learningtools.php b/lang/en/local_learningtools.php index c500368..9a9ff74 100644 --- a/lang/en/local_learningtools.php +++ b/lang/en/local_learningtools.php @@ -23,229 +23,218 @@ */ defined("MOODLE_INTERNAL") || die(); -$string['pluginname'] = "Learning Tools"; -$string['learningtoolproducts'] = "Learning Tools Products"; -$string['products'] = "Products"; -$string['learningtools'] = "Learning Tools"; -$string['general'] = 'General'; -$string['topic'] = 'Topic {$a}'; -$string['learningtoolsltool'] = "Manage Learning Tools"; -$string['notificationdisappertitle'] = "Notification disapper"; -$string['notificationdisapperdesc'] = "Use this option to set the notification disapper time between each Learning Tools save the notification. Value is in milliseconds (i.e 1 second = 1000 milliseconds)"; -$string['popout'] = "Pop Out"; -$string['viewreports'] = "View reports"; -$string['learningtoolssettings'] = "General settings"; -$string['ltoolsusermenu'] = "Display Learning Tools in usermenu bar"; -$string['ltoolusermenu_help'] = "List of menus available to display in the user menu. copy and paste the below given menu tools path in user menu items. Go to the Appearence->Themes->Theme settings in user menu items. "; -$string['privacy:metadata'] = 'Learning tools parent plugin don\'t store any user-related data, The learning tool sub plugins are stores the users data individually.'; -$string['coursenotes'] = "Course Notes"; +$string['activities'] = "activities"; $string['addbookmark'] = "Add bookmark"; -$string['createnote'] = "Create note"; -$string['fabiconbackcolor'] = "Learning Tools icon background color"; -$string['fabiconcolor'] = "Learning Tools icon color"; -$string['iconbackcolor'] = '{$a} icon background color'; -$string['iconcolor'] = '{$a} icon color'; -$string['ltoolsettings'] = '{$a} settings'; -$string['everywhere'] = "Everywhere"; +$string['after'] = "After"; +$string['all'] = "All"; +$string['allactiviies'] = "All Activities"; $string['allcourses'] = "All Courses"; -$string['specificcate'] = "Specific Categories"; -$string['visiblelearningtools'] = "Visibility of Learning Tools"; -$string['visiblecategories'] = "Select Visible Categories"; -$string['disablemodules'] = "Select Disable activities to hide Learning Tools"; -$string['enabledisablemodules'] = "Enable Learning Tools to hide activities"; -$string['fabbuttonvisible_desc'] = 'You can decide where the Learning Tools shall be available.'; -$string['sticky'] = "Sticky"; +$string['allsections'] = 'All sections'; +$string['alredyenrolled'] = "User was already enrolled"; $string['alwaysactive'] = "Always show active tools"; -$string['learningtools:studentcontroller'] = "Learning Tools student controller."; - -$string['bookmarksusermenu'] = "Display Bookmarks tool in user menu"; -$string['bookmarksusermenu_help'] = "bookmarks,local_learningtools|/local/learningtools/ltool/bookmarks/list.php"; -$string['notesusermenu'] = "Display Notes tool in user menu"; -$string['notesusermenu_help'] = "notes,local_learningtools|/local/learningtools/ltool/note/list.php"; - - -// Bookmarks strings. -$string['bookmarks'] = "Bookmarks"; -$string['managebookmarks'] = "Manage bookmarks access the users"; - -$string['eventltbookmarkscreated'] = "Learning Tools bookmarks created"; -$string['eventltbookmarksviewed'] = "Learning Tools bookmarks viewed"; -$string['eventltbookmarksdeleted'] = "Learning Tools bookmarks deleted"; - -// Note event strings. -$string['eventltnotecreated'] = "Learning Tools notes created"; -$string['eventltnotedeleted'] = "Learning Tools notes deleted"; -$string['eventltnoteviewed'] = "Learning Tools notes viewed"; -$string['eventltnoteedited'] = "Learning Tools notes edited"; - - +$string['attachments'] = "Attachments"; +$string['baseformat'] = '%B %d, %Y, %I:%M %p'; $string['bookicon'] = "Icon"; $string['bookmarkinfo'] = "Bookmarks Info"; -$string['time'] = "Time"; -$string['delete'] = "Delete"; -$string['view'] = "View Bookmarks"; -$string['allcourses'] = "All courses"; -$string['sortbydate'] = "Sort by date"; -$string['sortbycourse'] = "Sort by course"; -$string['viewcourse'] = "View course"; -$string['viewactivity'] = "View Activity"; -$string['viewchapter'] = "View Chapter"; -$string['deletemessage'] = 'Delete Message'; -$string['deletemsgcheckfull'] = 'Are you absolutely sure you want to completely delete the bookmarks, including their bookmarks and other bookmarks data?'; -$string['deletednotmessage'] = 'Could not delete bookmarks!'; -$string['successdeletemessage'] = "Successfully deleted"; -$string['ltbookmarks:manageltbookmarks'] = "User access the ltbookmarks tool."; +$string['bookmarks'] = "Bookmarks"; $string['bookmarkstoolcategory'] = "Tool Bookmarks"; +$string['bookmarksusermenu'] = "Display Bookmarks tool in user menu"; +$string['bookmarksusermenu_help'] = "bookmarks,local_learningtools|/local/learningtools/ltool/bookmarks/list.php"; +$string['cancel'] = "Cancel"; +$string['cmpdate'] = "Completion date"; +$string['completeactivity'] = "Complete activity"; +$string['course:'] = "Course: "; +$string['courseactivity'] = "Course activity"; $string['coursebookmarks'] = "Course Bookmarks"; -$string['successbookmarkmessage'] = "This page bookmarked successfully and you can view the bookmarks under profile / learning tools / bookmarks."; -$string['removebookmarkmessage'] = "This page bookmark removed and you can view the bookmarks under profile / learning tools / bookmarks."; - -$string['successchapterbookmarkmessage'] = "This chapter bookmarked successfully and you can view the bookmarks under profile / learning tools / bookmarks."; -$string['removechapterbookmarkmessage'] = "This chapter bookmark removed and you can view the bookmarks under profile / learning tools / bookmarks."; - -// Notes strings. - -$string['note'] = "Notes"; -$string['notes'] = "Notes"; -$string['managenote'] = "Manage note access the users"; -$string['ltnote:manageltnote'] = "User access the ltnote tool"; -$string['newnote'] = "Take notes"; -$string['allcourses'] = "All Courses"; -$string['sortbydate'] = "Sort by date"; -$string['sortbycourse'] = "Sort by course"; -$string['sortbyactivity'] = "Sort by Activity"; +$string['coursecompdate'] = "Course completion date"; +$string['coursecss'] = "Implement Course Css"; +$string['coursecustomstyle'] = 'Custom styles for {$a->name} {$a->help}'; +$string['courseduedate'] = "Course due date"; +$string['courseinfo'] = "Course Information"; $string['coursenotes'] = "Course Notes"; +$string['courseparticipants'] = "Course Participants"; +$string['courseprogress'] = "Course progress"; +$string['createnote'] = "Create note"; +$string['css'] = "Css"; +$string['customstyles'] = "Custom styles"; +$string['date'] = "Date"; +$string['dayago'] = '{$a} day ago'; +$string['days'] = "Days"; +$string['daysago'] = '{$a} days ago'; +$string['delete'] = "Delete"; +$string['deletedbookmessage'] = 'Could not delete bookmarks!'; +$string['deletednotmessage'] = 'Could not delete Note!'; $string['deletemessage'] = 'Delete Message'; -$string['editnote'] = 'Edit Note'; - -$string['deletemsgcheckfullbookmarks'] = "Are you absolutely sure you want to completely delete the Bookmarks, including their Bookmarks and data?"; - $string['deletemsgcheckfull'] = 'Are you absolutely sure you want to completely delete the Note, including their Note and data?'; - -$string['deletednotmessage'] = 'Could not delete Note!'; -$string['successdeletemessage'] = "Successfully deleted"; -$string['successeditnote'] = "Successfully edited"; -$string['allactiviies'] = "All Activities"; -$string['successnotemessage'] = "Notes added successfully and you can view the note under profile / learning tools / note."; -$string['viewownbookmarks'] = "View Own Bookmarks"; -$string['viewchildbookmarks'] = "View Child Bookmarks"; -$string['pagenotes'] = "Page notes"; -$string['courseparticipants'] = "Course Participants"; -$string['viewbookmarks'] = "View Bookmarks"; -$string['viewpage'] = "View Page"; - -// Invite ltool strings. -$string['invite'] = "Invite"; -$string['inviteusers'] = "Invite Users"; -$string['usersemail'] = "Users Email"; -$string['invitenow'] = "Invite Now"; -$string['inviteuserslist'] = "Invite users reports"; -$string['successinviteusers'] = 'Invite users successfully.'; +$string['deletemsgcheckfullbookmarks'] = "Are you absolutely sure you want to completely delete the Bookmarks, including their Bookmarks and data?"; +$string['disablemodules'] = "Select Disable activities to hide Learning Tools"; $string['donotcreateusers'] = "Do not create users"; +$string['donotresumecourse'] = "You don't have any pages to resume"; +$string['duedate'] = "Due date"; +$string['edited'] = 'edited'; +$string['editnote'] = 'Edit Note'; +$string['email'] = "Email"; +$string['enablecompletiontrackmsg'] = "Turn on completion tracking to use Time Management."; +$string['enabledisablemodules'] = "Enable Learning Tools to hide activities"; +$string['enrolldurationstr'] = "Enrollment duration"; $string['enrolled'] = "Enrolled successfully"; -$string['alredyenrolled'] = "User was already enrolled"; -$string['suspended'] = "User was suspended"; -$string['timeaccess'] = "Time access"; -$string['registerandenrolled'] = "User was registered and enrolled successfully"; +$string['enrolluserscourse'] = "Please enroll at least one user to use Time Management."; +$string['eventltbookmarkscreated'] = "Learning Tools bookmarks created"; +$string['eventltbookmarksdeleted'] = "Learning Tools bookmarks deleted"; +$string['eventltbookmarksviewed'] = "Learning Tools bookmarks viewed"; +$string['eventltnotecreated'] = "Learning Tools notes created"; +$string['eventltnotedeleted'] = "Learning Tools notes deleted"; +$string['eventltnoteedited'] = "Learning Tools notes edited"; +$string['eventltnoteviewed'] = "Learning Tools notes viewed"; +$string['everywhere'] = "Everywhere"; +$string['expectdueon'] = "should be completed"; +$string['expectstarton'] = "should be started"; +$string['export'] = "Export"; +$string['exportnotes'] = 'Export notes'; +$string['exuserenrollment'] = "example user enrollment"; +$string['fabbuttonvisible_desc'] = 'You can decide where the Learning Tools shall be available.'; +$string['fabiconbackcolor'] = "Learning Tools icon background color"; +$string['fabiconcolor'] = "Learning Tools icon color"; +$string['focus'] = "Focus"; +$string['focusmode'] = "Focus mode"; +$string['focusmodecss'] = "Customize Focus Mode"; +$string['forceactivity'] = "Force activity"; +$string['general'] = 'General'; +$string['gotocontext'] = 'Go to resource'; +$string['gotocourse'] = "Go to course"; +$string['hideprint'] = 'Hide (from print)'; +$string['hourago'] = '{$a} hour ago'; +$string['hours'] = "Hours"; +$string['hoursago'] = '{$a} hours ago'; +$string['iconbackcolor'] = '{$a} icon background color'; +$string['iconcolor'] = '{$a} icon color'; +$string['information'] = "Information"; $string['invaildemail'] = "User email not exists"; $string['invaildemailadderss'] = "Email adderss should be wrong"; +$string['invite'] = "Invite"; $string['invite_maunalenrolerr'] = "Manual enrolments are not available in this course."; - -// Resume course strings. -$string['resumecourse'] = "Resume course"; -$string['donotresumecourse'] = "You don't have any pages to resume"; - -// Email tool strings. -$string['email'] = "Email"; -$string['sentemailparticipants'] = "Send the email to course participants"; -$string['subject'] = "Subject"; +$string['invitenow'] = "Invite Now"; +$string['inviteusers'] = "Invite Users"; +$string['inviteusers_help'] = "Please add one e-mail per line."; +$string['inviteuserslist'] = "Invite users reports"; +$string['learningtoolproducts'] = "Learning Tools Products"; +$string['learningtools'] = "Learning Tools"; +$string['learningtools:studentcontroller'] = "Learning Tools student controller."; +$string['learningtoolsltool'] = "Manage Learning Tools"; +$string['learningtoolssettings'] = "General settings"; +$string['listemailreports'] = "Email send reports"; +$string['ltbookmarks:manageltbookmarks'] = "User access the ltbookmarks tool."; +$string['ltnote:manageltnote'] = "User access the ltnote tool"; +$string['ltoolsettings'] = '{$a} settings'; +$string['ltoolsusermenu'] = "Display Learning Tools in usermenu bar"; +$string['ltoolusermenu_help'] = "List of menus available to display in the user menu. copy and paste the below given menu tools path in user menu items. Go to the Appearence->Themes->Theme settings in user menu items. "; +$string['managebookmarks'] = "Manage bookmarks access the users"; +$string['managedates'] = "Manage dates"; +$string['managenote'] = "Manage note access the users"; +$string['managetimemanagment'] = "Manage dates reports"; $string['message'] = "Message"; -$string['subjecterr'] = "Missing Subject"; $string['messageerr'] = "Missing Message"; -$string['recipients'] = "Recipients"; -$string['recipientserr'] = "Missing Recipient"; -$string['attachments'] = "Attachments"; +$string['minuteago'] = '{$a} minute ago'; +$string['minutesago'] = '{$a} minutes ago'; +$string['module:'] = "Module: "; +$string['modulenotes'] = "Module Notes"; +$string['monthago'] = '{$a} month ago'; +$string['months'] = "Months"; +$string['monthsago'] = '{$a} months ago'; $string['msgemailsent'] = "Successfully sent the mail to users"; -$string['sentemailuserslist'] = "Sent the email to users list"; -$string['receivedusers'] = "Received Users"; -$string['listemailreports'] = "Email send reports"; -$string['inviteusers_help'] = "Please add one e-mail per line."; -// Force activity. - -$string['forceactivity'] = "Force activity"; -$string['courseactivity'] = "Course activity"; +$string['mynotes'] = 'My Notes'; +$string['newnote'] = "Take notes"; $string['noactivity'] = "No force activiy"; -$string['successforceactivityusers'] = "Successfully added the force activity in the course"; - -// Information tool. -$string['information'] = "Information"; -$string['courseinfo'] = "Course Information"; - -// Focus tool. -$string['focus'] = "Focus"; -$string['focusmodecss'] = "Customize Focus Mode"; -$string['focusmode'] = "Focus mode"; - -// Css tool. -$string['css'] = "Css"; -$string['coursecss'] = "Implement Course Css"; -$string['customstyles'] = "Custom styles"; -$string['coursecustomstyle'] = 'Custom styles for {$a->name} {$a->help}'; -$string['parsecustomstyles_help'] = "Use this field to provide CSS code which will be injected at -the end of the style sheet for all pages in the current course."; -$string['parsecustomstyles'] = "Use this field to provide CSS code which will be injected at -the end of the style sheet for all pages in the current course."; - -// Schedule tool. -$string['schedule'] = "Schedule"; -$string['visitpage'] = "Visit page"; -$string['successtoolschedule'] = "Schedule added the user calendar"; - -// Time management. -$string['timemanagement'] = 'Time management'; -$string['timemanagementheader'] = 'Time management for {$a->name}'; -$string['print'] = "Print"; -$string['sendmessage'] = "Send message"; -$string['viewprofile'] = "View profile"; -$string['managedates'] = "Manage dates"; -$string['activities'] = "activities"; -$string['today'] = "Today"; -$string['expectstarton'] = "should be started"; -$string['expectdueon'] = "should be completed"; +$string['none'] = "None"; +$string['nonotes'] = 'You have not created any notes in this course yet.'; +$string['note'] = "Notes"; +$string['notes'] = "Notes"; +$string['notesusermenu'] = "Display Notes tool in user menu"; +$string['notesusermenu_help'] = "notes,local_learningtools|/local/learningtools/ltool/note/list.php"; +$string['notificationdisapperdesc'] = "Use this option to set the notification disapper time between each Learning Tools save the notification. Value is in milliseconds (i.e 1 second = 1000 milliseconds)"; +$string['notificationdisappertitle'] = "Notification disapper"; $string['open'] = "Open"; +$string['pagenotes'] = "Page notes"; +$string['parsecustomstyles'] = "Use this field to provide CSS code which will be injected at the end of the style sheet for all pages in the current course."; +$string['parsecustomstyles_help'] = "Use this field to provide CSS code which will be injected at the end of the style sheet for all pages in the current course."; +$string['pluginname'] = "Learning Tools"; +$string['popout'] = "Pop Out"; +$string['print'] = "Print"; +$string['printlayout'] = 'Print layout'; +$string['printnotes'] = 'Print notes'; +$string['printnotestitle'] = 'Learning Tools - Notes'; +$string['privacy:metadata'] = 'Learning tools parent plugin don\'t store any user-related data, The learning tool sub plugins are stores the users data individually.'; +$string['products'] = "Products"; +$string['progress'] = "Progress"; +$string['receivedusers'] = "Received Users"; +$string['receivegrade'] = "Receive grade"; +$string['recipients'] = "Recipients"; +$string['recipientserr'] = "Missing Recipient"; +$string['registerandenrolled'] = "User was registered and enrolled successfully"; +$string['removebookmarkmessage'] = "This page bookmark removed and you can view the bookmarks under profile / learning tools / bookmarks."; +$string['removechapterbookmarkmessage'] = "This chapter bookmark removed and you can view the bookmarks under profile / learning tools / bookmarks."; $string['resume'] = "Resume"; +$string['resumecourse'] = "Resume course"; +$string['returntonotes'] = 'Return to notes'; $string['review'] = "Review"; -$string['receivegrade'] = "Receive grade"; -$string['completeactivity'] = "Complete activity"; -$string['exuserenrollment'] = "example user enrollment"; -$string['courseduedate'] = "Course due date"; -$string['none'] = "None"; -$string['after'] = "After"; -$string['date'] = "Date"; -$string['hours'] = "Hours"; -$string['days'] = "Days"; -$string['months'] = "Months"; -$string['years'] = "Years"; -$string['startdate'] = "Start date"; -$string['duedate'] = "Due date"; -$string['uponenroll'] = "Upon enrollment"; -$string['open'] = "Open"; $string['saveandgen'] = "Save and generate calendar entries"; -$string['cancel'] = "Cancel"; -$string['enablecompletiontrackmsg'] = "Turn on completion tracking to use Time Management."; -$string['enrolluserscourse'] = "Please enroll at least one user to use Time Management."; -$string['enrolldurationstr'] = "Enrollment duration"; -$string['courseprogress'] = "Course progress"; -$string['coursecompdate'] = "Course completion date"; -$string['progress'] = "Progress"; -$string['cmpdate'] = "Completion date"; -$string['managetimemanagment'] = "Manage dates reports"; -$string['gotocourse'] = "Go to course"; -$string['baseformat'] = '%B %d, %Y, %I:%M %p'; +$string['schedule'] = "Schedule"; +$string['searchmynotes'] = "Search my notes"; +$string['secondago'] = '{$a} second ago'; +$string['secondsago'] = '{$a} seconds ago'; +$string['section'] = "Section"; +$string['section:'] = "Section: "; +$string['sendmessage'] = "Send message"; +$string['sentemailparticipants'] = "Send the email to course participants"; +$string['sentemailuserslist'] = "Sent the email to users list"; +$string['showprint'] = 'Show (from print)'; +$string['sortbyactivity'] = "Sort by Activity"; +$string['sortbycourse'] = "Sort by course"; +$string['sortbydate'] = "Sort by date"; +$string['specificcate'] = "Specific Categories"; +$string['startdate'] = "Start date"; +$string['sticky'] = "Sticky"; +$string['strbookmark'] = " Bookmark"; +$string['strbookmarked'] = " Bookmarked"; $string['strftimemonthdateyear'] = '%B, %dth %Y'; -$string['strftimeyearmonth'] = '%Y/%m/%d'; $string['strftimemonthnamedate'] = '%B %d, %Y'; +$string['strftimeyearmonth'] = '%Y/%m/%d'; +$string['subject'] = "Subject"; +$string['subjecterr'] = "Missing Subject"; $string['subplugintype_ltool'] = "Learning Tool"; $string['subplugintype_ltool_plural'] = 'Learning Tools'; -$string['strbookmarked'] = " Bookmarked"; -$string['strbookmark'] = " Bookmark"; +$string['successbookmarkmessage'] = "This page bookmarked successfully and you can view the bookmarks under profile / learning tools / bookmarks."; +$string['successchapterbookmarkmessage'] = "This chapter bookmarked successfully and you can view the bookmarks under profile / learning tools / bookmarks."; +$string['successdeletemessage'] = "Successfully deleted"; +$string['successeditnote'] = "Successfully edited"; +$string['successforceactivityusers'] = "Successfully added the force activity in the course"; +$string['successinviteusers'] = 'Invite users successfully.'; +$string['successnotemessage'] = "Notes added successfully and you can view the note under profile / learning tools / note."; +$string['successtoolschedule'] = "Schedule added the user calendar"; +$string['suspended'] = "User was suspended"; +$string['time'] = "Time"; +$string['timeaccess'] = "Time access"; +$string['timemanagement'] = 'Time management'; +$string['timemanagementheader'] = 'Time management for {$a->name}'; +$string['today'] = "Today"; +$string['topic'] = 'Topic {$a}'; +$string['uponenroll'] = "Upon enrollment"; +$string['usersemail'] = "Users Email"; +$string['view'] = "View Bookmarks"; +$string['viewactivity'] = "View Activity"; +$string['viewbookmarks'] = "View Bookmarks"; +$string['viewchapter'] = "View Chapter"; +$string['viewchildbookmarks'] = "View Child Bookmarks"; +$string['viewcourse'] = "View course"; +$string['viewownbookmarks'] = "View Own Bookmarks"; +$string['viewpage'] = "View Page"; +$string['viewprofile'] = "View profile"; +$string['viewreports'] = "View reports"; +$string['visiblecategories'] = "Select Visible Categories"; +$string['visiblelearningtools'] = "Visibility of Learning Tools"; +$string['visitpage'] = "Visit page"; +$string['weekago'] = '{$a} week ago'; +$string['weeksago'] = '{$a} weeks ago'; +$string['yearago'] = '{$a} year ago'; +$string['years'] = "Years"; +$string['yearsago'] = '{$a} years ago'; diff --git a/learningtoolslist.php b/learningtoolslist.php index b3de8f9..7c43e83 100644 --- a/learningtoolslist.php +++ b/learningtoolslist.php @@ -51,19 +51,19 @@ if (!empty($action) && !empty($tool)) { require_sesskey(); if ($action == 'disable') { - $DB->set_field('local_learningtools_products', 'status', 0, array('shortname' => $tool)); + $DB->set_field('local_learningtools_products', 'status', 0, ['shortname' => $tool]); } else if ($action == 'enable') { - $DB->set_field('local_learningtools_products', 'status', 1, array('shortname' => $tool)); + $DB->set_field('local_learningtools_products', 'status', 1, ['shortname' => $tool]); } else if ($action == 'up') { - $curtool = $DB->get_record('local_learningtools_products', array('shortname' => $tool)); - $prevtool = $DB->get_record('local_learningtools_products', array('sort' => $curtool->sort - 1)); - $DB->set_field('local_learningtools_products', 'sort', $prevtool->sort, array('shortname' => $curtool->shortname)); - $DB->set_field('local_learningtools_products', 'sort', $curtool->sort, array('shortname' => $prevtool->shortname)); + $curtool = $DB->get_record('local_learningtools_products', ['shortname' => $tool]); + $prevtool = $DB->get_record('local_learningtools_products', ['sort' => $curtool->sort - 1]); + $DB->set_field('local_learningtools_products', 'sort', $prevtool->sort, ['shortname' => $curtool->shortname]); + $DB->set_field('local_learningtools_products', 'sort', $curtool->sort, ['shortname' => $prevtool->shortname]); } else if ($action = "down") { - $basetool = $DB->get_record('local_learningtools_products', array('shortname' => $tool)); - $nexttool = $DB->get_record('local_learningtools_products', array('sort' => $basetool->sort + 1)); - $DB->set_field('local_learningtools_products', 'sort', $nexttool->sort, array('shortname' => $basetool->shortname)); - $DB->set_field('local_learningtools_products', 'sort', $basetool->sort, array('shortname' => $nexttool->shortname)); + $basetool = $DB->get_record('local_learningtools_products', ['shortname' => $tool]); + $nexttool = $DB->get_record('local_learningtools_products', ['sort' => $basetool->sort + 1]); + $DB->set_field('local_learningtools_products', 'sort', $nexttool->sort, ['shortname' => $basetool->shortname]); + $DB->set_field('local_learningtools_products', 'sort', $basetool->sort, ['shortname' => $nexttool->shortname]); } redirect($pageurl); } @@ -72,18 +72,18 @@ // Print the table of all installed ltools plugins. $table = new flexible_table('learningtool_products_info'); -$table->define_columns(array('name', 'version', 'status', 'updown', 'uninstall')); -$table->define_headers(array($strname, $strversion, $strenable.'/'.$strdisable, -$strup.'/'.$strdown, $uninstallplug)); +$table->define_columns(['name', 'version', 'status', 'updown', 'uninstall']); +$table->define_headers([$strname, $strversion, $strenable.'/'.$strdisable, +$strup.'/'.$strdown, $uninstallplug]); $table->define_baseurl($PAGE->url); $table->set_attribute('id', 'learningtool-products'); $table->set_attribute('class', 'learningtool generaltable'); $table->setup(); -$plugins = array(); +$plugins = []; $pluginman = core_plugin_manager::instance(); -$spacer = $OUTPUT->pix_icon('spacer', '', 'moodle', array('class' => 'iconsmall')); +$spacer = $OUTPUT->pix_icon('spacer', '', 'moodle', ['class' => 'iconsmall']); $cnt = 0; $learningtools = $DB->get_records('local_learningtools_products', null, 'sort'); @@ -103,14 +103,14 @@ // Plugin enable/disable. $status = '-'; - $lttool = $DB->get_record('local_learningtools_products', array('shortname' => $plugin)); + $lttool = $DB->get_record('local_learningtools_products', ['shortname' => $plugin]); if ($lttool->status) { - $aurl = new moodle_url($PAGE->url, array('action' => 'disable', 'tool' => $plugin, 'sesskey' => sesskey())); + $aurl = new moodle_url($PAGE->url, ['action' => 'disable', 'tool' => $plugin, 'sesskey' => sesskey()]); $status = ""; $status .= $OUTPUT->pix_icon('t/hide', $strdisable) . ''; $enabled = true; } else { - $aurl = new moodle_url($PAGE->url, array('action' => 'enable', 'tool' => $plugin, 'sesskey' => sesskey())); + $aurl = new moodle_url($PAGE->url, ['action' => 'enable', 'tool' => $plugin, 'sesskey' => sesskey()]); $status = ""; $status .= $OUTPUT->pix_icon('t/show', $strenable) . ''; $enabled = false; @@ -119,20 +119,20 @@ // Plugin sort option. $updown = ''; if ($cnt) { - $updown .= html_writer::link($PAGE->url->out(false, array('action' => 'up', 'tool' => $plugin, 'sesskey' => sesskey())), - $OUTPUT->pix_icon('t/up', $strup, 'moodle', array('class' => 'iconsmall'))). ''; + $updown .= html_writer::link($PAGE->url->out(false, ['action' => 'up', 'tool' => $plugin, 'sesskey' => sesskey()]), + $OUTPUT->pix_icon('t/up', $strup, 'moodle', ['class' => 'iconsmall'])). ''; } else { $updown .= $spacer; } if ($cnt < count($learningtools) - 1) { - $updown .= ' '.html_writer::link($PAGE->url->out(false, array('action' => 'down', 'tool' => $plugin, - 'sesskey' => sesskey())), - $OUTPUT->pix_icon('t/down', $strdown, 'moodle', array('class' => 'iconsmall'))); + $updown .= ' '.html_writer::link($PAGE->url->out(false, ['action' => 'down', 'tool' => $plugin, + 'sesskey' => sesskey()]), + $OUTPUT->pix_icon('t/down', $strdown, 'moodle', ['class' => 'iconsmall'])); } else { $updown .= $spacer; } $cnt++; - $table->add_data(array($tool->name, $version, $status, $updown, $uninstall)); + $table->add_data([$tool->name, $version, $status, $updown, $uninstall]); } // Print the ltool plugins table. $table->print_html(); diff --git a/lib.php b/lib.php index 5dfecfe..e7e1d07 100644 --- a/lib.php +++ b/lib.php @@ -58,7 +58,7 @@ function local_learningtools_myprofile_navigation(tree $tree, $user, $iscurrentu function local_learningtools_extend_settings_navigation($settingnav, $context) { global $PAGE, $CFG; $context = context_system::instance(); - $ltoolsjs = array(); + $ltoolsjs = []; // Content of fab button html. $fabbuttonhtml = json_encode(local_learningtools_get_learningtools_info()); $ltoolsjs['disappertimenotify'] = get_config('local_learningtools', 'notificationdisapper'); @@ -68,7 +68,7 @@ function local_learningtools_extend_settings_navigation($settingnav, $context) { if (isloggedin() && !isguestuser()) { $loggedin = true; } - $viewcapability = array('loggedin' => $loggedin); + $viewcapability = ['loggedin' => $loggedin]; $PAGE->requires->js_call_amd('local_learningtools/learningtoolsinfo', 'init', $viewcapability); // List of subplugins. // Load available subplugins javascript. @@ -140,7 +140,7 @@ function local_learningtools_get_moduleid($contextid, $contextlevel) { function local_learningtools_get_coursemodule_id($record) { global $DB; - $contextinfo = $DB->get_record('context', array('id' => $record->contextid, 'contextlevel' => $record->contextlevel)); + $contextinfo = $DB->get_record('context', ['id' => $record->contextid, 'contextlevel' => $record->contextlevel]); return isset($contextinfo->instanceid) ? $contextinfo->instanceid : 0; } /** @@ -164,7 +164,7 @@ function local_learningtools_get_courses_name($courses, $url = '', $selectcourse $list = []; $list['id'] = $course->id; $list['name'] = $course->get_formatted_name(); - $urlparams = array('selectcourse' => $course->id); + $urlparams = ['selectcourse' => $course->id]; if ($userid) { $urlparams['userid'] = $userid; } @@ -220,11 +220,11 @@ function local_learningtools_get_course_categoryname($courseid) { */ function local_learningtools_get_module_name($data, $mod = false) { global $DB; - $coursemoduleinfo = $DB->get_record('course_modules', array('id' => $data->coursemodule)); + $coursemoduleinfo = $DB->get_record('course_modules', ['id' => $data->coursemodule]); if (empty($coursemoduleinfo)) { return ""; } - $moduleinfo = $DB->get_record('modules', array('id' => $coursemoduleinfo->module)); + $moduleinfo = $DB->get_record('modules', ['id' => $coursemoduleinfo->module]); if ($moduleinfo) { if ($mod) { return $moduleinfo->name; @@ -236,7 +236,6 @@ function local_learningtools_get_module_name($data, $mod = false) { return ""; } - /** * Get the course module current section. * @param int $courseid course id @@ -246,7 +245,7 @@ function local_learningtools_get_module_name($data, $mod = false) { function local_learningtools_get_mod_section($courseid, $modid) { global $DB; - $sections = $DB->get_records('course_sections', array('course' => $courseid)); + $sections = $DB->get_records('course_sections', ['course' => $courseid]); $sectionname = []; $sectionmod = []; if (!empty($sections)) { @@ -281,7 +280,6 @@ function local_learningtools_get_mod_section($courseid, $modid) { return ''; } - /** * Get list of available sub plugins. * @@ -289,7 +287,7 @@ function local_learningtools_get_mod_section($courseid, $modid) { */ function local_learningtools_get_subplugins() { global $DB, $PAGE, $SITE; - $learningtools = $DB->get_records('local_learningtools_products', array('status' => 1), 'sort'); + $learningtools = $DB->get_records('local_learningtools_products', ['status' => 1], 'sort'); if (!empty($learningtools)) { foreach ($learningtools as $tool) { $plugin = 'ltool_'.$tool->shortname; @@ -303,7 +301,6 @@ function local_learningtools_get_subplugins() { return []; } - /** * Display fab button html. * @return string fab button html content. @@ -389,17 +386,17 @@ function local_learningtools_get_learningtools_info() { } $fabbackiconcolor = get_config('local_learningtools', 'fabiconbackcolor'); $fabiconcolor = get_config('local_learningtools', 'fabiconcolor'); - $content .= html_writer::start_tag('div', array('class' => 'learningtools-action-info')); - $content .= html_writer::start_tag('div', array('class' => "floating-button $stickyclass")); - $content .= html_writer::start_tag('div', array('class' => 'list-learningtools')); + $content .= html_writer::start_tag('div', ['class' => 'learningtools-action-info']); + $content .= html_writer::start_tag('div', ['class' => "floating-button $stickyclass"]); + $content .= html_writer::start_tag('div', ['class' => 'list-learningtools']); $content .= $contentinner; $content .= html_writer::end_tag('div'); - $content .= html_writer::start_tag('button', array("class" => "btn btn-primary", - 'id' => 'tool-action-button', 'style' => "background:$fabbackiconcolor;") ); - $content .= html_writer::start_tag('i', array('class' => $fabiconclass, 'style' => "color:$fabiconcolor;")); + $content .= html_writer::start_tag('button', ["class" => "btn btn-primary", + 'id' => 'tool-action-button', 'style' => "background:$fabbackiconcolor;"] ); + $content .= html_writer::start_tag('i', ['class' => $fabiconclass, 'style' => "color:$fabiconcolor;"]); $content .= html_writer::end_tag('i'); $content .= html_writer::end_tag("button"); - $content .= html_writer::start_tag('div', array('class' => 'sticky-tools-list')); + $content .= html_writer::start_tag('div', ['class' => 'sticky-tools-list']); $content .= $stickytools; $content .= html_writer::end_tag('div'); $content .= html_writer::end_tag('div'); @@ -435,7 +432,6 @@ function local_learningtools_get_stickytool_status() { return $stickystatus; } - /** * Get the students in course. * @param int $courseid course id @@ -495,7 +491,7 @@ function local_learningtools_get_instance_tool_view_url($row) { return ''; } if ($data->instance == 'course') { - $courseurl = new moodle_url('/course/view.php', array('id' => $data->courseid)); + $courseurl = new moodle_url('/course/view.php', ['id' => $data->courseid]); $viewurl = $OUTPUT->single_button($courseurl, get_string('viewcourse', 'local_learningtools'), 'get'); } else if ($data->instance == 'mod') { $pageurl = $row->pageurl; @@ -530,7 +526,7 @@ function local_learningtools_get_eventlevel_courseid($context, $courseid) { function local_learningtools_add_learningtools_plugin($plugin) { global $DB; $strpluginname = get_string('pluginname', 'ltool_' . $plugin); - if (!$DB->record_exists('local_learningtools_products', array('shortname' => $plugin)) ) { + if (!$DB->record_exists('local_learningtools_products', ['shortname' => $plugin]) ) { $existrecords = $DB->get_records('local_learningtools_products', null); $maxrecord = $DB->get_record_sql('SELECT MAX(sort) AS value FROM {local_learningtools_products}', null); $sortval = !empty($existrecords) ? $maxrecord->value + 1 : 1; @@ -551,8 +547,8 @@ function local_learningtools_add_learningtools_plugin($plugin) { */ function local_learningtools_delete_ltool_table($plugin) { global $DB; - if ($DB->record_exists('local_learningtools_products', array('shortname' => $plugin)) ) { - $DB->delete_records('local_learningtools_products', array('shortname' => $plugin)); + if ($DB->record_exists('local_learningtools_products', ['shortname' => $plugin]) ) { + $DB->delete_records('local_learningtools_products', ['shortname' => $plugin]); } } @@ -616,3 +612,16 @@ function local_learningtools_can_visible_tool_incourse() { } return $access; } + +/** + * Add Learning Tools to the course secondary navigation. + * + * @param navigation_node $navigation The navigation node to extend + * @param stdClass $course The course object + * @param context $context The course context + */ +function local_learningtools_extend_navigation_course($navigation, $course, $context) { + $url = new moodle_url('/local/learningtools/ltool/note/view.php', ['id' => $course->id]); + $navigation->add(get_string('learningtools', 'local_learningtools'), $url, navigation_node::TYPE_SETTING, null, null, + new pix_icon('i/learningtools', get_string('learningtools', 'local_learningtools'))); +} diff --git a/ltool/bookmarks/amd/build/learningbookmarks.min.js.map b/ltool/bookmarks/amd/build/learningbookmarks.min.js.map index 133851f..3523a9c 100644 --- a/ltool/bookmarks/amd/build/learningbookmarks.min.js.map +++ b/ltool/bookmarks/amd/build/learningbookmarks.min.js.map @@ -1 +1 @@ -{"version":3,"file":"learningbookmarks.min.js","sources":["../src/learningbookmarks.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\r\n//\r\n// Moodle is free software: you can redistribute it and/or modify\r\n// it under the terms of the GNU General Public License as published by\r\n// the Free Software Foundation, either version 3 of the License, or\r\n// (at your option) any later version.\r\n//\r\n// Moodle is distributed in the hope that it will be useful,\r\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n// GNU General Public License for more details.\r\n//\r\n// You should have received a copy of the GNU General Public License\r\n// along with Moodle. If not, see .\r\n\r\n/**\r\n * Bookmarks ltool define js.\r\n * @module ltool_bookmarks\r\n * @category Classes - autoloading\r\n * @copyright 2021, bdecent gmbh bdecent.de\r\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\r\n */\r\n\r\ndefine(['core/str', 'core/ajax', 'core/notification', 'jquery'],\r\n function(String, Ajax, notification, $) {\r\n\r\n /* global ltools, pagebookmarks */\r\n\r\n /**\r\n * Controls bookmarks tool action.\r\n * @param {int} contextid\r\n * @param {object} params\r\n */\r\n function learningToolBookmarksAction(contextid, params) {\r\n\r\n var bookmarkmarked = document.getElementById('bookmarks-marked');\r\n if (bookmarkmarked) {\r\n if (pagebookmarks) {\r\n bookmarkmarked.classList.add('marked');\r\n } else {\r\n bookmarkmarked.classList.remove('marked');\r\n }\r\n }\r\n\r\n var bookmarksform = document.getElementById('ltbookmarks-action');\r\n if (bookmarksform) {\r\n bookmarksform.addEventListener(\"click\", function(e) {\r\n e.preventDefault();\r\n submitFormdata(contextid, params);\r\n });\r\n // Hover color.\r\n var bookmarkshovercolor = bookmarksform.getAttribute(\"data-hovercolor\");\r\n var bookmarksfontcolor = bookmarksform.getAttribute(\"data-fontcolor\");\r\n if (bookmarkshovercolor && bookmarksfontcolor) {\r\n bookmarksform.addEventListener(\"mouseover\", function() {\r\n document.querySelector('#ltbookmarksinfo p').style.background = bookmarkshovercolor;\r\n document.querySelector('#ltbookmarksinfo p').style.color = bookmarksfontcolor;\r\n });\r\n }\r\n\r\n }\r\n\r\n // Content designer bookmarks.\r\n $(document).on('click', '.content-designer-learningtool-bookmark', function(e) {\r\n e.preventDefault();\r\n var button = $(this);\r\n var itemType = button.data('itemtype');\r\n var itemId = button.data('itemid');\r\n var userid = button.data('userid');\r\n var sesskey = button.data('sesskey');\r\n var course = button.data('courseid');\r\n var coursemodule = button.data('coursemodule');\r\n var contextlevel = button.data('contextlevel');\r\n var pagetype = button.data('pagetype');\r\n var pageurl = button.data('pageurl');\r\n // Prepare the parameters for the bookmark.\r\n var contextId = M.cfg.contextid;\r\n var params = {\r\n pagetitle: document.title,\r\n pageurl: pageurl,\r\n pageid: 0,\r\n itemtype: itemType,\r\n itemid: itemId,\r\n user: userid,\r\n sesskey: sesskey,\r\n course: course,\r\n coursemodule: coursemodule,\r\n contextlevel: contextlevel,\r\n pagetype: pagetype,\r\n };\r\n submitFormdata(contextId, params, button);\r\n });\r\n\r\n var bookmarkssorttype = document.getElementById(\"bookmarkssorttype\");\r\n\r\n if (bookmarkssorttype) {\r\n bookmarkssorttype.addEventListener(\"click\", function() {\r\n var sorttype = this.getAttribute(\"data-type\");\r\n bookmarksSortActionPage(sorttype);\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Sort the bookmarks list.\r\n * @param {string} sorttype type of sort\r\n * @return {void}\r\n */\r\n function bookmarksSortActionPage(sorttype) {\r\n\r\n var pageurl = window.location.href;\r\n var para = '';\r\n pageurl = removeURLParameter(pageurl, 'sorttype');\r\n\r\n if (sorttype == 'asc') {\r\n sorttype = 'desc';\r\n } else if (sorttype == 'desc') {\r\n sorttype = 'asc';\r\n }\r\n\r\n if (pageurl.indexOf('?') > -1) {\r\n para = '&';\r\n } else {\r\n para = '?';\r\n }\r\n\r\n pageurl = pageurl + para + 'sorttype=' + sorttype;\r\n window.open(pageurl, '_self');\r\n }\r\n\r\n\r\n /**\r\n * Clean the url parameters.\r\n * @param {string} url page url.\r\n * @param {string} parameter url parameter.\r\n * @return {url} sort url\r\n */\r\n function removeURLParameter(url, parameter) {\r\n // Prefer to use l.search if you have a location/link object.\r\n var urlparts = url.split('?');\r\n if (urlparts.length >= 2) {\r\n\r\n var prefix = encodeURIComponent(parameter) + '=';\r\n var pars = urlparts[1].split(/[&;]/g);\r\n\r\n // Reverse iteration as may be destructive.\r\n for (var i = pars.length; i-- > 0;) {\r\n // Idiom for string.startsWith.\r\n if (pars[i].lastIndexOf(prefix, 0) !== -1) {\r\n pars.splice(i, 1);\r\n }\r\n }\r\n url = urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : \"\");\r\n return url;\r\n } else {\r\n return url;\r\n }\r\n }\r\n\r\n /**\r\n * Bookmarks submit the form data.\r\n * @param {int} contextid context id.\r\n * @param {object} formData form instance data.\r\n * @return {void} ajax response\r\n */\r\n function submitFormdata(contextid, formData, button = null) {\r\n\r\n if (formData.pagetitle == \"\") {\r\n formData.pagetitle = document.querySelector('title').innerHTML;\r\n }\r\n var Formdata = JSON.stringify(formData);\r\n Ajax.call([{\r\n methodname: 'ltool_bookmarks_save_userbookmarks',\r\n args: {contextid: contextid, formdata: Formdata},\r\n done: function(response) {\r\n\r\n notification.addNotification({\r\n message: response.bookmarksmsg,\r\n type: response.notificationtype\r\n });\r\n\r\n\r\n let bookmarkmarked = document.getElementById('bookmarks-marked');\r\n if (response.bookmarksstatus) {\r\n if (button) {\r\n require(['mod_contentdesigner/elements'], function(Elements) {\r\n var chapterId = formData.itemid;\r\n if (chapterId) {\r\n Elements.removeWarning();\r\n Elements.refreshContent();\r\n }\r\n });\r\n } else {\r\n bookmarkmarked.classList.add('marked');\r\n }\r\n } else {\r\n if (button) {\r\n require(['mod_contentdesigner/elements'], function(Elements) {\r\n var chapterId = formData.itemid;\r\n if (chapterId) {\r\n Elements.removeWarning();\r\n Elements.refreshContent();\r\n }\r\n });\r\n } else {\r\n bookmarkmarked.classList.remove('marked');\r\n }\r\n }\r\n\r\n if (ltools.disappertimenotify != 0) {\r\n setTimeout(function() {\r\n document.querySelector(\"span.notifications\").innerHTML = \"\";\r\n }, ltools.disappertimenotify);\r\n }\r\n\r\n },fail: function(error) {\r\n notification.exception(error);\r\n }\r\n }]);\r\n }\r\n\r\n return {\r\n init: function(contextid, params) {\r\n learningToolBookmarksAction(contextid, params);\r\n }\r\n };\r\n});\r\n"],"names":["define","String","Ajax","notification","$","learningToolBookmarksAction","contextid","params","bookmarkmarked","document","getElementById","pagebookmarks","classList","add","remove","bookmarksform","addEventListener","e","preventDefault","submitFormdata","bookmarkshovercolor","getAttribute","bookmarksfontcolor","querySelector","style","background","color","on","button","this","itemType","data","itemId","userid","sesskey","course","coursemodule","contextlevel","pagetype","pageurl","M","cfg","pagetitle","title","pageid","itemtype","itemid","user","bookmarkssorttype","sorttype","window","location","href","para","url","parameter","urlparts","split","length","prefix","encodeURIComponent","pars","i","lastIndexOf","splice","join","removeURLParameter","indexOf","open","bookmarksSortActionPage","formData","innerHTML","Formdata","JSON","stringify","call","methodname","args","formdata","done","response","addNotification","message","bookmarksmsg","type","notificationtype","bookmarksstatus","require","Elements","removeWarning","refreshContent","ltools","disappertimenotify","setTimeout","fail","error","exception","init"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"learningbookmarks.min.js","sources":["../src/learningbookmarks.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\r\n//\r\n// Moodle is free software: you can redistribute it and/or modify\r\n// it under the terms of the GNU General Public License as published by\r\n// the Free Software Foundation, either version 3 of the License, or\r\n// (at your option) any later version.\r\n//\r\n// Moodle is distributed in the hope that it will be useful,\r\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n// GNU General Public License for more details.\r\n//\r\n// You should have received a copy of the GNU General Public License\r\n// along with Moodle. If not, see .\r\n\r\n/**\r\n * Bookmarks ltool define js.\r\n * @module ltool_bookmarks\r\n * @category Classes - autoloading\r\n * @copyright 2021, bdecent gmbh bdecent.de\r\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\r\n */\r\n\r\ndefine(['core/str', 'core/ajax', 'core/notification', 'jquery'],\r\n function(String, Ajax, notification, $) {\r\n\r\n /* global ltools, pagebookmarks */\r\n\r\n /**\r\n * Controls bookmarks tool action.\r\n * @param {int} contextid\r\n * @param {object} params\r\n */\r\n function learningToolBookmarksAction(contextid, params) {\r\n\r\n var bookmarkmarked = document.getElementById('bookmarks-marked');\r\n if (bookmarkmarked) {\r\n if (pagebookmarks) {\r\n bookmarkmarked.classList.add('marked');\r\n } else {\r\n bookmarkmarked.classList.remove('marked');\r\n }\r\n }\r\n\r\n var bookmarksform = document.getElementById('ltbookmarks-action');\r\n if (bookmarksform) {\r\n bookmarksform.addEventListener(\"click\", function(e) {\r\n e.preventDefault();\r\n submitFormdata(contextid, params);\r\n });\r\n // Hover color.\r\n var bookmarkshovercolor = bookmarksform.getAttribute(\"data-hovercolor\");\r\n var bookmarksfontcolor = bookmarksform.getAttribute(\"data-fontcolor\");\r\n if (bookmarkshovercolor && bookmarksfontcolor) {\r\n bookmarksform.addEventListener(\"mouseover\", function() {\r\n document.querySelector('#ltbookmarksinfo p').style.background = bookmarkshovercolor;\r\n document.querySelector('#ltbookmarksinfo p').style.color = bookmarksfontcolor;\r\n });\r\n }\r\n\r\n }\r\n\r\n // Content designer bookmarks.\r\n $(document).on('click', '.content-designer-learningtool-bookmark', function(e) {\r\n e.preventDefault();\r\n var button = $(this);\r\n var itemType = button.data('itemtype');\r\n var itemId = button.data('itemid');\r\n var userid = button.data('userid');\r\n var sesskey = button.data('sesskey');\r\n var course = button.data('courseid');\r\n var coursemodule = button.data('coursemodule');\r\n var contextlevel = button.data('contextlevel');\r\n var pagetype = button.data('pagetype');\r\n // Prepare the parameters for the bookmark.\r\n var contextId = M.cfg.contextid;\r\n var params = {\r\n pagetitle: document.title,\r\n pageurl: window.location.href,\r\n pageid: 0,\r\n itemtype: itemType,\r\n itemid: itemId,\r\n user: userid,\r\n sesskey: sesskey,\r\n course: course,\r\n coursemodule: coursemodule,\r\n contextlevel: contextlevel,\r\n pagetype: pagetype,\r\n };\r\n submitFormdata(contextId, params, button);\r\n });\r\n\r\n var bookmarkssorttype = document.getElementById(\"bookmarkssorttype\");\r\n\r\n if (bookmarkssorttype) {\r\n bookmarkssorttype.addEventListener(\"click\", function() {\r\n var sorttype = this.getAttribute(\"data-type\");\r\n bookmarksSortActionPage(sorttype);\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Sort the bookmarks list.\r\n * @param {string} sorttype type of sort\r\n * @return {void}\r\n */\r\n function bookmarksSortActionPage(sorttype) {\r\n\r\n var pageurl = window.location.href;\r\n var para = '';\r\n pageurl = removeURLParameter(pageurl, 'sorttype');\r\n\r\n if (sorttype == 'asc') {\r\n sorttype = 'desc';\r\n } else if (sorttype == 'desc') {\r\n sorttype = 'asc';\r\n }\r\n\r\n if (pageurl.indexOf('?') > -1) {\r\n para = '&';\r\n } else {\r\n para = '?';\r\n }\r\n\r\n pageurl = pageurl + para + 'sorttype=' + sorttype;\r\n window.open(pageurl, '_self');\r\n }\r\n\r\n\r\n /**\r\n * Clean the url parameters.\r\n * @param {string} url page url.\r\n * @param {string} parameter url parameter.\r\n * @return {url} sort url\r\n */\r\n function removeURLParameter(url, parameter) {\r\n // Prefer to use l.search if you have a location/link object.\r\n var urlparts = url.split('?');\r\n if (urlparts.length >= 2) {\r\n\r\n var prefix = encodeURIComponent(parameter) + '=';\r\n var pars = urlparts[1].split(/[&;]/g);\r\n\r\n // Reverse iteration as may be destructive.\r\n for (var i = pars.length; i-- > 0;) {\r\n // Idiom for string.startsWith.\r\n if (pars[i].lastIndexOf(prefix, 0) !== -1) {\r\n pars.splice(i, 1);\r\n }\r\n }\r\n url = urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : \"\");\r\n return url;\r\n } else {\r\n return url;\r\n }\r\n }\r\n\r\n /**\r\n * Bookmarks submit the form data.\r\n * @param {int} contextid context id.\r\n * @param {object} formData form instance data.\r\n * @return {void} ajax response\r\n */\r\n function submitFormdata(contextid, formData, button = null) {\r\n\r\n if (formData.pagetitle == \"\") {\r\n formData.pagetitle = document.querySelector('title').innerHTML;\r\n }\r\n var Formdata = JSON.stringify(formData);\r\n Ajax.call([{\r\n methodname: 'ltool_bookmarks_save_userbookmarks',\r\n args: {contextid: contextid, formdata: Formdata},\r\n done: function(response) {\r\n\r\n notification.addNotification({\r\n message: response.bookmarksmsg,\r\n type: response.notificationtype\r\n });\r\n\r\n\r\n let bookmarkmarked = document.getElementById('bookmarks-marked');\r\n if (response.bookmarksstatus) {\r\n if (button) {\r\n require(['mod_contentdesigner/elements'], function(Elements) {\r\n var chapterId = formData.itemid;\r\n if (chapterId) {\r\n Elements.refreshContent();\r\n }\r\n });\r\n } else {\r\n bookmarkmarked.classList.add('marked');\r\n }\r\n } else {\r\n if (button) {\r\n require(['mod_contentdesigner/elements'], function(Elements) {\r\n var chapterId = formData.itemid;\r\n if (chapterId) {\r\n Elements.refreshContent();\r\n }\r\n });\r\n } else {\r\n bookmarkmarked.classList.remove('marked');\r\n }\r\n }\r\n\r\n if (ltools.disappertimenotify != 0) {\r\n setTimeout(function() {\r\n document.querySelector(\"span.notifications\").innerHTML = \"\";\r\n }, ltools.disappertimenotify);\r\n }\r\n\r\n },fail: function(error) {\r\n notification.exception(error);\r\n }\r\n }]);\r\n }\r\n\r\n return {\r\n init: function(contextid, params) {\r\n learningToolBookmarksAction(contextid, params);\r\n }\r\n };\r\n});\r\n"],"names":["define","String","Ajax","notification","$","learningToolBookmarksAction","contextid","params","bookmarkmarked","document","getElementById","pagebookmarks","classList","add","remove","bookmarksform","addEventListener","e","preventDefault","submitFormdata","bookmarkshovercolor","getAttribute","bookmarksfontcolor","querySelector","style","background","color","on","button","this","itemType","data","itemId","userid","sesskey","course","coursemodule","contextlevel","pagetype","M","cfg","pagetitle","title","pageurl","window","location","href","pageid","itemtype","itemid","user","bookmarkssorttype","sorttype","para","url","parameter","urlparts","split","length","prefix","encodeURIComponent","pars","i","lastIndexOf","splice","join","removeURLParameter","indexOf","open","bookmarksSortActionPage","formData","innerHTML","Formdata","JSON","stringify","call","methodname","args","formdata","done","response","addNotification","message","bookmarksmsg","type","notificationtype","bookmarksstatus","require","Elements","refreshContent","ltools","disappertimenotify","setTimeout","fail","error","exception","init"],"mappings":"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"} diff --git a/ltool/bookmarks/classes/bookmarkstool_filter.php b/ltool/bookmarks/classes/bookmarkstool_filter.php index e6fd2ed..6b658d1 100644 --- a/ltool/bookmarks/classes/bookmarkstool_filter.php +++ b/ltool/bookmarks/classes/bookmarkstool_filter.php @@ -134,7 +134,6 @@ public function get_course_selector($selectcourse, $usercondition, $userparams) return $template; } - /** * Displays the Bookmarks sort selector info. * @return string bookmarks sort html. @@ -143,10 +142,10 @@ public function get_sort_instance() { global $OUTPUT; $template = []; - $coursesortparams = array('sort' => 'course'); + $coursesortparams = ['sort' => 'course']; $coursesortparams = array_merge($this->urlparams, $coursesortparams); - $datesortparams = array('sort' => 'date'); + $datesortparams = ['sort' => 'date']; $datesortparams = array_merge($this->urlparams, $datesortparams); $dateselect = ''; @@ -331,8 +330,8 @@ public function get_bookmark_deleteinfo($row) { if (has_capability($capability, $context, $particularuser)) { $buttons = []; $returnurl = new moodle_url('/local/learningtools/ltool/bookmarks/list.php'); - $deleteparams = array('delete' => $row->id, 'sesskey' => sesskey(), - 'courseid' => $this->courseid); + $deleteparams = ['delete' => $row->id, 'sesskey' => sesskey(), + 'courseid' => $this->courseid]; $deleteparams = array_merge($deleteparams, $this->urlparams); $url = new moodle_url($returnurl, $deleteparams); $strdelete = get_string('delete'); @@ -345,7 +344,7 @@ public function get_bookmark_deleteinfo($row) { if (has_capability('ltool/bookmarks:manageownbookmarks', $context)) { $buttons = []; $returnurl = new moodle_url('/local/learningtools/ltool/bookmarks/list.php'); - $deleteparams = array('delete' => $row->id, 'sesskey' => sesskey()); + $deleteparams = ['delete' => $row->id, 'sesskey' => sesskey()]; $deleteparams = array_merge($deleteparams, $this->urlparams); $url = new moodle_url($returnurl, $deleteparams);; $strdelete = get_string('delete'); diff --git a/ltool/bookmarks/classes/bookmarkstool_table.php b/ltool/bookmarks/classes/bookmarkstool_table.php index dd9cb0f..3a13db0 100644 --- a/ltool/bookmarks/classes/bookmarkstool_table.php +++ b/ltool/bookmarks/classes/bookmarkstool_table.php @@ -57,8 +57,8 @@ public function __construct($tableid, $courseid, $child, $teacher, $urlparams) { $this->urlparams = $urlparams; $this->teacher = $teacher; - $columns = array(); - $headers = array(); + $columns = []; + $headers = []; $columns[] = 'icon'; $headers[] = get_string('bookicon', 'local_learningtools'); @@ -191,8 +191,8 @@ public function col_delete(stdclass $row) { $strdelete = get_string('delete'); $buttons = []; $returnurl = new moodle_url('/local/learningtools/ltool/bookmarks/list.php'); - $deleteparams = array('delete' => $row->id, 'sesskey' => sesskey(), - 'courseid' => $this->courseid); + $deleteparams = ['delete' => $row->id, 'sesskey' => sesskey(), + 'courseid' => $this->courseid]; $deleteparams = array_merge($deleteparams, $this->urlparams); $url = new moodle_url($returnurl, $deleteparams); $buttons[] = html_writer::link($url, $OUTPUT->pix_icon('t/delete', $strdelete)); @@ -205,7 +205,7 @@ public function col_delete(stdclass $row) { $strdelete = get_string('delete'); $buttons = []; $returnurl = new moodle_url('/local/learningtools/ltool/bookmarks/list.php'); - $deleteparams = array('delete' => $row->id, 'sesskey' => sesskey()); + $deleteparams = ['delete' => $row->id, 'sesskey' => sesskey()]; $deleteparams = array_merge($deleteparams, $this->urlparams); $url = new moodle_url($returnurl, $deleteparams);; $buttons[] = html_writer::link($url, $OUTPUT->pix_icon('t/delete', $strdelete)); diff --git a/ltool/bookmarks/classes/external.php b/ltool/bookmarks/classes/external.php index 38c6f40..b112623 100644 --- a/ltool/bookmarks/classes/external.php +++ b/ltool/bookmarks/classes/external.php @@ -40,10 +40,10 @@ class external extends \external_api { public static function save_userbookmarks_parameters() { return new \external_function_parameters( - array( + [ 'contextid' => new \external_value(PARAM_INT, 'The context id for the course'), - 'formdata' => new \external_value(PARAM_RAW, 'The data from the user bookmarks') - ) + 'formdata' => new \external_value(PARAM_RAW, 'The data from the user bookmarks'), + ] ); } @@ -60,7 +60,7 @@ public static function save_userbookmarks($contextid, $formdata) { $context = \context_system::instance(); require_capability('ltool/bookmarks:createbookmarks', $context); $params = self::validate_parameters(self::save_userbookmarks_parameters(), - array('contextid' => $contextid, 'formdata' => $formdata)); + ['contextid' => $contextid, 'formdata' => $formdata]); // Parse serialize form data. $data = json_decode($params['formdata']); $data = (array) $data; @@ -75,11 +75,11 @@ public static function save_userbookmarks($contextid, $formdata) { public static function save_userbookmarks_returns() { return new \external_single_structure( - array( + [ 'bookmarksstatus' => new \external_value(PARAM_BOOL, 'save bookmarks status'), 'bookmarksmsg' => new \external_value(PARAM_TEXT, 'bookmarks message'), - 'notificationtype' => new \external_value(PARAM_TEXT, 'Notification type') - ) + 'notificationtype' => new \external_value(PARAM_TEXT, 'Notification type'), + ] ); } } diff --git a/ltool/bookmarks/classes/privacy/provider.php b/ltool/bookmarks/classes/privacy/provider.php index e57bbe2..a49cee8 100644 --- a/ltool/bookmarks/classes/privacy/provider.php +++ b/ltool/bookmarks/classes/privacy/provider.php @@ -26,10 +26,10 @@ use context; use core_privacy\local\metadata\collection; -use \core_privacy\local\request\contextlist; -use \core_privacy\local\request\userlist; -use \core_privacy\local\request\approved_userlist; -use \core_privacy\local\request\approved_contextlist; +use core_privacy\local\request\contextlist; +use core_privacy\local\request\userlist; +use core_privacy\local\request\approved_userlist; +use core_privacy\local\request\approved_contextlist; use core_privacy\local\request\helper; use core_privacy\local\request\transform; use core_privacy\local\request\writer; @@ -87,7 +87,7 @@ public static function user_has_bookmark_data($userid) { * @param int $userid The user to search. * @return contextlist $contextlist The list of contexts used in this plugin. */ - public static function get_contexts_for_userid(int $userid) : contextlist { + public static function get_contexts_for_userid(int $userid): contextlist { $contextlist = new \core_privacy\local\request\contextlist(); if (self::user_has_bookmark_data($userid)) { diff --git a/ltool/bookmarks/db/access.php b/ltool/bookmarks/db/access.php index 79d9458..33c404b 100644 --- a/ltool/bookmarks/db/access.php +++ b/ltool/bookmarks/db/access.php @@ -22,47 +22,47 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); -$capabilities = array( +$capabilities = [ - 'ltool/bookmarks:createbookmarks' => array( + 'ltool/bookmarks:createbookmarks' => [ 'riskbitmask' => RISK_SPAM, 'captype' => 'read', 'contextlevel' => CONTEXT_SYSTEM, - 'archetypes' => array( - 'user' => CAP_ALLOW - ) - ), + 'archetypes' => [ + 'user' => CAP_ALLOW, + ], + ], - 'ltool/bookmarks:viewownbookmarks' => array( + 'ltool/bookmarks:viewownbookmarks' => [ 'riskbitmask' => RISK_SPAM, 'captype' => 'read', 'contextlevel' => CONTEXT_SYSTEM, - 'archetypes' => array( - 'user' => CAP_ALLOW - ) - ), - 'ltool/bookmarks:manageownbookmarks' => array( + 'archetypes' => [ + 'user' => CAP_ALLOW, + ], + ], + 'ltool/bookmarks:manageownbookmarks' => [ 'riskbitmask' => RISK_SPAM, 'captype' => 'read', 'contextlevel' => CONTEXT_SYSTEM, - 'archetypes' => array( - 'user' => CAP_ALLOW - ) - ), + 'archetypes' => [ + 'user' => CAP_ALLOW, + ], + ], - 'ltool/bookmarks:viewbookmarks' => array( + 'ltool/bookmarks:viewbookmarks' => [ 'riskbitmask' => RISK_SPAM, 'captype' => 'read', 'contextlevel' => CONTEXT_COURSE, - 'archetypes' => array( + 'archetypes' => [ 'manager' => CAP_ALLOW, - ) - ), + ], + ], - 'ltool/bookmarks:managebookmarks' => array( + 'ltool/bookmarks:managebookmarks' => [ 'riskbitmask' => RISK_SPAM, 'captype' => 'read', 'contextlevel' => CONTEXT_COURSE, - ), + ], // Add more capabilities here ... -); +]; diff --git a/ltool/bookmarks/db/events.php b/ltool/bookmarks/db/events.php index c7a01c7..641358c 100644 --- a/ltool/bookmarks/db/events.php +++ b/ltool/bookmarks/db/events.php @@ -24,13 +24,13 @@ */ defined('MOODLE_INTERNAL') || die(); -$observers = array( - array( +$observers = [ + [ 'eventname' => 'core\event\course_deleted', 'callback' => '\ltool_bookmarks\event_observer::bookmarks_coursedata_deleteaction', - ), - array( + ], + [ 'eventname' => 'core\event\course_module_deleted', 'callback' => '\ltool_bookmarks\event_observer::bookmarks_moduledata_deleteaction', - ) -); + ], +]; diff --git a/ltool/bookmarks/db/services.php b/ltool/bookmarks/db/services.php index da90788..d4572b3 100644 --- a/ltool/bookmarks/db/services.php +++ b/ltool/bookmarks/db/services.php @@ -24,8 +24,8 @@ defined('MOODLE_INTERNAL') || die(); -$functions = array( - 'ltool_bookmarks_save_userbookmarks' => array( +$functions = [ + 'ltool_bookmarks_save_userbookmarks' => [ 'classname' => 'ltool_bookmarks\external', 'methodname' => 'save_userbookmarks', 'description' => 'Save the user Bookmarks', @@ -33,5 +33,5 @@ 'capabilities' => 'ltool/bookmarks:createbookmarks', 'ajax' => true, 'loginrequired' => true, - ), -); + ], +]; diff --git a/ltool/bookmarks/lang/en/ltool_bookmarks.php b/ltool/bookmarks/lang/en/ltool_bookmarks.php index 5e21a75..a51140c 100644 --- a/ltool/bookmarks/lang/en/ltool_bookmarks.php +++ b/ltool/bookmarks/lang/en/ltool_bookmarks.php @@ -22,28 +22,24 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ - defined("MOODLE_INTERNAL") || die(); +defined("MOODLE_INTERNAL") || die(); -$string['pluginname'] = "Learning Tools Bookmarks"; +$string['bookmarks'] = "Bookmarks"; $string['bookmarks:createbookmarks'] = "Create the bookmarks."; -$string['bookmarks:viewownbookmarks'] = "View the own bookmarks."; +$string['bookmarks:managebookmarks'] = "Manage the others boomarks."; $string['bookmarks:manageownbookmarks'] = "Manage the own bookmarks."; $string['bookmarks:viewbookmarks'] = "View the others bookmarks."; -$string['bookmarks:managebookmarks'] = "Manage the others boomarks."; -$string['bookmarks'] = "Bookmarks"; - -// Privacy API Metadata. -$string['privacy:metadata:bookmarks:userid'] = 'The ID of the user'; +$string['bookmarks:viewownbookmarks'] = "View the own bookmarks."; +$string['pluginname'] = "Learning Tools Bookmarks"; +$string['privacy:metadata:bookmarks:contextid'] = 'The Context ID of the bookmark page'; +$string['privacy:metadata:bookmarks:contextlevel'] = 'The Context level of the bookmark page'; $string['privacy:metadata:bookmarks:course'] = 'The ID of the course'; $string['privacy:metadata:bookmarks:coursemodule'] = 'The ID of the course module if user bookmarked the course modules page'; -$string['privacy:metadata:bookmarks:contextlevel'] = 'The Context level of the bookmark page'; -$string['privacy:metadata:bookmarks:contextid'] = 'The Context ID of the bookmark page'; -$string['privacy:metadata:bookmarks:pagetype'] = 'Bookmarked pagetype'; $string['privacy:metadata:bookmarks:pagetitle'] = 'Page title of Bookmarked page'; +$string['privacy:metadata:bookmarks:pagetype'] = 'Bookmarked pagetype'; $string['privacy:metadata:bookmarks:pageurl'] = 'Bookmarked page url'; -$string['privacy:metadata:bookmarks:itemtype'] = 'Bookmarked item type'; -$string['privacy:metadata:bookmarks:itemid'] = 'Bookmarked item id'; $string['privacy:metadata:bookmarks:timecreated'] = 'Time of the bookmarks created'; $string['privacy:metadata:bookmarks:timemodified'] = 'Time of the bookmarks modified'; +$string['privacy:metadata:bookmarks:userid'] = 'The ID of the user'; $string['privacy:metadata:bookmarksmetadata'] = 'List of users data stored in bookmarks subplugin'; $string['privacybookmarks'] = 'Learning tools - Bookmarks'; diff --git a/ltool/bookmarks/lib.php b/ltool/bookmarks/lib.php index 8a435b5..d7090ac 100644 --- a/ltool/bookmarks/lib.php +++ b/ltool/bookmarks/lib.php @@ -46,8 +46,8 @@ function ltool_bookmarks_myprofile_navigation(tree $tree, $user, $iscurrentuser, if ($iscurrentuser) { if (!empty($course)) { $coursecontext = context_course::instance($course->id); - $bookmarksurl = new moodle_url('/local/learningtools/ltool/bookmarks/list.php', array('courseid' => $course->id, - 'userid' => $userid)); + $bookmarksurl = new moodle_url('/local/learningtools/ltool/bookmarks/list.php', ['courseid' => $course->id, + 'userid' => $userid]); $bookmarksnode = new core_user\output\myprofile\node('learningtools', 'bookmarks', get_string('coursebookmarks', 'local_learningtools'), null, $bookmarksurl); @@ -77,10 +77,10 @@ function ltool_bookmarks_myprofile_navigation(tree $tree, $user, $iscurrentuser, $coursecontext = context_course::instance($course->id); if (has_capability('ltool/bookmarks:viewbookmarks', $coursecontext)) { - $bookmarksurl = new moodle_url('/local/learningtools/ltool/bookmarks/list.php', array('courseid' => $course->id, + $bookmarksurl = new moodle_url('/local/learningtools/ltool/bookmarks/list.php', ['courseid' => $course->id, 'userid' => $userid, - 'teacher' => 1 - )); + 'teacher' => 1, + ]); $bookmarksnode = new core_user\output\myprofile\node('learningtools', 'bookmarks', get_string('coursebookmarks', 'local_learningtools'), null, $bookmarksurl); @@ -116,7 +116,7 @@ function ltool_bookmarks_user_save_bookmarks($contextid, $data) { WHERE " . $DB->sql_compare_text('pageurl', 255). " = " . $DB->sql_compare_text('?', 255) . " AND contextid = ? AND userid = ?"; - $params = array($data['pageurl'], $contextid, $data['user']); + $params = [$data['pageurl'], $contextid, $data['user']]; if ($itemtype == 'chapter') { $sql .= " AND itemtype = ? AND itemid = ?"; $params = array_merge($params , [$itemtype, $itemid]); @@ -158,7 +158,7 @@ function ltool_bookmarks_user_save_bookmarks($contextid, $data) { 'context' => $context, 'other' => [ 'pagetype' => $data['pagetype'], - ] + ], ]); $event->trigger(); if ($itemtype == 'chapter') { @@ -191,7 +191,7 @@ function ltool_bookmarks_user_save_bookmarks($contextid, $data) { 'relateduserid' => $relateduserid, 'other' => [ 'pagetype' => $data['pagetype'], - ] + ], ]); $event->trigger(); @@ -231,7 +231,7 @@ function ltool_bookmarks_load_bookmarks_js_config($data) { global $PAGE, $USER; $pagebookmarks = $data['pagebookmarks']; $PAGE->requires->data_for_js('pagebookmarks', $pagebookmarks, true); - $PAGE->requires->js_call_amd('ltool_bookmarks/learningbookmarks', 'init', array($PAGE->context->id, $data)); + $PAGE->requires->js_call_amd('ltool_bookmarks/learningbookmarks', 'init', [$PAGE->context->id, $data]); } /** @@ -260,7 +260,7 @@ function ltool_bookmarks_check_page_bookmarks_exist($contextid, $pageurl, $useri AND contextid = ? AND userid = ? AND itemtype = ''"; - $params = array($pageurl, $contextid, $userid); + $params = [$pageurl, $contextid, $userid]; if ($DB->record_exists_sql($sql, $params)) { $pagebookmarks = true; } @@ -273,7 +273,7 @@ function ltool_bookmarks_check_page_bookmarks_exist($contextid, $pageurl, $useri */ function ltool_bookmarks_is_bookmarks_status() { global $DB; - $bookmarksrecord = $DB->get_record('local_learningtools_products', array('shortname' => 'bookmarks')); + $bookmarksrecord = $DB->get_record('local_learningtools_products', ['shortname' => 'bookmarks']); if (isset($bookmarksrecord->status) && !empty($bookmarksrecord->status)) { return true; } @@ -298,13 +298,11 @@ function ltool_bookmarks_require_bookmarks_status() { */ function ltool_bookmarks_delete_course_bookmarks($courseid) { global $DB; - if ($DB->record_exists('ltool_bookmarks_data', array('course' => $courseid))) { - $DB->delete_records('ltool_bookmarks_data', array('course' => $courseid)); + if ($DB->record_exists('ltool_bookmarks_data', ['course' => $courseid])) { + $DB->delete_records('ltool_bookmarks_data', ['course' => $courseid]); } } - - /** * Delete the course bookmarks. * @param int $module course module id. @@ -312,8 +310,8 @@ function ltool_bookmarks_delete_course_bookmarks($courseid) { function ltool_bookmarks_delete_module_bookmarks($module) { global $DB; - if ($DB->record_exists('ltool_bookmarks_data', array('coursemodule' => $module))) { - $DB->delete_records('ltool_bookmarks_data', array('coursemodule' => $module)); + if ($DB->record_exists('ltool_bookmarks_data', ['coursemodule' => $module])) { + $DB->delete_records('ltool_bookmarks_data', ['coursemodule' => $module]); } } diff --git a/ltool/bookmarks/list.php b/ltool/bookmarks/list.php index f082144..9f0add9 100644 --- a/ltool/bookmarks/list.php +++ b/ltool/bookmarks/list.php @@ -161,7 +161,7 @@ if ($confirm != md5($delete)) { echo $OUTPUT->header(); echo $OUTPUT->heading(get_string('deletemessage', 'local_learningtools')); - $optionsyes = array('delete' => $delete, 'confirm' => md5($delete), 'sesskey' => sesskey()); + $optionsyes = ['delete' => $delete, 'confirm' => md5($delete), 'sesskey' => sesskey()]; $optionsyes = array_merge($optionsyes, $urlparams); $deleteurl = new moodle_url('/local/learningtools/ltool/bookmarks/list.php', $optionsyes); $deletebutton = new single_button($deleteurl, get_string('delete'), 'post'); @@ -180,7 +180,7 @@ 'context' => $deleteeventcontext, 'other' => [ 'pagetype' => $deleterecord->pagetype, - ] + ], ]; if ($childid) { @@ -206,8 +206,8 @@ if ($userbase) { $usercontext = context_user::instance($userbase); - $userinfo = $DB->get_record('user', array('id' => $userbase)); - $headerinfo = array('heading' => fullname($userinfo), 'user' => $userinfo, 'usercontext' => $usercontext); + $userinfo = $DB->get_record('user', ['id' => $userbase]); + $headerinfo = ['heading' => fullname($userinfo), 'user' => $userinfo, 'usercontext' => $usercontext]; echo $OUTPUT->context_header($headerinfo, 2); } @@ -230,7 +230,6 @@ $sqlparams['userid'] = $USER->id; } - $blockinstance = new \ltool_bookmarks\bookmarkstool_filter($USER->id, $courseid, $childid, $teacher, $urlparams, $baseurl); if (!$courseid) { @@ -245,7 +244,6 @@ $urlparams['selectcourse'] = $selectcourse; } - $templatecontent['sortfilter'] = $blockinstance->get_sort_instance(); $maindata = $blockinstance->get_main_body($sqlconditions, $sqlparams, $sort, $sorttype, $page, $perpage); $templatecontent['showbookmarks'] = true; diff --git a/ltool/bookmarks/tests/ltool_bookmarks_test.php b/ltool/bookmarks/tests/ltool_bookmarks_test.php index da1c70c..19182c2 100644 --- a/ltool/bookmarks/tests/ltool_bookmarks_test.php +++ b/ltool/bookmarks/tests/ltool_bookmarks_test.php @@ -27,8 +27,7 @@ * Bookmarks subplugin for learningtools phpunit test cases defined. * @runTestsInSeparateProcesses */ -class ltool_bookmarks_test extends \advanced_testcase { - +final class ltool_bookmarks_test extends \advanced_testcase { /** * Summary of context diff --git a/ltool/focus/classes/external.php b/ltool/focus/classes/external.php index a099098..1352d18 100644 --- a/ltool/focus/classes/external.php +++ b/ltool/focus/classes/external.php @@ -40,9 +40,9 @@ class external extends \external_api { public static function save_userfocusmode_parameters() { return new \external_function_parameters( - array( + [ 'status' => new \external_value(PARAM_INT, 'The user focus mode status'), - ) + ] ); } @@ -57,7 +57,7 @@ public static function save_userfocusmode($status) { $context = \context_system::instance(); require_capability('ltool/focus:createfocus', $context); $params = self::validate_parameters(self::save_userfocusmode_parameters(), - array('status' => $status)); + ['status' => $status]); $SESSION->focusmode = $params['status']; return $status; } diff --git a/ltool/focus/classes/privacy/provider.php b/ltool/focus/classes/privacy/provider.php index 08424e7..d6020b9 100644 --- a/ltool/focus/classes/privacy/provider.php +++ b/ltool/focus/classes/privacy/provider.php @@ -34,9 +34,8 @@ class provider implements \core_privacy\local\metadata\null_provider { * * @return string */ - public static function get_reason() : string { + public static function get_reason(): string { return 'privacy:metadata'; } } - diff --git a/ltool/focus/db/access.php b/ltool/focus/db/access.php index c81172e..693db58 100644 --- a/ltool/focus/db/access.php +++ b/ltool/focus/db/access.php @@ -23,14 +23,14 @@ */ defined('MOODLE_INTERNAL') || die(); -$capabilities = array( +$capabilities = [ - 'ltool/focus:createfocus' => array( + 'ltool/focus:createfocus' => [ 'riskbitmask' => RISK_SPAM, 'captype' => 'read', 'contextlevel' => CONTEXT_SYSTEM, - 'archetypes' => array( - 'user' => CAP_ALLOW - ) - ) -); + 'archetypes' => [ + 'user' => CAP_ALLOW, + ], + ], +]; diff --git a/ltool/focus/db/events.php b/ltool/focus/db/events.php index 88a08cd..b079e02 100644 --- a/ltool/focus/db/events.php +++ b/ltool/focus/db/events.php @@ -24,9 +24,9 @@ */ defined('MOODLE_INTERNAL') || die(); -$observers = array( - array( +$observers = [ + [ 'eventname' => 'core\event\config_log_created', 'callback' => '\ltool_focus\event_observer::ltool_focus_changeconfig', - ), -); + ], +]; diff --git a/ltool/focus/db/services.php b/ltool/focus/db/services.php index d2550a7..5b09ccc 100644 --- a/ltool/focus/db/services.php +++ b/ltool/focus/db/services.php @@ -24,8 +24,8 @@ defined('MOODLE_INTERNAL') || die(); -$functions = array( - 'ltool_focus_save_userfocusmode' => array( +$functions = [ + 'ltool_focus_save_userfocusmode' => [ 'classname' => 'ltool_focus\external', 'methodname' => 'save_userfocusmode', 'description' => 'Save the user focus mode', @@ -33,5 +33,5 @@ 'capabilities' => 'ltool/focus:createfocus', 'ajax' => true, 'loginrequired' => true, - ), -); + ], +]; diff --git a/ltool/focus/lang/en/ltool_focus.php b/ltool/focus/lang/en/ltool_focus.php index e0df53d..ea14802 100644 --- a/ltool/focus/lang/en/ltool_focus.php +++ b/ltool/focus/lang/en/ltool_focus.php @@ -24,6 +24,6 @@ defined("MOODLE_INTERNAL") || die(); -$string['pluginname'] = "Learning Tools Focus mode"; $string['focus:createfocus'] = "Create the Focus tool"; +$string['pluginname'] = "Learning Tools Focus mode"; $string['privacy:metadata'] = 'The Focus tool only displays existing data.'; diff --git a/ltool/focus/lib.php b/ltool/focus/lib.php index 1f5940b..7b0b535 100644 --- a/ltool/focus/lib.php +++ b/ltool/focus/lib.php @@ -44,9 +44,9 @@ function ltool_focus_load_focus_config() { $disableclass = 'disable-focus d-none'; $focuscsshtml = ''; $PAGE->add_header_action($focuscsshtml); - $focusdisable = html_writer::start_tag('div', array('id' => 'disable-focusmode', 'class' => $disableclass)); - $focusdisable .= html_writer::start_tag('button', array('class' => 'btn btn-primary')); - $focusdisable .= html_writer::tag('i', '', array('class' => 'fa fa-close')); + $focusdisable = html_writer::start_tag('div', ['id' => 'disable-focusmode', 'class' => $disableclass]); + $focusdisable .= html_writer::start_tag('button', ['class' => 'btn btn-primary']); + $focusdisable .= html_writer::tag('i', '', ['class' => 'fa fa-close']); $focusdisable .= html_writer::end_tag('button'); $focusdisable .= html_writer::end_tag('div'); $PAGE->add_header_action($focusdisable); @@ -67,7 +67,7 @@ function ltool_focus_get_focus_css_url() { $filename = $file->get_filename(); } } - // TODO: FILE EXISTS CHECK. + // Todo: FILE EXISTS CHECK. if ($fs->file_exists($fileinfo['contextid'], $fileinfo['component'], $fileinfo['filearea'], $fileinfo['itemid'], $fileinfo['filepath'], $filename)) { $url = moodle_url::make_pluginfile_url($fileinfo['contextid'], $fileinfo['component'], $fileinfo['filearea'], @@ -85,7 +85,7 @@ function ltool_focus_load_js_config() { global $PAGE, $SESSION; if (isset($SESSION->focusmode)) { $focusmode = $SESSION->focusmode; - $PAGE->requires->js_call_amd('ltool_focus/focus', 'init', array('focusmode' => $focusmode)); + $PAGE->requires->js_call_amd('ltool_focus/focus', 'init', ['focusmode' => $focusmode]); } } @@ -115,14 +115,14 @@ function ltool_focus_create_focus_temp_cssfile() { * @return array file info */ function ltool_focus_get_focus_css_fileinfo() { - $fileinfo = array( + $fileinfo = [ 'contextid' => context_system::instance()->id, 'component' => 'ltool_focus', 'filearea' => 'focuscss', 'itemid' => 0, 'filepath' => '/', - 'filename' => 'focus_'.time().'.css' - ); + 'filename' => 'focus_'.time().'.css', + ]; return $fileinfo; } @@ -185,4 +185,3 @@ function ltool_focus_focusmode_actions() { } ltool_focus_load_focus_config(); } - diff --git a/ltool/focus/tests/ltool_focus_test.php b/ltool/focus/tests/ltool_focus_test.php index def93e9..603bb3e 100644 --- a/ltool/focus/tests/ltool_focus_test.php +++ b/ltool/focus/tests/ltool_focus_test.php @@ -26,7 +26,7 @@ /** * focus subplugin for learningtools phpunit test cases defined. */ -class ltool_focus_test extends \advanced_testcase { +final class ltool_focus_test extends \advanced_testcase { /** * Create custom page instance and set admin user as loggedin user. * @@ -43,7 +43,7 @@ public function setup(): void { * Create css file in temp directory. * @covers ::ltool_focus_create_focus_temp_cssfile */ - public function test_ltool_focus_create_focus_temp_cssfile() { + public function test_ltool_focus_create_focus_temp_cssfile(): void { $configdata = get_config('ltool_focus', 'focusmodecss'); $fileinfo = ltool_focus_create_focus_temp_cssfile(); $this->assertEquals($configdata, $fileinfo->get_content()); diff --git a/ltool/note/amd/build/learningnote.min.js b/ltool/note/amd/build/learningnote.min.js index 694cd3d..f9f29a0 100644 --- a/ltool/note/amd/build/learningnote.min.js +++ b/ltool/note/amd/build/learningnote.min.js @@ -5,6 +5,6 @@ * @copyright 2021, bdecent gmbh bdecent.de * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("ltool_note/learningnote",["jquery","core/modal_factory","core/str","core/fragment","core/modal_events","core/ajax","core/notification"],(function($,ModalFactory,String,Fragment,ModalEvents,Ajax,notification){function learningToolNoteAction(contextid,params){!function(contextid,params){var notesinfo=document.querySelector(".ltnoteinfo #ltnote-action");if(notesinfo){notesinfo.addEventListener("click",(function(){params.itemtype="",params.itemid=0,modalshowHandler(contextid,params)}));var notehovercolor=notesinfo.getAttribute("data-hovercolor"),notefontcolor=notesinfo.getAttribute("data-fontcolor");notehovercolor&¬efontcolor&¬esinfo.addEventListener("mouseover",(function(){document.querySelector("#ltnoteinfo p").style.background=notehovercolor,document.querySelector("#ltnoteinfo p").style.color=notefontcolor}))}}(contextid,params);var sorttypefilter=document.querySelector(".ltnote-sortfilter i#notessorttype");sorttypefilter&&sorttypefilter.addEventListener("click",(function(){!function(sorttype){var pageurl=window.location.href;pageurl=function(url,parameter){var urlparts=url.split("?");if(urlparts.length>=2){for(var prefix=encodeURIComponent(parameter)+"=",pars=urlparts[1].split(/[&;]/g),i=pars.length;i-- >0;)-1!==pars[i].lastIndexOf(prefix,0)&&pars.splice(i,1);return url=urlparts[0]+(pars.length>0?"?"+pars.join("&"):"")}return url}(pageurl,"sorttype"),"asc"==sorttype?sorttype="desc":"desc"==sorttype&&(sorttype="asc");var para="";para=pageurl.indexOf("?")>-1?"&":"?";pageurl=pageurl+para+"sorttype="+sorttype,window.open(pageurl,"_self")}(this.getAttribute("data-type"))})),$(document).on("click",".content-designer-learningtool-note",(function(e){var button=$(this),itemType=button.data("itemtype"),itemId=button.data("itemid"),pageurl=button.data("pageurl");params.itemtype=itemType,params.itemid=itemId,params.pageurl=pageurl,modalshowHandler(contextid,params,!0)}))}function modalshowHandler(contextid,params){let contentDesigner=arguments.length>2&&void 0!==arguments[2]&&arguments[2];var newnote=String.get_string("newnote","local_learningtools");$.when(newnote).done((function(localizedEditString){var ltoolnotebody=document.getElementsByTagName("body")[0];ltoolnotebody.classList.contains("learningtool-note")||ltoolnotebody.classList.add("learningtool-note"),ModalFactory.create({title:localizedEditString+getPopoutAction(),type:ModalFactory.types.SAVE_CANCEL,body:getnoteaction(contextid,params),large:!0}).then((function(modal){return modal.show(),modal.getRoot().on(ModalEvents.hidden,(function(){modal.destroy()})),modal.getRoot().on(ModalEvents.save,(function(e){e.preventDefault(),$(e.target).find("button[data-action=save]").attr("disabled",!0),modal.getRoot().find("form").submit()})),modal.getRoot().on("submit","form",(e=>{e.preventDefault(),submitFormData(modal,contextid,params,contentDesigner)})),document.querySelector("#popout-action").addEventListener("click",(function(){var pageurlobj=params.pageurl.split("&"),pageurljson=JSON.stringify(pageurlobj),url=M.cfg.wwwroot+"/local/learningtools/ltool/note/pop_out.php?contextid="+params.contextid+"&pagetype="+params.pagetype+"&contextlevel="+params.contextlevel+"&course="+params.course+"&user="+params.user+"&pageurl="+pageurljson+"&pagetitle="+params.pagetitle+"&heading="+params.heading+"&sesskey="+params.sesskey;params.itemtype&&(url+="&itemtype="+params.itemtype+"&itemid="+params.itemid),modal.hide(),window.open(url,"_blank")})),modal})).catch(notification.exception)}))}function getPopoutAction(){return"
"}function submitFormData(modal,contextid,params){let contentDesigner=arguments.length>3&&void 0!==arguments[3]&&arguments[3];var modalform=document.querySelectorAll(".ltoolusernotes form")[0],formData=new URLSearchParams(new FormData(modalform)).toString(),notesuccess=String.get_string("successnotemessage","local_learningtools");Ajax.call([{methodname:"ltool_note_save_usernote",args:{contextid:contextid,formdata:formData},done:function(response){if(response)if(contentDesigner)require(["mod_contentdesigner/elements"],(function(Elements){params.itemid&&(Elements.removeWarning(),Elements.refreshContent())}));else{var noteinfo=document.querySelector(".ltnoteinfo span");noteinfo.classList.contains("ticked")||noteinfo.classList.add("ticked"),noteinfo.innerHTML=response}modal.hide(),$.when(notesuccess).done((function(localizedEditString){notification.addNotification({message:localizedEditString,type:"success"})})),0!=ltools.disappertimenotify&&setTimeout((function(){document.querySelector("span.notifications").innerHTML=""}),ltools.disappertimenotify)}}])}function getnoteaction(contextid,params){return params.contextid=contextid,""==params.pagetitle&&(params.pagetitle=document.querySelector("title").innerHTML),Fragment.loadFragment("ltool_note","get_note_form",contextid,params)}return{init:function(contextid,params){learningToolNoteAction(contextid,params)}}})); +define("ltool_note/learningnote",["jquery","core/modal_factory","core/str","core/fragment","core/modal_events","core/ajax","core/notification","core/utils","core/config"],(function($,ModalFactory,String,Fragment,ModalEvents,Ajax,notification,Utils,Config){var printWindow=null;function learningToolNoteAction(contextid){const params=window.ltool_note_config||{};!function(contextid,params){var notesinfo=document.querySelector(".ltnoteinfo #ltnote-action");if(notesinfo){notesinfo.addEventListener("click",(function(){params.itemtype="",params.itemid=0,modalshowHandler(contextid,params)}));var notehovercolor=notesinfo.getAttribute("data-hovercolor"),notefontcolor=notesinfo.getAttribute("data-fontcolor");notehovercolor&¬efontcolor&¬esinfo.addEventListener("mouseover",(function(){document.querySelector("#ltnoteinfo p").style.background=notehovercolor,document.querySelector("#ltnoteinfo p").style.color=notefontcolor}))}}(contextid,params);var sorttypefilter=document.querySelector(".ltnote-sortfilter i#notessorttype");sorttypefilter&&sorttypefilter.addEventListener("click",(function(){!function(sorttype){var pageurl=window.location.href;pageurl=function(url,parameter){var urlparts=url.split("?");if(urlparts.length>=2){for(var prefix=encodeURIComponent(parameter)+"=",pars=urlparts[1].split(/[&;]/g),i=pars.length;i-- >0;)-1!==pars[i].lastIndexOf(prefix,0)&&pars.splice(i,1);return url=urlparts[0]+(pars.length>0?"?"+pars.join("&"):"")}return url}(pageurl,"sorttype"),"asc"==sorttype?sorttype="desc":"desc"==sorttype&&(sorttype="asc");var para="";para=pageurl.indexOf("?")>-1?"&":"?";pageurl=pageurl+para+"sorttype="+sorttype,window.open(pageurl,"_self")}(this.getAttribute("data-type"))})),$(document).on("click",".content-designer-learningtool-note",(function(e){var button=$(this),itemType=button.data("itemtype"),itemId=button.data("itemid"),pageurl=button.data("pageurl");params.itemtype=itemType,params.itemid=itemId,params.pageurl=pageurl,modalshowHandler(contextid,params,!0)}));var noteprintblock=document.querySelector(".note-print-block");noteprintblock&¬eprintblock.addEventListener("click",notePrintHandler.bind(contextid,params));const clearIcon=document.querySelector('.ltool-navigation [data-action="clearsearch"]');var searchinput=document.querySelector('.ltool-navigation [data-action="search"]');clearIcon&&clearIcon.addEventListener("click",(()=>{searchinput.value="",searchinput.focus(),clearSearch(clearIcon),performSearch("",contextid,params)})),searchinput&&searchinput.addEventListener("input",Utils.debounce((()=>{if(""===searchinput.value)clearSearch(clearIcon),performSearch("",contextid,params);else{activeSearch(clearIcon);var search=searchinput.value.trim();console.log(searchinput.value.trim()),performSearch(search,contextid,params)}}),1e3))}function performSearch(searchTerm,contextid,params){var notesContainer=document.querySelector(".ltool-notes-container, .note-list-container, .ltool-notes-grid");if(!notesContainer){var currentUrl=new URL(window.location.href);return currentUrl.searchParams.set("search",searchTerm),void(window.location.href=currentUrl.toString())}notesContainer.innerHTML='

Searching notes...

';var fragmentParams={courseid:params.course,search:searchTerm,sectionid:0,activity:0,filter:"",print:!1};Fragment.loadFragment("ltool_note","get_notes_list",contextid,fragmentParams).then((html=>{notesContainer.innerHTML=html;var currentUrl=new URL(window.location.href);currentUrl.searchParams.set("search",searchTerm),window.history.pushState({},"",currentUrl.toString())})).catch((error=>{console.error("Search error:",error),notesContainer.innerHTML='
Error loading search results. Please try again.
'}))}const clearSearch=clearIcon=>{clearIcon.classList.add("d-none")},activeSearch=clearIcon=>{clearIcon.classList.remove("d-none")};function modalshowHandler(contextid,params){let contentDesigner=arguments.length>2&&void 0!==arguments[2]&&arguments[2];var newnote=String.get_string("newnote","local_learningtools");$.when(newnote).done((function(localizedEditString){var ltoolnotebody=document.getElementsByTagName("body")[0];ltoolnotebody.classList.contains("learningtool-note")||ltoolnotebody.classList.add("learningtool-note"),ModalFactory.create({title:localizedEditString+getPopoutAction(),type:ModalFactory.types.SAVE_CANCEL,body:getnoteaction(contextid,params),large:!0}).then((function(modal){return modal.show(),modal.getRoot().on(ModalEvents.hidden,(function(){modal.destroy()})),modal.getRoot().on(ModalEvents.save,(function(e){e.preventDefault(),$(e.target).find("button[data-action=save]").attr("disabled",!0),modal.getRoot().find("form").submit()})),modal.getRoot().on("submit","form",(e=>{e.preventDefault(),submitFormData(modal,contextid,params,contentDesigner)})),document.querySelector("#popout-action").addEventListener("click",(function(){var pageurlobj=params.pageurl.split("&"),pageurljson=JSON.stringify(pageurlobj),url=M.cfg.wwwroot+"/local/learningtools/ltool/note/pop_out.php?contextid="+params.contextid+"&pagetype="+params.pagetype+"&contextlevel="+params.contextlevel+"&course="+params.course+"&user="+params.user+"&pageurl="+pageurljson+"&pagetitle="+params.pagetitle+"&heading="+params.heading+"&sesskey="+params.sesskey;params.itemtype&&(url+="&itemtype="+params.itemtype+"&itemid="+params.itemid),modal.hide(),window.open(url,"_blank")})),modal})).catch(notification.exception)}))}function getPopoutAction(){return"
"}function submitFormData(modal,contextid,params){let contentDesigner=arguments.length>3&&void 0!==arguments[3]&&arguments[3];var modalform=document.querySelectorAll(".ltoolusernotes form")[0],formData=new URLSearchParams(new FormData(modalform)).toString(),notesuccess=String.get_string("successnotemessage","local_learningtools");Ajax.call([{methodname:"ltool_note_save_usernote",args:{contextid:contextid,formdata:formData},done:function(response){if(response)if(contentDesigner)require(["mod_contentdesigner/elements"],(function(Elements){params.itemid&&(Elements.removeWarning(),Elements.refreshContent())}));else{var noteinfo=document.querySelector(".ltnoteinfo span");noteinfo.classList.contains("ticked")||noteinfo.classList.add("ticked"),noteinfo.innerHTML=response}modal.hide(),$.when(notesuccess).done((function(localizedEditString){notification.addNotification({message:localizedEditString,type:"success"})})),0!=ltools.disappertimenotify&&setTimeout((function(){document.querySelector("span.notifications").innerHTML=""}),ltools.disappertimenotify)}}])}function getnoteaction(contextid,params){return params.contextid=contextid,""==params.pagetitle&&(params.pagetitle=document.querySelector("title").innerHTML),Fragment.loadFragment("ltool_note","get_note_form",contextid,params)}function notePrintHandler(args){if(printWindow&&!printWindow.closed)return printWindow.focus(),!0;var printUrl=Config.wwwroot+"/local/learningtools/ltool/note/print.php",params=new URLSearchParams;params.append("contextid",args.contextid),params.append("courseid",args.course||0),params.append("sesskey",args.sesskey);var currentUrl=new URL(window.location.href),search=currentUrl.searchParams.get("search")||"",filter=currentUrl.searchParams.get("filter")||"",sectionid=currentUrl.searchParams.get("sectionid")||0,activity=currentUrl.searchParams.get("activity")||0;search&¶ms.append("search",search),filter&¶ms.append("filter",filter),sectionid&¶ms.append("sectionid",sectionid),activity&¶ms.append("activity",activity);var fullUrl=printUrl+"?"+params.toString();return(printWindow=window.open(fullUrl,"printNotes","width=1000,height=700,scrollbars=yes,resizable=yes,toolbar=no,location=no,status=no"))&&printWindow.focus(),!0}return{init:contextid=>{learningToolNoteAction(contextid)}}})); //# sourceMappingURL=learningnote.min.js.map \ No newline at end of file diff --git a/ltool/note/amd/build/learningnote.min.js.map b/ltool/note/amd/build/learningnote.min.js.map index 50e57fc..f66a58f 100644 --- a/ltool/note/amd/build/learningnote.min.js.map +++ b/ltool/note/amd/build/learningnote.min.js.map @@ -1 +1 @@ -{"version":3,"file":"learningnote.min.js","sources":["../src/learningnote.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\r\n//\r\n// Moodle is free software: you can redistribute it and/or modify\r\n// it under the terms of the GNU General Public License as published by\r\n// the Free Software Foundation, either version 3 of the License, or\r\n// (at your option) any later version.\r\n//\r\n// Moodle is distributed in the hope that it will be useful,\r\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n// GNU General Public License for more details.\r\n//\r\n// You should have received a copy of the GNU General Public License\r\n// along with Moodle. If not, see .\r\n\r\n/**\r\n * Notes ltool define js.\r\n * @module ltool_note\r\n * @category Classes - autoloading\r\n * @copyright 2021, bdecent gmbh bdecent.de\r\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\r\n */\r\n\r\ndefine(['jquery', 'core/modal_factory', 'core/str', 'core/fragment', 'core/modal_events', 'core/ajax', 'core/notification'],\r\n function($, ModalFactory, String, Fragment, ModalEvents, Ajax, notification) {\r\n\r\n /* global ltools */\r\n\r\n /**\r\n * Controls notes tool action.\r\n * @param {int} contextid context id\r\n * @param {object} params notes info params\r\n */\r\n function learningToolNoteAction(contextid, params) {\r\n showModalLttool(contextid, params);\r\n var sorttypefilter = document.querySelector(\".ltnote-sortfilter i#notessorttype\");\r\n if (sorttypefilter) {\r\n sorttypefilter.addEventListener(\"click\", function() {\r\n var sorttype = this.getAttribute('data-type');\r\n noteSortActionPage(sorttype);\r\n });\r\n }\r\n // Content designer note.\r\n $(document).on('click', '.content-designer-learningtool-note', function(e) {\r\n var button = $(this);\r\n var itemType = button.data('itemtype');\r\n var itemId = button.data('itemid');\r\n var pageurl = button.data('pageurl');\r\n params.itemtype = itemType;\r\n params.itemid = itemId;\r\n params.pageurl = pageurl;\r\n modalshowHandler(contextid, params, true);\r\n });\r\n }\r\n\r\n /**\r\n * Clean the url parameters.\r\n * @param {string} url page url.\r\n * @param {string} parameter url parameter.\r\n * @return {url} sort url\r\n */\r\n function removeURLParameter(url, parameter) {\r\n // Prefer to use l.search if you have a location/link object.\r\n var urlparts = url.split('?');\r\n if (urlparts.length >= 2) {\r\n\r\n var prefix = encodeURIComponent(parameter) + '=';\r\n var pars = urlparts[1].split(/[&;]/g);\r\n\r\n // Reverse iteration as may be destructive.\r\n for (var i = pars.length; i-- > 0;) {\r\n // Idiom for string.startsWith.\r\n if (pars[i].lastIndexOf(prefix, 0) !== -1) {\r\n pars.splice(i, 1);\r\n }\r\n }\r\n\r\n url = urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : \"\");\r\n return url;\r\n } else {\r\n return url;\r\n }\r\n }\r\n\r\n\r\n function modalshowHandler(contextid, params, contentDesigner = false) {\r\n var newnote = String.get_string('newnote', 'local_learningtools');\r\n $.when(newnote).done(function(localizedEditString) {\r\n // Add class.\r\n var ltoolnotebody = document.getElementsByTagName('body')[0];\r\n if (!ltoolnotebody.classList.contains('learningtool-note')) {\r\n ltoolnotebody.classList.add('learningtool-note');\r\n }\r\n\r\n ModalFactory.create({\r\n title: localizedEditString + getPopoutAction(),\r\n type: ModalFactory.types.SAVE_CANCEL,\r\n body: getnoteaction(contextid, params),\r\n large: true\r\n }).then(function(modal) {\r\n\r\n modal.show();\r\n\r\n modal.getRoot().on(ModalEvents.hidden, function() {\r\n modal.destroy();\r\n });\r\n\r\n modal.getRoot().on(ModalEvents.save, function(e) {\r\n e.preventDefault();\r\n $(e.target).find(\"button[data-action=save]\").attr(\"disabled\", true);\r\n modal.getRoot().find('form').submit();\r\n });\r\n\r\n modal.getRoot().on('submit', 'form', e => {\r\n e.preventDefault();\r\n submitFormData(modal, contextid, params, contentDesigner);\r\n });\r\n\r\n document.querySelector(\"#popout-action\").addEventListener('click', function() {\r\n var pageurlobj = params.pageurl.split(\"&\");\r\n var pageurljson = JSON.stringify(pageurlobj);\r\n var url = M.cfg.wwwroot + \"/local/learningtools/ltool/note/pop_out.php?contextid=\" +\r\n params.contextid + \"&pagetype=\" + params.pagetype + \"&contextlevel=\" + params.contextlevel + \"&course=\"\r\n + params.course + \"&user=\" + params.user + \"&pageurl=\" + pageurljson + \"&pagetitle=\" + params.pagetitle\r\n + \"&heading=\" + params.heading + \"&sesskey=\" + params.sesskey;\r\n if (params.itemtype) {\r\n url += \"&itemtype=\" + params.itemtype + \"&itemid=\" + params.itemid;\r\n }\r\n modal.hide();\r\n window.open(url, '_blank');\r\n });\r\n return modal;\r\n }).catch(notification.exception);\r\n });\r\n };\r\n\r\n /**\r\n * Display the modal popup.\r\n * @param {int} contextid context id\r\n * @param {object} params notes info params\r\n * @return {void}\r\n */\r\n function showModalLttool(contextid, params) {\r\n\r\n var notesinfo = document.querySelector(\".ltnoteinfo #ltnote-action\");\r\n if (notesinfo) {\r\n notesinfo.addEventListener(\"click\", function() {\r\n params.itemtype= '';\r\n params.itemid= 0;\r\n modalshowHandler(contextid, params);\r\n });\r\n // Hover color.\r\n var notehovercolor = notesinfo.getAttribute(\"data-hovercolor\");\r\n var notefontcolor = notesinfo.getAttribute(\"data-fontcolor\");\r\n if (notehovercolor && notefontcolor) {\r\n notesinfo.addEventListener(\"mouseover\", function() {\r\n document.querySelector('#ltnoteinfo p').style.background = notehovercolor;\r\n document.querySelector('#ltnoteinfo p').style.color = notefontcolor;\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Sort the notes list.\r\n * @param {string} sorttype sort type\r\n * @return {void}\r\n */\r\n function noteSortActionPage(sorttype) {\r\n\r\n var pageurl = window.location.href;\r\n pageurl = removeURLParameter(pageurl, 'sorttype');\r\n\r\n if (sorttype == 'asc') {\r\n sorttype = 'desc';\r\n } else if (sorttype == 'desc') {\r\n sorttype = 'asc';\r\n }\r\n var para = '';\r\n if (pageurl.indexOf('?') > -1) {\r\n para = '&';\r\n } else {\r\n para = '?';\r\n }\r\n\r\n pageurl = pageurl + para + 'sorttype=' + sorttype;\r\n window.open(pageurl, '_self');\r\n }\r\n\r\n /**\r\n * Popout url action html.\r\n * @return {string} popout html\r\n */\r\n function getPopoutAction() {\r\n var popouthtml = \"
\";\r\n return popouthtml;\r\n }\r\n\r\n /**\r\n * Submit the modal data form.\r\n * @param {object} modal object\r\n * @param {int} contextid context id\r\n * @return {void} ajax respoltoolsnse.\r\n */\r\n function submitFormData(modal, contextid, params, contentDesigner = false) {\r\n var modalform = document.querySelectorAll('.ltoolusernotes form')[0];\r\n var formData = new URLSearchParams(new FormData(modalform)).toString();\r\n var notesuccess = String.get_string('successnotemessage', 'local_learningtools');\r\n Ajax.call([{\r\n methodname: 'ltool_note_save_usernote',\r\n args: {contextid: contextid, formdata: formData},\r\n done: function(response) {\r\n // Insert data into notes badge.\r\n if (response) {\r\n // Check if this is a content designer note by looking for the trigger button\r\n if (contentDesigner) {\r\n // Try to refresh the chapter if content designer is available\r\n require(['mod_contentdesigner/elements'], function(Elements) {\r\n var chapterId = params.itemid;\r\n if (chapterId) {\r\n Elements.removeWarning();\r\n Elements.refreshContent();\r\n }\r\n });\r\n } else {\r\n var noteinfo = document.querySelector(\".ltnoteinfo span\");\r\n if (!noteinfo.classList.contains('ticked')) {\r\n noteinfo.classList.add('ticked');\r\n }\r\n noteinfo.innerHTML = response;\r\n }\r\n }\r\n\r\n modal.hide();\r\n $.when(notesuccess).done(function(localizedEditString) {\r\n notification.addNotification({\r\n message: localizedEditString,\r\n type: \"success\"\r\n });\r\n });\r\n\r\n if (ltools.disappertimenotify != 0) {\r\n setTimeout(function() {\r\n document.querySelector(\"span.notifications\").innerHTML = \"\";\r\n }, ltools.disappertimenotify);\r\n }\r\n },\r\n }]);\r\n }\r\n\r\n /**\r\n * Submit the modal data form.\r\n * @param {int} contextid\r\n * @param {object} params list of the notes params.\r\n * @return {string} displayed the note editor form\r\n */\r\n function getnoteaction(contextid, params) {\r\n params.contextid = contextid;\r\n if (params.pagetitle == \"\") {\r\n params.pagetitle = document.querySelector(\"title\").innerHTML;\r\n }\r\n return Fragment.loadFragment('ltool_note', 'get_note_form', contextid, params);\r\n }\r\n return {\r\n init: function(contextid, params) {\r\n learningToolNoteAction(contextid, params);\r\n }\r\n };\r\n});"],"names":["define","$","ModalFactory","String","Fragment","ModalEvents","Ajax","notification","learningToolNoteAction","contextid","params","notesinfo","document","querySelector","addEventListener","itemtype","itemid","modalshowHandler","notehovercolor","getAttribute","notefontcolor","style","background","color","showModalLttool","sorttypefilter","sorttype","pageurl","window","location","href","url","parameter","urlparts","split","length","prefix","encodeURIComponent","pars","i","lastIndexOf","splice","join","removeURLParameter","para","indexOf","open","noteSortActionPage","this","on","e","button","itemType","data","itemId","contentDesigner","newnote","get_string","when","done","localizedEditString","ltoolnotebody","getElementsByTagName","classList","contains","add","create","title","getPopoutAction","type","types","SAVE_CANCEL","body","getnoteaction","large","then","modal","show","getRoot","hidden","destroy","save","preventDefault","target","find","attr","submit","submitFormData","pageurlobj","pageurljson","JSON","stringify","M","cfg","wwwroot","pagetype","contextlevel","course","user","pagetitle","heading","sesskey","hide","catch","exception","modalform","querySelectorAll","formData","URLSearchParams","FormData","toString","notesuccess","call","methodname","args","formdata","response","require","Elements","removeWarning","refreshContent","noteinfo","innerHTML","addNotification","message","ltools","disappertimenotify","setTimeout","loadFragment","init"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"learningnote.min.js","sources":["../src/learningnote.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\r\n//\r\n// Moodle is free software: you can redistribute it and/or modify\r\n// it under the terms of the GNU General Public License as published by\r\n// the Free Software Foundation, either version 3 of the License, or\r\n// (at your option) any later version.\r\n//\r\n// Moodle is distributed in the hope that it will be useful,\r\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n// GNU General Public License for more details.\r\n//\r\n// You should have received a copy of the GNU General Public License\r\n// along with Moodle. If not, see .\r\n\r\n/**\r\n * Notes ltool define js.\r\n * @module ltool_note\r\n * @category Classes - autoloading\r\n * @copyright 2021, bdecent gmbh bdecent.de\r\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\r\n */\r\n\r\ndefine(['jquery', 'core/modal_factory', 'core/str', 'core/fragment', 'core/modal_events', 'core/ajax', 'core/notification', 'core/utils', \"core/config\"],\r\n function ($, ModalFactory, String, Fragment, ModalEvents, Ajax, notification, Utils, Config) {\r\n\r\n /* global ltools, ltool_note_config */\r\n\r\n // Store reference to print window\r\n var printWindow = null\r\n\r\n /**\r\n * Controls notes tool action.\r\n * @param {int} contextid context id\r\n */\r\n function learningToolNoteAction(contextid) {\r\n // Get configuration from global variable\r\n const params = window.ltool_note_config || {}\r\n\r\n showModalLttool(contextid, params);\r\n var sorttypefilter = document.querySelector(\".ltnote-sortfilter i#notessorttype\");\r\n if (sorttypefilter) {\r\n sorttypefilter.addEventListener(\"click\", function () {\r\n var sorttype = this.getAttribute('data-type');\r\n noteSortActionPage(sorttype);\r\n });\r\n }\r\n\r\n // Content designer note.\r\n $(document).on('click', '.content-designer-learningtool-note', function (e) {\r\n var button = $(this);\r\n var itemType = button.data('itemtype');\r\n var itemId = button.data('itemid');\r\n var pageurl = button.data('pageurl');\r\n params.itemtype = itemType;\r\n params.itemid = itemId;\r\n params.pageurl = pageurl;\r\n modalshowHandler(contextid, params, true);\r\n });\r\n\r\n var noteprintblock = document.querySelector(\".note-print-block\");\r\n if (noteprintblock) {\r\n noteprintblock.addEventListener(\"click\", notePrintHandler.bind(contextid, params));\r\n }\r\n\r\n const clearIcon = document.querySelector('.ltool-navigation [data-action=\"clearsearch\"]');\r\n var searchinput = document.querySelector('.ltool-navigation [data-action=\"search\"]');\r\n\r\n if (clearIcon) {\r\n clearIcon.addEventListener('click', () => {\r\n searchinput.value = '';\r\n searchinput.focus();\r\n clearSearch(clearIcon);\r\n // Load default content without search\r\n performSearch(\"\", contextid, params);\r\n });\r\n }\r\n\r\n if (searchinput) {\r\n searchinput.addEventListener('input', Utils.debounce(() => {\r\n if (searchinput.value === '') {\r\n clearSearch(clearIcon);\r\n // Load default content without search\r\n performSearch(\"\", contextid, params);\r\n } else {\r\n activeSearch(clearIcon);\r\n var search = searchinput.value.trim();\r\n // If you have a search function, you can call it here.\r\n console.log(searchinput.value.trim());\r\n performSearch(search, contextid, params);\r\n }\r\n }, 1000));\r\n }\r\n\r\n }\r\n\r\n /**\r\n * Perform search and update the notes list\r\n * @param {string} searchTerm The search term\r\n * @param {int} contextid The context ID\r\n * @param {object} params The parameters\r\n */\r\n function performSearch(searchTerm, contextid, params) {\r\n var notesContainer = document.querySelector(\".ltool-notes-container, .note-list-container, .ltool-notes-grid\")\r\n\r\n if (!notesContainer) {\r\n // If no container found, reload page with search parameter\r\n var currentUrl = new URL(window.location.href)\r\n currentUrl.searchParams.set(\"search\", searchTerm)\r\n window.location.href = currentUrl.toString()\r\n return\r\n }\r\n\r\n // Show loading indicator\r\n notesContainer.innerHTML =\r\n '

Searching notes...

'\r\n\r\n // Prepare fragment parameters\r\n var fragmentParams = {\r\n courseid: params.course,\r\n search: searchTerm,\r\n sectionid: 0,\r\n activity: 0,\r\n filter: \"\",\r\n print: false,\r\n }\r\n\r\n // Load search results using fragment\r\n Fragment.loadFragment(\"ltool_note\", \"get_notes_list\", contextid, fragmentParams)\r\n .then((html) => {\r\n notesContainer.innerHTML = html\r\n // Update URL without reloading page\r\n var currentUrl = new URL(window.location.href)\r\n currentUrl.searchParams.set(\"search\", searchTerm)\r\n window.history.pushState({}, \"\", currentUrl.toString())\r\n })\r\n .catch((error) => {\r\n console.error(\"Search error:\", error)\r\n notesContainer.innerHTML =\r\n '
Error loading search results. Please try again.
'\r\n })\r\n }\r\n\r\n /**\r\n * Reset the search icon and trigger the init for the block.\r\n *\r\n * @param {HTMLElement} clearIcon Our closing icon to manipulate.\r\n */\r\n const clearSearch = (clearIcon) => {\r\n clearIcon.classList.add('d-none');\r\n };\r\n\r\n /**\r\n * Change the searching icon to its' active state.\r\n *\r\n * @param {HTMLElement} clearIcon Our closing icon to manipulate.\r\n */\r\n const activeSearch = (clearIcon) => {\r\n clearIcon.classList.remove('d-none');\r\n };\r\n\r\n /**\r\n * Clean the url parameters.\r\n * @param {string} url page url.\r\n * @param {string} parameter url parameter.\r\n * @return {url} sort url\r\n */\r\n function removeURLParameter(url, parameter) {\r\n // Prefer to use l.search if you have a location/link object.\r\n var urlparts = url.split('?');\r\n if (urlparts.length >= 2) {\r\n\r\n var prefix = encodeURIComponent(parameter) + '=';\r\n var pars = urlparts[1].split(/[&;]/g);\r\n\r\n // Reverse iteration as may be destructive.\r\n for (var i = pars.length; i-- > 0;) {\r\n // Idiom for string.startsWith.\r\n if (pars[i].lastIndexOf(prefix, 0) !== -1) {\r\n pars.splice(i, 1);\r\n }\r\n }\r\n\r\n url = urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : \"\");\r\n return url;\r\n } else {\r\n return url;\r\n }\r\n }\r\n\r\n\r\n function modalshowHandler(contextid, params, contentDesigner = false) {\r\n var newnote = String.get_string('newnote', 'local_learningtools');\r\n $.when(newnote).done(function (localizedEditString) {\r\n // Add class.\r\n var ltoolnotebody = document.getElementsByTagName('body')[0];\r\n if (!ltoolnotebody.classList.contains('learningtool-note')) {\r\n ltoolnotebody.classList.add('learningtool-note');\r\n }\r\n\r\n ModalFactory.create({\r\n title: localizedEditString + getPopoutAction(),\r\n type: ModalFactory.types.SAVE_CANCEL,\r\n body: getnoteaction(contextid, params),\r\n large: true\r\n }).then(function (modal) {\r\n\r\n modal.show();\r\n\r\n modal.getRoot().on(ModalEvents.hidden, function () {\r\n modal.destroy();\r\n });\r\n\r\n modal.getRoot().on(ModalEvents.save, function (e) {\r\n e.preventDefault();\r\n $(e.target).find(\"button[data-action=save]\").attr(\"disabled\", true);\r\n modal.getRoot().find('form').submit();\r\n });\r\n\r\n modal.getRoot().on('submit', 'form', e => {\r\n e.preventDefault();\r\n submitFormData(modal, contextid, params, contentDesigner);\r\n });\r\n\r\n document.querySelector(\"#popout-action\").addEventListener('click', function () {\r\n var pageurlobj = params.pageurl.split(\"&\");\r\n var pageurljson = JSON.stringify(pageurlobj);\r\n var url = M.cfg.wwwroot + \"/local/learningtools/ltool/note/pop_out.php?contextid=\" +\r\n params.contextid + \"&pagetype=\" + params.pagetype + \"&contextlevel=\" + params.contextlevel + \"&course=\"\r\n + params.course + \"&user=\" + params.user + \"&pageurl=\" + pageurljson + \"&pagetitle=\" + params.pagetitle\r\n + \"&heading=\" + params.heading + \"&sesskey=\" + params.sesskey;\r\n if (params.itemtype) {\r\n url += \"&itemtype=\" + params.itemtype + \"&itemid=\" + params.itemid;\r\n }\r\n modal.hide();\r\n window.open(url, '_blank');\r\n });\r\n return modal;\r\n }).catch(notification.exception);\r\n });\r\n };\r\n\r\n /**\r\n * Display the modal popup.\r\n * @param {int} contextid context id\r\n * @param {object} params notes info params\r\n * @return {void}\r\n */\r\n function showModalLttool(contextid, params) {\r\n\r\n var notesinfo = document.querySelector(\".ltnoteinfo #ltnote-action\");\r\n if (notesinfo) {\r\n notesinfo.addEventListener(\"click\", function () {\r\n params.itemtype = '';\r\n params.itemid = 0;\r\n modalshowHandler(contextid, params);\r\n });\r\n // Hover color.\r\n var notehovercolor = notesinfo.getAttribute(\"data-hovercolor\");\r\n var notefontcolor = notesinfo.getAttribute(\"data-fontcolor\");\r\n if (notehovercolor && notefontcolor) {\r\n notesinfo.addEventListener(\"mouseover\", function () {\r\n document.querySelector('#ltnoteinfo p').style.background = notehovercolor;\r\n document.querySelector('#ltnoteinfo p').style.color = notefontcolor;\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Sort the notes list.\r\n * @param {string} sorttype sort type\r\n * @return {void}\r\n */\r\n function noteSortActionPage(sorttype) {\r\n\r\n var pageurl = window.location.href;\r\n pageurl = removeURLParameter(pageurl, 'sorttype');\r\n\r\n if (sorttype == 'asc') {\r\n sorttype = 'desc';\r\n } else if (sorttype == 'desc') {\r\n sorttype = 'asc';\r\n }\r\n var para = '';\r\n if (pageurl.indexOf('?') > -1) {\r\n para = '&';\r\n } else {\r\n para = '?';\r\n }\r\n\r\n pageurl = pageurl + para + 'sorttype=' + sorttype;\r\n window.open(pageurl, '_self');\r\n }\r\n\r\n /**\r\n * Popout url action html.\r\n * @return {string} popout html\r\n */\r\n function getPopoutAction() {\r\n var popouthtml = \"
\";\r\n return popouthtml;\r\n }\r\n\r\n /**\r\n * Submit the modal data form.\r\n * @param {object} modal object\r\n * @param {int} contextid context id\r\n * @return {void} ajax respoltoolsnse.\r\n */\r\n function submitFormData(modal, contextid, params, contentDesigner = false) {\r\n var modalform = document.querySelectorAll('.ltoolusernotes form')[0];\r\n var formData = new URLSearchParams(new FormData(modalform)).toString();\r\n var notesuccess = String.get_string('successnotemessage', 'local_learningtools');\r\n Ajax.call([{\r\n methodname: 'ltool_note_save_usernote',\r\n args: { contextid: contextid, formdata: formData },\r\n done: function (response) {\r\n // Insert data into notes badge.\r\n if (response) {\r\n // Check if this is a content designer note by looking for the trigger button\r\n if (contentDesigner) {\r\n // Try to refresh the chapter if content designer is available\r\n require(['mod_contentdesigner/elements'], function (Elements) {\r\n var chapterId = params.itemid;\r\n if (chapterId) {\r\n Elements.removeWarning();\r\n Elements.refreshContent();\r\n }\r\n });\r\n } else {\r\n var noteinfo = document.querySelector(\".ltnoteinfo span\");\r\n if (!noteinfo.classList.contains('ticked')) {\r\n noteinfo.classList.add('ticked');\r\n }\r\n noteinfo.innerHTML = response;\r\n }\r\n }\r\n\r\n modal.hide();\r\n $.when(notesuccess).done(function (localizedEditString) {\r\n notification.addNotification({\r\n message: localizedEditString,\r\n type: \"success\"\r\n });\r\n });\r\n\r\n if (ltools.disappertimenotify != 0) {\r\n setTimeout(function () {\r\n document.querySelector(\"span.notifications\").innerHTML = \"\";\r\n }, ltools.disappertimenotify);\r\n }\r\n },\r\n }]);\r\n }\r\n\r\n /**\r\n * Submit the modal data form.\r\n * @param {int} contextid\r\n * @param {object} params list of the notes params.\r\n * @return {string} displayed the note editor form\r\n */\r\n function getnoteaction(contextid, params) {\r\n params.contextid = contextid;\r\n if (params.pagetitle == \"\") {\r\n params.pagetitle = document.querySelector(\"title\").innerHTML;\r\n }\r\n return Fragment.loadFragment('ltool_note', 'get_note_form', contextid, params);\r\n }\r\n\r\n /**\r\n * Handle print action\r\n * @param {object} args Configuration arguments\r\n */\r\n function notePrintHandler(args) {\r\n // Prevent multiple print windows\r\n if (printWindow && !printWindow.closed) {\r\n printWindow.focus()\r\n return true\r\n }\r\n\r\n // Create URL for print page\r\n var printUrl = Config.wwwroot + \"/local/learningtools/ltool/note/print.php\"\r\n var params = new URLSearchParams()\r\n\r\n params.append(\"contextid\", args.contextid)\r\n params.append(\"courseid\", args.course || 0)\r\n params.append(\"sesskey\", args.sesskey)\r\n\r\n // Add current filter parameters if they exist\r\n var currentUrl = new URL(window.location.href)\r\n var search = currentUrl.searchParams.get(\"search\") || \"\"\r\n var filter = currentUrl.searchParams.get(\"filter\") || \"\"\r\n var sectionid = currentUrl.searchParams.get(\"sectionid\") || 0\r\n var activity = currentUrl.searchParams.get(\"activity\") || 0\r\n\r\n if (search) params.append(\"search\", search)\r\n if (filter) params.append(\"filter\", filter)\r\n if (sectionid) params.append(\"sectionid\", sectionid)\r\n if (activity) params.append(\"activity\", activity)\r\n\r\n var fullUrl = printUrl + \"?\" + params.toString()\r\n\r\n // Open print page in new window and store reference\r\n printWindow = window.open(\r\n fullUrl,\r\n \"printNotes\",\r\n \"width=1000,height=700,scrollbars=yes,resizable=yes,toolbar=no,location=no,status=no\",\r\n )\r\n\r\n // Focus the print window\r\n if (printWindow) {\r\n printWindow.focus()\r\n }\r\n\r\n return true\r\n }\r\n\r\n function getnotescontents(contextid, params) {\r\n return Fragment.loadFragment('ltool_note', 'get_notes_contents', contextid, params);\r\n }\r\n\r\n return {\r\n\r\n init: (contextid) => {\r\n learningToolNoteAction(contextid);\r\n },\r\n };\r\n});\r\n"],"names":["define","$","ModalFactory","String","Fragment","ModalEvents","Ajax","notification","Utils","Config","printWindow","learningToolNoteAction","contextid","params","window","ltool_note_config","notesinfo","document","querySelector","addEventListener","itemtype","itemid","modalshowHandler","notehovercolor","getAttribute","notefontcolor","style","background","color","showModalLttool","sorttypefilter","sorttype","pageurl","location","href","url","parameter","urlparts","split","length","prefix","encodeURIComponent","pars","i","lastIndexOf","splice","join","removeURLParameter","para","indexOf","open","noteSortActionPage","this","on","e","button","itemType","data","itemId","noteprintblock","notePrintHandler","bind","clearIcon","searchinput","value","focus","clearSearch","performSearch","debounce","activeSearch","search","trim","console","log","searchTerm","notesContainer","currentUrl","URL","searchParams","set","toString","innerHTML","fragmentParams","courseid","course","sectionid","activity","filter","print","loadFragment","then","html","history","pushState","catch","error","classList","add","remove","contentDesigner","newnote","get_string","when","done","localizedEditString","ltoolnotebody","getElementsByTagName","contains","create","title","getPopoutAction","type","types","SAVE_CANCEL","body","getnoteaction","large","modal","show","getRoot","hidden","destroy","save","preventDefault","target","find","attr","submit","submitFormData","pageurlobj","pageurljson","JSON","stringify","M","cfg","wwwroot","pagetype","contextlevel","user","pagetitle","heading","sesskey","hide","exception","modalform","querySelectorAll","formData","URLSearchParams","FormData","notesuccess","call","methodname","args","formdata","response","require","Elements","removeWarning","refreshContent","noteinfo","addNotification","message","ltools","disappertimenotify","setTimeout","closed","printUrl","append","get","fullUrl","init"],"mappings":"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"} \ No newline at end of file diff --git a/ltool/note/amd/build/print.min.js b/ltool/note/amd/build/print.min.js new file mode 100644 index 0000000..7dd6443 --- /dev/null +++ b/ltool/note/amd/build/print.min.js @@ -0,0 +1,10 @@ +/** + * Print functionality for notes. + * + * @module ltool_note/print + * @copyright 2025 bdecent gmbh + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +define("ltool_note/print",["jquery"],($=>({init:function(){const printBtn=document.getElementById("print-notes-btn");printBtn&&printBtn.addEventListener("click",(e=>{e.preventDefault(),window.print()}));const returnBtn=document.getElementById("return-notes-btn");returnBtn&&returnBtn.addEventListener("click",(e=>{e.preventDefault(),window.close()})),document.addEventListener("keydown",(e=>{e.ctrlKey&&"p"===e.key&&(e.preventDefault(),window.print()),"Escape"===e.key&&(e.preventDefault(),window.close())})),document.querySelectorAll(".collapse").forEach((element=>{element.classList.add("show")}))}}))); + +//# sourceMappingURL=print.min.js.map \ No newline at end of file diff --git a/ltool/note/amd/build/print.min.js.map b/ltool/note/amd/build/print.min.js.map new file mode 100644 index 0000000..15d96dd --- /dev/null +++ b/ltool/note/amd/build/print.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"print.min.js","sources":["../src/print.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Print functionality for notes.\n *\n * @module ltool_note/print\n * @copyright 2025 bdecent gmbh \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(['jquery'], ($) => {\n /**\n * Initialize print functionality\n */\n function init() {\n // Print button functionality\n const printBtn = document.getElementById(\"print-notes-btn\")\n if (printBtn) {\n printBtn.addEventListener(\"click\", (e) => {\n e.preventDefault()\n window.print()\n })\n }\n\n // Return button functionality\n const returnBtn = document.getElementById(\"return-notes-btn\")\n if (returnBtn) {\n returnBtn.addEventListener(\"click\", (e) => {\n e.preventDefault()\n window.close()\n })\n }\n\n // Keyboard shortcuts\n document.addEventListener(\"keydown\", (e) => {\n // Ctrl+P for print\n if (e.ctrlKey && e.key === \"p\") {\n e.preventDefault()\n window.print()\n }\n // Escape to close\n if (e.key === \"Escape\") {\n e.preventDefault()\n window.close()\n }\n })\n\n // Auto-expand all accordions for print\n const collapseElements = document.querySelectorAll(\".collapse\")\n collapseElements.forEach((element) => {\n element.classList.add(\"show\")\n })\n\n }\n\n return {\n init: init,\n }\n})\n"],"names":["define","$","init","printBtn","document","getElementById","addEventListener","e","preventDefault","window","print","returnBtn","close","ctrlKey","key","querySelectorAll","forEach","element","classList","add"],"mappings":";;;;;;;AAuBAA,0BAAO,CAAC,WAAYC,IA6CX,CACLC,sBAxCMC,SAAWC,SAASC,eAAe,mBACrCF,UACFA,SAASG,iBAAiB,SAAUC,IAClCA,EAAEC,iBACFC,OAAOC,iBAKLC,UAAYP,SAASC,eAAe,oBACtCM,WACFA,UAAUL,iBAAiB,SAAUC,IACnCA,EAAEC,iBACFC,OAAOG,WAKXR,SAASE,iBAAiB,WAAYC,IAEhCA,EAAEM,SAAqB,MAAVN,EAAEO,MACjBP,EAAEC,iBACFC,OAAOC,SAGK,WAAVH,EAAEO,MACJP,EAAEC,iBACFC,OAAOG,YAKcR,SAASW,iBAAiB,aAClCC,SAASC,UACxBA,QAAQC,UAAUC,IAAI"} \ No newline at end of file diff --git a/ltool/note/amd/src/learningnote.js b/ltool/note/amd/src/learningnote.js index ae8291a..74b7b5a 100644 --- a/ltool/note/amd/src/learningnote.js +++ b/ltool/note/amd/src/learningnote.js @@ -21,27 +21,33 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define(['jquery', 'core/modal_factory', 'core/str', 'core/fragment', 'core/modal_events', 'core/ajax', 'core/notification'], - function($, ModalFactory, String, Fragment, ModalEvents, Ajax, notification) { +define(['jquery', 'core/modal_factory', 'core/str', 'core/fragment', 'core/modal_events', 'core/ajax', 'core/notification', 'core/utils', "core/config"], + function ($, ModalFactory, String, Fragment, ModalEvents, Ajax, notification, Utils, Config) { - /* global ltools */ + /* global ltools, ltool_note_config */ + + // Store reference to print window + var printWindow = null /** * Controls notes tool action. * @param {int} contextid context id - * @param {object} params notes info params */ - function learningToolNoteAction(contextid, params) { + function learningToolNoteAction(contextid) { + // Get configuration from global variable + const params = window.ltool_note_config || {} + showModalLttool(contextid, params); var sorttypefilter = document.querySelector(".ltnote-sortfilter i#notessorttype"); if (sorttypefilter) { - sorttypefilter.addEventListener("click", function() { + sorttypefilter.addEventListener("click", function () { var sorttype = this.getAttribute('data-type'); noteSortActionPage(sorttype); }); } + // Content designer note. - $(document).on('click', '.content-designer-learningtool-note', function(e) { + $(document).on('click', '.content-designer-learningtool-note', function (e) { var button = $(this); var itemType = button.data('itemtype'); var itemId = button.data('itemid'); @@ -51,8 +57,108 @@ define(['jquery', 'core/modal_factory', 'core/str', 'core/fragment', 'core/modal params.pageurl = pageurl; modalshowHandler(contextid, params, true); }); + + var noteprintblock = document.querySelector(".note-print-block"); + if (noteprintblock) { + noteprintblock.addEventListener("click", notePrintHandler.bind(contextid, params)); + } + + const clearIcon = document.querySelector('.ltool-navigation [data-action="clearsearch"]'); + var searchinput = document.querySelector('.ltool-navigation [data-action="search"]'); + + if (clearIcon) { + clearIcon.addEventListener('click', () => { + searchinput.value = ''; + searchinput.focus(); + clearSearch(clearIcon); + // Load default content without search + performSearch("", contextid, params); + }); + } + + if (searchinput) { + searchinput.addEventListener('input', Utils.debounce(() => { + if (searchinput.value === '') { + clearSearch(clearIcon); + // Load default content without search + performSearch("", contextid, params); + } else { + activeSearch(clearIcon); + var search = searchinput.value.trim(); + // If you have a search function, you can call it here. + console.log(searchinput.value.trim()); + performSearch(search, contextid, params); + } + }, 1000)); + } + + } + + /** + * Perform search and update the notes list + * @param {string} searchTerm The search term + * @param {int} contextid The context ID + * @param {object} params The parameters + */ + function performSearch(searchTerm, contextid, params) { + var notesContainer = document.querySelector(".ltool-notes-container, .note-list-container, .ltool-notes-grid") + + if (!notesContainer) { + // If no container found, reload page with search parameter + var currentUrl = new URL(window.location.href) + currentUrl.searchParams.set("search", searchTerm) + window.location.href = currentUrl.toString() + return + } + + // Show loading indicator + notesContainer.innerHTML = + '

Searching notes...

' + + // Prepare fragment parameters + var fragmentParams = { + courseid: params.course, + search: searchTerm, + sectionid: 0, + activity: 0, + filter: "", + print: false, + } + + // Load search results using fragment + Fragment.loadFragment("ltool_note", "get_notes_list", contextid, fragmentParams) + .then((html) => { + notesContainer.innerHTML = html + // Update URL without reloading page + var currentUrl = new URL(window.location.href) + currentUrl.searchParams.set("search", searchTerm) + window.history.pushState({}, "", currentUrl.toString()) + }) + .catch((error) => { + console.error("Search error:", error) + notesContainer.innerHTML = + '
Error loading search results. Please try again.
' + }) } + /** + * Reset the search icon and trigger the init for the block. + * + * @param {HTMLElement} clearIcon Our closing icon to manipulate. + */ + const clearSearch = (clearIcon) => { + clearIcon.classList.add('d-none'); + }; + + /** + * Change the searching icon to its' active state. + * + * @param {HTMLElement} clearIcon Our closing icon to manipulate. + */ + const activeSearch = (clearIcon) => { + clearIcon.classList.remove('d-none'); + }; + /** * Clean the url parameters. * @param {string} url page url. @@ -85,7 +191,7 @@ define(['jquery', 'core/modal_factory', 'core/str', 'core/fragment', 'core/modal function modalshowHandler(contextid, params, contentDesigner = false) { var newnote = String.get_string('newnote', 'local_learningtools'); - $.when(newnote).done(function(localizedEditString) { + $.when(newnote).done(function (localizedEditString) { // Add class. var ltoolnotebody = document.getElementsByTagName('body')[0]; if (!ltoolnotebody.classList.contains('learningtool-note')) { @@ -97,15 +203,15 @@ define(['jquery', 'core/modal_factory', 'core/str', 'core/fragment', 'core/modal type: ModalFactory.types.SAVE_CANCEL, body: getnoteaction(contextid, params), large: true - }).then(function(modal) { + }).then(function (modal) { modal.show(); - modal.getRoot().on(ModalEvents.hidden, function() { + modal.getRoot().on(ModalEvents.hidden, function () { modal.destroy(); }); - modal.getRoot().on(ModalEvents.save, function(e) { + modal.getRoot().on(ModalEvents.save, function (e) { e.preventDefault(); $(e.target).find("button[data-action=save]").attr("disabled", true); modal.getRoot().find('form').submit(); @@ -116,13 +222,13 @@ define(['jquery', 'core/modal_factory', 'core/str', 'core/fragment', 'core/modal submitFormData(modal, contextid, params, contentDesigner); }); - document.querySelector("#popout-action").addEventListener('click', function() { + document.querySelector("#popout-action").addEventListener('click', function () { var pageurlobj = params.pageurl.split("&"); var pageurljson = JSON.stringify(pageurlobj); var url = M.cfg.wwwroot + "/local/learningtools/ltool/note/pop_out.php?contextid=" + - params.contextid + "&pagetype=" + params.pagetype + "&contextlevel=" + params.contextlevel + "&course=" - + params.course + "&user=" + params.user + "&pageurl=" + pageurljson + "&pagetitle=" + params.pagetitle - + "&heading=" + params.heading + "&sesskey=" + params.sesskey; + params.contextid + "&pagetype=" + params.pagetype + "&contextlevel=" + params.contextlevel + "&course=" + + params.course + "&user=" + params.user + "&pageurl=" + pageurljson + "&pagetitle=" + params.pagetitle + + "&heading=" + params.heading + "&sesskey=" + params.sesskey; if (params.itemtype) { url += "&itemtype=" + params.itemtype + "&itemid=" + params.itemid; } @@ -144,16 +250,16 @@ define(['jquery', 'core/modal_factory', 'core/str', 'core/fragment', 'core/modal var notesinfo = document.querySelector(".ltnoteinfo #ltnote-action"); if (notesinfo) { - notesinfo.addEventListener("click", function() { - params.itemtype= ''; - params.itemid= 0; + notesinfo.addEventListener("click", function () { + params.itemtype = ''; + params.itemid = 0; modalshowHandler(contextid, params); }); // Hover color. var notehovercolor = notesinfo.getAttribute("data-hovercolor"); var notefontcolor = notesinfo.getAttribute("data-fontcolor"); if (notehovercolor && notefontcolor) { - notesinfo.addEventListener("mouseover", function() { + notesinfo.addEventListener("mouseover", function () { document.querySelector('#ltnoteinfo p').style.background = notehovercolor; document.querySelector('#ltnoteinfo p').style.color = notefontcolor; }); @@ -193,7 +299,7 @@ define(['jquery', 'core/modal_factory', 'core/str', 'core/fragment', 'core/modal */ function getPopoutAction() { var popouthtml = "
"; + + "name='popoutsubmit'>Pop out "; return popouthtml; } @@ -209,14 +315,14 @@ define(['jquery', 'core/modal_factory', 'core/str', 'core/fragment', 'core/modal var notesuccess = String.get_string('successnotemessage', 'local_learningtools'); Ajax.call([{ methodname: 'ltool_note_save_usernote', - args: {contextid: contextid, formdata: formData}, - done: function(response) { + args: { contextid: contextid, formdata: formData }, + done: function (response) { // Insert data into notes badge. if (response) { // Check if this is a content designer note by looking for the trigger button if (contentDesigner) { // Try to refresh the chapter if content designer is available - require(['mod_contentdesigner/elements'], function(Elements) { + require(['mod_contentdesigner/elements'], function (Elements) { var chapterId = params.itemid; if (chapterId) { Elements.removeWarning(); @@ -233,7 +339,7 @@ define(['jquery', 'core/modal_factory', 'core/str', 'core/fragment', 'core/modal } modal.hide(); - $.when(notesuccess).done(function(localizedEditString) { + $.when(notesuccess).done(function (localizedEditString) { notification.addNotification({ message: localizedEditString, type: "success" @@ -241,7 +347,7 @@ define(['jquery', 'core/modal_factory', 'core/str', 'core/fragment', 'core/modal }); if (ltools.disappertimenotify != 0) { - setTimeout(function() { + setTimeout(function () { document.querySelector("span.notifications").innerHTML = ""; }, ltools.disappertimenotify); } @@ -262,9 +368,63 @@ define(['jquery', 'core/modal_factory', 'core/str', 'core/fragment', 'core/modal } return Fragment.loadFragment('ltool_note', 'get_note_form', contextid, params); } + + /** + * Handle print action + * @param {object} args Configuration arguments + */ + function notePrintHandler(args) { + // Prevent multiple print windows + if (printWindow && !printWindow.closed) { + printWindow.focus() + return true + } + + // Create URL for print page + var printUrl = Config.wwwroot + "/local/learningtools/ltool/note/print.php" + var params = new URLSearchParams() + + params.append("contextid", args.contextid) + params.append("courseid", args.course || 0) + params.append("sesskey", args.sesskey) + + // Add current filter parameters if they exist + var currentUrl = new URL(window.location.href) + var search = currentUrl.searchParams.get("search") || "" + var filter = currentUrl.searchParams.get("filter") || "" + var sectionid = currentUrl.searchParams.get("sectionid") || 0 + var activity = currentUrl.searchParams.get("activity") || 0 + + if (search) params.append("search", search) + if (filter) params.append("filter", filter) + if (sectionid) params.append("sectionid", sectionid) + if (activity) params.append("activity", activity) + + var fullUrl = printUrl + "?" + params.toString() + + // Open print page in new window and store reference + printWindow = window.open( + fullUrl, + "printNotes", + "width=1000,height=700,scrollbars=yes,resizable=yes,toolbar=no,location=no,status=no", + ) + + // Focus the print window + if (printWindow) { + printWindow.focus() + } + + return true + } + + function getnotescontents(contextid, params) { + return Fragment.loadFragment('ltool_note', 'get_notes_contents', contextid, params); + } + return { - init: function(contextid, params) { - learningToolNoteAction(contextid, params); - } + + init: (contextid) => { + learningToolNoteAction(contextid); + }, }; -}); \ No newline at end of file +}); diff --git a/ltool/note/amd/src/print.js b/ltool/note/amd/src/print.js new file mode 100644 index 0000000..2b05af4 --- /dev/null +++ b/ltool/note/amd/src/print.js @@ -0,0 +1,72 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * Print functionality for notes. + * + * @module ltool_note/print + * @copyright 2025 bdecent gmbh + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +define(['jquery'], ($) => { + /** + * Initialize print functionality + */ + function init() { + // Print button functionality + const printBtn = document.getElementById("print-notes-btn") + if (printBtn) { + printBtn.addEventListener("click", (e) => { + e.preventDefault() + window.print() + }) + } + + // Return button functionality + const returnBtn = document.getElementById("return-notes-btn") + if (returnBtn) { + returnBtn.addEventListener("click", (e) => { + e.preventDefault() + window.close() + }) + } + + // Keyboard shortcuts + document.addEventListener("keydown", (e) => { + // Ctrl+P for print + if (e.ctrlKey && e.key === "p") { + e.preventDefault() + window.print() + } + // Escape to close + if (e.key === "Escape") { + e.preventDefault() + window.close() + } + }) + + // Auto-expand all accordions for print + const collapseElements = document.querySelectorAll(".collapse") + collapseElements.forEach((element) => { + element.classList.add("show") + }) + + } + + return { + init: init, + } +}) diff --git a/ltool/note/classes/external.php b/ltool/note/classes/external.php index 55ec7e6..8fc3aa0 100644 --- a/ltool/note/classes/external.php +++ b/ltool/note/classes/external.php @@ -39,10 +39,10 @@ class external extends \external_api { public static function save_usernote_parameters() { return new \external_function_parameters( - array( + [ 'contextid' => new \external_value(PARAM_INT, 'The context id for the course'), - 'formdata' => new \external_value(PARAM_RAW, 'The data from the user notes') - ) + 'formdata' => new \external_value(PARAM_RAW, 'The data from the user notes'), + ] ); } @@ -57,7 +57,7 @@ public static function save_usernote($contextid, $formdata) { require_once($CFG->dirroot.'/local/learningtools/ltool/note/lib.php'); require_login(); $validparams = self::validate_parameters(self::save_usernote_parameters(), - array('contextid' => $contextid, 'formdata' => $formdata)); + ['contextid' => $contextid, 'formdata' => $formdata]); $context = \context_system::instance(); require_capability("ltool/note:createnote", $context); // Parse serialize form data. diff --git a/ltool/note/classes/ltool_note_filter.php b/ltool/note/classes/ltool_note_filter.php index 6c3db1a..da6ea4b 100644 --- a/ltool/note/classes/ltool_note_filter.php +++ b/ltool/note/classes/ltool_note_filter.php @@ -55,13 +55,11 @@ class ltool_note_filter { */ public $sort; - /** * @var int */ public $activity; - /** * @var int */ @@ -72,7 +70,6 @@ class ltool_note_filter { */ public $courseid; - /** * @var int */ @@ -93,7 +90,6 @@ class ltool_note_filter { */ public $totalnotes; - /** * Loads the notes info data. * @param int $userid current user id @@ -252,7 +248,7 @@ public function get_sort_instance() { $coursesortparams = array_merge($this->urlparams, $coursesortparams); $datesortparams = ['sort' => 'date']; $datesortparams = array_merge($this->urlparams, $datesortparams); - $activitysortparams = array('sort' => 'activity'); + $activitysortparams = ['sort' => 'activity']; $activitysortparams = array_merge($this->urlparams, $activitysortparams); $dateselect = ''; $courseselect = ''; @@ -462,7 +458,7 @@ public function get_main_body() { } else if ($sorttype == 'desc') { $queryfunction = 'querycoursesortdesc'; } - usort($data, array($this, $queryfunction)); + usort($data, [$this, $queryfunction]); } } @@ -480,7 +476,7 @@ public function get_main_body() { $template['enableactivityfilter'] = !empty($this->selectcourse) ? true : false; if ($this->selectcourse) { - $coursefilterparams = array('selectcourse' => $this->selectcourse); + $coursefilterparams = ['selectcourse' => $this->selectcourse]; $coursefilterparams = array_merge($coursefilterparams, $this->urlparams); unset($coursefilterparams['activity']); $coursefilterurl = new moodle_url('/local/learningtools/ltool/note/list.php', $coursefilterparams); @@ -586,7 +582,7 @@ public function edit_note_info($row) { $stredit = get_string('edit'); $buttons = []; $returnurl = new moodle_url('/local/learningtools/ltool/note/editlist.php'); - $optionyes = array('edit' => $row->id, 'sesskey' => sesskey()); + $optionyes = ['edit' => $row->id, 'sesskey' => sesskey()]; $optionyes = array_merge($optionyes, $this->urlparams); $url = new moodle_url($returnurl, $optionyes); $buttons[] = html_writer::link($url, $OUTPUT->pix_icon('t/edit', $stredit)); @@ -606,7 +602,7 @@ public function delete_note_info($row) { $strdelete = get_string('delete'); $buttons = []; $returnurl = new moodle_url('/local/learningtools/ltool/note/list.php'); - $optionyes = array('delete' => $row->id, 'sesskey' => sesskey()); + $optionyes = ['delete' => $row->id, 'sesskey' => sesskey()]; $optionyes = array_merge($optionyes, $this->urlparams); $url = new moodle_url($returnurl, $optionyes); $buttons[] = html_writer::link($url, $OUTPUT->pix_icon('t/delete', $strdelete)); @@ -670,4 +666,3 @@ public function get_title_note($data, $record) { return $title; } } - diff --git a/ltool/note/classes/output/notes_list.php b/ltool/note/classes/output/notes_list.php new file mode 100644 index 0000000..167fee1 --- /dev/null +++ b/ltool/note/classes/output/notes_list.php @@ -0,0 +1,330 @@ +. + +/** + * Notes listing page. + * + * @package ltool_note + * @copyright bdecent GmbH 2021 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace ltool_note\output; + +use renderable; +use templatable; +use renderer_base; +use stdclass; + +/** + * Class to display notes list with search functionality. + * + * @package ltool_note + * @copyright bdecent GmbH 2021 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class notes_list implements renderable, templatable { + /** @var int $courseid The course id */ + private $courseid; + /** @var string $search The search term */ + private $search; + + /** + * Section ID to filter notes by a specific section. + * @var int|null + */ + protected $sectionid; + + /** + * Activity ID to filter notes by a specific activity. + * @var int|null + */ + protected $activity; + + /** + * Filter. + * @var string + */ + protected $filter; + + /** + * print. + * @var bool + */ + protected $print; + + /** + * Constructor. + * + * @param int $courseid The course ID + * @param int $sectionid The section ID + * @param int $activity The activity ID + * @param string $search The search term + * @param string $filter Filter + * @param bool $print + */ + public function __construct($courseid, $sectionid, $activity, $search = '', $filter = '', $print = false) { + $this->courseid = $courseid; + $this->sectionid = $sectionid; + $this->activity = $activity; + $this->search = $search; + $this->filter = $filter; + $this->print = $print; + } + + /** + * Export data for template. + * + * @param renderer_base $output The renderer + * @return array Data for template + */ + public function export_for_template(renderer_base $output) { + global $DB, $USER; + + $params = ['courseid' => $this->courseid, 'userid' => $USER->id]; + $searchconditions = []; + $searchjoins = ''; + + // Build advanced search conditions. + if (!empty($this->search)) { + $searchterm = $this->search; + + // Search in note content and title. + $searchconditions[] = $DB->sql_like('n.note', ':note', false, false); + $searchconditions[] = $DB->sql_like('n.pagetitle', ':pagetitle', false, false); + $params['note'] = '%' . $DB->sql_like_escape($searchterm) . '%'; + $params['pagetitle'] = '%' . $DB->sql_like_escape($searchterm) . '%'; + + // Search by activity type and name. + $searchjoins .= " LEFT JOIN {course_modules} cm ON cm.id = n.coursemodule "; + $searchjoins .= " LEFT JOIN {modules} m ON m.id = cm.module "; + $searchjoins .= " LEFT JOIN {course_sections} cs ON cs.id = cm.section "; + + // Search by module name. + $searchconditions[] = $DB->sql_like('m.name', ':modname', false, false); + $params['modname'] = '%' . $DB->sql_like_escape($searchterm) . '%'; + + // Search by section name. + $searchconditions[] = $DB->sql_like('cs.name', ':sectionname', false, false); + $params['sectionname'] = '%' . $DB->sql_like_escape($searchterm) . '%'; + + // Search by date (month name, year, or month/year format). + $months = [ + 'january' => 1, 'february' => 2, 'march' => 3, 'april' => 4, 'may' => 5, 'june' => 6, + 'july' => 7, 'august' => 8, 'september' => 9, 'october' => 10, 'november' => 11, 'december' => 12, + 'jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4, 'jun' => 6, 'jul' => 7, 'aug' => 8, 'sep' => 9, + 'oct' => 10, 'nov' => 11, 'dec' => 12, + ]; + + $searchlower = strtolower($searchterm); + + // Check if search is a month name. + foreach ($months as $monthname => $monthnumber) { + if (strpos($searchlower, $monthname) !== false) { + $startofmonth = strtotime("1 $monthname"); + $endofmonth = strtotime("+1 month", $startofmonth) - 1; + + // If year is also specified (e.g., "January 2023"). + if (preg_match('/\b(19|20)\d{2}\b/', $searchterm, $matches)) { + $year = $matches[0]; + $startofmonth = strtotime("1 $monthname $year"); + $endofmonth = strtotime("+1 month", $startofmonth) - 1; + } + + $searchconditions[] = "(n.timecreated BETWEEN :startdate AND :enddate)"; + $params['startdate'] = $startofmonth; + $params['enddate'] = $endofmonth; + break; + } + } + + // Check if search is a year (4 digits). + if (preg_match('/^(19|20)\d{2}$/', $searchterm)) { + $year = $searchterm; + $startofyear = strtotime("January 1, $year"); + $endofyear = strtotime("December 31, $year 23:59:59"); + + $searchconditions[] = "(n.timecreated BETWEEN :startyear AND :endyear)"; + $params['startyear'] = $startofyear; + $params['endyear'] = $endofyear; + } + + // Check if search is in MM/YYYY format. + if (preg_match('/^(0?[1-9]|1[0-2])\/((19|20)\d{2})$/', $searchterm, $matches)) { + $month = $matches[1]; + $year = $matches[2]; + + $startofmonth = strtotime("$year-$month-01"); + $endofmonth = strtotime("+1 month", $startofmonth) - 1; + + $searchconditions[] = "(n.timecreated BETWEEN :startmonthyear AND :endmonthyear)"; + $params['startmonthyear'] = $startofmonth; + $params['endmonthyear'] = $endofmonth; + } + } + + if (!empty($this->filter)) { + // Filter by section. + if ($this->filter === 'section' && $this->sectionid) { + $searchconditions[] = 'n.pagetype = :pagetype AND n.pageurl LIKE :pageurl'; + $params['pagetype'] = 'course-view-section-' . get_course($this->courseid)->format; + $params['pageurl'] = '%id=' . $this->sectionid . '%'; + } else if ($this->filter === 'activity' && $this->activity) { + $searchconditions[] = 'n.coursemodule = :cmid'; + $params['cmid'] = $this->activity; + } + } + + // Build the SQL query. + $sql = "SELECT n.*, cm.id as cmid, m.name as modulename + FROM {ltool_note_data} n + LEFT JOIN {course_modules} cm ON cm.id = n.coursemodule + LEFT JOIN {modules} m ON m.id = cm.module"; + + // Only add the section join if we're searching. + if (!empty($this->search)) { + $sql .= " LEFT JOIN {course_sections} cs ON cs.id = cm.section"; + } + + $sql .= " WHERE n.course = :courseid + AND n.userid = :userid"; + + if (!empty($searchconditions)) { + $sql .= " AND (" . implode(" OR ", $searchconditions) . ")"; + } + + if ($this->print) { + // Only show notes that are not hidden. + $sql .= " AND n.printstatus = 0"; + } + + $sql .= " ORDER BY n.timecreated DESC"; + $notes = $DB->get_records_sql($sql, $params); + + $course = get_course($this->courseid); + + // Process notes for template. + $notedata = []; + foreach ($notes as $note) { + $editstr = ($note->timemodified != null) ? + ' (' . get_string('edited', 'local_learningtools') . ' ' . $this->get_relative_time($note->timemodified) . ')' : ''; + $list = [ + 'id' => $note->id, + 'content' => $note->note, + 'timecreated' => userdate($note->timecreated), + 'editurl' => new \moodle_url('/local/learningtools/ltool/note/editlist.php', ['edit' => $note->id, + 'sesskey' => sesskey(), 'view' => $this->courseid]), + 'deleteurl' => new \moodle_url('/local/learningtools/ltool/note/deletelist.php', ['delete' => $note->id, + 'sesskey' => sesskey(), 'view' => $this->courseid]), + 'time' => $this->get_relative_time($note->timecreated) . $editstr, + 'hideurl' => new \moodle_url('/local/learningtools/ltool/note/view.php', ['id' => $this->courseid, + 'action' => 'hide', 'noteid' => $note->id]), + 'showurl' => new \moodle_url('/local/learningtools/ltool/note/view.php', ['id' => $this->courseid, + 'action' => 'show', 'noteid' => $note->id]), + 'printstatus' => $note->printstatus ? true : false, + ]; + + if (!empty($note->cmid)) { + $module = new stdclass; + $module->coursemodule = $note->cmid; + $module->courseid = $note->course; + $list['name'] = local_learningtools_get_module_name($module); + $cmid = $note->cmid; + $url = new \moodle_url('/mod/' . $note->modulename . '/view.php', ['id' => $cmid]); + $list['contexturl'] = $url->out(false); + $list['contextname'] = get_string('module:', 'local_learningtools') . get_string('modulename', $note->modulename); + } else { + $courseformat = $course->format; + if ($note->pagetype == 'course-view-section-' . $courseformat) { + $sectionurl = new \moodle_url($note->pageurl); + $sectionid = $sectionurl->get_param('id'); + $section = $DB->get_record('course_sections', ['course' => $this->courseid, 'id' => $sectionid]); + $sectionname = $section->name; + if (!$sectionname) { + $sectionname = ($section->section == 0) ? get_string('general') : + get_string('section', 'local_learningtools') . ' ' . $section->section; + } else { + $sectionname = $section->name; + } + $list['contexturl'] = $note->pageurl; + $list['contextname'] = get_string('section:', 'local_learningtools') . $sectionname; + $list['name'] = $sectionname; + } else { + $list['contexturl'] = new \moodle_url('/course/view.php', ['id' => $this->courseid]); + $list['contextname'] = get_string('course:', 'local_learningtools') . format_string($course->fullname); + } + } + $notedata[] = $list; + } + + return [ + 'notes' => $notedata, + 'courseurl' => new \moodle_url('/course/view.php', ['id' => $this->courseid]), + 'hasnotes' => !empty($notedata), + 'search' => $this->search, + 'hassearch' => !empty($this->search), + 'courseid' => $this->courseid, + 'hasprint' => $this->print, + ]; + } + + /** + * Returns a human-readable relative time string (e.g., "2 minutes ago") + * + * @param int $timestamp The timestamp to format + * @return string Formatted relative time + */ + private function get_relative_time($timestamp) { + $diff = time() - $timestamp; + + if ($diff < 60) { + // Seconds. + $count = $diff; + $stringid = ($count == 1) ? 'secondago' : 'secondsago'; + return get_string($stringid, 'local_learningtools', $count); + } else if ($diff < 3600) { + // Minutes. + $count = floor($diff / 60); + $stringid = ($count == 1) ? 'minuteago' : 'minutesago'; + return get_string($stringid, 'local_learningtools', $count); + } else if ($diff < 86400) { + // Hours. + $count = floor($diff / 3600); + $stringid = ($count == 1) ? 'hourago' : 'hoursago'; + return get_string($stringid, 'local_learningtools', $count); + } else if ($diff < 604800) { + // Days. + $count = floor($diff / 86400); + $stringid = ($count == 1) ? 'dayago' : 'daysago'; + return get_string($stringid, 'local_learningtools', $count); + } else if ($diff < 2592000) { + // Weeks. + $count = floor($diff / 604800); + $stringid = ($count == 1) ? 'weekago' : 'weeksago'; + return get_string($stringid, 'local_learningtools', $count); + } else if ($diff < 31536000) { + // Months. + $count = floor($diff / 2592000); + $stringid = ($count == 1) ? 'monthago' : 'monthsago'; + return get_string($stringid, 'local_learningtools', $count); + } else { + // Years. + $count = floor($diff / 31536000); + $stringid = ($count == 1) ? 'yearago' : 'yearsago'; + return get_string($stringid, 'local_learningtools', $count); + } + } +} diff --git a/ltool/note/classes/privacy/provider.php b/ltool/note/classes/privacy/provider.php index b177753..59020e0 100644 --- a/ltool/note/classes/privacy/provider.php +++ b/ltool/note/classes/privacy/provider.php @@ -27,10 +27,10 @@ use context; use core_privacy\local\metadata\collection; -use \core_privacy\local\request\contextlist; -use \core_privacy\local\request\userlist; -use \core_privacy\local\request\approved_userlist; -use \core_privacy\local\request\approved_contextlist; +use core_privacy\local\request\contextlist; +use core_privacy\local\request\userlist; +use core_privacy\local\request\approved_userlist; +use core_privacy\local\request\approved_contextlist; use core_privacy\local\request\helper; use core_privacy\local\request\transform; use core_privacy\local\request\writer; @@ -63,7 +63,7 @@ public static function get_metadata(collection $collection): collection { 'itemtype' => 'privacy:metadata:note:itemtype', 'itemid' => 'privacy:metadata:note:itemid', 'timecreated' => 'privacy:metadata:note:timecreated', - 'timemodified' => 'privacy:metadata:note:timemodified' + 'timemodified' => 'privacy:metadata:note:timemodified', ]; $collection->add_database_table('ltool_note_data', $notemetadata, 'privacy:metadata:notemetadata'); @@ -91,7 +91,7 @@ public static function user_has_note_data($userid): bool { * @param int $userid The user to search. * @return contextlist $contextlist The list of contexts used in this plugin. */ - public static function get_contexts_for_userid(int $userid) : contextlist { + public static function get_contexts_for_userid(int $userid): contextlist { $contextlist = new \core_privacy\local\request\contextlist(); // Check user has stored any notes. if (self::user_has_note_data($userid)) { diff --git a/ltool/note/db/access.php b/ltool/note/db/access.php index c9caaea..79cba6a 100644 --- a/ltool/note/db/access.php +++ b/ltool/note/db/access.php @@ -23,45 +23,45 @@ */ defined('MOODLE_INTERNAL') || die(); -$capabilities = array( - 'ltool/note:createnote' => array( +$capabilities = [ + 'ltool/note:createnote' => [ 'riskbitmask' => RISK_SPAM, 'captype' => 'read', 'contextlevel' => CONTEXT_SYSTEM, - 'archetypes' => array( - 'user' => CAP_ALLOW - ) - ), - 'ltool/note:viewownnote' => array( + 'archetypes' => [ + 'user' => CAP_ALLOW, + ], + ], + 'ltool/note:viewownnote' => [ 'riskbitmask' => RISK_SPAM, 'captype' => 'read', 'contextlevel' => CONTEXT_SYSTEM, - 'archetypes' => array( - 'user' => CAP_ALLOW - ) - ), - 'ltool/note:manageownnote' => array( + 'archetypes' => [ + 'user' => CAP_ALLOW, + ], + ], + 'ltool/note:manageownnote' => [ 'riskbitmask' => RISK_SPAM, 'captype' => 'read', 'contextlevel' => CONTEXT_SYSTEM, - 'archetypes' => array( - 'user' => CAP_ALLOW - ) - ), - 'ltool/note:viewnote' => array( + 'archetypes' => [ + 'user' => CAP_ALLOW, + ], + ], + 'ltool/note:viewnote' => [ 'riskbitmask' => RISK_SPAM, 'captype' => 'read', 'contextlevel' => CONTEXT_COURSE, - 'archetypes' => array( + 'archetypes' => [ 'manager' => CAP_ALLOW, - ) - ), + ], + ], - 'ltool/note:managenote' => array( + 'ltool/note:managenote' => [ 'riskbitmask' => RISK_SPAM, 'captype' => 'read', 'contextlevel' => CONTEXT_COURSE, - ), + ], // Add more capabilities here ... -); +]; diff --git a/ltool/note/db/events.php b/ltool/note/db/events.php index 041d468..1965568 100644 --- a/ltool/note/db/events.php +++ b/ltool/note/db/events.php @@ -24,13 +24,13 @@ */ defined('MOODLE_INTERNAL') || die(); -$observers = array( - array( +$observers = [ + [ 'eventname' => 'core\event\course_deleted', 'callback' => '\ltool_note\event_observer::note_coursedata_deleteaction', - ), - array( + ], + [ 'eventname' => 'core\event\course_module_deleted', 'callback' => '\ltool_note\event_observer::note_moduledata_deleteaction', - ) -); + ], +]; diff --git a/ltool/note/db/install.xml b/ltool/note/db/install.xml index bb374f9..ba7e308 100644 --- a/ltool/note/db/install.xml +++ b/ltool/note/db/install.xml @@ -17,6 +17,7 @@ + diff --git a/ltool/note/db/services.php b/ltool/note/db/services.php index a20b6e6..fa891cf 100644 --- a/ltool/note/db/services.php +++ b/ltool/note/db/services.php @@ -23,8 +23,8 @@ */ defined('MOODLE_INTERNAL') || die(); -$functions = array( - 'ltool_note_save_usernote' => array( +$functions = [ + 'ltool_note_save_usernote' => [ 'classname' => 'ltool_note\external', 'methodname' => 'save_usernote', 'description' => 'Save the user note', @@ -32,5 +32,5 @@ 'capabilities' => 'ltool/note:createnote', 'ajax' => true, 'loginrequired' => true, - ), -); + ], +]; diff --git a/ltool/note/db/upgrade.php b/ltool/note/db/upgrade.php index 0ea5344..ccb6950 100644 --- a/ltool/note/db/upgrade.php +++ b/ltool/note/db/upgrade.php @@ -79,6 +79,23 @@ function xmldb_ltool_note_upgrade($oldversion) { upgrade_plugin_savepoint(true, 2025041701, 'ltool', 'note'); } + if ($oldversion < 2025061800) { + // Modify the note table to support itemtype and itemid. + $table = new xmldb_table('ltool_note_data'); + + // Add print field if it doesn't exist. + $field = new xmldb_field('printstatus', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'itemid'); + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + // Update existing records to use the new fields. + $DB->execute("UPDATE {ltool_note_data} SET printstatus = 0"); + + // Savepoint reached. + upgrade_plugin_savepoint(true, 2025061800, 'ltool', 'note'); + + } + return true; } - diff --git a/ltool/note/deletelist.php b/ltool/note/deletelist.php index 8b6e4a4..453c05a 100644 --- a/ltool/note/deletelist.php +++ b/ltool/note/deletelist.php @@ -21,6 +21,7 @@ * @copyright bdecent GmbH 2021 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ + require_once(dirname(__FILE__).'/../../../../config.php'); require_login(); require_once(dirname(__FILE__).'/lib.php'); @@ -36,6 +37,7 @@ $delete = optional_param('delete', 0, PARAM_INT); $returnurl = optional_param('returnurl', '', PARAM_URL); $confirm = optional_param('confirm', '', PARAM_ALPHANUM); +$view = optional_param('view', 0, PARAM_INT); // Require access the page. ltool_note_require_deletenote_cap($delete); // If user is logged in, then use profile navigation in breadcrumbs. @@ -46,13 +48,18 @@ $pageurl = new moodle_url('/local/learningtools/ltool/note/deletelist.php'); +if ($view) { + $baseurl = new moodle_url('/local/learningtools/ltool/note/view.php', ['id' => $view]); + $returnurl = $baseurl; +} + if ($delete && confirm_sesskey()) { if ($confirm != md5($delete)) { echo $OUTPUT->header(); echo $OUTPUT->heading(get_string('deletemessage', 'local_learningtools')); - $deleteoptions = array('delete' => $delete, 'confirm' => md5($delete), 'sesskey' => sesskey()); + $deleteoptions = ['delete' => $delete, 'confirm' => md5($delete), 'sesskey' => sesskey()]; $deleteoptions = array_merge($deleteoptions, ['returnurl' => $returnurl]); $deletenoteurl = new moodle_url($pageurl, $deleteoptions); $deletenotebutton = new single_button($deletenoteurl, get_string('delete'), 'post'); @@ -62,8 +69,7 @@ die; } else if (data_submitted()) { - - $deleterecord = $DB->get_record('ltool_note_data', array('id' => $delete)); + $deleterecord = $DB->get_record('ltool_note_data', ['id' => $delete]); $deleteeventcontext = context::instance_by_id($deleterecord->contextid, MUST_EXIST); if ($DB->delete_records('ltool_note_data', ['id' => $delete])) { $eventcourseid = local_learningtools_get_eventlevel_courseid($deleteeventcontext, $deleterecord->course); @@ -73,7 +79,7 @@ 'context' => $deleteeventcontext, 'other' => [ 'pagetype' => $deleterecord->pagetype, - ] + ], ]; // Add event to user delete the bookmark. diff --git a/ltool/note/editlist.php b/ltool/note/editlist.php index 7989be9..e7654a3 100644 --- a/ltool/note/editlist.php +++ b/ltool/note/editlist.php @@ -21,6 +21,7 @@ * @copyright bdecent GmbH 2021 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ + require_once(dirname(__FILE__).'/../../../../config.php'); require_login(); require_once(dirname(__FILE__).'/lib.php'); @@ -37,9 +38,10 @@ $childid = optional_param('userid', 0, PARAM_INT); $teacher = optional_param('teacher', 0, PARAM_INT); $returnurl = optional_param('returnurl', '', PARAM_URL); +$view = optional_param('view', 0, PARAM_INT); if ($edit) { - $editedrecord = $DB->get_record('ltool_note_data', array('id' => $edit)); + $editedrecord = $DB->get_record('ltool_note_data', ['id' => $edit]); if (empty($editedrecord)) { redirect(new moodle_url('/')); } @@ -68,11 +70,15 @@ } } - $baseurl = new moodle_url('/local/learningtools/ltool/note/list.php', $urlparams); $baseurl = !empty($returnurl) ? $returnurl : $baseurl; $pageurl = new moodle_url('/local/learningtools/ltool/note/editlist.php', $urlparams); +if ($view) { + $baseurl = new moodle_url('/local/learningtools/ltool/note/view.php', ['id' => $view]); + $returnurl = $baseurl; +} + // If user is logged in, then use profile navigation in breadcrumbs. if ($profilenode = $PAGE->settingsnav->find('myprofile', null)) { $profilenode->make_active(); @@ -89,30 +95,32 @@ redirect($baseurl); } else if ($fromdata = $editorform->get_data()) { $usernote = $fromdata->noteeditor['text']; - $exitnote = $DB->get_record('ltool_note_data', array('id' => $edit)); + $exitnote = $DB->get_record('ltool_note_data', ['id' => $edit]); if ($exitnote) { if ($usernote != $exitnote->note) { - $DB->set_field('ltool_note_data', 'note', $usernote, array('id' => $edit)); - $DB->set_field('ltool_note_data', 'timemodified', time(), array('id' => $edit)); - $editeventcontext = context::instance_by_id($exitnote->contextid, MUST_EXIST); - $eventcourseid = local_learningtools_get_eventlevel_courseid($editeventcontext, $exitnote->course); - // Add event to user edit the note. - $editeventparams = [ - 'objectid' => $exitnote->id, - 'courseid' => $eventcourseid, - 'context' => $editeventcontext, - 'other' => [ - 'pagetype' => $exitnote->pagetype, - ] - ]; + $DB->set_field('ltool_note_data', 'note', $usernote, ['id' => $edit]); + if ($DB->record_exists('ltool_note_data', ['id' => $edit])) { + $DB->set_field('ltool_note_data', 'timemodified', time(), ['id' => $edit]); + } + $editeventcontext = context::instance_by_id($exitnote->contextid, MUST_EXIST); + $eventcourseid = local_learningtools_get_eventlevel_courseid($editeventcontext, $exitnote->course); + // Add event to user edit the note. + $editeventparams = [ + 'objectid' => $exitnote->id, + 'courseid' => $eventcourseid, + 'context' => $editeventcontext, + 'other' => [ + 'pagetype' => $exitnote->pagetype, + ], + ]; - if ($childid) { - $editeventparams = array_merge($editeventparams, ['relateduserid' => $childid]); - } - $event = \ltool_note\event\ltnote_edited::create($editeventparams); - $event->trigger(); - redirect($baseurl, get_string('successeditnote', 'local_learningtools'), - null, \core\output\notification::NOTIFY_SUCCESS); + if ($childid) { + $editeventparams = array_merge($editeventparams, ['relateduserid' => $childid]); + } + $event = \ltool_note\event\ltnote_edited::create($editeventparams); + $event->trigger(); + redirect($baseurl, get_string('successeditnote', 'local_learningtools'), + null, \core\output\notification::NOTIFY_SUCCESS); } } redirect($baseurl); @@ -124,4 +132,3 @@ } } - diff --git a/ltool/note/lang/en/ltool_note.php b/ltool/note/lang/en/ltool_note.php index 1f99dbb..0865c1b 100644 --- a/ltool/note/lang/en/ltool_note.php +++ b/ltool/note/lang/en/ltool_note.php @@ -24,27 +24,29 @@ defined("MOODLE_INTERNAL") || die(); -$string['pluginname'] = "Learning Tools Note"; +$string['nonotes'] = "No notes found"; $string['note:createnote'] = "Create the note tool."; -$string['note:viewownnote'] = "View the own note tool."; +$string['note:managenote'] = "Manage the others notes."; $string['note:manageownnote'] = "Manage the own note tool."; $string['note:viewnote'] = "View the others notes."; -$string['note:managenote'] = "Manage the others notes."; +$string['note:viewownnote'] = "View the own note tool."; $string['notes'] = "Notes"; - -// Privacy Metadata. -$string['privacynote'] = 'Learning Tools - Notes'; -$string['privacy:metadata:note:userid'] = 'The ID of the user'; +$string['pluginname'] = "Learning Tools Note"; +$string['print'] = 'Print'; +$string['printnotes'] = 'My Notes'; +$string['privacy:metadata'] = 'The Learning Tools Note plugin stores user notes.'; +$string['privacy:metadata:note:contextid'] = 'The Context ID of the note craeted page'; +$string['privacy:metadata:note:contextlevel'] = 'The Context level of the note created page'; $string['privacy:metadata:note:course'] = 'The ID of the course'; $string['privacy:metadata:note:coursemodule'] = 'The ID of the course module if note created on course modules page'; -$string['privacy:metadata:note:contextlevel'] = 'The Context level of the note created page'; -$string['privacy:metadata:note:contextid'] = 'The Context ID of the note craeted page'; -$string['privacy:metadata:note:pagetype'] = 'Note created pagetype'; +$string['privacy:metadata:note:note'] = 'User entered note content.'; $string['privacy:metadata:note:pagetitle'] = 'Page title of the note created page'; +$string['privacy:metadata:note:pagetype'] = 'Note created pagetype'; $string['privacy:metadata:note:pageurl'] = 'Note created page url'; -$string['privacy:metadata:bookmarks:itemtype'] = 'Note item type'; -$string['privacy:metadata:bookmarks:itemid'] = 'Note item id'; -$string['privacy:metadata:note:note'] = 'User entered note content.'; $string['privacy:metadata:note:timecreated'] = 'Time of the note created'; $string['privacy:metadata:note:timemodified'] = 'Time of the note modified'; +$string['privacy:metadata:note:userid'] = 'The ID of the user'; $string['privacy:metadata:notemetadata'] = 'List of data stored in note subplugin'; +$string['privacynote'] = 'Learning Tools - Notes'; +$string['returntonotes'] = 'Return to Notes'; +$string['toolname'] = "Notes"; diff --git a/ltool/note/lib.php b/ltool/note/lib.php index f23d039..85bf2d2 100644 --- a/ltool/note/lib.php +++ b/ltool/note/lib.php @@ -21,6 +21,7 @@ * @copyright bdecent GmbH 2021 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ + use core_user\output\myprofile\tree; defined('MOODLE_INTERNAL') || die(); @@ -47,7 +48,7 @@ public function definition() { $popoutaction = isset($this->_customdata['popoutaction']) ? $this->_customdata['popoutaction'] : ''; - $mform->addElement('editor', 'ltnoteeditor', '', array('autosave' => false)); + $mform->addElement('editor', 'ltnoteeditor', '', ['autosave' => false]); $mform->addElement('hidden', 'course'); $mform->setType('course', PARAM_INT); $mform->setDefault('course', $course); @@ -101,9 +102,9 @@ public function definition() { $courseid = $this->_customdata['courseid']; $returnurl = $this->_customdata['returnurl']; - $note = $DB->get_record('ltool_note_data', array('id' => $noteid)); + $note = $DB->get_record('ltool_note_data', ['id' => $noteid]); $usernote = !empty($note->note) ? $note->note : ''; - $mform->addElement('editor', 'noteeditor', '')->setValue( array('text' => $usernote)); + $mform->addElement('editor', 'noteeditor', '')->setValue( ['text' => $usernote]); $mform->addElement('hidden', 'edit'); $mform->setType('edit', PARAM_INT); $mform->setDefault('edit', $noteid); @@ -124,7 +125,6 @@ public function definition() { $this->add_action_buttons(); } } - /** * Defines the ltool notes nodes for my profile navigation tree. * @@ -144,7 +144,7 @@ function ltool_note_myprofile_navigation(tree $tree, $user, $iscurrentuser, $cou if (!empty($course)) { $coursecontext = context_course::instance($course->id); $noteurl = new moodle_url('/local/learningtools/ltool/note/list.php', - array('courseid' => $course->id, 'userid' => $userid)); + ['courseid' => $course->id, 'userid' => $userid]); $notenode = new core_user\output\myprofile\node('learningtools', 'note', get_string('coursenotes', 'local_learningtools'), null, $noteurl); $tree->add_node($notenode); @@ -173,7 +173,7 @@ function ltool_note_myprofile_navigation(tree $tree, $user, $iscurrentuser, $cou $coursecontext = context_course::instance($course->id); if (has_capability('ltool/note:viewnote', $coursecontext)) { $noteurl = new moodle_url('/local/learningtools/ltool/note/list.php', - array('courseid' => $course->id, 'userid' => $userid, 'teacher' => 1)); + ['courseid' => $course->id, 'userid' => $userid, 'teacher' => 1]); $notenode = new core_user\output\myprofile\node('learningtools', 'note', get_string('coursenotes', 'local_learningtools'), null, $noteurl); $tree->add_node($notenode); @@ -203,72 +203,72 @@ function ltool_note_output_fragment_get_note_form($args) { // Generate a unique ID for the editor to prevent content caching. $editorid = "usernotes_" . time(); - $editor->use_editor($editorid, array('autosave' => false)); + $editor->use_editor($editorid, ['autosave' => false]); $editor->set_text(''); - $editorhtml .= html_writer::start_tag('div', array('class' => 'ltoolusernotes')); - $editorhtml .= html_writer::start_tag('form', array('method' => 'post', 'action' => $args['pageurl'], 'class' => 'mform')); + $editorhtml .= \html_writer::start_tag('div', ['class' => 'ltoolusernotes']); + $editorhtml .= \html_writer::start_tag('form', ['method' => 'post', 'action' => $args['pageurl'], 'class' => 'mform']); - $editorhtml .= html_writer::tag('textarea', '', - array('id' => $editorid, 'name' => 'ltnoteeditor', 'class' => 'form-group', 'rows' => 20, 'cols' => 100)); + $editorhtml .= \html_writer::tag('textarea', '', + ['id' => $editorid, 'name' => 'ltnoteeditor', 'class' => 'form-group', 'rows' => 20, 'cols' => 100]); - $editorhtml .= html_writer::tag('input', '', array( + $editorhtml .= \html_writer::tag('input', '', [ 'type' => 'hidden', 'name' => 'course', 'value' => $args['course'], - )); + ]); - $editorhtml .= html_writer::tag('input', '', array( + $editorhtml .= \html_writer::tag('input', '', [ 'type' => 'hidden', 'name' => 'itemtype', 'value' => isset($args['itemtype']) ? $args['itemtype'] : '', - )); + ]); - $editorhtml .= html_writer::tag('input', '', array( + $editorhtml .= \html_writer::tag('input', '', [ 'type' => 'hidden', 'name' => 'itemid', 'value' => isset($args['itemid']) ? $args['itemid'] : 0, - )); + ]); - $editorhtml .= html_writer::tag('input', '', array( + $editorhtml .= \html_writer::tag('input', '', [ 'type' => 'hidden', 'name' => 'contextid', 'value' => $args['contextid'], - )); + ]); - $editorhtml .= html_writer::tag('input', '', array( + $editorhtml .= \html_writer::tag('input', '', [ 'type' => 'hidden', 'name' => 'contextlevel', 'value' => $args['contextlevel'], - )); + ]); - $editorhtml .= html_writer::tag('input', '', array( + $editorhtml .= \html_writer::tag('input', '', [ 'type' => 'hidden', 'name' => 'pagetype', 'value' => $args['pagetype'], - )); + ]); - $editorhtml .= html_writer::tag('input', '', array( + $editorhtml .= \html_writer::tag('input', '', [ 'type' => 'hidden', 'name' => 'pagetitle', 'value' => $args['pagetitle'], - )); + ]); - $editorhtml .= html_writer::tag('input', '', array( + $editorhtml .= \html_writer::tag('input', '', [ 'type' => 'hidden', 'name' => 'pageurl', 'value' => $args['pageurl'], - )); + ]); - $editorhtml .= html_writer::tag('input', '', array( + $editorhtml .= \html_writer::tag('input', '', [ 'type' => 'hidden', 'name' => 'user', 'value' => $args['user'], - )); + ]); - $editorhtml .= html_writer::end_tag('form'); - $editorhtml .= html_writer::end_tag('div'); + $editorhtml .= \html_writer::end_tag('form'); + $editorhtml .= \html_writer::end_tag('div'); $editorhtml .= ltool_note_load_context_notes($args); return $editorhtml; } @@ -282,9 +282,9 @@ function ltool_note_load_context_notes($args) { $editorhtml = ''; $context = context_system::instance(); if (ltool_note_get_userpage_countnotes($args) && has_capability('ltool/note:viewownnote', $context)) { - $editorhtml .= html_writer::start_tag('div', array('class' => 'list-context-existnotes')); + $editorhtml .= \html_writer::start_tag('div', ['class' => 'list-context-existnotes']); $editorhtml .= ltool_note_get_contextuser_notes($args); - $editorhtml .= html_writer::end_tag('div'); + $editorhtml .= \html_writer::end_tag('div'); } return $editorhtml; } @@ -325,7 +325,7 @@ function ltool_note_get_contextuser_notes($args) { if (isset($listrecords[$time])) { $listrecords[$time]['notesgroup'][] = $record->id; } else { - $listrecords[$time]['notesgroup'] = array($record->id); + $listrecords[$time]['notesgroup'] = [$record->id]; } } foreach ($listrecords as $time => $listrecord) { @@ -341,7 +341,7 @@ function ltool_note_get_contextuser_notes($args) { $notetime = !empty($note->timemodified) ? $note->timemodified : $note->timecreated; $list['time'] = userdate(($notetime), get_string("baseformat", "local_learningtools"), '', false); if (has_capability('ltool/note:manageownnote', $context)) { - $returnparams = array('returnurl' => $args['pageurl']); + $returnparams = ['returnurl' => $args['pageurl']]; $list['delete'] = ltool_note_delete_note_record($note, $returnparams); $list['edit'] = ltool_note_edit_note_record($note, $returnparams); } @@ -406,7 +406,7 @@ function ltool_note_user_save_notes($contextid, $data) { 'context' => $context, 'other' => [ 'pagetype' => $data['pagetype'], - ] + ], ]); $event->trigger(); @@ -415,24 +415,22 @@ function ltool_note_user_save_notes($contextid, $data) { WHERE " . $DB->sql_compare_text('pageurl', 255). " = " . $DB->sql_compare_text('?', 255) ." AND pagetype = ? AND userid = ?"; - $params = array( + $params = [ $data['pageurl'], $data['pagetype'], - $data['user'] - ); + $data['user'], + ]; if (!empty($itemtype)) { $sql .= " AND itemtype = ? AND itemid = ?"; $params[] = $itemtype; $params[] = $itemid; - } else { - $sql .= " AND itemtype = ''"; } + $pageusernotes = $DB->count_records_sql($sql, $params); return $pageusernotes; } - /** * Get notes edit records * @param object $row record @@ -444,10 +442,10 @@ function ltool_note_edit_note_record($row, $params = []) { $stredit = get_string('edit'); $buttons = []; $returnurl = new moodle_url('/local/learningtools/ltool/note/editlist.php'); - $optionyes = array('edit' => $row->id, 'sesskey' => sesskey()); + $optionyes = ['edit' => $row->id, 'sesskey' => sesskey()]; $optionyes = array_merge($optionyes, $params); $url = new moodle_url($returnurl, $optionyes); - $buttons[] = html_writer::link($url, $OUTPUT->pix_icon('t/edit', $stredit)); + $buttons[] = \html_writer::link($url, $OUTPUT->pix_icon('t/edit', $stredit)); $buttonhtml = implode(' ', $buttons); return $buttonhtml; @@ -465,10 +463,10 @@ function ltool_note_delete_note_record($row, $params = []) { $strdelete = get_string('delete'); $buttons = []; $returnurl = new moodle_url('/local/learningtools/ltool/note/deletelist.php'); - $optionyes = array('delete' => $row->id, 'sesskey' => sesskey()); + $optionyes = ['delete' => $row->id, 'sesskey' => sesskey()]; $optionyes = array_merge($optionyes, $params); $url = new moodle_url($returnurl, $optionyes); - $buttons[] = html_writer::link($url, $OUTPUT->pix_icon('t/delete', $strdelete)); + $buttons[] = \html_writer::link($url, $OUTPUT->pix_icon('t/delete', $strdelete)); $buttonhtml = implode(' ', $buttons); return $buttonhtml; } @@ -482,7 +480,7 @@ function ltool_note_require_deletenote_cap($id) { $context = context_system::instance(); $returnurl = new moodle_url('/my'); - $currentrecord = $DB->get_record('ltool_note_data', array('id' => $id)); + $currentrecord = $DB->get_record('ltool_note_data', ['id' => $id]); if (!empty($currentrecord)) { if ($currentrecord->userid == $USER->id) { if (has_capability('ltool/note:manageownnote', $context)) { @@ -509,12 +507,11 @@ function ltool_note_get_userpage_countnotes($args) { WHERE " . $DB->sql_compare_text('pageurl', 255). " = " . $DB->sql_compare_text('?', 255) ." AND pagetype = ? AND userid = ?"; - - $params = array( + $params = [ $args['pageurl'], $args['pagetype'], - $args['user'] - ); + $args['user'], + ]; if (isset($args['itemtype']) && !empty($args['itemtype'])) { $sql .= " AND itemtype = ? AND itemid = ?"; $params[] = $args['itemtype']; @@ -543,19 +540,36 @@ function ltool_note_check_view_notes() { * @return void */ function ltool_note_load_js_config() { - global $COURSE, $PAGE, $USER; - $params['course'] = $COURSE->id; - $params['contextlevel'] = $PAGE->context->contextlevel; - $params['pagetype'] = $PAGE->pagetype; - $params['pagetitle'] = $PAGE->title; - $pageurl = local_learningtools_clean_mod_assign_userlistid($PAGE->url->out(false), $PAGE->cm); - $params['pageurl'] = $pageurl; - $params['user'] = $USER->id; - $params['contextid'] = $PAGE->context->id; - $params['title'] = $PAGE->title; - $params['heading'] = $PAGE->heading; - $params['sesskey'] = sesskey(); - $PAGE->requires->js_call_amd('ltool_note/learningnote', 'init', array($PAGE->context->id, $params)); + global $COURSE, $PAGE, $USER, $CFG; + // Create config data. + $config = [ + 'course' => $COURSE->id, + 'contextlevel' => $PAGE->context->contextlevel, + 'pagetype' => $PAGE->pagetype, + 'pagetitle' => $PAGE->title, + 'pageurl' => local_learningtools_clean_mod_assign_userlistid($PAGE->url->out(false), $PAGE->cm), + 'user' => $USER->id, + 'contextid' => $PAGE->context->id, + 'title' => $PAGE->title, + 'heading' => $PAGE->heading, + 'sesskey' => sesskey(), + 'noteheading' => get_string('mynotes', 'local_learningtools'), + ]; + + // Add theme URL if needed. + if (isset($CFG->theme)) { + $themeconfig = theme_config::load($CFG->theme); + $themeurls = $themeconfig->css_urls($PAGE); + if (!empty($themeurls)) { + $config['themeurl'] = $themeurls[0]->out(false); + } + } + + // Set the configuration for the module. + $PAGE->requires->js_call_amd('ltool_note/learningnote', 'init', [$PAGE->context->id]); + + // Register the configuration. + $PAGE->requires->data_for_js('ltool_note_config', $config); } /** @@ -568,14 +582,13 @@ function ltool_note_render_template($templatecontent) { return $OUTPUT->render_from_template('ltool_note/note', $templatecontent); } - /** * Check the note status. * @return bool */ function ltool_note_is_note_status() { global $DB; - $noterecord = $DB->get_record('local_learningtools_products', array('shortname' => 'note')); + $noterecord = $DB->get_record('local_learningtools_products', ['shortname' => 'note']); if (isset($noterecord->status) && !empty($noterecord->status)) { return true; } @@ -593,15 +606,14 @@ function ltool_note_require_note_status() { return true; } - /** * Delete the course notes. * @param int $courseid course id. */ function ltool_note_delete_course_note($courseid) { global $DB; - if ($DB->record_exists('ltool_note_data', array('course' => $courseid))) { - $DB->delete_records('ltool_note_data', array('course' => $courseid)); + if ($DB->record_exists('ltool_note_data', ['course' => $courseid])) { + $DB->delete_records('ltool_note_data', ['course' => $courseid]); } } @@ -612,8 +624,8 @@ function ltool_note_delete_course_note($courseid) { function ltool_note_delete_module_note($module) { global $DB; - if ($DB->record_exists('ltool_note_data', array('coursemodule' => $module))) { - $DB->delete_records('ltool_note_data', array('coursemodule' => $module)); + if ($DB->record_exists('ltool_note_data', ['coursemodule' => $module])) { + $DB->delete_records('ltool_note_data', ['coursemodule' => $module]); } } @@ -647,3 +659,52 @@ function local_learningtools_get_chapter_name($data, $record) { $modulename = $record->pagetitle . " | " . $chaptertitle; return $coursename.' / '. $section. ' / '. $modulename; } + +/** + * Get the notes content for the nots listing page. + * @param object $args + * @return string + */ +function ltool_note_output_fragment_get_notes_contents($args) { + global $PAGE; + + $pageurl = new \moodle_url($args['pageurl']);; + $courseid = $pageurl->get_param('id'); + $filter = $pageurl->get_param('filter'); + + if ($filter == 'section') { + $sectionid = $pageurl->get_param('sectionid'); + } else if ($filter == 'activity') { + $activity = $pageurl->get_param('activity'); + } + + $output = $PAGE->get_renderer('local_learningtools'); + $noteslist = new \ltool_note\output\notes_list($courseid, $sectionid, $activity, '', $filter, true); + return $output->render($noteslist); +} + +/** + * Fragment output for notes list with search functionality. + * @param array $args + * @return string + */ +function ltool_note_output_fragment_get_notes_list($args) { + global $PAGE; + + $args = (object) $args; + $context = $args->context; + + $PAGE->set_context($context); + + $courseid = $args->courseid ?? 0; + $search = $args->search ?? ''; + $sectionid = $args->sectionid ?? 0; + $activity = $args->activity ?? 0; + $filter = $args->filter ?? ''; + $print = $args->print ?? false; + + $noteslist = new \ltool_note\output\notes_list($courseid, $sectionid, $activity, $search, $filter, $print); + $renderer = $PAGE->get_renderer('local_learningtools'); + + return $renderer->render($noteslist); +} diff --git a/ltool/note/list.php b/ltool/note/list.php index fccc2cb..e64db32 100644 --- a/ltool/note/list.php +++ b/ltool/note/list.php @@ -68,7 +68,6 @@ } } - if ($coursebase) { $title = get_string('coursenotes', 'local_learningtools'); @@ -91,7 +90,6 @@ $PAGE->set_url('/local/learningtools/ltool/note/list.php'); $PAGE->set_title($title); - $urlparams = []; $pageparams = []; @@ -171,8 +169,8 @@ echo $OUTPUT->header(); echo $OUTPUT->heading(get_string('deletemessage', 'local_learningtools')); - $optionsyes = array('delete' => $delete, 'confirm' => md5($delete), - 'sesskey' => sesskey()); + $optionsyes = ['delete' => $delete, 'confirm' => md5($delete), + 'sesskey' => sesskey()]; $optionsyes = array_merge($optionsyes, $urlparams); $deleteurl = new moodle_url($pageurl, $optionsyes); $deletebutton = new single_button($deleteurl, get_string('delete'), 'post'); @@ -182,7 +180,7 @@ die; } else if (data_submitted()) { - $deleterecord = $DB->get_record('ltool_note_data', array('id' => $delete)); + $deleterecord = $DB->get_record('ltool_note_data', ['id' => $delete]); $deleteeventcontext = context::instance_by_id($deleterecord->contextid, MUST_EXIST); if ($DB->delete_records('ltool_note_data', ['id' => $delete])) { $eventcourseid = local_learningtools_get_eventlevel_courseid($deleteeventcontext, $deleterecord->course); @@ -192,7 +190,7 @@ 'context' => $deleteeventcontext, 'other' => [ 'pagetype' => $deleterecord->pagetype, - ] + ], ]; if ($childid) { $deleteeventparams = array_merge($deleteeventparams, ['relateduserid' => $childid]); @@ -224,8 +222,8 @@ if ($userbase) { $usercontext = context_user::instance($userbase); - $userinfo = $DB->get_record('user', array('id' => $userbase)); - $headerinfo = array('heading' => fullname($userinfo), 'user' => $userinfo, 'usercontext' => $usercontext); + $userinfo = $DB->get_record('user', ['id' => $userbase]); + $headerinfo = ['heading' => fullname($userinfo), 'user' => $userinfo, 'usercontext' => $usercontext]; echo $OUTPUT->context_header($headerinfo, 2); } echo $OUTPUT->heading($title); diff --git a/ltool/note/pop_out.php b/ltool/note/pop_out.php index b859bae..aff0d76 100644 --- a/ltool/note/pop_out.php +++ b/ltool/note/pop_out.php @@ -87,7 +87,6 @@ $PAGE->set_heading($pageheading); $PAGE->set_pagetype($pagetype); - if ($contextid && $courseid && $user && $contextlevel && $pagetype && $pageurl) { $params['popoutaction'] = true; @@ -108,4 +107,3 @@ echo $OUTPUT->footer(); } } - diff --git a/ltool/note/print.php b/ltool/note/print.php new file mode 100644 index 0000000..14f57e9 --- /dev/null +++ b/ltool/note/print.php @@ -0,0 +1,73 @@ +. + +/** + * Print notes page for learning tools. + * + * @package ltool_note + * @copyright 2021 bdecent gmbh + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require_once(dirname(__FILE__).'/../../../../config.php'); +require_once($CFG->dirroot.'/local/learningtools/lib.php'); +require_once($CFG->dirroot.'/local/learningtools/ltool/note/lib.php'); + +$courseid = optional_param('courseid', 0, PARAM_INT); +$contextid = optional_param('contextid', 0, PARAM_INT); +$search = optional_param('search', '', PARAM_TEXT); +$sectionid = optional_param('sectionid', 0, PARAM_INT); +$activity = optional_param('activity', 0, PARAM_INT); +$filter = optional_param('filter', '', PARAM_TEXT); + +require_login(); +ltool_note_require_note_status(); + +$context = context_system::instance(); +if ($courseid) { + $context = context_course::instance($courseid); +} + +require_capability('ltool/note:viewownnote', $context); + +$PAGE->set_context($context); +$PAGE->set_url('/local/learningtools/ltool/note/print.php'); +$PAGE->set_title(get_string('printnotes', 'ltool_note')); +$PAGE->set_heading(get_string('printnotes', 'ltool_note')); +$PAGE->set_pagelayout('popup'); + +// Add CSS and JS. +$PAGE->requires->css('/local/learningtools/ltool/note/styles.css'); +$PAGE->requires->js_call_amd('ltool_note/print', 'init'); + +echo $OUTPUT->header(); + +// Get notes using the existing fragment system. +$output = $PAGE->get_renderer('local_learningtools'); +$noteslist = new \ltool_note\output\notes_list($courseid, $sectionid, $activity, $search, $filter, true); +$notescontent = $output->render($noteslist); + +// Prepare template context. +$templatecontext = [ + 'printtitle' => get_string('printnotes', 'ltool_note'), + 'printbuttontext' => get_string('print', 'ltool_note'), + 'returnbuttontext' => get_string('returntonotes', 'ltool_note'), + 'notescontent' => $notescontent, +]; + +echo $OUTPUT->render_from_template('ltool_note/print_notes', $templatecontext); + +echo $OUTPUT->footer(); diff --git a/ltool/note/styles.css b/ltool/note/styles.css index bebecd6..9016560 100644 --- a/ltool/note/styles.css +++ b/ltool/note/styles.css @@ -5,33 +5,40 @@ text-align: right; margin-bottom: 20px; } + .path-local-learningtools-ltool-note .top-block .course-block, .path-local-learningtools-ltool-note .top-block #ltnote-coursefilter { float: left; margin-bottom: 20px; margin-right: 15px; } + .path-local-learningtools-ltool-note .top-block #ltnote-coursefilter, .path-local-learningtools-ltool-note .top-block .ltnote-activityfilter { display: inline-block; float: left; margin-bottom: 15px; } + .path-local-learningtools-ltool-note .top-block > div:last-child { display: inline-block; } + .path-local-learningtools-ltool-note .top-block > div.ltbookmarks-coursefilter { text-align: left; float: none; display: block; } + .path-local-learningtools-ltool-note .top-block > div.ltnote-sortfilter { margin-left: 20px; margin-bottom: 20px; } + .path-local-learningtools-ltool-note .top-block > div.ltnote-sortfilter i { margin-right: 5px; } + .path-local-learningtools-ltool-note .top-block > div select { min-width: 250px; width: auto; @@ -42,6 +49,7 @@ padding: 5px; display: inline-block; } + .path-local-learningtools-ltool-note .top-block > div select:after { float: right; margin-top: 10px; @@ -51,10 +59,12 @@ .path-local-learningtools-ltool-note .top-block > div.sort-block { margin-bottom: 20px; } + .path-local-learningtools-ltool-note .top-block > div.sort-block select { border: 0; display: inline-block; } + .path-local-learningtools-ltool-note .top-block > div.sort-block select:focus, .path-local-learningtools-ltool-note .top-block > div.sort-block select:active, .path-local-learningtools-ltool-note .top-block > div.sort-block select:focus:active { @@ -67,11 +77,13 @@ margin-top: 20px; clear: both; } + .ltnotes-mainbody .card { border: 0; padding-top: 10px; margin-bottom: 20px; } + .ltnotes-mainbody .card + .card { border-top: 1px solid #ccc; } @@ -83,6 +95,7 @@ border: 0; background: none; } + .ltnotes-mainbody .card .card-header h5 button { width: 100%; color: #000; @@ -91,12 +104,14 @@ text-decoration: none; display: block; } + .ltnotes-mainbody .card .card-header h5 button:after { content: '\f103'; font-family: var(--fa-style-family, "Font Awesome 6 Free", "Font Awesome 6 Brands", fontawesome); font-weight: 700; float: right; } + .ltnotes-mainbody .card .card-header h5 button.collapsed:after { content: '\f102'; font-family: var(--fa-style-family, "Font Awesome 6 Free", "Font Awesome 6 Brands", fontawesome); @@ -108,9 +123,11 @@ border: 1px solid #eee; margin-bottom: 20px; } + .ltnotes-mainbody .card .card-body .content-block .title-block { text-align: right; } + .ltnotes-mainbody .card .card-body .content-block .title-block h4 { font-size: 15px; font-weight: bold; @@ -118,12 +135,15 @@ float: left; margin-right: 15px; } + .ltnotes-mainbody .card .card-body .content-block .title-block .details-block { display: inline-block; } + .ltnotes-mainbody .card .card-body .content-block .title-block .details-block .calendar-block { margin-right: 10px; } + .ltnotes-mainbody .card .card-body .content-block .title-block .details-block .btn-block { width: auto; display: inline-block; @@ -134,9 +154,11 @@ text-align: left; float: none; } + .ltnotes-mainbody .card .card-body .content-block .title-block .details-block { display: block; } + .ltnotes-mainbody .card .card-body .content-block .title-block .details-block .calendar-block { float: left; } @@ -146,10 +168,12 @@ .learningtool-note .modal .modal-dialog .modal-header h5.modal-title { width: 100%; } + .learningtool-note .modal .modal-dialog .modal-header h5.modal-title .popout-block { float: right; display: flex; } + .learningtool-note .modal .modal-dialog .modal-header h5.modal-title .popout-block #popout-action { font-size: 13px; color: #000; @@ -159,34 +183,42 @@ border: 0; background: none; } + .learningtool-note .modal .modal-dialog .modal-header h5.modal-title .popout-block i { font-size: 13px; line-height: 24px; color: #000; display: inline-block; } + .learningtool-note .modal .modal-body .ltoolusernotes { width: 100%; } + .learningtool-note .modal .modal-body .ltoolusernotes form .editor_atto .editor_atto_content_wrap .editor_atto_content, .learningtool-note .modal .modal-body .ltoolusernotes form .editor_atto .editor_atto + textarea { border: 1px solid #ccc; } + .learningtool-note .modal .modal-body .list-context-existnotes { margin-top: 20px; } + .learningtool-note .modal .modal-body .list-context-existnotes h3 { margin-bottom: 20px; } + .learningtool-note .modal .modal-body .list-context-existnotes .usernotes-mainbody .card { margin-bottom: 5px; border: 1px solid #ccc; } + .learningtool-note .modal .modal-body .list-context-existnotes .usernotes-mainbody .card .card-header { padding: 0; border-bottom: 0; background: #efefef; } + .learningtool-note .modal .modal-body .list-context-existnotes .usernotes-mainbody .card .card-header h5 button { width: 100%; color: #000; @@ -194,20 +226,24 @@ text-align: left; text-decoration: none; } + .learningtool-note .modal .modal-body .list-context-existnotes .usernotes-mainbody .card .card-header h5 button:after { content: '\f102'; font-family: var(--fa-style-family, "Font Awesome 6 Free", "Font Awesome 6 Brands", fontawesome); font-weight: 700; float: right; } + .learningtool-note .modal .modal-body .list-context-existnotes .usernotes-mainbody .card .card-header h5 button.collapsed:after { content: '\f103'; } + .learningtool-note .modal .modal-body .list-context-existnotes .usernotes-mainbody .card .collapse .card-body, .learningtool-note .modal .modal-body .list-context-existnotes .usernotes-mainbody .card .collapsing .card-body { padding: 10px; border-bottom: 1px solid #efefef; } + .learningtool-note .modal .modal-body .list-context-existnotes .usernotes-mainbody .card .collapse .card-body:last-child, .learningtool-note .modal .modal-body .list-context-existnotes .usernotes-mainbody .card .collapsing .card-body:last-child { border-bottom: 0; @@ -217,23 +253,28 @@ .learningtool-note .modal .modal-body .list-context-existnotes .usernotes-mainbody .card .collapsing .content-block .title-block { float: right; } + .learningtool-note .modal .modal-body .list-context-existnotes .usernotes-mainbody .card .collapse .content-block .action-block, .learningtool-note .modal .modal-body .list-context-existnotes .usernotes-mainbody .card .collapsing .content-block .action-block { text-align: right; margin-left: 10px; } + .learningtool-note .modal .modal-body .usernotes-mainbody .card .collapse .content-block .action-block .edit-action, .learningtool-note .modal .modal-body .usernotes-mainbody .card .collapsing .content-block .action-block .edit-action { display: inline-block; } + .learningtool-note .modal .modal-body .usernotes-mainbody .card .collapse .content-block .action-block .delete-action, .learningtool-note .modal .modal-body .usernotes-mainbody .card .collapsing .content-block .action-block .delete-action { display: inline-block; } + .learningtool-note .modal .modal-body .list-context-existnotes .usernotes-mainbody .card .collapse .content-block .desc-block, .learningtool-note .modal .modal-body .list-context-existnotes .usernotes-mainbody .card .collapsing .content-block .desc-block { margin-top: 15px; } + .learningtool-note .modal .modal-body .usernotes-mainbody .card .collapse .content-block .desc-block p:empty, .learningtool-note .modal .modal-body .usernotes-mainbody .card .collapsing .content-block .desc-block p:empty { display: none; @@ -244,12 +285,15 @@ .local-learningtools .floating-button div.ltnoteinfo button { background: #17a2b8; } + .local-learningtools .floating-button div.ltnoteinfo button span { display: none; } + .local-learningtools .floating-button div.ltnoteinfo button span.ticked { display: block; } + .local-learningtools .floating-button div.ltnoteinfo button:hover p { background: #17a2b8; } @@ -273,4 +317,159 @@ .ltool-note-popout #page-content .activity-header { display: none; -} \ No newline at end of file +} + +/* Print page styles */ +.ltool-note-print-page { + padding: 20px; + line-height: 1.6; +} + +.ltool-note-print-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 30px; + padding-bottom: 20px; + border-bottom: 2px solid #e9ecef; +} + +.ltool-note-print-title { + font-size: 28px; + font-weight: 600; + margin: 0; +} + +.ltool-note-print-actions { + display: flex; + gap: 12px; +} + +.ltool-note-print-btn { + font-size: 14px; + font-weight: 500; + border: none; + border-radius: 6px; + padding: 10px 20px; + cursor: pointer; + display: inline-flex; + align-items: center; + gap: 8px; + transition: all 0.2s ease; +} + +.ltool-note-print-btn-primary { + color: white; + background: #007bff; +} + +.ltool-note-print-btn-primary:hover { + background: #0056b3; + transform: translateY(-1px); +} + +.ltool-note-print-btn-secondary { + color: white; + background: #6c757d; +} + +.ltool-note-print-btn-secondary:hover { + background: #545b62; + transform: translateY(-1px); +} + +.ltool-notes-container .ltool-notes-grid .note-card { + margin-bottom: 30px; + display: flex; + gap: 30px; + justify-content: space-between; +} + +.ltool-notes-container .ltool-notes-grid .note-card .note-content { + width: 100%; + border-right: 1px solid #ccc; + padding-right: 20px; +} + +.ltool-notes-container .ltool-notes-grid .note-card .note-footer { + width: 100%; +} + +.ltool-notes-container .ltool-notes-grid .note-card .note-footer .note-title-block { + display: flex; + justify-content: space-between; + /* flex-wrap: wrap; */ +} + +.ltool-notes-container .ltool-notes-grid .note-card .note-footer .note-title-block .note-title { + width: 100%; +} + +.ltool-notes-container .ltool-notes-grid .note-card .note-footer .note-title-block .note-actions button { + width: 30px; + height: 30px; + padding: 0; + border: 0; + border-radius: 50%; + background: #f5f5f5; +} + +.ltool-notes-container .ltool-notes-grid .note-card .note-footer .note-title-block .note-actions button i.icon { + margin-right: 0; +} + +.ltool-notes-container .ltool-notes-grid .note-card .note-footer .note-timestamp { + margin-top: 10px; +} + +@media (min-width: 1400px) { + .ltool-notes-container .ltool-notes-grid .note-card .note-footer { + max-width: 400px; + } +} + +@media (max-width: 1399px) { + .ltool-notes-container .ltool-notes-grid .note-card .note-footer { + max-width: 300px; + } +} + +@media (max-width: 1199px) { + .ltool-notes-container .ltool-notes-grid .note-card .note-footer { + max-width: 120px; + } +} + +@media (max-width: 991px) { + .ltool-notes-container .ltool-notes-grid .note-card .note-footer { + max-width: 200px; + } +} + +@media (max-width: 575px) { + .ltool-notes-container .ltool-notes-grid .note-card .note-footer { + max-width: 150px; + } +} + +/* Simple print styles - back to basics */ +@media print { + .ltool-note-print-header, + .ltool-note-print-actions, + .ltool-note-print-btn, + .no-print { + display: none; + } +} + +/* Loading state */ +.ltool-note-print-loading { + color: #6c757d; + text-align: center; + padding: 40px; +} + +.ltool-note-print-loading i { + font-size: 24px; + margin-bottom: 10px; +} diff --git a/ltool/note/templates/ltnote.mustache b/ltool/note/templates/ltnote.mustache index 7f0da1b..15c9c35 100644 --- a/ltool/note/templates/ltnote.mustache +++ b/ltool/note/templates/ltnote.mustache @@ -59,9 +59,9 @@ {{/enableactivityfilter}} {{! End of Course activity block }} - - {{#sortfilter}} + + {{#sortfilter}} {{! Filter block }}
@@ -81,8 +81,8 @@ {{! Notes block main content }} {{{pageingbar}}} -
- {{#records}} +
+ {{#records}}
{{! Card header }}
diff --git a/ltool/note/templates/navigationheader.mustache b/ltool/note/templates/navigationheader.mustache new file mode 100644 index 0000000..77d665b --- /dev/null +++ b/ltool/note/templates/navigationheader.mustache @@ -0,0 +1,70 @@ +{{! + This file is part of Moodle - http://moodle.org/ + + Moodle is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Moodle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Moodle. If not, see . +}} +{{! + @template ltool_note/navigationheader + + Example context (json): + { + + } + +}} +{{#collapsedcolumns}} + + {{< core/search_input_auto }} + {{$additionalattributes}} + data-input-element="ltoolnote-list-search-input" + {{/additionalattributes}} + {{$label}}{{#str}} + searchmynotes, local_learningtools + {{/str}}{{/label}} + {{$placeholder}}{{#str}} + searchmynotes, local_learningtools + {{/str}}{{/placeholder}} + {{/ core/search_input_auto }} +
+ + +
+ + +
+ + +
+ + +
+ + + + +{{/collapsedcolumns}} diff --git a/ltool/note/templates/notes_list.mustache b/ltool/note/templates/notes_list.mustache new file mode 100644 index 0000000..4aec367 --- /dev/null +++ b/ltool/note/templates/notes_list.mustache @@ -0,0 +1,93 @@ +{{! + This file is part of Moodle - http://moodle.org/ + + Moodle is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Moodle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Moodle. If not, see . +}} +{{! + @template ltool_note/notes_list + + Example context (json): + { + + } +}} + +
+
+ {{#hasnotes}} + {{#notes}} + + {{/notes}} + {{/hasnotes}} + {{^hasnotes}} +
+ {{#str}}nonotes, ltool_note{{/str}} +
+ {{/hasnotes}} +
+
+ diff --git a/ltool/note/templates/print_notes.mustache b/ltool/note/templates/print_notes.mustache new file mode 100644 index 0000000..a7791d3 --- /dev/null +++ b/ltool/note/templates/print_notes.mustache @@ -0,0 +1,44 @@ +{{! + This file is part of Moodle - http://moodle.org/ + + Moodle is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Moodle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Moodle. If not, see . +}} +{{! + @template ltool_note/print_notes + + Example context (json): + { + + } +}} + +
+
+

{{printtitle}}

+
+ + +
+
+ +
+ {{{notescontent}}} +
+
diff --git a/ltool/note/templates/usernotes.mustache b/ltool/note/templates/usernotes.mustache index 2d6d0df..ed827d0 100644 --- a/ltool/note/templates/usernotes.mustache +++ b/ltool/note/templates/usernotes.mustache @@ -53,8 +53,7 @@ {{time}}{{! Calendar block }}
-
- +
{{! Edit link icon }} {{{edit}}}
diff --git a/ltool/note/tests/behat/lnote_list.feature b/ltool/note/tests/behat/lnote_list.feature new file mode 100644 index 0000000..8861e4e --- /dev/null +++ b/ltool/note/tests/behat/lnote_list.feature @@ -0,0 +1,214 @@ +@local @local_learningtools @ltool @ltool_note @ltool_note_list + +Feature: Check the Note ltool listing and notes add/edit delete and list viewes. + In order to check ltools notes features works + As a admin + I should able to add/delete and view notes. + + Background: Create users to check the visbility of the notes. + Given the following "users" exist: + | username | firstname | lastname | email | + | student1 | Student | User 1 | student1@email.com | + | teacher1 | Teacher | User 1 | teacher1@email.com | + And the following "courses" exist: + | fullname | shortname | category | enablecompletion | showcompletionconditions | + | Course 1 | C1 | 0 | 1 | 1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | teacher1 | C1 | editingteacher | + And the following "activities" exist: + | activity | name | course | idnumber | intro | section |completion| + | page | PageName1 | C1 | page1 | Page description | 1 | 1 | + | page | Test page2 | C1 | page1 | Page description | 2 | 1 | + | page | Test page3 | C1 | page1 | Page description | 3 | 1 | + | quiz | Quiz1 | C1 | quiz1 | Page description | 1 | 1 | + | page | Test page4 | C1 | page1 | Page description | 1 | 1 | + | assign | Assign1 | C1 | assign1 | Page description | 1 | 1 | + And I log in as "student1" + And I click on FAB button + And I click on "#ltnoteinfo" "css_element" + And ".modal-title" "css_element" should be visible + And I should see "Take notes" in the ".modal-title" "css_element" + And I set the field "ltnoteeditor" to "Test note 1" + And I press "Save changes" + Then I should see "Notes added successfully" + And I am on the "Course 1" course page + And I click on FAB button + And I click on "#ltnoteinfo" "css_element" + And ".modal-title" "css_element" should be visible + And I should see "Take notes" in the ".modal-title" "css_element" + And I set the field "ltnoteeditor" to "Course Test note 1" + And I press "Save changes" + Then I should see "Notes added successfully" + And I am on the "Course 1 > Section 1" "course > section" page + And I click on FAB button + And I click on "#ltnoteinfo" "css_element" + And ".modal-title" "css_element" should be visible + And I should see "Take notes" in the ".modal-title" "css_element" + And I set the field "ltnoteeditor" to "Section Test note 1" + And I press "Save changes" + Then I should see "Notes added successfully" + And I am on the "Course 1 > Section 2" "course > section" page + And I click on FAB button + And I click on "#ltnoteinfo" "css_element" + And ".modal-title" "css_element" should be visible + And I should see "Take notes" in the ".modal-title" "css_element" + And I set the field "ltnoteeditor" to "Section Test note 2" + And I press "Save changes" + Then I should see "Notes added successfully" + And I am on the "PageName1" "page activity" page + And I click on FAB button + And I click on "#ltnoteinfo" "css_element" + And ".modal-title" "css_element" should be visible + And I should see "Take notes" in the ".modal-title" "css_element" + And I set the field "ltnoteeditor" to "Module Test note 1" + And I press "Save changes" + Then I should see "Notes added successfully" + + @javascript + Scenario: Access Notes Listing from Learning Tools Navigation. + Given I am on the "Course 1" course page logged in as student1 + And I should see "Learning Tools" in the ".secondary-navigation" "css_element" + And I click on "Learning Tools" "link" in the ".secondary-navigation" "css_element" + And I should see "Module Test note 1" in the ".note-card:nth-child(1) .note-content p" "css_element" + And I should see "Module: Page" in the ".note-card:nth-child(1) .note-context span" "css_element" + And I should see "PageName1" in the ".note-card:nth-child(1) .note-title span" "css_element" + And I should see "Section Test note 1" in the ".note-card:nth-child(3) .note-content p" "css_element" + And I should see "Section Test note 2" in the ".note-card:nth-child(2) .note-content p" "css_element" + And I should see "Course Test note 1" in the ".note-card:nth-child(4) .note-content p" "css_element" + + @javascript + Scenario: Notes Listing page actions. + # Edit the notes on the listing page. + Given I am on the "Course 1" course page logged in as student1 + And I should see "Learning Tools" in the ".secondary-navigation" "css_element" + And I click on "Learning Tools" "link" in the ".secondary-navigation" "css_element" + And I should see "Module Test note 1" in the ".note-card:nth-child(1) .note-content p" "css_element" + And I should see "Module: Page" in the ".note-card:nth-child(1) .note-context span" "css_element" + And I should see "PageName1" in the ".note-card:nth-child(1) .note-title span" "css_element" + And I click on " .note-card:nth-child(1) .note-actions button" "css_element" + And I click on "Edit" "link" in the ".note-card:nth-child(1) .note-actions .dropdown-menu" "css_element" + And I set the field "noteeditor[text]" to "Module Test note 1 is edited" + And I press "Save changes" + And I should see "Module Test note 1 is edited" in the " .note-card:nth-child(1) .note-content p" "css_element" + # Delete the notes on the listing page. + And I click on " .note-card:nth-child(1) .note-actions button" "css_element" + And I click on "Delete" "link" in the " .note-card:nth-child(1) .note-actions .dropdown-menu" "css_element" + And "Confirm" "dialogue" should be visible + Then I should see "Are you absolutely sure you want to completely delete the Note, including their Note and data?" + And "Delete" "button" should exist in the "Confirm" "dialogue" + When I click on "Delete" "button" in the "Confirm" "dialogue" + And I wait until the page is ready + Then I should see "Successfully deleted" + And I should not see "Module Test note 1 is edited" + # View the notes on the listing page. + And I click on ".note-card:nth-child(1) .note-actions button" "css_element" + And I click on "View" "link" in the ".note-card:nth-child(1) .note-actions .dropdown-menu" "css_element" + And I should see "New section" + And I click on FAB button + And I click on "#ltnoteinfo" "css_element" + And ".modal-title" "css_element" should be visible + And I should see "Take notes" in the ".modal-title" "css_element" + And I should see "Section Test note 2" in the ".modal-body .card-body:nth-of-type(1)" "css_element" + + @javascript + Scenario: Notes course section filter. + Given I am on the "Course 1" course page logged in as student1 + And I am on the "Course 1 > Section 1" "course > section" page + And I click on FAB button + And I click on "#ltnoteinfo" "css_element" + And ".modal-title" "css_element" should be visible + And I should see "Take notes" in the ".modal-title" "css_element" + And I set the field "ltnoteeditor" to "Section Test note 3" + And I press "Save changes" + And I am on the "Course 1 > Section 3" "course > section" page + And I click on FAB button + And I click on "#ltnoteinfo" "css_element" + And ".modal-title" "css_element" should be visible + And I should see "Take notes" in the ".modal-title" "css_element" + And I set the field "ltnoteeditor" to "Section Test note 4" + And I press "Save changes" + And I am on the "Course 1" course page + And I should see "Learning Tools" in the ".secondary-navigation" "css_element" + And I click on "Learning Tools" "link" in the ".secondary-navigation" "css_element" + And I should see "Section" in the ".ltnote-sectionfilter label" "css_element" + When I select "Section 3" from the "section-filter" singleselect + And I should see "Section Test note 4" in the ".note-card:nth-child(1) .note-content p" "css_element" + And I should not see "Section Test note 3" + And I should not see "Module Test note 1" + When I select "All sections" from the "section-filter" singleselect + And I should see "Section Test note 4" in the ".note-card:nth-child(1) .note-content p" "css_element" + And I should see "Section Test note 3" in the ".note-card:nth-child(2) .note-content p" "css_element" + And I should see "Module Test note 1" in the ".note-card:nth-child(3) .note-content p" "css_element" + + @javascript + Scenario: Notes course activity filter. + Given I am on the "Course 1" course page logged in as student1 + And I am on the "Quiz1" "quiz activity" page + And I click on FAB button + And I click on "#ltnoteinfo" "css_element" + And ".modal-title" "css_element" should be visible + And I should see "Take notes" in the ".modal-title" "css_element" + And I set the field "ltnoteeditor" to "Quiz module Test note 1" + And I press "Save changes" + Then I should see "Notes added successfully" + When I am on the "Assign1" "assign activity" page + And I click on FAB button + And I click on "#ltnoteinfo" "css_element" + And ".modal-title" "css_element" should be visible + And I should see "Take notes" in the ".modal-title" "css_element" + And I set the field "ltnoteeditor" to "Assignment module Test note 1" + And I press "Save changes" + Then I should see "Notes added successfully" + And I am on the "Course 1" course page + And I should see "Learning Tools" in the ".secondary-navigation" "css_element" + And I click on "Learning Tools" "link" in the ".secondary-navigation" "css_element" + And I should see "Activity" in the ".ltnote-activityfilter label" "css_element" + When I select "PageName1" from the "activity-filter" singleselect + And I should see "Module Test note 1" in the ".note-card:nth-child(1) .note-content p" "css_element" + When I select "Quiz1" from the "activity-filter" singleselect + And I should see "Quiz module Test note 1" in the ".note-card:nth-child(1) .note-content p" "css_element" + And I should not see "Module Test note 1" + When I select "Assign1" from the "activity-filter" singleselect + And I should see "Assignment module Test note 1" in the ".note-card:nth-child(1) .note-content p" "css_element" + And I should not see "Quiz module Test note 1" + When I select "All Activities" from the "activity-filter" singleselect + And I should see "Assignment module Test note 1" in the ".note-card:nth-child(1) .note-content p" "css_element" + And I should see "Quiz module Test note 1" in the ".note-card:nth-child(2) .note-content p" "css_element" + And I should see "Module Test note 1" in the ".note-card:nth-child(3) .note-content p" "css_element" + And I log out + + @javascript + Scenario: Notes search check. + Given I am on the "Course 1" course page logged in as student1 + And I should see "Learning Tools" in the ".secondary-navigation" "css_element" + And I click on "Learning Tools" "link" in the ".secondary-navigation" "css_element" + # Activity type based search. + When I set the field "Search my notes" to "page" + And I should see "Module Test note 1" in the ".note-card:nth-child(1) .note-content p" "css_element" + And I should not see "Section Test note 1" + And I should not see "Course Test note 1" + And I am on the "Quiz1" "quiz activity" page + And I click on FAB button + And I click on "#ltnoteinfo" "css_element" + And ".modal-title" "css_element" should be visible + And I should see "Take notes" in the ".modal-title" "css_element" + And I set the field "ltnoteeditor" to "Quiz module Test note 1" + And I press "Save changes" + And I am on the "Course 1" course page + And I click on "Learning Tools" "link" in the ".secondary-navigation" "css_element" + # Activity name based search. + When I set the field "Search my notes" to "Quiz1" + And I should see "Quiz module Test note 1" in the ".note-card:nth-child(1) .note-content p" "css_element" + And I should not see "Module Test note 1" + And I should not see "Section Test note 1" + And I should not see "Course Test note 1" + # Notes content based search. + When I set the field "Search my notes" to "Course Test" + And I should see "Course Test note 1" in the ".note-card:nth-child(1) .note-content p" "css_element" + And I should not see "Module Test note 1" + And I should not see "Section Test note 1" + # Notes created mon based search. + When I set the field "Search my notes" to "June" + And I should see "Course Test note 1" in the ".note-card:nth-child(1) .note-content p" "css_element" diff --git a/ltool/note/tests/ltool_note_test.php b/ltool/note/tests/ltool_note_test.php index ab18d51..abcfed5 100644 --- a/ltool/note/tests/ltool_note_test.php +++ b/ltool/note/tests/ltool_note_test.php @@ -27,8 +27,7 @@ * Note subplugin for learningtools phpunit test cases defined. * @runTestsInSeparateProcesses */ -class ltool_note_test extends \advanced_testcase { - +final class ltool_note_test extends \advanced_testcase { /** * Summary of context @@ -108,7 +107,7 @@ public function test_note_count(): void { 'contextid' => $data['contextid'], 'pagetype' => $data['pagetype'], 'user' => $data['user'], - 'pageurl' => $data['pageurl'] + 'pageurl' => $data['pageurl'], ]; $count = ltool_note_get_userpage_countnotes($args); $this->assertEquals(2, $count); @@ -137,7 +136,6 @@ public function test_external_test(): void { $this->assertEquals(2, $notecount); } - /** * Generate and fetch data for create new note instnace. * diff --git a/ltool/note/version.php b/ltool/note/version.php index bafeab4..b290649 100644 --- a/ltool/note/version.php +++ b/ltool/note/version.php @@ -24,5 +24,5 @@ defined('MOODLE_INTERNAL') || die(); $plugin->component = 'ltool_note'; -$plugin->version = 2025041702; +$plugin->version = 2025061800; $plugin->requires = 2020061501; diff --git a/ltool/note/view.php b/ltool/note/view.php new file mode 100644 index 0000000..fd0e91d --- /dev/null +++ b/ltool/note/view.php @@ -0,0 +1,76 @@ +. + +/** + * Main view page for Learning Tools + * + * @package ltool_note + * @copyright bdecent GmbH 2021 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require_once(dirname(__FILE__).'/../../../../config.php'); +require_once($CFG->dirroot.'/local/learningtools/lib.php'); + +$id = required_param('id', PARAM_INT); // Course ID. +$sectionid = optional_param('sectionid', 0, PARAM_INT); // Section ID. +$activity = optional_param('activity', 0, PARAM_INT); +$filter = optional_param('filter', '', PARAM_ALPHA); +$action = optional_param('action', '', PARAM_ALPHA); // Action to perform, e.g., 'hide' or 'show'. +$noteid = optional_param('noteid', 0, PARAM_INT); // Note ID for specific actions. + +// Get course and context information. +$course = $DB->get_record('course', ['id' => $id], '*', MUST_EXIST); +$context = context_course::instance($course->id); + +// Check login and capability. +require_login($course); + +$pageurl = new moodle_url('/local/learningtools/ltool/note/view.php', ['id' => $id]); + +// Set up page. +$PAGE->set_url($pageurl); +$PAGE->set_context($context); +$PAGE->set_course($course); +$PAGE->set_heading($course->fullname); +$PAGE->set_title(get_string('learningtools', 'local_learningtools')); +$PAGE->set_pagelayout('course'); + +// Set up secondary navigation. +$PAGE->set_secondary_active_tab('learningtools'); + +// Create the notes renderer. +$output = $PAGE->get_renderer('local_learningtools'); + +// Render the page. +echo $OUTPUT->header(); + +if ($action == 'hide' && (!empty($noteid))) { + $DB->set_field('ltool_note_data', 'printstatus', 1, ['id' => $noteid]); +} else if ($action == 'show' && (!empty($noteid))) { + $DB->set_field('ltool_note_data', 'printstatus', 0, ['id' => $noteid]); +} + +$actionbar = new \local_learningtools\output\general_action_bar($context, $pageurl, 'learningtools', 'notes', $course->id, + $sectionid, $activity); +$renderer = $PAGE->get_renderer('local_learningtools'); + +echo $renderer->render_action_bar($actionbar); + +$noteslist = new \ltool_note\output\notes_list($course->id, $sectionid, $activity, '', $filter); +echo $output->render($noteslist); + +echo $OUTPUT->footer(); diff --git a/ltool/schedule/classes/privacy/provider.php b/ltool/schedule/classes/privacy/provider.php index 97e905a..705a0dc 100644 --- a/ltool/schedule/classes/privacy/provider.php +++ b/ltool/schedule/classes/privacy/provider.php @@ -34,9 +34,8 @@ class provider implements \core_privacy\local\metadata\null_provider { * * @return string */ - public static function get_reason() : string { + public static function get_reason(): string { return 'privacy:metadata'; } } - diff --git a/ltool/schedule/db/access.php b/ltool/schedule/db/access.php index a93f52f..375c081 100644 --- a/ltool/schedule/db/access.php +++ b/ltool/schedule/db/access.php @@ -23,17 +23,17 @@ */ defined('MOODLE_INTERNAL') || die(); -$capabilities = array( +$capabilities = [ - 'ltool/schedule:createschedule' => array( + 'ltool/schedule:createschedule' => [ 'riskbitmask' => RISK_SPAM, 'captype' => 'read', 'contextlevel' => CONTEXT_COURSE, - 'archetypes' => array( + 'archetypes' => [ 'manager' => CAP_ALLOW, 'teacher' => CAP_ALLOW, 'editingteacher' => CAP_ALLOW, - 'student' => CAP_ALLOW - ) - ) -); + 'student' => CAP_ALLOW, + ], + ], +]; diff --git a/ltool/schedule/lang/en/ltool_schedule.php b/ltool/schedule/lang/en/ltool_schedule.php index 60828dd..d04ec2f 100644 --- a/ltool/schedule/lang/en/ltool_schedule.php +++ b/ltool/schedule/lang/en/ltool_schedule.php @@ -22,8 +22,8 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ - defined("MOODLE_INTERNAL") || die(); +defined("MOODLE_INTERNAL") || die(); $string['pluginname'] = "Learning Tools Schedule"; -$string['schedule:createschedule'] = "Create the Schedule tool"; $string['privacy:metadata'] = 'The Schedule tool only displays existing users data.'; +$string['schedule:createschedule'] = "Create the Schedule tool"; diff --git a/ltool/schedule/lib.php b/ltool/schedule/lib.php index fc5809c..a7de0cb 100644 --- a/ltool/schedule/lib.php +++ b/ltool/schedule/lib.php @@ -101,7 +101,7 @@ function ltool_schedule_load_js_config() { $params['pageurl'] = $PAGE->url->out(false); $params['course'] = $PAGE->course->id; $params['cm'] = !empty($PAGE->cm->id) ? $PAGE->cm->id : 0; - $PAGE->requires->js_call_amd('ltool_schedule/schedule', 'init', array($params)); + $PAGE->requires->js_call_amd('ltool_schedule/schedule', 'init', [$params]); } /** @@ -111,7 +111,7 @@ function ltool_schedule_load_js_config() { * @return string display form */ function ltool_schedule_output_fragment_get_schedule_form($args) { - $schedulebox = html_writer::start_tag('div', array('id' => 'ltoolschedule-editorbox')); + $schedulebox = html_writer::start_tag('div', ['id' => 'ltoolschedule-editorbox']); $mform = new ltool_schedule_editbox(null, $args); $schedulebox .= $mform->render(); $schedulebox .= html_writer::end_tag('div'); @@ -153,4 +153,3 @@ function ltool_schedule_output_fragment_set_calendar_event($args) { } } } - diff --git a/settings.php b/settings.php index ad6a66d..67eac9e 100644 --- a/settings.php +++ b/settings.php @@ -45,11 +45,11 @@ $name = "local_learningtools/fabbuttonvisible"; $title = get_string('visiblelearningtools', 'local_learningtools'); $desc = get_string('fabbuttonvisible_desc', 'local_learningtools'); - $choices = array( + $choices = [ 'all' => get_string('everywhere', 'local_learningtools'), 'allcourses' => get_string('allcourses', 'local_learningtools'), - 'specificcate' => get_string('specificcate', 'local_learningtools') - ); + 'specificcate' => get_string('specificcate', 'local_learningtools'), + ]; $default = 1; $setting = new admin_setting_configselect($name, $title, $desc, 'all', $choices); $page->add($setting); @@ -69,7 +69,7 @@ $page->add($setting); // Disable specific activity types. - $modules = $DB->get_records_menu('modules', array('visible' => 1), '', 'id,name'); + $modules = $DB->get_records_menu('modules', ['visible' => 1], '', 'id,name'); $modules[0] = get_string('none'); ksort($modules); if (!empty($modules)) { diff --git a/styles.css b/styles.css index e687da0..e9bd595 100644 --- a/styles.css +++ b/styles.css @@ -30,6 +30,7 @@ body.local-learningtools.scrolled #goto-top-link, z-index: 1005; transition: 0.2s; } + .learningtools-action-info .floating-button > button { width: 50px; height: 50px; @@ -42,45 +43,56 @@ body.local-learningtools.scrolled #goto-top-link, position: relative; transition: all .5s ease; } + .learningtools-action-info .floating-button > button:focus { border: 0; box-shadow: none; outline: none; } + .learningtools-action-info .floating-button > button i { font-size: 20px; color: #fff; } + .learningtools-action-info .floating-button > button:hover { box-shadow: 2px 5px 5px rgba(0, 0, 0, 0.5); } + .learningtools-action-info .floating-button .list-learningtools { display: none; transition: all .5s ease; } + .learningtools-action-info .floating-button.sticky-tool > .show + button { position: absolute; top: 0; transition: all .5s ease; } + .learningtools-action-info .floating-button.sticky-tool > .show + button i:before { content: '\f103'; } + .learningtools-action-info .floating-button .list-learningtools.show { padding-top: 55px; display: block; transition: all .5s ease; } + .learningtools-action-info .floating-button > div > div { margin-bottom: 5px; position: relative; } + .learningtools-action-info .floating-button .list-learningtools > div { transform: scale(0); } + .learningtools-action-info .floating-button .list-learningtools.show > div { transform: scale(1); } + .learningtools-action-info .floating-button > div > div button { width: 50px; height: 50px; @@ -90,6 +102,7 @@ body.local-learningtools.scrolled #goto-top-link, box-shadow: 2px 5px 5px rgb(0, 0, 0, .2); position: relative; } + .learningtools-action-info .floating-button > div > div button span { width: 25px; height: 15px; @@ -102,17 +115,20 @@ body.local-learningtools.scrolled #goto-top-link, top: 0; right: -5px; } + .learningtools-action-info .floating-button > div > div button:focus { border: 0; box-shadow: none; outline: none; } + .learningtools-action-info .floating-button > div > div p { position: absolute; top: 0; right: 60px; display: none; } + .learningtools-action-info .floating-button > div > div:hover p { min-width: 130px; color: #fff; @@ -136,8 +152,69 @@ body.local-learningtools.scrolled #goto-top-link, footer .btn-footer-popover { right: 5rem; } + .jsenabled #page.drawers.show-drawer-right .learningtools-action-info .floating-button { bottom: 80px; right: calc(315px + 2rem); transition: 0.2s; -} \ No newline at end of file +} + +.ltool-navigation.tertiary-navigation.full-width-bottom-border { + padding-bottom: 35px; + margin-bottom: 30px; +} + +.ltool-navigation.tertiary-navigation.full-width-bottom-border .row { + gap: 20px; +} + +.ltool-navigation.tertiary-navigation.ltool-navigation .navitem { + margin: 0; + display: flex; + align-items: center; +} + +.tertiary-navigation .navitem:first-child { + margin-right: 10px; +} + +.ltool-navigation.tertiary-navigation.ltool-navigation .navitem-divider { + margin: 10px; +} + +.ltool-navigation .ltnote-sectionfilter, +.ltool-navigation .ltnote-activityfilter { + max-width: 200px; + width: 100%; +} + +.ltool-navigation .ltnote-sectionfilter label, +.ltool-navigation .ltnote-activityfilter label, +.ltool-navigation .note-print-block label { + font-size: 12px; + color: #000; + opacity: .5; + margin-bottom: 0; +} + +.ltool-navigation .ltnote-sectionfilter select, +.ltool-navigation .ltnote-activityfilter select, +.ltool-navigation .ltnote-sectionfilter select:focus, +.ltool-navigation .ltnote-activityfilter select:focus { + font-weight: bold; + border: 0; + padding: 0; + cursor: pointer; +} + +.ltool-navigation [data-region="searchplaceholder"], +.ltool-navigation .ltnote-activityfilter + .navitem-divider { + display: none; +} + +.ltool-navigation .note-print-block { + margin-left: auto; + display: flex; + align-items: center; + gap: 15px; +} diff --git a/templates/tertiary_navigation.mustache b/templates/tertiary_navigation.mustache new file mode 100644 index 0000000..e733a2a --- /dev/null +++ b/templates/tertiary_navigation.mustache @@ -0,0 +1,36 @@ +{{! + This file is part of Moodle - http://moodle.org/ + + Moodle is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Moodle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Moodle. If not, see . +}} +{{! + @template local_learningtools/teritary_navigation + + Example context (json): + { + + } +}} + +
+
+ {{#generalnavselector}} + + {{/generalnavselector}} + + {{> ltool_note/navigationheader}} +
+
diff --git a/tests/local_learningtools_test.php b/tests/local_learningtools_test.php index aa8f430..0827cd0 100644 --- a/tests/local_learningtools_test.php +++ b/tests/local_learningtools_test.php @@ -26,7 +26,7 @@ /** * local learning tools main primary plugin phpunit test cases defined. */ -class local_learningtools_test extends \advanced_testcase { +final class local_learningtools_test extends \advanced_testcase { /** * Summary of course @@ -67,7 +67,7 @@ public function create_course(): void { $this->mod = $this->generator->create_module('page', [ 'course' => $this->course->id, 'title' => 'Test page', - 'content' => 'Test page content' + 'content' => 'Test page content', ]); }