diff --git a/blocks/site_main_menu/block_site_main_menu.php b/blocks/site_main_menu/block_site_main_menu.php index a638761e6e0..82b76e962e0 100644 --- a/blocks/site_main_menu/block_site_main_menu.php +++ b/blocks/site_main_menu/block_site_main_menu.php @@ -102,7 +102,7 @@ class block_site_main_menu extends block_list { 'contentwithoutlink activity-item activity' ); } else { - $cmname = new $cmnameclass($format, $cm->get_section_info(), $cm, $isediting); + $cmname = new $cmnameclass($format, $cm->get_section_info(), $cm); $activitybasis = html_writer::div( $indent . $courserenderer->render($cmname), 'activity-basis d-flex align-items-center'); @@ -214,7 +214,7 @@ class block_site_main_menu extends block_list { 'contentwithoutlink activity-item activity' ); } else { - $cmname = new $cmnameclass($format, $mod->get_section_info(), $mod, $isediting); + $cmname = new $cmnameclass($format, $mod->get_section_info(), $mod); $activitybasis = html_writer::div( $moveaction . $indent . diff --git a/blocks/social_activities/block_social_activities.php b/blocks/social_activities/block_social_activities.php index 8ab6296c59b..046e0d036d5 100644 --- a/blocks/social_activities/block_social_activities.php +++ b/blocks/social_activities/block_social_activities.php @@ -99,7 +99,7 @@ class block_social_activities extends block_list { $this->content->items[] = $content; $this->content->icons[] = ''; } else { - $cmname = new $cmnameclass($format, $cm->get_section_info(), $cm, $isediting); + $cmname = new $cmnameclass($format, $cm->get_section_info(), $cm); $activitybasis = html_writer::div( $courserenderer->render($cmname), 'activity-basis d-flex align-items-center'); @@ -205,7 +205,7 @@ class block_social_activities extends block_list { $this->content->items[] = $content; $this->content->icons[] = ''; } else { - $cmname = new $cmnameclass($format, $mod->get_section_info(), $mod, $isediting); + $cmname = new $cmnameclass($format, $mod->get_section_info(), $mod); $activitybasis = html_writer::div( $courserenderer->render($cmname) . $editbuttons, diff --git a/course/format/classes/output/local/content/cm.php b/course/format/classes/output/local/content/cm.php index cc8d96d29b8..9bb6ea48634 100644 --- a/course/format/classes/output/local/content/cm.php +++ b/course/format/classes/output/local/content/cm.php @@ -59,12 +59,6 @@ class cm implements named_templatable, renderable { /** @var array optional display options */ protected $displayoptions; - /** @var string activity link css classes */ - protected $linkclasses = null; - - /** @var string text css classes */ - protected $textclasses = null; - /** @var string the activity name output class name */ protected $cmnameclass; @@ -88,10 +82,8 @@ class cm implements named_templatable, renderable { $this->mod = $mod; // Add extra display options. - $this->load_classes(); - $displayoptions['linkclasses'] = $this->get_link_classes(); - $displayoptions['textclasses'] = $this->get_text_classes(); $this->displayoptions = $displayoptions; + $this->load_classes(); // Get the necessary classes. $this->cmnameclass = $format->get_output_classname('content\\cm\\cmname'); @@ -148,11 +140,11 @@ class cm implements named_templatable, renderable { $this->format, $this->section, $this->mod, - $this->format->show_editor(), + null, $this->displayoptions ); $data->cmname = $cmname->export_for_template($output); - $data->hasname = !empty($data->cmname['displayvalue']); + $data->hasname = $cmname->has_name(); return $data->hasname; } @@ -323,8 +315,9 @@ class cm implements named_templatable, renderable { $textclasses .= ' conditionalhidden'; } } - $this->linkclasses = $linkclasses; - $this->textclasses = $textclasses; + $this->displayoptions['linkclasses'] = $linkclasses; + $this->displayoptions['textclasses'] = $textclasses; + $this->displayoptions['onclick'] = htmlspecialchars_decode($mod->onclick, ENT_QUOTES);; } /** @@ -333,7 +326,7 @@ class cm implements named_templatable, renderable { * @return string the activity link classes. */ public function get_link_classes(): string { - return $this->linkclasses; + return $this->displayoptions['linkclasses'] ?? ''; } /** @@ -342,6 +335,15 @@ class cm implements named_templatable, renderable { * @return string the activity text classes. */ public function get_text_classes(): string { - return $this->textclasses; + return $this->displayoptions['textclasses'] ?? ''; + } + + /** + * Get the activity onclick code. + * + * @return string the activity onclick. + */ + public function get_onclick_code(): string { + return $this->displayoptions['onclick']; } } diff --git a/course/format/classes/output/local/content/cm/cmname.php b/course/format/classes/output/local/content/cm/cmname.php index 229940063bc..063768f7f66 100644 --- a/course/format/classes/output/local/content/cm/cmname.php +++ b/course/format/classes/output/local/content/cm/cmname.php @@ -25,13 +25,9 @@ namespace core_courseformat\output\local\content\cm; use cm_info; -use context_module; -use core\output\inplace_editable; use core\output\named_templatable; use core_courseformat\base as course_format; use core_courseformat\output\local\courseformat_named_templatable; -use external_api; -use lang_string; use renderable; use section_info; use stdClass; @@ -43,7 +39,7 @@ use stdClass; * @copyright 2020 Ferran Recio * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class cmname extends inplace_editable implements named_templatable, renderable { +class cmname implements named_templatable, renderable { use courseformat_named_templatable; @@ -56,9 +52,6 @@ class cmname extends inplace_editable implements named_templatable, renderable { /** @var cm_info the course module instance */ protected $mod; - /** @var editable if the title is editable */ - protected $editable; - /** @var array optional display options */ protected $displayoptions; @@ -71,14 +64,14 @@ class cmname extends inplace_editable implements named_templatable, renderable { * @param course_format $format the course format * @param section_info $section the section info * @param cm_info $mod the course module ionfo - * @param bool $editable if it is editable + * @param bool|null $editable if it is editable (not used) * @param array $displayoptions optional extra display options */ public function __construct( course_format $format, section_info $section, cm_info $mod, - bool $editable, + ?bool $editable = null, array $displayoptions = [] ) { $this->format = $format; @@ -86,25 +79,8 @@ class cmname extends inplace_editable implements named_templatable, renderable { $this->mod = $mod; $this->displayoptions = $displayoptions; - $this->editable = $editable && has_capability( - 'moodle/course:manageactivities', - $mod->context - ); - // Get the necessary classes. $this->titleclass = $format->get_output_classname('content\\cm\\title'); - - // Setup inplace editable. - parent::__construct( - 'core_course', - 'activityname', - $mod->id, - $this->editable, - $mod->name, - $mod->name, - new lang_string('edittitle'), - new lang_string('newactivityname', '', $mod->get_formatted_name()) - ); } /** @@ -114,51 +90,49 @@ class cmname extends inplace_editable implements named_templatable, renderable { * @return stdClass data context for a mustache template */ public function export_for_template(\renderer_base $output): array { - global $PAGE; + $mod = $this->mod; + $displayoptions = $this->displayoptions; - // Inplace editable uses core renderer by default. However, course elements require - // the format specific renderer. - $courseoutput = $this->format->get_renderer($PAGE); + if (!$this->has_name()) { + // Nothing to be displayed to the user. + return []; + } - // Inplace editable uses pre-rendered elements and does not allow line beaks in the UI value. + $data = [ + 'url' => $mod->url, + 'icon' => $mod->get_icon_url(), + 'modname' => $mod->modname, + 'pluginname' => get_string('pluginname', 'mod_' . $mod->modname), + 'textclasses' => $displayoptions['textclasses'] ?? '', + 'purpose' => plugin_supports('mod', $mod->modname, FEATURE_MOD_PURPOSE, MOD_PURPOSE_OTHER), + 'activityname' => $this->get_title_data($output), + ]; + + return $data; + } + + /** + * Get the title data. + * + * @param \renderer_base $output typically, the renderer that's calling this function + * @return array data context for a mustache template + */ + protected function get_title_data(\renderer_base $output): array { $title = new $this->titleclass( $this->format, $this->section, $this->mod, $this->displayoptions ); - $this->displayvalue = str_replace("\n", "", $courseoutput->render($title)); - - if (trim($this->displayvalue) == '') { - $this->editable = false; - } - $data = parent::export_for_template($output); - - return $data; + return (array) $title->export_for_template($output); } /** - * Updates course module name + * Return if the activity has a visible name. * - * @param int $itemid course module id - * @param string $newvalue new name - * @return static + * @return bool if the title is visible. */ - public static function update($itemid, $newvalue) { - $context = context_module::instance($itemid); - // Check access. - external_api::validate_context($context); - require_capability('moodle/course:manageactivities', $context); - - // Trim module name and Update value. - set_coursemodule_name($itemid, trim($newvalue)); - $coursemodulerecord = get_coursemodule_from_id('', $itemid, 0, false, MUST_EXIST); - // Return instance. - $modinfo = get_fast_modinfo($coursemodulerecord->course); - $cm = $modinfo->get_cm($itemid); - $section = $modinfo->get_section_info($cm->sectionnum); - - $format = course_get_format($cm->course); - return new static($format, $section, $cm, true); + public function has_name(): bool { + return $this->mod->is_visible_on_course_page() && $this->mod->url; } } diff --git a/course/format/classes/output/local/content/cm/title.php b/course/format/classes/output/local/content/cm/title.php index 57c06992679..779ed39c861 100644 --- a/course/format/classes/output/local/content/cm/title.php +++ b/course/format/classes/output/local/content/cm/title.php @@ -27,13 +27,16 @@ namespace core_courseformat\output\local\content\cm; use cm_info; +use core\output\inplace_editable; use core\output\named_templatable; use core_courseformat\base as course_format; -use core_courseformat\output\local\courseformat_named_templatable; use core_text; +use lang_string; use renderable; use section_info; use stdClass; +use external_api; +use context_module; /** * Base class to render a course module title inside a course format. @@ -42,9 +45,7 @@ use stdClass; * @copyright 2020 Ferran Recio * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class title implements named_templatable, renderable { - - use courseformat_named_templatable; +class title extends inplace_editable implements named_templatable, renderable { /** @var course_format the course format */ protected $format; @@ -58,6 +59,12 @@ class title implements named_templatable, renderable { /** @var array optional display options */ protected $displayoptions; + /** @var editable if the title is editable */ + protected $editable; + + /** @var displaytemplate the default display template */ + protected $displaytemplate = 'core_courseformat/local/content/cm/title'; + /** * Constructor. * @@ -65,12 +72,52 @@ class title implements named_templatable, renderable { * @param section_info $section the section info * @param cm_info $mod the course module ionfo * @param array $displayoptions optional extra display options + * @param bool|null $editable force editable value */ - public function __construct(course_format $format, section_info $section, cm_info $mod, array $displayoptions = []) { + public function __construct( + course_format $format, + section_info $section, + cm_info $mod, + array $displayoptions = [], + ?bool $editable = null + ) { $this->format = $format; $this->section = $section; $this->mod = $mod; - $this->displayoptions = $displayoptions; + + // Usually displayoptions are loaded in the main cm output. However when the user uses the inplace editor + // the cmname output does not calculate the css classes. + $this->displayoptions = $this->load_display_options($displayoptions); + + if ($editable === null) { + $editable = $format->show_editor() && has_capability( + 'moodle/course:manageactivities', + $mod->context + ); + } + $this->editable = $editable; + + // Setup inplace editable. + parent::__construct( + 'core_course', + 'activityname', + $mod->id, + $this->editable, + $mod->name, + $mod->name, + new lang_string('edittitle'), + new lang_string('newactivityname', '', $mod->get_formatted_name()) + ); + } + + /** + * Get the name of the template to use for this templatable. + * + * @param \renderer_base $renderer The renderer requesting the template name + * @return string + */ + public function get_template_name(\renderer_base $renderer): string { + return 'core/inplace_editable'; } /** @@ -79,41 +126,35 @@ class title implements named_templatable, renderable { * @param \renderer_base $output typically, the renderer that's calling this function * @return stdClass data context for a mustache template */ - public function export_for_template(\renderer_base $output): stdClass { + public function export_for_template(\renderer_base $output): array { + + // Inplace editable uses pre-rendered elements and does not allow line beaks in the UI value. + $this->displayvalue = str_replace("\n", "", $this->get_title_displayvalue()); + + if (trim($this->displayvalue) == '') { + $this->editable = false; + } + return parent::export_for_template($output); + } + + /** + * Return the title template data to be used inside the inplace editable. + * + */ + protected function get_title_displayvalue (): string { + global $PAGE; + + // Inplace editable uses core renderer by default. However, course elements require + // the format specific renderer. + $courseoutput = $this->format->get_renderer($PAGE); - $format = $this->format; $mod = $this->mod; - $displayoptions = $this->displayoptions; - - if (!$mod->is_visible_on_course_page() || !$mod->url) { - // Nothing to be displayed to the user. - return new stdClass(); - } - - // Usually classes are loaded in the main cm output. However when the user uses the inplace editor - // the cmname output does not calculate the css classes. - if (!isset($displayoptions['linkclasses']) || !isset($displayoptions['textclasses'])) { - $cmclass = $format->get_output_classname('content\\cm'); - $cmoutput = new $cmclass( - $format, - $this->section, - $mod, - $displayoptions - ); - $displayoptions['linkclasses'] = $cmoutput->get_link_classes(); - $displayoptions['textclasses'] = $cmoutput->get_text_classes(); - } $data = (object)[ 'url' => $mod->url, 'instancename' => $mod->get_formatted_name(), 'uservisible' => $mod->uservisible, - 'icon' => $mod->get_icon_url(), - 'modname' => $mod->modname, - 'pluginname' => get_string('pluginname', 'mod_' . $mod->modname), - 'linkclasses' => $displayoptions['linkclasses'], - 'textclasses' => $displayoptions['textclasses'], - 'purpose' => plugin_supports('mod', $mod->modname, FEATURE_MOD_PURPOSE, MOD_PURPOSE_OTHER), + 'linkclasses' => $this->displayoptions['linkclasses'], ]; // File type after name, for alphabetic lists (screen reader). @@ -128,6 +169,71 @@ class title implements named_templatable, renderable { // has already been encoded for display (puke). $data->onclick = htmlspecialchars_decode($mod->onclick, ENT_QUOTES); - return $data; + return $courseoutput->render_from_template( + $this->displaytemplate, + $data + ); + } + + /** + * Load the required display options if not present already. + * + * In most cases, display options are provided as a param when creating the + * object. However, inplace_editable and some blocks does not know all of them as it is + * called in a webservice and we need to ensure it is calculated. + * + * @param array $displayoptions the provided dispaly options + * @return array the full display options list + */ + protected function load_display_options(array $displayoptions): array { + $format = $this->format; + $mod = $this->mod; + + if ( + isset($displayoptions['linkclasses']) && + isset($displayoptions['textclasses']) && + isset($displayoptions['onclick']) + ) { + return $displayoptions; + } + + $cmclass = $format->get_output_classname('content\\cm'); + $cmoutput = new $cmclass( + $format, + $this->section, + $mod, + $displayoptions + ); + $displayoptions['linkclasses'] = $cmoutput->get_link_classes(); + $displayoptions['textclasses'] = $cmoutput->get_text_classes(); + $displayoptions['onclick'] = $cmoutput->get_onclick_code(); + return $displayoptions; + } + + /** + * Updates course module name. + * + * This method is used mainly by inplace_editable webservice. + * + * @param int $itemid course module id + * @param string $newvalue new name + * @return static + */ + public static function update($itemid, $newvalue) { + $context = context_module::instance($itemid); + // Check access. + external_api::validate_context($context); + require_capability('moodle/course:manageactivities', $context); + + // Trim module name and Update value. + set_coursemodule_name($itemid, trim($newvalue)); + $coursemodulerecord = get_coursemodule_from_id('', $itemid, 0, false, MUST_EXIST); + // Return instance. + $modinfo = get_fast_modinfo($coursemodulerecord->course); + $cm = $modinfo->get_cm($itemid); + $section = $modinfo->get_section_info($cm->sectionnum); + + $format = course_get_format($cm->course); + return new static($format, $section, $cm, [], true); } } diff --git a/course/format/templates/local/content/addsection.mustache b/course/format/templates/local/content/addsection.mustache index cab431ff2a7..8a6a89fc6fc 100644 --- a/course/format/templates/local/content/addsection.mustache +++ b/course/format/templates/local/content/addsection.mustache @@ -39,7 +39,7 @@ } }} {{#showaddsection}} -
+
{{#increase}} {{#pix}}t/switch_plus, moodle, {{#str}} increasesections, moodle {{/str}}{{/pix}} diff --git a/course/format/templates/local/content/cm/activity.mustache b/course/format/templates/local/content/cm/activity.mustache index 2023e6cc500..4b73db02f53 100644 --- a/course/format/templates/local/content/cm/activity.mustache +++ b/course/format/templates/local/content/cm/activity.mustache @@ -65,9 +65,9 @@ {{/ core_courseformat/local/content/cm/badges }} {{/hasname}} {{#cmname}} - {{$ core/inplace_editable }} - {{> core/inplace_editable }} - {{/ core/inplace_editable }} + {{$ core_courseformat/local/content/cm/cmname }} + {{> core_courseformat/local/content/cm/cmname }} + {{/ core_courseformat/local/content/cm/cmname }} {{/cmname}} {{#afterlink}}
-
\ No newline at end of file + diff --git a/message/templates/message_drawer_view_conversation_header_content_type_private.mustache b/message/templates/message_drawer_view_conversation_header_content_type_private.mustache index 35555c4593b..2ea58936dc1 100644 --- a/message/templates/message_drawer_view_conversation_header_content_type_private.mustache +++ b/message/templates/message_drawer_view_conversation_header_content_type_private.mustache @@ -59,13 +59,17 @@
{{name}} - - {{#pix}} i/star-rating, core {{/pix}} + + {{#pix}} i/star-rating, core, {{#str}} favourites, core {{/str}} {{/pix}} - - {{#pix}} i/muted, core {{/pix}} + + {{#pix}} i/muted, core, {{#str}} mutedconversation, core_message {{/str}} {{/pix}}
{{#showonlinestatus}} diff --git a/message/templates/message_drawer_view_conversation_header_content_type_private_no_controls.mustache b/message/templates/message_drawer_view_conversation_header_content_type_private_no_controls.mustache index 95eaac657d4..799ba62eb24 100644 --- a/message/templates/message_drawer_view_conversation_header_content_type_private_no_controls.mustache +++ b/message/templates/message_drawer_view_conversation_header_content_type_private_no_controls.mustache @@ -58,13 +58,17 @@
{{name}} - - {{#pix}} i/star-rating, core {{/pix}} + + {{#pix}} i/star-rating, core, {{#str}} favourites, core {{/str}} {{/pix}} - - {{#pix}} i/muted, core {{/pix}} + + {{#pix}} i/muted, core, {{#str}} mutedconversation, core_message {{/str}} {{/pix}}
{{#showonlinestatus}} @@ -75,4 +79,4 @@ {{/showonlinestatus}}
- \ No newline at end of file + diff --git a/message/templates/message_drawer_view_conversation_header_content_type_public.mustache b/message/templates/message_drawer_view_conversation_header_content_type_public.mustache index 30000291498..f1bae5f9ba2 100644 --- a/message/templates/message_drawer_view_conversation_header_content_type_public.mustache +++ b/message/templates/message_drawer_view_conversation_header_content_type_public.mustache @@ -58,13 +58,17 @@
{{name}} - - {{#pix}} i/star-rating, core {{/pix}} + + {{#pix}} i/star-rating, core, {{#str}} favourites, core {{/str}} {{/pix}} - - {{#pix}} i/muted, core {{/pix}} + + {{#pix}} i/muted, core, {{#str}} mutedconversation, core_message {{/str}} {{/pix}}

{{subname}}

diff --git a/message/templates/message_drawer_view_overview_header.mustache b/message/templates/message_drawer_view_overview_header.mustache index ef479ea53f2..e8041fdd58f 100644 --- a/message/templates/message_drawer_view_overview_header.mustache +++ b/message/templates/message_drawer_view_overview_header.mustache @@ -67,10 +67,12 @@ {{#pix}} i/user, core {{/pix}} {{#str}} contacts, core_message {{/str}} - - {{contactrequestcount}} + + + {{#str}} pendingcontactrequests, core_message, {{contactrequestcount}} {{/str}}
diff --git a/message/templates/message_drawer_view_overview_section.mustache b/message/templates/message_drawer_view_overview_section.mustache index ed0ce53d4d6..bfa62485333 100644 --- a/message/templates/message_drawer_view_overview_section.mustache +++ b/message/templates/message_drawer_view_overview_section.mustache @@ -54,17 +54,19 @@ {{#pix}} t/expanded, core {{/pix}} {{$title}}{{/title}} -