MDL-51283 core_tag: Allow each tag area to set 'showstandard'
authorMarina Glancy <marina@moodle.com>
Thu, 14 Jan 2016 07:20:57 +0000 (15:20 +0800)
committerMarina Glancy <marina@moodle.com>
Tue, 2 Feb 2016 09:31:17 +0000 (17:31 +0800)
lang/en/tag.php
lib/db/install.xml
lib/db/tag.php
lib/db/upgrade.php
lib/form/tags.php
tag/classes/area.php
tag/classes/areas_table.php
tag/manage.php
tag/tests/behat/standard_tags.feature
user/editlib.php
version.php

index 302c8c5..5d576fd 100644 (file)
@@ -28,6 +28,7 @@ $string['addtagcoll'] = 'Add tag collection';
 $string['addtagtomyinterests'] = 'Add "{$a}" to my interests';
 $string['alltagpages'] = 'All tag pages';
 $string['backtoallitems'] = 'Back to all items tagged with "{$a}"';
+$string['changeshowstandard'] = 'Change showing standard tags in area {$a}';
 $string['changessaved'] = 'Changes saved';
 $string['changetagcoll'] = 'Change tag collection of area {$a}';
 $string['collnameexplained'] = 'Leave the field empty to use the default value: {$a}';
@@ -91,6 +92,8 @@ $string['resetflag'] = 'Reset flag';
 $string['responsiblewillbenotified'] = 'The person responsible will be notified';
 $string['rssdesc'] = 'This RSS feed was automatically generated by Moodle and contains user generated tags for courses.';
 $string['rsstitle'] = 'Course tags RSS feed for user: {$a}';
+$string['showstandard'] = 'Standard tags usage';
+$string['showstandard_help'] = 'This controls how area handles standard tags. When user edits the item the standard tags may be suggested or not, it is also possible to force area to only use standard tags and not allow user to type new ones.';
 $string['search'] = 'Search';
 $string['searchable'] = 'Searchable';
 $string['searchable_help'] = 'Tags in this tag collection can be searched for on "Search tags" page. If unchecked, tags can still be accessed by clicking on them or via different search interfaces.';
@@ -103,6 +106,9 @@ $string['selecttag'] = 'Select tag {$a}';
 $string['settypedefault'] = 'Remove from standard tags';
 $string['settypestandard'] = 'Make standard';
 $string['showingfirsttags'] = 'Showing {$a} most popular tags';
+$string['standardforce'] = 'Force';
+$string['standardhide'] = 'Don\'t suggest';
+$string['standardsuggest'] = 'Suggest';
 $string['standardtag'] = 'Standard';
 $string['suredeletecoll'] = 'Are you sure you want to delete tag collection "{$a}"?';
 $string['tag'] = 'Tag';
@@ -114,6 +120,7 @@ $string['tagareaenabled'] = 'Enabled';
 $string['tagareaname'] = 'Name';
 $string['tagareas'] = 'Tag areas';
 $string['tagcollection'] = 'Tag collection';
+$string['tagcollection_help'] = 'Tag collections are sets of tags for different areas. For example, a collection of standard tags can be used to tag courses, with user interests and blog post tags kept in a separate collection. When a user clicks on a tag, the tag page displays only items with that tag in the same collection. Tags can be automatically added to a collection according to the area tagged or can be added manually as standard tags.';
 $string['tagcollections'] = 'Tag collections';
 $string['tagdescription'] = 'Tag description';
 $string['tags'] = 'Tags';
index 7eac93f..c8cda52 100644 (file)
         <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
         <FIELD NAME="component" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false"/>
         <FIELD NAME="itemtype" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false"/>
-        <FIELD NAME="enabled" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="1" SEQUENCE="false"/>
+        <FIELD NAME="enabled" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false"/>
         <FIELD NAME="tagcollid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
         <FIELD NAME="callback" TYPE="char" LENGTH="100" NOTNULL="false" SEQUENCE="false"/>
         <FIELD NAME="callbackfile" TYPE="char" LENGTH="100" NOTNULL="false" SEQUENCE="false"/>
+        <FIELD NAME="showstandard" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
       </FIELDS>
       <KEYS>
         <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
