From ecc1a8746364707ebed329fe451dfa0f90ae02f3 Mon Sep 17 00:00:00 2001
From: Dennis Ahrens <dennis.ahrens@hs-hannover.de>
Date: Wed, 14 Jul 2021 12:29:06 +0200
Subject: [PATCH] Hack: Support for semesters as we think of them \o/

---
 classes/data_controller.php      | 54 +++++++++++++++++-
 lang/de/customfield_semester.php |  5 ++
 lang/en/customfield_semester.php |  5 ++
 locallib.php                     | 29 ++++++++++
 settings.php                     | 49 ++++++++++++++++
 update-customfield-hsh.php       | 96 ++++++++++++++++++++++++++++++++
 version.php                      |  2 +-
 7 files changed, 237 insertions(+), 3 deletions(-)
 create mode 100644 locallib.php
 create mode 100644 settings.php
 create mode 100644 update-customfield-hsh.php

diff --git a/classes/data_controller.php b/classes/data_controller.php
index 0b41a91..0ae72ca 100644
--- a/classes/data_controller.php
+++ b/classes/data_controller.php
@@ -157,14 +157,64 @@ class data_controller extends \core_customfield\data_controller {
     public static function get_semester_for_datetime(DateTime $datetime): int {
         $year = (int) $datetime->format('Y');
         $month = (int) $datetime->format('m');
-        if ($month < 4) {
+        $summertermstartmonth = self::get_summerterm_startmonth();
+        $wintertermstartmonth = self::get_winterterm_startmonth();
+        if ($month < $summertermstartmonth) {
             $year--;
             $semester = 1;
-        } else if ($month < 10) {
+        } else if ($month < $wintertermstartmonth) {
             $semester = 0;
         } else {
             $semester = 1;
         }
         return $year * 10 + $semester;
     }
+
+    /**
+     * Returns the configured start month of the summer term from the plugin settings.
+     *
+     * @return int
+     */
+    public static function get_summerterm_startmonth(): int {
+        global $CFG;
+
+        // Require local library.
+        require_once($CFG->dirroot.'/customfield/field/semester/locallib.php');
+
+        // Get config from DB.
+        $config = get_config('customfield_semester');
+
+        // Double-check that the value is within the acceptable range. If not, return the default value.
+        if (is_numeric($config->summertermstartmonth) == false ||
+                $config->summertermstartmonth < 1 || $config->summertermstartmonth > 12 ||
+                $config->summertermstartmonth > $config->wintertermstartmonth) {
+            return CUSTOMFIELD_SEMESTER_SUMMERTERMSTART;
+        }
+
+        return $config->summertermstartmonth;
+    }
+
+    /**
+     * Returns the configured start month of the winter term from the plugin settings.
+     *
+     * @return int
+     */
+    public static function get_winterterm_startmonth(): int {
+        global $CFG;
+
+        // Require local library.
+        require_once($CFG->dirroot.'/customfield/field/semester/locallib.php');
+
+        // Get config from DB.
+        $config = get_config('customfield_semester');
+
+        // Double-check that the value is within the acceptable range. If not, return the default value.
+        if (is_numeric($config->wintertermstartmonth) == false ||
+                $config->wintertermstartmonth < 1 || $config->wintertermstartmonth > 12 ||
+                $config->wintertermstartmonth < $config->summertermstartmonth) {
+            return CUSTOMFIELD_SEMESTER_WINTERTERMSTART;
+        }
+
+        return $config->wintertermstartmonth;
+    }
 }
diff --git a/lang/de/customfield_semester.php b/lang/de/customfield_semester.php
index d00a9b7..ed5f341 100644
--- a/lang/de/customfield_semester.php
+++ b/lang/de/customfield_semester.php
@@ -32,3 +32,8 @@ $string['specificsettings'] = 'Einstellungen für das Semesterfeld';
 $string['showmonthsintofuture'] = 'Ein Semester ist auswählbar, wenn es in weniger als X Monaten beginnt.';
 $string['defaultmonthsintofuture'] = 'Standard ist das Semester in X Monaten.';
 $string['beginofsemesters'] = 'Das Jahr, in dem die Liste der Semester anfängt.';
+$string['summertermstartmonth'] = 'Der Monat in dem das Sommersemester startet';
+$string['summertermstartmonth_desc'] = 'Mit dieser Einstellung definieren Sie in welchem Monat das Sommersemester startet.';
+$string['wintertermstartmonth'] = 'Der Monat in dem das Wintersemester startet';
+$string['wintertermstartmonth_desc'] = 'Mit dieser Einstellung definieren Sie in welchem Monat das Wintersemester startet.';
+$string['startmonthnote'] = 'Bitte beachten: Gültige Einstellungen sind Werte zwischen 1 und 12. Diese Einstellung geht davon aus, dass das Sommersemester im Jahresverlauf vor dem Wintersemester kommt. Falls Sie die Semester andersrum konfigurieren, wird das Kursfeld Ihre Einstellung stillschweigend ignorieren und die Standardwerte nutzen.';
diff --git a/lang/en/customfield_semester.php b/lang/en/customfield_semester.php
index 732dd91..560b245 100644
--- a/lang/en/customfield_semester.php
+++ b/lang/en/customfield_semester.php
@@ -32,3 +32,8 @@ $string['specificsettings'] = 'Semester field settings';
 $string['showmonthsintofuture'] = 'A semester will be selectable, if it begins in less than X months.';
 $string['defaultmonthsintofuture'] = 'The default option is the semester in X months.';
 $string['beginofsemesters'] = 'The year, the list of semesters begins in.';
+$string['summertermstartmonth'] = 'The month when summer term starts';
+$string['summertermstartmonth_desc'] = 'With this setting, you define in which month the summer term starts.';
+$string['wintertermstartmonth'] = 'The month when winter term starts';
+$string['wintertermstartmonth_desc'] = 'With this setting, you define in which month the winter term starts.';
+$string['startmonthnote'] = 'Please note: Acceptable values are numbers between 1 and 12. This setting assumes that the summer term comes before the winter term. If you configure the terms the other way round, the custom field will silently ignore your settings and use the defaults.';
diff --git a/locallib.php b/locallib.php
new file mode 100644
index 0000000..8b083f9
--- /dev/null
+++ b/locallib.php
@@ -0,0 +1,29 @@
+<?php
+// 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 <http://www.gnu.org/licenses/>.
+
+/**
+ * Customfield Semester Type - Local library.
+ *
+ * @package   customfield_semester
+ * @copyright 2021 Alexander Bias
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+// Constants for term default start months.
+define('CUSTOMFIELD_SEMESTER_SUMMERTERMSTART', 4);
+define('CUSTOMFIELD_SEMESTER_WINTERTERMSTART', 10);
diff --git a/settings.php b/settings.php
new file mode 100644
index 0000000..309cace
--- /dev/null
+++ b/settings.php
@@ -0,0 +1,49 @@
+<?php
+// 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 <http://www.gnu.org/licenses/>.
+
+/**
+ * Customfield Semester Type - Settings file.
+ *
+ * @package   customfield_semester
+ * @copyright 2021 Alexander Bias
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+if ($ADMIN->fulltree) {
+    // Require local library.
+    require_once($CFG->dirroot.'/customfield/field/semester/locallib.php');
+
+    // Prepare regex for month number. This will be used instead of the PARAM_* type within the admin settings.
+    $monthregex = '/^([1-9]|1[0-2])$/';
+
+    // Setting for the summer term start month.
+    $name = 'customfield_semester/summertermstartmonth';
+    $title = get_string('summertermstartmonth', 'customfield_semester', null, true);
+    $description = get_string('summertermstartmonth_desc', 'customfield_semester', null, true).'<br />'.
+            get_string('startmonthnote', 'customfield_semester', null, true);
+    $setting = new admin_setting_configtext($name, $title, $description, CUSTOMFIELD_SEMESTER_SUMMERTERMSTART, $monthregex, 2);
+    $settings->add($setting);
+
+    // Setting for the winter term start month.
+    $name = 'customfield_semester/wintertermstartmonth';
+    $title = get_string('wintertermstartmonth', 'customfield_semester', null, true);
+    $description = get_string('wintertermstartmonth_desc', 'customfield_semester', null, true).'<br />'.
+            get_string('startmonthnote', 'customfield_semester', null, true);
+    $setting = new admin_setting_configtext($name, $title, $description, CUSTOMFIELD_SEMESTER_WINTERTERMSTART, $monthregex, 2);
+    $settings->add($setting);
+}
diff --git a/update-customfield-hsh.php b/update-customfield-hsh.php
new file mode 100644
index 0000000..fbb772c
--- /dev/null
+++ b/update-customfield-hsh.php
@@ -0,0 +1,96 @@
+<?php
+
+// 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 <http://www.gnu.org/licenses/>.
+
+/**
+ * Update semester custom field type.
+ *
+ *
+ * @package    customfield_semester
+ * @copyright  2020 Peter Fricke HsH
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+define('CLI_SCRIPT', 1);
+
+require_once(__DIR__ . '/../../../config.php');
+require_once($CFG->libdir . '/clilib.php');
+global $DB;
+
+$category = $DB->get_record('customfield_category', array('name' => 'Semester', 'component' => 'core_course', 'area' => 'course'));
+if (!$category) {
+    die('Customfield category does not exist!');
+}
+
+$field = $DB->get_record('customfield_field', array('type' => 'semester', 'categoryid' => $category->id));
+if (!$field) {
+    die('Customfield does not exist!');
+}
+
+$fieldcontroller = \core_customfield\field_controller::create($field->id);
+$datacontroller = \core_customfield\data_controller::create(0, null, $fieldcontroller);
+
+
+// Update custom field data for every course.
+$courses = get_courses();
+$actualDate = new DateTime('NOW');
+foreach ($courses as $dbcourse) {
+
+    $courseid = $dbcourse->id;
+    $actualDate->setTimestamp($dbcourse->startdate);
+    $record = $DB->get_record('customfield_data', array(
+        'fieldid' => $field->id,
+        'instanceid' => $courseid
+    ));
+    $context = context_course::instance($courseid);
+    //there is no record, so prepare to add it
+    if (!$record) {
+		$record = new \StdClass;
+        echo cli_write("Warning: course ($courseid) has no semester custom field, adding a new one<br>") . PHP_EOL;
+        if ($actualDate->format('Y') < 2000) {
+            $record->intvalue = 1;
+            $record->value = 1;
+        } else {
+            $record->intvalue = $datacontroller->get_semester_for_datetime($actualDate);
+            $record->value = $record->intvalue;
+        }
+        $record->fieldid = $field->id;
+        $record->contextid = $context->id;
+        $record->instanceid = $courseid;
+        $record->valueformat = 0;
+        $record->timecreated = time();
+        $record->timemodified = $record->timecreated;
+
+        if (!$DB->insert_record('customfield_data', $record)) {
+            echo cli_write("Error: Updating course ($courseid) failed!<br>") . PHP_EOL;
+        }
+    } else { // set the righ
+        if ($actualDate->format('Y') < 2000) {
+            $record->intvalue = 1;
+            $record->value = 1;
+        } else {
+            $record->intvalue = $datacontroller->get_semester_for_datetime($actualDate);
+            $record->value = $record->intvalue;
+        }
+        $record->timemodified = time();
+
+        if (!$DB->update_record('customfield_data', $record)) {
+            echo cli_write("Error: Updating course ($courseid) failed!<br>") . PHP_EOL;
+        }
+    }
+    echo cli_heading("course ($courseid) is from " . $actualDate->format('c') . " setting semester to: " . $record->intvalue) . PHP_EOL;
+}
+
+echo "Finished!";
diff --git a/version.php b/version.php
index fa5648b..8c9fbf0 100644
--- a/version.php
+++ b/version.php
@@ -25,5 +25,5 @@
 defined('MOODLE_INTERNAL') || die();
 
 $plugin->component = 'customfield_semester';
-$plugin->version   = 2020041301;
+$plugin->version   = 2020041302;
 $plugin->requires  = 2019111800;
-- 
GitLab