<?php class Massmail_MessageController extends \AuthenticatedController { public function before_filter(&$action, &$args) { parent::before_filter($action, $args); if (!\MassMail\MassMailPermission::has(User::findCurrent()->id)) { throw new AccessDeniedException(); } } public function index_action($id = null) { Navigation::activateItem('/messaging/massmail/message'); PageLayout::setTitle(_('Nachricht an Zielgruppe schreiben')); $message = new \MassMail\MassMailMessage($id); $temp_id = $id ?: uniqid(md5(time())); $folder = $message->findFolder($temp_id); // SearchType needed for course selection $courseSearch = new StandardSearch('Seminar_id'); // SearchType needed for user $userSearch = new StandardSearch('user_id'); $form = \Studip\Forms\Form::fromSORM( $message, [ 'legend' => _('Grunddaten'), 'collapsed' => false, 'collapsable' => false, 'fields' => [ 'target' => [ 'type' => 'select', 'required' => true, 'label' => _('Zielgruppe'), 'value' => $message->target ?? 'all', 'options' => \MassMail\MassMailMessage::getTargets() ], 'student_filters' => [ 'type' => 'userFilter', 'label' => _('Auswahlfilter'), 'if' => 'target === "students"', 'context' => 'MassMail', 'target' => 'students', 'store' => function($value, $input) { if ($input->getContextObject()->target === 'students') { $filters = []; foreach ($value as $one) { $filter = new UserFilter($one['id'] ?? ''); $filter->fields = []; foreach ($one['attributes']['fields'] as $field) { $classname = $field['attributes']['type']; $f = new $classname(); if (!empty($fiele['id'])) { $f->setId($field['id']); } $f->setCompareOperator($field['attributes']['compare-operator']); $f->setValue($field['attributes']['value']); $filter->addField($f); } $filter->store(); $connection = new \MassMail\MassMailFilter(); $connection->filter_id = $filter->getId(); $filters[] = $connection; } $input->getContextObject()->filters = $filters; } } ], 'employee_filters' => [ 'type' => 'userFilter', 'label' => _('Auswahlfilter'), 'if' => 'target === "employees"', 'context' => 'MassMail', 'target' => 'employees', 'store' => function($value, $input) { if ($input->getContextObject()->target === 'employees') { $filters = []; foreach ($value as $one) { $filter = new UserFilter($one['id'] ?? ''); $filter->fields = []; foreach ($one['attributes']['fields'] as $field) { $classname = $field['attributes']['type']; $f = new $classname(); if (!empty($fiele['id'])) { $f->setId($field['id']); } $f->setCompareOperator($field['attributes']['compare-operator']); $f->setValue($field['attributes']['value']); $filter->addField($f); } $filter->store(); $connection = new \MassMail\MassMailFilter(); $connection->filter_id = $filter->getId(); $filters[] = $connection; } $input->getContextObject()->filters = $filters; } } ], 'semester' => [ 'type' => 'select', 'label' => _('Semester wählen'), 'value' => $message->config['semester'] ?? \Semester::findDefault()->id, 'if' => 'target === "lecturers"', 'options' => \MassMail\MassMailMessage::getSemesters(), 'store' => function($value, $input) { if ($input->getContextObject()->target === 'lecturers') { $input->getContextObject()->config = ['semester' => $value]; } } ], 'courses' => [ 'type' => 'quicksearchList', 'label' => _('Veranstaltungen wählen'), 'value' => json_encode($message->config?->getArrayCopy()['courses'] ?? []), 'if' => 'target === "courses"', 'searchtype' => $courseSearch, 'store' => function($value, $input) { if ($input->getContextObject()->target === 'courses') { $input->getContextObject()->config = []; $input->getContextObject()->config['courses'] = \Course::findAndMapMany( function ($course) { return ['id' => $course->id, 'name' => $course->getFullname()]; }, json_decode($value, true) ); } } ], 'course_perm' => [ 'type' => 'select', 'label' => _('Berechtigungsebene wählen'), 'value' => $message->config['perm'] ?? 'autor', 'if' => 'target === "courses"', 'options' => [ 'dozent' => get_title_for_status('dozent', 2, 1), 'tutor' => get_title_for_status('tutor', 2, 1), 'autor' => get_title_for_status('autor', 2, 1), 'user' => get_title_for_status('user', 2, 1), ], 'store' => function($value, $input) { if ($input->getContextObject()->target === 'courses') { $input->getContextObject()->config['perm'] = $value; } } ], 'manual_usernames' => [ 'type' => 'textarea', 'label' => _('Liste von Benutzernamen, durch Zeilenumbruch getrennt'), 'if' => 'target === "usernames"', 'value' => $message->config['usernames'] ?? '', 'store' => function($value, $input) { if ($input->getContextObject()->target === 'usernames') { $input->getContextObject()->config = []; $input->getContextObject()->config['usernames'] = $value; } } ], 'subject' => [ 'type' => 'text', 'required' => true, 'label' => _('Betreff'), 'value' => $message->subject ], 'message' => [ 'type' => 'serialWysiwyg', 'required' => true, 'label' => _('Nachricht'), 'value' => $message->message, 'markers' => json_encode( array_map( fn ($m) => $m->toArray(), \MassMail\MassMailMarker::findAll( \MassMail\MassMailPermission::has(User::findCurrent()->id, true) ) ) ) ] ] ], $this->url_for('massmail/overview') )->addSORM($message, [ 'legend' => _('Weitere Einstellungen'), 'collapsable' => true, 'collapsed' => true, 'fields' => [ 'author_id' => [ 'type' => 'hidden', 'value' => User::findCurrent()->id ], 'attachments' => [ 'type' => 'file', 'label' => _('Dateianhänge auswählen'), 'value' => $message->folder_id ?? $message->folder_id = $folder->id, 'upload_url' => $this->url_for('massmail/message/attachments', $folder->id), 'multiple' => true, 'if' => $GLOBALS['ENABLE_EMAIL_ATTACHMENTS'] ? 'true' : 'false', 'store' => function($value, $input) { $input->getContextObject()->folder_id = $value; } ], 'tokens' => [ 'type' => 'file', 'label' => _('CSV mit Teilnahmecodes auswählen'), 'value' => $message->folder_id ?? $message->folder_id = $folder->id, 'upload_url' => $this->url_for('massmail/message/tokens', $message->folder_id), 'accept' => '.csv,.txt', 'if' => \MassMail\MassMailPermission::has(User::findCurrent()->id, true) ? 'true' : 'false', 'store' => function($value, $input) { $input->getContextObject()->folder_id = $value; } ], 'send_at_date' => [ 'type' => 'datetimepicker', 'label' => _('Zu einem späteren Zeitpunkt senden'), 'value' => $message->send_at_date ?? time() ], 'send_as' => [ 'type' => 'select', 'label' => ('Nachricht senden als'), 'value' => $message->sender_id ?? User::findCurrent()->id, 'if' => \MassMail\MassMailPermission::has(User::findCurrent()->id, true) ? 'true' : 'false', 'options' => [ User::findCurrent()->id => _('Von meiner Kennung verschicken'), 'user_id' => _('Eine andere Person eintragen'), '____%system%____' => _('Anonym, mit "Stud.IP" als Absender') ], 'store' => function($value, $input) { if ($value === User::findCurrent()->id || $value === '____%system%____') { $input->getContextObject()->sender_id = $value; } } ], 'sender_id' => [ 'type' => 'quicksearch', 'label' => _('Absender:in wählen'), 'value' => $message->sender_id ?? '', 'if' => 'send_as === "user_id"', 'searchtype' => $userSearch, 'store' => function($value, $input) { $sender_id = $input->getContextObject()->sender_id; if ($sender_id !== User::findCurrent()->id && $sender_id !== '____%system%____') { $input->sender_id = $value; } } ], 'exclude_users' => [ 'type' => 'textarea', 'label' => _('Liste von Benutzernamen, die die Nachricht nicht erhalten sollen'), 'value' => $message->exclude_users ?? '' ], 'cc' => [ 'type' => 'textarea', 'label' => _('Liste von Benutzernamen, die die Nachricht als Kopie erhalten sollen'), 'value' => $message->cc ?? '' ], 'flags' => [ 'type' => 'radio', 'label' => _('Besondere Kennzeichnung'), 'value' => $message->is_template ? 'is_template' : ($message->protected ? 'protected' : ''), 'options' => [ '' => _('Keine besondere Kennzeichnung'), 'is_template' => _('Nicht verschicken, sondern als Vorlage speichern'), 'protected' => _('Auch nach dem Versand dauerhaft speichern') ], 'store' => function($value, $input) { switch ($value) { case 'is_template': $input->getContextObject()->is_template = 1; $input->getContextObject()->protected = 0; break; case 'protected': $input->getContextObject()->is_template = 0; $input->getContextObject()->protected = 1; break; default: $input->getContextObject()->is_template = 0; $input->getContextObject()->protected = 0; break; } } ] ] ])->addStoreCallback(function ($form) { $message = $form->getLastPart()->getContextObject(); // Adjust folder range_id to the actual message id. $folder = Folder::find($message->folder_id); $folder->range_id = $message->id; $folder->store(); // Create message tokens if necessary. if ($message->hasMarkers('token')) { foreach ($folder->getTypedFolder()->getFiles() as $ref) { if (isset($ref->file->metadata['is_token_file'])) { $file = fopen($ref->file->getPath(), 'r'); while (!feof($file)) { $token = fgets($file); $t = new \MassMail\MassMailToken(); $t->message_id = $message->id; $t->token = $token; $t->store(); } } } } })->autoStore(); $this->render_form($form); } public function delete_action(int $id) { $message = \MassMail\MassMailMessage::find($id); if ( !$message || ( $message->author_id !== User::findCurrent()->id && !\MassMail\MassMailPermission::has(User::findCurrent()->id, true) ) ) { throw new AccessDeniedException(); } if ($message->delete() !== false) { PageLayout::postSuccess(_('Die Nachricht wurde gelöscht.')); } else { PageLayout::postError(_('Die Nachricht konnte nicht gelöscht werden.')); } $this->relocate('massmail/overview'); } public function attachments_action(string $folder_id) { if (!$GLOBALS['ENABLE_EMAIL_ATTACHMENTS']) { throw new AccessDeniedException(); } $folder = Folder::find($folder_id)->getTypedFolder(); $uploaded = FileManager::handleFileUpload($_FILES['attachments'], $folder); if (!empty($uploaded['error'])) { $this->set_status(400); $this->render_text(implode('<br>' . $uploaded['error'])); } else { $this->render_nothing(); } } public function tokens_action(string $folder_id) { if (!\MassMail\MassMailPermission::has(User::findCurrent()->id, true)) { throw new AccessDeniedException(); } $data = [ 'name' => [$_FILES['tokens']['name']], 'tmp_name' => [$_FILES['tokens']['tmp_name']], 'type' => [$_FILES['tokens']['type']], 'error' => [$_FILES['tokens']['error']], 'size' => [$_FILES['tokens']['size']], ]; $folder = Folder::find($folder_id)->getTypedFolder(); $uploaded = FileManager::handleFileUpload($data, $folder); if (!empty($uploaded['error'])) { $this->set_status(400); $this->render_text(implode('<br>' . $uploaded['error'])); } else { // Set metadata for created file, indicating that this is a file with message tokens. foreach ($uploaded['files'] as $ref) { $ref->file->metadata = ['is_token_file' => true]; $ref->file->store(); } $this->render_nothing(); } } }