MDL-30340 blocks - hide some redundant pagetypepattern options at front page
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Sun, 4 Dec 2011 23:48:08 +0000 (00:48 +0100)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Mon, 5 Dec 2011 00:09:02 +0000 (01:09 +0100)
The dual front-page/system-wide form to edit blocks can
be reduced asuming that, always:

A) system sets the context to system,
   recursively and with page-type set to "*"
B) frontpage only sets the context to site-course,
   non-recursively and with page-type set to "site-index"
C) frontpage all added sets the context to site-course,
   recursively and with paget-type set to "*"

And that is the change that this patch provides, by:

1) detecting properly if we are editing blocks @ protpage
2) passing that information to the form data processor
3) setting parentcontextid, showinsubcontexts and
   pagetypepattern following the A, B, C immutables above.

Finally, and affecting some other system-wide pages, there
are cases (my, user templates...) having only one possible
pagetypepattern, and it looks badly if the page has subpages, so
for those system-wide cases we are showing exceptionaly the
pagetypepattern statically. This will be revisited once MDL-30574
is decided and implemented, although perhaps it's ok to leave it
as default to places with only one pagetypepattern available.

blocks/edit_form.php
lib/blocklib.php

index 1e1cf8c..9b7198c 100644 (file)
@@ -93,24 +93,44 @@ class block_edit_form extends moodleform {
         $mform->addElement('static', 'bui_homecontext', get_string('createdat', 'block'), print_context_name($parentcontext));
         $mform->addHelpButton('bui_homecontext', 'createdat', 'block');
 
+        // For pre-calculated (fixed) pagetype lists
+        $pagetypelist = array();
+
         // parse pagetype patterns
         $bits = explode('-', $this->page->pagetype);
 
-        $contextoptions = array();
-        if ( ($parentcontext->contextlevel == CONTEXT_COURSE && $parentcontext->instanceid == SITEID) ||
-            ($parentcontext->contextlevel == CONTEXT_SYSTEM)) {        // Home page
-            if ($bits[0] == 'tag' || $bits[0] == 'admin') {
-                // tag and admin pages always use system context
-                // the contexts options don't make differences, so we use
-                // page type patterns only
-                $mform->addElement('hidden', 'bui_contexts', BUI_CONTEXTS_ENTIRE_SITE);
-            } else {
-                $contextoptions[BUI_CONTEXTS_FRONTPAGE_ONLY] = get_string('showonfrontpageonly', 'block');
-                $contextoptions[BUI_CONTEXTS_FRONTPAGE_SUBS] = get_string('showonfrontpageandsubs', 'block');
-                $contextoptions[BUI_CONTEXTS_ENTIRE_SITE]    = get_string('showonentiresite', 'block');
-                $mform->addElement('select', 'bui_contexts', get_string('contexts', 'block'), $contextoptions);
-                $mform->addHelpButton('bui_contexts', 'contexts', 'block');
-            }
+        // First of all, check if we are editing blocks @ front-page or no and
+        // make some dark magic if so (MDL-30340) because each page context
+        // implies one (and only one) harcoded page-type that will be set later
+        // when processing the form data at {@link block_manager::process_url_edit()}
+
+        // There are some conditions to check related to contexts
+        $ctxconditions = $this->page->context->contextlevel == CONTEXT_COURSE &&
+                         $this->page->context->instanceid == get_site()->id;
+        // And also some pagetype conditions
+        $pageconditions = isset($bits[0]) && isset($bits[1]) && $bits[0] == 'site' && $bits[1] == 'index';
+        // So now we can be 100% sure if edition is happening at frontpage
+        $editingatfrontpage = $ctxconditions && $pageconditions;
+
+        // Let the form to know about that, can be useful later
+        $mform->addElement('hidden', 'bui_editingatfrontpage', (int)$editingatfrontpage);
+
+        // Front page, show the page-contexts element and set $pagetypelist to 'any page' (*)
+        // as unique option. Processign the form will do any change if needed
+        if ($editingatfrontpage) {
+            $contextoptions = array();
+            $contextoptions[BUI_CONTEXTS_FRONTPAGE_ONLY] = get_string('showonfrontpageonly', 'block');
+            $contextoptions[BUI_CONTEXTS_FRONTPAGE_SUBS] = get_string('showonfrontpageandsubs', 'block');
+            $contextoptions[BUI_CONTEXTS_ENTIRE_SITE]    = get_string('showonentiresite', 'block');
+            $mform->addElement('select', 'bui_contexts', get_string('contexts', 'block'), $contextoptions);
+            $mform->addHelpButton('bui_contexts', 'contexts', 'block');
+            $pagetypelist['*'] = '*'; // This is not going to be shown ever, it's an unique option
+
+        // Any other system context block, hide the page-contexts element,
+        // it's always system-wide BUI_CONTEXTS_ENTIRE_SITE
+        } else if ($parentcontext->contextlevel == CONTEXT_SYSTEM) {
+            $mform->addElement('hidden', 'bui_contexts', BUI_CONTEXTS_ENTIRE_SITE);
+
         } else if ($parentcontext->contextlevel == CONTEXT_COURSE) {
             // 0 means display on current context only, not child contexts
             // but if course managers select mod-* as pagetype patterns, block system will overwrite this option
@@ -126,19 +146,21 @@ class block_edit_form extends moodleform {
             $mform->addElement('select', 'bui_contexts', get_string('contexts', 'block'), $contextoptions);
         }
 
-        // Generate pagetype patterns by callbacks
-        $displaypagetypewarning = false;
-        $pagetypelist = generate_page_type_patterns($this->page->pagetype, $parentcontext, $this->page->context);
-        if (!array_key_exists($this->block->instance->pagetypepattern, $pagetypelist)) {
-            // Pushing block's existing page type pattern
-            $pagetypestringname = 'page-'.str_replace('*', 'x', $this->block->instance->pagetypepattern);
-            if (get_string_manager()->string_exists($pagetypestringname, 'pagetype')) {
-                $pagetypelist[$this->block->instance->pagetypepattern] = get_string($pagetypestringname, 'pagetype');
-            } else {
-                //as a last resort we could put the page type pattern in the select box
-                //however this causes mod-data-view to be added if the only option available is mod-data-*
-                // so we are just showing a warning to users about their prev setting being reset
-                $displaypagetypewarning = true;
+        // Generate pagetype patterns by callbacks if necessary (has not been set specifically)
+        if (empty($pagetypelist)) {
+            $pagetypelist = generate_page_type_patterns($this->page->pagetype, $parentcontext, $this->page->context);
+            $displaypagetypewarning = false;
+            if (!array_key_exists($this->block->instance->pagetypepattern, $pagetypelist)) {
+                // Pushing block's existing page type pattern
+                $pagetypestringname = 'page-'.str_replace('*', 'x', $this->block->instance->pagetypepattern);
+                if (get_string_manager()->string_exists($pagetypestringname, 'pagetype')) {
+                    $pagetypelist[$this->block->instance->pagetypepattern] = get_string($pagetypestringname, 'pagetype');
+                } else {
+                    //as a last resort we could put the page type pattern in the select box
+                    //however this causes mod-data-view to be added if the only option available is mod-data-*
+                    // so we are just showing a warning to users about their prev setting being reset
+                    $displaypagetypewarning = true;
+                }
             }
         }
 
@@ -152,6 +174,25 @@ class block_edit_form extends moodleform {
         } else {
             $value = array_pop(array_keys($pagetypelist));
             $mform->addElement('hidden', 'bui_pagetypepattern', $value);
+            // Now we are really hiding a lot (both page-contexts and page-type-patterns),
+            // specially in some systemcontext pages having only one option (my/user...)
+            // so, until it's decided if we are going to add the 'bring-back' pattern to
+            // all those pages or no (see MDL-30574), we are going to show the unique
+            // element statically
+            // TODO: Revisit this once MDL-30574 has been decided and implemented, although
+            // perhaps it's not bad to always show this statically when only one pattern is
+            // available.
+            if (!$editingatfrontpage) {
+                // Try to beautify it
+                $strvalue = $value;
+                $strkey = 'page-'.str_replace('*', 'x', $strvalue);
+                if (get_string_manager()->string_exists($strkey, 'pagetype')) {
+                    $strvalue = get_string($strkey, 'pagetype');
+                }
+                // Show as static (hidden has been set already)
+                $mform->addElement('static', 'bui_staticpagetypepattern',
+                    get_string('restrictpagetypes','block'), $strvalue);
+            }
         }
 
         if ($this->page->subpage) {
index a25b5d4..814dc36 100644 (file)
@@ -1227,35 +1227,49 @@ class block_manager {
                 $bi->subpagepattern = $data->bui_subpagepattern;
             }
 
-            $parentcontext = get_context_instance_by_id($data->bui_parentcontextid);
             $systemcontext = get_context_instance(CONTEXT_SYSTEM);
+            $frontpagecontext = get_context_instance(CONTEXT_COURSE, SITEID);
+            $parentcontext = get_context_instance_by_id($data->bui_parentcontextid);
 
             // Updating stickiness and contexts.  See MDL-21375 for details.
             if (has_capability('moodle/site:manageblocks', $parentcontext)) { // Check permissions in destination
-                // Explicitly set the context
-                $bi->parentcontextid = $parentcontext->id;
 
-                // Should the block be sticky
-                if ($data->bui_contexts == BUI_CONTEXTS_ENTIRE_SITE or $data->bui_contexts == BUI_CONTEXTS_FRONTPAGE_SUBS) {
-                    $bi->showinsubcontexts = true;
-                } else {
-                    $bi->showinsubcontexts = false;
-                }
-
-                // If the block wants to be system-wide, then explicitly set that
-                if ($data->bui_contexts == BUI_CONTEXTS_ENTIRE_SITE) {   // Only possible on a frontpage or system page
-                    $bi->parentcontextid = $systemcontext->id;
+                // Explicitly set the default context
+                $bi->parentcontextid = $parentcontext->id;
 
-                } else { // The block doesn't want to be system-wide, so let's ensure that
-                    if ($parentcontext->id == $systemcontext->id) {  // We need to move it to the front page
-                        $frontpagecontext = get_context_instance(CONTEXT_COURSE, SITEID);
+                // Perform some exceptions for system/frontpage data. MDL-30340
+                switch ($data->bui_contexts) {
+                    case BUI_CONTEXTS_ENTIRE_SITE:
+                        // it's a system-wide block. 100% guaranteed, set parentcontextid and showinsubcontexts
+                        $bi->parentcontextid = $systemcontext->id;
+                        $bi->showinsubcontexts = true;
+                        // and also, if it's one edition @ frontpage, set its pagetypepattern to '*'
+                        // it already arrives that way from the form, but just re-enforce it here
+                        if ($data->bui_editingatfrontpage) {
+                            $bi->pagetypepattern  = '*';
+                        }
+                        break;
+                    case BUI_CONTEXTS_FRONTPAGE_SUBS:
+                        // it's a frontpage-wide (with subcontexts) block. 100% guaranteed, set parentcontextid and showinsubcontexts
                         $bi->parentcontextid = $frontpagecontext->id;
-                        if ($data->bui_contexts == BUI_CONTEXTS_FRONTPAGE_ONLY) {
-                            // If the front page only is specified, the page type setting is ignored
-                            // as explicitely set to site-index
-                            $bi->pagetypepattern = 'site-index';
+                        $bi->showinsubcontexts = true;
+                        // and also, if it's one edition @ frontpage, set its pagetypepattern to '*'
+                        // it already arrives that way from the form, but just re-enforce it here
+                        if ($data->bui_editingatfrontpage) {
+                            $bi->pagetypepattern  = '*';
                         }
-                    }
+                        break;
+                    case BUI_CONTEXTS_FRONTPAGE_ONLY:
+                        // it's a frontpage-only (no subcontexts) block. 100% guaranteed, set parentcontextid and showinsubcontexts
+                        $bi->parentcontextid = $frontpagecontext->id;
+                        $bi->showinsubcontexts = false;
+                        // and also, if it's one edition @ frontpage, set its pagetypepattern to 'site-index'
+                        // it originally comes as '*' from the form, here we change that in proviosion of
+                        // future 'site-index' pages
+                        if ($data->bui_editingatfrontpage) {
+                            $bi->pagetypepattern  = 'site-index';
+                        }
+                        break;
                 }
             }