From fdcae6561b30066b1b2183ff6d76439afdf5b9fd Mon Sep 17 00:00:00 2001 From: Kavalerchik Nadav Date: Sun, 24 May 2020 10:42:40 +0300 Subject: [PATCH] New field type "multimenu" --- fieldtype/multimenu/classes/define.php | 88 +++++++++ fieldtype/multimenu/classes/metadata.php | 182 ++++++++++++++++++ .../multimenu/classes/privacy/provider.php | 43 +++++ .../lang/en/metadatafieldtype_multimenu.php | 31 +++ fieldtype/multimenu/version.php | 33 ++++ 5 files changed, 377 insertions(+) create mode 100755 fieldtype/multimenu/classes/define.php create mode 100755 fieldtype/multimenu/classes/metadata.php create mode 100644 fieldtype/multimenu/classes/privacy/provider.php create mode 100644 fieldtype/multimenu/lang/en/metadatafieldtype_multimenu.php create mode 100755 fieldtype/multimenu/version.php diff --git a/fieldtype/multimenu/classes/define.php b/fieldtype/multimenu/classes/define.php new file mode 100755 index 0000000..6b59857 --- /dev/null +++ b/fieldtype/multimenu/classes/define.php @@ -0,0 +1,88 @@ +. + +/** + * Menu profile field definition. + * + * @package profilefield_multimenu + * @copyright 2007 onwards Shane Elliot {@link http://pukunui.com} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace metadatafieldtype_multimenu; + +defined('MOODLE_INTERNAL') || die; + +/** + * Class local_metadata_define_multimenu + * + * @copyright 2007 onwards Shane Elliot {@link http://pukunui.com} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class define extends \local_metadata\fieldtype\define_base { + + /** + * Adds elements to the form for creating/editing this type of profile field. + * @param moodleform $form + */ + public function define_form_specific($form) { + // Param 1 for menu type contains the options. + $form->addElement('textarea', 'param1', get_string('profilemenuoptions', 'admin'), ['rows' => 6, 'cols' => 40]); + $form->setType('param1', PARAM_TEXT); + + // Default data. + $form->addElement('text', 'defaultdata', get_string('profiledefaultdata', 'admin'), 'size="50"'); + $form->setType('defaultdata', PARAM_TEXT); + } + + /** + * Validates data for the profile field. + * + * @param array $data + * @param array $files + * @return array + */ + public function define_validate_specific($data, $files) { + $err = []; + + $data->param1 = str_replace("\r", '', $data->param1); + + // Check that we have at least 2 options. + if (($options = explode("\n", $data->param1)) === false) { + $err['param1'] = get_string('profilemenunooptions', 'admin'); + } else if (count($options) < 2) { + $err['param1'] = get_string('profilemenutoofewoptions', 'admin'); + } else if (!empty($data->defaultdata) && !in_array($data->defaultdata, $options)) { + // Check the default data exists in the options. + $err['defaultdata'] = get_string('profilemenudefaultnotinoptions', 'admin'); + } + return $err; + } + + /** + * Processes data before it is saved. + * @param array|stdClass $data + * @return array|stdClass + */ + public function define_save_preprocess($data) { + $data->param1 = str_replace("\r", '', $data->param1); + + return $data; + } + +} + + diff --git a/fieldtype/multimenu/classes/metadata.php b/fieldtype/multimenu/classes/metadata.php new file mode 100755 index 0000000..ba7edb4 --- /dev/null +++ b/fieldtype/multimenu/classes/metadata.php @@ -0,0 +1,182 @@ +. + +/** + * Menu profile field. + * + * @package profilefield_menu + * @copyright 2007 onwards Shane Elliot {@link http://pukunui.com} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace metadatafieldtype_multimenu; + +defined('MOODLE_INTERNAL') || die; + +/** + * Class local_metadata_field_menu + * + * @copyright 2007 onwards Shane Elliot {@link http://pukunui.com} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class metadata extends \local_metadata\fieldtype\metadata { + + /** @var array $options */ + public $options; + + /** @var int $datakey */ + public $datakey; + + /** + * Constructor method. + * + * Pulls out the options for the menu from the database and sets the the corresponding key for the data if it exists. + * + * @param int $fieldid + * @param int $instanceid + * @param object $fielddata optional data for the field object. + */ + public function __construct($fieldid = 0, $instanceid = 0, $fielddata = null) { + // First call parent constructor. + parent::__construct($fieldid, $instanceid, $fielddata); + + // Param 1 for menu type is the options. + if (isset($this->field->param1)) { + $options = explode("\n", $this->field->param1); + } else { + $options = []; + } + $this->options = []; + if (!empty($this->field->required)) { + $this->options[''] = get_string('choose').'...'; + } + foreach ($options as $key => $option) { + $this->options[$option] = format_string($option); // Multilang formatting with filters. + } + + // Set the data key. + if ($this->data !== null) { + $key = json_decode($this->data); + // TODO: remove or refactor key validity. + //if (isset($this->options[$key]) || ($key = array_search($key, $this->options)) !== false) { + $this->data = $key; + $this->datakey = $key; + //} + } + // Set the name for display; + $this->name = get_string('name', 'metadatafieldtype_multimenu'); + } + + /** + * Create the code snippet for this field instance + * Overwrites the base class method + * @param moodleform $mform Moodle form instance + */ + public function edit_field_add($mform) { + $select = $mform->addElement('select', $this->inputname, format_string($this->field->name), $this->options); + $select->setMultiple(true); + } + + /** + * Set the default value for this field instance + * Overwrites the base class method. + * @param moodleform $mform Moodle form instance + */ + public function edit_field_set_default($mform) { + $key = $this->field->defaultdata; + if (isset($this->options[$key]) || ($key = array_search($key, $this->options)) !== false) { + $defaultkey = $key; + } else { + $defaultkey = ''; + } + $mform->setDefault($this->inputname, $defaultkey); + } + + /** + * The data from the form returns the key. + * + * This should be converted to the respective option string to be saved in database + * Overwrites base class accessor method. + * + * @param mixed $data The key returned from the select input in the form + * @param stdClass $datarecord The object that will be used to save the record + * @return mixed Data or null + */ + public function edit_save_data_preprocess($data, $datarecord) { + // TODO: remove or refactor data validity. + //return isset($this->options[$data]) ? $data : null; + return json_encode($data, JSON_UNESCAPED_UNICODE); + } + + /** + * When passing the instance object to the form class for the edit page + * we should load the key for the saved data + * + * Overwrites the base class method. + * + * @param stdClass $instance Instance object. + */ + public function edit_load_instance_data($instance) { + $instance->{$this->inputname} = $this->datakey; + } + + /** + * HardFreeze the field if locked. + * @param moodleform $mform instance of the moodleform class + */ + public function edit_field_set_locked($mform) { + if (!$mform->elementExists($this->inputname)) { + return; + } + if ($this->is_locked() && !has_capability('moodle/user:update', context_system::instance())) { + $mform->hardFreeze($this->inputname); + $mform->setConstant($this->inputname, format_string($this->datakey)); + } + } + /** + * Convert external data (csv file) from value to key for processing later by edit_save_data_preprocess + * + * @param string $value one of the values in menu options. + * @return int options key for the menu + */ + public function convert_external_data($value) { + if (isset($this->options[$value])) { + $retval = $value; + } else { + $retval = array_search($value, $this->options); + } + + // If value is not found in options then return null, so that it can be handled + // later by edit_save_data_preprocess. + if ($retval === false) { + $retval = null; + } + return $retval; + } + + /** + * Return the field type and null properties. + * This will be used for validating the data submitted by a user. + * + * @return array the param type and null property + * @since Moodle 3.2 + */ + public function get_field_properties() { + return [PARAM_TEXT, NULL_NOT_ALLOWED]; + } +} + + diff --git a/fieldtype/multimenu/classes/privacy/provider.php b/fieldtype/multimenu/classes/privacy/provider.php new file mode 100644 index 0000000..3c494b5 --- /dev/null +++ b/fieldtype/multimenu/classes/privacy/provider.php @@ -0,0 +1,43 @@ +. + +/** + * @package local_metadata + * @subpackage metadatafieldtype_multimenu + * @author Mike Churchward + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @copyright 2017, onwards Poet + */ + +namespace metadatafieldtype_multimenu\privacy; + +defined('MOODLE_INTERNAL') || die(); + +class provider implements +// This plugin does not store any personal user data. + \core_privacy\local\metadata\null_provider { + + use \core_privacy\local\legacy_polyfill; + + /** + * Returns meta data about this system. + * + * @return string + */ + public static function _get_reason() { + return 'privacy:metadata'; + } +} \ No newline at end of file diff --git a/fieldtype/multimenu/lang/en/metadatafieldtype_multimenu.php b/fieldtype/multimenu/lang/en/metadatafieldtype_multimenu.php new file mode 100644 index 0000000..1d0b601 --- /dev/null +++ b/fieldtype/multimenu/lang/en/metadatafieldtype_multimenu.php @@ -0,0 +1,31 @@ +. + +/** + * Metadata menu fieldtype plugin language file. + * + * @package local_metadata + * @subpackage metadatafieldtype_menu + * @author Mike Churchward + * @copyright 2017 onwards Mike Churchward (mike.churchward@poetgroup.org) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die; + +$string['pluginname'] = 'Multimenu metadata fieldtype'; +$string['displayname'] = 'Menu - multi selection'; +$string['name'] = 'Multi selection'; \ No newline at end of file diff --git a/fieldtype/multimenu/version.php b/fieldtype/multimenu/version.php new file mode 100755 index 0000000..1c003ae --- /dev/null +++ b/fieldtype/multimenu/version.php @@ -0,0 +1,33 @@ +. + +/** + * Metadata menu fieldtype plugin version info. + * + * @package local_metadata + * @subpackage metadatafieldtype_menu + * @author Mike Churchward + * @copyright 2017 onwards Mike Churchward (mike.churchward@poetopensource.org) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die; + +$plugin->version = 2017070102; +$plugin->release = 'BETA3.3.4 (Build 2018062800)'; +$plugin->maturity = MATURITY_BETA; +$plugin->requires = 2016052300; // Requires this Moodle version. +$plugin->component = 'metadatafieldtype_multimenu'; // Full name of the plugin (used for diagnostics).