Skip to content
Snippets Groups Projects
Commit 7dddea8c authored by Jan-Hendrik Willms's avatar Jan-Hendrik Willms
Browse files

rework aux lock rules, use sorm model, deprecate old class and let name and...

rework aux lock rules, use sorm model, deprecate old class and let name and description be translatable, fixes #1791

Closes #1791

Merge request !1177
parent 12310228
Branches
No related tags found
No related merge requests found
Showing
with 481 additions and 313 deletions
......@@ -372,13 +372,7 @@ class Admin_CoursesController extends AuthenticatedController
]],
LockRule::findAllByType('sem')
));
$this->aux_lock_rules = array_merge(
[[
'name' => '--' . _("keine Zusatzangaben") . '--',
'lock_id' => 'none'
]],
AuxLockRules::getAllLockRules()
);
$this->aux_lock_rules = AuxLockRule::findBySQL('1 ORDER BY name');
//build the sidebar:
......
......@@ -17,6 +17,8 @@
*/
class Admin_SpecificationController extends AuthenticatedController
{
protected $_autobind = true;
/**
* Common tasks for all actions.
*/
......@@ -41,25 +43,39 @@ class Admin_SpecificationController extends AuthenticatedController
*/
public function index_action()
{
$this->allrules = AuxLockRules::getAllLockRules();
$this->rules = AuxLockRule::findBySQL('1 ORDER BY name');
Sidebar::Get()->addWidget(new ActionsWidget())->addLink(
_('Neue Regel anlegen'),
$this->editURL(),
Icon::create('add')
);
}
/**
* Edit or create a rule
*
* @param string $edit_id
* @property AuxLockRule $rule
*/
public function edit_action($id = null)
public function edit_action(AuxLockRule $rule = null)
{
//get data
$user_field = 'user';
$semdata_field = 'usersemdata';
$this->semFields = AuxLockRules::getSemFields();
$this->entries_user = DataField::getDataFields($user_field);
$this->entries_semdata = DataField::getDataFields($semdata_field);
$this->rule = is_null($id) ? false : AuxLockRules::getLockRuleByID($id);
if ($GLOBALS['perm']->have_perm('root') && count($this->entries_semdata) == 0) {
$rule->name = Request::i18n('name', $rule->name);
$rule->description = Request::i18n('description', $rule->description);
$rule->attributes = Request::optionArray('fields') ?: $rule->attributes;
$rule->sorting = Request::getArray('order') ?: $rule->sorting;
if ($GLOBALS['perm']->have_perm('root')) {
Sidebar::Get()->addWidget(new ActionsWidget())->addLink(
_('Datenfelder bearbeiten'),
URLHelper::getURL('dispatch.php/admin/datafields'),
Icon::create('edit')
);
}
$this->semFields = $this->getSemFields();
$this->entries_user = DataField::getDataFields('user');
$this->entries_semdata = DataField::getDataFields('usersemdata');
if ($GLOBALS['perm']->have_perm('root') && count($this->entries_semdata) === 0) {
PageLayout::postWarning(sprintf(
_('Sie müssen zuerst im Bereich %sDatenfelder%s in der Kategorie '
. '<em>Datenfelder für Personenzusatzangaben in Veranstaltungen</em> '
......@@ -74,51 +90,63 @@ class Admin_SpecificationController extends AuthenticatedController
* Store or edit Rule
* @param string $id
*/
public function store_action($id = '')
public function store_action(AuxLockRule $rule = null)
{
CSRFProtection::verifyRequest();
CSRFProtection::verifyUnsafeRequest();
$errors = [];
if (!Request::get('rulename')) {
if (!trim(Request::get('name'))) {
$errors[] = _('Bitte geben Sie der Regel mindestens einen Namen!');
}
if (!AuxLockRules::checkLockRule(Request::getArray('fields'))) {
if (!AuxLockRule::validateFields(Request::optionArray('fields'))) {
$errors[] = _('Bitte wählen Sie mindestens ein Feld aus der Kategorie "Zusatzinformationen" aus!');
}
if (empty($errors)) {
if (!$id) {
//new
AuxLockRules::createLockRule(Request::get('rulename'), Request::get('description'), Request::getArray('fields'), Request::getArray('order'));
if ($errors) {
PageLayout::postError(_('Ihre Eingaben sind ungültig.'), $errors);
$this->keepRequest();
$this->redirect($this->editURL($rule));
} else {
//edit
AuxLockRules::updateLockRule($id, Request::get('rulename'), Request::get('description'), Request::getArray('fields'), Request::getArray('order'));
}
$rule->name = Request::i18n('name');
$rule->description = Studip\Markup::purifyHtml(Request::i18n('description'));
$rule->attributes = Request::optionArray('fields') ?? [];
$rule->sorting = Request::getArray('order') ?? [];
if ($rule->store()) {
PageLayout::postSuccess(sprintf(
_('Die Regel "%s" wurde erfolgreich gespeichert!'),
htmlReady(Request::get('rulename'))
htmlReady($rule->name)
));
} else {
PageLayout::postError(_('Ihre Eingaben sind ungültig.'), $errors);
}
$this->redirect('admin/specification');
}
}
/**
* Delete a rule, using a modal dialog
*
* @param string $rule_id
*/
public function delete_action($rule_id)
public function delete_action(AuxLockRule $rule)
{
CSRFProtection::verifyUnsafeRequest();
if (AuxLockRules::deleteLockRule($rule_id)) {
PageLayout::postSuccess(_('Die Regel wurde erfolgreich gelöscht!'));
} else {
$result = $rule->delete();
if ($result === false) {
PageLayout::postError(_('Es können nur nicht verwendete Regeln gelöscht werden!'));
} elseif ($result > 0) {
PageLayout::postSuccess(_('Die Regel wurde erfolgreich gelöscht!'));
}
$this->redirect('admin/specification');
$this->redirect($this->indexURL());
}
private function getSemFields(): array
{
return [
'vasemester' => _('Semester'),
'vanr' => _('Veranstaltungsnummer'),
'vatitle' => _('Veranstaltungstitel'),
'vadozent' => _('Dozent'),
];
}
}
<?php
# Lifter007: TODO
# Lifter003: TODO
# Lifter010: TODO
/*
* Copyright (C) 2009 - Marcus Lunzenauer <mlunzena@uos.de>
*
......@@ -16,4 +12,21 @@ class AuthenticatedController extends StudipController
{
protected $with_session = true; //we do need to have a session for this controller
protected $allow_nobody = false; //nobody is not allowed and always gets a login-screen
public function before_filter(&$action, &$args)
{
parent::before_filter($action, $args);
// Restore request if present
if (isset($this->flash['request'])) {
foreach ($this->flash['request'] as $key => $value) {
Request::set($key, $value);
}
}
}
protected function keepRequest()
{
$this->flash['request'] = Request::getInstance()->getIterator()->getArrayCopy();
}
}
......@@ -26,13 +26,6 @@ abstract class ConsultationController extends AuthenticatedController
URLHelper::addLinkParam('cid', $this->range->id);
}
// Restore request if present
if (isset($this->flash['request'])) {
foreach ($this->flash['request'] as $key => $value) {
Request::set($key, $value);
}
}
// This defines the function to display a note. Not really a partial,
// not a controller method. This has no real place...
$this->displayNote = function ($what, $length = 40, $position = 'above') {
......@@ -72,11 +65,6 @@ abstract class ConsultationController extends AuthenticatedController
return $this->range->getConfiguration()->CONSULTATION_TAB_TITLE;
}
protected function keepRequest()
{
$this->flash['request'] = Request::getInstance()->getIterator()->getArrayCopy();
}
/**
* @param $block_id
*
......
......@@ -1330,6 +1330,9 @@ class Course_MembersController extends AuthenticatedController
$course = Course::findCurrent();
$member = $course->members->findOneBy('user_id', $GLOBALS['user']->id);
$this->datafields = $member ? $course->aux->getMemberData($member) : [];
$this->editable = false;
// We need aux data in the view
$this->aux = $course->aux;
......
......@@ -87,24 +87,14 @@ class Course_OverviewController extends AuthenticatedController
$this->show_dozenten = $show_dozenten;
// Check lock rules
if (!$GLOBALS["perm"]->have_studip_perm('dozent', $this->course_id)) {
$rule = AuxLockRules::getLockRuleBySemId($this->course_id);
if (isset($rule)) {
$show = false;
foreach ((array) $rule['attributes'] as $val) {
if ($val == 1) {
// Es gibt also Zusatzangaben. Nun noch überprüfen ob der Nutzer diese Angaben schon gemacht hat...
if (!$GLOBALS['perm']->have_studip_perm('dozent', $this->course_id)) {
$rule = AuxLockRule::findOneByCourse($this->course);
if ($rule && count($rule->attributes) > 0) {
$count = DataField::countBySql("LEFT JOIN datafields_entries USING (datafield_id) WHERE object_type = ? AND sec_range_id = ? AND range_id = ?",
['usersemdata', $this->course_id, $GLOBALS['user']->id]
);
if (!$count) {
$show = true;
}
break;
}
}
if ($show) {
if ($count === 0) {
PageLayout::postInfo(
_("Sie haben noch nicht die für diese Veranstaltung benötigten Zusatzinformationen eingetragen."),
[
......
<?php
/**
* @var Course $course
* @var array $aux_lock_rules
* @var AuxLockRule[] $aux_lock_rules
* @var array $values
*/
?>
<select name="lock_sem[<?= htmlReady($course->id) ?>]" style="max-width: 200px">
<? foreach ($aux_lock_rules as $id => $rule) : ?>
<option value="<?= $id ?>" <?= $values['aux_lock_rule'] == $id ? 'selected' : '' ?>>
<?= htmlReady($rule['name']) ?>
<option value="none">
--<?= _('keine Zusatzangaben') ?>--
</option>
<? foreach ($aux_lock_rules as $rule) : ?>
<option value="<?= htmlReady($rule->id) ?>" <? if ($values['aux_lock_rule'] === $rule->id) echo 'selected'; ?>>
<?= htmlReady($rule->name) ?>
</option>
<? endforeach ?>
</select>
......
<?php
/**
* @var array $values
* @var array $aux_lock_rules
* @var AuxLockRule[] $aux_lock_rules
*/
?>
<label><?= _('Für alle Veranstaltungen') ?>
<select name="lock_sem_all" style="max-width: 200px">
<? foreach ($aux_lock_rules as $id => $rule) : ?>
<option value="<?= $id ?>"
<?= ($values['aux_lock_rule'] == $id) ? 'selected' : '' ?>>
<?= htmlReady($rule["name"]) ?>
<option value="none">
--<?= _('keine Zusatzangaben') ?>--
</option>
<? foreach ($aux_lock_rules as $rule) : ?>
<option value="<?= htmlReady($rule->id) ?>"
<? if ($values['aux_lock_rule'] === $rule->id) echo 'selected'; ?>>
<?= htmlReady($rule->name) ?>
</option>
<? endforeach ?>
</select>
</label>
<label>
<input type="checkbox" value="1" name="aux_all_forced">
<?=_("Erzwungen")?>
<?=_('Erzwungen')?>
</label>
<?= \Studip\Button::createAccept(_('Speichern'), 'all'); ?>
......@@ -2,10 +2,8 @@
/**
* @var string $name
* @var string $id
* @var array $rule
* @var AuxLockRule $rule
*/
$fields = Request::getArray('fields');
$order = Request::getArray('order');
?>
<section>
......@@ -17,25 +15,23 @@ $order = Request::getArray('order');
<?= htmlReady($name) ?>
<? endif ?>
<div class="hgroup">
<label class="col-2">
<?= _('Sortierung') ?>
<input id="order_<?= $id ?>" min="0" type="number" size="3" name="order[<?= $id ?>]"
value="<?= (int)(($order && isset($order[$id])) ? $order[$id] : @$rule['order'][$id]) ?>">
<input type="hidden" name="fields[<?= $id ?>]" value="0">
<input id="order_<?= htmlReady($id) ?>" min="0" type="number" size="3" name="order[<?= htmlReady($id) ?>]"
value="<?= ($rule->sorting[$id] ?? 0) ?>">
</label>
<label class="col-2">
<input type="checkbox"
name="fields[<?= $id ?>]"
value="1"
<?= (($fields && isset($fields[$id])) ? $fields[$id] : @$rule['attributes'][$id]) ? 'checked="checked"' : '' ?>>
name="fields[]"
value="<?= htmlReady($id) ?>"
<? if ($rule->attributes->contains($id)) echo 'checked'; ?>>
<?= _('Aktivieren') ?>
</label>
<label class="col-1">
<? if (!empty($institution)) : ?>
<label class="col-1">
<?= htmlReady($institution->name )?>
<? endif; ?>
</label>
<? endif; ?>
</div>
</section>
......@@ -3,59 +3,56 @@
/**
* @var Admin_SpecificationController $controller
* @var AuxLockRules $rule
* @var AuxLockRule $rule
* @var array $semFields
* @var DataField[] $entries_semdata
* @var DataField[] $entries_user
*/
use Studip\Button, Studip\LinkButton;
?>
<? if (isset($flash['error'])) : ?>
<?= MessageBox::error($flash['error'], $flash['error_detail']) ?>
<? elseif (isset($flash['info'])): ?>
<?= MessageBox::info($flash['info']) ?>
<? endif ?>
<form action="<?= $controller->url_for('admin/specification/store' . ($rule ? '/' . $rule['lock_id'] : '')) ?>"
method="post" class="default">
<form action="<?= $controller->store($rule) ?>" method="post" class="default">
<?= CSRFProtection::tokenTag() ?>
<fieldset>
<legend>
<? if ($rule) : ?>
<?= sprintf(_('Regel "%s" editieren'), htmlReady($rule['name'])) ?>
<? else : ?>
<? if ($rule->isNew()) : ?>
<?= _('Eine neue Regel definieren') ?>
<? else : ?>
<?= sprintf(_('Regel "%s" editieren'), htmlReady($rule['name'])) ?>
<? endif ?>
</legend>
<label>
<span class="required">
<?= _('Name der Regel:') ?>
<?= _('Name der Regel') ?>
</span>
<input type="text" name="rulename" value="<?= htmlReady(Request::get('rulename', $rule ? $rule['name'] : '')) ?>"
required="required">
<?= I18N::input('name', $rule->name, [
'required' => '',
]) ?>
</label>
<label>
<?= _('Beschreibung') ?>
<textarea cols="60" rows="5"
name="description"><?= htmlReady(Request::get('description', $rule ? $rule['description'] : '')) ?></textarea>
<?= I18N::textarea('description', $rule->description, [
'class' => 'wysiwyg',
]) ?>
</label>
</fieldset>
<? if (count($entries_semdata) > 0) : ?>
<fieldset>
<legend>
<?= _('Zusatzinformationen') ?>
</legend>
<? foreach ($entries_semdata as $id => $entry) : ?>
<?= $this->render_partial('admin/specification/_field', array_merge(
compact('rule'),
['id' => $entry->datafield_id, 'name' => $entry->name],
['required' => true, 'institution' => $entry->institution]
)) ?>
<?= $this->render_partial('admin/specification/_field', [
'rule' => $rule,
'id' => $entry->datafield_id,
'name' => $entry->name,
'required' => true,
'institution' => $entry->institution,
]) ?>
<? endforeach ?>
</fieldset>
<? endif ?>
<? if (count($semFields) > 0) : ?>
<fieldset>
<legend>
<?= _('Veranstaltungsinformationen') ?>
......@@ -64,7 +61,6 @@ use Studip\Button, Studip\LinkButton;
<?= $this->render_partial('admin/specification/_field', compact('rule', 'id', 'name')) ?>
<? endforeach ?>
</fieldset>
<? endif ?>
<? if (count($entries_user) > 0) : ?>
<fieldset>
......@@ -72,26 +68,21 @@ use Studip\Button, Studip\LinkButton;
<?= _('Personenbezogene Informationen') ?>
</legend>
<? foreach ($entries_user as $id => $entry) : ?>
<?= $this->render_partial('admin/specification/_field',
array_merge(compact('rule'), ['id' => $entry->datafield_id, 'name' => $entry->name])) ?>
<?= $this->render_partial('admin/specification/_field', [
'rule' => $rule,
'id' => $entry->datafield_id,
'name' => $entry->name,
]) ?>
<? endforeach ?>
</fieldset>
<? endif ?>
<footer>
<? if ($rule) : ?>
<?= Button::createAccept(_('Übernehmen'), 'uebernehmen', ['title' => _('Änderungen übernehmen')]) ?>
<? else : ?>
<? if ($rule->isNew()) : ?>
<?= Button::createAccept(_('Erstellen'), 'erstellen', ['title' => _('Neue Regel erstellen')]) ?>
<? else : ?>
<?= Button::createAccept(_('Übernehmen'), 'uebernehmen', ['title' => _('Änderungen übernehmen')]) ?>
<? endif ?>
<?= LinkButton::createCancel(_('Abbrechen'), $controller->url_for('admin/specification'), ['title' => _('Zurück zur Übersicht')]) ?>
<?= LinkButton::createCancel(_('Abbrechen'), $controller->indexURL(), ['title' => _('Zurück zur Übersicht')]) ?>
</footer>
</form>
<?
$sidebar = Sidebar::Get();
if ($GLOBALS['perm']->have_perm('root')) {
$actions = new ActionsWidget();
$actions->addLink(_('Datenfelder bearbeiten'), URLHelper::getLink('dispatch.php/admin/datafields'), Icon::create('add', 'clickable'));
$sidebar->addWidget($actions);
}
?>
<?php
/**
* @var Admin_SpecificationController $controller
* @var AuxLockRules[] $allrules
* @var AuxLockRule[] $rules
*/
?>
<form method="post" class="default">
<?= CSRFProtection::tokenTag() ?>
<table class="default">
<table class="default <? if (count($rules) > 0) echo 'sortable-table'; ?>" data-sortlist="[[0, 0]]">
<caption>
<?= _('Verwaltung von Zusatzangaben') ?>
</caption>
<colgroup>
<col style="width: 45%">
<col style="width: 45%">
<col style="width: 10%">
<col style="width: 40%">
<col>
<col style="width: 10ex">
<col style="width: 8ex">
</colgroup>
<thead>
<tr>
<th><?= _('Name') ?></th>
<th><?= _('Beschreibung') ?></th>
<th><?= _('Aktionen') ?></th>
<th data-sort="text"><?= _('Name') ?></th>
<th data-sort="text"><?= _('Beschreibung') ?></th>
<th data-sort="htmldata">
<abbr title="<?= _('Anzahl der zugeordneten Veranstaltungen') ?>">#</abbr>
</th>
<th class="actions" data-sort="false"><?= _('Aktionen') ?></th>
</tr>
</thead>
<tbody>
<? if (!empty($allrules)): ?>
<? foreach ($allrules as $index => $rule) : ?>
<? if (count($rules) === 0): ?>
<tr>
<td>
<?= htmlReady($rule['name']) ?>
<td colspan="4" style="text-align: center">
<?= _('Es wurden noch keine Zusatzangaben definiert.') ?>
</td>
<td>
<?= htmlReady($rule['description']) ?>
</tr>
<? endif ?>
<? foreach ($rules as $index => $rule) : ?>
<tr>
<td><?= htmlReady($rule->name) ?></td>
<td><?= htmlReady(Studip\Markup::removeHtml($rule->description)) ?></td>
<td data-sort-value="<?= count($rule->courses) ?>">
<?= number_format(count($rule->courses), 0, ',', '.') ?>
</td>
<td class="actions">
<a href="<?=$controller->url_for('admin/specification/edit/'.$rule['lock_id']) ?>" style="vertical-align: bottom">
<?= Icon::create('edit', 'clickable', ['title' => _('Regel bearbeiten')])->asImg() ?>
<a href="<?= $controller->edit($rule) ?>">
<?= Icon::create('edit')->asImg(['title' => _('Regel bearbeiten')]) ?>
</a>
<?=Icon::create('trash', 'clickable', tooltip2(_('Regel löschen')))->asInput([
'formaction' => $controller->url_for('admin/specification/delete/' . $rule['lock_id']),
'data-confirm' => sprintf(_('Wollen Sie die Regel "%s" wirklich löschen?'), $rule['name']),
'style' => 'vertical-align: bottom'
<? if (count($rule->courses) > 0): ?>
<?= Icon::create('trash', Icon::ROLE_INACTIVE)->asImg(
tooltip2(_('Die Regel kann nicht gelöscht werden, da sie noch verwendet wird.'))
) ?>
<? else: ?>
<?= Icon::create('trash')->asInput(tooltip2(_('Regel löschen')) + [
'formaction' => $controller->deleteURL($rule),
'data-confirm' => sprintf(_('Wollen Sie die Regel "%s" wirklich löschen?'), $rule->name),
]) ?>
<? endif; ?>
</td>
</tr>
<? endforeach ?>
<? else : ?>
<tr>
<td colspan="3" style="text-align: center">
<?= _('Es wurden noch keine Zusatzangaben definiert.') ?>
</td>
</tr>
<? endif ?>
</tbody>
</table>
</form>
<?
$sidebar = Sidebar::Get();
$actions = new ActionsWidget();
$actions->addLink(_('Neue Regel anlegen'), $controller->url_for('admin/specification/edit'), Icon::create('add', 'clickable'));
$sidebar->addWidget($actions);
<?php
/**
* @var DataFieldEntryModel[] $datafields
* @var AuxLockRule $aux
* @var bool $editable
*/
$editable = false;
?>
<form class="default" method="post">
<? if ($datafields) : ?>
<fieldset>
......@@ -19,7 +27,7 @@
<? if ($editable): ?>
<footer>
<?= \Studip\Button::create(_('Speichern'), 'save') ?>
<?= Studip\Button::create(_('Speichern'), 'save') ?>
</footer>
<? else: ?>
<?= MessageBox::info(_('Keine einstellbaren Zusatzdaten vorhanden')) ?>
......
<?php
final class ConvertAuxLockRulesJsonFields extends Migration
{
public function description()
{
return parent::description(); // TODO: Change the autogenerated stub
}
protected function up()
{
$query = "SELECT `lock_id`, `attributes`, `sorting` FROM `aux_lock_rules`";
$rows = DBManager::get()->fetchAll($query);
$query = "UPDATE `aux_lock_rules`
SET `attributes` = :attributes,
`sorting` = :sorting
WHERE `lock_id` = :id";
$statement = DBManager::get()->prepare($query);
foreach ($rows as $row) {
$attributes = json_decode($row['attributes'], true) ?: [];
$attributes = array_filter($attributes);
$attributes = array_keys($attributes);
$sorting = json_decode($row['sorting'], true) ?: [];
$sorting = array_filter($sorting, function ($id) use ($attributes) {
return in_array($id, $attributes);
}, ARRAY_FILTER_USE_KEY);
$statement->bindValue(':id', $row['lock_id']);
$statement->bindValue(':attributes', json_encode($attributes));
$statement->bindValue(':sorting', json_encode($sorting));
$statement->execute();
}
}
protected function down()
{
$query = "SELECT `lock_id`, `attributes` FROM `aux_lock_rules`";
$rows = DBManager::get()->fetchAll($query);
$query = "UPDATE `aux_lock_rules`
SET `attributes` = :attributes
WHERE `lock_id` = :id";
$statement = DBManager::get()->prepare($query);
foreach ($rows as $row) {
$attributes = json_decode($row['attributes'], true) ?: [];
$attributes = array_fill_keys($attributes, '1');
$statement->bindValue(':id', $row['lock_id']);
$statement->bindValue(':attributes', json_encode($attributes));
$statement->execute();
}
}
}
......@@ -23,6 +23,9 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/**
* @deprecated since Stud.IP 5.3
*/
class AuxLockRules
{
......
......@@ -233,7 +233,7 @@ class Markup
* Create HTML purifier instance with Stud.IP-specific configuration.
*
* @param boolean $autoformat Apply the AutoFormat rules
* @return HTMLPurifier A new instance of the HTML purifier.
* @return \HTMLPurifier A new instance of the HTML purifier.
*/
private static function createPurifier($autoformat)
{
......
......@@ -436,4 +436,12 @@ class StudipArrayObject implements IteratorAggregate, ArrayAccess, Serializable,
throw new InvalidArgumentException("{$key} is a protected property, use a different key");
}
}
/**
* Returns whether the given value is in the underlying array.
*/
public function contains($value): bool
{
return in_array($value, $this->storage);
}
}
......@@ -46,10 +46,11 @@ abstract class WidgetContainer
/**
* Add a widget to the container.
*
* @param Widget $widget The actual widget
* @template W of Widget
* @param W $widget The actual widget
* @param String $index Optional index/name of the widget, defaults to
* class name without "widget"
* @return Widget The added widget to allow for easier handling
* @return W The added widget to allow for easier handling
*/
public function addWidget(Widget $widget, $index = null)
{
......
......@@ -13,31 +13,75 @@
* @license http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
* @category Stud.IP
* @since 3.0
*
* @property string lock_id database column
* @property string id alias column for lock_id
* @property string name database column
* @property string description database column
* @property string attributes database column
* @property string sorting database column
* @property JSONArrayObject attributes database column
* @property JSONArrayObject sorting database column
* @property array datafields computed column
* @property string order computed column
* @property Course course belongs_to Course
* @property Course[]|SimpleORMapCollection courses has_and_belongs_to_many Courses
*/
class AuxLockRule extends SimpleORMap
{
protected static function configure($config = [])
{
$config['db_table'] = 'aux_lock_rules';
$config['belongs_to']['course'] = [
$config['has_many'] = [
'courses' => [
'class_name' => Course::class,
'foreign_key' => 'lock_id',
'assoc_foreign_key' => 'aux_lock_rule',
],
];
$config['additional_fields'] = [
'datafields' => true
];
$config['serialized_fields'] = [
'attributes' => JSONArrayObject::class,
'sorting' => JSONArrayObject::class,
];
$config['additional_fields']['datafields'] = true;
$config['additional_fields']['order'] = true;
$config['i18n_fields'] = [
'name' => true,
'description' => true,
];
$config['registered_callbacks'] = [
'before_store' => [
function (AuxLockRule $rule) {
$rule->sorting = array_filter($rule->sorting->getArrayCopy(), function ($id) use ($rule) {
return $rule->attributes->contains($id);
}, ARRAY_FILTER_USE_KEY);
},
],
'before_delete' => [
function (AuxLockRule $rule) {
return count($rule->courses) === 0;
},
]
];
parent::configure($config);
}
public static function findOneByCourse(Course $course): ?AuxLockRule
{
return self::findOneByCourseId($course->id);
}
public static function findOneByCourseId(string $course_id): ?AuxLockRule
{
$condition = "JOIN seminare ON lock_id = aux_lock_rule
WHERE Seminar_id = ?";
return self::findOneBySQL($condition, [$course_id]);
}
/**
* Cache to avoid loading datafields for a user more than once
*/
......@@ -50,8 +94,8 @@ class AuxLockRule extends SimpleORMap
*/
public function getDatafields()
{
$attributes = json_decode($this->attributes, true) ?: [];
$sorting = json_decode($this->sorting, true) ?: [];
$attributes = $this->attributes->getArrayCopy();
$sorting = $this->sorting->getArrayCopy();
foreach ($attributes as $key => $attr) {
if (!$attr) {
......@@ -64,11 +108,8 @@ class AuxLockRule extends SimpleORMap
/**
* Updates a datafield of a courseMember by the given data
*
* @param object $member
* @param object $data
*/
public function updateMember($member, $data)
public function updateMember(CourseMember $member, array $data)
{
foreach ($data as $key => $value) {
$datafield = current($this->getDatafield($member, $key));
......@@ -88,7 +129,6 @@ class AuxLockRule extends SimpleORMap
*/
public function getCourseData($course = null, $display_only = false)
{
// set course
if (!$course) {
$course = $this->course;
......@@ -98,7 +138,7 @@ class AuxLockRule extends SimpleORMap
'vadozent' => join(', ', $course->members->findBy('status', 'dozent')->getUserFullname()),
'vasemester' => $course->start_semester->name,
'vatitle' => $course->name,
'vanr' => $course->VeranstaltungsNummer,
'vanr' => $course->veranstaltungsnummer,
];
$head_mapping = [
'vadozent' => _('Dozenten'),
......@@ -145,38 +185,44 @@ class AuxLockRule extends SimpleORMap
return $result;
}
public function getMemberData($member)
public function getMemberData(CourseMember $member)
{
$datafields = SimpleCollection::createFromArray(DatafieldEntryModel::findByModel($member));
$result = [];
foreach (array_keys($this->datafields) as $field) {
foreach ($this->attributes as $field) {
// since we have no only datafields we have to filter!
if ($new = $datafields->findOneBy('datafield_id', $field)) {
$new = $datafields->findOneBy('datafield_id', $field);
if ($new) {
$result[] = $new;
}
}
usort($result, function (DatafieldEntryModel $a, DatafieldEntryModel $b) {
$a_order = $this->sorting[$a->datafield_id] ?? 0;
$b_order = $this->sorting[$b->datafield_id] ?? 0;
return $a_order - $b_order;
});
return $result;
}
/**
* Caching for the datafields
* @param type $member
* @param type $fieldID
* @return null
*/
private function getDatafield($member, $fieldID)
private function getDatafield(CourseMember $member, $field_id): ?array
{
if (mb_strlen($fieldID) == 32) {
if (!array_key_exists($fieldID, $this->datafieldCache)) {
$this->datafieldCache[$fieldID] = DataField::find($fieldID);
if (mb_strlen($field_id) === 32) {
if (!array_key_exists($field_id, $this->datafieldCache)) {
$this->datafieldCache[$field_id] = DataField::find($field_id);
}
if (isset($this->datafieldCache[$fieldID])) {
if ($this->datafieldCache[$fieldID]->object_type == 'usersemdata') {
$field = current(DatafieldEntryModel::findByModel($member, $fieldID));
if (isset($this->datafieldCache[$field_id])) {
$field = null;
if ($this->datafieldCache[$field_id]->object_type === 'usersemdata') {
$field = current(DatafieldEntryModel::findByModel($member, $field_id));
}
if ($this->datafieldCache[$fieldID]->object_type == 'user') {
$field = current(DatafieldEntryModel::findByModel(User::find($member->user_id), $fieldID));
if ($this->datafieldCache[$field_id]->object_type === 'user') {
$field = current(DatafieldEntryModel::findByModel(User::find($member->user_id), $field_id));
}
if ($field) {
$range_id = $field->sec_range_id ? [$field->range_id, $field->sec_range_id] : $field->range_id;
......@@ -185,6 +231,19 @@ class AuxLockRule extends SimpleORMap
}
}
}
return null;
}
public static function validateFields(array $fields): bool
{
$entries = DataField::getDataFields('usersemdata');
foreach ($entries as $entry) {
if (in_array($entry->id, $fields)) {
return true;
}
}
return false;
}
}
......@@ -48,37 +48,44 @@ class DatafieldEntryModel extends SimpleORMap implements PrivacyObject
*/
public static function findByModel(SimpleORMap $model, $datafield_id = null)
{
$mask = ["user" => 1, "autor" => 2, "tutor" => 4, "dozent" => 8, "admin" => 16, "root" => 32];
$mask = [
'user' => 1,
'autor' => 2,
'tutor' => 4,
'dozent' => 8,
'admin' => 16,
'root' => 32,
];
$sec_range_id = null;
if (is_a($model, "Course")) {
if ($model instanceof Course) {
$params[':institution_ids'] = $model->institutes->pluck('institut_id');
$object_class = SeminarCategories::GetByTypeId($model->status)->id;
$object_type = 'sem';
$range_id = $model->getId();
} elseif(is_a($model, "Institute")) {
$params[':institution_ids'] = [$model->Institut_id];
$range_id = $model->id;
} elseif ($model instanceof Institute) {
$params[':institution_ids'] = [$model->id];
$object_class = $model->type;
$object_type = 'inst';
$range_id = $model->getId();
} elseif(is_a($model, "User")) {
$range_id = $model->id;
} elseif ($model instanceof User) {
$params[':institution_ids'] = $model->institute_memberships->pluck('institut_id');
$object_class = $mask[$model->perms];
$object_type = 'user';
$range_id = $model->getId();
} elseif(is_a($model, "CourseMember")) {
$range_id = $model->id;
} elseif($model instanceof CourseMember) {
$params[':institution_ids'] = $model->course->institutes->pluck('institut_id');
$object_class = $mask[$model->status];
$object_type = 'usersemdata';
$range_id = $model->user_id;
$sec_range_id = $model->seminar_id;
} elseif(is_a($model, "InstituteMember")) {
} elseif($model instanceof InstituteMember) {
$params[':institution_ids'] = [$model->institut_id];
$object_class = $mask[$model->inst_perms];
$object_type = 'userinstrole';
$range_id = $model->user_id;
$sec_range_id = $model->institut_id;
} elseif (is_a($model, 'ModulDeskriptor')) {
} elseif ($model instanceof ModulDeskriptor) {
$params[':institution_ids'] = '';
if (!empty($model->modul->responsible_institute->institut_id)) {
$params[':institution_ids'] = [$model->modul->responsible_institute->institut_id];
......@@ -86,7 +93,7 @@ class DatafieldEntryModel extends SimpleORMap implements PrivacyObject
$object_class = $model->getVariant();
$object_type = 'moduldeskriptor';
$range_id = $model->deskriptor_id;
} elseif (is_a($model, 'ModulteilDeskriptor')) {
} elseif ($model instanceof ModulteilDeskriptor) {
$params[':institution_ids'] = [$model->modulteil->modul->responsible_institute->institut_id];
$object_class = $model->getVariant();
$object_type = 'modulteildeskriptor';
......@@ -106,46 +113,50 @@ class DatafieldEntryModel extends SimpleORMap implements PrivacyObject
$object_class = $model->getVariant();
$object_type = 'studycourse';
$range_id = $model->studiengang_id;
}
if (!$object_type) {
} else {
throw new InvalidArgumentException('Wrong type of model: ' . get_class($model));
}
$one_datafield = '';
$query = "SELECT a.*, b.*, a.datafield_id, b.datafield_id AS isset_content
FROM datafields a
LEFT JOIN datafields_entries b
ON (a.datafield_id=b.datafield_id AND range_id = :range_id AND sec_range_id = :sec_range_id)
WHERE object_type = :object_type
AND (lang IS NULL OR lang = '')
AND (a.institut_id IS NULL OR a.institut_id IN (:institution_ids))";
if ($datafield_id !== null) {
$one_datafield = ' AND a.datafield_id = ' . DBManager::get()->quote($datafield_id);
} else {
$one_datafield = '';
$query .= ' AND a.datafield_id = :one_datafield_id';
$params[':one_datafield_id'] = $datafield_id;
}
$query = "SELECT a.*, b.*,a.datafield_id,b.datafield_id as isset_content ";
$query .= "FROM datafields a LEFT JOIN datafields_entries b ON (a.datafield_id=b.datafield_id AND range_id = :range_id AND sec_range_id = :sec_range_id) ";
$query .= "WHERE object_type = :object_type AND (ISNULL(lang) OR lang = '') AND (a.institut_id IS NULL OR a.institut_id IN (:institution_ids))";
if ($object_type === 'studycourse') {
$query .= "AND (LOCATE(:object_class, object_class) OR LOCATE('all', object_class)) $one_datafield ORDER BY priority";
$query .= " AND (LOCATE(:object_class, object_class) OR LOCATE('all', object_class)) ORDER BY priority";
$params = array_merge($params,[
':range_id' => (string) $range_id,
':sec_range_id' => (string) $sec_range_id,
':object_type' => $object_type,
':object_class' => (string) $object_class]);
':object_class' => (string) $object_class,
]);
} elseif ($object_type === 'moduldeskriptor'
|| $object_type === 'modulteildeskriptor') {
// find datafields by language (string)
$query .= "AND (LOCATE(:object_class, object_class) OR object_class IS NULL) $one_datafield ORDER BY priority";
$query .= " AND (LOCATE(:object_class, object_class) OR object_class IS NULL) ORDER BY priority";
$params = array_merge($params,[
':range_id' => (string) $range_id,
':sec_range_id' => (string) $sec_range_id,
':object_type' => $object_type,
':object_class' => (string) $object_class]);
':object_class' => (string) $object_class,
]);
} else {
// find datafields by perms or status (int)
$query .= "AND ((object_class & :object_class) OR object_class IS NULL) $one_datafield ORDER BY priority";
$query .= " AND ((object_class & :object_class) OR object_class IS NULL) ORDER BY priority";
$params = array_merge($params, [
':range_id' => (string) $range_id,
':sec_range_id' => (string) $sec_range_id,
':object_type' => $object_type,
':object_class' => (int) $object_class]);
':object_class' => (int) $object_class,
]);
}
$st = DBManager::get()->prepare($query);
......@@ -181,6 +192,7 @@ class DatafieldEntryModel extends SimpleORMap implements PrivacyObject
}
return $ret;
}
public function setContentLanguage($language)
{
if (!Config::get()->CONTENT_LANGUAGES[$language]) {
......
<?php
/**
* @var array $languages
* @var array $attributes
* @var string $base_lang
* @var string $name
* @var I18NString $value
*
*/
?>
<? foreach ($languages as $locale => $lang): ?>
<?
$attr = $attributes;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment