threads_more_down = 0; } public function index_action($thread_id = null) { if (Navigation::hasItem('/community/blubber')) { Navigation::activateItem('/community/blubber'); } $this->search = Request::get('search'); $this->threads = BlubberThread::findMyGlobalThreads(21, null, null, null, $this->search); if (count($this->threads) > 20) { array_pop($this->threads); $this->threads_more_down = 1; } if ($thread_id) { $GLOBALS['user']->cfg->store('BLUBBER_DEFAULT_THREAD', $thread_id); } else { $thread_id = $GLOBALS['user']->cfg->BLUBBER_DEFAULT_THREAD; } if ($thread_id) { $this->thread = BlubberThread::find($thread_id); if (!$this->thread || !$this->thread->isReadable()) { $this->thread = null; } } if (!$this->thread) { $threads = array_reverse($this->threads); $this->thread = array_pop($threads); } if ($this->thread) { $this->thread->markAsRead(); } if ( empty($_SESSION['already_asked_for_avatar']) && !Avatar::getAvatar($GLOBALS['user']->id)->is_customized() ) { $_SESSION['already_asked_for_avatar'] = true; PageLayout::postInfo( sprintf( _('Wollen Sie ein Avatar-Bild nutzen? %sLaden Sie jetzt ein Bild hoch%s.'), '', '' ) ); } $this->buildSidebar(); if (Request::isDialog()) { PageLayout::setTitle($this->thread->getName()); $this->render_template('blubber/dialog'); } } public function compose_action($thread_id = null) { $this->thread = BlubberThread::find($thread_id); if ($this->thread && !$this->thread->isWritable()) { throw new AccessDeniedException(); } PageLayout::setTitle($this->thread ? _('Blubber bearbeiten') : _('Neuer Blubber')); if (Request::isPost() && count(Request::getArray('user_ids'))) { $user_ids = array_filter(Request::getArray('user_ids')); if (count($user_ids) === 1) { //try to redirect to an existing 2 person thread: $query = "SELECT blubber_threads.thread_id FROM blubber_threads JOIN blubber_mentions ON blubber_mentions.thread_id = blubber_threads.thread_id JOIN blubber_mentions AS blubber_mentions_me ON blubber_mentions_me.thread_id = blubber_threads.thread_id JOIN blubber_mentions AS blubber_mentions_friend ON blubber_mentions_friend.thread_id = blubber_threads.thread_id WHERE blubber_threads.context_type = 'private' AND blubber_mentions_me.user_id = :me AND blubber_mentions_friend.user_id = :friend GROUP BY blubber_threads.thread_id HAVING COUNT(blubber_mentions.user_id) = 2 ORDER BY blubber_threads.mkdate DESC LIMIT 1"; $statement = DBManager::get()->prepare($query); $statement->execute([ 'me' => $GLOBALS['user']->id, 'friend' => $user_ids[0], ]); $thread_id = $statement->fetchColumn(); if ($thread_id) { $this->redirect("blubber/index/{$thread_id}"); return; } } $blubber = new BlubberThread(); $blubber['context_type'] = 'private'; $blubber['context_id'] = 'global'; $blubber['user_id'] = $GLOBALS['user']->id; $blubber['external_contact'] = 0; $blubber['display_class'] = null; $blubber['visible_in_stream'] = 1; $blubber['commentable'] = 1; $blubber['content'] = ''; $blubber->store(); $query = "INSERT IGNORE INTO blubber_mentions SET thread_id = :thread_id, user_id = :user_id, external_contact = 0, mkdate = UNIX_TIMESTAMP()"; $insert = DBManager::get()->prepare($query); $user_ids[] = $GLOBALS['user']->id; foreach ($user_ids as $user_id) { $insert->execute([ 'thread_id' => $blubber->getId(), 'user_id' => $user_id, ]); } $this->relocate("blubber/index/{$blubber->getId()}"); return; } $this->contacts = Contact::findBySQL( "JOIN auth_user_md5 USING (user_id) WHERE owner_id = ? ORDER BY auth_user_md5.Nachname, auth_user_md5.Vorname", [$GLOBALS['user']->id] ); } public function delete_action($thread_id) { CSRFProtection::verifyUnsafeRequest(); $this->thread = BlubberThread::find($thread_id); if (!$this->thread->isWritable()) { throw new AccessDeniedException(); } $this->thread->delete(); PageLayout::postSuccess(_('Der Blubber wurde gelöscht.')); $this->redirect('blubber/index'); } public function write_to_action($user_id = null) { $user_ids = array_filter(Request::getArray('user_ids')); if (!$user_ids) { $user_ids = [$user_id]; } if (count($user_ids) === 1) { //try to redirect to an existing 2 person thread: $query = "SELECT blubber_threads.thread_id FROM blubber_threads JOIN blubber_mentions ON blubber_mentions.thread_id = blubber_threads.thread_id JOIN blubber_mentions AS blubber_mentions_me ON blubber_mentions_me.thread_id = blubber_threads.thread_id JOIN blubber_mentions AS blubber_mentions_friend ON blubber_mentions_friend.thread_id = blubber_threads.thread_id WHERE blubber_threads.context_type = 'private' AND blubber_mentions_me.user_id = :me AND blubber_mentions_friend.user_id = :friend GROUP BY blubber_threads.thread_id HAVING COUNT(blubber_mentions.user_id) = 2 ORDER BY blubber_threads.mkdate DESC LIMIT 1"; $statement = DBManager::get()->prepare($query); $statement->execute([ 'me' => $GLOBALS['user']->id, 'friend' => $user_ids[0], ]); $thread_id = $statement->fetchColumn(); if ($thread_id) { $this->redirect("blubber/index/{$thread_id}"); return; } } $blubber = new BlubberThread(); $blubber['context_type'] = 'private'; $blubber['context_id'] = 'global'; $blubber['user_id'] = $GLOBALS['user']->id; $blubber['external_contact'] = 0; $blubber['display_class'] = null; $blubber['visible_in_stream'] = 1; $blubber['commentable'] = 1; $blubber['content'] = ''; $blubber->store(); $query = "INSERT IGNORE INTO blubber_mentions SET thread_id = :thread_id, user_id = :user_id, external_contact = 0, mkdate = UNIX_TIMESTAMP()"; $insert = DBManager::get()->prepare($query); $user_ids[] = $GLOBALS['user']->id; foreach ($user_ids as $user_id) { $insert->execute([ 'thread_id' => $blubber->getId(), 'user_id' => $user_id, ]); } $this->redirect("blubber/index/{$blubber->getId()}"); } public function to_course_action($course_id) { if (!$GLOBALS['perm']->have_studip_perm('user', $course_id)) { throw new AccessDeniedException(); } $condition = "context_type = 'course' AND context_id = ? AND visible_in_stream = 1 AND content IS NULL"; $thread = BlubberThread::findOneBySQL($condition, [$course_id]); if (!$thread) { //create the default-thread for this context $thread = new BlubberThread(); $thread['user_id'] = $GLOBALS['user']->id; $thread['external_contact'] = 0; $thread['context_type'] = 'course'; $thread['context_id'] = $course_id; $thread['visible_in_stream'] = 1; $thread['commentable'] = 1; $thread->store(); } $this->redirect("blubber/index/{$thread->getId()}"); } /** * Saves given files (dragged into the textarea) and returns the link to the * file to the user as json. * @throws AccessDeniedException */ public function upload_files_action() { $context = Request::get('context', $GLOBALS['user']->id); $context_type = Request::option('context_type'); if ( !Request::isPost() || ( $context_type === 'course' && !$GLOBALS['perm']->have_studip_perm('autor', $context) ) ) { throw new AccessDeniedException(); } $output = []; foreach ($_FILES as $file) { if ($file['size']) { $document['user_id'] = $GLOBALS['user']->id; $success = false; $url = ''; try { $root_dir = Folder::findTopFolder($GLOBALS['user']->id); $root_dir = $root_dir->getTypedFolder(); $blubber_directory = Folder::findOneBySql( "parent_id = :parent_id AND folder_type = 'PublicFolder' AND data_content = :content", [ 'parent_id' => $root_dir->getId(), 'content' => json_encode(['Blubber']), ] ); if ($blubber_directory) { $blubber_directory = $blubber_directory->getTypedFolder(); } else { //blubber directory not found: create it $blubber_directory = FileManager::createSubFolder( $root_dir, $GLOBALS['user']->getAuthenticatedUser(), 'PublicFolder', 'Blubber', _('Ihre Dateien aus Blubberstreams') ); if (!$blubber_directory instanceof FolderType) { throw new Exception($blubber_directory[0]); } $blubber_directory->data_content = ['Blubber']; $blubber_directory->store(); } if ($blubber_directory) { //ok, blubber directory exists: we can handle the uploaded file $uploaded = FileManager::handleFileUpload( [ 'tmp_name' => [$file['tmp_name']], 'name' => [$file['name']], 'size' => [$file['size']], 'type' => [$file['type']], 'error' => [$file['error']], ], $blubber_directory, $GLOBALS['user']->id ); if ($uploaded['error']) { throw new Exception(implode("\n", $uploaded['error'])); } elseif ($uploaded['files'][0]) { $oldbase = URLHelper::setBaseURL($GLOBALS['ABSOLUTE_URI_STUDIP']); $url = $uploaded['files'][0]->getDownloadURL(); URLHelper::setBaseURL($oldbase); $success = true; } else { throw new Exception('File cannot be created!'); } } } catch (Exception $e) { $output['errors'][] = $e->getMessage(); } if ($success) { $type = null; if (mb_strpos($file['type'], 'image') !== false) { $type = 'img'; } if (mb_strpos($file['type'], 'video') !== false) { $type = 'video'; } if (mb_strpos($file['type'], 'audio') !== false || mb_strpos($file['name'], '.ogg') !== false) { $type = 'audio'; } if ($type) { $output['inserts'][] = "[{$type}]{$url}"; } else { $output['inserts'][] = "[{$file['name']}]{$url}"; } } } } $this->render_json($output); } public function add_member_to_private_action($thread_id) { $this->thread = BlubberThread::find($thread_id); if (!$this->thread['context_type'] === 'private' || !$this->thread->isReadable()) { throw new AccessDeniedException(); } PageLayout::setTitle(_('Person hinzufügen')); if (Request::isPost() && Request::option('user_id')) { $data = [ 'user_id' => Request::option('user_id'), 'thread_id' => $thread_id, 'external_contact' => 0, ]; $blubber_mention = BlubberMention::findOneBySQL('user_id = ? AND thread_id = ?', [Request::option('user_id'), $thread_id]); if ($blubber_mention) { $blubber_mention->setData($data); } else { $blubber_mention = BlubberMention::create($data); } $blubber_mention->store(); $this->relocate('blubber/index/' . $thread_id); return; } } public function private_to_studygroup_action(BlubberThread $thread) { if ($this->thread['context_type'] !== 'private' || !$this->thread->isReadable()) { throw new AccessDeniedException(); } PageLayout::setTitle(_('Studiengruppe aus Konversation erstellen')); if (Request::isPost() && count(studygroup_sem_types())) { $studgroup_sem_types = studygroup_sem_types(); $course = new Course(); $course['name'] = Request::get('name'); $course['status'] = array_shift($studgroup_sem_types); $course->store(); if ($_FILES['avatar'] && $_FILES['avatar']['error'] !== UPLOAD_ERR_NO_FILE) { CourseAvatar::getAvatar($course->getId())->createFromUpload('avatar'); } $blubber_mentions = BlubberMention::findBySQL('thread_id = ?', [$this->thread->id]); foreach ($blubber_mentions as $blubber_mention) { CourseMember::insertCourseMember($course->getId(), $blubber_mention->user_id, $blubber_mention->user_id === $this->thread['user_id'] ? 'dozent' : 'tutor'); } $this->thread['context_type'] = 'course'; $this->thread['context_id'] = $course->getId(); $this->thread['content'] = trim($this->thread['content']) ?: null; $this->thread->store(); PluginManager::getInstance()->setPluginActivated( PluginManager::getInstance() ->getPlugin(Blubber::class) ->getPluginId(), $course->getId(), true ); PageLayout::postSuccess(sprintf(_('Studiengruppe "%s" wurde angelegt.'), htmlReady($course['name']))); $this->redirect(URLHelper::getURL('dispatch.php/course/go', ['to' => $course->getId()])); } } public function leave_private_action(BlubberThread $thread) { if ($this->thread['context_type'] !== 'private' || !$this->thread->isReadable()) { throw new AccessDeniedException(); } PageLayout::setTitle(_('Private Konversation verlassen')); if (Request::isPost()) { BlubberMention::deleteBySQL("user_id = :me AND external_contact = '0' AND thread_id = :thread_id", [ 'thread_id' => $this->thread->getId(), 'me' => $GLOBALS['user']->id, ]); if (Request::get('delete_comments')) { BlubberComment::deleteBySQL("thread_id = :thread_id AND user_id = :me AND external_contact = '0'", [ 'thread_id' => $this->thread->getId(), 'me' => $GLOBALS['user']->id, ]); } if ($this->thread['user_id'] === $GLOBALS['user']->id) { $this->thread['content'] = ''; $this->thread->store(); } $count_departed = BlubberMention::countBySQL( "JOIN auth_user_md5 USING (user_id) WHERE external_contact = 0 AND thread_id = :thread_id", [ 'thread_id' => $this->thread->getId(), ] ); $count_comments = BlubberComment::countBySQL("thread_id = :thread_id AND external_contact = '0'", [ 'thread_id' => $this->thread->getId(), ]); if (!$count_departed || (!$count_comments && !$this->thread['content'])) { //ich mache das Licht aus: $this->thread->delete(); PageLayout::postSuccess(_('Private Konversation gelöscht.')); } else { PageLayout::postSuccess(_('Private Konversation verlassen')); } $this->redirect('blubber/index'); } } protected function buildSidebar() { $sidebar = Sidebar::Get(); $sidebar->addWidget(new VueWidget('blubber-search-widget')); $sidebar->addWidget(new VueWidget('blubber-threads-widget')); } }