aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hackl <hackl@data-quest.de>2025-07-09 08:56:42 +0200
committerThomas Hackl <hackl@data-quest.de>2025-07-25 13:51:44 +0200
commit241783fad82aaaa0167316e58ffb5ec3660a012e (patch)
treeb4264c82dc602b193b69d8e765b5c02653d39ea6
parent263b56af47c8039a8c9b6fba67a8f67ea8e324bd (diff)
adjust to new int root ID
-rw-r--r--app/controllers/admin/tree.php4
-rw-r--r--app/views/admin/tree/edit.php2
-rw-r--r--db/migrations/6.1.6_tree_node_path.php (renamed from db/migrations/6.1.2_tree_node_path.php)11
-rw-r--r--lib/classes/JsonApi/Schemas/TreeNode.php2
-rw-r--r--lib/models/StudipStudyArea.php46
-rw-r--r--resources/vue/components/tree/StudipTreeList.vue4
-rw-r--r--resources/vue/components/tree/StudipTreeNode.vue8
-rw-r--r--resources/vue/components/tree/StudipTreeTable.vue2
8 files changed, 44 insertions, 35 deletions
diff --git a/app/controllers/admin/tree.php b/app/controllers/admin/tree.php
index 5d22775..8a307c8 100644
--- a/app/controllers/admin/tree.php
+++ b/app/controllers/admin/tree.php
@@ -22,7 +22,7 @@ class Admin_TreeController extends AuthenticatedController
'editable' => true,
'semester' => $this->semester,
'show-structure-as-navigation' => true,
- 'start-id' => Request::get('node_id', 'RangeTreeNode_root'),
+ 'start-id' => Request::get('node_id', 'RangeTreeNode_0'),
'title' => _('Einrichtungshierarchie bearbeiten'),
'view-type' => 'table',
'visible-children-only' => false,
@@ -52,7 +52,7 @@ class Admin_TreeController extends AuthenticatedController
'editable' => true,
'semester' => $this->semester,
'show-structure-as-navigation' => true,
- 'start-id' => Request::get('node_id', 'StudipStudyArea_root'),
+ 'start-id' => Request::get('node_id', 'StudipStudyArea_' . StudipStudyArea::ROOT),
'title' => _('Veranstaltungshierarchie bearbeiten'),
'view-type' => 'table',
'visible-children-only' => false,
diff --git a/app/views/admin/tree/edit.php b/app/views/admin/tree/edit.php
index 0076b95..15f6b07 100644
--- a/app/views/admin/tree/edit.php
+++ b/app/views/admin/tree/edit.php
@@ -24,7 +24,7 @@
<option value="<?= htmlReady($index) ?>"<?= $node->type == $index ? ' selected' : '' ?>>
<?= $type['name'] ?: _('Standard') ?>
<?= !$type['editable'] ? _('(nicht mehr nachträglich änderbar)') : '' ?>
- <?= $type['hidden'] ? _('(dieser Knoten ist versteckt)') : '' ?>
+ <?= !empty($type['hidden']) ? _('(dieser Knoten ist versteckt)') : '' ?>
</option>
<? endforeach ?>
</select>
diff --git a/db/migrations/6.1.2_tree_node_path.php b/db/migrations/6.1.6_tree_node_path.php
index 76468da..35c3bd1 100644
--- a/db/migrations/6.1.2_tree_node_path.php
+++ b/db/migrations/6.1.6_tree_node_path.php
@@ -4,7 +4,7 @@ return new class extends Migration
{
public function description()
{
- return 'Adds the path to the current node to all sem_tree and range_tree entries.';
+ return 'Introduces numeric IDs and adds the path to the current node to all sem_tree and range_tree entries.';
}
public function up()
@@ -44,11 +44,16 @@ return new class extends Migration
{
foreach ($classname::findByParent_id($oldParentId, "ORDER BY `priority`") as $child) {
$currentId++;
+ $newAncestors = $ancestors;
+ if ($ancestors !== '') {
+ $newAncestors .= '|';
+ }
+ $newAncestors .= $newParentId;
$oldId = $child->id;
$child->id = $currentId;
$child->parent_id = $newParentId;
- $child->ancestors = $ancestors . ($ancestors === '' ? '' : '|') . $newParentId;
+ $child->ancestors = $newAncestors;
$child->store();
DBManager::get()->execute(
@@ -56,7 +61,7 @@ return new class extends Migration
['new' => $child->id, 'old' => $oldId]
);
- $currentId = $this->buildStructure($classname, $oldId, $child->id, $currentId, $child->ancestors);
+ $currentId = $this->buildStructure($classname, $oldId, $child->id, $currentId, $newAncestors);
}
return $currentId;
diff --git a/lib/classes/JsonApi/Schemas/TreeNode.php b/lib/classes/JsonApi/Schemas/TreeNode.php
index 9824450..13c826a 100644
--- a/lib/classes/JsonApi/Schemas/TreeNode.php
+++ b/lib/classes/JsonApi/Schemas/TreeNode.php
@@ -26,7 +26,7 @@ class TreeNode extends SchemaProvider
public function getAttributes($resource, ContextInterface $context): iterable
{
$schema = [
- 'id' => (string) $resource->getId(),
+ 'id' => $resource->getId(),
'name' => (string) $resource->getName(),
'description' => (string) $resource->getDescription(),
'description-formatted' => (string) formatReady($resource->getDescription()),
diff --git a/lib/models/StudipStudyArea.php b/lib/models/StudipStudyArea.php
index c48d5dd..c3121b2 100644
--- a/lib/models/StudipStudyArea.php
+++ b/lib/models/StudipStudyArea.php
@@ -427,9 +427,9 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode
public static function getNode($id): StudipTreeNode
{
- if ($id === 'root') {
+ if ($id == static::ROOT) {
return static::build([
- 'id' => 'root',
+ 'id' => self::ROOT,
'name' => Config::get()->UNI_NAME_CLEAN,
]);
}
@@ -506,7 +506,7 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode
$semclass = 0,
$with_children = false
): int {
- if ($this->id === 'root' && !$with_children) {
+ if ($this->id == 0 && !$with_children) {
return 0;
}
@@ -519,12 +519,11 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode
$query = "SELECT COUNT(DISTINCT t.`seminar_id`) FROM `seminar_sem_tree` t {$condition}";
if ($with_children) {
- $query .= " AND t.`sem_tree_id` IN (:ids)";
- $parameters['ids'] = array_merge([$this->id], $this->getDescendantIds());
+ $query .= " AND (t.`ancestors` LIKE '%|:id|%' OR t.`ancestors` LIKE ':id|%' OR t.`ancestors` LIKE '%|:id')";
} else {
$query .= " AND t.`sem_tree_id` = :id";
- $parameters['id'] = $this->id;
}
+ $parameters['id'] = $this->id;
return DBManager::get()->fetchColumn($query, $parameters);
}
@@ -548,12 +547,11 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode
$query = "SELECT DISTINCT s.* FROM `seminar_sem_tree` AS t {$condition}";
if ($with_children) {
- $query .= " AND t.`sem_tree_id` IN (:ids)";
- $parameters['ids'] = array_merge([$this->id], $this->getDescendantIds());
+ $query .= " AND (t.`ancestors` LIKE '%|:id|%' OR t.`ancestors` LIKE ':id|%' OR t.`ancestors` LIKE '%|:id')";
} else {
$query .= " AND t.`sem_tree_id` = :id";
- $parameters['id'] = $this->id;
}
+ $parameters['id'] = $this->id;
$query .= " ORDER BY " . implode(', ', $order_by);
@@ -562,19 +560,25 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode
public function getAncestorNodes(): array
{
- $path = [
+ return array_merge(
[
- 'id' => $this->id,
- 'name' => $this->getName(),
- 'classname' => static::class
- ]
- ];
-
- if ($this->parent_id) {
- $path = array_merge($this->getNode($this->parent_id)->getAncestorNodes(), $path);
- }
-
- return $path;
+ [
+ 'id' => static::ROOT,
+ 'name' => Config::get()->UNI_NAME_CLEAN,
+ 'classname' => static::class
+ ]
+ ],
+ static::findAndMapMany(
+ function ($node) {
+ return [
+ 'id' => $node->id,
+ 'name' => $node->getName(),
+ 'classname' => static::class
+ ];
+ },
+ explode('|', $this->ancestors)
+ )
+ );
}
/**
diff --git a/resources/vue/components/tree/StudipTreeList.vue b/resources/vue/components/tree/StudipTreeList.vue
index e76e29a..53265d9 100644
--- a/resources/vue/components/tree/StudipTreeList.vue
+++ b/resources/vue/components/tree/StudipTreeList.vue
@@ -1,7 +1,7 @@
<template>
<article class="studip-tree-list">
<header>
- <tree-breadcrumb v-if="currentNode.id !== 'root'" :node="currentNode"
+ <tree-breadcrumb v-if="currentNode.id !== 0" :node="currentNode"
:edit-url="editUrl" :icon="breadcrumbIcon" :assignable="assignable"
:num-children="children.length" :num-courses="courses.length"
:show-navigation="showStructureAsNavigation"
@@ -12,7 +12,7 @@
<h1>
{{ currentNode.attributes.name }}
- <a v-if="editable && currentNode.attributes.id !== 'root'"
+ <a v-if="editable && currentNode.attributes.id !== 0"
:href="editUrl + '/' + currentNode.attributes.id"
@click.prevent="editNode(editUrl, currentNode.id)" data-dialog="size=medium"
:title="$gettext('%{name} bearbeiten', {name: currentNode.attributes.name}, true)">
diff --git a/resources/vue/components/tree/StudipTreeNode.vue b/resources/vue/components/tree/StudipTreeNode.vue
index 81abec1..ab88fbd 100644
--- a/resources/vue/components/tree/StudipTreeNode.vue
+++ b/resources/vue/components/tree/StudipTreeNode.vue
@@ -6,7 +6,7 @@
<studip-icon :shape="openState ? 'arr_1down': 'arr_1right'"/>
</div>
</a>
- <button v-if="isAssignable && node.attributes.id !== 'root'" class="studip-tree-node-assignment-state"
+ <button v-if="isAssignable && node.attributes.id !== 0" class="studip-tree-node-assignment-state"
@click.prevent="changeAssignmentState()" :title="$gettext('Zuordnung ändern')">
<studip-icon :shape="assignmentState === 0
? 'checkbox-unchecked'
@@ -19,9 +19,9 @@
</a>
<studip-tooltip-icon v-if="withInfo && !isLoading && node.attributes.description?.trim() !== ''"
:text="node.attributes['description-formatted'].trim()"></studip-tooltip-icon>
- <input v-if="isAssignable && node.attributes.id !== 'root'" type="hidden" :name="assignmentAction"
+ <input v-if="isAssignable && node.attributes.id !== 0" type="hidden" :name="assignmentAction"
:value="node.attributes.id">
- <a v-if="editable && node.attributes.id !== 'root'" :href="editUrl + '/' + node.attributes.id"
+ <a v-if="editable && node.attributes.id !== 0" :href="editUrl + '/' + node.attributes.id"
@click.prevent="editNode(editUrl, node.id)" data-dialog="size=medium"
class="studip-tree-node-edit-link">
<studip-icon shape="edit"></studip-icon>
@@ -267,7 +267,7 @@ export default {
if (this.theAncestors?.includes(this.node.id) && !this.openState) {
this.toggleNode();
}
- if (this.isAssignable && this.node.attributes.id !== 'root') {
+ if (this.isAssignable && this.node.attributes.id !== 0) {
this.checkAssignments();
}
});
diff --git a/resources/vue/components/tree/StudipTreeTable.vue b/resources/vue/components/tree/StudipTreeTable.vue
index 0df3826..c88cb82 100644
--- a/resources/vue/components/tree/StudipTreeTable.vue
+++ b/resources/vue/components/tree/StudipTreeTable.vue
@@ -4,7 +4,7 @@
</div>
<article v-else class="studip-tree-table">
<header>
- <tree-breadcrumb v-if="currentNode.id !== 'root'" :node="currentNode"
+ <tree-breadcrumb v-if="currentNode.id !== 0" :node="currentNode"
:icon="breadcrumbIcon" :editable="editable" :edit-url="editUrl" :create-url="createUrl"
:delete-url="deleteUrl" :show-navigation="showStructureAsNavigation"
:num-children="children.length" :num-courses="courses.length"