/** * Delete / undelete posts * * @param array Array of Post IDs * @param boolean Approve (TRUE) / Unapprove (FALSE) * @return boolean */ public function topicToggleSoftDelete($topicIds, $delete = FALSE, $reason = '') { //----------------------------------------- // INIT //----------------------------------------- $_restoreTopic = 1; if ($delete === TRUE) { $_restoreTopic = -1; } $_topics = array(); $_forumIDs = array(); $_tids = IPSLib::cleanIntArray($topicIds); //----------------------------------------- // Fetch distinct topic IDs //----------------------------------------- $this->DB->build(array('select' => '*', 'from' => 'topics', 'where' => 'tid IN (' . implode(',', $_tids) . ')')); $this->DB->execute(); while ($row = $this->DB->fetch()) { if (!$this->registry->getClass('topics')->isArchived($row)) { $_topics[$row['tid']] = $row; $_forumIDs[$row['forum_id']] = $row['forum_id']; } } //----------------------------------------- // Did we get the first post too? //----------------------------------------- foreach ($_topics as $tid => $topicData) { $this->DB->update('topics', array('approved' => $_restoreTopic), 'tid=' . $tid); if ($delete) { IPSDeleteLog::addEntry($tid, 'topic', $reason, $this->memberData); } /* Rebuild topic */ $this->rebuildTopic($tid); /* Mod log */ $this->addModerateLog($topicData['forum_id'], $tid, 0, $topicData['title'], sprintf($this->lang->words['acp_altered_topics'], "approved={$_restoreTopic}", $topicData['title'])); } /* Restoring */ if (!$delete) { /* Un-deleting, so delete */ IPSDeleteLog::removeEntries($_tids, 'post'); /* Delete from recent posts */ $this->registry->topics->restoreRecentPost(array('post_topic_id' => $_tids)); /* Run moderation sync */ $this->runModSync('topicUnhide', $_tids); } else { /* Delete from recent posts */ $this->registry->topics->deleteRecentPost(array('post_topic_id' => $_tids)); /* Run moderation sync */ $this->runModSync('topicHide', $_tids); } if (count($_forumIDs)) { foreach ($_forumIDs as $_fid) { $this->forumRecount($_fid); } } /* Tagging */ $this->registry->tags->updateVisibilityByMetaId($_tids, $delete ? 0 : 1); /* Likes */ require_once IPS_ROOT_PATH . 'sources/classes/like/composite.php'; /*noLibHook*/ $_like = classes_like::bootstrap('forums', 'topics'); $_like->toggleVisibility($_tids, $delete ? 0 : 1); $this->cache->rebuildCache('stats', 'global'); return TRUE; }
/** * Merge two or more topics * * @return @e void [Outputs to screen] */ protected function _multiTopicMerge() { $this->_genericPermissionCheck('split_merge'); if (count($this->tids) < 2) { $this->_showError('mod_topics_merge_two', 103107); } //----------------------------------------- // Get the topics in ascending date order //----------------------------------------- $topics = array(); $tids = array(); $merge_ids = array(); $newViews = 0; $this->DB->build(array('select' => 'tid, forum_id, approved, views', 'from' => 'topics', 'where' => 'tid IN (' . implode(",", $this->tids) . ')', 'order' => 'start_date asc')); $this->DB->execute(); while ($r = $this->DB->fetch()) { $topics[] = $r; $tids[] = $r['tid']; $newViews += $r['views']; } //----------------------------------------- // Check... //----------------------------------------- if (count($topics) < 2) { $this->_showError('mod_topics_merge_two', 103108); } //----------------------------------------- // Make sure we can moderate EACH topic //----------------------------------------- foreach ($topics as $topic) { $this->_resetModerator($topic['forum_id']); $this->_genericPermissionCheck('split_merge'); } //----------------------------------------- // Get topic ID for first topic 'master' //----------------------------------------- $first_topic = array_shift($topics); $main_topic_id = $first_topic['tid']; $unapproved = array(); foreach ($topics as $t) { /* Add to unapproved array */ if (!$t['approved']) { $unapproved[] = $t['tid']; } $merge_ids[] = $t['tid']; } //----------------------------------------- // Sort out polls //----------------------------------------- $polls = array(); /* Who has a poll? */ $this->DB->build(array('select' => '*', 'from' => 'polls', 'where' => "tid={$main_topic_id} OR tid IN(" . implode(',', $merge_ids) . ")")); $this->DB->execute(); while ($row = $this->DB->fetch()) { $polls[$row['tid']] = $row; } /* We have one poll */ if (count($polls) == 1) { /* Update the poll ONLY if it's not our main one */ if (empty($polls[$main_topic_id])) { $this->DB->update('polls', array('tid' => $main_topic_id), "tid IN(" . implode(',', $merge_ids) . ")"); $this->DB->update('voters', array('tid' => $main_topic_id), "tid IN(" . implode(',', $merge_ids) . ")"); $this->DB->update('topics', array('poll_state' => 1), "tid={$main_topic_id}"); } } elseif (count($polls) > 1) { // Have we selected one? $chosenTid = intval($this->request['chosenpolltid']); if ($chosenTid) { /* Chosen one is not from the main topic? */ if ($chosenTid != $main_topic_id) { $this->DB->delete('polls', "tid={$main_topic_id}"); $this->DB->delete('voters', "tid={$main_topic_id}"); // Update poll status here if the chosen poll is not from the main topic otherwise there's no need to.. right? ;P $this->DB->update('topics', array('poll_state' => 1), "tid={$main_topic_id}"); } // Remove the non chosen ones $this->DB->delete('polls', "tid IN(" . implode(',', $merge_ids) . ")" . " AND tid <> {$chosenTid}"); $this->DB->delete('voters', "tid IN(" . implode(',', $merge_ids) . ")" . " AND tid <> {$chosenTid}"); // Update the master topic $this->DB->update('polls', array('tid' => $main_topic_id), "tid={$chosenTid}"); $this->DB->update('voters', array('tid' => $main_topic_id), "tid={$chosenTid}"); } else { ipsRegistry::getClass('class_localization')->loadLanguageFile(array('public_topic')); $this->output .= $this->registry->getClass('output')->getTemplate('mod')->mergeMultiplePolls($polls, $this->request['selectedtids']); return false; } } //----------------------------------------- // Update the posts, subs and topic //----------------------------------------- /* Bug #20829: If the topic is not approved, set all the posts unapproved so that they are not displayed after the merge */ if (is_array($unapproved) && count($unapproved)) { $this->DB->update('posts', array('queued' => 1), 'topic_id IN (' . implode(",", $unapproved) . ")"); } $this->DB->update('posts', array('topic_id' => $main_topic_id, 'new_topic' => 0), 'topic_id IN (' . implode(",", $merge_ids) . ")"); $this->DB->update('topics', array('views' => $newViews), 'tid=' . $main_topic_id); /* @Link http://community.invisionpower.com/resources/bugs.html/_/ip-board/merging-topics-does-not-update-attach-parent-id-for-attachments-r41886 */ $this->DB->update('attachments', array('attach_parent_id' => $main_topic_id), 'attach_parent_id IN(' . implode(",", $merge_ids) . ") AND attach_rel_module='post'"); $this->DB->delete('voters', "tid IN (" . implode(",", $merge_ids) . ")"); $this->DB->delete('topics', "tid IN (" . implode(",", $merge_ids) . ")"); /* Bug #38221: Set the new first post in topic */ $first_post = $this->DB->buildAndFetch(array('select' => 'pid', 'from' => 'posts', 'where' => "topic_id={$main_topic_id}", 'order' => "pid ASC", 'limit' => array(0, 1))); $this->DB->update('posts', array('new_topic' => 1), 'pid = ' . $first_post['pid']); //----------------------------------------- // Update followers //----------------------------------------- require_once IPS_ROOT_PATH . 'sources/classes/like/composite.php'; /*noLibHook*/ $_like = classes_like::bootstrap('forums', 'topics'); foreach ($merge_ids as $mid) { $_like->merge($mid, $main_topic_id); } //----------------------------------------- // Remove from delete log //----------------------------------------- IPSDeleteLog::removeEntries($merge_ids, 'topic', TRUE); //----------------------------------------- // Update the newly merged topic //----------------------------------------- $this->modLibrary->rebuildTopic($main_topic_id); $this->registry->class_forums->allForums[$this->forum['id']]['_update_deletion'] = 1; $this->modLibrary->forumRecount($this->forum['id']); $this->cache->rebuildCache('stats', 'global'); /* Tags */ $this->registry->tags->moveTagsByMetaId($tids, $main_topic_id); /* Run Sync */ foreach ($merge_ids as $mid) { $this->modLibrary->runModSync('topicMerge', $mid, $main_topic_id); } /* Log */ $this->_addModeratorLog(sprintf($this->lang->words['multi_topic_merge_mod_log'], count($topics))); }
/** * Unhide a comment * * @param int Parent ID * @param int|array Comment IDs * @param int|array Member Data * @return bool|string TRUE on sucess, error string on error */ public function unhide($parentId, $commentIds, $memberData) { /* Init */ if (is_numeric($memberData)) { $memberData = IPSMember::load($memberData, 'all'); } /* Check */ if (!is_array($commentIds)) { $commentIds = array($commentIds); } if (!$memberData['member_id'] or !$parentId) { return 'MISSING_DATA'; } /* Permission Check */ foreach ($commentIds as $k) { $permCheck = $this->can('unhide', array('comment_id' => $k, 'comment_parent_id' => $parentId)); if ($permCheck !== TRUE) { return $permCheck; } } /* Do it */ $_remap = $this->remapKeys(); $array = array('comment_approved' => 1); $update = $this->preVisibility(1, $commentIds, $parentId, $array); $save = $this->remapToLocal($update); $this->DB->update($this->table(), $save, $this->DB->buildWherePermission($commentIds, $_remap['comment_id'], FALSE)); $this->postVisibility(1, $commentIds, $parentId); /* Log */ IPSDeleteLog::removeEntries($commentIds, $this->whoAmI()); return true; }