diff --git a/.github/workflows/download.yaml b/.github/workflows/download.yaml
index aa71a827..2a6979cf 100644
--- a/.github/workflows/download.yaml
+++ b/.github/workflows/download.yaml
@@ -2,59 +2,20 @@ name: dl_constants.php maintainer
on:
release:
types: [published]
- branches: ["app", "moodle"]
+ branches: ["main"]
jobs:
- update-frontend-files:
- name: Update app version & download url
- if: github.event.release.target_commitish == 'app' && !github.event.release.prerelease
- runs-on: ubuntu-latest
- steps:
- - name: Checkout repo
- uses: actions/checkout@v3
- with:
- ref: web
-
- - name: Update linux url
- run: sed -i '/linux/c\const dl_linux = "${{ github.server_url }}/${{ github.repository }}/releases/download/${{ github.event.release.tag_name }}/LB.Planner-x86_64.AppImage";' /home/runner/work/${{ github.event.repository.name }}/${{ github.event.repository.name }}/snippets/dl_constants.php
-
- - name: Update linux comment
- run: sed -i '/Linux download url/c\ * Linux download url [@${{ github.event.release.tag_name }}](${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.event.release.tag_name }}).' /home/runner/work/${{ github.event.repository.name }}/${{ github.event.repository.name }}/snippets/dl_constants.php
-
- - name: Update windows url
- run: sed -i '/windows/c\const dl_windows = "${{ github.server_url }}/${{ github.repository }}/releases/download/${{ github.event.release.tag_name }}/LB.Planner.Setup.exe";' /home/runner/work/${{ github.event.repository.name }}/${{ github.event.repository.name }}/snippets/dl_constants.php
-
- - name: Update windows comment
- run: sed -i '/Windows download url/c\ * Windows download url [@${{ github.event.release.tag_name }}](${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.event.release.tag_name }}).' /home/runner/work/${{ github.event.repository.name }}/${{ github.event.repository.name }}/snippets/dl_constants.php
-
- - name: Update mac url
- run: sed -i '/mac/c\const dl_mac = "${{ github.server_url }}/${{ github.repository }}/releases/download/${{ github.event.release.tag_name }}/LB.Planner.Setup.dmg";' /home/runner/work/${{ github.event.repository.name }}/${{ github.event.repository.name }}/snippets/dl_constants.php
-
- - name: Update mac comment
- run: sed -i '/MacOS download url/c\ * MacOS download url [@${{ github.event.release.tag_name }}](${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.event.release.tag_name }}).' /home/runner/work/${{ github.event.repository.name }}/${{ github.event.repository.name }}/snippets/dl_constants.php
-
- - name: Commit & Push
- uses: Andro999b/push@v1.3
- with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
- branch: web
- message: "Github Actions - Updated dl_constants.php to ${{ github.event.release.tag_name }}"
- - name: SFTP Upload to Webserver
- uses: Dylan700/sftp-upload-action@v1.1.4
- with:
- server: ${{ secrets.SFTP_HOST }}
- username: ${{ secrets.SFTP_USER }}
- password: ${{ secrets.SFTP_PASSWORD }}
- uploads: |
- snippets/dl_constants.php => /htdocs/snippets/dl_constants.php
update-backend-files:
name: Update plugin version & download url
- if: github.event.release.target_commitish == 'moodle' && !github.event.release.prerelease
+ if: '!github.event.release.prerelease'
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
- ref: web
+ repository: 'necodeIT/lb_planner_web'
+ ref: main
+ persist-credentials: false
+ fetch-depth: 0
- name: Update plugin url
run: sed -i '/dl_plugin/c\const dl_plugin = "${{ github.server_url }}/${{ github.repository }}/releases/download/${{ github.event.release.tag_name }}/lb_planner.zip";' /home/runner/work/${{ github.event.repository.name }}/${{ github.event.repository.name }}/snippets/dl_constants.php
@@ -65,8 +26,9 @@ jobs:
- name: Commit & Push
uses: Andro999b/push@v1.3
with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
- branch: web
+ github_token: ${{ secrets.REPO_WEB_TOKEN }}
+ repository: 'necodeIT/lb_planner_web'
+ branch: main
message: "Github Actions - Updated dl_constants.php to ${{ github.event.release.tag_name }}"
- name: SFTP Upload to Webserver
uses: Dylan700/sftp-upload-action@v1.1.4
diff --git a/.github/workflows/gen_docs.yaml b/.github/workflows/gen_docs.yaml
new file mode 100644
index 00000000..a776125c
--- /dev/null
+++ b/.github/workflows/gen_docs.yaml
@@ -0,0 +1,46 @@
+name: Generate API Docs
+
+on:
+ push:
+ branches:
+ - LP-55-Backend-Refactor # This is temporary and will be replaced by `main` once the refactor is complete
+ workflow_dispatch: # For manual triggering
+
+jobs:
+ generate-api-docs:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repo
+ uses: actions/checkout@v3
+ with:
+ ref: LP-55-Backend-Refactor # This is temporary and will be replaced by `main` once the refactor is complete
+ path: moodle
+
+ - name: Checkout docs repo
+ uses: actions/checkout@v3
+ with:
+ repository: 'necodeIT/lb_planner_docs'
+ ref: main
+ clean: false
+ path: docs
+ persist-credentials: false
+ fetch-depth: 0
+
+ - name: Setup Python
+ uses: actions/setup-python@v4.7.1
+ with:
+ python-version: '3.12'
+
+ - name: Generate docs
+ working-directory: moodle
+ run: python document_services.py ../docs/moodle
+
+ - name: Push new documentation to docs repo
+ working-directory: docs
+ uses: Andro999b/push@v1.3
+ with:
+ github_token: ${{ secrets.REPO_DOCS_TOKEN }}
+ repository: 'necodeIT/lb_planner_docs'
+ branch: main
+ message: "GitHub Actions - Update Web Service Documentation to ${{ github.sha }}"
diff --git a/.github/workflows/gha.dist.yml b/.github/workflows/gha.dist.yml
new file mode 100644
index 00000000..c7c45536
--- /dev/null
+++ b/.github/workflows/gha.dist.yml
@@ -0,0 +1,122 @@
+name: CI
+
+on:
+ pull_request:
+ types:
+ - opened
+ - synchronize
+ branches:
+ - LP-55-Backend-Refactor # Temporary. Will be changed to `main` when refactor is complete
+
+jobs:
+ Analysis:
+ runs-on: ubuntu-22.04
+
+ services:
+ postgres:
+ image: postgres:13
+ env:
+ POSTGRES_USER: 'postgres'
+ POSTGRES_HOST_AUTH_METHOD: 'trust'
+ ports:
+ - 5432:5432
+ options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 3
+
+ mariadb:
+ image: mariadb:10
+ env:
+ MYSQL_USER: 'root'
+ MYSQL_ALLOW_EMPTY_PASSWORD: "true"
+ MYSQL_CHARACTER_SET_SERVER: "utf8mb4"
+ MYSQL_COLLATION_SERVER: "utf8mb4_unicode_ci"
+ ports:
+ - 3306:3306
+ options: --health-cmd="mysqladmin ping" --health-interval 10s --health-timeout 5s --health-retries 3
+
+ strategy:
+ fail-fast: false
+ matrix:
+ php: ['7.4']
+ moodle-branch: ['MOODLE_401_STABLE']
+ database: [mariadb]
+
+ steps:
+ - name: Check out repository code
+ uses: actions/checkout@v3
+ with:
+ path: plugin
+
+ - name: Setup PHP ${{ matrix.php }}
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+ extensions: ${{ matrix.extensions }}
+ ini-values: max_input_vars=5000
+ # If you are not using code coverage, keep "none". Otherwise, use "pcov" (Moodle 3.10 and up) or "xdebug".
+ # If you try to use code coverage with "none", it will fallback to phpdbg (which has known problems).
+ coverage: none
+
+ - name: Initialise moodle-plugin-ci
+ run: |
+ composer create-project -n --no-dev --prefer-dist moodlehq/moodle-plugin-ci ci ^4
+ echo $(cd ci/bin; pwd) >> $GITHUB_PATH
+ echo $(cd ci/vendor/bin; pwd) >> $GITHUB_PATH
+ sudo locale-gen en_AU.UTF-8
+ echo "NVM_DIR=$HOME/.nvm" >> $GITHUB_ENV
+
+ - name: Install NVM and Node # TODO: remove this step after https://github.com/moodlehq/moodle-plugin-ci/issues/309 is fixed
+ run: |
+ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
+ export NVM_DIR="$HOME/.nvm"
+ [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
+ nvm install 20
+ nvm use 20
+
+ - name: Install moodle-plugin-ci
+ run: |
+ moodle-plugin-ci install --plugin ./plugin/lbplanner --db-host=127.0.0.1
+ env:
+ DB: ${{ matrix.database }}
+ MOODLE_BRANCH: ${{ matrix.moodle-branch }}
+
+ - name: PHP Lint
+ if: ${{ always() }}
+ run: moodle-plugin-ci phplint
+
+ - name: PHP Copy/Paste Detector
+ continue-on-error: true # This step will show errors but will not fail
+ if: ${{ always() }}
+ run: moodle-plugin-ci phpcpd
+
+ - name: PHP Mess Detector
+ continue-on-error: true # This step will show errors but will not fail
+ if: ${{ always() }}
+ run: moodle-plugin-ci phpmd
+
+ - name: Moodle Code Checker
+ if: ${{ always() }}
+ run: moodle-plugin-ci phpcs --max-warnings 1
+
+ - name: Moodle PHPDoc Checker
+ if: ${{ always() }}
+ run: moodle-plugin-ci phpdoc --max-warnings 0
+
+ - name: Validating
+ if: ${{ always() }}
+ run: moodle-plugin-ci validate
+
+ - name: Check upgrade savepoints
+ if: ${{ always() }}
+ run: moodle-plugin-ci savepoints
+
+ - name: Mustache Lint
+ if: ${{ always() }}
+ run: moodle-plugin-ci mustache
+
+ - name: Grunt
+ if: ${{ always() }}
+ run: moodle-plugin-ci grunt --max-lint-warnings 0
+
+ - name: PHPUnit tests
+ if: ${{ always() }}
+ run: moodle-plugin-ci phpunit --fail-on-warning
diff --git a/.github/workflows/test_docs.yaml b/.github/workflows/test_docs.yaml
new file mode 100644
index 00000000..6637377f
--- /dev/null
+++ b/.github/workflows/test_docs.yaml
@@ -0,0 +1,28 @@
+name: API Doc Parsing
+
+on:
+ pull_request:
+ types:
+ - opened
+ - synchronize
+ branches:
+ - LP-55-Backend-Refactor # Temporary. Will be changed to `main` when refactor is complete
+
+jobs:
+ generate-api-docs:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repo
+ uses: actions/checkout@v3
+ with:
+ path: moodle
+
+ - name: Setup Python
+ uses: actions/setup-python@v4.7.1
+ with:
+ python-version: '3.12'
+
+ - name: Generate docs
+ working-directory: moodle
+ run: python document_services.py -
diff --git a/.gitignore b/.gitignore
index f7c27e56..b1203584 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
moodle
*.zip
lbplanner.dart/test/env.dart
+example
+.idea
\ No newline at end of file
diff --git a/.kateproject b/.kateproject
new file mode 100644
index 00000000..b9ffc1c6
--- /dev/null
+++ b/.kateproject
@@ -0,0 +1,9 @@
+{
+ "lspclient": {
+ "servers": {
+ "php" : {
+ "root": "../moodle/"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/document_services.py b/document_services.py
new file mode 100644
index 00000000..a694ac94
--- /dev/null
+++ b/document_services.py
@@ -0,0 +1,461 @@
+import json
+import re
+import sys
+from os import path
+import traceback as tb
+
+from typing import Any
+
+# https://regex101.com/r/kgCV7K
+MOODLESTRUCT_REGEX = r"(?:['\"](\w+)['\"]\s*=>|return)\s*new\s*" \
+ r"external_value\s*\(\s*(PARAM_\w+)\s*,\s*((?:(['\"]).+?\4)(?:\s*\.\s*(?:\w+::format\(\))|'.*?')*)" \
+ r"(?:,\s*(\w+)(?:,\s*([^,]+?)(?:,\s*(\w+),?)?)?)?\s*\)"
+
+HAS_WARNED = False
+CURRENT_SERVICE: str | None = None
+
+def warn(msg: str, *context: Any):
+ """Prints a warning message to the console and sets the global HAS_WARNED variable to True.
+
+ :param str msg: The warning message to print.
+ """
+ global HAS_WARNED
+ WARN = "\033[43m\033[30mWARN:\033[0m "
+ WARN_TAB = " \033[43m\033[33m|\033[0m "
+
+ HAS_WARNED = True
+
+ stack = tb.extract_stack()
+ stack_str = " -> ".join([f"\033[34m{frame.name}\033[0m" for frame in stack if frame != stack[-1]])
+
+ service_msg: str
+ if CURRENT_SERVICE is None:
+ service_msg = "outside any service"
+ else:
+ service_msg = f"in service \033[36m{CURRENT_SERVICE}\033[0m"
+
+ print(
+ f"{WARN}\033[31m{msg}\033[0m {service_msg} ({stack_str})",
+ f"\n{WARN_TAB} " if len(context) > 0 else "",
+ *[f"\033[2m{c}\033[0m".replace('\n', '\n\033[0m' + WARN_TAB + " \033[2m") for c in context],
+ file=sys.stderr,
+ sep=""
+ )
+
+def convert_php_type_to_normal_type(param_type: str) -> str:
+ CONVERSIONS = {
+ "PARAM_INT": "int",
+ "PARAM_TEXT": "String",
+ "PARAM_URL": "String",
+ "PARAM_BOOL": "bool",
+ }
+
+ return CONVERSIONS.get(param_type, param_type)
+
+def explain_php_value(val: str) -> tuple[None | str | int | bool, str]:
+ SPECIAL_VALUES = {
+ "$USER->id": ("derived from token", "int"), # this exact phrase is checked for in the web UI
+ "null": (None, "")
+ }
+
+ if val in SPECIAL_VALUES.keys():
+ return SPECIAL_VALUES[val]
+ elif val.isnumeric():
+ return (int(val), "int")
+ elif val.lower() in ("true", "false"):
+ return (val.lower() == "true", "bool")
+ elif val[0] + val[-1] in ("''", '""'):
+
+ # see if the same kind of quote is within string
+ if val[1:-1].count(val[0]) > 0:
+ warn("found potentially non-literal string", val)
+
+ return (val[1:-1], "String")
+ else:
+ warn("found unknown value", val)
+ return (f"unknown: {val}", "unknown")
+
+def parse_isrequired(inpot: str) -> bool | None:
+ if inpot in ('VALUE_REQUIRED', ''):
+ return True
+ elif inpot == 'VALUE_DEFAULT':
+ return False
+ else:
+ warn("found unparseable value for isrequired", inpot)
+ return None
+
+def parse_nullable(inpot: str) -> bool | None:
+ if inpot in ('', 'NULL_NOT_ALLOWED'):
+ return False
+ elif inpot == 'NULL_ALLOWED':
+ return True
+ else:
+ warn(f"found weird value for nullable: {inpot}")
+ return None
+
+class SlotsDict:
+ @property
+ def __dict__(self):
+ slots = tuple()
+
+ for cls in self.__class__.__mro__:
+ if cls != SlotsDict and issubclass(cls, SlotsDict):
+ slots = cls.__slots__ + slots
+ return {name: self.__getattribute__(name) for name in slots}
+
+class ReturnInfo(SlotsDict):
+ __slots__ = ('type', 'description', 'nullable')
+
+ def __init__(self, type: str, description: str, nullable: str):
+ self.type = convert_php_type_to_normal_type(type)
+ self.description = description
+ self.nullable = parse_nullable(nullable)
+
+class ParamInfo(SlotsDict):
+ __slots__ = ('type', 'description', 'required', 'default_value', 'nullable')
+
+ def __init__(self,
+ type: str,
+ description: str,
+ required: str,
+ default_value: str,
+ nullable: str):
+
+ self.type = convert_php_type_to_normal_type(type)
+
+ defval, deftype = explain_php_value(default_value)
+ if defval is not None and deftype != self.type:
+ warn(f"Type of default value does not match parameter type - {deftype} != {self.type}", description)
+
+ self.description = description
+ self.required = parse_isrequired(required)
+ self.default_value = defval
+ self.nullable = parse_nullable(nullable)
+
+class FunctionInfo(SlotsDict):
+ __slots__ = ('name', 'group', 'capabilities', 'description', 'path')
+
+ def __init__(self, name: str, group: str, capabilities: list[str], description: str, path: str):
+ self.name = name
+ self.group = group
+ self.capabilities = capabilities
+ self.description = description
+ self.path = path
+
+class FunctionInfoEx(FunctionInfo):
+ __slots__ = ('parameters', 'returns', 'returns_multiple')
+
+ def __init__(self,
+ parent: FunctionInfo,
+ parameters: dict[str, ParamInfo],
+ returns: dict[str, ReturnInfo],
+ returns_multiple: bool):
+ super().__init__(**parent.__dict__)
+
+ self.parameters = parameters
+ self.returns = returns
+ self.returns_multiple = returns_multiple
+
+def extract_function_info(file_content: str) -> list[FunctionInfo]:
+ function_info = []
+
+ # Removing comments, PHP tags, and definitions
+ clean_content = re.sub(r"//.*|<\?php|defined\(.*\)\s*\|\|\s*die\(\);", "", file_content)
+
+ # Splitting the content based on function definition blocks
+ # https://regex101.com/r/qyzYks
+ functions = re.findall(r"'(local_lbplanner_(\w+?)_(\w+))' => \[(.*?)\],", clean_content, re.DOTALL)
+
+ for function in functions:
+ func_dict = {}
+
+ # Extracting function name and group
+ func_dict["name"] = function[2]
+ func_dict["group"] = function[1]
+
+ # Extracting and adjusting capabilities
+ capabilities = re.search(r"'capabilities' => '(.*?:.*?)'", function[3])
+ if capabilities is None:
+ # check if call needs no capabilities
+ capabilities = re.search(r"'capabilities' => ''", function[3])
+ func_dict["capabilities"] = [] if capabilities else None
+ else:
+ func_dict["capabilities"] = [cap.strip() for cap in capabilities.group(1).split(',') if len(cap) > 0]
+
+ # Extracting description
+ description = re.search(r"'description' => '(.*?)'", function[3])
+ func_dict["description"] = description.group(1) if description else None
+
+ # Extracting and adjusting path
+ classpath = re.search(r"'classpath' => 'local/(.*?)'", function[3])
+ func_dict["path"] = classpath.group(1) if classpath else None
+
+ # Only adding to the list if all information is present
+ if all(value is not None for value in func_dict.values()):
+ function_info.append(FunctionInfo(**func_dict))
+ else:
+ warn(f"Could not gather all info for {func_dict["name"]}", func_dict)
+
+ if len(function_info) == 0:
+ warn("Couldn't find any functions!")
+
+ return function_info
+
+
+def extract_php_functions(php_code: str, name: str) -> tuple[str | None, str | None]:
+ # Regular expression to match the function names and bodies
+ # https://regex101.com/r/9GtIMA
+ pattern = re.compile(r"(public static function (\w+_(?:returns|parameters))\W[^{}]*?{[^{}]+?})", re.DOTALL)
+
+ # Find all matches in the PHP code
+ matches: list[tuple[str, str]] = pattern.findall(php_code)
+
+ parameters_function = None
+ returns_function = None
+
+ for match in matches:
+ # Extract function name
+ function_name = match[1]
+
+ if function_name.endswith("_parameters"):
+ parameters_function = match[0]
+ elif function_name.endswith("_returns"):
+ returns_function = match[0]
+
+ if parameters_function is None:
+ warn(f"Couldn't find parameters function in {name}")
+ if returns_function is None:
+ warn(f"Couldn't find returns function in {name}")
+
+ return parameters_function, returns_function
+
+def parse_imports(input_str: str, symbol: str) -> str | None:
+ use_pattern = fr"use ((?:\w+\\)+){symbol};"
+ uses: list[str] = re.findall(use_pattern, input_str)
+
+ namespaces = { # it's technically possible to import from outside /classes/
+ "local_lbplanner\\helpers": "classes/helpers",
+ "local_lbplanner\\enums": "classes/enums",
+ "local_lbplanner\\polyfill": "classes/polyfill",
+ "local_lbplanner\\model": "classes/model",
+ }
+ fp_l: list[str] = []
+ for use in uses:
+ for namespace, p in namespaces.items():
+ if use.startswith(namespace):
+ fp_l.append(path.join(path.dirname(__file__), "lbplanner", p, f"{symbol}.php"))
+
+ if len(fp_l) > 1:
+ warn(f"found potential import collision for {symbol}", input_str)
+ return None
+ elif len(fp_l) == 0:
+ warn(f"Couldn't find symbol: {symbol}", input_str)
+ return None
+ else:
+ return fp_l[0]
+
+def parse_phpstuff(inpot: str) -> str:
+ # https://regex101.com/r/p5FzCh
+ casepattern = r"const (\w+) = (\d+|true|false|(['\"]).*?\3)"
+
+ if inpot.endswith('::format()'):
+ enum_name = inpot[:-10]
+ fullbody_pattern = f"class {enum_name} extends Enum {{.*?}}"
+
+ fp = f"lbplanner/classes/enums/{enum_name}.php"
+ if not path.exists(fp):
+ warn(f"Couldn't find enum file {fp}")
+ return ""
+ with open(fp, "r") as f:
+ matches: list[str] = re.findall(fullbody_pattern, f.read(), re.DOTALL)
+ if len(matches) == 1:
+ body = matches[0]
+ else:
+ warn(f"couldn't parse enum {enum_name}", matches)
+
+ cases = {}
+ matches = re.findall(casepattern, body)
+ for match in matches:
+ # capitalizing first letter, if exists
+ name = "".join([match[0][0].upper(), match[0][1:].lower()])
+ cases[name] = match[1].replace("'", '"')
+
+ return "{ " + ", ".join([f"{name} = {value}" for name, value in cases.items()]) + " }"
+ else:
+ warn('unknown phpstuff', inpot)
+ return ""
+
+def parse_phpstring(inpot: str) -> str:
+ WHITESPACE = '. \t\n\r' # the . is for string concat in php
+
+ out = []
+ strlit = False
+ quotetype = ''
+ tmp_refarr: list[str] = []
+ for char in inpot:
+ if char in '\'"':
+ if not strlit:
+ strlit = True
+ quotetype = char
+ if len(tmp_refarr) > 0:
+ out.append(parse_phpstuff("".join(tmp_refarr)))
+ tmp_refarr = []
+ else:
+ if char == quotetype:
+ strlit = False
+ else:
+ out.append(char)
+ else:
+ if strlit:
+ out.append(char)
+ else:
+ if char in WHITESPACE:
+ continue
+ else:
+ tmp_refarr.append(char)
+
+ if len(tmp_refarr) > 0:
+ out.append(parse_phpstuff("".join(tmp_refarr)))
+ tmp_refarr = []
+
+ return "".join(out)
+
+def parse_returns(input_str: str, file_content: str, name: str) -> tuple[dict[str, ReturnInfo], bool]:
+ # https://regex101.com/r/gUtsX3/
+ redir_pattern = r"(\w+)::(\w+)(? 1:
+ warn(f"Couldn't parse return values in {name}", input_str)
+ return ({}, False)
+
+ if len(redir_matches) == 1:
+ match = redir_matches[0]
+ meth_pattern = rf"public static function {match[1]}\(\)(?: ?: ?\w+)? ?{{(?P
.*?)}}"
+
+ fp = parse_imports(file_content, match[0])
+ if fp is None:
+ # already warned in parse_imports, we don't need to warn again
+ return {}, is_multiple_structure
+
+ with open(fp, "r") as f:
+ new_file_content = f.read()
+ meth_matches: list[str] = re.findall(meth_pattern, new_file_content, re.DOTALL)
+ if len(meth_matches) == 0:
+ warn(f"Couldn't find {match[0]}::{match[1]}() inside {fp} for {name}")
+ return ({}, False)
+ elif len(meth_matches) > 1:
+ raise Exception(f"Found multiple definitions for {match[0]}::{match[1]}() inside {fp}")
+ else:
+ result = parse_returns(meth_matches[0], new_file_content, fp)
+
+ # if multiple_structure is detected here, add it
+ if is_multiple_structure:
+ return (result[0], True)
+ else:
+ return result
+
+ matches: list[list[str]] = re.findall(MOODLESTRUCT_REGEX, input_str)
+
+ output_dict = {}
+ for match in matches:
+ key = match[0]
+ if key is None:
+ if len(matches) > 1:
+ warn("got empty return key name in a structure larger than 1", matches)
+ else:
+ key = ''
+
+ if not parse_isrequired(match[4]):
+ warn(f"found optional value in returns structure for {name}", input_str)
+
+ default_str = match[5]
+ if default_str not in ('null', ''):
+ warn(f"found non-null 'default value' in returns structure for {name}: {default_str}", input_str)
+
+ output_dict[key] = ReturnInfo(match[1], parse_phpstring(match[2]), match[6])
+
+ if len(output_dict) == 0:
+ if re.match(nullensure_pattern, input_str) is None:
+ warn(f"could not find any returns in non-empty {name}", input_str)
+
+ return output_dict, is_multiple_structure
+
+def parse_params(input_text: str) -> dict[str, ParamInfo]:
+ # Regular expression to match the parameters inside the 'new external_value()' function
+
+ # Find all matches of the pattern in the input text
+ matches: list[list[str]] = re.findall(MOODLESTRUCT_REGEX, input_text)
+
+ if len(matches) == 0:
+ nullensure_pattern = r".*return new external_function_parameters(\s*\[\]\s*);.*"
+ if re.match(nullensure_pattern, input_text) is not None:
+ warn("could not parse params", input_text)
+ return {}
+
+ result = {}
+ for match in matches:
+ param_name = match[0]
+ result[param_name] = ParamInfo(
+ match[1],
+ parse_phpstring(match[2]),
+ match[4],
+ match[5],
+ match[6],
+ )
+
+ return result
+
+
+if __name__ == "__main__":
+ with open("lbplanner/db/services.php", "r") as file:
+ content = file.read()
+ infos = extract_function_info(content)
+
+ complete_info = []
+
+ for i, info in enumerate(infos):
+
+ CURRENT_SERVICE = info.name
+
+ with open(info.path, "r") as func_file:
+ func_content = func_file.read()
+ params_func, returns_func = extract_php_functions(func_content, info.path)
+
+ if returns_func is None or params_func is None:
+ continue
+
+ returns, returns_multiple = parse_returns(returns_func, func_content, info.path)
+
+ params = parse_params(params_func)
+
+ complete_info.append(FunctionInfoEx(info, params, returns, returns_multiple))
+
+ CURRENT_SERVICE = None
+
+ data = json.dumps(complete_info, default=lambda x: x.__dict__)
+
+ if sys.argv[1] == "-":
+ print(data)
+ else:
+ declaration = f"const funcs = {data}"
+
+ script: str
+ with open(f"{sys.argv[1]}/script.js", "r") as f:
+ script = f.read()
+ lines = script.splitlines()
+ for i in range(len(lines)):
+ if lines[i].startswith('const funcs = '):
+ lines[i] = declaration
+ script = "\n".join(lines)
+
+ with open(f"{sys.argv[1]}/script.js", "w") as f:
+ f.write(script)
+
+ if HAS_WARNED:
+ sys.exit(1)
diff --git a/lbplanner/classes/enums/CAPABILITY.php b/lbplanner/classes/enums/CAPABILITY.php
new file mode 100644
index 00000000..22e44a83
--- /dev/null
+++ b/lbplanner/classes/enums/CAPABILITY.php
@@ -0,0 +1,67 @@
+.
+
+/**
+ * capability string
+ *
+ * @package local_lbplanner
+ * @subpackage enums
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\enums;
+
+// TODO: revert to native enums once we migrate to php8.
+
+use local_lbplanner\polyfill\Enum;
+use local_lbplanner\enums\CAPABILITY_FLAG;
+
+/**
+ * Capabilities a user can have
+ */
+class CAPABILITY extends Enum {
+ /**
+ * Shortname of the admin CAPABILITY.
+ */
+ const ADMIN = 'local/lb_planner:admin';
+
+ /**
+ * Shortname of the manager CAPABILITY.
+ */
+ const MANAGER = 'local/lb_planner:manager';
+
+ /**
+ * Shortname of the teacher CAPABILITY.
+ */
+ const TEACHER = 'local/lb_planner:teacher';
+
+ /**
+ * Shortname of the student CAPABILITY.
+ */
+ const STUDENT = 'local/lb_planner:student';
+
+ /**
+ * Matches a capability string to its bitmappable flag
+ * @param string $str the capability string
+ * @return int the bitmappable flag
+ * @link CAPABILITY_FLAG
+ */
+ public static function to_capability(string $str): int {
+ $name = self::name_from($str);
+ return constant('CAPABILITY_FLAG::'.$name);
+ }
+}
diff --git a/lbplanner/classes/enums/CAPABILITY_FLAG.php b/lbplanner/classes/enums/CAPABILITY_FLAG.php
new file mode 100644
index 00000000..5419ebf5
--- /dev/null
+++ b/lbplanner/classes/enums/CAPABILITY_FLAG.php
@@ -0,0 +1,67 @@
+.
+
+/**
+ * capability string
+ *
+ * @package local_lbplanner
+ * @subpackage enums
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\enums;
+
+// TODO: revert to native enums once we migrate to php8.
+
+use local_lbplanner\polyfill\Enum;
+use local_lbplanner\enums\CAPABILITY;
+
+/**
+ * Bitmappable flags for capabilities a user can have
+ */
+class CAPABILITY_FLAG extends Enum {
+ /**
+ * Flag of the admin CAPABILITY.
+ */
+ const ADMIN = 1;
+
+ /**
+ * Flag of the manager CAPABILITY.
+ */
+ const MANAGER = 2;
+
+ /**
+ * Flag of the teacher CAPABILITY.
+ */
+ const TEACHER = 4;
+
+ /**
+ * Flag of the student CAPABILITY.
+ */
+ const STUDENT = 8;
+
+ /**
+ * matches a flag to its capability string
+ * @param int $num the bitmappable flag
+ * @return string the capability string
+ * @link CAPABILITY
+ */
+ public static function to_capability(int $num): string {
+ $name = self::name_from($num);
+ return constant('CAPABILITY::'.$name);
+ }
+}
diff --git a/lbplanner/classes/enums/MODULE_GRADE.php b/lbplanner/classes/enums/MODULE_GRADE.php
new file mode 100644
index 00000000..20714e9a
--- /dev/null
+++ b/lbplanner/classes/enums/MODULE_GRADE.php
@@ -0,0 +1,56 @@
+.
+
+/**
+ * enum for module grade
+ *
+ * @package local_lbplanner
+ * @subpackage enums
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\enums;
+
+// TODO: revert to native enums once we migrate to php8.
+
+use local_lbplanner\polyfill\Enum;
+
+/**
+ * Grades a module can receive
+ */
+class MODULE_GRADE extends Enum {
+ /**
+ * Erweiterte Kompetenz vollständig.
+ */
+ const EKV = 0;
+ /**
+ * Erweiterte Kompetenz überwiegend.
+ */
+ const EK = 1;
+ /**
+ * Grundlegende Kompetenz vollständig.
+ */
+ const GKV = 2;
+ /**
+ * Grundlegende Kompetenz überwiegend.
+ */
+ const GK = 3;
+ /**
+ * Negative grade.
+ */
+ const RIP = 4;
+}
diff --git a/lbplanner/classes/enums/MODULE_STATUS.php b/lbplanner/classes/enums/MODULE_STATUS.php
new file mode 100644
index 00000000..6d78ea59
--- /dev/null
+++ b/lbplanner/classes/enums/MODULE_STATUS.php
@@ -0,0 +1,52 @@
+.
+
+/**
+ * enum for module status
+ *
+ * @package local_lbplanner
+ * @subpackage enums
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\enums;
+
+// TODO: revert to native enums once we migrate to php8.
+
+use local_lbplanner\polyfill\Enum;
+
+/**
+ * Stati a module can be in
+ */
+class MODULE_STATUS extends Enum {
+ /**
+ * Finished module.
+ */
+ const DONE = 0;
+ /**
+ * Uploaded module.
+ */
+ const UPLOADED = 1;
+ /**
+ * Overdue module.
+ */
+ const LATE = 2;
+ /**
+ * Todo module.
+ */
+ const PENDING = 3;
+}
diff --git a/lbplanner/classes/enums/MODULE_TYPE.php b/lbplanner/classes/enums/MODULE_TYPE.php
new file mode 100644
index 00000000..6eb68d2f
--- /dev/null
+++ b/lbplanner/classes/enums/MODULE_TYPE.php
@@ -0,0 +1,56 @@
+.
+
+/**
+ * enum for module type
+ *
+ * @package local_lbplanner
+ * @subpackage enums
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\enums;
+
+// TODO: revert to native enums once we migrate to php8.
+
+use local_lbplanner\polyfill\Enum;
+
+/**
+ * Module Types
+ */
+class MODULE_TYPE extends Enum {
+ /**
+ * Grundlegende Kompetenz.
+ */
+ const GK = 0;
+ /**
+ * Erweiterte Kompetenz.
+ */
+ const EK = 1;
+ /**
+ * Test i.e. exam.
+ */
+ const TEST = 2;
+ /**
+ * TODO: ???
+ */
+ const M = 3;
+ /**
+ * TODO: ???
+ */
+ const NONE = 4;
+}
diff --git a/lbplanner/classes/enums/NOTIF_STATUS.php b/lbplanner/classes/enums/NOTIF_STATUS.php
new file mode 100644
index 00000000..25818738
--- /dev/null
+++ b/lbplanner/classes/enums/NOTIF_STATUS.php
@@ -0,0 +1,44 @@
+.
+
+/**
+ * enum for notif status
+ *
+ * @package local_lbplanner
+ * @subpackage enums
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\enums;
+
+// TODO: revert to native enums once we migrate to php8.
+
+use local_lbplanner\polyfill\Enum;
+
+/**
+ * Stati a notification can be in
+ */
+class NOTIF_STATUS extends Enum {
+ /**
+ * unread notification
+ */
+ const UNREAD = 0;
+ /**
+ * read notification
+ */
+ const READ = 1;
+}
diff --git a/lbplanner/classes/enums/NOTIF_TRIGGER.php b/lbplanner/classes/enums/NOTIF_TRIGGER.php
new file mode 100644
index 00000000..cfdf2c17
--- /dev/null
+++ b/lbplanner/classes/enums/NOTIF_TRIGGER.php
@@ -0,0 +1,68 @@
+.
+
+/**
+ * enum for notif trigger
+ *
+ * @package local_lbplanner
+ * @subpackage enums
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\enums;
+
+// TODO: revert to native enums once we migrate to php8.
+
+use local_lbplanner\polyfill\Enum;
+
+/**
+ * Possible triggers for sending a notification
+ */
+class NOTIF_TRIGGER extends Enum {
+ /**
+ * Invitation sent
+ */
+ const INVITE = 0;
+ /**
+ * Invitation accepted
+ */
+ const INVITE_ACCEPTED = 1;
+ /**
+ * Invitation declined
+ */
+ const INVITE_DECLINED = 2;
+ /**
+ * User left the plan
+ */
+ const PLAN_LEFT = 3;
+ /**
+ * User got removed from the plan
+ */
+ const PLAN_REMOVED = 4;
+ /**
+ * User registered
+ */
+ const USER_REGISTERED = 5;
+ /**
+ * Unbook requested by supervisor
+ */
+ const UNBOOK_REQUESTED = 6;
+ /**
+ * Unbook forced by supervisor
+ */
+ const UNBOOK_FORCED = 7;
+}
diff --git a/lbplanner/classes/enums/PLAN_ACCESS_TYPE.php b/lbplanner/classes/enums/PLAN_ACCESS_TYPE.php
new file mode 100644
index 00000000..71ad83cb
--- /dev/null
+++ b/lbplanner/classes/enums/PLAN_ACCESS_TYPE.php
@@ -0,0 +1,52 @@
+.
+
+/**
+ * enum for plan access type
+ *
+ * @package local_lbplanner
+ * @subpackage enums
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\enums;
+
+// TODO: revert to native enums once we migrate to php8.
+
+use local_lbplanner\polyfill\Enum;
+
+/**
+ * Levels of access that a user can have for a plan
+ */
+class PLAN_ACCESS_TYPE extends Enum {
+ /**
+ * owning the plan
+ */
+ const OWNER = 0;
+ /**
+ * allowed to modify the plan
+ */
+ const WRITE = 1;
+ /**
+ * allowed to look at the plan
+ */
+ const READ = 2;
+ /**
+ * disallowed
+ */
+ const NONE = -1;
+}
diff --git a/lbplanner/classes/enums/PLAN_EK.php b/lbplanner/classes/enums/PLAN_EK.php
new file mode 100644
index 00000000..a14b7de2
--- /dev/null
+++ b/lbplanner/classes/enums/PLAN_EK.php
@@ -0,0 +1,44 @@
+.
+
+/**
+ * enum for plan EK
+ *
+ * @package local_lbplanner
+ * @subpackage enums
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\enums;
+
+// TODO: revert to native enums once we migrate to php8.
+
+use local_lbplanner\polyfill\Enum;
+
+/**
+ * Whether EK modules are enabled inside the planner
+ */
+class PLAN_EK extends Enum {
+ /**
+ * EK hidden
+ */
+ const DISABLED = 0;
+ /**
+ * EK visible
+ */
+ const ENABLED = 1;
+}
diff --git a/lbplanner/classes/enums/PLAN_INVITE_STATE.php b/lbplanner/classes/enums/PLAN_INVITE_STATE.php
new file mode 100644
index 00000000..f039479d
--- /dev/null
+++ b/lbplanner/classes/enums/PLAN_INVITE_STATE.php
@@ -0,0 +1,52 @@
+.
+
+/**
+ * enum for plan invite state
+ *
+ * @package local_lbplanner
+ * @subpackage enums
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\enums;
+
+// TODO: revert to native enums once we migrate to php8.
+
+use local_lbplanner\polyfill\Enum;
+
+/**
+ * States an invite can be in
+ */
+class PLAN_INVITE_STATE extends Enum {
+ /**
+ * pending invite
+ */
+ const PENDING = 0;
+ /**
+ * accepted invite
+ */
+ const ACCEPTED = 1;
+ /**
+ * declined invite
+ */
+ const DECLINED = 2;
+ /**
+ * expired invite
+ */
+ const EXPIRED = 3;
+}
diff --git a/lbplanner/classes/enums/WEEKDAY.php b/lbplanner/classes/enums/WEEKDAY.php
new file mode 100644
index 00000000..407c409d
--- /dev/null
+++ b/lbplanner/classes/enums/WEEKDAY.php
@@ -0,0 +1,67 @@
+.
+
+/**
+ * enum for weekdays
+ * (cringe, ik, but we need these defined concretely)
+ *
+ * @package local_lbplanner
+ * @subpackage enums
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\enums;
+
+// TODO: revert to native enums once we migrate to php8.
+
+use local_lbplanner\polyfill\Enum;
+
+/**
+ * All the days of the week.
+ * All seven of them.
+ * Yup.
+ */
+class WEEKDAY extends Enum {
+ /**
+ * monday
+ */
+ const MONDAY = 1;
+ /**
+ * tuesday
+ */
+ const TUESDAY = 2;
+ /**
+ * wednesday
+ */
+ const WEDNESDAY = 3;
+ /**
+ * thursday
+ */
+ const THURSDAY = 4;
+ /**
+ * friday
+ */
+ const FRIDAY = 5;
+ /**
+ * saturday
+ */
+ const SATURDAY = 6;
+ /**
+ * sunday
+ */
+ const SUNDAY = 7;
+}
diff --git a/lbplanner/classes/helpers/config_helper.php b/lbplanner/classes/helpers/config_helper.php
index e64fd382..57c65be4 100644
--- a/lbplanner/classes/helpers/config_helper.php
+++ b/lbplanner/classes/helpers/config_helper.php
@@ -16,27 +16,100 @@
namespace local_lbplanner\helpers;
+use core_component;
+use core_customfield\category_controller;
+use customfield_select\field_controller;
+use local_modcustomfields\customfield\mod_handler;
+
+/**
+ * Helper class for config
+ *
+ * @package local_lbplanner
+ * @subpackage helpers
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
class config_helper {
+ /**
+ * Sets the current active year
+ */
public static function set_default_active_year() {
$currentmonth = idate('m');
+ $currentyear = idate('Y') % 100;
+ $lastyear = $currentyear - 1;
+ $nextyear = $currentyear + 1;
+ // Adding the default active year, when the plugin is installed for the first time.
+ // If the current month is between August and December, the default active year is set to current year and the next year.
if ($currentmonth >= 8 && $currentmonth <= 12) {
- // Adding the default active year, when the plugin is installed for the first time.
set_config(
'defaultactiveyear',
- substr(strval(idate('Y')), 2)
- .'/'.
- substr(strval(idate('Y') + 1), 2),
+ $currentyear . '/' . $nextyear,
'local_lbplanner'
);
+ // If the current month is between January and July, the default active year is set to the previous year and the
+ // current year.
} else {
- // Adding the default active year, when the plugin is installed for the first time.
set_config(
'defaultactiveyear',
- substr(strval(idate('Y') - 1), 2)
- .'/'.
- substr(strval(idate('Y')), 2),
+ $lastyear . '/' . $currentyear,
'local_lbplanner'
);
}
}
+
+ /**
+ * Adds a customfield to moodle for each activity where teachers can select GK EK or both.
+ *
+ * Default value is GK.
+ * @throws \coding_exception
+ * @throws \moodle_exception
+ * @throws \coding_exception
+ */
+ public static function add_customfield(): void {
+ // Check if the category is already created and only create it if it doesn't exist.
+ // Check if plugin "modcustomfields" is installed and create the category and the custom field.
+ if (!get_config('local_lbplanner', 'categoryid')) {
+
+ if (array_key_exists('modcustomfields', core_component::get_plugin_list('local'))) {
+
+ $handler = mod_handler::create();
+ $categoryid = $handler->create_category('LB Planner');
+
+ set_config('categoryid', $categoryid, 'local_lbplanner');
+ $categorycontroller = category_controller::create($categoryid, null, $handler);
+ $categorycontroller->save();
+
+ // Dont ask me why but moodle doesnt allow me to just insert the String "select" into the type field.
+ $record = new \stdClass();
+ $record->type = 'select';
+
+ $fieldcontroller = field_controller::create(0, $record, $categorycontroller);
+ // Added the default attributes for the custom field.
+ $fieldcontroller->set('name', 'LB Planner Task Type');
+ $fieldcontroller->set('description', 'Tracks whether the task is GK/EK/GKandEK/TEST/SA/M');
+ $fieldcontroller->set('type', 'select');
+ // Because moodle wants me to save the configdata as a json string, I have to do this.
+ // I don't know why moodle does this, but it does. I don't like it. but I have to do it. so I do it.
+ $fieldcontroller->set(
+ 'configdata',
+ '{"required":"1","uniquevalues":"0","options":"GK\r\nEK\r\nGK and EK\r\nTEST\r\nSA\r\nM",
+ "defaultvalue":"GK","locked":"0","visibility":"2"}'
+ );
+ $fieldcontroller->set('shortname', 'lb_planner_gk_ek');
+ $fieldcontroller->save();
+ }
+ }
+ }
+
+ /**
+ * Get the category id from the config
+ * @return int the category id if it is set, -1 otherwise
+ */
+ public static function get_category_id(): int {
+ if (!get_config('local_lbplanner', 'categoryid')) {
+ return -1;
+ } else {
+ return intval(get_config('local_lbplanner', 'categoryid'));
+ }
+ }
}
diff --git a/lbplanner/classes/helpers/course_helper.php b/lbplanner/classes/helpers/course_helper.php
index 78927bcf..dfce13c3 100644
--- a/lbplanner/classes/helpers/course_helper.php
+++ b/lbplanner/classes/helpers/course_helper.php
@@ -16,160 +16,157 @@
namespace local_lbplanner\helpers;
-use stdClass;
-
+use context_course;
+use dml_exception;
+
+use local_lbplanner\model\course;
+
+/**
+ * Helper class for courses
+ *
+ * @package local_lbplanner
+ * @subpackage helpers
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
class course_helper {
-
-
- /**
- * Name of the Enrol Table
- */
- const ENROL_TABLE = 'enrol';
-
- /**
- * Name of the User Enroll Table
- */
- const USER_ENROL_TABLE = 'user_enrolments';
-
- /**
- * Name of the Course Table
- */
- const COURSE_TABLE = 'course';
-
/**
- * Name of the Category Table
+ * The course table used by the LP
*/
- const CATEGORY_TABLE = 'course_categories';
-
const LBPLANNER_COURSE_TABLE = 'local_lbplanner_courses';
- const COLORS = array(
- "#f50057",
- "#536dfe",
- "#f9a826",
- "#00bfa6",
- "#9b59b6",
- "#37bbca",
- "#e67e22",
- "#37CA48",
- "#CA3737",
- "#B5CA37",
- "#37CA9E",
- "#3792CA",
- "#376ECA",
- "#8B37CA",
- "#CA37B9",
- );
-
- const DISABLED_COURSE = 0;
- const ENABLED_COURSE = 1;
-
/**
- * Get all the courses of the user
- * @param int userid The id of the user
- *
- * @return array of EnrollIds
+ * A list of nice colors to choose from :)
*/
- public static function get_enrollments(int $userid) {
- global $DB;
- $enrollments = array();
- $records = $DB->get_records(self::USER_ENROL_TABLE, array ('userid' => $userid));
- foreach ($records as $record) {
- if (in_array($record->enrolid, $enrollments) === false) {
- $enrollments[] = $record->enrolid;
- }
- }
- return $enrollments;
- }
+ const COLORS
+ = [
+ "#f50057",
+ "#536dfe",
+ "#f9a826",
+ "#00bfa6",
+ "#9b59b6",
+ "#37bbca",
+ "#e67e22",
+ "#37CA48",
+ "#CA3737",
+ "#B5CA37",
+ "#37CA9E",
+ "#3792CA",
+ "#376ECA",
+ "#8B37CA",
+ "#CA37B9",
+ ];
/**
- * Get the current year
+ * Get the current school year from the config
+ * Definition of a school year: 2020/2021
+ * Check in config_helper.php for more info how the date is set for defaultactiveyear
*
- * @return string the current year the last 2 digits (20(20))
+ * @return string the current year the last 2 digits (20/20)
+ * @throws dml_exception
*/
- public static function get_current_year() : string {
- if (strpos(get_config('local_lbplanner', 'activeyear'), '/' ) !== false) {
+ public static function get_current_year(): string {
+ if (strpos(get_config('local_lbplanner', 'activeyear'), '/') !== false) {
return get_config('local_lbplanner', 'activeyear');
}
return get_config('local_lbplanner', 'defaultactiveyear');
}
/**
- * Get the current category id
+ * Get course from lbpanner DB
*
- * @return int id of the current category
- */
- public static function get_current_category() : int {
- global $DB;
-
- return $DB->get_record_sql(
- 'SELECT id FROM ' . self::CATEGORY_TABLE . ' WHERE name LIKE "%' . self::get_current_year() . '%"'
- );
- }
- /**
- * Get course from mdl DB
+ * @param int $courseid id of the course in lbplanner
+ * @param int $userid id of the user
*
- * @param int $courseid id of the course
- * @return stdClass course from moodle
+ * @return course course from lbplanner
+ * @throws dml_exception
*/
- public static function get_mdl_course($courseid) : stdClass {
+ public static function get_lbplanner_course(int $courseid, int $userid): course {
global $DB;
- return $DB->get_record(self::COURSE_TABLE, array('id' => $courseid));
+ return course::from_db($DB->get_record(self::LBPLANNER_COURSE_TABLE, ['courseid' => $courseid, 'userid' => $userid]));
}
+
/**
- * Get course from lbpanner DB
- *
- * @param int $courseid id of the course in lbplanner
- * @return stdClass course from lbplanner
+ * Get all the courses of the current year.
+ * @return course[] all courses of the current year
*/
- public static function get_lbplanner_course($courseid, $userid) : stdClass {
- global $DB;
- return $DB->get_record(self::LBPLANNER_COURSE_TABLE, array('courseid' => $courseid, 'userid' => $userid));
+ public static function get_all_lbplanner_courses(): array {
+ global $DB, $USER;
+ $userid = $USER->id;
+
+ $mdlcourses = enrol_get_my_courses();
+ // Remove Duplicates.
+ $mdlcourses = array_unique($mdlcourses, SORT_REGULAR);
+ // Check this out: https://www.youtube.com/watch?v=WmdAk2zyQkU .
+ $results = [];
+
+ foreach ($mdlcourses as $mdlcourse) {
+ $courseid = $mdlcourse->id;
+ // Check if the course is from the current year.
+ // TODO: pass fullname to function instead of courseid.
+ if (!self::check_current_year($courseid)) {
+ continue;
+ }
+ // Check if the course is already in the LB Planner database.
+ if ($DB->record_exists(self::LBPLANNER_COURSE_TABLE, ['courseid' => $courseid, 'userid' => $userid])) {
+ $fetchedcourse = self::get_lbplanner_course($courseid, $userid);
+ } else {
+ // IF not create an Object to be put into the LB Planner database.
+ $fetchedcourse = new course(
+ 0, $courseid, $userid,
+ course::prepare_shortname($mdlcourse->shortname),
+ self::COLORS[array_rand(self::COLORS)],
+ false,
+ );
+ $fetchedcourse->set_fresh(
+ $DB->insert_record(
+ self::LBPLANNER_COURSE_TABLE,
+ $fetchedcourse->prepare_for_db()
+ )
+ );
+ }
+ // Add name to fetched Course.
+ $fetchedcourse->set_fullname($mdlcourse->fullname);
+ array_push($results, $fetchedcourse);
+ }
+ return $results;
}
/**
* Check if the user is enrolled in the course
*
* @param int $courseid course id
- * @param int $userid user id
+ * @param int $userid user id
+ *
* @return bool true if the user is enrolled
*/
- public static function check_access($courseid, $userid) : bool {
- global $DB;
- $enrolmentids = $DB->get_records(self::ENROL_TABLE, array('courseid' => $courseid), '', '*');
- foreach ($enrolmentids as $enrolmentid) {
- if ($DB->record_exists(self::USER_ENROL_TABLE, array('enrolid' => $enrolmentid->id, 'userid' => $userid))) {
- return true;
- }
- }
- return false;
+ public static function check_access(int $courseid, int $userid): bool {
+ $context = context_course::instance($courseid);
+ return is_enrolled($context, $userid, '', true);
}
+
/**
* gets the fullname from a course
*
* @param int $courseid the course id
+ *
* @return string the fullname of the course
+ * @throws dml_exception
*/
- public static function get_fullname($courseid) {
- global $DB;
- return $DB->get_record(self::COURSE_TABLE, array('id' => $courseid), '*', MUST_EXIST)->fullname;
+ public static function get_fullname(int $courseid): string {
+ return get_course($courseid)->fullname;
}
+
/**
* Check if the course is from the current year
*
* @param int $courseid the course id
+ *
* @return bool true if the course is from the current year
+ * @throws dml_exception
*/
- public static function check_current_year($courseid) {
- if (strpos(self::get_fullname($courseid), self::get_current_year()) !== false) {
- return true;
- } else {
- return false;
- }
- }
- public static function get_courseid($enrolmentid) {
- global $DB;
- return $DB->get_record(self::ENROL_TABLE, array('id' => $enrolmentid), '*', MUST_EXIST)->courseid;
+ public static function check_current_year(int $courseid): bool {
+ return strpos(self::get_fullname($courseid), self::get_current_year()) !== false;
}
}
diff --git a/lbplanner/classes/helpers/feedback_helper.php b/lbplanner/classes/helpers/feedback_helper.php
index ceaa739c..a6931134 100644
--- a/lbplanner/classes/helpers/feedback_helper.php
+++ b/lbplanner/classes/helpers/feedback_helper.php
@@ -19,16 +19,35 @@
use external_function_parameters;
use external_single_structure;
use external_value;
+use local_lbplanner\enums\CAPABILITY;
use stdClass;
use local_lbplanner\helpers\user_helper;
+// TODO: use enums.
+
+/**
+ * Helper class for feedback
+ *
+ * @package local_lbplanner
+ * @subpackage helpers
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
class feedback_helper {
+ /**
+ * Unread Feedback
+ */
const STATUS_UNREAD = 0;
+ /**
+ * Read Feedback
+ */
const STATUS_READ = 1;
-
+ /**
+ * The name of the table which is used by LP to store feedback in
+ */
const LBPLANNER_FEEDBACK_TABLE = 'local_lbplanner_feedback';
/**
@@ -36,9 +55,9 @@ class feedback_helper {
*
* @return external_single_structure The structure of a module.
*/
- public static function structure() : external_single_structure {
+ public static function structure(): external_single_structure {
return new external_single_structure(
- array(
+ [
'content' => new external_value(PARAM_TEXT, 'Content of the feedback'),
'userid' => new external_value(PARAM_INT, 'The id of the user'),
'type' => new external_value(PARAM_INT, 'The Type of the feedback'),
@@ -49,33 +68,41 @@ public static function structure() : external_single_structure {
'lastmodified' => new external_value(PARAM_INT, 'The time when the feedback was last modified'),
'lastmodifiedby' => new external_value(PARAM_INT, 'The id of the user who last modified the feedback'),
'logfile' => new external_value(PARAM_TEXT, 'The logs of the feedback'),
- )
+ ]
);
}
+
/**
* Gives back the feedback of the given feedbackid
*
- * @param integer $feedbackid The id of the feedback
+ * @param int $feedbackid The id of the feedback
+ *
* @return stdClass The feedback
*/
- public static function get_feedback(int $feedbackid) : stdClass {
+ public static function get_feedback(int $feedbackid): stdClass {
global $DB;
return $DB->get_record(self::LBPLANNER_FEEDBACK_TABLE, ['id' => $feedbackid]);
}
+
/**
* Checks if the user has access to feedback
*
- * @param integer $userid The id of the user
- * @return void Throws an exception if the user has no access
+ * @throws \moodle_exception when the user has no access
*/
public static function assert_admin_access() {
- if (!has_capability(user_helper::CAPABILITY_ADMIN, \context_system::instance()) &&
- !has_capability(user_helper::CAPABILITY_MANAGER, \context_system::instance())) {
+ if (!has_capability(CAPABILITY::ADMIN, \context_system::instance())
+ && !has_capability(CAPABILITY::MANAGER, \context_system::instance())
+ ) {
throw new \moodle_exception('Acces denied');
}
}
- public static function get_all_feedbacks() : array {
+ /**
+ * Returns all feedback records.
+ *
+ * @return array all feedback records
+ */
+ public static function get_all_feedbacks(): array {
global $DB;
return $DB->get_records(self::LBPLANNER_FEEDBACK_TABLE);
}
diff --git a/lbplanner/classes/helpers/invite_helper.php b/lbplanner/classes/helpers/invite_helper.php
new file mode 100644
index 00000000..184cdfe7
--- /dev/null
+++ b/lbplanner/classes/helpers/invite_helper.php
@@ -0,0 +1,49 @@
+.
+
+namespace local_lbplanner\helpers;
+
+use external_single_structure;
+use external_value;
+
+/**
+ * Helper class for plan invites
+ *
+ * @package local_lbplanner
+ * @subpackage helpers
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class invite_helper {
+
+ /**
+ * Returns the data structure of an invite.
+ *
+ * @return external_single_structure The data structure of an invite.
+ */
+ public static function structure(): external_single_structure {
+ return new external_single_structure(
+ [
+ 'id' => new external_value(PARAM_INT, 'invite ID'),
+ 'inviterid' => new external_value(PARAM_INT, 'ID of the user who issued the invitation'),
+ 'inviteeid' => new external_value(PARAM_INT, 'ID of the user who got invited'),
+ 'planid' => new external_value(PARAM_INT, 'plan ID'),
+ 'status' => new external_value(PARAM_INT, 'status of the invitation'),
+ 'timestamp' => new external_value(PARAM_INT, 'time when the invitation was send'),
+ ]
+ );
+ }
+}
diff --git a/lbplanner/classes/helpers/modules_helper.php b/lbplanner/classes/helpers/modules_helper.php
index 99cb0278..b3500e08 100644
--- a/lbplanner/classes/helpers/modules_helper.php
+++ b/lbplanner/classes/helpers/modules_helper.php
@@ -14,6 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
+/**
+ * Collection of helper classes for handling modules
+ *
+ * @package local_lbplanner
+ * @subpackage helpers
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
namespace local_lbplanner\helpers;
use block_accessreview\external\get_module_data;
@@ -21,6 +30,7 @@
use external_single_structure;
use external_value;
use moodle_url;
+use local_lbplanner\enums\{MODULE_STATUS, MODULE_GRADE, MODULE_TYPE};
/**
* Contains helper functions for working with modules.
@@ -62,109 +72,38 @@ class modules_helper {
*/
const SUBMISSION_STATUS_SUBMITTED = 'submitted';
- /**
- * Enum value for grade 'Nicht erfüllt'.
- */
- const GRADE_RIP = 4;
-
- /**
- * Enum value for grade 'GK überwiegend'.
- */
- const GRADE_GK = 3;
-
- /**
- * Enum value for grade 'GK vollständig'.
- */
- const GRADE_GKV = 2;
-
-
- /**
- * Enum value for grade 'EK überwiegend'.
- */
- const GRADE_EK = 1;
-
- /**
- * Enum value for grade 'EK vollständig'.
- */
- const GRADE_EKV = 0;
-
- /**
- * Enum value for completed module.
- */
- const STATUS_DONE = 0;
-
- /**
- * Enum value for uploaded module.
- */
- const STATUS_UPLOADED = 1;
-
- /**
- * Enum value for not completed module.
- */
- const STATUS_LATE = 2;
-
- /**
- * Enum value for pending module.
- */
- const STATUS_PENDING = 3;
-
- /**
- * Enum value for modules of type 'GK'.
- */
- const TYPE_GK = 0;
-
- /**
- * Enum value for modules of type 'EK'.
- */
- const TYPE_EK = 1;
-
- /**
- * Enum value for modules of type 'TEST'.
- */
- const TYPE_TEST = 2;
-
- /**
- * Enum value for modules of type 'M'.
- */
- const TYPE_M = 3;
-
- /**
- * Enum value for non
- */
- const TYPE_NONE = 4;
-
/**
* The return structure of a module.
*
* @return external_single_structure The structure of a module.
*/
- public static function structure() : external_single_structure {
+ public static function structure(): external_single_structure {
return new external_single_structure(
- array(
- 'moduleid' => new external_value(PARAM_INT, 'The id of the module'),
- 'name' => new external_value(PARAM_TEXT, 'The name of the module'),
- 'courseid' => new external_value(PARAM_INT, 'The id of the course'),
- 'status' => new external_value(PARAM_INT, 'The status of the module'),
- 'type' => new external_value(PARAM_INT, 'The type of the module'),
- 'url' => new external_value(PARAM_TEXT, 'The url of the module in moodle'),
- 'grade' => new external_value(PARAM_INT, 'The grade of the module'),
+ [
+ 'moduleid' => new external_value(PARAM_INT, 'Module ID'),
+ 'name' => new external_value(PARAM_TEXT, 'Shortened module name (max. 5 chars)'),
+ 'courseid' => new external_value(PARAM_INT, 'Course ID'),
+ 'status' => new external_value(PARAM_INT, 'Module status '.MODULE_STATUS::format()),
+ 'type' => new external_value(PARAM_INT, 'Module type '.MODULE_TYPE::format()),
+ 'url' => new external_value(PARAM_TEXT, 'URL to moodle page for module'),
+ 'grade' => new external_value(PARAM_INT, 'The grade of the module '.MODULE_GRADE::format()),
'deadline' => new external_value(PARAM_INT, 'The deadline of the module set by the teacher'),
- )
+ ]
);
}
/**
* Determins the enum value for a grade.
*
- * @param integer $grade The grade of the module.
- * @param integer $maxgrade The max. grade of the module.
- * @param integer $mingrade The min. grade of the module.
- * @param integer $gradepass The grade to pass the module.
+ * @param int $grade The grade of the module.
+ * @param int $maxgrade The max. grade of the module.
+ * @param int $mingrade The min. grade of the module.
+ * @param int $gradepass The grade to pass the module.
* @return integer The enum value for the grade.
*/
- public static function determin_uinified_grade(int $grade, int $maxgrade, int $mingrade, int $gradepass) : int {
+ public static function determin_uinified_grade(int $grade, int $maxgrade, int $mingrade, int $gradepass): int {
if ($grade < $gradepass) {
- return self::GRADE_RIP;
+ return MODULE_GRADE::RIP;
}
$maxgrade = $maxgrade - $mingrade;
@@ -172,35 +111,35 @@ public static function determin_uinified_grade(int $grade, int $maxgrade, int $m
$p = $grade / $maxgrade;
if ($p >= 0.9) {
- return self::GRADE_EKV;
+ return MODULE_GRADE::EKV;
} else if ($p >= 0.8) {
- return self::GRADE_EK;
+ return MODULE_GRADE::EK;
} else if ($p >= 0.7) {
- return self::GRADE_GKV;
+ return MODULE_GRADE::GKV;
} else if ($p >= 0.4) {
- return self::GRADE_GK;
+ return MODULE_GRADE::GK;
} else {
- return self::GRADE_RIP;
+ return MODULE_GRADE::RIP;
}
}
/**
* Maps the given info to a module status.
*
- * @param boolean $submitted Whether the module is submitted.
- * @param boolean $done Whether the module is completed.
- * @param boolean $late Whether the module is late.
+ * @param bool $submitted Whether the module is submitted.
+ * @param bool $done Whether the module is completed.
+ * @param bool $late Whether the module is late.
* @return integer The enum value for the module status.
*/
- public static function map_status(bool $submitted, bool $done, bool $late) : int {
+ public static function map_status(bool $submitted, bool $done, bool $late): int {
if ($done) {
- return self::STATUS_DONE;
+ return MODULE_STATUS::DONE;
} else if ($submitted) {
- return self::STATUS_UPLOADED;
+ return MODULE_STATUS::UPLOADED;
} else if ($late) {
- return self::STATUS_LATE;
+ return MODULE_STATUS::LATE;
} else {
- return self::STATUS_PENDING;
+ return MODULE_STATUS::PENDING;
}
}
@@ -210,46 +149,46 @@ public static function map_status(bool $submitted, bool $done, bool $late) : int
* @param string $modulename The name of the module.
* @return integer The enum value for the module type.
*/
- public static function determin_type(string $modulename) : int {
+ public static function determin_type(string $modulename): int {
// Convert module name to uppercase.
$modulename = strtoupper($modulename);
// Return TYPE_TEST if the name contains 'test' or 'sa'.
if (strpos($modulename, '[TEST]') !== false || strpos($modulename, '[SA]') !== false) {
- return self::TYPE_TEST;
+ return MODULE_TYPE::TEST;
}
// Return TYPE_GK if the name contains 'GK'.
if (strpos($modulename, '[GK]') !== false) {
- return self::TYPE_GK;
+ return MODULE_TYPE::GK;
}
if (strpos($modulename, '[EK]') !== false) {
- return self::TYPE_EK;
+ return MODULE_TYPE::EK;
}
// Return TYPE_EK if the name contains 'M'.
if (strpos($modulename, '[M]') !== false) {
- return self::TYPE_M;
+ return MODULE_TYPE::M;
}
// Return TYPE_NONE elswise.
- return self::TYPE_NONE;
+ return MODULE_TYPE::NONE;
}
/**
* Returns the url of the module.
*
- * @param integer $moduleid The id of the module.
- * @param integer $courseid The id of the course.
+ * @param int $moduleid The id of the module.
+ * @param int $courseid The id of the course.
* @return string The url of the module.
*/
- public static function get_module_url(int $moduleid, int $courseid) : string {
+ public static function get_module_url(int $moduleid, int $courseid): string {
global $DB;
$view = $DB->get_record(
self::COURSE_MODULES_TABLE,
- array('course' => $courseid, 'instance' => $moduleid, 'module' => 1)
+ ['course' => $courseid, 'instance' => $moduleid, 'module' => 1]
);
return strval(new moodle_url('/mod/assign/view.php?id='.$view->id));
@@ -258,31 +197,31 @@ public static function get_module_url(int $moduleid, int $courseid) : string {
/**
* Retrieves a module of the given id for the given user.
*
- * @param integer $moduleid The id of the module.
- * @param integer $userid The id of the user.
+ * @param int $moduleid The id of the module.
+ * @param int $userid The id of the user.
* @return array The module.
*/
- public static function get_module(int $moduleid, int $userid) : array {
+ public static function get_module(int $moduleid, int $userid): array {
global $DB;
date_default_timezone_set('UTC');
// Get module data.
- $module = $DB->get_record(self::ASSIGN_TABLE, array('id' => $moduleid));
+ $module = $DB->get_record(self::ASSIGN_TABLE, ['id' => $moduleid]);
// Determine module type.
$type = self::determin_type($module->name);
- if ($type == self::TYPE_NONE) {
- return array();
+ if ($type == MODULE_TYPE::NONE) {
+ return [];
}
// Check if there are any submissions or feedbacks for this module.
$submitted = false;
- if ($DB->record_exists(self::SUBMISSIONS_TABLE, array('assignment' => $moduleid, 'userid' => $userid))) {
+ if ($DB->record_exists(self::SUBMISSIONS_TABLE, ['assignment' => $moduleid, 'userid' => $userid])) {
$submission = $DB->get_record(
self::SUBMISSIONS_TABLE,
- array('assignment' => $moduleid, 'userid' => $userid)
+ ['assignment' => $moduleid, 'userid' => $userid]
);
$submitted = strval($submission->status) == self::SUBMISSION_STATUS_SUBMITTED;
@@ -291,12 +230,12 @@ public static function get_module(int $moduleid, int $userid) : array {
$done = false;
$grade = null;
- if ($DB->record_exists(self::GRADES_TABLE, array('assignment' => $moduleid, 'userid' => $userid))) {
- $moduleboundaries = $DB->get_record(self::GRADE_ITEMS_TABLE, array('iteminstance' => $moduleid));
+ if ($DB->record_exists(self::GRADES_TABLE, ['assignment' => $moduleid, 'userid' => $userid])) {
+ $moduleboundaries = $DB->get_record(self::GRADE_ITEMS_TABLE, ['iteminstance' => $moduleid]);
$mdlgrades = $DB->get_records(
self::GRADES_TABLE,
- array('assignment' => $moduleid, 'userid' => $userid)
+ ['assignment' => $moduleid, 'userid' => $userid]
);
$mdlgrade = end($mdlgrades);
@@ -310,7 +249,7 @@ public static function get_module(int $moduleid, int $userid) : array {
$moduleboundaries->gradepass
);
- $done = $grade != self::GRADE_RIP;
+ $done = $grade != MODULE_GRADE::RIP;
}
}
// Check if the module is late.
@@ -318,8 +257,8 @@ public static function get_module(int $moduleid, int $userid) : array {
$late = false;
$planid = plan_helper::get_plan_id($userid);
- if ($DB->record_exists(plan_helper::DEADLINES_TABLE, array('planid' => $planid, 'moduleid' => $moduleid))) {
- $deadline = $DB->get_record(plan_helper::DEADLINES_TABLE, array('planid' => $planid, 'moduleid' => $moduleid));
+ if ($DB->record_exists(plan_helper::DEADLINES_TABLE, ['planid' => $planid, 'moduleid' => $moduleid])) {
+ $deadline = $DB->get_record(plan_helper::DEADLINES_TABLE, ['planid' => $planid, 'moduleid' => $moduleid]);
$late = intval(date("Ymd", $deadline->deadlineend)) < intval(date("Ymd")) && !$done;
}
@@ -327,7 +266,7 @@ public static function get_module(int $moduleid, int $userid) : array {
// Return the appropriate data.
- return array(
+ return [
'moduleid' => $moduleid,
'name' => $module->name,
'courseid' => $module->course,
@@ -336,25 +275,26 @@ public static function get_module(int $moduleid, int $userid) : array {
'url' => self::get_module_url($moduleid, $module->course),
'grade' => $grade,
'deadline' => $module->duedate > 0 ? $module->duedate : null,
- );
+ ];
}
/**
* Reteruns all modules for the given course id.
*
- * @param integer $courseid The id of the course.
- * @param integer $userid The id of the user.
+ * @param int $courseid The id of the course.
+ * @param int $userid The id of the user.
+ * @param bool $ekenabled Whether EK modules should be included.
* @return array The modules.
*/
- public static function get_all_course_modules(int $courseid, int $userid, bool $ekenabled) : array {
+ public static function get_all_course_modules(int $courseid, int $userid, bool $ekenabled): array {
global $DB;
- $mdlmodules = $DB->get_records(self::ASSIGN_TABLE, array('course' => $courseid));
+ $mdlmodules = $DB->get_records(self::ASSIGN_TABLE, ['course' => $courseid]);
- $modules = array();
+ $modules = [];
foreach ($mdlmodules as $mdlmodule) {
- if (!$ekenabled && self::determin_type($mdlmodule->name) == self::TYPE_EK) {
+ if (!$ekenabled && self::determin_type($mdlmodule->name) == MODULE_TYPE::EK) {
continue;
}
$module = self::get_module($mdlmodule->id, $userid);
diff --git a/lbplanner/classes/helpers/notifications_helper.php b/lbplanner/classes/helpers/notifications_helper.php
index f7a40964..2d2f82e5 100644
--- a/lbplanner/classes/helpers/notifications_helper.php
+++ b/lbplanner/classes/helpers/notifications_helper.php
@@ -14,77 +14,69 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
+/**
+ * Provides helper classes for notification related stuff
+ *
+ * @package local_lbplanner
+ * @subpackage helpers
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
namespace local_lbplanner\helpers;
+use external_single_structure;
+use external_value;
+use local_lbplanner\enums\{NOTIF_STATUS, NOTIF_TRIGGER};
+
/**
- * Provides helper methods for notification related stuff.
+ * Provides helper methods for notification related stuff
*/
class notifications_helper {
/**
* Name of the notifications table.
*/
- const TABLE = 'local_lbplanner_notification';
-
- /**
- * Enum value for a read notification.
- */
- const STATUS_READ = 1;
-
- /**
- * Enum value for a unread notification.
- */
- const STATUS_UNREAD = 0;
-
- /**
- * Enum value for a notification triggered by an invitation.
- */
- const TRIGGER_INVITE = 0;
-
- /**
- * Enum value for a notification triggered by an acceptation of an invitation.
- */
- const TRIGGER_INVITE_ACCEPTED = 1;
-
- /**
- * Enum value for a notification triggered by a rejection of an invitation.
- */
- const TRIGGER_INVITE_DECLINED = 2;
-
- /**
- * Enum value for a notification triggered by a user leaving a plan.
- */
- const TRIGGER_PLAN_LEFT = 3;
-
- /**
- * Enum value for a notification triggered by a user being removed from a plan.
- */
- const TRIGGER_PLAN_REMOVED = 4;
+ const LBPLANNER_NOTIFICATION_TABLE = 'local_lbplanner_notification';
/**
- * Enum value for a notification triggered by a new user.
+ * Returns the data structure of a notification
+ *
+ * @return external_single_structure The data structure of a notification.
*/
- const TRIGGER_USER_REGISTERED = 5;
+ public static function structure(): external_single_structure {
+ return new external_single_structure([
+ 'status' => new external_value(PARAM_INT, 'The status of the notification ' . NOTIF_STATUS::format()),
+ 'type' =>
+ new external_value(PARAM_INT, 'The type of the event that triggered the notification ' . NOTIF_TRIGGER::format()),
+ 'info' => new external_value(PARAM_INT, 'Additional information about the notification'),
+ 'userid' => new external_value(PARAM_INT, 'The ID of the user for whom the notification is for'),
+ 'notificationid' => new external_value(PARAM_INT, 'The ID of the notification', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
+ 'timestamp' => new external_value(PARAM_INT, 'The timestamp of the notification'),
+ 'timestamp_read' => new external_value(PARAM_INT, 'The timestamp of the notification when it was read'),
+ ]);
+ }
/**
* Notifies the given user about the given event, with the given info.
*
- * @param integer $userid The user to notify.
- * @param integer $info Additional information as stringified json.
- * @param integer $type The type of notification.
+ * @param int $userid The user to notify.
+ * @param int $info Additional information as stringified json.
+ * @param int $type The type of notification.
+ *
* @return integer The id of the notification.
*/
- public static function notify_user( int $userid, int $info, int $type ): int {
+ public static function notify_user(int $userid, int $info, int $type): int {
global $DB;
$notification = new \stdClass();
$notification->userid = $userid;
$notification->info = $info;
$notification->type = $type;
- $notification->status = self::STATUS_UNREAD;
+ $notification->status = NOTIF_STATUS::UNREAD;
$notification->timestamp = time();
$notification->timestamp_read = null;
- $id = $DB->insert_record(self::TABLE, $notification);
+ $id = $DB->insert_record(self::LBPLANNER_NOTIFICATION_TABLE, $notification);
return $id;
}
diff --git a/lbplanner/classes/helpers/plan_helper.php b/lbplanner/classes/helpers/plan_helper.php
index eee5da31..63b803b6 100644
--- a/lbplanner/classes/helpers/plan_helper.php
+++ b/lbplanner/classes/helpers/plan_helper.php
@@ -14,66 +14,26 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
+/**
+ * Provides helper classes for any tables related with the planning function of the app
+ *
+ * @package local_lbplanner
+ * @subpackage helpers
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
namespace local_lbplanner\helpers;
use external_single_structure;
use external_value;
use external_multiple_structure;
+use local_lbplanner\enums\PLAN_ACCESS_TYPE;
/**
- * Provides helper methods for any tables related with the planning function of the app.
+ * Provides helper methods for any tables related with the planning function of the app
*/
class plan_helper {
- /**
- * Enum value for the plan owner.
- */
- const ACCESS_TYPE_OWNER = 0;
-
- /**
- * Enum value for plan members with write access to the plan.
- */
- const ACCESS_TYPE_WRITE = 1;
-
- /**
- * Enum value for plan members with read access to the plan.
- */
- const ACCESS_TYPE_READ = 2;
-
- /**
- * Enum value for plan members with no access to the plan.
- */
- const ACCESS_TYPE_NONE = -1;
-
- /**
- * Boolean value for ek-modules disabled.
- */
- const EK_DISABLED = 0;
-
- /**
- * Boolean value for ek-modules enabled.
- */
- const EK_ENABLED = 1;
-
- /**
- * Enum value for invites: The invite is pending and has not been accepted yet.
- */
- const INVITE_PENDING = 0;
-
- /**
- * Enum value for invites: The invite has been accepted.
- */
- const INVITE_ACCEPTED = 1;
-
- /**
- * Enum value for invites: The invite has been declined.
- */
- const INVITE_DECLINED = 2;
-
- /**
- * Enum value for invites: The invite has expired.
- */
- const INVITE_EXPIRED = 3;
-
/**
* local_lbplanner_plans table.
*/
@@ -97,27 +57,29 @@ class plan_helper {
/**
* Returns a list of user id's that are members of the plan.
*
- * @param integer $planid The id of the plan.
+ * @param int $planid The id of the plan.
+ *
* @return array An array of user id's.
*/
- public static function get_plan_members(int $planid):array {
+ public static function get_plan_members(int $planid): array {
global $DB;
- $members = $DB->get_records(self::ACCESS_TABLE, array('planid' => $planid));
+ $members = $DB->get_records(self::ACCESS_TABLE, ['planid' => $planid]);
return $members;
}
/**
* Returns the user id of the owner of the plan.
*
- * @param integer $planid The id of the plan.
+ * @param int $planid The id of the plan.
+ *
* @return integer The user id of the owner.
*/
- public static function get_owner(int $planid):int {
+ public static function get_owner(int $planid): int {
global $DB;
$owner = $DB->get_field(
self::ACCESS_TABLE,
- 'userid', array('planid' => $planid, 'accesstype' => self::ACCESS_TYPE_OWNER)
+ 'userid', ['planid' => $planid, 'accesstype' => PLAN_ACCESS_TYPE::OWNER]
);
return $owner;
@@ -126,65 +88,74 @@ public static function get_owner(int $planid):int {
/**
* Returns the id of the plan that the given user is a member of.
*
- * @param integer $userid The id of the user.
+ * @param int $userid The id of the user.
+ *
* @return integer The id of the plan the given user is a member of.
*/
- public static function get_plan_id(int $userid):int {
+ public static function get_plan_id(int $userid): int {
global $DB;
- $planid = $DB->get_field(self::ACCESS_TABLE, 'planid', array('userid' => $userid));
+ $planid = $DB->get_field(self::ACCESS_TABLE, 'planid', ['userid' => $userid]);
return $planid;
}
/**
* Returns the access type of the given user for the given plan.
*
- * @param integer $planid The id of the plan.
- * @param integer $userid The id of the user.
- * @return integer The access type of the given user for the given plan.
+ * @param int $userid The id of the user.
+ * @param int $planid The id of the plan.
+ *
+ * @return int The access type of the given user for the given plan.
*/
- public static function get_access_type(int $userid, int $planid):int {
+ public static function get_access_type(int $userid, int $planid): int {
global $DB;
- if ($DB->record_exists(self::ACCESS_TABLE, array('planid' => $planid, 'userid' => $userid))) {
- return $DB->get_field(self::ACCESS_TABLE, 'accesstype', array('planid' => $planid, 'userid' => $userid));
+ $field = $DB->get_field(
+ self::ACCESS_TABLE,
+ 'accesstype',
+ ['planid' => $planid, 'userid' => $userid]
+ );
+
+ if ($field === false) {
+ return PLAN_ACCESS_TYPE::NONE;
} else {
- return self::ACCESS_TYPE_NONE;
+ return PLAN_ACCESS_TYPE::from($field);
}
}
/**
* Checks if the given user has editing permissions for the given plan.
*
- * @param integer $planid The id of the plan.
- * @param integer $userid The id of the user.
+ * @param int $planid The id of the plan.
+ * @param int $userid The id of the user.
+ *
* @return boolean True if the given user has editing permissions for the given plan.
*/
- public static function check_edit_permissions(int $planid, int $userid):bool {
+ public static function check_edit_permissions(int $planid, int $userid): bool {
$access = self::get_access_type($userid, $planid);
- return $access == self::ACCESS_TYPE_OWNER || $access == self::ACCESS_TYPE_WRITE;
+ return $access === PLAN_ACCESS_TYPE::OWNER || $access === PLAN_ACCESS_TYPE::WRITE;
}
/**
* Returns a list of all deadlines for the given plan.
*
- * @param integer $planid The id of the plan.
+ * @param int $planid The id of the plan.
+ *
* @return array A list of all deadlines for the given plan.
*/
public static function get_deadlines(int $planid): array {
global $DB;
- $dbdeadlines = $DB->get_records(self::DEADLINES_TABLE, array('planid' => $planid));
+ $dbdeadlines = $DB->get_records(self::DEADLINES_TABLE, ['planid' => $planid]);
- $deadlines = array();
+ $deadlines = [];
foreach ($dbdeadlines as $dbdeadline) {
- $deadlines[] = array(
- 'planid' => $dbdeadline->planid,
+ $deadlines[] = [
'deadlinestart' => $dbdeadline->deadlinestart,
'deadlineend' => $dbdeadline->deadlineend,
'moduleid' => $dbdeadline->moduleid,
- );
+ ];
}
return $deadlines;
@@ -193,29 +164,30 @@ public static function get_deadlines(int $planid): array {
/**
* Retrieves all the information available about the given plan.
*
- * @param integer $planid The id of the plan.
+ * @param int $planid The id of the plan.
+ *
* @return array An array containing all the information available about the given plan.
*/
- public static function get_plan(int $planid) : array {
+ public static function get_plan(int $planid): array {
global $DB;
- $plan = $DB->get_record(self::TABLE, array('id' => $planid));
- $members = array();
+ $plan = $DB->get_record(self::TABLE, ['id' => $planid]);
+ $members = [];
foreach (self::get_plan_members($planid) as $member) {
- $members[] = array(
+ $members[] = [
'userid' => $member->userid,
'accesstype' => $member->accesstype,
- );
+ ];
}
- return array(
+ return [
'name' => $plan->name,
'planid' => $planid,
'enableek' => $plan->enableek,
'deadlines' => self::get_deadlines($planid),
'members' => $members,
- );
+ ];
}
/**
@@ -223,72 +195,70 @@ public static function get_plan(int $planid) : array {
*
* @return external_single_structure The structure.
*/
- public static function plan_structure() : external_single_structure {
+ public static function plan_structure(): external_single_structure {
return new external_single_structure(
- array(
- 'name' => new external_value(PARAM_TEXT, 'The name of the plan'),
- 'planid' => new external_value(PARAM_INT, 'The id of the plan'),
- 'enableek' => new external_value(PARAM_BOOL, 'If the plan is enabled for ek'),
+ [
+ 'name' => new external_value(PARAM_TEXT, 'Name of the plan'),
+ 'planid' => new external_value(PARAM_INT, 'ID of the plan'),
+ 'enableek' => new external_value(PARAM_BOOL, 'Whether EK is enabled'),
'deadlines' => new external_multiple_structure(
new external_single_structure(
- array(
- 'planid' => new external_value(PARAM_INT, 'The id of the user'),
- 'moduleid' => new external_value(PARAM_INT, 'The id of the user'),
- 'deadlinestart' => new external_value(PARAM_INT, 'The id of the user'),
- 'deadlineend' => new external_value(PARAM_INT, 'The id of the user'),
- )
+ [
+ 'moduleid' => new external_value(PARAM_INT, 'ID of the module'),
+ 'deadlinestart' => new external_value(PARAM_INT, 'Start of the deadline as an UNIX timestamp'),
+ 'deadlineend' => new external_value(PARAM_INT, 'End of the deadline as an UNIX timestamp'),
+ ]
)
),
'members' => new external_multiple_structure(
new external_single_structure(
- array(
+ [
'userid' => new external_value(PARAM_INT, 'The id of the user'),
- 'accesstype' => new external_value(PARAM_INT, 'The role of the user'),
- )
+ 'accesstype' => new external_value(PARAM_INT, 'The role of the user ' . PLAN_ACCESS_TYPE::format()),
+ ]
)
),
- )
+ ]
);
}
/**
* Copies the given plan to the given user.
*
- * @param integer $planid The id of the plan.
- * @param integer $userid The id of the user.
+ * @param int $planid The id of the plan.
+ * @param string $username Username of the user.
+ *
* @return integer The id of the new copy of the plan.
*/
- public static function copy_plan(int $planid, int $userid) : int {
+ public static function copy_plan(int $planid, string $username): int {
global $DB;
- $user = user_helper::get_mdl_user_info($userid);
-
- $plan = $DB->get_record(self::TABLE, array('id' => $planid));
- $plan->name = $plan->name . ' (' . $user->username . ')';
+ $plan = $DB->get_record(self::TABLE, ['id' => $planid]);
+ $plan->name = $plan->name . ' (' . $username . ')';
$plan->id = null;
$deadlines = self::get_deadlines($planid);
$newplanid = $DB->insert_record(self::TABLE, $plan);
- // Had to do it with insert and then update because the Variable didnt change in the Loop.
- // I don't know why. It just works, so dont touch it 🚧.
foreach ($deadlines as $deadline) {
- $id = $DB->insert_record(self::DEADLINES_TABLE, $deadline);
- $DB->update_record(self::DEADLINES_TABLE, array('id' => $id, 'planid' => $newplanid));
+ $deadline['planid'] = $newplanid;
+ $DB->insert_record(self::DEADLINES_TABLE, $deadline);
}
return $newplanid;
}
+
/**
* Removes the user from the given plan.
*
- * @param integer $planid the plan id.
- * @param integer $userid the user id.
- * @param integer $removeuserid the user id to remove.
- * @return array An array containing the new id of the plan
+ * @param int $planid the plan id.
+ * @param int $userid the user id.
+ * @param int $removeuserid the user id to remove.
+ *
+ * @return int The ID of the new plan for the removed user
*/
- public static function remove_user(int $planid, int $userid, int $removeuserid) : array {
- global $DB;
+ public static function remove_user(int $planid, int $userid, int $removeuserid): int {
+ global $DB; // TODO: use global user object.
if (self::get_owner($planid) != $userid) {
throw new \moodle_exception('Access denied');
}
@@ -301,32 +271,50 @@ public static function remove_user(int $planid, int $userid, int $removeuserid)
throw new \moodle_exception('Cannot remove yourself');
}
- if (self::get_access_type($removeuserid, $planid) == self::ACCESS_TYPE_OWNER) {
+ if (self::get_access_type($removeuserid, $planid) === PLAN_ACCESS_TYPE::OWNER) {
throw new \moodle_exception('Cannot remove owner');
}
- $newplanid = self::copy_plan($planid, $removeuserid);
+ $newplanid = self::copy_plan($planid, user_helper::get_mdluser($removeuserid)->username);
$oldaccess = $DB->get_record(
self::ACCESS_TABLE,
- array('planid' => $planid, 'userid' => $removeuserid), '*', MUST_EXIST
+ ['planid' => $planid, 'userid' => $removeuserid], '*', MUST_EXIST
);
$oldaccess->planid = $newplanid;
- $oldaccess->accesstype = self::ACCESS_TYPE_OWNER;
+ $oldaccess->accesstype = PLAN_ACCESS_TYPE::OWNER;
$DB->update_record(self::ACCESS_TABLE, $oldaccess);
- return self::get_plan($planid, $removeuserid);
+ return $newplanid;
}
- public static function get_invites_send(int $userid):array {
+
+ /**
+ * Get all invites that have been sent by the user.
+ * TODO: move to notifications_helper
+ *
+ * @param int $userid ID of the sender
+ *
+ * @return array an array of invites sent by the user
+ */
+ public static function get_invites_send(int $userid): array {
global $DB;
- $invites = $DB->get_records(self::INVITES_TABLE, array('inviterid' => $userid));
+ $invites = $DB->get_records(self::INVITES_TABLE, ['inviterid' => $userid]);
return $invites;
}
- public static function get_invites_received(int $userid):array {
+
+ /**
+ * Get all invites that have been received by the user.
+ * TODO: move to notifications_helper
+ *
+ * @param int $userid ID of the receiver
+ *
+ * @return array an array of invites received by the user
+ */
+ public static function get_invites_received(int $userid): array {
global $DB;
- $invites = $DB->get_records(self::INVITES_TABLE, array('inviteeid' => $userid));
+ $invites = $DB->get_records(self::INVITES_TABLE, ['inviteeid' => $userid]);
return $invites;
}
}
diff --git a/lbplanner/classes/helpers/slot_helper.php b/lbplanner/classes/helpers/slot_helper.php
new file mode 100644
index 00000000..16a52cbd
--- /dev/null
+++ b/lbplanner/classes/helpers/slot_helper.php
@@ -0,0 +1,310 @@
+.
+
+/**
+ * Provides helper classes for any tables related with the slot booking function of the app
+ *
+ * @package local_lbplanner
+ * @subpackage helpers
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\helpers;
+
+use DateInterval;
+use DateTime;
+use DateTimeImmutable;
+use DateTimeInterface;
+use local_lbplanner\enums\WEEKDAY;
+use local_lbplanner\model\{slot, reservation, slot_filter};
+
+/**
+ * Provides helper methods for any tables related with the planning function of the app
+ */
+class slot_helper {
+ /**
+ * how far into the future a user can reserve a slot
+ */
+ const RESERVATION_RANGE_USER = 3;
+ /**
+ * how far into the future a supervisor can reserve a slot for a user
+ */
+ const RESERVATION_RANGE_SUPERVISOR = 7;
+ /**
+ * how long the room names can be in characters
+ * unicode characters might count as multiple characters
+ */
+ const ROOM_MAXLENGTH = 7; // TODO: increase to 255 or sumn.
+ /**
+ * school units according to untis, in H:i format
+ */
+ const SCHOOL_UNITS = [
+ null,
+ '08:00',
+ '08:50',
+ '09:50',
+ '10:40',
+ '11:30',
+ '12:30',
+ '13:20',
+ '14:10',
+ '15:10',
+ '16:00',
+ '17:00', // All units after this point are 45min long instead of the usual 50.
+ '17:45', // We will assume 50min anyway because it's easier that way.
+ '18:45',
+ '19:30',
+ '20:15',
+ '21:00',
+ ];
+ /**
+ * local_lbplanner_slots table.
+ */
+ const TABLE_SLOTS = 'local_lbplanner_slots';
+ /**
+ * local_lbplanner_reservations table.
+ */
+ const TABLE_RESERVATIONS = 'local_lbplanner_reservations';
+ /**
+ * local_lbplanner_slot_courses table.
+ */
+ const TABLE_SLOT_FILTERS = 'local_lbplanner_slot_courses';
+ /**
+ * local_lbplanner_supervisors table.
+ */
+ const TABLE_SUPERVISORS = 'local_lbplanner_supervisors';
+
+ /**
+ * Returns a list of all slots.
+ *
+ * @return slot[] An array of the slots.
+ */
+ public static function get_all_slots(): array {
+ global $DB;
+ $slots = $DB->get_records(self::TABLE_SLOTS, []);
+
+ $slotsobj = [];
+ foreach ($slots as $slot) {
+ array_push($slotsobj, new slot(...$slot));
+ }
+
+ return $slotsobj;
+ }
+
+ /**
+ * Returns a list of all slots belonging to a supervisor.
+ * @param int $supervisorid userid of the supervisor in question
+ *
+ * @return slot[] An array of the slots.
+ */
+ public static function get_supervisor_slots(int $supervisorid): array {
+ global $DB;
+
+ $slots = $DB->get_records_sql(
+ 'SELECT slot.* FROM {'.self::TABLE_SLOTS.'} as slot'.
+ 'INNER JOIN '.self::TABLE_SUPERVISORS.' as supervisor ON supervisor.slotid=slot.id'.
+ 'WHERE supervisor.userid=?',
+ [$supervisorid]
+ );
+
+ $slotsobj = [];
+ foreach ($slots as $slot) {
+ array_push($slotsobj, new slot(...$slot));
+ }
+
+ return $slotsobj;
+ }
+
+ /**
+ * Returns a singular slot.
+ * @param int $slotid ID of the slot
+ *
+ * @return slot the requested slot
+ */
+ public static function get_slot(int $slotid): slot {
+ global $DB;
+ $slot = $DB->get_record(self::TABLE_SLOTS, ['id' => $slotid]);
+
+ return new slot(...$slot);
+ }
+
+ /**
+ * Returns a singular reservation.
+ * @param int $reservationid ID of the reservation
+ *
+ * @return reservation the requested reservation
+ */
+ public static function get_reservation(int $reservationid): reservation {
+ global $DB;
+ $reservation = $DB->get_record(self::TABLE_RESERVATIONS, ['id' => $reservationid]);
+
+ if ($reservation === false) {
+ throw new \moodle_exception('requested reservation does not exist');
+ }
+
+ $reservation['date'] = new DateTimeImmutable($reservation['date']);
+
+ return new reservation(...$reservation);
+ }
+
+ /**
+ * Returns reservations for a slot.
+ * @param int $slotid ID of the slot
+ *
+ * @return reservation[] the requested reservations
+ */
+ public static function get_reservations_for_slot(int $slotid): array {
+ global $DB;
+ $reservations = $DB->get_records(self::TABLE_RESERVATIONS, ['slotid' => $slotid]);
+
+ $reservationsobj = [];
+ foreach ($reservations as $reservation) {
+ $reservation['date'] = new DateTimeImmutable($reservation['date']);
+ array_push($reservationsobj, new reservation(...$reservation));
+ }
+
+ return $reservationsobj;
+ }
+
+ /**
+ * Returns filters for a slot.
+ * @param int $slotid ID of the slot
+ *
+ * @return slot_filter[] the requested filters
+ */
+ public static function get_filters_for_slot(int $slotid): array {
+ global $DB;
+ $filters = $DB->get_records(self::TABLE_SLOT_FILTERS, ['slotid' => $slotid]);
+
+ $filtersobj = [];
+ foreach ($filters as $filter) {
+ array_push($filtersobj, new slot_filter(...$filter));
+ }
+
+ return $filtersobj;
+ }
+
+ /**
+ * Filters an array of slots for the slots that the user can theoretically reserve
+ * NOTE: not taking into account time or fullness, only filters i.e. users' class and courses
+ * TODO: replace $user with $vintage
+ * @param slot[] $allslots the slots to filter
+ * @param mixed $user a user object - e.g. $USER or a user object from the database
+ * @return slot[] the filtered slot array
+ */
+ public static function filter_slots_for_user(array $allslots, mixed $user): array {
+ $mycourses = course_helper::get_all_lbplanner_courses();
+ $mycourseids = [];
+ foreach ($mycourses as $course) {
+ array_push($mycourseids, $course->courseid);
+ }
+
+ $slots = [];
+ foreach ($allslots as $slot) {
+ $filters = self::get_filters_for_slot($slot->id);
+ foreach ($filters as $filter) {
+ // Checking for course ID.
+ if (!is_null($filter->courseid) && !in_array($filter->courseid, $mycourseids)) {
+ continue;
+ }
+ // TODO: replace address with cohorts.
+ // Checking for vintage.
+ if (!is_null($filter->vintage) && $user->address !== $filter->vintage) {
+ continue;
+ }
+ // If all filters passed, add slot to my slots and break.
+ array_push($slots, $slot);
+ break;
+ }
+ }
+ return $slots;
+ }
+
+ /**
+ * Filters an array of slots for a timerange around now.
+ * @param slot[] $allslots the slots to filter
+ * @param int $range how many days in the future the slot is allowed to be
+ * @return slot[] the filtered slot array
+ */
+ public static function filter_slots_for_time(array $allslots, int $range): array {
+ $now = new DateTimeImmutable();
+ $slots = [];
+ // Calculate date and time each slot happens next, and add it to the return list if within reach from today.
+ foreach ($allslots as $slot) {
+ $slotdatetime = self::calculate_slot_datetime($slot, $now);
+
+ if ($now->diff($slotdatetime)->days <= $range) {
+ array_push($slots, $slot);
+ }
+ }
+ return $slots;
+ }
+
+ /**
+ * calculates when a slot is to happen next
+ * @param slot $slot the slot
+ * @param DateTimeInterface $now the point in time representing now
+ * @return DateTimeImmutable the next time this slot will occur
+ */
+ public static function calculate_slot_datetime(slot $slot, DateTimeInterface $now): DateTimeImmutable {
+ $slotdaytime = self::SCHOOL_UNITS[$slot->startunit];
+ // NOTE: format and fromFormat use different date formatting conventions.
+ $slotdatetime = DateTime::createFromFormat('YY-MM-DD tHH:MM', $now->format('Y-m-d ').$slotdaytime);
+ // Move to next day this weekday occurs (doesn't move if it's the same as today).
+ $slotdatetime->modify('this '.WEEKDAY::name_from($slot->weekday));
+
+ // Check if slot is before now (because time of day and such) and move it a week into the future if so.
+ if ($now->diff($slotdatetime)->invert === 1) {
+ $slotdatetime->add(new DateInterval('P1W'));
+ }
+
+ return new DateTimeImmutable($slotdatetime);
+ }
+
+ /**
+ * Amends a date with time of day using the units system
+ * @param int $unit the unit to use
+ * @param DateTimeInterface $date the date (time of day will be ignored)
+ *
+ * @return DateTimeImmutable the new date with time of day filled in
+ * @link slot_helper::SCHOOL_UNITS
+ */
+ public static function amend_date_with_unit_time(int $unit, DateTimeInterface $date): DateTimeImmutable {
+ $daytime = self::SCHOOL_UNITS[$unit];
+
+ return DateTimeImmutable::createFromFormat('YY-MM-DD tHH:MM', $date->format('Y-m-d ').$daytime);
+ }
+
+ /**
+ * Checks whether a user is supervisor for a specific slot.
+ * @param int $supervisorid userid of the supervisor in question
+ * @param int $slotid the slot to check
+ *
+ * @return slot[] An array of the slots.
+ */
+ public static function check_slot_supervisor(int $supervisorid, int $slotid): bool {
+ global $DB;
+
+ $result = $DB->get_record_sql(
+ 'SELECT supervisor.userid FROM '.self::TABLE_SUPERVISORS.' as supervisor'.
+ 'WHERE supervisor.userid=? AND supervisor.slotid=?',
+ [$supervisorid, $slotid]
+ );
+
+ return $result !== false;
+ }
+}
diff --git a/lbplanner/classes/helpers/user_helper.php b/lbplanner/classes/helpers/user_helper.php
index 01b2dee8..4fe6f701 100644
--- a/lbplanner/classes/helpers/user_helper.php
+++ b/lbplanner/classes/helpers/user_helper.php
@@ -16,104 +16,42 @@
namespace local_lbplanner\helpers;
+use coding_exception;
use context_system;
-use moodle1_converter;
-use moodle_database;
-use moodle_url;
-use moodleform;
+use dml_exception;
+use moodle_exception;
use stdClass;
+use user_picture;
+use core_user;
+
+use local_lbplanner\enums\{CAPABILITY, CAPABILITY_FLAG};
+use local_lbplanner\model\user;
/**
* Provides helper methods for user related stuff.
+ *
+ * @package local_lbplanner
+ * @subpackage helpers
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class user_helper {
- /**
- * Shortname of the admin CAPABILITY.
- */
- const CAPABILITY_ADMIN = 'local/lb_planner:admin';
-
- /**
- * Shortname of the manager CAPABILITY.
- */
- const CAPABILITY_MANAGER = 'local/lb_planner:manager';
-
- /**
- * Shortname of the teacher CAPABILITY.
- */
- const CAPABILITY_TEACHER = 'local/lb_planner:teacher';
-
- /**
- * Shortname of the student CAPABILITY.
- */
- const CAPABILITY_STUDENT = 'local/lb_planner:student';
-
- /**
- * Maps CAPABILITY shortnames to their corresponding enum value.
- */
- const CAPABILITY_ENUMS = [
- self::CAPABILITY_ADMIN => 1,
- self::CAPABILITY_MANAGER => 2,
- self::CAPABILITY_TEACHER => 4,
- self::CAPABILITY_STUDENT => 8
- ];
-
/**
* Name of the user database
*/
- const TABLE = 'local_lbplanner_users';
+ const LB_PLANNER_USER_TABLE = 'local_lbplanner_users';
/**
- * The table where moodle stores the user data.
- */
- const MOODLE_TABLE = 'user';
-
- /**
- * The table where moodle stores the user context data.
- */
- const MOODLE_CONTEXT_TABLE = 'context';
-
- /**
- * @deprecated Use user_helper::assert_access() instead
* Checks if the current user has access to the given user id.
*
* @param int $userid The id of the user to check access for.
+ *
* @return bool True if the current user has access to the given user id, false otherwise.
*/
- public static function check_access(int $userid):bool {
+ public static function check_access(int $userid): bool {
global $USER;
- return $USER->id == $userid;
- }
-
- /**
- * Retrieves the user with the given id.
- * ```php
- * $mdluser->username // The username of the user.
- * $mdluser->firstname // The firstname of the user.
- * $mdluser->lastname // The lastname of the user.
- * $mdluser->profileimageurl // The profile image url of the user.
- * ```
- *
- * @param integer $userid The id of the user to retrieve.
- * @return stdClass The user with the given id.
- */
- public static function get_mdl_user_info(int $userid):stdClass {
- global $DB;
- $user = $DB->get_record(self::MOODLE_TABLE, array('id' => $userid), '*', MUST_EXIST);
- $contextid = $DB->get_record(
- self::MOODLE_CONTEXT_TABLE,
- array('depth' => 2, 'contextlevel' => 30, 'instanceid' => $userid),
- '*',
- IGNORE_MISSING
- );
- $mdluser = new stdClass();
- $mdluser->username = $user->username;
- $mdluser->firstname = $user->firstname;
- $mdluser->lastname = $user->lastname;
- $mdluser->profileimageurl = strval(moodle_url::make_pluginfile_url($contextid->id, 'user', 'icon', null, '/boost_union/', 'f1.png'));
- $mdluser->vintage = $user->address;
-
- return $mdluser;
+ return ((int) $USER->id) === $userid;
}
/**
@@ -121,15 +59,30 @@ public static function get_mdl_user_info(int $userid):stdClass {
* Throws an exception if the current user does not have access.
*
* @param int $userid The id of the user to check access for.
+ *
* @return void
+ * @throws moodle_exception
*/
- public static function assert_access(int $userid) {
- global $USER;
- if ($USER->id != $userid) {
- throw new \moodle_exception('Access denied');
+ public static function assert_access(int $userid): void {
+ if (!self::check_access($userid)) {
+ throw new moodle_exception('Access denied');
}
}
+ /**
+ * Checks if the given user is an admin.
+ *
+ * @param int $userid The id of the user to check.
+ *
+ * @return bool True if the given user is an admin, false otherwise.
+ * @throws coding_exception
+ * @throws dml_exception
+ */
+ public static function is_admin(int $userid): bool {
+ $context = context_system::instance();
+ return has_capability(CAPABILITY::ADMIN, $context, $userid, false);
+ }
+
/**
* Gives back a bitmask which represents the capabilities of the given user.
* 0 = no capabilities
@@ -151,65 +104,70 @@ public static function assert_access(int $userid) {
*
*
* @param int $userid The id of the user to check access for.
+ *
* @return int The capabilities of the given user.
+ * @throws coding_exception
+ * @throws dml_exception
*/
- public static function get_user_capability_bitmask(int $userid) : int {
- global $DB;
+ public static function get_user_capability_bitmask(int $userid): int {
$capabilities = 0;
$context = context_system::instance();
- if (has_capability(self::CAPABILITY_ADMIN, $context, $userid, false)) {
- $capabilities += self::CAPABILITY_ENUMS[self::CAPABILITY_ADMIN];
+ if (has_capability(CAPABILITY::ADMIN, $context, $userid, false)) {
+ $capabilities += CAPABILITY_FLAG::ADMIN;
}
- if (has_capability(self::CAPABILITY_MANAGER, $context, $userid, false)) {
- $capabilities += self::CAPABILITY_ENUMS[self::CAPABILITY_MANAGER];
+ if (has_capability(CAPABILITY::MANAGER, $context, $userid, false)) {
+ $capabilities += CAPABILITY_FLAG::MANAGER;
}
- if (has_capability(self::CAPABILITY_TEACHER, $context, $userid, false)) {
- $capabilities += self::CAPABILITY_ENUMS[self::CAPABILITY_TEACHER];
+ if (has_capability(CAPABILITY::TEACHER, $context, $userid, false)) {
+ $capabilities += CAPABILITY_FLAG::TEACHER;
}
- if (has_capability(self::CAPABILITY_STUDENT, $context, $userid, false)) {
- $capabilities += self::CAPABILITY_ENUMS[self::CAPABILITY_STUDENT];
+ if (has_capability(CAPABILITY::STUDENT, $context, $userid, false)) {
+ $capabilities += CAPABILITY_FLAG::STUDENT;
}
return $capabilities;
}
+
/**
- * Checks if the given user exists in the database.
+ * Checks if the given user exists in the LB_PLANNER_USER database.
+ *
+ * @param int $userid The id of the user to check.
*
- * @param integer $userid The id of the user to check.
- * @return boolean True if the user exists, false otherwise.
+ * @return bool True if the user exists, false otherwise.
+ * @throws dml_exception
*/
public static function check_user_exists(int $userid): bool {
global $DB;
- return $DB->record_exists(self::TABLE, array('userid' => $userid));
+ return $DB->record_exists(self::LB_PLANNER_USER_TABLE, ['userid' => $userid]);
}
/**
* Retrieves the user with the given id.
- * The returned object contains the following properties:
- * ```php
- * $user->id // The lbplanner id of the user.
- * $user->userid // The moodle id of the user.
- * $user->theme // The name of the theme the user has set for the app.
- * $user->language // The language the user has set for the app.
- * ```
*
- * @param integer $userid The id of the user to retrieve.
- * @return stdClass The user with the given id.
+ * @param int $userid The id of the user to retrieve.
+ *
+ * @return user The user with the given id.
+ * @throws dml_exception
*/
- public static function get_user(int $userid): stdClass {
+ public static function get_user(int $userid): user {
global $DB;
- return $DB->get_record(self::TABLE, array('userid' => $userid), '*', MUST_EXIST);
+ return user::from_db($DB->get_record(self::LB_PLANNER_USER_TABLE, ['userid' => $userid], '*', MUST_EXIST));
}
/**
- * Retrieves the full name of the user with the given id.
+ * Retrieves the user with the given id.
+ *
+ * @param int $userid The id of the user to retrieve.
*
- * @param integer $userid The id of the user to retrieve the full name for.
- * @return string The full name of the user with the given id.
+ * @return \stdClass The user with the given id.
+ * @throws dml_exception
*/
- public static function get_complete_name(int $userid): string {
- $user = self::get_mdl_user_info($userid);
-
- return $user->firstname . ' ' . $user->lastname;
+ public static function get_mdluser(int $userid): \stdClass {
+ global $USER;
+ if ($userid === ((int) $USER->id)) {
+ $data = $USER;
+ } else {
+ $data = core_user::get_user($userid, '*', MUST_EXIST);
+ }
+ return $data;
}
-
}
diff --git a/lbplanner/classes/model/course.php b/lbplanner/classes/model/course.php
new file mode 100644
index 00000000..b0cccecd
--- /dev/null
+++ b/lbplanner/classes/model/course.php
@@ -0,0 +1,249 @@
+.
+
+/**
+ * Model for a course
+ *
+ * @package local_lbplanner
+ * @subpackage helpers
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\model;
+
+use external_single_structure;
+use external_value;
+use local_lbplanner\helpers\course_helper;
+
+/**
+ * Model class for course
+ */
+class course {
+ /**
+ * @var int $id course ID
+ */
+ private int $id;
+ /**
+ * @var int $courseid the moodle-internal ID of the course
+ */
+ public int $courseid;
+ /**
+ * @var int $userid the user for whom these course settings are for
+ */
+ public int $userid;
+ /**
+ * @var string $shortname the short name of this course for this user
+ * maximum size: 5 chars
+ */
+ public string $shortname;
+ /**
+ * @var string $fullname the full name of this course
+ */
+ private ?string $fullname;
+ /**
+ * @var string $color the color for this course as #RRGGBB
+ */
+ public string $color;
+ /**
+ * @var bool $enabled whether the user wants to see this course
+ */
+ public bool $enabled;
+
+ /**
+ * Constructs a new course
+ * @param int $id ID of course
+ * @param int $courseid ID of the moodle course
+ * @param int $userid ID of the user these settings are for
+ * @param string $shortname the short name for this course
+ * @param string $color the color for this course as #RRGGBB
+ * @param bool $enabled whether the course is enabled
+ */
+ public function __construct(int $id, int $courseid, int $userid, string $shortname, string $color, bool $enabled) {
+ $this->id = $id;
+ $this->courseid = $courseid;
+ $this->userid = $userid;
+ $this->set_shortname($shortname);
+ $this->set_color($color);
+ $this->enabled = $enabled;
+ $this->fullname = null;
+ }
+
+ /**
+ * Takes data from DB and makes a new Course out of it
+ *
+ * @param object $obj the DB object to get data from
+ * @return object a representation of this course and its data
+ * @throws \AssertionError
+ */
+ public static function from_db(object $obj): self {
+ assert($obj->enabled === 0 || $obj->enabled === 1);
+ return new self($obj->id, $obj->courseid, $obj->userid, $obj->shortname, $obj->color, (bool) $obj->enabled);
+ }
+
+ /**
+ * Mark the object as freshly created and sets the new ID
+ * @param int $id the new ID after inserting into the DB
+ * @throws \AssertionError
+ */
+ public function set_fresh(int $id) {
+ assert($this->id === 0);
+ assert($id !== 0);
+ $this->id = $id;
+ }
+
+ /**
+ * sets the color as #RRGGBB or #RGB in hexadecimal notation
+ * @param string $color the color
+ * @throws \coding_exception when the color format is wrong
+ */
+ public function set_color(string $color) {
+ if ($color[0] !== '#') {
+ throw new \coding_exception("incorrect color format - must be either #RGB or #RRGGBB, got \"{$color}\" instead");
+ }
+ $len = strlen($color);
+ if ($len === 4) {
+ // Transforming #RGB to #RRGGBB.
+ // This way, 0 corresponds to 00, and F to FF, meaning the full spectrum is used.
+ // This is also how Browsers handle it.
+ $rrggbb = $color[0] . $color[1] . $color[1] . $color[2] . $color[2] . $color[3] . $color[3];
+ } else if ($len === 7) {
+ // Format #RRGGBB.
+ $rrggbb = $color;
+ } else {
+ throw new \coding_exception("incorrect color format - got incorrect length of {$len}");
+ }
+ $rrggbb = strtoupper($rrggbb);
+ if (preg_match('/^#[1-9A-F]{6}$/', $rrggbb) === false) {
+ throw new \coding_exception("incorrect color format - found non-hexadecimal character in color \"{$color}\"");
+ }
+ $this->color = $rrggbb;
+ }
+
+ /**
+ * sets the shortname
+ * @param string $shortname the shortname
+ * @throws \AssertionError
+ */
+ public function set_shortname(string $shortname) {
+ assert(strlen($shortname) <= 5);
+ assert(strlen($shortname) > 0);
+ $this->shortname = $shortname;
+ }
+
+ /**
+ * sets whether the course is enabled
+ * @param bool $enabled whether to enable the course
+ */
+ public function set_enabled(bool $enabled) {
+ $this->enabled = $enabled;
+ }
+
+ /**
+ * sets the cached fullname (mainly for deduplicating DB requests)
+ * @param string $fullname the cached fullname
+ */
+ public function set_fullname(string $fullname) {
+ // If we already have a fullname stored and it's different, then we've found data inconsistency.
+ assert($this->fullname === null || $this->fullname === $fullname);
+ $this->fullname = $fullname;
+ }
+
+ /**
+ * get the cached fullname
+ * @return string the cached fullname
+ */
+ public function get_fullname(): string {
+ if ($this->fullname === null) {
+ $this->fullname = course_helper::get_fullname($this->courseid);
+ }
+
+ return $this->fullname;
+ }
+
+ /**
+ * Prepares a string to be eligible for shortname
+ * @param string $shortname the shortname to be prepared
+ * @return string the prepared shortname
+ */
+ public static function prepare_shortname(string $shortname): string {
+ if (strpos($shortname, ' ') !== false) {
+ $shortname = substr($shortname, 0, strpos($shortname, ' '));
+ }
+ if (strlen($shortname) >= 5) {
+ $shortname = substr($shortname, 0, 5);
+ }
+ return strtoupper($shortname);
+ }
+
+ /**
+ * Prepares data for the DB endpoint.
+ * doesn't set ID if it's 0
+ *
+ * @return object a representation of this course and its data
+ */
+ public function prepare_for_db(): object {
+ $obj = new \stdClass();
+
+ $obj->courseid = $this->courseid;
+ $obj->userid = $this->userid;
+ $obj->shortname = $this->shortname;
+ $obj->color = $this->color;
+ $obj->enabled = $this->enabled ? 1 : 0; // The DB uses int instead of bool here.
+
+ if ($this->id !== 0) {
+ $obj->id = $this->id;
+ }
+
+ return $obj;
+ }
+
+ /**
+ * Prepares data for the API endpoint.
+ *
+ * @return array a representation of this course and its data
+ */
+ public function prepare_for_api(): array {
+ return [
+ 'id' => $this->id,
+ 'courseid' => $this->courseid,
+ 'userid' => $this->userid,
+ 'name' => $this->get_fullname(),
+ 'shortname' => $this->shortname,
+ 'color' => $this->color,
+ 'enabled' => $this->enabled ? 1 : 0, // Moodle's API uses int instead of bool.
+ ];
+ }
+
+ /**
+ * Returns the data structure of a course for the API.
+ *
+ * @return external_single_structure The data structure of a course for the API.
+ */
+ public static function api_structure(): external_single_structure {
+ return new external_single_structure(
+ [
+ 'id' => new external_value(PARAM_INT, 'course ID'),
+ 'courseid' => new external_value(PARAM_INT, 'moodle-internal course ID'),
+ 'userid' => new external_value(PARAM_INT, 'The user for whom these course settings are for'),
+ 'name' => new external_value(PARAM_TEXT, 'Full name of this course'),
+ 'shortname' => new external_value(PARAM_TEXT, 'Short name of this course for this user (maximum size: 5 chars)'),
+ 'color' => new external_value(PARAM_TEXT, 'Color for this course as #RRGGBB'),
+ 'enabled' => new external_value(PARAM_BOOL, 'Whether the user wants to see this course'),
+ ]
+ );
+ }
+}
diff --git a/lbplanner/classes/model/reservation.php b/lbplanner/classes/model/reservation.php
new file mode 100644
index 00000000..7f8ac6f6
--- /dev/null
+++ b/lbplanner/classes/model/reservation.php
@@ -0,0 +1,207 @@
+.
+
+/**
+ * Model for a reservation
+ *
+ * @package local_lbplanner
+ * @subpackage helpers
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\model;
+
+use DateTimeImmutable;
+
+use external_single_structure;
+use external_value;
+
+use local_lbplanner\model\slot;
+use local_lbplanner\helpers\slot_helper;
+
+/**
+ * Model class for reservation
+ */
+class reservation {
+ /**
+ * @var int $id ID of reservation
+ */
+ public int $id;
+ /**
+ * @var int $slotid ID of the linked slot
+ */
+ public int $slotid;
+ /**
+ * @var DateTimeImmutable $date date this reservation is on (time will be ignored)
+ */
+ public DateTimeImmutable $date;
+ /**
+ * @var int $userid ID of the user this reservation is for
+ */
+ public int $userid;
+ /**
+ * @var int $reserverid ID of the user who submitted this reservation (either pupil or supervisor)
+ */
+ public int $reserverid;
+ /**
+ * @var ?slot $slot the linked slot (gets filled in by helper functions)
+ */
+ private ?slot $slot;
+ /**
+ * @var ?DateTimeImmutable $datetime the date this reservation starts at, with time filled in
+ */
+ private ?DateTimeImmutable $datetime;
+ /**
+ * @var ?DateTimeImmutable $datetime the date this reservation ends at, with time filled in
+ */
+ private ?DateTimeImmutable $datetimeend;
+
+ /**
+ * Constructs a reservation
+ * @param int $id ID of reservation
+ * @param int $slotid ID of the linked slot
+ * @param DateTimeImmutable $date date this reservation is on (time will be ignored)
+ * @param int $userid ID of the user this reservation is for
+ * @param int $reserverid ID of the user who submitted this reservation (either pupil or supervisor)
+ * @link slot
+ */
+ public function __construct(int $id, int $slotid, DateTimeImmutable $date, int $userid, int $reserverid) {
+ $this->id = $id;
+ $this->slotid = $slotid;
+ $this->date = $date;
+ $this->userid = $userid;
+ $this->reserverid = $reserverid;
+ $this->slot = null;
+ }
+
+ /**
+ * Mark the object as freshly created and sets the new ID
+ * @param int $id the new ID after insertint into the DB
+ * @param ?slot $slot the cached slot object
+ */
+ public function set_fresh(int $id, ?slot $slot) {
+ assert($this->id === 0);
+ assert($id !== 0);
+ $this->id = $id;
+ if (!is_null($slot)) {
+ $this->set_slot($slot);
+ }
+ }
+
+ /**
+ * sets the cached slot object (mainly for deduplicating DB requests)
+ * @param slot $slot the cached slot object
+ */
+ public function set_slot(slot $slot) {
+ assert($this->slotid === $slot->id);
+ $this->slot = $slot;
+ }
+
+ /**
+ * Returns the associated slot.
+ *
+ * @return slot the associated slot
+ */
+ public function get_slot(): slot {
+ if (is_null($this->slot)) {
+ $this->slot = slot_helper::get_slot($this->slotid);
+ }
+
+ return $this->slot;
+ }
+
+ /**
+ * Calculates the exact time and date this reservation is supposed to start
+ *
+ * @return DateTimeImmutable
+ */
+ public function get_datetime(): DateTimeImmutable {
+ if (is_null($this->datetime)) {
+ $slot = $this->get_slot();
+ $this->datetime = slot_helper::amend_date_with_unit_time($slot->startunit, $this->date);
+ }
+
+ return $this->datetime;
+ }
+
+ /**
+ * Calculates the exact time and date this reservation is supposed to start
+ *
+ * @return DateTimeImmutable
+ */
+ public function get_datetime_end(): DateTimeImmutable {
+ if (is_null($this->datetime)) {
+ $slot = $this->get_slot();
+ $this->datetimeend = slot_helper::amend_date_with_unit_time($slot->startunit + $slot->duration, $this->date);
+ }
+
+ return $this->datetimeend;
+ }
+
+ /**
+ * Prepares data for the DB endpoint.
+ * doesn't set ID if it's 0
+ *
+ * @return object a representation of this reservation and its data
+ */
+ public function prepare_for_db(): object {
+ $obj = new \stdClass();
+
+ $obj->slotid = $this->slotid;
+ $obj->date = $this->date;
+ $obj->userid = $this->userid;
+ $obj->reserverid = $this->reserverid;
+
+ if ($this->id !== 0) {
+ $obj->id = $this->id;
+ }
+
+ return $obj;
+ }
+
+ /**
+ * Prepares data for the API endpoint.
+ *
+ * @return array a representation of this reservation and its data
+ */
+ public function prepare_for_api(): array {
+ return [
+ 'id' => $this->id,
+ 'slotid' => $this->slotid,
+ 'date' => $this->date->format('Y-m-d'),
+ 'userid' => $this->userid,
+ 'reserverid' => $this->reserverid,
+ ];
+ }
+
+ /**
+ * Returns the data structure of a reservation for the API.
+ *
+ * @return external_single_structure The data structure of a reservation for the API.
+ */
+ public static function api_structure(): external_single_structure {
+ return new external_single_structure(
+ [
+ 'id' => new external_value(PARAM_INT, 'reservation ID'),
+ 'slotid' => new external_value(PARAM_INT, 'ID of associated slot'),
+ 'date' => new external_value(PARAM_TEXT, 'date of the reservation in YYYY-MM-DD (as per ISO-8601)'),
+ 'userid' => new external_value(PARAM_INT, 'ID of the user this reservation is for'),
+ 'reserverid' => new external_value(PARAM_INT, 'ID of the user who submitted this reservation'),
+ ]
+ );
+ }
+}
diff --git a/lbplanner/classes/model/slot.php b/lbplanner/classes/model/slot.php
new file mode 100644
index 00000000..4621d2c0
--- /dev/null
+++ b/lbplanner/classes/model/slot.php
@@ -0,0 +1,212 @@
+.
+
+/**
+ * Model for a slot
+ *
+ * @package local_lbplanner
+ * @subpackage helpers
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\model;
+
+use local_lbplanner\enums\WEEKDAY;
+use local_lbplanner\helpers\slot_helper;
+
+use external_single_structure;
+use external_value;
+
+/**
+ * Model class for slot
+ */
+class slot {
+ /**
+ * @var int $id ID of slot
+ */
+ public int $id;
+ /**
+ * @var int $startunit Unit this slot starts in
+ */
+ public int $startunit;
+ /**
+ * @var int $duration duration of slot in units
+ */
+ public int $duration;
+ /**
+ * @var int $weekday weekday this slot occurs in
+ */
+ public int $weekday;
+ /**
+ * @var string $room room this slot is for
+ */
+ public string $room;
+ /**
+ * @var int $size how many pupils fit in this slot
+ */
+ public int $size;
+ /**
+ * @var ?int $fullness how many pupils have already reserved this slot (gets filled in by helper functions)
+ */
+ private ?int $fullness;
+ /**
+ * @var ?bool $forcuruser whether the current user has reserved this slot (gets filled in by helper functions)
+ */
+ private ?bool $forcuruser;
+
+ /**
+ * Constructs a new Slot
+ * @param int $id ID of slot
+ * @param int $startunit Unit this slot starts in
+ * @param int $duration duration of slot in units
+ * @param int $weekday weekday this slot occurs in
+ * @param string $room room this slot is for
+ * @param int $size how many pupils fit in this slot
+ * @link slot_helper::SCHOOL_UNITS
+ * @link WEEKDAY
+ */
+ public function __construct(int $id, int $startunit, int $duration, int $weekday, string $room, int $size) {
+ $this->id = $id;
+ assert($startunit > 0);
+ $this->startunit = $startunit;
+ assert($duration > 0);
+ assert($duration + $startunit < count(slot_helper::SCHOOL_UNITS));
+ $this->duration = $duration;
+ $this->weekday = WEEKDAY::from($weekday);
+ assert(strlen($room) > 0 && strlen($room) <= slot_helper::ROOM_MAXLENGTH);
+ $this->room = $room;
+ assert($size >= 0); // Make it technically possible to not allow any students in a room to temporarily disable the slot.
+ $this->size = $size;
+ $this->fullness = null;
+ $this->forcuruser = null;
+ }
+
+ /**
+ * Mark the object as freshly created and sets the new ID
+ * @param int $id the new ID after insertint into the DB
+ */
+ public function set_fresh(int $id) {
+ assert($this->id === 0);
+ assert($id !== 0);
+ $this->id = $id;
+ $this->fullness = 0;
+ $this->forcuruser = false;
+ }
+
+ /**
+ * Returns how many reservations there are for this slot.
+ *
+ * @return int fullness
+ */
+ public function get_fullness(): int {
+ if (is_null($this->fullness)) {
+ $this->check_reservations();
+ }
+
+ return $this->fullness;
+ }
+
+ /**
+ * Returns whether the current user has a reservation for this slot.
+ *
+ * @return bool forcuruser
+ */
+ public function get_forcuruser(): bool {
+ if (is_null($this->forcuruser)) {
+ $this->check_reservations();
+ }
+
+ return $this->forcuruser;
+ }
+
+ /**
+ * Prepares data for the DB endpoint.
+ * doesn't set ID if it's 0
+ *
+ * @return object a representation of this slot and its data
+ */
+ public function prepare_for_db(): object {
+ $obj = new \stdClass();
+
+ $obj->startunit = $this->startunit;
+ $obj->duration = $this->duration;
+ $obj->weekday = $this->weekday;
+ $obj->room = $this->room;
+ $obj->size = $this->size;
+
+ if ($this->id !== 0) {
+ $obj->id = $this->id;
+ }
+ return $obj;
+ }
+
+ /**
+ * Prepares data for the API endpoint.
+ *
+ * @return array a representation of this slot and its data
+ */
+ public function prepare_for_api(): array {
+ return [
+ 'id' => $this->id,
+ 'startunit' => $this->startunit,
+ 'duration' => $this->duration,
+ 'weekday' => $this->weekday,
+ 'room' => $this->room,
+ 'size' => $this->size,
+ 'fullness' => $this->get_fullness(),
+ 'forcuruser' => $this->get_forcuruser(),
+ ];
+ }
+
+ /**
+ * Returns the data structure of a slot for the API.
+ *
+ * @return external_single_structure The data structure of a slot for the API.
+ */
+ public static function api_structure(): external_single_structure {
+ return new external_single_structure(
+ [
+ 'id' => new external_value(PARAM_INT, 'slot ID'),
+ 'startunit' => new external_value(PARAM_INT, 'unit this slot starts in (8:00 is unit 1)'),
+ 'duration' => new external_value(PARAM_INT, 'duration of the slot in units'),
+ 'weekday' => new external_value(PARAM_INT, 'The day this unit repeats weekly: '.WEEKDAY::format()),
+ 'room' => new external_value(PARAM_TEXT, 'The room this slot is for'),
+ 'size' => new external_value(PARAM_INT, 'total capacity of the slot'),
+ 'fullness' => new external_value(PARAM_INT, 'how many people have already reserved this slot'),
+ 'forcuruser' => new external_value(PARAM_BOOL, 'whether the current user has reserved this slot'),
+ ]
+ );
+ }
+
+ /**
+ * Queries reservations for this slot and fills in internal data with that info.
+ */
+ private function check_reservations(): void {
+ global $USER;
+ $reservations = slot_helper::get_reservations_for_slot($this->id);
+
+ $this->fullness = count($reservations);
+
+ foreach ($reservations as $reservation) {
+ if ($reservation->userid === $USER['id']) {
+ $this->forcuruser = true;
+ return;
+ }
+ }
+ $this->forcuruser = false;
+ }
+}
diff --git a/lbplanner/classes/model/slot_filter.php b/lbplanner/classes/model/slot_filter.php
new file mode 100644
index 00000000..c732fb52
--- /dev/null
+++ b/lbplanner/classes/model/slot_filter.php
@@ -0,0 +1,65 @@
+.
+
+/**
+ * Model for a filter for slots
+ *
+ * @package local_lbplanner
+ * @subpackage helpers
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\model;
+
+/**
+ * Model class for a filter for slots
+ */
+class slot_filter {
+ /**
+ * @var int $id ID of filter
+ */
+ public int $id;
+ /**
+ * @var int $id ID of linked slot
+ */
+ public int $slotid;
+ /**
+ * @var ?int $id ID of linked course or null if any
+ */
+ public ?int $courseid;
+ /**
+ * @var ?string $vintage linked class or null if any
+ */
+ public ?string $vintage;
+
+ /**
+ * Constructs new slot_filter
+ * @param int $id ID of filter
+ * @param int $slotid ID of linked slot
+ * @param ?int $courseid ID of linked course or null if any
+ * @param ?string $vintage linked class or null if any
+ */
+ public function __construct(int $id, int $slotid, ?int $courseid, ?string $vintage) {
+ $this->id = $id;
+ $this->slotid = $slotid;
+ $this->courseid = $courseid;
+ if (!is_null($vintage)) {
+ assert(strlen($vintage) <= 7);
+ }
+ $this->vintage = $vintage;
+ }
+}
diff --git a/lbplanner/classes/model/user.php b/lbplanner/classes/model/user.php
new file mode 100644
index 00000000..88eefb61
--- /dev/null
+++ b/lbplanner/classes/model/user.php
@@ -0,0 +1,346 @@
+.
+
+/**
+ * Model for a course
+ *
+ * @package local_lbplanner
+ * @subpackage helpers
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\model;
+
+use coding_exception;
+use external_single_structure;
+use external_value;
+use local_lbplanner\helpers\plan_helper;
+use local_lbplanner\helpers\user_helper;
+use user_picture;
+
+/**
+ * Model class for course
+ */
+class user {
+ /**
+ * @var int $lbpid our userid
+ */
+ private int $lbpid;
+
+ /**
+ * @var int $mdlid moodle's userid
+ */
+ public int $mdlid;
+
+ /**
+ * @var string $theme selected theme
+ */
+ public string $theme;
+
+ /**
+ * @var string $lang user language
+ */
+ public string $lang;
+
+ /**
+ * @var string $colorblindness the kind of color blindness of a user
+ */
+ public string $colorblindness;
+
+ /**
+ * @var int $displaytaskcount The display task count the user has selected in the app.
+ */
+ public int $displaytaskcount;
+
+ /**
+ * @var ?\stdClass $mdluser the cached moodle user
+ */
+ private ?\stdClass $mdluser;
+
+ /**
+ * @var ?string $pfp the cached pfp
+ */
+ private ?string $pfp;
+
+ /**
+ * @var ?int $planid the cached planid
+ */
+ private ?int $planid;
+
+ /**
+ * Constructs a new course
+ * @param int $lbpid ID of the lb planner user
+ * @param int $mdlid ID of the moodle user
+ * @param string $theme user-chosen theme
+ * @param string $lang user language
+ * @param string $colorblindness user's colorblindness
+ * @param int $displaytaskcount user's display task count
+ */
+ public function __construct(
+ int $lbpid,
+ int $mdlid,
+ string $theme,
+ string $lang,
+ string $colorblindness,
+ int $displaytaskcount
+ ) {
+ global $USER;
+ $this->lbpid = $lbpid;
+ $this->mdlid = $mdlid;
+ $this->set_theme($theme);
+ $this->set_lang($lang);
+ $this->set_colorblindness($colorblindness);
+ $this->set_displaytaskcount($displaytaskcount);
+ $this->planid = null;
+ $this->pfp = null;
+
+ if ($mdlid === (int) $USER->id) {
+ $this->mdluser = $USER;
+ } else {
+ $this->mdluser = null;
+ }
+ }
+
+ /**
+ * Takes data from DB and makes a new user obj out of it
+ *
+ * @param object $obj the DB object to get data from
+ * @return user a representation of this user and its data
+ */
+ public static function from_db(object $obj): self {
+ return new self($obj->id, $obj->userid, $obj->theme, $obj->language, $obj->colorblindness, $obj->displaytaskcount);
+ }
+
+ /**
+ * Mark the object as freshly created and sets the new ID
+ * @param int $lbpid the new ID after inserting into the DB
+ * @throws \AssertionError
+ */
+ public function set_fresh(int $lbpid): void {
+ assert($this->lbpid === 0);
+ assert($lbpid !== 0);
+ $this->lbpid = $lbpid;
+ }
+
+ /**
+ * Sets display task count
+ * @param int $count display task count
+ * @throws \coding_exception if $count <= 0
+ */
+ public function set_displaytaskcount(int $count): void {
+ if ($count <= 0) {
+ throw new \coding_exception('User\'s Display Task Count cannot be <= 0');
+ }
+ $this->displaytaskcount = $count;
+ }
+
+ /**
+ * Sets colorblindness
+ * @param string $cbn colorblindness
+ */
+ public function set_colorblindness(string $cbn): void {
+ $this->colorblindness = $cbn;
+ }
+
+ /**
+ * Sets user language
+ * @param string $lang language
+ * @throws \coding_exception if $lang isn't ISO 639-1 conformant
+ */
+ public function set_lang(string $lang): void {
+ if (preg_match('/^[a-z]{2}$/', $lang) !== 1) {
+ throw new \coding_exception('Incorrect language format - must be ISO 639-1, e.g. en or de');
+ }
+ $this->lang = $lang;
+ }
+
+ /**
+ * Sets user theme
+ * @param string $theme theme
+ */
+ public function set_theme(string $theme): void {
+ $this->theme = $theme;
+ }
+
+ /**
+ * sets the associated moodle user (for caching)
+ * @param \stdClass $mdluser
+ */
+ public function set_mdluser(\stdClass $mdluser): void {
+ global $USER;
+ if ($this->mdluser !== null) {
+ if ($this->mdluser->id !== $USER->id) {
+ throw new \coding_exception('tried to set cached mdluser twice');
+ }
+ }
+ $this->mdluser = $mdluser;
+ }
+
+ /**
+ * gets the associated moodle user
+ * @return \stdClass mdluser
+ */
+ public function get_mdluser(): \stdClass {
+ if ($this->mdluser === null) {
+ $this->mdluser = user_helper::get_mdluser($this->mdlid);
+ }
+
+ return $this->mdluser;
+ }
+
+ /**
+ * sets the associated plan ID (for caching)
+ * @param int $planid
+ */
+ public function set_planid(int $planid): void {
+ if ($this->planid !== null) {
+ throw new \coding_exception('tried to set cached planid twice');
+ }
+ $this->planid = $planid;
+ }
+
+ /**
+ * gets the associated plan ID
+ * @return int planid
+ */
+ public function get_planid(): int {
+ if ($this->planid === null) {
+ $this->planid = plan_helper::get_plan_id($this->mdlid);
+ }
+
+ return $this->planid;
+ }
+
+ /**
+ * gets the associated profile picture
+ * @return string pfp
+ */
+ public function get_pfp(): string {
+ if ($this->pfp === null) {
+ global $PAGE;
+ $userpicture = new user_picture($this->get_mdluser());
+ $userpicture->size = 1; // Size f1.
+ $this->pfp = $userpicture->get_url($PAGE)->out(false);
+ }
+
+ return $this->pfp;
+ }
+
+ /**
+ * Prepares data for the DB endpoint.
+ * doesn't set ID if it's 0
+ *
+ * @return object a representation of this course and its data
+ */
+ public function prepare_for_db(): object {
+ $obj = new \stdClass();
+
+ $obj->userid = $this->mdlid;
+ $obj->theme = $this->theme;
+ $obj->language = $this->lang;
+ $obj->colorblindness = $this->colorblindness;
+ $obj->displaytaskcount = $this->displaytaskcount;
+
+ if ($this->lbpid !== 0) {
+ $obj->id = $this->lbpid;
+ }
+
+ return $obj;
+ }
+
+ /**
+ * Prepares shortened data for the API endpoint.
+ *
+ * @return array a shortened representation of this user and its data
+ */
+ public function prepare_for_api_short(): array {
+ $mdluser = $this->get_mdluser();
+ return [
+ 'userid' => $this->mdlid,
+ 'username' => $mdluser->username,
+ 'firstname' => $mdluser->firstname,
+ 'lastname' => $mdluser->lastname,
+ 'profileimageurl' => $this->get_pfp(),
+ 'vintage' => $mdluser->address,
+ ];
+ }
+
+ /**
+ * Returns the shortened data structure of a user for the API.
+ *
+ * @return external_single_structure The shortened data structure of a user for the API.
+ */
+ public static function api_structure_short(): external_single_structure {
+ return new external_single_structure(
+ [
+ 'userid' => new external_value(PARAM_INT, 'The id of the user'),
+ 'username' => new external_value(PARAM_TEXT, 'The username of the user'),
+ 'firstname' => new external_value(PARAM_TEXT, 'The firstname of the user'),
+ 'lastname' => new external_value(PARAM_TEXT, 'The lastname of the user'),
+ 'profileimageurl' => new external_value(PARAM_URL, 'The url of the profile image'),
+ 'vintage' => new external_value(PARAM_TEXT, 'The vintage of the user'),
+ ]
+ );
+ }
+
+ /**
+ * Prepares full data for the API endpoint.
+ *
+ * @return array a full representation of this user and its data
+ */
+ public function prepare_for_api(): array {
+ $mdluser = $this->get_mdluser();
+ return [
+ 'userid' => $mdluser->id,
+ 'username' => $mdluser->username,
+ 'firstname' => $mdluser->firstname,
+ 'lastname' => $mdluser->lastname,
+ 'theme' => $this->theme,
+ 'lang' => $this->lang,
+ 'profileimageurl' => $this->get_pfp(),
+ 'planid' => $this->get_planid(),
+ 'colorblindness' => $this->colorblindness,
+ 'displaytaskcount' => $this->displaytaskcount,
+ 'capabilities' => user_helper::get_user_capability_bitmask($this->mdlid),
+ 'vintage' => $mdluser->address,
+ ];
+ }
+
+ /**
+ * Returns the full data structure of a user for the API.
+ *
+ * @return external_single_structure The full data structure of a user for the API.
+ */
+ public static function api_structure(): external_single_structure {
+ return new external_single_structure(
+ [
+ 'userid' => new external_value(PARAM_INT, 'The id of the user'),
+ 'username' => new external_value(PARAM_TEXT, 'The username of the user'),
+ 'firstname' => new external_value(PARAM_TEXT, 'The firstname of the user'),
+ 'lastname' => new external_value(PARAM_TEXT, 'The lastname of the user'),
+ 'theme' => new external_value(PARAM_TEXT, 'The theme the user has selected'),
+ 'lang' => new external_value(PARAM_TEXT, 'The language the user has selected'),
+ 'profileimageurl' => new external_value(PARAM_URL, 'The url of the profile image'),
+ 'planid' => new external_value(PARAM_INT, 'The id of the plan the user is assigned to'),
+ 'colorblindness' => new external_value(PARAM_TEXT, 'The colorblindness of the user'),
+ 'displaytaskcount' => new external_value(PARAM_INT, 'If the user has the taskcount-enabled 1-yes 0-no'),
+ 'capabilities' => new external_value(PARAM_INT, 'The capabilities of the user represented as a bitmask value'),
+ 'vintage' => new external_value(PARAM_TEXT, 'The vintage of the user'),
+ ]
+ );
+ }
+}
diff --git a/lbplanner/classes/polyfill/Enum.php b/lbplanner/classes/polyfill/Enum.php
new file mode 100644
index 00000000..410c6273
--- /dev/null
+++ b/lbplanner/classes/polyfill/Enum.php
@@ -0,0 +1,130 @@
+.
+
+/**
+ * polyfill for php8 enums
+ *
+ * @package local_lbplanner
+ * @subpackage polyfill
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\polyfill;
+
+use ReflectionClass;
+use ValueError;
+use local_lbplanner\polyfill\EnumCase;
+
+/**
+ * Class which is meant to serve as a substitute for native enums.
+ */
+class Enum {
+ /**
+ * tries to match the passed value to one of the enum values
+ * @param mixed $value the value to be matched
+ * @param bool $try whether to return null (true) or throw an error (false) if not found
+ * @return ?EnumCase the matching enum case or null if not found and $try==true
+ * @throws ValueError if not found and $try==false
+ */
+ private static function find(mixed $value, bool $try): ?EnumCase {
+ foreach (static::cases() as $case) {
+ if ($case->value === $value) {
+ return $case;
+ }
+ }
+
+ if ($try) {
+ return null;
+ } else {
+ throw new ValueError("value {$value} cannot be represented as a value in enum ".static::class);
+ }
+ }
+ /**
+ * tries to match the passed value to one of the enum values
+ * @param mixed $value the value to be matched
+ * @return mixed either the matching enum value or null if not found
+ */
+ public static function try_from(mixed $value): mixed {
+ // TODO: replace with nullsafe operator in php8.
+ $case = static::find($value, true);
+ if (is_null($case)) {
+ return null;
+ } else {
+ return $case->value;
+ }
+ }
+ /**
+ * tries to match the passed value to one of the enum values
+ * @param mixed $value the value to be matched
+ * @return mixed the matching enum value
+ * @throws ValueError if not found
+ */
+ public static function from(mixed $value): mixed {
+ return static::find($value, false)->value;
+ }
+ /**
+ * tries to match the passed value to one of the enum values
+ * @param mixed $value the value to be matched
+ * @return string the matching enum case name
+ * @throws mixed either the matching enum case name or null if not found
+ */
+ public static function try_name_from(mixed $value): ?string {
+ // TODO: replace with nullsafe operator in php8.
+ $case = static::find($value, true);
+ if (is_null($case)) {
+ return null;
+ } else {
+ return $case->name;
+ }
+ }
+ /**
+ * tries to match the passed value to one of the enum values
+ * @param mixed $value the value to be matched
+ * @return string the matching enum case name
+ * @throws ValueError if not found
+ */
+ public static function name_from(mixed $value): string {
+ return static::find($value, false)->name;
+ }
+ /**
+ * Returns an array of all the cases that exist in this enum
+ *
+ * @return EnumCase[] array of cases inside this enum
+ */
+ public static function cases(): array {
+ $reflection = new ReflectionClass(static::class);
+ $cases = [];
+ foreach ($reflection->getConstants() as $name => $val) {
+ array_push($cases, new EnumCase($name, $val));
+ }
+ return $cases;
+ }
+ /**
+ * Formats all possible enum values into a string
+ * Example:
+ * [31=>RED,32=>GREEN,33=>YELLOW]
+ * @return string the resulting string
+ */
+ public static function format(): string {
+ $result = "[";
+ foreach (static::cases() as $case) {
+ $result .= "{$case->value}=>{$case->name},";
+ }
+ $result[-1] = ']';
+ return $result;
+ }
+}
diff --git a/lbplanner/classes/polyfill/EnumCase.php b/lbplanner/classes/polyfill/EnumCase.php
new file mode 100644
index 00000000..f2451977
--- /dev/null
+++ b/lbplanner/classes/polyfill/EnumCase.php
@@ -0,0 +1,50 @@
+.
+
+/**
+ * case for enums
+ *
+ * @package local_lbplanner
+ * @subpackage polyfill
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace local_lbplanner\polyfill;
+
+defined('MOODLE_INTERNAL') || die();
+
+// TODO: revert to native enums once we migrate to php8.
+
+/**
+ * This represents a single case within an Enum
+ */
+class EnumCase {
+ /** @var string the name of the case */
+ public string $name;
+ /** @var string the value of the case */
+ public $value;
+ /**
+ * Constructs an EnumCase
+ *
+ * @param string $name the name of the case
+ * @param mixed $value the value of the case
+ */
+ public function __construct(string $name, $value) {
+ $this->name = $name;
+ $this->value = $value;
+ }
+};
diff --git a/lbplanner/db/access.php b/lbplanner/db/access.php
index 34b52cb3..3e29ec72 100644
--- a/lbplanner/db/access.php
+++ b/lbplanner/db/access.php
@@ -14,29 +14,36 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
+/**
+ * contains access levels, i.e. capabilities
+ *
+ * @package local_lbplanner
+ * @subpackage db
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
defined('MOODLE_INTERNAL') || die();
-$capabilities = array(
- 'local/lb_planner:student' => array(
+$capabilities = [
+ 'local/lb_planner:student' => [
'riskbitmask' => RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
- ),
- 'local/lb_planner:teacher' => array(
+ ],
+ 'local/lb_planner:teacher' => [
'riskbitmask' => RISK_SPAM || RISK_PERSONAL,
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
- ),
- 'local/lb_planner:admin' => array(
+ ],
+ 'local/lb_planner:admin' => [
'riskbitmask' => RISK_SPAM || RISK_PERSONAL,
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
- ),
- 'local/lb_planner:manager' => array(
+ ],
+ 'local/lb_planner:manager' => [
'riskbitmask' => RISK_SPAM || RISK_PERSONAL,
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
- )
-
-
-);
+ ],
+];
diff --git a/lbplanner/db/install.php b/lbplanner/db/install.php
index 1c3512c8..b6ea5700 100644
--- a/lbplanner/db/install.php
+++ b/lbplanner/db/install.php
@@ -14,14 +14,22 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
-use local_lbplanner\helpers\user_helper;
+/**
+ * contains some stuff for the first install of the module
+ *
+ * @package local_lbplanner
+ * @subpackage db
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
use local_lbplanner\helpers\config_helper;
-defined('MOODLE_INTERNAL') || die;
+/**
+ * Runs when plugin is first installed
+ */
function xmldb_local_lbplanner_install() {
- global $DB;
-
+ config_helper::set_default_active_year();
+ config_helper::add_customfield();
}
-config_helper::set_default_active_year();
-
diff --git a/lbplanner/db/install.xml b/lbplanner/db/install.xml
index f0d274fb..86012c1a 100644
--- a/lbplanner/db/install.xml
+++ b/lbplanner/db/install.xml
@@ -114,5 +114,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lbplanner/db/services.php b/lbplanner/db/services.php
index b0e6b9a2..3c6bde75 100644
--- a/lbplanner/db/services.php
+++ b/lbplanner/db/services.php
@@ -14,11 +14,19 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
+/**
+ * contains all service endpoints
+ *
+ * @package local_lbplanner
+ * @subpackage db
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
defined('MOODLE_INTERNAL') || die();
-$functions = array(
- 'local_lbplanner_user_get_user' => array(
+$functions = [
+ 'local_lbplanner_user_get_user' => [
'classname' => 'local_lbplanner_services\user_get_user',
'methodname' => 'get_user',
'classpath' => 'local/lbplanner/services/user/get_user.php',
@@ -26,8 +34,8 @@
'type' => 'read',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_user_get_all_users' => array(
+ ],
+ 'local_lbplanner_user_get_all_users' => [
'classname' => 'local_lbplanner_services\user_get_all_users',
'methodname' => 'get_all_users',
'classpath' => 'local/lbplanner/services/user/get_all_users.php',
@@ -35,17 +43,8 @@
'type' => 'read',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_user_register_user' => array(
- 'classname' => 'local_lbplanner_services\user_register_user',
- 'methodname' => 'register_user',
- 'classpath' => 'local/lbplanner/services/user/register_user.php',
- 'description' => 'Register a new user in the lbplanner app',
- 'type' => 'write',
- 'capabilities' => 'local/lb_planner:student',
- 'ajax' => true,
- ),
- 'local_lbplanner_user_update_user' => array(
+ ],
+ 'local_lbplanner_user_update_user' => [
'classname' => 'local_lbplanner_services\user_update_user',
'methodname' => 'update_user',
'classpath' => 'local/lbplanner/services/user/update_user.php',
@@ -53,17 +52,8 @@
'type' => 'write',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_courses_get_course' => array(
- 'classname' => 'local_lbplanner_services\courses_get_course',
- 'methodname' => 'get_course',
- 'classpath' => 'local/lbplanner/services/courses/get_course.php',
- 'description' => 'Get the data for a course',
- 'type' => 'read',
- 'capabilities' => 'local/lb_planner:student',
- 'ajax' => true,
- ),
- 'local_lbplanner_courses_get_all_courses' => array(
+ ],
+ 'local_lbplanner_courses_get_all_courses' => [
'classname' => 'local_lbplanner_services\courses_get_all_courses',
'methodname' => 'get_all_courses',
'classpath' => 'local/lbplanner/services/courses/get_all_courses.php',
@@ -71,8 +61,8 @@
'type' => 'read',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_courses_update_course' => array(
+ ],
+ 'local_lbplanner_courses_update_course' => [
'classname' => 'local_lbplanner_services\courses_update_course',
'methodname' => 'update_course',
'classpath' => 'local/lbplanner/services/courses/update_course.php',
@@ -80,8 +70,8 @@
'type' => 'write',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_modules_get_module' => array(
+ ],
+ 'local_lbplanner_modules_get_module' => [
'classname' => 'local_lbplanner_services\modules_get_module',
'methodname' => 'get_module',
'classpath' => 'local/lbplanner/services/modules/get_module.php',
@@ -89,8 +79,8 @@
'type' => 'read',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_modules_get_all_modules' => array(
+ ],
+ 'local_lbplanner_modules_get_all_modules' => [
'classname' => 'local_lbplanner_services\modules_get_all_modules',
'methodname' => 'get_all_modules',
'classpath' => 'local/lbplanner/services/modules/get_all_modules.php',
@@ -98,8 +88,8 @@
'type' => 'read',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_modules_get_all_course_modules' => array(
+ ],
+ 'local_lbplanner_modules_get_all_course_modules' => [
'classname' => 'local_lbplanner_services\modules_get_all_course_modules',
'methodname' => 'get_all_course_modules',
'classpath' => 'local/lbplanner/services/modules/get_all_course_modules.php',
@@ -107,8 +97,8 @@
'type' => 'read',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_plan_clear_plan' => array(
+ ],
+ 'local_lbplanner_plan_clear_plan' => [
'classname' => 'local_lbplanner_services\plan_clear_plan',
'methodname' => 'clear_plan',
'classpath' => 'local/lbplanner/services/plan/clear_plan.php',
@@ -116,8 +106,8 @@
'type' => 'write',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_plan_get_plan' => array(
+ ],
+ 'local_lbplanner_plan_get_plan' => [
'classname' => 'local_lbplanner_services\plan_get_plan',
'methodname' => 'get_plan',
'classpath' => 'local/lbplanner/services/plan/get_plan.php',
@@ -125,8 +115,8 @@
'type' => 'read',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_plan_invite_user' => array(
+ ],
+ 'local_lbplanner_plan_invite_user' => [
'classname' => 'local_lbplanner_services\plan_invite_user',
'methodname' => 'invite_user',
'classpath' => 'local/lbplanner/services/plan/invite_user.php',
@@ -134,8 +124,8 @@
'type' => 'write',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_plan_remove_user' => array(
+ ],
+ 'local_lbplanner_plan_remove_user' => [
'classname' => 'local_lbplanner_services\plan_remove_user',
'methodname' => 'remove_user',
'classpath' => 'local/lbplanner/services/plan/remove_user.php',
@@ -143,8 +133,8 @@
'type' => 'write',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_plan_update_plan' => array(
+ ],
+ 'local_lbplanner_plan_update_plan' => [
'classname' => 'local_lbplanner_services\plan_update_plan',
'methodname' => 'update_plan',
'classpath' => 'local/lbplanner/services/plan/update_plan.php',
@@ -152,8 +142,8 @@
'type' => 'write',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_plan_leave_plan' => array(
+ ],
+ 'local_lbplanner_plan_leave_plan' => [
'classname' => 'local_lbplanner_services\plan_leave_plan',
'methodname' => 'leave_plan',
'classpath' => 'local/lbplanner/services/plan/leave_plan.php',
@@ -161,17 +151,8 @@
'type' => 'write',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_plan_add_deadline' => array(
- 'classname' => 'local_lbplanner_services\plan_add_deadline',
- 'methodname' => 'add_deadline',
- 'classpath' => 'local/lbplanner/services/plan/add_deadline.php',
- 'description' => 'Add a deadline to the plan',
- 'type' => 'write',
- 'capabilities' => 'local/lb_planner:student',
- 'ajax' => true,
- ),
- 'local_lbplanner_plan_delete_deadline' => array(
+ ],
+ 'local_lbplanner_plan_delete_deadline' => [
'classname' => 'local_lbplanner_services\plan_delete_deadline',
'methodname' => 'delete_deadline',
'classpath' => 'local/lbplanner/services/plan/delete_deadline.php',
@@ -179,8 +160,8 @@
'type' => 'write',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_user_delete_user' => array(
+ ],
+ 'local_lbplanner_user_delete_user' => [
'classname' => 'local_lbplanner_services\user_delete_user',
'methodname' => 'delete_user',
'classpath' => 'local/lbplanner/services/user/delete_user.php',
@@ -188,26 +169,17 @@
'type' => 'write',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_plan_update_deadline' => array(
- 'classname' => 'local_lbplanner_services\plan_update_deadline',
- 'methodname' => 'update_deadline',
- 'classpath' => 'local/lbplanner/services/plan/update_deadline.php',
- 'description' => 'Update a deadline from the plan',
+ ],
+ 'local_lbplanner_plan_set_deadline' => [
+ 'classname' => 'local_lbplanner_services\plan_set_deadline',
+ 'methodname' => 'set_deadline',
+ 'classpath' => 'local/lbplanner/services/plan/set_deadline.php',
+ 'description' => 'Set a deadline from the plan',
'type' => 'write',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_plan_get_access' => array(
- 'classname' => 'local_lbplanner_services\plan_get_access',
- 'methodname' => 'get_access',
- 'classpath' => 'local/lbplanner/services/plan/get_access.php',
- 'description' => 'Get the access type to the plan',
- 'type' => 'read',
- 'capabilities' => 'local/lb_planner:student',
- 'ajax' => true,
- ),
- 'local_lbplanner_plan_update_access' => array(
+ ],
+ 'local_lbplanner_plan_update_access' => [
'classname' => 'local_lbplanner_services\plan_update_access',
'methodname' => 'update_access',
'classpath' => 'local/lbplanner/services/plan/update_access.php',
@@ -215,8 +187,8 @@
'type' => 'write',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_plan_get_invites' => array(
+ ],
+ 'local_lbplanner_plan_get_invites' => [
'classname' => 'local_lbplanner_services\plan_get_invites',
'methodname' => 'get_invites',
'classpath' => 'local/lbplanner/services/plan/get_invites.php',
@@ -224,8 +196,8 @@
'type' => 'read',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_notifications_get_all_notifications' => array(
+ ],
+ 'local_lbplanner_notifications_get_all_notifications' => [
'classname' => 'local_lbplanner_services\notifications_get_all_notifications',
'methodname' => 'get_all_notifications',
'classpath' => 'local/lbplanner/services/notifications/get_all_notifications.php',
@@ -233,8 +205,8 @@
'type' => 'read',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_notifications_update_notification' => array(
+ ],
+ 'local_lbplanner_notifications_update_notification' => [
'classname' => 'local_lbplanner_services\notifications_update_notification',
'methodname' => 'update_notification',
'classpath' => 'local/lbplanner/services/notifications/update_notification.php',
@@ -242,8 +214,8 @@
'type' => 'write',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_feedback_submit_feedback' => array(
+ ],
+ 'local_lbplanner_feedback_submit_feedback' => [
'classname' => 'local_lbplanner_services\feedback_submit_feedback',
'methodname' => 'submit_feedback',
'classpath' => 'local/lbplanner/services/feedback/submit_feedback.php',
@@ -251,17 +223,8 @@
'type' => 'write',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_feedback_get_feedback' => array(
- 'classname' => 'local_lbplanner_services\feedback_get_feedback',
- 'methodname' => 'get_feedback',
- 'classpath' => 'local/lbplanner/services/feedback/get_feedback.php',
- 'description' => 'Get the feedback of the given id',
- 'type' => 'read',
- 'capabilities' => 'local/lb_planner:admin, local/lb_planner:manager',
- 'ajax' => true,
- ),
- 'local_lbplanner_feedback_get_all_feedbacks' => array(
+ ],
+ 'local_lbplanner_feedback_get_all_feedbacks' => [
'classname' => 'local_lbplanner_services\feedback_get_all_feedbacks',
'methodname' => 'get_all_feedbacks',
'classpath' => 'local/lbplanner/services/feedback/get_all_feedbacks.php',
@@ -269,8 +232,8 @@
'type' => 'read',
'capabilities' => 'local/lb_planner:admin, local/lb_planner:manager',
'ajax' => true,
- ),
- 'local_lbplanner_feedback_update_feedback' => array(
+ ],
+ 'local_lbplanner_feedback_update_feedback' => [
'classname' => 'local_lbplanner_services\feedback_update_feedback',
'methodname' => 'update_feedback',
'classpath' => 'local/lbplanner/services/feedback/update_feedback.php',
@@ -278,8 +241,8 @@
'type' => 'write',
'capabilities' => 'local/lb_planner:admin, local/lb_planner:manager',
'ajax' => true,
- ),
- 'local_lbplanner_feedback_delete_feedback' => array(
+ ],
+ 'local_lbplanner_feedback_delete_feedback' => [
'classname' => 'local_lbplanner_services\feedback_delete_feedback',
'methodname' => 'delete_feedback',
'classpath' => 'local/lbplanner/services/feedback/delete_feedback.php',
@@ -287,8 +250,8 @@
'type' => 'write',
'capabilities' => 'local/lb_planner:admin, local/lb_planner:manager',
'ajax' => true,
- ),
- 'local_lbplanner_plan_accept_invite' => array(
+ ],
+ 'local_lbplanner_plan_accept_invite' => [
'classname' => 'local_lbplanner_services\plan_accept_invite',
'methodname' => 'accept_invite',
'classpath' => 'local/lbplanner/services/plan/accept_invite.php',
@@ -296,8 +259,8 @@
'type' => 'write',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_plan_decline_invite' => array(
+ ],
+ 'local_lbplanner_plan_decline_invite' => [
'classname' => 'local_lbplanner_services\plan_decline_invite',
'methodname' => 'decline_invite',
'classpath' => 'local/lbplanner/services/plan/decline_invite.php',
@@ -305,8 +268,8 @@
'type' => 'write',
'capabilities' => 'local/lb_planner:student',
'ajax' => true,
- ),
- 'local_lbplanner_config_get_version' => array(
+ ],
+ 'local_lbplanner_config_get_version' => [
'classname' => 'local_lbplanner_services\config_get_version',
'methodname' => 'get_version',
'classpath' => 'local/lbplanner/services/config/get_version.php',
@@ -314,23 +277,74 @@
'type' => 'read',
'capabilities' => '',
'ajax' => true,
- ),
-);
+ ],
+ 'local_lbplanner_slots_get_my_slots' => [
+ 'classname' => 'local_lbplanner_services\slots_get_my_slots',
+ 'methodname' => 'get_my_slots',
+ 'classpath' => 'local/lbplanner/services/slots/get_my_slots.php',
+ 'description' => 'Get all slots the user can theoretically reserve.',
+ 'type' => 'read',
+ 'capabilities' => 'local/lb_planner:student',
+ 'ajax' => true,
+ ],
+ 'local_lbplanner_slots_get_student_slots' => [
+ 'classname' => 'local_lbplanner_services\slots_get_student_slots',
+ 'methodname' => 'get_student_slots',
+ 'classpath' => 'local/lbplanner/services/slots/get_student_slots.php',
+ 'description' => 'Get all slots a supervisor can theoretically reserve for a student.',
+ 'type' => 'read',
+ 'capabilities' => 'local/lb_planner:student',
+ 'ajax' => true,
+ ],
+ 'local_lbplanner_slots_get_supervisor_slots' => [
+ 'classname' => 'local_lbplanner_services\slots_get_supervisor_slots',
+ 'methodname' => 'get_supervisor_slots',
+ 'classpath' => 'local/lbplanner/services/slots/get_supervisor_slots.php',
+ 'description' => 'Get all slots belonging to the supervisor.',
+ 'type' => 'read',
+ 'capabilities' => 'local/lb_planner:student',
+ 'ajax' => true,
+ ],
+ 'local_lbplanner_slots_book_reservation' => [
+ 'classname' => 'local_lbplanner_services\slots_book_reservation',
+ 'methodname' => 'book_reservation',
+ 'classpath' => 'local/lbplanner/services/slots/book_reservation.php',
+ 'description' => 'Book a reservation',
+ 'type' => 'write',
+ 'capabilities' => 'local/lb_planner:student',
+ 'ajax' => true,
+ ],
+ 'local_lbplanner_slots_unbook_reservation' => [
+ 'classname' => 'local_lbplanner_services\slots_unbook_reservation',
+ 'methodname' => 'unbook_reservation',
+ 'classpath' => 'local/lbplanner/services/slots/unbook_reservation.php',
+ 'description' => 'Unbook a reservation',
+ 'type' => 'write',
+ 'capabilities' => 'local/lb_planner:student',
+ 'ajax' => true,
+ ],
+ 'local_lbplanner_slots_create_slot' => [
+ 'classname' => 'local_lbplanner_services\slots_create_slot',
+ 'methodname' => 'create_slot',
+ 'classpath' => 'local/lbplanner/services/slots/create_slot.php',
+ 'description' => 'Create a slot',
+ 'type' => 'write',
+ 'capabilities' => 'local/lb_planner:teacher',
+ 'ajax' => true,
+ ],
+];
-$services = array(
- 'LB Planner API' => array(
- 'functions' => array(
+$services = [
+ 'LB Planner API' => [
+ 'functions' => [
'local_lbplanner_user_get_user',
'local_lbplanner_user_get_all_users',
- 'local_lbplanner_user_register_user',
'local_lbplanner_user_update_user',
'local_lbplanner_courses_get_all_courses',
- 'local_lbplanner_courses_get_course',
'local_lbplanner_courses_update_course',
'local_lbplanner_modules_get_all_course_modules',
'local_lbplanner_modules_get_all_modules',
'local_lbplanner_modules_get_module',
- 'local_lbplanner_plan_add_deadline',
'local_lbplanner_plan_clear_plan',
'local_lbplanner_plan_delete_deadline',
'local_lbplanner_plan_get_plan',
@@ -338,7 +352,7 @@
'local_lbplanner_plan_get_invites',
'local_lbplanner_plan_leave_plan',
'local_lbplanner_plan_remove_user',
- 'local_lbplanner_plan_update_deadline',
+ 'local_lbplanner_plan_set_deadline',
'local_lbplanner_plan_update_plan',
'local_lbplanner_notifications_get_all_notifications',
'local_lbplanner_notifications_update_notification',
@@ -348,14 +362,18 @@
'local_lbplanner_feedback_submit_feedback',
'local_lbplanner_feedback_delete_feedback',
'local_lbplanner_feedback_get_all_feedbacks',
- 'local_lbplanner_feedback_get_feedback',
'local_lbplanner_feedback_update_feedback',
'local_lbplanner_plan_accept_invite',
'local_lbplanner_plan_decline_invite',
'local_lbplanner_config_get_version',
- ),
+ 'local_lbplanner_slots_book_reservation',
+ 'local_lbplanner_slots_create_slot',
+ 'local_lbplanner_slots_get_my_slots',
+ 'local_lbplanner_slots_get_student_slots',
+ 'local_lbplanner_slots_get_supervisor_slots',
+ ],
'restrictedusers' => 0,
'enabled' => 1,
- 'shortname' => 'lb_planner_api'
- ),
-);
+ 'shortname' => 'lb_planner_api',
+ ],
+];
diff --git a/lbplanner/db/upgrade.php b/lbplanner/db/upgrade.php
index bd52dcd0..feee43e2 100644
--- a/lbplanner/db/upgrade.php
+++ b/lbplanner/db/upgrade.php
@@ -14,10 +14,29 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
+/**
+ * for upgrading the db
+ *
+ * @package local_lbplanner
+ * @subpackage db
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
use local_lbplanner\helpers\config_helper;
-function xmldb_local_lbplanner_upgrade($oldversion) {
- config_helper::set_default_active_year();
+/**
+ * Upgrades the DB version
+ * right now it only sets the default active year
+ *
+ * @param mixed $oldversion (unused) the previous version to upgrade from
+ * @return bool true
+ */
+function xmldb_local_lbplanner_upgrade($oldversion): bool {
+ if ($oldversion < 2024022700) {
+ config_helper::set_default_active_year();
+ config_helper::add_customfield();
+ }
return true;
}
diff --git a/lbplanner/lang/en/local_lbplanner.php b/lbplanner/lang/en/local_lbplanner.php
index 85f45bbd..71a353f1 100644
--- a/lbplanner/lang/en/local_lbplanner.php
+++ b/lbplanner/lang/en/local_lbplanner.php
@@ -14,7 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
-defined('MOODLE_INTERNAL') or die();
+/**
+ * Defines some translation strings in english
+ *
+ * @package local_lbplanner
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
$string['pluginname'] = 'LB Planner';
$string['lb_planner:student'] = 'LB Planner Student';
diff --git a/lbplanner/services/config/get_version.php b/lbplanner/services/config/get_version.php
index 3f3c51ec..1f66b731 100644
--- a/lbplanner/services/config/get_version.php
+++ b/lbplanner/services/config/get_version.php
@@ -23,25 +23,43 @@
/**
* Get version service.
+ *
+ * @package local_lbplanner
+ * @subpackage services_config
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class config_get_version extends external_api {
- public static function get_version_parameters() {
+ /**
+ * Parameters for get_version.
+ * @return external_function_parameters
+ */
+ public static function get_version_parameters(): external_function_parameters {
return new external_function_parameters(
- array()
+ []
);
}
- public static function get_version() {
- $release = get_config('local_lbplanner', 'release');
- return array(
- 'release' => get_config('local_lbplanner', 'release'));
+ /**
+ * Returns the version.
+ *
+ * @return array containing the version
+ */
+ public static function get_version(): array {
+ return [
+ 'release' => get_config('local_lbplanner', 'release'),
+ ];
}
- public static function get_version_returns() {
+ /**
+ * Returns the structure of the versioning array.
+ * @return external_single_structure
+ */
+ public static function get_version_returns(): external_single_structure {
return new external_single_structure(
- array(
+ [
'release' => new external_value(PARAM_TEXT, 'the current LBPlanner version'),
- )
+ ]
);
}
}
diff --git a/lbplanner/services/courses/get_all_courses.php b/lbplanner/services/courses/get_all_courses.php
index d50fcf58..2ee6374e 100644
--- a/lbplanner/services/courses/get_all_courses.php
+++ b/lbplanner/services/courses/get_all_courses.php
@@ -16,105 +16,50 @@
namespace local_lbplanner_services;
-use coding_exception;
-use dml_exception;
use external_api;
use external_function_parameters;
use external_multiple_structure;
-use external_single_structure;
-use external_value;
-use invalid_parameter_exception;
-use local_lbplanner\helpers\user_helper;
+
use local_lbplanner\helpers\course_helper;
-use moodle_exception;
+use local_lbplanner\model\course;
/**
* Get all the courses of the current year.
+ *
+ * @package local_lbplanner
+ * @subpackage services_courses
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class courses_get_all_courses extends external_api {
+
+ /**
+ * Has no Parameters
+ * @return external_function_parameters
+ */
public static function get_all_courses_parameters(): external_function_parameters {
- return new external_function_parameters(array(
- 'userid' => new external_value(
- PARAM_INT,
- 'The id of the user to get the courses for',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- ));
+ return new external_function_parameters([]);
}
/**
- * @throws coding_exception
- * @throws dml_exception
- * @throws moodle_exception
- * @throws invalid_parameter_exception
+ * Get all the courses of the current year.
*/
- public static function get_all_courses($userid): array {
- global $DB;
-
- self::validate_parameters(self::get_all_courses_parameters(), array('userid' => $userid));
-
- user_helper::assert_access($userid);
-
- $courses = enrol_get_my_courses();
- // Remove Duplicates.
- $courses = array_unique($courses, SORT_REGULAR);
-
- // Check this out: https://www.youtube.com/watch?v=z3Pzfi476HI .
- $catgirls = array();
-
+ public static function get_all_courses(): array {
+ $courses = course_helper::get_all_lbplanner_courses();
+ $results = [];
foreach ($courses as $course) {
- $courseid = $course->id;
- $name = $course->fullname;
- $shortname = substr($course->shortname, 0, 5);
-
- if (strpos($shortname, ' ') !== false) {
- $shortname = substr($shortname, 0, strpos($shortname, ' '));
- }
-
- if (!course_helper::check_current_year($courseid)) {
- continue;
- }
- if ($DB->record_exists(
- course_helper::LBPLANNER_COURSE_TABLE, array('courseid' => $courseid, 'userid' => $userid)
- )) {
- $fetchedcourse = $DB->get_record(
- course_helper::LBPLANNER_COURSE_TABLE, array('courseid' => $courseid, 'userid' => $userid),
- '*',
- MUST_EXIST
- );
- $fetchedcourse->name = $name;
- $catgirls[] = (object) $fetchedcourse;
- } else {
- $catgirl = (object) array(
- 'courseid' => $courseid,
- 'color' => course_helper::COLORS[array_rand(course_helper::COLORS)],
- 'shortname' => strtoupper($shortname),
- 'enabled' => course_helper::DISABLED_COURSE,
- 'userid' => $userid,
- );
- $DB->insert_record(course_helper::LBPLANNER_COURSE_TABLE, $catgirl);
- $catgirl->name = $name;
- $catgirls[] = $catgirl;
- }
-
+ array_push($results, $course->prepare_for_api());
}
- return $catgirls;
+ return $results;
}
+ /**
+ * Returns description of method result value
+ * @return external_multiple_structure description of method result value
+ */
public static function get_all_courses_returns(): external_multiple_structure {
return new external_multiple_structure(
- new external_single_structure(
- array(
- 'courseid' => new external_value(PARAM_INT, 'The id of the course'),
- 'color' => new external_value(PARAM_TEXT, 'The color of the course'),
- 'name' => new external_value(PARAM_TEXT, 'The name of the course'),
- 'shortname' => new external_value(PARAM_TEXT, 'The shortname of the course'),
- 'enabled' => new external_value(PARAM_BOOL, 'Whether the course is enabled or not'),
- 'userid' => new external_value(PARAM_INT, 'The id of the user'),
- )
- )
+ course::api_structure()
);
}
}
diff --git a/lbplanner/services/courses/get_course.php b/lbplanner/services/courses/get_course.php
deleted file mode 100644
index e59d98fc..00000000
--- a/lbplanner/services/courses/get_course.php
+++ /dev/null
@@ -1,74 +0,0 @@
-.
-
-namespace local_lbplanner_services;
-
-use external_api;
-use external_function_parameters;
-use external_single_structure;
-use external_value;
-use local_lbplanner\helpers\user_helper;
-use local_lbplanner\helpers\course_helper;
-
-/**
- * Get the data for a course.
- */
-class courses_get_course extends external_api {
- public static function get_course_parameters() {
- return new external_function_parameters(array(
- 'courseid' => new external_value(PARAM_INT, 'The id of the course', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'userid' => new external_value(PARAM_INT, 'The id of the user', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- ));
- }
-
- public static function get_course($courseid, $userid) {
- global $DB;
-
- self::validate_parameters(self::get_course_parameters(), array('courseid' => $courseid, 'userid' => $userid));
-
- if (!$DB->record_exists('course', array('id' => $courseid))) {
- throw new \moodle_exception('Course not found');
- }
-
- user_helper::assert_access($userid);
-
- if (!course_helper::check_access($courseid, $userid)) {
- throw new \moodle_exception('Not Enrolled in course');
- }
-
- $course = $DB->get_record(
- course_helper::LBPLANNER_COURSE_TABLE,
- array('courseid' => $courseid, 'userid' => $userid),
- '*',
- MUST_EXIST
- );
- $course->name = course_helper::get_fullname($course->courseid);
- return $course;
- }
-
- public static function get_course_returns() {
- return new external_single_structure(
- array(
- 'courseid' => new external_value(PARAM_INT, 'The id of the course'),
- 'color' => new external_value(PARAM_TEXT, 'The color of the course'),
- 'name' => new external_value(PARAM_TEXT, 'The name of the course'),
- 'shortname' => new external_value(PARAM_TEXT, 'The shortname of the course'),
- 'enabled' => new external_value(PARAM_BOOL, 'Whether the course is enabled or not'),
- 'userid' => new external_value(PARAM_INT, 'The id of the user'),
- )
- );
- }
-}
diff --git a/lbplanner/services/courses/update_course.php b/lbplanner/services/courses/update_course.php
index 21c2dcf2..26ed6a87 100644
--- a/lbplanner/services/courses/update_course.php
+++ b/lbplanner/services/courses/update_course.php
@@ -16,77 +16,87 @@
namespace local_lbplanner_services;
+use dml_exception;
use external_api;
use external_function_parameters;
-use external_single_structure;
use external_value;
-use local_lbplanner\helpers\user_helper;
+use invalid_parameter_exception;
use local_lbplanner\helpers\course_helper;
+use moodle_exception;
/**
* Update the data for a course.
+ *
+ * @package local_lbplanner
+ * @subpackage services_courses
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class courses_update_course extends external_api {
- public static function update_course_parameters() {
- return new external_function_parameters(array(
+ /**
+ * Parameters for update_course.
+ * @return external_function_parameters
+ */
+ public static function update_course_parameters(): external_function_parameters {
+ return new external_function_parameters([
'courseid' => new external_value(PARAM_INT, 'The id of the course', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'color' => new external_value(PARAM_TEXT, 'The color of the course', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'shortname' => new external_value(PARAM_TEXT, 'The shortname of the course', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
+ 'color' => new external_value(PARAM_TEXT, 'The color of the course in HEX', VALUE_DEFAULT, null),
+ 'shortname' => new external_value(PARAM_TEXT, 'The shortname of the course', VALUE_DEFAULT, null),
'enabled' => new external_value(
PARAM_BOOL,
'Whether the course is enabled or not',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
+ VALUE_DEFAULT,
+ null
),
- 'userid' => new external_value(PARAM_INT, 'The id of the user', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- ));
+ ]);
}
- public static function update_course($courseid, $color, $shortname, $enabled, $userid) {
- global $DB;
+ /**
+ * Update the User-data for a course.
+ * @param int $courseid The id of the course
+ * @param string $color The color of the course
+ * @param string $shortname The shortname of the course
+ * @param int $enabled Whether the course is enabled or not (0 or 1)
+ * @return void
+ * @throws moodle_exception
+ */
+ public static function update_course(int $courseid, string $color, string $shortname, int $enabled): void {
+ global $DB, $USER;
self::validate_parameters(
self::update_course_parameters(),
- array(
+ [
'courseid' => $courseid,
'color' => $color,
'shortname' => $shortname,
'enabled' => $enabled,
- 'userid' => $userid
- )
+ ]
);
- user_helper::assert_access($userid);
-
- if (!course_helper::check_access($courseid, $userid)) {
- throw new \moodle_exception('Access denied');
- }
- $course = course_helper::get_lbplanner_course($courseid, $userid);
-
if (strlen($shortname) > 5) {
- throw new \moodle_exception('Shortname is too long');
+ throw new moodle_exception('Shortname is too long');
}
- $course->color = $color;
- $course->shortname = $shortname;
- $course->enabled = $enabled;
- $DB->update_record(course_helper::LBPLANNER_COURSE_TABLE, $course);
- $course->name = course_helper::get_fullname($course->courseid);
+ $course = course_helper::get_lbplanner_course($courseid, $USER->id);
+
+ if ($color !== null) {
+ $course->set_color($color);
+ }
+ if ($shortname !== null) {
+ $course->set_shortname($shortname);
+ }
+ if ($enabled !== null) {
+ $course->set_enabled((bool) $enabled);
+ }
- return $course;
+ $DB->update_record(course_helper::LBPLANNER_COURSE_TABLE, $course->prepare_for_db());
}
+ /**
+ * Returns nothing.
+ * @return null
+ */
public static function update_course_returns() {
- return new external_single_structure(
- array(
- 'courseid' => new external_value(PARAM_INT, 'The id of the course'),
- 'color' => new external_value(PARAM_TEXT, 'The color of the course'),
- 'name' => new external_value(PARAM_TEXT, 'The name of the course'),
- 'shortname' => new external_value(PARAM_TEXT, 'The shortname of the course'),
- 'enabled' => new external_value(PARAM_BOOL, 'Whether the course is enabled or not'),
- 'userid' => new external_value(PARAM_INT, 'The id of the user'),
- )
- );
+ return null;
}
}
diff --git a/lbplanner/services/feedback/delete_feedback.php b/lbplanner/services/feedback/delete_feedback.php
index a75455fb..6b5cefb9 100644
--- a/lbplanner/services/feedback/delete_feedback.php
+++ b/lbplanner/services/feedback/delete_feedback.php
@@ -20,44 +20,56 @@
use external_multiple_structure;
use external_function_parameters;
use external_value;
-use local_lbplanner\helpers\user_helper;
use local_lbplanner\helpers\feedback_helper;
/**
* Deletes feedback from the database.
+ *
+ * @package local_lbplanner
+ * @subpackage services_feedback
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class feedback_delete_feedback extends external_api {
- public static function delete_feedback_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(PARAM_INT, 'The id of the user', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'feedbackid' => new external_value(PARAM_INT, 'The id of the course', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- ));
+ /**
+ * Parameters for delete_feedback.
+ * @return external_function_parameters
+ */
+ public static function delete_feedback_parameters(): external_function_parameters {
+ return new external_function_parameters([
+ 'feedbackid' => new external_value(PARAM_INT, 'ID of the feedback to delete', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
+ ]);
}
- public static function delete_feedback($userid, $feedbackid) {
- global $DB;
+ /**
+ * Deletes feedback from the database.
+ *
+ * @param int $feedbackid ID of the feedback to delete
+ * @return void
+ * @throws \moodle_exception when feedback wasn't found
+ */
+ public static function delete_feedback(int $feedbackid) {
+ global $DB, $USER;
self::validate_parameters(
self::delete_feedback_parameters(),
- array('userid' => $userid , 'feedbackid' => $feedbackid)
+ ['feedbackid' => $feedbackid]
);
- user_helper::assert_access($userid);
-
- if (!$DB->record_exists(feedback_helper::LBPLANNER_FEEDBACK_TABLE, array('id' => $feedbackid))) {
+ if (!$DB->record_exists(feedback_helper::LBPLANNER_FEEDBACK_TABLE, ['id' => $feedbackid])) {
throw new \moodle_exception('feedback_not_found');
}
feedback_helper::assert_admin_access();
- $DB->delete_records(feedback_helper::LBPLANNER_FEEDBACK_TABLE, array('id' => $feedbackid));
-
- return feedback_helper::get_all_feedbacks($userid);
+ $DB->delete_records(feedback_helper::LBPLANNER_FEEDBACK_TABLE, ['id' => $feedbackid]);
}
+ /**
+ * Returns the structure of nothing.
+ * @return null
+ */
public static function delete_feedback_returns() {
- return new external_multiple_structure(
- feedback_helper::structure(),
- );
+ return null;
}
}
diff --git a/lbplanner/services/feedback/get_all_feedbacks.php b/lbplanner/services/feedback/get_all_feedbacks.php
index d33385a1..207ee2ef 100644
--- a/lbplanner/services/feedback/get_all_feedbacks.php
+++ b/lbplanner/services/feedback/get_all_feedbacks.php
@@ -19,36 +19,40 @@
use external_api;
use external_function_parameters;
use external_multiple_structure;
-use external_value;
-use local_lbplanner\helpers\user_helper;
use local_lbplanner\helpers\feedback_helper;
/**
* Get all feedback from the database.
+ *
+ * @package local_lbplanner
+ * @subpackage services_feedback
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class feedback_get_all_feedbacks extends external_api {
- public static function get_all_feedbacks_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(PARAM_INT, 'The id of the user', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- ));
+ /**
+ * Parameters for get_all_feedbacks.
+ * @return external_function_parameters
+ */
+ public static function get_all_feedbacks_parameters(): external_function_parameters {
+ return new external_function_parameters([]);
}
- public static function get_all_feedbacks($userid) {
- global $DB;
-
- self::validate_parameters(
- self::get_all_feedbacks_parameters(),
- array('userid' => $userid)
- );
-
- user_helper::assert_access($userid);
-
+ /**
+ * Returns all feedbacks from the database.
+ *
+ * @return array all feedback objects
+ */
+ public static function get_all_feedbacks(): array {
feedback_helper::assert_admin_access();
-
- return feedback_helper::get_all_feedbacks($userid);
+ return feedback_helper::get_all_feedbacks();
}
- public static function get_all_feedbacks_returns() {
+ /**
+ * Returns the structure of the array of feedbacks.
+ * @return external_multiple_structure
+ */
+ public static function get_all_feedbacks_returns(): external_multiple_structure {
return new external_multiple_structure(
feedback_helper::structure(),
);
diff --git a/lbplanner/services/feedback/get_feedback.php b/lbplanner/services/feedback/get_feedback.php
deleted file mode 100644
index a280630e..00000000
--- a/lbplanner/services/feedback/get_feedback.php
+++ /dev/null
@@ -1,57 +0,0 @@
-.
-
-namespace local_lbplanner_services;
-
-use external_api;
-use external_function_parameters;
-use external_value;
-use local_lbplanner\helpers\user_helper;
-use local_lbplanner\helpers\feedback_helper;
-
-/**
- * Get feedback from the database.
- */
-class feedback_get_feedback extends external_api {
- public static function get_feedback_parameters() {
- return new external_function_parameters(array(
- 'feedbackid' => new external_value(PARAM_INT, 'The id of the course', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'userid' => new external_value(PARAM_INT, 'The id of the user', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- ));
- }
-
- public static function get_feedback($feedbackid, $userid) {
- global $DB;
-
- self::validate_parameters(
- self::get_feedback_parameters(),
- array('feedbackid' => $feedbackid, 'userid' => $userid)
- );
-
- user_helper::assert_access($userid);
- feedback_helper::assert_admin_access();
-
- if (!$DB->record_exists(feedback_helper::LBPLANNER_FEEDBACK_TABLE, array('id' => $feedbackid))) {
- throw new \moodle_exception('feedback_not_found');
- }
-
- return feedback_helper::get_feedback($feedbackid);
- }
-
- public static function get_feedback_returns() {
- return feedback_helper::structure();
- }
-}
diff --git a/lbplanner/services/feedback/submit_feedback.php b/lbplanner/services/feedback/submit_feedback.php
index 15722cb9..1c857c67 100644
--- a/lbplanner/services/feedback/submit_feedback.php
+++ b/lbplanner/services/feedback/submit_feedback.php
@@ -18,49 +18,86 @@
use external_api;
use external_function_parameters;
-use external_single_structure;
use external_value;
-use local_lbplanner\helpers\user_helper;
use local_lbplanner\helpers\feedback_helper;
/**
* Add feedback to the database.
+ *
+ * @package local_lbplanner
+ * @subpackage services_feedback
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class feedback_submit_feedback extends external_api {
- public static function submit_feedback_parameters() {
+ /**
+ * Parameters for submit_feedback.
+ * @return external_function_parameters
+ */
+ public static function submit_feedback_parameters(): external_function_parameters {
return new external_function_parameters(
- array(
- 'userid' => new external_value(PARAM_INT, 'The id of the user', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'type' => new external_value(PARAM_INT, 'The type ', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'content' => new external_value(PARAM_TEXT, 'The content of the feedback', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'logfile' => new external_value(PARAM_TEXT, 'The name of the logfile', VALUE_DEFAULT, null, NULL_NOT_ALLOWED ),
- )
+ [
+ 'type' => new external_value(
+ PARAM_INT,
+ 'type of Feedback (bug, typo, feature, other)', // TODO: use enums.
+ VALUE_REQUIRED,
+ null,
+ NULL_NOT_ALLOWED,
+ ),
+ 'content' => new external_value(
+ PARAM_TEXT,
+ 'feedback contents',
+ VALUE_REQUIRED,
+ null,
+ NULL_NOT_ALLOWED,
+ ),
+ 'logfile' => new external_value(
+ PARAM_TEXT,
+ 'file name of the associated log file',
+ VALUE_DEFAULT,
+ null,
+ NULL_NOT_ALLOWED,
+ ),
+ ]
);
}
- public static function submit_feedback($userid, $type, $content, $logfile) {
- global $DB;
+ /**
+ * Add feedback to the database.
+ *
+ * @param int $type type of Feedback
+ * @see feedback_helper
+ * @param string $content feedback contents
+ * @param string $logfile file name of the associated log file
+ * @return int The ID of the new feedback
+ */
+ public static function submit_feedback(int $type, string $content, string $logfile): int {
+ global $DB, $USER;
self::validate_parameters(
self::submit_feedback_parameters(),
- array('userid' => $userid, 'type' => $type, 'content' => $content, 'logfile' => $logfile)
+ ['type' => $type, 'content' => $content, 'logfile' => $logfile]
);
- user_helper::assert_access($userid);
+ // TODO: validate $type.
- $id = $DB->insert_record(feedback_helper::LBPLANNER_FEEDBACK_TABLE, array(
+ $id = $DB->insert_record(feedback_helper::LBPLANNER_FEEDBACK_TABLE, [
'content' => $content,
- 'userid' => $userid,
+ 'userid' => $USER->id,
'type' => $type,
'status' => feedback_helper::STATUS_UNREAD,
'timestamp' => time(),
'logfile' => $logfile,
- ));
+ ]);
- return feedback_helper::get_feedback($id);
+ return $id;
}
- public static function submit_feedback_returns() {
- return feedback_helper::structure();
+ /**
+ * Returns the structure of the feedback ID.
+ * @return external_value
+ */
+ public static function submit_feedback_returns(): external_value {
+ return new external_value(PARAM_INT, "The ID of the new feedback");
}
}
diff --git a/lbplanner/services/feedback/update_feedback.php b/lbplanner/services/feedback/update_feedback.php
index 256e217d..85df8503 100644
--- a/lbplanner/services/feedback/update_feedback.php
+++ b/lbplanner/services/feedback/update_feedback.php
@@ -20,52 +20,71 @@
use external_function_parameters;
use external_value;
use gradereport_singleview\local\ui\feedback;
-use local_lbplanner\helpers\user_helper;
use local_lbplanner\helpers\feedback_helper;
/**
* Updates feedback from the database.
+ *
+ * @package local_lbplanner
+ * @subpackage services_feedback
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class feedback_update_feedback extends external_api {
- public static function update_feedback_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(PARAM_INT, 'The id of the user', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'feedbackid' => new external_value(PARAM_INT, 'The id of the course', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'notes' => new external_value(PARAM_TEXT, 'The notes of the feedback', VALUE_DEFAULT, null, NULL_ALLOWED),
- 'status' => new external_value(PARAM_INT, 'The status of the feedback', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- ));
+ /**
+ * Parameters for update_feedback.
+ * @return external_function_parameters
+ */
+ public static function update_feedback_parameters(): external_function_parameters {
+ return new external_function_parameters([
+ 'feedbackid' =>
+ new external_value(PARAM_INT, 'ID of the feedback to be updated', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
+ 'notes' => new external_value(PARAM_TEXT, 'updated notes', VALUE_DEFAULT, null, NULL_ALLOWED),
+ 'status' => new external_value(PARAM_INT, 'updated status', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
+ ]);
}
- public static function update_feedback($userid, $feedbackid, $notes, $status) {
- global $DB;
+ /**
+ * Updates feedback from the database.
+ *
+ * @param int $feedbackid ID of the feedback to be updated
+ * @param string $notes updated notes
+ * @param int $status updated status
+ * @see feedback_helper
+ * @return void
+ * @throws \moodle_exception when feedback not found or status invalid
+ */
+ public static function update_feedback(int $feedbackid, string $notes, int $status) {
+ global $DB, $USER;
self::validate_parameters(
self::update_feedback_parameters(),
- array('userid' => $userid , 'feedbackid' => $feedbackid, 'notes' => $notes, 'status' => $status)
+ ['feedbackid' => $feedbackid, 'notes' => $notes, 'status' => $status]
);
- user_helper::assert_access($userid);
feedback_helper::assert_admin_access();
- if (!$DB->record_exists(feedback_helper::LBPLANNER_FEEDBACK_TABLE, array('id' => $feedbackid))) {
+ if (!$DB->record_exists(feedback_helper::LBPLANNER_FEEDBACK_TABLE, ['id' => $feedbackid])) {
throw new \moodle_exception('feedback_not_found');
}
- $feedback = $DB->get_record(feedback_helper::LBPLANNER_FEEDBACK_TABLE, array('id' => $feedbackid), '*', MUST_EXIST);
+ $feedback = $DB->get_record(feedback_helper::LBPLANNER_FEEDBACK_TABLE, ['id' => $feedbackid], '*', MUST_EXIST);
$feedback->notes = $notes;
- if ($status > 1 || $status < 0) {
+ if ($status > 1 || $status < 0) { // TODO: use enum to validate.
throw new \moodle_exception('Invalid status');
}
$feedback->status = $status;
$feedback->lastmodified = time();
- $feedback->lastmodifiedby = $userid;
+ $feedback->lastmodifiedby = $USER->id;
$DB->update_record(feedback_helper::LBPLANNER_FEEDBACK_TABLE, $feedback);
-
- return $feedback;
}
+ /**
+ * Returns the structure of nothing.
+ * @return null
+ */
public static function update_feedback_returns() {
- return feedback_helper::structure();
+ return null;
}
}
diff --git a/lbplanner/services/modules/get_all_course_modules.php b/lbplanner/services/modules/get_all_course_modules.php
index 9ca6555b..7222f68a 100644
--- a/lbplanner/services/modules/get_all_course_modules.php
+++ b/lbplanner/services/modules/get_all_course_modules.php
@@ -21,39 +21,55 @@
use external_multiple_structure;
use external_value;
use local_lbplanner\helpers\modules_helper;
-use local_lbplanner\helpers\user_helper;
/**
* Get all the modules of the given course.
+ *
+ * @package local_lbplanner
+ * @subpackage services_modules
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class modules_get_all_course_modules extends external_api {
- public static function get_all_course_modules_parameters() {
- return new external_function_parameters(array(
+ /**
+ * Parameters for get_all_course_modules
+ * @return external_function_parameters
+ */
+ public static function get_all_course_modules_parameters(): external_function_parameters {
+ return new external_function_parameters([
'courseid' => new external_value(PARAM_INT, 'The id of the course', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'userid' => new external_value(PARAM_INT, 'The id of the user', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
'ekenabled' => new external_value(
- PARAM_BOOL,
- 'Whether or not to include ek modules',
- VALUE_REQUIRED,
- false,
- NULL_NOT_ALLOWED),
- ));
+ PARAM_BOOL,
+ 'Whether to include ek modules',
+ VALUE_DEFAULT,
+ false,
+ NULL_NOT_ALLOWED
+ ),
+ ]);
}
- public static function get_all_course_modules($courseid, $userid, $ekenabled) {
- global $DB;
-
+ /**
+ * Returns all the modules inside a course.
+ *
+ * @param int $courseid The ID of the course
+ * @param bool $ekenabled whether or not to include ek modules
+ * @return array the modules
+ */
+ public static function get_all_course_modules(int $courseid, bool $ekenabled): array {
+ global $USER;
self::validate_parameters(
self::get_all_course_modules_parameters(),
- array('courseid' => $courseid, 'userid' => $userid, 'ekenabled' => $ekenabled)
+ ['courseid' => $courseid, 'ekenabled' => $ekenabled]
);
- user_helper::assert_access($userid);
-
- return modules_helper::get_all_course_modules($courseid, $userid, $ekenabled);
+ return modules_helper::get_all_course_modules($courseid, $USER->id, $ekenabled);
}
- public static function get_all_course_modules_returns() {
+ /**
+ * Returns the structure of the module array.
+ * @return external_multiple_structure
+ */
+ public static function get_all_course_modules_returns(): external_multiple_structure {
return new external_multiple_structure(
modules_helper::structure(),
);
diff --git a/lbplanner/services/modules/get_all_modules.php b/lbplanner/services/modules/get_all_modules.php
index 6d2d08e3..67ee3932 100644
--- a/lbplanner/services/modules/get_all_modules.php
+++ b/lbplanner/services/modules/get_all_modules.php
@@ -19,51 +19,61 @@
use external_api;
use external_function_parameters;
use external_multiple_structure;
-use external_value;
use local_lbplanner\helpers\course_helper;
use local_lbplanner\helpers\modules_helper;
-use local_lbplanner\helpers\user_helper;
use local_lbplanner\helpers\plan_helper;
/**
* Get all the modules of the current year.
+ *
+ * @package local_lbplanner
+ * @subpackage services_modules
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class modules_get_all_modules extends external_api {
- public static function get_all_modules_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(PARAM_INT, 'The id of the user', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- ));
+ /**
+ * Parameters for get_all_modules.
+ * @return external_function_parameters
+ */
+ public static function get_all_modules_parameters(): external_function_parameters {
+ return new external_function_parameters([]);
}
- public static function get_all_modules($userid) {
- global $DB;
+ /**
+ * Returns all the modules for a user.
+ *
+ * @return array the modules
+ */
+ public static function get_all_modules(): array {
+ global $USER;
- self::validate_parameters(self::get_all_modules_parameters(), array('userid' => $userid));
+ $modules = [];
- user_helper::assert_access($userid);
-
- $modules = array();
-
- $courses = self::call_external_function('local_lbplanner_courses_get_all_courses', array('userid' => $userid));
- $plan = plan_helper::get_plan(plan_helper::get_plan_id($userid));
+ $courses = course_helper::get_all_lbplanner_courses();
+ $plan = plan_helper::get_plan(plan_helper::get_plan_id($USER->id));
$ekenabled = $plan["enableek"];
- foreach ($courses["data"] as $course) {
- if ($course["enabled"] == course_helper::DISABLED_COURSE) {
+ foreach ($courses as $course) {
+ if (!$course->enabled) {
continue;
}
$modules = array_merge(
- modules_helper::get_all_course_modules($course['courseid'], $userid, $ekenabled),
+ modules_helper::get_all_course_modules($course->courseid, $USER->id, $ekenabled),
$modules
);
}
return $modules;
}
- public static function get_all_modules_returns() {
+ /**
+ * Returns the structure of the module array.
+ * @return external_multiple_structure
+ */
+ public static function get_all_modules_returns(): external_multiple_structure {
return new external_multiple_structure(
- modules_helper::structure(),
+ modules_helper::structure(),
);
}
}
diff --git a/lbplanner/services/modules/get_module.php b/lbplanner/services/modules/get_module.php
index 4f66f036..a57c33d4 100644
--- a/lbplanner/services/modules/get_module.php
+++ b/lbplanner/services/modules/get_module.php
@@ -18,6 +18,7 @@
use external_api;
use external_function_parameters;
+use external_single_structure;
use external_value;
use local_lbplanner\helpers\modules_helper;
use local_lbplanner\helpers\plan_helper;
@@ -25,30 +26,50 @@
/**
* Get the data for a module.
+ *
+ * @package local_lbplanner
+ * @subpackage services_modules
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class modules_get_module extends external_api {
- public static function get_module_parameters() {
- return new external_function_parameters(array(
+ /**
+ * Parameters for get_module.
+ * @return external_function_parameters
+ */
+ public static function get_module_parameters(): external_function_parameters {
+ return new external_function_parameters([
'moduleid' => new external_value(PARAM_INT, 'The id of the module', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
'userid' => new external_value(PARAM_INT, 'The id of the user', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- ));
+ ]);
}
- public static function get_module($moduleid, $userid) {
+ /**
+ * Returns the data for a module
+ *
+ * @param int $moduleid The ID of the course
+ * @param int $userid The ID of the user
+ * @return array the module
+ */
+ public static function get_module(int $moduleid, int $userid): array {
global $DB;
- self::validate_parameters(self::get_module_parameters(), array('moduleid' => $moduleid, 'userid' => $userid));
+ self::validate_parameters(self::get_module_parameters(), ['moduleid' => $moduleid, 'userid' => $userid]);
user_helper::assert_access($userid);
- if (!$DB->record_exists(modules_helper::ASSIGN_TABLE, array('id' => $moduleid))) {
+ if (!$DB->record_exists(modules_helper::MDL_ASSIGN_TABLE, ['id' => $moduleid])) {
throw new \moodle_exception('Module not found');
}
return modules_helper::get_module($moduleid, $userid);
}
- public static function get_module_returns() {
+ /**
+ * Returns the structure of the module.
+ * @return external_single_structure
+ */
+ public static function get_module_returns(): external_single_structure {
return modules_helper::structure();
}
}
diff --git a/lbplanner/services/notifications/get_all_notifications.php b/lbplanner/services/notifications/get_all_notifications.php
index 06f52bde..36b71fb3 100644
--- a/lbplanner/services/notifications/get_all_notifications.php
+++ b/lbplanner/services/notifications/get_all_notifications.php
@@ -19,34 +19,39 @@
use external_api;
use external_function_parameters;
use external_multiple_structure;
-use external_single_structure;
-use external_value;
-use local_lbplanner\helpers\user_helper;
use local_lbplanner\helpers\notifications_helper;
/**
- * Get all the notifications of the given user.
+ * Get all the notifications of the user.
+ *
+ * @package local_lbplanner
+ * @subpackage services_notifications
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class notifications_get_all_notifications extends external_api {
- public static function get_all_notifications_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(PARAM_INT, 'User ID', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- ));
+ /**
+ * Parameters for get_all_notifications.
+ * @return external_function_parameters
+ */
+ public static function get_all_notifications_parameters(): external_function_parameters {
+ return new external_function_parameters([]);
}
- public static function get_all_notifications($userid) {
- global $DB;
+ /**
+ * Returns all the notifications of the user
+ *
+ * @return array
+ */
+ public static function get_all_notifications(): array {
+ global $DB, $USER;
- self::validate_parameters(self::get_all_notifications_parameters(), array('userid' => $userid));
+ $dbnotifications = $DB->get_records(notifications_helper::LBPLANNER_NOTIFICATION_TABLE, ['userid' => $USER->id]);
- user_helper::assert_access($userid);
-
- $dbnotifications = $DB->get_records(notifications_helper::TABLE, array('userid' => $userid));
-
- $notifications = array();
+ $notifications = [];
foreach ($dbnotifications as $dbnotification) {
- $notifications[] = array(
+ $notifications[] = [
'status' => $dbnotification->status,
'type' => $dbnotification->type,
'info' => $dbnotification->info,
@@ -54,24 +59,18 @@ public static function get_all_notifications($userid) {
'notificationid' => $dbnotification->id,
'timestamp' => $dbnotification->timestamp,
'timestamp_read' => $dbnotification->timestamp_read,
- );
+ ];
}
return $notifications;
}
- public static function get_all_notifications_returns() {
+ /**
+ * Returns the structure of the array of notifications.
+ * @return external_multiple_structure
+ */
+ public static function get_all_notifications_returns(): external_multiple_structure {
return new external_multiple_structure(
- new external_single_structure(
- array(
- 'status' => new external_value(PARAM_INT, 'The status of the notification {0: unread, 1: read}'),
- 'type' => new external_value(PARAM_INT, 'The type of the event that triggered the notification'),
- 'info' => new external_value(PARAM_INT, 'Additional information about the notification'),
- 'userid' => new external_value(PARAM_INT, 'The ID of the user for whom the notification is for'),
- 'notificationid' => new external_value(PARAM_INT, 'The ID of the notification', NULL_NOT_ALLOWED),
- 'timestamp' => new external_value(PARAM_INT, 'The timestamp of the notification'),
- 'timestamp_read' => new external_value(PARAM_INT, 'The timestamp of the notification when it was read'),
- )
- )
+ notifications_helper::structure()
);
}
}
diff --git a/lbplanner/services/notifications/update_notification.php b/lbplanner/services/notifications/update_notification.php
index 912cb2b0..64262fe6 100644
--- a/lbplanner/services/notifications/update_notification.php
+++ b/lbplanner/services/notifications/update_notification.php
@@ -18,71 +18,75 @@
use external_api;
use external_function_parameters;
-use external_single_structure;
use external_value;
-use local_lbplanner\helpers\user_helper;
+use local_lbplanner\enums\NOTIF_STATUS;
use local_lbplanner\helpers\notifications_helper;
/**
- * Update the notification status of the given user and id.
+ * Update the notification status.
+ *
+ * @package local_lbplanner
+ * @subpackage services_notifications
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class notifications_update_notification extends external_api {
- public static function update_notification_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(PARAM_INT, 'User ID', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
+ /**
+ * Parameters for update_notification.
+ * @return external_function_parameters
+ */
+ public static function update_notification_parameters(): external_function_parameters {
+ return new external_function_parameters([
'status' => new external_value(
PARAM_INT,
- 'The status of the notification {0: unread, 1: read}',
+ 'notification status ' . NOTIF_STATUS::format(),
VALUE_REQUIRED,
null,
NULL_NOT_ALLOWED
),
- 'notificationid' => new external_value(PARAM_INT, 'The ID of the notification', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- ));
+ 'notificationid' =>
+ new external_value(PARAM_INT, 'ID of the notification to be updated', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
+ ]);
}
- public static function update_notification($userid, $status, $notificationid) {
+ /**
+ * Update the notification status.
+ *
+ * @param int $status notification status
+ * @see notifications_helper
+ * @param int $notificationid ID of the notification to be updated
+ * @return void
+ * @throws \moodle_exception when the notification doesn't exist
+ */
+ public static function update_notification(int $status, int $notificationid) {
global $DB;
self::validate_parameters(
self::update_notification_parameters(),
- array('userid' => $userid, 'status' => $status, 'notificationid' => $notificationid)
+ ['status' => $status, 'notificationid' => $notificationid]
);
- user_helper::assert_access($userid);
-
- if (!$DB->record_exists(notifications_helper::TABLE, array('id' => $notificationid))) {
+ if (!$DB->record_exists(notifications_helper::LBPLANNER_NOTIFICATION_TABLE, ['id' => $notificationid])) {
throw new \moodle_exception('Notification does not exist');
}
- $notification = $DB->get_record(notifications_helper::TABLE, array('id' => $notificationid), '*', MUST_EXIST);
+ $notification = $DB->get_record(
+ notifications_helper::LBPLANNER_NOTIFICATION_TABLE,
+ ['id' => $notificationid],
+ '*',
+ MUST_EXIST
+ );
$notification->status = $status;
$notification->timestamp_read = time();
- $DB->update_record(notifications_helper::TABLE, $notification);
-
- return array(
- 'status' => $notification->status,
- 'type' => $notification->type,
- 'info' => $notification->info,
- 'userid' => $notification->userid,
- 'notificationid' => $notification->id,
- 'timestamp' => $notification->timestamp,
- 'timestamp_read' => $notification->timestamp_read,
- );
+ $DB->update_record(notifications_helper::LBPLANNER_NOTIFICATION_TABLE, $notification);
}
+ /**
+ * Returns the structure of nothing.
+ * @return null
+ */
public static function update_notification_returns() {
- return new external_single_structure(
- array(
- 'status' => new external_value(PARAM_INT, 'The status of the notification {0: unread, 1: read}'),
- 'type' => new external_value(PARAM_INT, 'The type of the event that triggered the notification'),
- 'info' => new external_value(PARAM_INT, 'Additional information about the notification'),
- 'userid' => new external_value(PARAM_INT, 'The ID of the user for whom the notification is for'),
- 'notificationid' => new external_value(PARAM_INT, 'The ID of the notification'),
- 'timestamp' => new external_value(PARAM_INT, 'The timestamp of the notification'),
- 'timestamp_read' => new external_value(PARAM_INT, 'The timestamp of the notification'),
- )
- );
+ return null;
}
}
diff --git a/lbplanner/services/plan/accept_invite.php b/lbplanner/services/plan/accept_invite.php
index c0105850..7729818d 100644
--- a/lbplanner/services/plan/accept_invite.php
+++ b/lbplanner/services/plan/accept_invite.php
@@ -18,47 +18,58 @@
use external_api;
use external_function_parameters;
-use external_single_structure;
use external_value;
-use local_lbplanner\helpers\user_helper;
use local_lbplanner\helpers\plan_helper;
use local_lbplanner\helpers\notifications_helper;
+use local_lbplanner\enums\{PLAN_ACCESS_TYPE, PLAN_INVITE_STATE, NOTIF_TRIGGER};
/**
- * Update a invite from the plan.
+ * Accept an invite to the plan.
+ *
+ * @package local_lbplanner
+ * @subpackage services_plan
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plan_accept_invite extends external_api {
- public static function accept_invite_parameters() {
- return new external_function_parameters(array(
- 'inviteid' => new external_value(PARAM_INT, 'The id of the plan', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'userid' => new external_value(PARAM_INT, 'The id of the invited user', VALUE_REQUIRED, null, NULL_NOT_ALLOWED)
- ));
+ /**
+ * Parameters for accept_invite.
+ * @return external_function_parameters
+ */
+ public static function accept_invite_parameters(): external_function_parameters {
+ return new external_function_parameters([
+ 'inviteid' => new external_value(PARAM_INT, 'the ID of the invite to be accepted', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
+ ]);
}
- public static function accept_invite($inviteid, $userid) {
- global $DB;
-
- self::validate_parameters(self::accept_invite_parameters(), array(
+ /**
+ * Accepts an invite
+ *
+ * @param int $inviteid the ID of the invite to be accepted
+ * @return void
+ * @throws \moodle_exception when invite not found, already accepted or declined
+ */
+ public static function accept_invite(int $inviteid) {
+ global $DB, $USER;
+
+ self::validate_parameters(self::accept_invite_parameters(), [
'inviteid' => $inviteid,
- 'userid' => $userid,
- ));
-
- user_helper::assert_access($userid);
+ ]);
- if (!$DB->record_exists(plan_helper::INVITES_TABLE, array('id' => $inviteid, 'inviteeid' => $userid))) {
+ if (!$DB->record_exists(plan_helper::INVITES_TABLE, ['id' => $inviteid, 'inviteeid' => $USER->id])) {
throw new \moodle_exception('Invite not found');
}
if (!$DB->record_exists(plan_helper::INVITES_TABLE,
- array( 'id' => $inviteid, 'inviteeid' => $userid, 'status' => plan_helper::INVITE_PENDING))) {
+ [ 'id' => $inviteid, 'inviteeid' => $USER->id, 'status' => PLAN_INVITE_STATE::PENDING])) {
throw new \moodle_exception('Invite already accepted or declined');
}
$invite = $DB->get_record(plan_helper::INVITES_TABLE,
- array(
+ [
'id' => $inviteid,
- 'inviteeid' => $userid,
- 'status' => plan_helper::INVITE_PENDING,
- ),
+ 'inviteeid' => $USER->id,
+ 'status' => PLAN_INVITE_STATE::PENDING,
+ ],
'*',
MUST_EXIST
);
@@ -67,75 +78,61 @@ public static function accept_invite($inviteid, $userid) {
notifications_helper::notify_user(
$invite->inviterid,
$invite->id,
- notifications_helper::TRIGGER_INVITE_ACCEPTED
+ NOTIF_TRIGGER::INVITE_ACCEPTED
);
- // If the User is the User has Member in his plan, then removes it.
- $oldplanid = plan_helper::get_plan_id($userid);
- if (plan_helper::get_owner($oldplanid) == $userid) {
+ // Deletes the old plan if the user is the owner of it.
+ $oldplanid = plan_helper::get_plan_id($USER->id);
+ if (plan_helper::get_owner($oldplanid) == $USER->id) {
foreach (plan_helper::get_plan_members($oldplanid) as $member) {
- if ($member->userid != $userid) {
- self::call_external_function('local_lbplanner_plan_remove_user', array(
+ if ($member->userid != $USER->id) {
+ self::call_external_function('local_lbplanner_plan_remove_user', [
'planid' => $oldplanid,
- 'userid' => $member->userid
- ));
+ 'userid' => $member->userid,
+ ]);
}
}
- self::call_external_function('local_lbplanner_plan_clear_plan', array(
+ // TODO: replace with helper function.
+ self::call_external_function('local_lbplanner_plan_clear_plan', [
'planid' => $oldplanid,
- 'userid' => $userid
- ));
- $DB->delete_records(plan_helper::TABLE, array('id' => $oldplanid));
+ 'userid' => $USER->id,
+ ]);
+ $DB->delete_records(plan_helper::TABLE, ['id' => $oldplanid]);
}
// Updates the plan access.
$planaccess = $DB->get_record(
plan_helper::ACCESS_TABLE,
- array(
+ [
'planid' => $oldplanid,
- 'userid' => $userid
- ),
+ 'userid' => $USER->id,
+ ],
'*',
MUST_EXIST
);
- $invite->status = plan_helper::INVITE_ACCEPTED;
+ $invite->status = PLAN_INVITE_STATE::ACCEPTED;
$DB->update_record(plan_helper::INVITES_TABLE, $invite);
- $planaccess->accesstype = plan_helper::ACCESS_TYPE_READ;
+ $planaccess->accesstype = PLAN_ACCESS_TYPE::READ;
$planaccess->planid = $invite->planid;
$DB->update_record(plan_helper::ACCESS_TABLE, $planaccess);
- $invites = plan_helper::get_invites_send($userid);
+ $invites = plan_helper::get_invites_send($USER->id);
foreach ($invites as $invite) {
- if ($invite->status == plan_helper::INVITE_PENDING) {
- $invite->status = plan_helper::INVITE_EXPIRED;
+ if ($invite->status == PLAN_INVITE_STATE::PENDING) {
+ $invite->status = PLAN_INVITE_STATE::EXPIRED;
$DB->update_record(plan_helper::INVITES_TABLE, $invite);
}
}
-
- return array(
- 'id' => $invite->id,
- 'inviterid' => $invite->inviterid,
- 'inviteeid' => $invite->inviteeid,
- 'planid' => $invite->planid,
- 'status' => $invite->status,
- 'timestamp' => $invite->timestamp,
- );
}
-
+ /**
+ * Returns the structure of nothing.
+ * @return null
+ */
public static function accept_invite_returns() {
- return new external_single_structure(
- array(
- 'id' => new external_value(PARAM_INT, 'The id of the invite'),
- 'inviterid' => new external_value(PARAM_INT, 'The id of the owner user'),
- 'inviteeid' => new external_value(PARAM_INT, 'The id of the invited user'),
- 'planid' => new external_value(PARAM_INT, 'The id of the plan'),
- 'status' => new external_value(PARAM_INT, 'The Status of the invitation'),
- 'timestamp' => new external_value(PARAM_INT, 'The time when the invitation was send'),
- )
- );
+ return null;
}
}
diff --git a/lbplanner/services/plan/add_deadline.php b/lbplanner/services/plan/add_deadline.php
deleted file mode 100644
index 3dd6329c..00000000
--- a/lbplanner/services/plan/add_deadline.php
+++ /dev/null
@@ -1,110 +0,0 @@
-.
-
-namespace local_lbplanner_services;
-
-use external_api;
-use external_function_parameters;
-use external_value;
-use local_lbplanner\helpers\user_helper;
-use local_lbplanner\helpers\plan_helper;
-
-/**
- * Add a deadline to the plan.
- */
-class plan_add_deadline extends external_api {
- public static function add_deadline_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(
- PARAM_INT,
- 'The id of the user to get the data for',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- 'planid' => new external_value(
- PARAM_INT,
- 'The ID of the Plan',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- 'moduleid' => new external_value(
- PARAM_INT,
- 'The ID of the Module',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- 'deadlinestart' => new external_value(
- PARAM_INT,
- 'The Start of the Module',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- 'deadlineend' => new external_value(
- PARAM_INT,
- 'The End of the Module',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- ));
- }
-
- public static function add_deadline($userid, $planid, $moduleid, $deadlinestart, $deadlineend) {
- global $DB;
-
- self::validate_parameters(
- self::add_deadline_parameters(),
- array(
- 'userid' => $userid,
- 'planid' => $planid,
- 'moduleid' => $moduleid,
- 'deadlinestart' => $deadlinestart,
- 'deadlineend' => $deadlineend,
- )
- );
-
- user_helper::assert_access($userid);
-
- if ( !plan_helper::check_edit_permissions( $planid, $userid ) ) {
- throw new \moodle_exception('Access denied');
- }
-
- if ($DB->record_exists(plan_helper::DEADLINES_TABLE, array('moduleid' => $moduleid, 'planid' => $planid))) {
- throw new \moodle_exception('Deadline already exists');
- }
-
- $deadline = new \stdClass();
-
- $deadline->planid = $planid;
- $deadline->moduleid = $moduleid;
- $deadline->deadlinestart = $deadlinestart;
- $deadline->deadlineend = $deadlineend;
-
- $DB->insert_record(plan_helper::DEADLINES_TABLE, $deadline);
-
- $plan = $DB->get_record(plan_helper::TABLE, array('id' => $planid));
-
- return plan_helper::get_plan($planid);
- }
-
- public static function add_deadline_returns() {
- return plan_helper::plan_structure();
- }
-}
diff --git a/lbplanner/services/plan/clear_plan.php b/lbplanner/services/plan/clear_plan.php
index 30755937..6a90fd97 100644
--- a/lbplanner/services/plan/clear_plan.php
+++ b/lbplanner/services/plan/clear_plan.php
@@ -18,52 +18,48 @@
use external_api;
use external_function_parameters;
-use external_value;
use local_lbplanner\helpers\plan_helper;
-use local_lbplanner\helpers\user_helper;
/**
* Clear the plan for the given user.
+ *
+ * @package local_lbplanner
+ * @subpackage services_plan
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plan_clear_plan extends external_api {
- public static function clear_plan_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(
- PARAM_INT,
- 'The id of the user to get the data for',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- 'planid' => new external_value(
- PARAM_INT,
- 'The id of the plan',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- ));
+ /**
+ * Parameters for clear_plan.
+ * @return external_function_parameters
+ */
+ public static function clear_plan_parameters(): external_function_parameters {
+ return new external_function_parameters([]);
}
- public static function clear_plan($userid, $planid) {
- global $DB;
+ /**
+ * Clear the plan.
+ *
+ * @return void
+ * @throws Exception when access denied
+ */
+ public static function clear_plan() {
+ global $DB, $USER;
- self::validate_parameters(self::clear_plan_parameters(), array('userid' => $userid, 'planid' => $planid));
+ $planid = plan_helper::get_plan_id($USER->id);
- user_helper::assert_access($userid);
-
- if (!plan_helper::check_edit_permissions($planid, $userid)) {
+ if (!plan_helper::check_edit_permissions($planid, $USER->id)) {
throw new \Exception('Access denied');
}
- $DB->delete_records(plan_helper::DEADLINES_TABLE, array('planid' => $planid ));
-
- $plan = $DB->get_record(plan_helper::TABLE, array('id' => $planid));
-
- return plan_helper::get_plan($planid);
+ $DB->delete_records(plan_helper::DEADLINES_TABLE, ['planid' => $planid ]);
}
+ /**
+ * Returns the structure of nothing.
+ * @return null
+ */
public static function clear_plan_returns() {
- return plan_helper::plan_structure();
+ return null;
}
}
diff --git a/lbplanner/services/plan/decline_invite.php b/lbplanner/services/plan/decline_invite.php
index 67341ca5..044672e9 100644
--- a/lbplanner/services/plan/decline_invite.php
+++ b/lbplanner/services/plan/decline_invite.php
@@ -18,83 +18,78 @@
use external_api;
use external_function_parameters;
-use external_single_structure;
use external_value;
-use local_lbplanner\helpers\user_helper;
use local_lbplanner\helpers\plan_helper;
use local_lbplanner\helpers\notifications_helper;
+use local_lbplanner\enums\{NOTIF_TRIGGER, PLAN_INVITE_STATE};
/**
- * Update a invite from the plan.
+ * Decline an invite from the plan.
+ *
+ * @package local_lbplanner
+ * @subpackage services_plan
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plan_decline_invite extends external_api {
- public static function decline_invite_parameters() {
- return new external_function_parameters(array(
- 'inviteid' => new external_value(PARAM_INT, 'The inviteid of the plan', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'userid' => new external_value(PARAM_INT, 'The id of the invited user', VALUE_REQUIRED, null, NULL_NOT_ALLOWED)
- ));
+ /**
+ * Parameters for decline_invite.
+ * @return external_function_parameters
+ */
+ public static function decline_invite_parameters(): external_function_parameters {
+ return new external_function_parameters([
+ 'inviteid' => new external_value(PARAM_INT, 'the ID of the invite to be declined', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
+ ]);
}
- public static function decline_invite($inviteid, $userid) {
- global $DB;
+ /**
+ * Decline an invite.
+ *
+ * @param int $inviteid the ID of the invite to be declined
+ * @return void
+ * @throws \moodle_exception when invite not found, already accepted or declined
+ */
+ public static function decline_invite(int $inviteid) {
+ global $DB, $USER;
- self::validate_parameters(self::decline_invite_parameters(), array(
+ self::validate_parameters(self::decline_invite_parameters(), [
'inviteid' => $inviteid,
- 'userid' => $userid,
- ));
+ ]);
- user_helper::assert_access($userid);
-
- if (!$DB->record_exists(plan_helper::INVITES_TABLE, array('id' => $inviteid, 'inviteeid' => $userid))) {
+ if (!$DB->record_exists(plan_helper::INVITES_TABLE, ['id' => $inviteid, 'inviteeid' => $USER->id])) {
throw new \moodle_exception('Invite not found');
}
- if (!$DB->record_exists(plan_helper::INVITES_TABLE,
- array('id' => $inviteid, 'inviteeid' => $userid, 'status' => plan_helper::INVITE_PENDING))) {
- throw new \moodle_exception('Invite already accepted or declined');
- }
$invite = $DB->get_record(plan_helper::INVITES_TABLE,
- array(
+ [
'id' => $inviteid,
- 'inviteeid' => $userid,
- 'status' => plan_helper::INVITE_PENDING,
- ),
+ 'inviteeid' => $USER->id,
+ ],
'*',
MUST_EXIST
);
+ if ($invite->status !== PLAN_INVITE_STATE::PENDING) {
+ throw new \moodle_exception('Invite already accepted or declined');
+ }
+
// Notify the user that invite has been declined.
notifications_helper::notify_user(
$invite->inviterid,
$invite->id,
- notifications_helper::TRIGGER_INVITE_DECLINED
+ NOTIF_TRIGGER::INVITE_DECLINED
);
- $invite->status = plan_helper::INVITE_DECLINED;
+ $invite->status = PLAN_INVITE_STATE::DECLINED;
$DB->update_record(plan_helper::INVITES_TABLE, $invite);
-
- return array(
- 'id' => $invite->id,
- 'inviterid' => $invite->inviterid,
- 'inviteeid' => $invite->inviteeid,
- 'planid' => $invite->planid,
- 'status' => $invite->status,
- 'timestamp' => $invite->timestamp,
- );
}
-
+ /**
+ * Returns the structure of nothing.
+ * @return null
+ */
public static function decline_invite_returns() {
- return new external_single_structure(
- array(
- 'id' => new external_value(PARAM_INT, 'The id of the invite'),
- 'inviterid' => new external_value(PARAM_INT, 'The id of the owner user'),
- 'inviteeid' => new external_value(PARAM_INT, 'The id of the invited user'),
- 'planid' => new external_value(PARAM_INT, 'The id of the plan'),
- 'status' => new external_value(PARAM_INT, 'The Status of the invitation'),
- 'timestamp' => new external_value(PARAM_INT, 'The time when the invitation was send'),
- )
- );
+ return null;
}
}
diff --git a/lbplanner/services/plan/delete_deadline.php b/lbplanner/services/plan/delete_deadline.php
index 971bfb4d..d9a9d215 100644
--- a/lbplanner/services/plan/delete_deadline.php
+++ b/lbplanner/services/plan/delete_deadline.php
@@ -20,68 +20,69 @@
use external_function_parameters;
use external_value;
use local_lbplanner\helpers\plan_helper;
-use local_lbplanner\helpers\user_helper;
/**
- * Delete a deadline from the plan.
+ * Delete a deadline from your plan
+ *
+ * @package local_lbplanner
+ * @subpackage services_plan
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plan_delete_deadline extends external_api {
- public static function delete_deadline_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(
- PARAM_INT,
- 'The id of the user to get the data for',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- 'planid' => new external_value(
- PARAM_INT,
- 'The ID of the Plan',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
+ /**
+ * Parameters for delete_deadline.
+ * @return external_function_parameters
+ */
+ public static function delete_deadline_parameters(): external_function_parameters {
+ return new external_function_parameters([
'moduleid' => new external_value(
PARAM_INT,
- 'The ID of the Module',
+ 'ID of the Module',
VALUE_REQUIRED,
null,
NULL_NOT_ALLOWED
),
- ));
+ ]);
}
- public static function delete_deadline($userid, $planid, $moduleid) {
- global $DB;
+ /**
+ * Delete a deadline.
+ *
+ * @param int $moduleid ID of the Module
+ * @return void
+ * @throws Exception when access denied
+ */
+ public static function delete_deadline(int $moduleid) {
+ global $DB, $USER;
self::validate_parameters(
self::delete_deadline_parameters(),
- array(
- 'userid' => $userid,
- 'planid' => $planid,
+ [
'moduleid' => $moduleid,
- )
+ ]
);
- user_helper::assert_access($userid);
+ $planid = plan_helper::get_plan_id($USER->id);
- if (!plan_helper::check_edit_permissions($planid, $userid)) {
+ if (!plan_helper::check_edit_permissions($planid, $USER->id)) {
throw new \Exception('Access denied');
}
$DB->delete_records(
plan_helper::DEADLINES_TABLE,
- array(
- 'planid' => $planid ,
- 'moduleid' => $moduleid
- )
+ [
+ 'planid' => $planid,
+ 'moduleid' => $moduleid,
+ ]
);
-
- return plan_helper::get_plan($planid);
}
+ /**
+ * Returns the structure of nothing.
+ * @return null
+ */
public static function delete_deadline_returns() {
- return plan_helper::plan_structure();
+ return null;
}
}
diff --git a/lbplanner/services/plan/get_access.php b/lbplanner/services/plan/get_access.php
deleted file mode 100644
index d209ca76..00000000
--- a/lbplanner/services/plan/get_access.php
+++ /dev/null
@@ -1,70 +0,0 @@
-.
-
-namespace local_lbplanner_services;
-
-use external_api;
-use external_function_parameters;
-use external_single_structure;
-use external_value;
-use local_lbplanner\helpers\plan_helper;
-use local_lbplanner\helpers\user_helper;
-
-/**
- * Get the access type to the plan.
- */
-class plan_get_access extends external_api {
- public static function get_access_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(
- PARAM_INT,
- 'The id of the user to get the data for',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- 'planid' => new external_value(
- PARAM_INT,
- 'The id of the plan',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- ));
- }
-
- public static function get_access($userid, $planid) {
- self::validate_parameters(self::get_access_parameters(), array('userid' => $userid, 'planid' => $planid));
-
- user_helper::assert_access($userid);
-
- return array(
- 'accesstype' => plan_helper::get_access_type($userid, $planid),
- 'planid' => $planid,
- 'userid' => $userid,
- );
- }
-
- public static function get_access_returns() {
- return new external_single_structure(
- array(
- 'accesstype' => new external_value(PARAM_INT, 'The type of access the user has to the plan'),
- 'planid' => new external_value(PARAM_INT, 'The id of the plan'),
- 'userid' => new external_value(PARAM_INT, 'The id of the plan'),
- )
- );
- }
-}
diff --git a/lbplanner/services/plan/get_invites.php b/lbplanner/services/plan/get_invites.php
index ca2e02db..dbeddf01 100644
--- a/lbplanner/services/plan/get_invites.php
+++ b/lbplanner/services/plan/get_invites.php
@@ -18,80 +18,72 @@
use external_api;
use external_function_parameters;
-use external_single_structure;
use external_multiple_structure;
-use external_value;
-use local_lbplanner\helpers\user_helper;
+use local_lbplanner\helpers\invite_helper;
use local_lbplanner\helpers\plan_helper;
/**
- * Get all the invites of the given user.
+ * Get all the invites of the current user.
+ *
+ * @package local_lbplanner
+ * @subpackage services_plan
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plan_get_invites extends external_api {
- public static function get_invites_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(
- PARAM_INT,
- 'The id of the Owner of the plan',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- ));
+ /**
+ * Parameters for get_invites.
+ * @return external_function_parameters
+ */
+ public static function get_invites_parameters(): external_function_parameters {
+ return new external_function_parameters([]);
}
- public static function get_invites($userid) {
- global $DB;
+ /**
+ * Returns all invites of the current user.
+ *
+ * @return array
+ */
+ public static function get_invites(): array {
+ global $DB, $USER;
- self::validate_parameters(
- self::get_invites_parameters(),
- array('userid' => $userid)
- );
-
- user_helper::assert_access($userid);
-
- $invitesreceived = $DB->get_records(plan_helper::INVITES_TABLE, array('inviteeid' => $userid));
- $invitessent = $DB->get_records(plan_helper::INVITES_TABLE, array('inviterid' => $userid));
+ $invitesreceived = $DB->get_records(plan_helper::INVITES_TABLE, ['inviteeid' => $USER->id]);
+ $invitessent = $DB->get_records(plan_helper::INVITES_TABLE, ['inviterid' => $USER->id]);
- $invites = array();
+ $invites = [];
foreach ($invitesreceived as $invite) {
- $invites[] = array(
+ $invites[] = [
'id' => $invite->id,
'inviterid' => $invite->inviterid,
'inviteeid' => $invite->inviteeid,
'planid' => $invite->planid,
'status' => $invite->status,
'timestamp' => $invite->timestamp,
- );
+ ];
}
foreach ($invitessent as $invitesent) {
- $invites[] = array(
+ $invites[] = [
'id' => $invitesent->id,
'inviterid' => $invitesent->inviterid,
'inviteeid' => $invitesent->inviteeid,
'planid' => $invitesent->planid,
'status' => $invitesent->status,
'timestamp' => $invitesent->timestamp,
- );
+ ];
}
return $invites;
}
- public static function get_invites_returns() {
+ /**
+ * Returns the structure of the array of invites.
+ * @return external_multiple_structure
+ */
+ public static function get_invites_returns(): external_multiple_structure {
return new external_multiple_structure(
- new external_single_structure(
- array(
- 'id' => new external_value(PARAM_INT, 'The id of the invite'),
- 'inviterid' => new external_value(PARAM_INT, 'The id of the owner user'),
- 'inviteeid' => new external_value(PARAM_INT, 'The id of the invited user'),
- 'planid' => new external_value(PARAM_INT, 'The id of the plan'),
- 'status' => new external_value(PARAM_INT, 'The Status of the invitation'),
- 'timestamp' => new external_value(PARAM_INT, 'The time when the invitation was send'),
- )
- )
+ invite_helper::structure()
);
}
}
diff --git a/lbplanner/services/plan/get_plan.php b/lbplanner/services/plan/get_plan.php
index e5aa3693..822c2e82 100644
--- a/lbplanner/services/plan/get_plan.php
+++ b/lbplanner/services/plan/get_plan.php
@@ -18,41 +18,44 @@
use external_api;
use external_function_parameters;
-use external_value;
+use external_single_structure;
use local_lbplanner\helpers\plan_helper;
-use local_lbplanner\helpers\user_helper;
/**
* Get the plan of the given user.
+ *
+ * @package local_lbplanner
+ * @subpackage services_plan
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plan_get_plan extends external_api {
- public static function get_plan_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(
- PARAM_INT,
- 'The id of the user',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- ));
+ /**
+ * Parameters for get_plan.
+ * @return external_function_parameters
+ */
+ public static function get_plan_parameters(): external_function_parameters {
+ return new external_function_parameters([]);
}
- public static function get_plan($userid) {
- global $DB;
+ /**
+ * Returns the plan of the current user.
+ *
+ * @return array
+ */
+ public static function get_plan(): array {
+ global $DB, $USER;
- self::validate_parameters(self::get_plan_parameters(), array('userid' => $userid));
-
- user_helper::assert_access($userid);
-
- $planid = plan_helper::get_plan_id($userid);
-
- $plan = $DB->get_record(plan_helper::TABLE, array('id' => $planid));
+ $planid = plan_helper::get_plan_id($USER->id);
return plan_helper::get_plan($planid);
}
- public static function get_plan_returns() {
+ /**
+ * Returns the structure of the plan.
+ * @return external_single_structure
+ */
+ public static function get_plan_returns(): external_single_structure {
return plan_helper::plan_structure();
}
}
diff --git a/lbplanner/services/plan/invite_user.php b/lbplanner/services/plan/invite_user.php
index 722800dd..e572fdf1 100644
--- a/lbplanner/services/plan/invite_user.php
+++ b/lbplanner/services/plan/invite_user.php
@@ -20,54 +20,57 @@
use external_function_parameters;
use external_single_structure;
use external_value;
+use local_lbplanner\helpers\invite_helper;
use local_lbplanner\helpers\plan_helper;
-use local_lbplanner\helpers\user_helper;
use local_lbplanner\helpers\notifications_helper;
+use local_lbplanner\enums\{NOTIF_TRIGGER, PLAN_INVITE_STATE};
/**
- * Invite a user to the plan.
+ * Invite a user to the current user's plan
+ *
+ * @package local_lbplanner
+ * @subpackage services_plan
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plan_invite_user extends external_api {
- public static function invite_user_parameters() {
- return new external_function_parameters(array(
- 'inviterid' => new external_value(
- PARAM_INT,
- 'The id of the Owner of the plan',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
+ /**
+ * Parameters for invite_user.
+ * @return external_function_parameters
+ */
+ public static function invite_user_parameters(): external_function_parameters {
+ return new external_function_parameters([
'inviteeid' => new external_value(
PARAM_INT,
- 'The id of the user who gets invited',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- 'planid' => new external_value(
- PARAM_INT,
- 'The id of the plan',
+ 'ID of the user who gets invited',
VALUE_REQUIRED,
null,
NULL_NOT_ALLOWED
),
- ));
+ ]);
}
- public static function invite_user($inviterid, $inviteeid , $planid) {
- global $DB;
+ /**
+ * Invite a user to the current user's plan
+ *
+ * @param int $inviteeid ID of the user who gets invited
+ * @return mixed the newly created invite
+ */
+ public static function invite_user(int $inviteeid): mixed {
+ global $DB, $USER;
self::validate_parameters(
self::invite_user_parameters(),
- array('inviterid' => $inviterid, 'inviteeid' => $inviteeid, 'planid' => $planid)
+ ['inviteeid' => $inviteeid]
);
- user_helper::assert_access($inviterid);
- if (plan_helper::get_owner($planid) != $inviterid) {
+ $planid = plan_helper::get_plan_id($USER->id);
+
+ if (plan_helper::get_owner($planid) !== $USER->id) {
throw new \moodle_exception('Access denied');
}
- if ($inviterid == $inviteeid) {
+ if ($USER->id === $inviteeid) {
throw new \moodle_exception('Cannot invite yourself');
}
@@ -77,55 +80,36 @@ public static function invite_user($inviterid, $inviteeid , $planid) {
if ($DB->record_exists(
plan_helper::INVITES_TABLE,
- array('inviteeid' => $inviteeid, 'planid' => $planid, 'status' => plan_helper::INVITE_PENDING)
+ ['inviteeid' => $inviteeid, 'planid' => $planid, 'status' => PLAN_INVITE_STATE::PENDING]
)) {
throw new \moodle_exception('User is already invited');
}
- $invitee = user_helper::get_mdl_user_info($inviteeid);
- $inviter = user_helper::get_mdl_user_info($inviterid);
-
- if ($invitee->address != $inviter->address) {
- throw new \moodle_exception('Cannot invite user who is not in the same class');
- }
-
// Save the invite.
$invite = new \stdClass();
$invite->planid = $planid;
- $invite->inviterid = $inviterid;
+ $invite->inviterid = $USER->id;
$invite->inviteeid = $inviteeid;
$invite->timestamp = time();
- $invite->status = plan_helper::INVITE_PENDING;
+ $invite->status = PLAN_INVITE_STATE::PENDING;
$invite->id = $DB->insert_record(plan_helper::INVITES_TABLE, $invite);
- // Notifiy the invitee that he/she/it/they/xier/* has been invited.
+ // Notify the invitee that they've been invited.
notifications_helper::notify_user(
$inviteeid,
$invite->id,
- notifications_helper::TRIGGER_INVITE
+ NOTIF_TRIGGER::INVITE
);
- return array(
- 'id' => $invite->id,
- 'inviterid' => $inviterid,
- 'inviteeid' => $inviteeid,
- 'planid' => $planid,
- 'timestamp' => $invite->timestamp,
- 'status' => $invite->status
- );
+ return $invite;
}
- public static function invite_user_returns() {
- return new external_single_structure(
- array(
- 'id' => new external_value(PARAM_INT, 'The id of the invite'),
- 'inviterid' => new external_value(PARAM_INT, 'The id of the owner user'),
- 'inviteeid' => new external_value(PARAM_INT, 'The id of the invited user'),
- 'planid' => new external_value(PARAM_INT, 'The id of the plan'),
- 'status' => new external_value(PARAM_INT, 'The status of the invitation'),
- 'timestamp' => new external_value(PARAM_INT, 'The time when the invitation was send'),
- )
- );
+ /**
+ * Returns the structure of the invite.
+ * @return external_single_structure
+ */
+ public static function invite_user_returns(): external_single_structure {
+ return invite_helper::structure();
}
}
diff --git a/lbplanner/services/plan/leave_plan.php b/lbplanner/services/plan/leave_plan.php
index acc84fc3..5a7e9b28 100644
--- a/lbplanner/services/plan/leave_plan.php
+++ b/lbplanner/services/plan/leave_plan.php
@@ -18,59 +18,59 @@
use external_api;
use external_function_parameters;
-use external_value;
use local_lbplanner\helpers\plan_helper;
-use local_lbplanner\helpers\user_helper;
use local_lbplanner\helpers\notifications_helper;
+use local_lbplanner\enums\{NOTIF_TRIGGER, PLAN_ACCESS_TYPE, PLAN_INVITE_STATE};
/**
- * Leave the plan of the given user.
+ * Leave your plan
+ *
+ * if no other user exists in the plan, the user can't leave
+ *
+ * @package local_lbplanner
+ * @subpackage services_plan
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plan_leave_plan extends external_api {
- public static function leave_plan_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(
- PARAM_INT,
- 'The id of the user to get the data for',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- 'planid' => new external_value(
- PARAM_INT,
- 'The id of the plan',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- ));
+ /**
+ * Parameters for leave_plan.
+ * @return external_function_parameters
+ */
+ public static function leave_plan_parameters(): external_function_parameters {
+ return new external_function_parameters([]);
}
- public static function leave_plan($userid, $planid) {
- global $DB;
+ /**
+ * Leave your plan
+ *
+ * @return void
+ * @throws \moodle_exception when user is only member left in plan
+ */
+ public static function leave_plan() {
+ global $DB, $USER;
- self::validate_parameters(self::leave_plan_parameters(), array('userid' => $userid, 'planid' => $planid));
+ $planid = plan_helper::get_plan_id($USER->id);
- user_helper::assert_access($userid);
-
- if (plan_helper::get_access_type($userid, $planid) == plan_helper::ACCESS_TYPE_NONE) {
+ // TODO: remove useless check.
+ if (plan_helper::get_access_type($USER->id, $planid) === PLAN_ACCESS_TYPE::NONE) {
throw new \moodle_exception('User is not a member of this plan');
}
- if (plan_helper::get_access_type($userid, $planid) == plan_helper::ACCESS_TYPE_OWNER) {
+ if (plan_helper::get_access_type($USER->id, $planid) === PLAN_ACCESS_TYPE::OWNER) {
$members = plan_helper::get_plan_members($planid);
if (count($members) == 1) {
throw new \moodle_exception('Cannot Leave Plan: Plan must have at least one other member');
}
- $writemembers = array();
- $allmembers = array();
+ $writemembers = [];
+ $allmembers = [];
foreach ($members as $member) {
- if ($member->userid == $userid) {
+ if ($member->userid == $USER->id) {
continue;
}
- if ($member->accesstype == plan_helper::ACCESS_TYPE_WRITE) {
+ if ($member->accesstype == PLAN_ACCESS_TYPE::WRITE) {
$writemembers[] = $member;
}
$allmembers[] = $member;
@@ -82,42 +82,45 @@ public static function leave_plan($userid, $planid) {
}
$newowneraccess = $DB->get_record(
plan_helper::ACCESS_TABLE,
- array('planid' => $planid, 'userid' => $newowner), '*', MUST_EXIST
+ ['planid' => $planid, 'userid' => $newowner], '*', MUST_EXIST
);
- $newowneraccess->accesstype = plan_helper::ACCESS_TYPE_OWNER;
+ $newowneraccess->accesstype = PLAN_ACCESS_TYPE::OWNER;
$DB->update_record(plan_helper::ACCESS_TABLE, $newowneraccess);
}
- $newplanid = plan_helper::copy_plan($planid, $userid);
+ $newplanid = plan_helper::copy_plan($planid, $USER->id);
$oldaccess = $DB->get_record(
plan_helper::ACCESS_TABLE,
- array('planid' => $planid, 'userid' => $userid), '*', MUST_EXIST
+ ['planid' => $planid, 'userid' => $USER->id], '*', MUST_EXIST
);
$oldaccess->planid = $newplanid;
- $oldaccess->accesstype = plan_helper::ACCESS_TYPE_OWNER;
+ $oldaccess->accesstype = PLAN_ACCESS_TYPE::OWNER;
$DB->update_record(plan_helper::ACCESS_TABLE, $oldaccess);
// Notify plan owner that user has left his plan.
- $invites = plan_helper::get_invites_send($userid);
+ $invites = plan_helper::get_invites_send($USER->id);
foreach ($invites as $invite) {
- if ($invite->status == plan_helper::INVITE_PENDING) {
- $invite->status = plan_helper::INVITE_EXPIRED;
+ if ($invite->status == PLAN_INVITE_STATE::PENDING) {
+ $invite->status = PLAN_INVITE_STATE::EXPIRED;
$DB->update_record(plan_helper::INVITES_TABLE, $invite);
}
}
notifications_helper::notify_user(
plan_helper::get_owner($planid),
- $userid,
- notifications_helper::TRIGGER_PLAN_LEFT
+ $USER->id,
+ NOTIF_TRIGGER::PLAN_LEFT
);
-
- return plan_helper::get_plan($planid, $userid);
}
+
+ /**
+ * Returns the structure of nothing.
+ * @return null
+ */
public static function leave_plan_returns() {
- return plan_helper::plan_structure();
+ return null;
}
}
diff --git a/lbplanner/services/plan/remove_user.php b/lbplanner/services/plan/remove_user.php
index 1341ad24..2cd75cfd 100644
--- a/lbplanner/services/plan/remove_user.php
+++ b/lbplanner/services/plan/remove_user.php
@@ -20,34 +20,50 @@
use external_function_parameters;
use external_value;
use local_lbplanner\helpers\plan_helper;
-use local_lbplanner\helpers\user_helper;
/**
- * Remove a user from the plan.
+ * Remove a user from your plan
+ *
+ * @package local_lbplanner
+ * @subpackage services_plan
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plan_remove_user extends external_api {
- public static function remove_user_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(PARAM_INT, 'The id of the user', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'removeuserid' => new external_value(PARAM_INT, 'The id of the user to remove', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'planid' => new external_value(PARAM_INT, 'The id of the plan', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- ));
+ /**
+ * Parameters for remove_user.
+ * @return external_function_parameters
+ */
+ public static function remove_user_parameters(): external_function_parameters {
+ return new external_function_parameters([
+ 'userid' => new external_value(PARAM_INT, 'ID of the user to remove', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
+ ]);
}
- public static function remove_user($userid, $removeuserid, $planid) {
- global $DB;
+ /**
+ * Remove a user from your plan
+ *
+ * @param int $userid ID of the user to remove
+ * @return void
+ */
+ public static function remove_user(int $userid) {
+ global $DB, $USER;
self::validate_parameters(
self::remove_user_parameters(),
- array('userid' => $userid, 'removeuserid' => $removeuserid, 'planid' => $planid)
+ ['userid' => $userid]
);
- user_helper::assert_access($userid);
+ $planid = plan_helper::get_plan_id($USER->id);
- return plan_helper::remove_user($planid, $userid, $removeuserid);
+ plan_helper::remove_user($planid, $USER->id, $userid);
}
+ /**
+ * Returns the structure of nothing.
+ * @return null
+ */
public static function remove_user_returns() {
- return plan_helper::plan_structure();
+ return null;
}
}
diff --git a/lbplanner/services/plan/set_deadline.php b/lbplanner/services/plan/set_deadline.php
new file mode 100644
index 00000000..aac4d86d
--- /dev/null
+++ b/lbplanner/services/plan/set_deadline.php
@@ -0,0 +1,119 @@
+.
+
+namespace local_lbplanner_services;
+
+use external_api;
+use external_function_parameters;
+use external_value;
+use local_lbplanner\helpers\plan_helper;
+
+/**
+ * Set the deadline for a module.
+ *
+ * @package local_lbplanner
+ * @subpackage services_plan
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class plan_set_deadline extends external_api {
+ /**
+ * Parameters for set_deadline.
+ * @return external_function_parameters
+ */
+ public static function set_deadline_parameters(): external_function_parameters {
+ return new external_function_parameters([
+ 'moduleid' => new external_value(
+ PARAM_INT,
+ 'ID of the module the deadline is for',
+ VALUE_REQUIRED,
+ null,
+ NULL_NOT_ALLOWED
+ ),
+ 'deadlinestart' => new external_value(
+ PARAM_INT,
+ 'Start of the deadline',
+ VALUE_REQUIRED,
+ null,
+ NULL_NOT_ALLOWED
+ ),
+ 'deadlineend' => new external_value(
+ PARAM_INT,
+ 'End of the deadline',
+ VALUE_REQUIRED,
+ null,
+ NULL_NOT_ALLOWED
+ ),
+ ]);
+ }
+
+ /**
+ * Set the deadline for a module
+ *
+ * @param int $moduleid ID of the module the deadline is for
+ * @param int $deadlinestart Start of the deadline
+ * @param int $deadlineend End of the deadline
+ * @return void
+ * @throws \moodle_exception when access denied
+ */
+ public static function set_deadline(int $moduleid, int $deadlinestart, int $deadlineend) {
+ global $DB, $USER;
+
+ self::validate_parameters(
+ self::set_deadline_parameters(),
+ [
+ 'moduleid' => $moduleid,
+ 'deadlinestart' => $deadlinestart,
+ 'deadlineend' => $deadlineend,
+ ]
+ );
+
+ $planid = plan_helper::get_plan_id($USER->id);
+
+ if (!plan_helper::check_edit_permissions($planid, $USER->id)) {
+ throw new \moodle_exception('Access denied');
+ }
+
+ // If a deadline already exists.
+ if (!$DB->record_exists(plan_helper::DEADLINES_TABLE, ['moduleid' => $moduleid, 'planid' => $planid])) {
+ // Update the existing deadline.
+ $deadline = $DB->get_record(plan_helper::DEADLINES_TABLE, ['moduleid' => $moduleid, 'planid' => $planid]);
+
+ $deadline->deadlinestart = $deadlinestart;
+ $deadline->deadlineend = $deadlineend;
+
+ $DB->update_record(plan_helper::DEADLINES_TABLE, $deadline);
+ } else {
+ // Otherwise insert a new one.
+ $deadline = new \stdClass();
+
+ $deadline->planid = $planid;
+ $deadline->moduleid = $moduleid;
+ $deadline->deadlinestart = $deadlinestart;
+ $deadline->deadlineend = $deadlineend;
+
+ $DB->insert_record(plan_helper::DEADLINES_TABLE, $deadline);
+ }
+ }
+
+ /**
+ * Returns the structure of nothing.
+ * @return null
+ */
+ public static function set_deadline_returns() {
+ return null;
+ }
+}
diff --git a/lbplanner/services/plan/update_access.php b/lbplanner/services/plan/update_access.php
index dc49d370..a9ddd3ea 100644
--- a/lbplanner/services/plan/update_access.php
+++ b/lbplanner/services/plan/update_access.php
@@ -19,65 +19,71 @@
use external_api;
use external_function_parameters;
use external_value;
+use local_lbplanner\enums\PLAN_ACCESS_TYPE;
use local_lbplanner\helpers\plan_helper;
-use local_lbplanner\helpers\user_helper;
/**
* Update the access of the plan.
+ *
+ * @package local_lbplanner
+ * @subpackage services_plan
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plan_update_access extends external_api {
- public static function update_access_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(
- PARAM_INT,
- 'The id of the user to get the data for',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- 'planid' => new external_value(
- PARAM_INT,
- 'The id of the plan',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
+ /**
+ * Parameters for update_access.
+ * @return external_function_parameters
+ */
+ public static function update_access_parameters(): external_function_parameters {
+ return new external_function_parameters([
'accesstype' => new external_value(
PARAM_INT,
- 'The access type',
+ 'New access type '.PLAN_ACCESS_TYPE::format(),
VALUE_REQUIRED,
null,
NULL_NOT_ALLOWED
),
'memberid' => new external_value(
PARAM_INT,
- 'The id of the member',
+ 'ID of the member to have their access changed',
VALUE_REQUIRED,
null,
NULL_NOT_ALLOWED
),
- ));
+ ]);
}
- public static function update_access($userid, $planid, $accesstype, $memberid) {
- global $DB;
+ /**
+ * Update the access of the plan.
+ *
+ * @param int $accesstype new access type
+ * @see PLAN_ACCESS_TYPE
+ * @param int $memberid ID of the member to have their access changed
+ * @return void
+ * @throws \moodle_exception when access denied, type not valid or insufficient permissions
+ */
+ public static function update_access(int $accesstype, int $memberid) {
+ global $DB, $USER;
self::validate_parameters(
self::update_access_parameters(),
- array('userid' => $userid, 'planid' => $planid, 'accesstype' => $accesstype, 'memberid' => $memberid)
+ ['accesstype' => $accesstype, 'memberid' => $memberid]
);
- user_helper::assert_access($userid);
+ $planid = plan_helper::get_plan_id($USER->id);
- if (plan_helper::get_owner($planid) != $userid) {
+ if (plan_helper::get_owner($planid) !== $USER->id) {
throw new \moodle_exception('Access denied');
}
- if ($accesstype < 0 || $accesstype > 2) {
+ $accesstypeobj = PLAN_ACCESS_TYPE::try_from($accesstype);
+
+ if ($accesstypeobj === null) {
throw new \moodle_exception('Access type not valid');
}
- if ($userid == $memberid) {
+ if ($USER->id === $memberid) {
throw new \moodle_exception('Cannot change own permissions');
}
@@ -85,19 +91,21 @@ public static function update_access($userid, $planid, $accesstype, $memberid) {
throw new \moodle_exception('Cannot change permissions for the plan owner');
}
- if ($accesstype == plan_helper::ACCESS_TYPE_OWNER) {
- throw new \moodle_exception('Cannot change permissions to owner');
+ if ($accesstypeobj === PLAN_ACCESS_TYPE::OWNER) {
+ throw new \moodle_exception('Cannot change permission to owner');
}
- $access = $DB->get_record(plan_helper::ACCESS_TABLE, array('planid' => $planid, 'userid' => $memberid), '*', MUST_EXIST);
+ $access = $DB->get_record(plan_helper::ACCESS_TABLE, ['planid' => $planid, 'userid' => $memberid], '*', MUST_EXIST);
$access->accesstype = $accesstype;
$DB->update_record(plan_helper::ACCESS_TABLE, $access);
-
- return plan_helper::get_plan($planid);
}
+ /**
+ * Returns the structure of nothing.
+ * @return null
+ */
public static function update_access_returns() {
- return plan_helper::plan_structure();
+ return null;
}
}
diff --git a/lbplanner/services/plan/update_deadline.php b/lbplanner/services/plan/update_deadline.php
deleted file mode 100644
index c85fe7cf..00000000
--- a/lbplanner/services/plan/update_deadline.php
+++ /dev/null
@@ -1,106 +0,0 @@
-.
-
-namespace local_lbplanner_services;
-
-use external_api;
-use external_function_parameters;
-use external_value;
-use local_lbplanner\helpers\user_helper;
-use local_lbplanner\helpers\plan_helper;
-
-/**
- * Update a deadline from the plan.
- */
-class plan_update_deadline extends external_api {
- public static function update_deadline_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(
- PARAM_INT,
- 'The id of the user to get the data for',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- 'planid' => new external_value(
- PARAM_INT,
- 'The ID of the Plan',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- 'moduleid' => new external_value(
- PARAM_INT,
- 'The ID of the Module',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- 'deadlinestart' => new external_value(
- PARAM_INT,
- 'The start of the Module',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- 'deadlineend' => new external_value(
- PARAM_INT,
- 'The End of the Module',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- ));
- }
-
- public static function update_deadline($userid, $planid, $moduleid, $deadlinestart, $deadlineend) {
- global $DB;
-
- self::validate_parameters(
- self::update_deadline_parameters(),
- array(
- 'userid' => $userid,
- 'planid' => $planid,
- 'moduleid' => $moduleid,
- 'deadlinestart' => $deadlinestart,
- 'deadlineend' => $deadlineend,
- )
- );
-
- user_helper::assert_access($userid);
-
- if (!plan_helper::check_edit_permissions($planid, $userid)) {
- throw new \moodle_exception('Access denied');
- }
-
- if (!$DB->record_exists(plan_helper::DEADLINES_TABLE, array('moduleid' => $moduleid, 'planid' => $planid))) {
- throw new \moodle_exception('Deadline doesnt exists');
- }
- $deadline = $DB->get_record(plan_helper::DEADLINES_TABLE, array('moduleid' => $moduleid, 'planid' => $planid));
-
- $deadline->deadlinestart = $deadlinestart;
- $deadline->deadlineend = $deadlineend;
-
- $DB->update_record(plan_helper::DEADLINES_TABLE, $deadline);
-
- return plan_helper::get_plan($planid);
-
- }
-
- public static function update_deadline_returns() {
- return plan_helper::plan_structure();
- }
-}
diff --git a/lbplanner/services/plan/update_invite.php b/lbplanner/services/plan/update_invite.php
deleted file mode 100644
index 3b3640c9..00000000
--- a/lbplanner/services/plan/update_invite.php
+++ /dev/null
@@ -1,132 +0,0 @@
-.
-
-namespace local_lbplanner_services;
-
-use external_api;
-use external_function_parameters;
-use external_single_structure;
-use external_value;
-use local_lbplanner\helpers\user_helper;
-use local_lbplanner\helpers\plan_helper;
-use local_lbplanner\helpers\notifications_helper;
-
-/**
- * THIS METHOD IS NOT USED ANYMORE. JUST TO KEEP OLD CODE FOR REFERENCE.
- */
-class plan_update_invite extends external_api {
- public static function update_invite_parameters() {
- return new external_function_parameters(array(
- 'planid' => new external_value(PARAM_INT, 'The id of the plan', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'userid' => new external_value(PARAM_INT, 'The id of the invited user', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'status' => new external_value(PARAM_INT, 'The status of the invite', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- ));
- }
-
- public static function update_invite($planid, $userid, $status) {
- global $DB;
-
- self::validate_parameters(self::update_invite_parameters(), array(
- 'planid' => $planid,
- 'userid' => $userid,
- 'status' => $status,
- ));
-
- user_helper::assert_access($userid);
-
- if ($status != plan_helper::INVITE_ACCEPTED && $status != plan_helper::INVITE_DECLINED) {
- throw new \moodle_exception('Invalid status');
- }
-
- $invite = $DB->get_record(plan_helper::INVITES_TABLE,
- array(
- 'planid' => $planid,
- 'inviteeid' => $userid,
- ),
- '*',
- MUST_EXIST
- );
-
- if ($invite->status != plan_helper::INVITE_PENDING) {
- throw new \moodle_exception('Invalid status');
- }
-
- $invite->status = $status;
-
- $DB->update_record(plan_helper::INVITES_TABLE, $invite);
-
- $trigger = $status == plan_helper::INVITE_ACCEPTED ?
- notifications_helper::TRIGGER_INVITE_ACCEPTED
- : notifications_helper::TRIGGER_INVITE_DECLINED;
-
- notifications_helper::notify_user($invite->inviterid, $userid , $trigger);
-
- // TODO: Change plan access and delete old plan if inivite is accepted.
-
- if ($status == plan_helper::INVITE_ACCEPTED) {
- $oldplanid = plan_helper::get_plan_id($userid);
-
- if (plan_helper::get_owner($oldplanid) == $userid) {
-
- foreach (plan_helper::get_plan_members($oldplanid) as $member) {
- if ($member->userid != $userid) {
- plan_leave_plan::leave_plan($member->userid, $oldplanid);
- }
- }
- self::call_external_function('local_lbplanner_plan_clear_plan', array ($userid, $oldplanid));
-
- $DB->delete_records(plan_helper::TABLE, array('id' => $oldplanid));
- }
-
- $planaccess = $DB->get_record(
- plan_helper::ACCESS_TABLE,
- array(
- 'planid' => $oldplanid,
- 'userid' => $userid
- ),
- '*',
- MUST_EXIST
- );
-
- $planaccess->accesstype = plan_helper::ACCESS_TYPE_READ;
- $planaccess->planid = $planid;
-
- $DB->update_record(plan_helper::ACCESS_TABLE, $planaccess);
-
- $DB->delete_records(plan_helper::INVITES_TABLE, array('id' => $invite->id));
- }
- return array(
- 'inviterid' => $invite->inviterid,
- 'inviteeid' => $invite->inviteeid,
- 'planid' => $invite->planid,
- 'status' => $invite->status,
- 'timestamp' => $invite->timestamp,
- );
- }
-
-
- public static function update_invite_returns() {
- return new external_single_structure(
- array(
- 'inviterid' => new external_value(PARAM_INT, 'The id of the owner user'),
- 'inviteeid' => new external_value(PARAM_INT, 'The id of the invited user'),
- 'planid' => new external_value(PARAM_INT, 'The id of the plan'),
- 'status' => new external_value(PARAM_INT, 'The Status of the invitation'),
- 'timestamp' => new external_value(PARAM_INT, 'The time when the invitation was send'),
- )
- );
- }
-}
diff --git a/lbplanner/services/plan/update_plan.php b/lbplanner/services/plan/update_plan.php
index ade69cc5..586e4e42 100644
--- a/lbplanner/services/plan/update_plan.php
+++ b/lbplanner/services/plan/update_plan.php
@@ -20,71 +20,73 @@
use external_function_parameters;
use external_value;
use local_lbplanner\helpers\plan_helper;
-use local_lbplanner\helpers\user_helper;
/**
- * Update the plan of the given user.
+ * Update the plan details.
+ *
+ * @package local_lbplanner
+ * @subpackage services_plan
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plan_update_plan extends external_api {
- public static function update_plan_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(
- PARAM_INT,
- 'The id of the user to get the data for',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- 'planid' => new external_value(
- PARAM_INT,
- 'The id of the plan',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
+ /**
+ * Parameters for update_plan.
+ * @return external_function_parameters
+ */
+ public static function update_plan_parameters(): external_function_parameters {
+ return new external_function_parameters([
'planname' => new external_value(
PARAM_TEXT,
- 'The Name of the Plan',
+ 'Name of the Plan',
VALUE_REQUIRED,
null,
NULL_NOT_ALLOWED
),
'enableek' => new external_value(
PARAM_BOOL,
- 'If the plan is enabled for ek',
+ 'Whether EK is enabled for the plan',
VALUE_REQUIRED,
null,
NULL_NOT_ALLOWED
),
- ));
+ ]);
}
- public static function update_plan($userid, $planid, $planname, $enableek) {
- global $DB;
+ /**
+ * Update the plan details.
+ *
+ * @param string $planname Name of the Plan
+ * @param bool $enableek Whether EK is enabled for the plan
+ * @return void
+ * @throws Exception when access denied
+ */
+ public static function update_plan(string $planname, bool $enableek) {
+ global $DB, $USER;
self::validate_parameters(
self::update_plan_parameters(),
- array('userid' => $userid, 'planid' => $planid, 'planname' => $planname, 'enableek' => $enableek)
+ ['planname' => $planname, 'enableek' => $enableek]
);
- user_helper::assert_access($userid);
+ $planid = plan_helper::get_plan_id($USER->id);
- if (!plan_helper::check_edit_permissions($planid, $userid)) {
+ if (!plan_helper::check_edit_permissions($planid, $USER->id)) {
throw new \Exception('Access denied');
}
- $planid = plan_helper::get_plan_id($userid);
-
- $plan = $DB->get_record(plan_helper::TABLE, array('id' => $planid), '*', MUST_EXIST);
+ $plan = $DB->get_record(plan_helper::TABLE, ['id' => $planid], '*', MUST_EXIST);
$plan->name = $planname;
$plan->enableek = $enableek;
$DB->update_record(plan_helper::TABLE, $plan);
-
- return plan_helper::get_plan($planid);
}
+ /**
+ * Returns the structure of nothing.
+ * @return null
+ */
public static function update_plan_returns() {
- return plan_helper::plan_structure();
+ return null;
}
}
diff --git a/lbplanner/services/slots/book_reservation.php b/lbplanner/services/slots/book_reservation.php
new file mode 100644
index 00000000..d07725d7
--- /dev/null
+++ b/lbplanner/services/slots/book_reservation.php
@@ -0,0 +1,156 @@
+.
+
+namespace local_lbplanner_services;
+
+use DateTimeImmutable;
+
+use core_user;
+use external_api;
+use external_function_parameters;
+use external_single_structure;
+use external_value;
+
+use local_lbplanner\helpers\slot_helper;
+use local_lbplanner\model\reservation;
+
+/**
+ * Books a reservation for the user
+ *
+ * @package local_lbplanner
+ * @subpackage services_slots
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class slots_book_reservation extends external_api {
+ /**
+ * Parameters for book_reservation.
+ * @return external_function_parameters
+ */
+ public static function book_reservation_parameters(): external_function_parameters {
+ global $USER;
+ return new external_function_parameters([
+ 'slotid' => new external_value(
+ PARAM_INT,
+ 'ID of the slot for which a reservation is being requested',
+ VALUE_REQUIRED,
+ null,
+ NULL_NOT_ALLOWED
+ ),
+ 'date' => new external_value(
+ PARAM_TEXT,
+ 'date of the reservation in YYYY-MM-DD (as per ISO-8601)',
+ VALUE_REQUIRED,
+ null,
+ NULL_NOT_ALLOWED
+ ),
+ 'userid' => new external_value(
+ PARAM_INT,
+ 'the user to reserve this slot for',
+ VALUE_DEFAULT,
+ $USER->id,
+ NULL_NOT_ALLOWED
+ ),
+ ]);
+ }
+
+ /**
+ * Books a reservation
+ * @param int $slotid the slot to book a reservation for
+ * @param string $date the day this reservation should take place
+ * @param int $userid the user to reserve for
+ */
+ public static function book_reservation(int $slotid, string $date, int $userid): array {
+ global $USER, $DB;
+ self::validate_parameters(
+ self::book_reservation_parameters(),
+ [
+ 'slotid' => $slotid,
+ 'date' => $date,
+ 'userid' => $userid,
+ ]
+ );
+
+ $now = new DateTimeImmutable();
+ $dateobj = DateTimeImmutable::createFromFormat("YY-MM-DD", $date);
+ $td = $dateobj->diff($now);
+
+ if ($td->invert) {
+ throw new \moodle_exception('Can\'t reserve date in the past');
+ }
+
+ $maxdays = null;
+ $student = null;
+
+ if ($userid === $USER->id) {
+ // Student reserving slot for themself.
+
+ $maxdays = slot_helper::RESERVATION_RANGE_USER;
+ $student = $USER;
+ } else {
+ // Supervisor reserving slot for student.
+
+ if (!slot_helper::check_slot_supervisor($USER->id, $slotid)) {
+ throw new \moodle_exception('Forbidden: you\'re not a supervisor of this slot');
+ }
+
+ $maxdays = slot_helper::RESERVATION_RANGE_USER;
+ $student = core_user::get_user($userid, '*', MUST_EXIST);
+ }
+
+ if ($td->days > $maxdays) {
+ throw new \moodle_exception("Date is past allowed date ({$maxdays} days in the future)");
+ }
+
+ $slot = slot_helper::get_slot($slotid);
+
+ // Check if user has access to slot.
+ if (count(slot_helper::filter_slots_for_user([$slot], $student)) === 0) {
+ throw new \moodle_exception('Student does not have access to this slot');
+ }
+
+ // Check if user is already in slot.
+ foreach (slot_helper::get_reservations_for_slot($slotid) as $tmpreservation) {
+ if ($tmpreservation->userid === $userid) {
+ throw new \moodle_exception('Student is already in slot');
+ }
+ }
+
+ // TODO: check if user is already in a different slot at the same time.
+
+ // Check if slot is full.
+ if ($slot->get_fullness() >= $slot->size) {
+ throw new \moodle_exception('Slot is already full');
+ }
+
+ $reservation = new reservation(0, $slotid, $dateobj, $userid, $USER->id);
+
+ $id = $DB->insert_record(slot_helper::TABLE_RESERVATIONS, $reservation->prepare_for_db());
+ $reservation->set_fresh($id, $slot);
+
+ // TODO: if userid!=USER->id → send notif to the user that the supervisor booked a reservation for them.
+
+ return $reservation->prepare_for_api();
+ }
+
+ /**
+ * Returns the structure of the reservation
+ * @return external_single_structure
+ */
+ public static function book_reservation_returns(): external_single_structure {
+ return reservation::api_structure();
+ }
+}
diff --git a/lbplanner/services/slots/create_slot.php b/lbplanner/services/slots/create_slot.php
new file mode 100644
index 00000000..30499923
--- /dev/null
+++ b/lbplanner/services/slots/create_slot.php
@@ -0,0 +1,144 @@
+.
+
+namespace local_lbplanner_services;
+
+use external_api;
+use external_function_parameters;
+use external_single_structure;
+use external_value;
+use local_lbplanner\enums\WEEKDAY;
+use local_lbplanner\helpers\slot_helper;
+use local_lbplanner\model\slot;
+use moodle_exception;
+
+/**
+ * Create a slot
+ *
+ * @package local_lbplanner
+ * @subpackage services_slots
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class slots_create_slot extends external_api {
+ /**
+ * Parameters for create_slot.
+ * @return external_function_parameters
+ */
+ public static function create_slot_parameters(): external_function_parameters {
+ // TODO: set hardcoded doc values with constants instead of hardcoded values.
+ return new external_function_parameters([
+ 'startunit' => new external_value(
+ PARAM_INT,
+ 'The school unit this slot starts in, starting at 1 for 8:00 and ending at 16 for 21:00',
+ VALUE_REQUIRED,
+ null,
+ NULL_NOT_ALLOWED
+ ),
+ 'duration' => new external_value(
+ PARAM_INT,
+ 'The amount of units this slot is long. startunit + duration may not exceed 16',
+ VALUE_REQUIRED,
+ null,
+ NULL_NOT_ALLOWED
+ ),
+ 'weekday' => new external_value(
+ PARAM_INT,
+ 'The weekday this slot happens on. '.WEEKDAY::format(),
+ VALUE_REQUIRED,
+ null,
+ NULL_NOT_ALLOWED
+ ),
+ 'room' => new external_value(
+ PARAM_TEXT,
+ 'The room this slot happens in. max. 7 characters',
+ VALUE_REQUIRED,
+ null,
+ NULL_NOT_ALLOWED
+ ),
+ 'size' => new external_value(
+ PARAM_INT,
+ 'How many pupils this slot can fit',
+ VALUE_REQUIRED,
+ null,
+ NULL_NOT_ALLOWED
+ ),
+ ]);
+ }
+
+ /**
+ * Create a slot
+ * @param int $startunit the unit this slot starts in
+ * @param int $duration how long the unit lasts for
+ * @param int $weekday which day of the week this slot is on
+ * @param string $room which room this slot is for
+ * @param int $size how many pupils this slot can fit
+ */
+ public static function create_slot(int $startunit, int $duration, int $weekday, string $room, int $size): array {
+ global $DB;
+ self::validate_parameters(
+ self::create_slot_parameters(),
+ [
+ 'startunit' => $startunit,
+ 'duration' => $duration,
+ 'weekday' => $weekday,
+ 'room' => $room,
+ 'size' => $size,
+ ]
+ );
+
+ // Validating startunit.
+ $maxunit = count(slot_helper::SCHOOL_UNITS) - 1;
+ if ($startunit < 1) {
+ throw new moodle_exception('can\'t have a start unit smaller than 1');
+ } else if ($startunit > $maxunit) {
+ throw new moodle_exception("can't have a start unit larger than {$maxunit}");
+ }
+ // Validating duration.
+ if ($duration < 1) {
+ throw new moodle_exception('duration must be at least 1');
+ } else if ($startunit + $duration > $maxunit) {
+ throw new moodle_exception("slot goes past the max unit {$maxunit}");
+ }
+ // Validating weekday.
+ WEEKDAY::from($weekday);
+ // Validating room.
+ if (strlen($room) <= 1) {
+ throw new moodle_exception('room name has to be at least 2 characters long');
+ } else if (strlen($room) > slot_helper::ROOM_MAXLENGTH) {
+ throw new moodle_exception('room name has a maximum of '.slot_helper::ROOM_MAXLENGTH.' characters');
+ }
+ // Validating size.
+ if ($size < 0) {
+ throw new moodle_exception('can\'t have a negative size for a slot');
+ }
+
+ // Actually inserting the slot.
+ $slot = new slot(0, $startunit, $duration, $weekday, $room, $size);
+ $id = $DB->insert_record(slot_helper::TABLE_SLOTS, $slot->prepare_for_db());
+ $slot->set_fresh($id);
+
+ return $slot->prepare_for_api();
+ }
+
+ /**
+ * Returns the structure of the slot
+ * @return external_single_structure
+ */
+ public static function create_slot_returns(): external_single_structure {
+ return slot::api_structure();
+ }
+}
diff --git a/lbplanner/services/slots/get_my_slots.php b/lbplanner/services/slots/get_my_slots.php
new file mode 100644
index 00000000..e50f4206
--- /dev/null
+++ b/lbplanner/services/slots/get_my_slots.php
@@ -0,0 +1,67 @@
+.
+
+namespace local_lbplanner_services;
+
+use external_api;
+use external_function_parameters;
+use external_multiple_structure;
+use local_lbplanner\helpers\slot_helper;
+use local_lbplanner\model\slot;
+
+/**
+ * Returns all slots the user can theoretically reserve.
+ * This does not include times the user has already reserved a slot for.
+ *
+ * @package local_lbplanner
+ * @subpackage services_slots
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class slots_get_my_slots extends external_api {
+ /**
+ * Parameters for get_my_slots.
+ * @return external_function_parameters
+ */
+ public static function get_my_slots_parameters(): external_function_parameters {
+ return new external_function_parameters([]);
+ }
+
+ /**
+ * Returns slots the current user is supposed to see
+ */
+ public static function get_my_slots(): array {
+ global $USER;
+
+ $allslots = slot_helper::get_all_slots();
+
+ $myslots = slot_helper::filter_slots_for_user($allslots, $USER);
+
+ $returnslots = slot_helper::filter_slots_for_time($myslots, slot_helper::RESERVATION_RANGE_USER);
+
+ return array_map(fn(slot $slot) => $slot->prepare_for_api(), $returnslots);
+ }
+
+ /**
+ * Returns the structure of the slot array
+ * @return external_multiple_structure
+ */
+ public static function get_my_slots_returns(): external_multiple_structure {
+ return new external_multiple_structure(
+ slot::api_structure()
+ );
+ }
+}
diff --git a/lbplanner/services/slots/get_student_slots.php b/lbplanner/services/slots/get_student_slots.php
new file mode 100644
index 00000000..c423196a
--- /dev/null
+++ b/lbplanner/services/slots/get_student_slots.php
@@ -0,0 +1,76 @@
+.
+
+namespace local_lbplanner_services;
+
+use external_api;
+use external_function_parameters;
+use external_multiple_structure;
+use external_value;
+use local_lbplanner\helpers\slot_helper;
+use local_lbplanner\helpers\user_helper;
+use local_lbplanner\model\slot;
+
+/**
+ * Returns all slots a supervisor can theoretically reserve for a user.
+ * This does not include times the user has already reserved a slot for.
+ *
+ * @package local_lbplanner
+ * @subpackage services_slots
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class slots_get_student_slots extends external_api {
+ /**
+ * Parameters for get_student_slots.
+ * @return external_function_parameters
+ */
+ public static function get_student_slots_parameters(): external_function_parameters {
+ return new external_function_parameters([
+ 'userid' => new external_value(PARAM_INT, 'ID of the user to query for', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
+ ]);
+ }
+
+ /**
+ * Returns slots of a user the supervisor can see.
+ * @param int $userid ID of the user in question (NOT the supervisor)
+ */
+ public static function get_student_slots(int $userid): array {
+ global $USER;
+ self::validate_parameters(
+ self::get_student_slots_parameters(),
+ ['userid' => $userid]
+ );
+
+ $superslots = slot_helper::get_supervisor_slots($USER->id);
+
+ $myslots = slot_helper::filter_slots_for_user($superslots, user_helper::get_mdluser($userid));
+
+ $returnslots = slot_helper::filter_slots_for_time($myslots, slot_helper::RESERVATION_RANGE_SUPERVISOR);
+
+ return array_map(fn(slot $slot) => $slot->prepare_for_api(), $returnslots);
+ }
+
+ /**
+ * Returns the structure of the slot array
+ * @return external_multiple_structure
+ */
+ public static function get_student_slots_returns(): external_multiple_structure {
+ return new external_multiple_structure(
+ slot::api_structure()
+ );
+ }
+}
diff --git a/lbplanner/services/slots/get_supervisor_slots.php b/lbplanner/services/slots/get_supervisor_slots.php
new file mode 100644
index 00000000..20278673
--- /dev/null
+++ b/lbplanner/services/slots/get_supervisor_slots.php
@@ -0,0 +1,62 @@
+.
+
+namespace local_lbplanner_services;
+
+use external_api;
+use external_function_parameters;
+use external_multiple_structure;
+use local_lbplanner\helpers\slot_helper;
+use local_lbplanner\model\slot;
+
+/**
+ * Returns all slots a supervisor can see.
+ *
+ * @package local_lbplanner
+ * @subpackage services_slots
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class slots_get_supervisor_slots extends external_api {
+ /**
+ * Parameters for get_supervisor_slots.
+ * @return external_function_parameters
+ */
+ public static function get_supervisor_slots_parameters(): external_function_parameters {
+ return new external_function_parameters([]);
+ }
+
+ /**
+ * Returns all slots a supervisor controls.
+ */
+ public static function get_supervisor_slots(): array {
+ global $USER;
+
+ $slots = slot_helper::get_supervisor_slots($USER->id);
+
+ return array_map(fn(slot $slot) => $slot->prepare_for_api(), $slots);
+ }
+
+ /**
+ * Returns the structure of the slot array
+ * @return external_multiple_structure
+ */
+ public static function get_supervisor_slots_returns(): external_multiple_structure {
+ return new external_multiple_structure(
+ slot::api_structure()
+ );
+ }
+}
diff --git a/lbplanner/services/slots/unbook_reservation.php b/lbplanner/services/slots/unbook_reservation.php
new file mode 100644
index 00000000..2dd4da6e
--- /dev/null
+++ b/lbplanner/services/slots/unbook_reservation.php
@@ -0,0 +1,119 @@
+.
+
+namespace local_lbplanner_services;
+
+use DateTimeImmutable;
+
+use external_api;
+use external_function_parameters;
+use external_value;
+
+use local_lbplanner\helpers\slot_helper;
+use local_lbplanner\helpers\notifications_helper;
+use local_lbplanner\enums\NOTIF_TRIGGER;
+
+/**
+ * Unbooks reservation
+ *
+ * @package local_lbplanner
+ * @subpackage services_slots
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class slots_unbook_reservation extends external_api {
+ /**
+ * Parameters for unbook_reservation.
+ * @return external_function_parameters
+ */
+ public static function unbook_reservation_parameters(): external_function_parameters {
+ return new external_function_parameters([
+ 'reservationid' => new external_value(
+ PARAM_INT,
+ 'ID of the reservation for which unbooking is being requested',
+ VALUE_REQUIRED,
+ null,
+ NULL_NOT_ALLOWED
+ ),
+ 'nice' => new external_value(
+ PARAM_BOOL,
+ 'whether to ask the student nicely to unbook themself via a notification',
+ VALUE_DEFAULT,
+ true,
+ NULL_NOT_ALLOWED
+ ),
+ ]);
+ }
+
+ /**
+ * Tries to request unbooking
+ * @param int $reservationid which reservation to unbook
+ * @param bool $nice whether to ask the student to unbook themself, or force-unbook
+ */
+ public static function unbook_reservation(int $reservationid, bool $nice): void {
+ global $USER, $DB;
+ self::validate_parameters(
+ self::unbook_reservation_parameters(),
+ [
+ 'reservationid' => $reservationid,
+ 'nice' => $nice,
+ ]
+ );
+
+ $reservation = slot_helper::get_reservation($reservationid);
+ $now = new DateTimeImmutable();
+
+ $endpast = $now->diff($reservation->get_datetime_end())->invert === 1;
+ $startpast = $endpast || ($now->diff($reservation->get_datetime())->invert === 1);
+
+ if ($USER->id === $reservation->userid) {
+ if ($startpast) {
+ throw new \moodle_exception('You can\'t unbook this reservation because it has already started');
+ }
+ } else if (slot_helper::check_slot_supervisor($USER->id, $reservation->slotid)) {
+ if ($endpast) {
+ throw new \moodle_exception('You can\'t unbook this reservation because it has already ended');
+ }
+ if ($nice) {
+ if ($startpast) {
+ throw new \moodle_exception(
+ 'Students can\'t unbook reservations that have already started.'
+ .' If you want to unbook this reservation regardless, force it.'
+ );
+ }
+ notifications_helper::notify_user($reservation->userid, $reservation->id, NOTIF_TRIGGER::UNBOOK_REQUESTED);
+ return;
+ } else {
+ notifications_helper::notify_user($reservation->userid, $reservation->id, NOTIF_TRIGGER::UNBOOK_FORCED);
+ }
+ } else {
+ throw new \moodle_exception('insufficient permission to unbook this reservation');
+ }
+
+ $DB->delete_records(
+ slot_helper::TABLE_RESERVATIONS,
+ ['id' => $reservation->id]
+ );
+ }
+
+ /**
+ * Returns nothing at all
+ * @return null
+ */
+ public static function unbook_reservation_returns() {
+ return null;
+ }
+}
diff --git a/lbplanner/services/user/delete_user.php b/lbplanner/services/user/delete_user.php
index d099bf69..01c90bfc 100644
--- a/lbplanner/services/user/delete_user.php
+++ b/lbplanner/services/user/delete_user.php
@@ -16,80 +16,100 @@
namespace local_lbplanner_services;
-use core_competency\plan;
+use dml_exception;
use external_api;
use external_function_parameters;
-use external_single_structure;
use external_value;
-use local_lbplanner\helpers\user_helper;
-use local_lbplanner\helpers\plan_helper;
-use local_lbplanner\helpers\course_helper;
-use local_lbplanner\helpers\notifications_helper;
+use local_lbplanner\helpers\{user_helper, plan_helper, course_helper, notifications_helper};
+use local_lbplanner\enums\{PLAN_INVITE_STATE, PLAN_ACCESS_TYPE};
+use moodle_exception;
/**
- * Removes all user data stored by the lbplanner app
+ * Removes all user data stored by the lbplanner app.
+ *
+ * Admins can pass a userid to delete the user with the given id
+ *
+ * @package local_lbplanner
+ * @subpackage services_user
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class user_delete_user extends external_api {
- public static function delete_user_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(
+ /**
+ * Parameters for delete_user
+ * @return external_function_parameters
+ */
+ public static function delete_user_parameters(): external_function_parameters {
+ global $USER;
+ return new external_function_parameters(
+ ['userid' => new external_value(
PARAM_INT,
- 'The id of the user to get the data for',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
- ),
- ));
+ 'The id of the user to delete',
+ VALUE_DEFAULT,
+ $USER->id,
+ NULL_NOT_ALLOWED,
+ )]
+ );
}
+ /**
+ * Removes all user data stored by the lbplanner app
+ * @param int $userid (optional) the id of the user to delete
+ * @throws dml_exception
+ * @throws moodle_exception
+ */
public static function delete_user($userid) {
- global $DB;
- self::validate_parameters(self::delete_user_parameters(), array('userid' => $userid));
+ global $DB, $USER;
+
+ self::validate_parameters(self::delete_user_parameters(), ['userid' => $userid]);
- user_helper::assert_access($userid);
+ if (!user_helper::is_admin($USER->id)) {
+ user_helper::assert_access($userid);
+ }
// Check if User is in user table.
- if (!$DB->record_exists(user_helper::TABLE, array('userid' => $userid))) {
- throw new \moodle_exception('Access denied');
+ if (!$DB->record_exists(user_helper::LB_PLANNER_USER_TABLE, ['userid' => $userid])) {
+ throw new moodle_exception('User is not registered in LB Planner');
}
$planid = plan_helper::get_plan_id($userid);
-
- if (plan_helper::get_access_type($planid, $userid) == plan_helper::ACCESS_TYPE_OWNER) {
- if (plan_helper::get_plan_members($planid) > 1) {
- self::call_external_function('local_lbplanner_plan_leave_plan', array('userid' => $userid, 'planid' => $planid));
- } else {
- // Deleting Plan.
- $DB->delete_records(plan_helper::DEADLINES_TABLE, array('planid' => $planid));
- $DB->delete_records(plan_helper::TABLE, array('id' => $planid));
- }
+ // Check if User is in a plan. If yes, leave the plan first then delete the plan.
+ // If the user is the only member of the plan, delete the plan.
+ if (
+ !(count(plan_helper::get_plan_members($planid)) == 1 )
+ &&
+ !(plan_helper::get_access_type($planid, $userid) == PLAN_ACCESS_TYPE::OWNER)) {
+ self::call_external_function('local_lbplanner_plan_leave_plan', ['userid' => $userid, 'planid' => $planid]);
}
+ $DB->delete_records(plan_helper::DEADLINES_TABLE, ['planid' => $planid]);
+ $DB->delete_records(plan_helper::TABLE, ['id' => $planid]);
+
// Delete all Notifications.
- if ($DB->record_exists(notifications_helper::TABLE, array('userid' => $userid))) {
- $DB->delete_records(notifications_helper::TABLE, array('userid' => $userid));
+ if ($DB->record_exists(notifications_helper::LBPLANNER_NOTIFICATION_TABLE, ['userid' => $userid])) {
+ $DB->delete_records(notifications_helper::LBPLANNER_NOTIFICATION_TABLE, ['userid' => $userid]);
}
$invites = plan_helper::get_invites_send($userid);
foreach ($invites as $invite) {
- if ($invite->status == plan_helper::INVITE_PENDING) {
- $invite->status = plan_helper::INVITE_EXPIRED;
+ if ($invite->status == PLAN_INVITE_STATE::PENDING) {
+ $invite->status = PLAN_INVITE_STATE::EXPIRED;
$DB->update_record(plan_helper::INVITES_TABLE, $invite);
}
}
// Deleting associating with the plan.
- $DB->delete_records(plan_helper::ACCESS_TABLE, array('userid' => $userid));
+ $DB->delete_records(plan_helper::ACCESS_TABLE, ['userid' => $userid]);
// Deleting all Courses associated with the User.
- $DB->delete_records(course_helper::LBPLANNER_COURSE_TABLE, array('userid' => $userid));
+ $DB->delete_records(course_helper::LBPLANNER_COURSE_TABLE, ['userid' => $userid]);
// Deleting User from User table.
- $DB->delete_records(user_helper::TABLE, array('userid' => $userid));
-
- return array('message' => 'User deleted successfully');
+ $DB->delete_records(user_helper::LB_PLANNER_USER_TABLE, ['userid' => $userid]);
}
+ /**
+ * Returns the structure of the data returned by the delete_user function
+ * @return external_multiple_structure
+ */
public static function delete_user_returns() {
- return new external_single_structure(
- array('message' => new external_value(PARAM_TEXT, 'The message to return to the user'))
- );
+ return null;
}
}
diff --git a/lbplanner/services/user/get_all_users.php b/lbplanner/services/user/get_all_users.php
index 6308f87b..69ce75b6 100644
--- a/lbplanner/services/user/get_all_users.php
+++ b/lbplanner/services/user/get_all_users.php
@@ -16,63 +16,73 @@
namespace local_lbplanner_services;
+use dml_exception;
use external_api;
use external_function_parameters;
use external_multiple_structure;
-use external_single_structure;
use external_value;
+use invalid_parameter_exception;
+use moodle_exception;
+
use local_lbplanner\helpers\user_helper;
+use local_lbplanner\model\user;
/**
* Gets all users registered by the lbplanner app.
+ *
+ * @package local_lbplanner
+ * @subpackage services_user
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class user_get_all_users extends external_api {
- public static function get_all_users_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(PARAM_INT, 'The id of the user', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- ));
+ /**
+ * Parameters for get_all_users
+ * @return external_function_parameters
+ */
+ public static function get_all_users_parameters(): external_function_parameters {
+ return new external_function_parameters([
+ 'vintage' => new external_value(PARAM_TEXT, 'The vintage to filter the users by', VALUE_DEFAULT, null),
+ ]);
}
- public static function get_all_users($userid) {
- global $DB;
+ /**
+ * Gives back all users registered by the lbplanner app.
+ * @param string $vintage (optional) gives back all users with the given vintage
+ * @throws moodle_exception
+ * @throws dml_exception
+ * @throws invalid_parameter_exception
+ */
+ public static function get_all_users(string $vintage): array {
+ global $DB, $USER;
- self::validate_parameters(self::get_all_users_parameters(), array('userid' => $userid));
+ self::validate_parameters(self::get_all_users_parameters(), ['vintage' => $vintage]);
// Check if token is allowed to access this function.
- user_helper::assert_access($userid);
+ user_helper::assert_access($USER->id);
- $users = $DB->get_records(user_helper::TABLE);
+ $users = $DB->get_records(user_helper::LB_PLANNER_USER_TABLE);
- $result = array();
+ $results = [];
- foreach ($users as $user) {
- $mdluser = user_helper::get_mdl_user_info($user->userid);
- $result[] = array(
- 'userid' => $user->userid,
- 'username' => $mdluser->username,
- 'firstname' => $mdluser->firstname,
- 'lastname' => $mdluser->lastname,
- 'profileimageurl' => $mdluser->profileimageurl,
- 'vintage' => $mdluser->vintage,
- );
+ foreach ($users as $userdata) {
+ $user = user::from_db($userdata);
+ if ($vintage === null || $vintage == $user->get_mdluser()->vintage) {
+ array_push($results, $user->prepare_for_api_short());
+ }
}
- return $result;
+ return $results;
}
- public static function get_all_users_returns() {
+ /**
+ * Returns the structure of the data returned by the get_all_users function
+ * @return external_multiple_structure
+ */
+ public static function get_all_users_returns(): external_multiple_structure {
return new external_multiple_structure(
- new external_single_structure(
- array(
- 'userid' => new external_value(PARAM_INT, 'The id of the user'),
- 'username' => new external_value(PARAM_TEXT, 'The username of the user'),
- 'firstname' => new external_value(PARAM_TEXT, 'The firstname of the user'),
- 'lastname' => new external_value(PARAM_TEXT, 'The lastname of the user'),
- 'profileimageurl' => new external_value(PARAM_URL, 'The url of the profile image'),
- 'vintage' => new external_value(PARAM_TEXT, 'The vintage of the user')
- )
- )
+ user::api_structure_short()
);
}
}
diff --git a/lbplanner/services/user/get_user.php b/lbplanner/services/user/get_user.php
index d6737c02..b9abded2 100644
--- a/lbplanner/services/user/get_user.php
+++ b/lbplanner/services/user/get_user.php
@@ -16,93 +16,99 @@
namespace local_lbplanner_services;
-use block_recentlyaccesseditems\external;
-use core_privacy\local\request\subsystem\plugin_provider;
+use coding_exception;
+use dml_exception;
use external_api;
use external_function_parameters;
use external_single_structure;
-use external_multiple_structure;
use external_value;
-use local_lbplanner\helpers\plan_helper;
-use local_lbplanner\helpers\user_helper;
+use core_user;
+use moodle_exception;
+
+use local_lbplanner\helpers\{user_helper, plan_helper, notifications_helper};
+use local_lbplanner\enums\{PLAN_EK, PLAN_ACCESS_TYPE, NOTIF_TRIGGER};
+use local_lbplanner\model\user;
/**
* Get the data for a user.
+ *
+ * Get the data for a user. param userid (optional) gives back the user data with the given ID
+ *
+ * @package local_lbplanner
+ * @subpackage services_user
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class user_get_user extends external_api {
- public static function get_user_parameters() {
- return new external_function_parameters(array(
+ /**
+ * Parameters for get_user
+ * @return external_function_parameters
+ */
+ public static function get_user_parameters(): external_function_parameters {
+ global $USER;
+ return new external_function_parameters([
'userid' => new external_value(
PARAM_INT,
- 'The id of the user to get the data for',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED
+ 'The id of the user to get the data for. If not provided it will be inferred via the token',
+ VALUE_DEFAULT,
+ $USER->id,
+ NULL_NOT_ALLOWED,
),
- ));
+ ]);
}
- public static function get_user($userid) {
- global $USER;
- self::validate_parameters(self::get_user_parameters(), array('userid' => $userid));
+ /**
+ * Gives back the data of a user.
+ * Default: The user who calls this function
+ * @param int $userid gives back the data of the given user
+ * @throws coding_exception
+ * @throws dml_exception
+ * @throws moodle_exception
+ * @return array The data of the user
+ */
+ public static function get_user(int $userid): array {
+ global $USER, $DB;
- if (!user_helper::check_user_exists($userid)) {
- throw new \moodle_exception('User does not exist');
- }
+ self::validate_parameters(self::get_user_parameters(), ['userid' => $userid]);
- $user = user_helper::get_user($userid);
+ // Check if the user is allowed to get the data for this userid.
+ user_helper::assert_access($userid);
- $mdluser = user_helper::get_mdl_user_info($user->userid);
+ // Checks if the user is enrolled in LB Planner.
+ if (!user_helper::check_user_exists($userid)) {
+ // Register user if not found.
+ $lbplanneruser = new user(0, $userid, 'default', 'en', 'none', 1);
+ $lbpid = $DB->insert_record(user_helper::LB_PLANNER_USER_TABLE, $lbplanneruser->prepare_for_db());
+ $lbplanneruser->set_fresh($lbpid);
- // Check if the user is allowed to get the data for this userid.
- if ($userid == $USER->id) {
+ // Create empty plan for newly registered user.
+ $plan = new \stdClass();
+ $plan->name = 'Plan for ' . $USER->username;
+ $plan->enableek = PLAN_EK::ENABLED;
+ $planid = $DB->insert_record(plan_helper::TABLE, $plan);
+ $lbplanneruser->set_planid($planid);
+
+ // Set user as owner of new plan.
+ $planaccess = new \stdClass();
+ $planaccess->userid = $userid;
+ $planaccess->accesstype = PLAN_ACCESS_TYPE::OWNER;
+ $planaccess->planid = $planid;
+ $DB->insert_record(plan_helper::ACCESS_TABLE, $planaccess);
- return array(
- 'userid' => $user->userid,
- 'username' => $mdluser->username,
- 'firstname' => $mdluser->firstname,
- 'lastname' => $mdluser->lastname,
- 'capabilities' => user_helper::get_user_capability_bitmask($userid),
- 'theme' => $user->theme,
- 'lang' => $user->language,
- 'profileimageurl' => $mdluser->profileimageurl,
- 'planid' => plan_helper::get_plan_id($userid),
- 'colorblindness' => $user->colorblindness,
- 'displaytaskcount' => $user->displaytaskcount,
- 'vintage' => $mdluser->vintage,
- );
+ // Notify the FE that this user likely hasn't used LBP before.
+ notifications_helper::notify_user($userid, -1, NOTIF_TRIGGER::USER_REGISTERED);
+ } else {
+ $lbplanneruser = user_helper::get_user($userid);
}
- return array(
- 'userid' => $user->userid,
- 'username' => $user->username,
- 'firstname' => $mdluser->firstname,
- 'lastname' => $mdluser->lastname,
- 'capabilities' => null,
- 'theme' => null,
- 'lang' => null,
- 'profileimageurl' => $mdluser->profileimageurl,
- 'planid' => null,
- 'colorblindness' => null,
- 'displaytaskcount' => null,
- 'vintage' => $mdluser->vintage,
- );
+
+ return $lbplanneruser->prepare_for_api();
}
- public static function get_user_returns() {
- return new external_single_structure(
- array(
- 'userid' => new external_value(PARAM_INT, 'The id of the user'),
- 'username' => new external_value(PARAM_TEXT, 'The username of the user'),
- 'firstname' => new external_value(PARAM_TEXT, 'The firstname of the user'),
- 'lastname' => new external_value(PARAM_TEXT, 'The lastname of the user'),
- 'theme' => new external_value(PARAM_TEXT, 'The theme the user has selected'),
- 'lang' => new external_value(PARAM_TEXT, 'The language the user has selected'),
- 'profileimageurl' => new external_value(PARAM_URL, 'The url of the profile image'),
- 'planid' => new external_value(PARAM_INT, 'The id of the plan the user is assigned to'),
- 'colorblindness' => new external_value(PARAM_TEXT, 'The colorblindness of the user'),
- 'displaytaskcount' => new external_value(PARAM_INT, 'The displaytaskcount of the user'),
- 'capabilities' => new external_value(PARAM_INT, 'The capability'),
- 'vintage' => new external_value(PARAM_TEXT, 'The vintage of the user')
- )
- );
+
+ /**
+ * Returns the data of a user.
+ * @return external_single_structure
+ */
+ public static function get_user_returns(): external_single_structure {
+ return user::api_structure();
}
}
diff --git a/lbplanner/services/user/register_user.php b/lbplanner/services/user/register_user.php
deleted file mode 100644
index 59a3fbe1..00000000
--- a/lbplanner/services/user/register_user.php
+++ /dev/null
@@ -1,108 +0,0 @@
-.
-
-namespace local_lbplanner_services;
-
-use external_api;
-use external_function_parameters;
-use external_single_structure;
-use external_value;
-use local_lbplanner\helpers\user_helper;
-use local_lbplanner\helpers\plan_helper;
-use local_lbplanner\helpers\notifications_helper;
-
-/**
- * Register a new user in the lbplanner app.
- */
-class user_register_user extends external_api {
- public static function register_user_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(PARAM_INT, 'The id of the user to register', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'lang' => new external_value(PARAM_TEXT, 'The language the user has selected', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'theme' => new external_value(PARAM_TEXT, 'The theme the user has selected', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- ));
- }
-
- public static function register_user($userid, $lang, $theme) {
- global $DB;
-
- self::validate_parameters(
- self::register_user_parameters(),
- array('userid' => $userid, 'lang' => $lang, 'theme' => $theme)
- );
-
- user_helper::assert_access($userid);
-
- if (user_helper::check_user_exists($userid)) {
- throw new \moodle_exception('User already registered');
- }
-
- $user = new \stdClass();
- $user->userid = $userid;
- $user->language = $lang;
- $user->theme = $theme;
- $user->colorblindness = "none";
-
- $DB->insert_record(user_helper::TABLE, $user);
-
- $mdluser = user_helper::get_mdl_user_info($userid);
-
- $plan = new \stdClass();
- $plan->name = 'Plan for ' . $mdluser->firstname;
- $plan->enableek = plan_helper::EK_DISABLED;
-
- $planid = $DB->insert_record(plan_helper::TABLE, $plan);
-
- $planaccess = new \stdClass();
- $planaccess->userid = $userid;
- $planaccess->accesstype = plan_helper::ACCESS_TYPE_OWNER;
- $planaccess->planid = $planid;
-
- $DB->insert_record(plan_helper::ACCESS_TABLE, $planaccess);
-
- notifications_helper::notify_user($userid, -1, notifications_helper::TRIGGER_USER_REGISTERED);
-
- return array(
- 'userid' => $user->userid,
- 'username' => $mdluser->username,
- 'firstname' => $mdluser->firstname,
- 'lastname' => $mdluser->lastname,
- 'capabilities' => user_helper::get_user_capability_bitmask($userid),
- 'theme' => $user->theme,
- 'lang' => $user->language,
- 'profileimageurl' => $mdluser->profileimageurl,
- 'planid' => $planid,
- 'colorblindness' => $user->colorblindness,
- );
- }
-
- public static function register_user_returns() {
- return new external_single_structure(
- array(
- 'userid' => new external_value(PARAM_INT, 'The id of the user'),
- 'username' => new external_value(PARAM_TEXT, 'The username of the user'),
- 'firstname' => new external_value(PARAM_TEXT, 'The firstname of the user'),
- 'lastname' => new external_value(PARAM_TEXT, 'The lastname of the user'),
- 'capabilities' => new external_value(PARAM_INT, 'The capability'),
- 'theme' => new external_value(PARAM_TEXT, 'The theme the user has selected'),
- 'lang' => new external_value(PARAM_TEXT, 'The language the user has selected'),
- 'profileimageurl' => new external_value(PARAM_URL, 'The url of the profile image'),
- 'planid' => new external_value(PARAM_INT, 'The id of the plan the user is assigned to'),
- 'colorblindness' => new external_value(PARAM_TEXT, 'The colorblindness of the user'),
- )
- );
- }
-}
diff --git a/lbplanner/services/user/update_user.php b/lbplanner/services/user/update_user.php
index 9b681f46..cb9247e6 100644
--- a/lbplanner/services/user/update_user.php
+++ b/lbplanner/services/user/update_user.php
@@ -16,103 +16,99 @@
namespace local_lbplanner_services;
+use dml_exception;
use external_api;
use external_function_parameters;
use external_single_structure;
use external_value;
-use local_lbplanner\helpers\user_helper;
-use local_lbplanner\helpers\plan_helper;
+use invalid_parameter_exception;
+use moodle_exception;
+
+use local_lbplanner\helpers\{plan_helper, user_helper};
+use local_lbplanner\model\user;
/**
* Update the data for a user.
+ *
+ * @package local_lbplanner
+ * @subpackage services_user
+ * @copyright 2024 necodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class user_update_user extends external_api {
- public static function update_user_parameters() {
- return new external_function_parameters(array(
- 'userid' => new external_value(PARAM_INT, 'The id of the user to register', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'lang' => new external_value(PARAM_TEXT, 'The language the user has selected', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
- 'theme' => new external_value(PARAM_TEXT, 'The theme the user has selected', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
+ /**
+ * Parameters for update_user
+ * @return external_function_parameters
+ */
+ public static function update_user_parameters(): external_function_parameters {
+ return new external_function_parameters([
+ 'lang' => new external_value(PARAM_TEXT, 'The language the user has selected', VALUE_DEFAULT, null),
+ 'theme' => new external_value(PARAM_TEXT, 'The theme the user has selected', VALUE_DEFAULT, null),
'colorblindness' => new external_value(
PARAM_TEXT,
'The colorblindness the user has selected',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED),
+ VALUE_DEFAULT,
+ null),
'displaytaskcount' => new external_value(
PARAM_INT,
- 'The displaytaskcount the user has selected',
- VALUE_REQUIRED,
- null,
- NULL_NOT_ALLOWED),
- ));
+ 'If the user has the taskcount-enabled 1-yes 0-no',
+ VALUE_DEFAULT,
+ null),
+ ]);
}
- public static function update_user($userid, $lang, $theme, $colorblindness, $displaytaskcount) {
- global $DB;
+ /**
+ * Updates the given user in the lbplanner DB
+ * @param string $lang language the user choose
+ * @param string $theme The theme the user has selected
+ * @param string $colorblindness The colorblindness the user has selected
+ * @param int $displaytaskcount The displaytaskcount the user has selected
+ * @return array The updated user
+ * @throws moodle_exception
+ * @throws dml_exception
+ * @throws invalid_parameter_exception
+ */
+ public static function update_user($lang, $theme, $colorblindness, $displaytaskcount): array {
+ global $DB, $USER;
self::validate_parameters(
self::update_user_parameters(),
- array(
- 'userid' => $userid,
+ [
'lang' => $lang,
'theme' => $theme,
'colorblindness' => $colorblindness,
- 'displaytaskcount' => $displaytaskcount
- )
+ 'displaytaskcount' => $displaytaskcount,
+ ]
);
-
- user_helper::assert_access($userid);
-
- if (!user_helper::check_user_exists($userid)) {
- throw new \moodle_exception('User does not exist');
- }
+ user_helper::assert_access($USER->id);
// Look if User-Id is in the DB.
+ if (!user_helper::check_user_exists($USER->id)) {
+ throw new moodle_exception('User does not exist');
+ }
+ $user = user_helper::get_user($USER->id);
+ if ($lang !== null) {
+ $user->set_lang($lang);
+ }
+ if ($colorblindness !== null) {
+ $user->set_colorblindness($colorblindness);
+ }
+ if ($theme !== null) {
+ $user->set_theme($theme);
+ }
+ if ($displaytaskcount !== null) {
+ $user->set_displaytaskcount($displaytaskcount);
+ }
- $user = user_helper::get_user($userid);
-
- $user->language = $lang;
- $user->theme = $theme;
- $user->colorblindness = $colorblindness;
- $user->displaytaskcount = $displaytaskcount;
-
- $DB->update_record(user_helper::TABLE, $user, false);
-
- $mdluser = user_helper::get_mdl_user_info($userid);
-
- return array(
- 'userid' => $userid,
- 'lang' => $lang,
- 'theme' => $theme,
- 'capabilities' => user_helper::get_user_capability_bitmask($userid),
- 'username' => $mdluser->username,
- 'firstname' => $mdluser->firstname,
- 'lastname' => $mdluser->lastname,
- 'profileimageurl' => $mdluser->profileimageurl,
- 'planid' => plan_helper::get_plan_id($userid),
- 'colorblindness' => $colorblindness,
- 'displaytaskcount' => $displaytaskcount,
- 'vintage' => $mdluser->vintage,
+ $DB->update_record(user_helper::LB_PLANNER_USER_TABLE, $user->prepare_for_db());
- );
+ return $user->prepare_for_api();
}
-
- public static function update_user_returns() {
- return new external_single_structure(
- array(
- 'userid' => new external_value(PARAM_INT, 'The id of the user'),
- 'username' => new external_value(PARAM_TEXT, 'The username of the user'),
- 'firstname' => new external_value(PARAM_TEXT, 'The firstname of the user'),
- 'lastname' => new external_value(PARAM_TEXT, 'The lastname of the user'),
- 'capabilities' => new external_value(PARAM_INT, 'The role of the user'),
- 'theme' => new external_value(PARAM_TEXT, 'The theme the user has selected'),
- 'lang' => new external_value(PARAM_TEXT, 'The language the user has selected'),
- 'profileimageurl' => new external_value(PARAM_URL, 'The url of the profile image'),
- 'planid' => new external_value(PARAM_INT, 'The id of the plan the user is assigned to'),
- 'colorblindness' => new external_value(PARAM_TEXT, 'The colorblindness the user has selected'),
- 'displaytaskcount' => new external_value(PARAM_INT, 'The displaytaskcount the user has selected'),
- 'vintage' => new external_value(PARAM_TEXT, 'The vintage of the user')
- )
- );
+ /**
+ * Returns the data of a user.
+ * @return external_single_structure
+ */
+ public static function update_user_returns(): external_single_structure {
+ return user::api_structure();
}
}
diff --git a/lbplanner/settings.php b/lbplanner/settings.php
index 24b59fd4..cccad430 100644
--- a/lbplanner/settings.php
+++ b/lbplanner/settings.php
@@ -14,6 +14,14 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
+/**
+ * Defines some settings
+ *
+ * @package local_lbplanner
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
defined('MOODLE_INTERNAL') || die;
if ($hassiteconfig) {
diff --git a/lbplanner/version.php b/lbplanner/version.php
index 68f4a001..69c161af 100644
--- a/lbplanner/version.php
+++ b/lbplanner/version.php
@@ -14,12 +14,24 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
+/**
+ * Defines versioning
+ *
+ * @package local_lbplanner
+ * @copyright 2024 NecodeIT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
defined('MOODLE_INTERNAL') || die();
$release = '0.0.0';
$plugin->component = 'local_lbplanner';
$plugin->release = 'Alpha v.'.$release;
-$plugin->version = 2023030601;
+$plugin->version = 2024031200;
+$plugin->dependencies = [
+ // Depend upon version 2023110600 of local_modcustomfields.
+ 'local_modcustomfields' => 2023110600,
+];
set_config('release', $release, 'local_lbplanner');