index 2923bb5..074b685 100644 (file)
@@ -28,6 +28,8 @@
  *     any other tag areas to this collection nor move this tag area elsewhere
  *   - searchable (only if collection is specified) - wether the tag collection
  *     should be searchable on /tag/search.php
+ *   - showstandard - default value for the "Standard tags" attribute of the area,
+ *     this is only respected when new tag area is added and ignored during upgrade
  *   - customurl (only if collection is specified) - custom url to use instead of
  *     /tag/search.php to display information about one tag
  *   - callback - name of the function that returns items tagged with this tag,
@@ -56,6 +58,7 @@ $tagareas = array(
         'component' => 'core',
         'callback' => 'user_get_tagged_users',
         'callbackfile' => '/user/lib.php',
+        'showstandard' => core_tag_tag::HIDE_STANDARD,
     ),
     array(
         'itemtype' => 'course', // Courses.
index 11523d5..7e6ca5c 100644 (file)
@@ -4890,5 +4890,31 @@ function xmldb_main_upgrade($oldversion) {
         upgrade_main_savepoint(true, 2016020200.00);
     }
 
+    if ($oldversion < 2016020201.00) {
+
+        // Define field showstandard to be added to tag_area.
+        $table = new xmldb_table('tag_area');
+        $field = new xmldb_field('showstandard', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'callbackfile');
+
+        // Conditionally launch add field showstandard.
+        if (!$dbman->field_exists($table, $field)) {
+            $dbman->add_field($table, $field);
+        }
+
+        // By default set user area to hide standard tags. 2 = core_tag_tag::HIDE_STANDARD (can not use constant here).
+        $DB->execute("UPDATE {tag_area} SET showstandard = ? WHERE itemtype = ? AND component = ?",
+            array(2, 'user', 'core'));
+
+        // Changing precision of field enabled on table tag_area to (1).
+        $table = new xmldb_table('tag_area');
+        $field = new xmldb_field('enabled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'itemtype');
+
+        // Launch change of precision for field enabled.
+        $dbman->change_field_precision($table, $field);
+
+        // Main savepoint reached.
+        upgrade_main_savepoint(true, 2016020201.00);
+    }
+
     return true;
 }
index ff2fe68..3a66e69 100644 (file)
@@ -18,7 +18,7 @@
 /**
  * Tag autocomplete field.
  *
- * Contains HTML class for editing tags, both official and personal.
+ * Contains HTML class for editing tags, both standard and not.
  *
  * @package   core_form
  * @copyright 2009 Tim Hunt
@@ -31,7 +31,7 @@ require_once($CFG->libdir . '/form/autocomplete.php');
 /**
  * Form field type for editing tags.
  *
- * HTML class for editing tags, both official and personal.
+ * HTML class for editing tags, both standard and not.
  *
  * @package   core_form
  * @copyright 2009 Tim Hunt
@@ -41,12 +41,14 @@ class MoodleQuickForm_tags extends MoodleQuickForm_autocomplete {
     /**
      * Inidcates that the user should be the usual interface, with the official
      * tags listed seprately, and a text box where they can type anything.
+     * @deprecated since 3.1
      * @var int
      */
     const DEFAULTUI = 'defaultui';
 
     /**
      * Indicates that the user should only be allowed to select official tags.
+     * @deprecated since 3.1
      * @var int
      */
     const ONLYOFFICIAL = 'onlyofficial';
@@ -54,14 +56,15 @@ class MoodleQuickForm_tags extends MoodleQuickForm_autocomplete {
     /**
      * Indicates that the user should just be given a text box to type in (they
      * can still type official tags though.
+     * @deprecated since 3.1
      * @var int
      */
     const NOOFFICIAL = 'noofficial';
 
     /**
-     * @var boolean $showingofficial Official tags shown? (if not, then don't show link to manage official tags).
+     * @var boolean $showstandard Standard tags suggested? (if not, then don't show link to manage standard tags).
      */
-    protected $showingofficial = false;
+    protected $showstandard = false;
 
     /**
      * Options passed when creating an element.
@@ -83,25 +86,33 @@ class MoodleQuickForm_tags extends MoodleQuickForm_autocomplete {
         if (!empty($options)) {
             // Only execute it when the element was created and $options has values set by user.
             // In onQuickFormEvent() we make sure that $options is not empty even if developer left it empty.
-            if (empty($options['display'])) {
-                $options['display'] = self::DEFAULTUI;
+            $showstandard = core_tag_tag::BOTH_STANDARD_AND_NOT;
+            if (isset($options['showstandard'])) {
+                $showstandard = $options['showstandard'];
+            } else if (isset($options['display'])) {
+                debugging('Option "display" is deprecated, each tag area can be configured to show standard tags or not ' .
+                    'by admin or manager. If it is necessary for the developer to override it, please use "showstandard" option',
+                    DEBUG_DEVELOPER);
+                if ($options['display'] === self::NOOFFICIAL) {
+                    $showstandard = core_tag_tag::HIDE_STANDARD;
+                } else if ($options['display'] === self::ONLYOFFICIAL) {
+                    $showstandard = core_tag_tag::STANDARD_ONLY;
+                }
+            } else if (!empty($options['component']) && !empty($options['itemtype'])) {
+                $showstandard = core_tag_area::get_showstandard($options['component'], $options['itemtype']);
             }
-            $this->tagsoptions = $options;
 
-            $this->showingofficial = $options['display'] != self::NOOFFICIAL;
+            $this->tagsoptions = $options;
 
-            if ($this->showingofficial) {
-                $validoptions = $this->load_official_tags();
+            $this->showstandard = ($showstandard != core_tag_tag::HIDE_STANDARD);
+            if ($this->showstandard) {
+                $validoptions = $this->load_standard_tags();
             }
             // Option 'tags' allows us to type new tags.
-            if ($options['display'] == self::ONLYOFFICIAL) {
-                $attributes['tags'] = false;
-            } else {
-                $attributes['tags'] = true;
-            }
+            $attributes['tags'] = ($showstandard != core_tag_tag::STANDARD_ONLY);
             $attributes['multiple'] = 'multiple';
             $attributes['placeholder'] = get_string('entertags', 'tag');
-            $attributes['showsuggestions'] = $this->showingofficial;
+            $attributes['showsuggestions'] = $this->showstandard;
         }
 
         parent::__construct($elementName, $elementLabel, $validoptions, $attributes);
@@ -149,7 +160,7 @@ class MoodleQuickForm_tags extends MoodleQuickForm_autocomplete {
     }
 
     /**
-     * Finds the tag collection to use for official tag selector
+     * Finds the tag collection to use for standard tag selector
      *
      * @return int
      */
@@ -181,7 +192,7 @@ class MoodleQuickForm_tags extends MoodleQuickForm_autocomplete {
         global $OUTPUT;
 
         $managelink = '';
-        if (has_capability('moodle/tag:manage', context_system::instance()) && $this->showingofficial) {
+        if (has_capability('moodle/tag:manage', context_system::instance()) && $this->showstandard) {
             $url = new moodle_url('/tag/manage.php', array('tc' => $this->get_tag_collection()));
             $managelink = ' ' . $OUTPUT->action_link($url, get_string('managestandardtags', 'tag'));
         }
@@ -205,16 +216,16 @@ class MoodleQuickForm_tags extends MoodleQuickForm_autocomplete {
     }
 
     /**
-     * Internal function to load official tags
+     * Internal function to load standard tags
      */
-    protected function load_official_tags() {
+    protected function load_standard_tags() {
         global $CFG, $DB;
         if (!$this->is_tagging_enabled()) {
             return array();
         }
         $namefield = empty($CFG->keeptagnamecase) ? 'name' : 'rawname';
         $tags = $DB->get_records_menu('tag',
-            array('tagtype' => core_tag_tag::TAGTYPE_OFFICIAL, 'tagcollid' => $this->get_tag_collection()),
+            array('isstandard' => 1, 'tagcollid' => $this->get_tag_collection()),
             $namefield, 'id,' . $namefield);
         return array_combine($tags, $tags);
     }
index ef80a1a..93f16c1 100644 (file)
@@ -140,6 +140,24 @@ class core_tag_area {
         return core_tag_collection::get_default();
     }
 
+    /**
+     * Returns wether this tag area should display or not standard tags when user edits it.
+     *
+     * @param string $component component responsible for tagging
+     * @param string $itemtype what is being tagged, for example, 'post', 'course', 'user', etc.
+     * @return int
+     */
+    public static function get_showstandard($component, $itemtype) {
+        $itemtypes = self::get_areas();
+        if (array_key_exists($itemtype, $itemtypes)) {
+            if (!array_key_exists($component, $itemtypes[$itemtype])) {
+                $component = key($itemtypes[$itemtype]);
+            }
+            return $itemtypes[$itemtype][$component]->showstandard;
+        }
+        return core_tag_tag::BOTH_STANDARD_AND_NOT;
+    }
+
     /**
      * Returns all tag areas and collections that are currently cached in DB for this component
      *
@@ -198,7 +216,8 @@ class core_tag_area {
             'itemtype' => $record->itemtype,
             'tagcollid' => $record->tagcollid,
             'callback' => $record->callback,
-            'callbackfile' => $record->callbackfile));
+            'callbackfile' => $record->callbackfile,
+            'showstandard' => isset($record->showstandard) ? $record->showstandard : core_tag_tag::BOTH_STANDARD_AND_NOT));
 
         // Reset cache.
         cache::make('core', 'tags')->delete('tag_area');
@@ -214,7 +233,7 @@ class core_tag_area {
         global $DB;
         $data = array_intersect_key((array)$data,
                 array('enabled' => 1, 'tagcollid' => 1,
-                    'callback' => 1, 'callbackfile' => 1));
+                    'callback' => 1, 'callbackfile' => 1, 'showstandard' => 1));
         foreach ($data as $key => $value) {
             if ($existing->$key == $value) {
                 unset($data[$key]);
@@ -312,6 +331,7 @@ class core_tag_area {
                     }
                 }
             }
+            unset($itemtypes[$key]->showstandard); // Do not override value that was already changed by admin with the default.
             self::update($tagarea, $itemtypes[$key]);
         }
 
index 495f011..6ae1149 100644 (file)
@@ -49,6 +49,8 @@ class core_tag_areas_table extends html_table {
             get_string('component', 'tag'),
             get_string('tagareaenabled', 'core_tag'),
             get_string('tagcollection', 'tag'),
+            get_string('showstandard', 'tag') .
+                $OUTPUT->help_icon('showstandard', 'tag')
         );
 
         $this->data = array();
@@ -58,6 +60,12 @@ class core_tag_areas_table extends html_table {
         $tagcollections = core_tag_collection::get_collections_menu(true);
         $tagcollectionsall = core_tag_collection::get_collections_menu();
 
+        $standardchoices = array(
+            core_tag_tag::BOTH_STANDARD_AND_NOT => get_string('standardsuggest', 'tag'),
+            core_tag_tag::STANDARD_ONLY => get_string('standardforce', 'tag'),
+            core_tag_tag::HIDE_STANDARD => get_string('standardhide', 'tag')
+        );
+
         foreach ($tagareas as $itemtype => $it) {
             foreach ($it as $component => $record) {
                 $areaname = core_tag_area::display_name($record->component, $record->itemtype);
@@ -79,12 +87,24 @@ class core_tag_areas_table extends html_table {
                 } else {
                     $collectionselect = $tagcollectionsall[$record->tagcollid];
                 }
+
+                if ($record->enabled) {
+                    $changeshowstandardurl = new moodle_url($baseurl, array('action' => 'areasetshowstandard'));
+                    $select = new single_select($changeshowstandardurl, 'showstandard', $standardchoices,
+                        $record->showstandard, null);
+                    $select->set_label(get_string('changeshowstandard', 'core_tag', $areaname), array('class' => 'accesshide'));
+                    $showstandardselect = $OUTPUT->render($select);
+                } else {
+                    $showstandardselect = $standardchoices[$record->showstandard];
+                }
+
                 $this->data[] = array(
                     $areaname,
                     ($record->component === 'core' || preg_match('/^core_/', $record->component)) ?
                         get_string('coresystem') : get_string('pluginname', $record->component),
                     $enabled,
-                    $collectionselect
+                    $collectionselect,
+                    $showstandardselect
                 );
                 $this->rowclasses[] = $record->enabled ? '' : 'dimmed_text';
             }
index 6a00dde..7066faf 100644 (file)
@@ -160,6 +160,17 @@ switch($action) {
         redirect($manageurl);
         break;
 
+    case 'areasetshowstandard':
+        if ($tagarea) {
+            require_sesskey();
+            if (($showstandard = optional_param('showstandard', null, PARAM_INT)) !== null) {
+                core_tag_area::update($tagarea, array('showstandard' => $showstandard));
+                redirect(new moodle_url($manageurl, array('notice' => 'changessaved')));
+            }
+        }
+        redirect($manageurl);
+        break;
+
     case 'delete':
         require_sesskey();
         if (!$tagschecked && $tagid) {
@@ -224,7 +235,7 @@ if (!$tagcoll) {
     $tagareastable = new core_tag_areas_table($manageurl);
     $colltable = new core_tag_collections_table($manageurl);
 
-    echo $OUTPUT->heading(get_string('tagcollections', 'core_tag'), 3);
+    echo $OUTPUT->heading(get_string('tagcollections', 'core_tag') . $OUTPUT->help_icon('tagcollection', 'tag'), 3);
     echo html_writer::table($colltable);
     $url = new moodle_url($manageurl, array('action' => 'colladd'));
     echo html_writer::div(html_writer::link($url, get_string('addtagcoll', 'tag')), 'mdl-right addtagcoll');
@@ -237,6 +248,7 @@ if (!$tagcoll) {
 }
 
 // Tag collection is specified. Manage tags in this collection.
+echo $OUTPUT->heading(core_tag_collection::display_name($tagcoll));
 
 // Small form to add an standard tag.
 print('<form class="tag-addtags-form" method="post" action="'.$CFG->wwwroot.'/tag/manage.php">');
index b5a27e6..3c9e972 100644 (file)
@@ -102,3 +102,35 @@ Feature: Manager can add standard tags and change the tag type of existing tags
     And I press "Update"
     And "Make standard" "link" should exist in the "Tag1" "table_row"
     And I log out
+
+  @javascript
+  Scenario: Changing standard tags property of tag area
+    When I log in as "manager1"
+    And I follow "Profile" in the user menu
+    And I follow "Edit profile"
+    And I expand all fieldsets
+    And I should not see "Manage standard tags"
+    And I set the following fields to these values:
+      | List of interests | Tag3 , Tag2 |
+    And I press "Update profile"
+    And I navigate to "Manage tags" node in "Site administration > Appearance"
+    And the field "Change showing standard tags in area User interests" matches value "Don't suggest"
+    And I set the field "Change showing standard tags in area User interests" to "Suggest"
+    And I follow "Profile" in the user menu
+    And I follow "Edit profile"
+    And I expand all fieldsets
+    And I should see "Manage standard tags"
+    And I navigate to "Manage tags" node in "Site administration > Appearance"
+    And the field "Change showing standard tags in area User interests" matches value "Suggest"
+    And I set the field "Change showing standard tags in area User interests" to "Force"
+    And I follow "Profile" in the user menu
+    And I should see "Tag3"
+    And I should see "Tag2"
+    And I follow "Edit profile"
+    And I expand all fieldsets
+    And I should see "Manage standard tags"
+    And I press "Update profile"
+    # Non-standard tags were automatically removed on form save.
+    And I should see "Tag3"
+    And I should not see "Tag2"
+    And I log out
index ae9504d..2ea1fa4 100644 (file)
@@ -399,7 +399,7 @@ function useredit_shared_definition(&$mform, $editoroptions, $filemanageroptions
     if (core_tag_tag::is_enabled('core', 'user') and empty($USER->newadminuser)) {
         $mform->addElement('header', 'moodle_interests', get_string('interests'));
         $mform->addElement('tags', 'interests', get_string('interestslist'),
-            array('display' => 'noofficial', 'itemtype' => 'user', 'component' => 'core'));
+            array('itemtype' => 'user', 'component' => 'core'));
         $mform->addHelpButton('interests', 'interestslist');
     }
 
index a1d2e5c..fe667ea 100644 (file)
@@ -29,7 +29,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$version  = 2016020200.00;              // YYYYMMDD      = weekly release date of this DEV branch.
+$version  = 2016020201.00;              // YYYYMMDD      = weekly release date of this DEV branch.
                                         //         RR    = release increments - 00 in DEV branches.
                                         //           .XX = incremental changes.