/** * Run a refreshLinks job * @return boolean success */ function run() { global $wgUser, $wgTitle, $wrIsTreeDeletion; $status = FTE_SUCCESS; $user = $this->params['user']; $wgUser = User::newFromName($user); $treeId = $this->params['tree_id']; if ($treeId == 9662) { return false; } $delPages = $this->params['delete_pages'] == 1; $wgTitle = $this->title; // FakeTitle (the default) generates errors when accessed, and sometimes I log wgTitle, so set it to something else $dbw =& wfGetDB(DB_MASTER); $dbw->begin(); $dbw->ignoreErrors(true); if ($delPages) { // Delete the page if it is in this tree // and is in one of the 4 deletable namespaces // and nobody else is watching the page // and it is not in another of the users trees // Keep this query in sync with SpecialTreeDeletionImpact.php $sql = 'SELECT fp_namespace, fp_title FROM familytree_page AS fp1' . ' WHERE fp_tree_id=' . $dbw->addQuotes($treeId) . ' and fp_namespace in (' . NS_IMAGE . ',' . NS_PERSON . ',' . NS_FAMILY . ',' . NS_MYSOURCE . ')' . ' and not exists (SELECT 1 FROM watchlist WHERE wl_namespace = fp_namespace and wl_title = fp_title and wl_user <> fp_user_id)' . ' and not exists (SELECT 1 FROM familytree_page AS fp2 WHERE fp2.fp_namespace = fp1.fp_namespace and fp2.fp_title = fp1.fp_title and fp2.fp_user_id = fp1.fp_user_id and fp2.fp_tree_id <> fp1.fp_tree_id)'; $rows = $dbw->query($sql); $errno = $dbw->lastErrno(); if ($errno > 0) { $status = FTE_DB_ERROR; } else { if ($rows !== false) { $titles = array(); while ($row = $dbw->fetchObject($rows)) { $title = Title::makeTitle($row->fp_namespace, $row->fp_title); $talkTitle = $title->getTalkPage(); if ($title->exists()) { $titles[] = $title; PropagationManager::addBlacklistPage($title); } if ($talkTitle->exists()) { $titles[] = $talkTitle; } } $dbw->freeResult($rows); $wrIsTreeDeletion = true; foreach ($titles as $title) { $status = ftDelPage($title, false); if ($status == FTE_NOT_AUTHORIZED) { $this->error = "While deleting {$treeId} tried to delete a page not authorized to delete: " . $title->getPrefixedText() . "\n"; } if ($status != FTE_SUCCESS) { break; } } } } // remove remaining pages from watchlist if ($status == FTE_SUCCESS) { $sql = 'SELECT fp_namespace, fp_title FROM familytree_page AS fp1' . ' WHERE fp_tree_id=' . $dbw->addQuotes($treeId) . ' and not exists (SELECT 1 FROM familytree_page AS fp2 WHERE fp2.fp_namespace = fp1.fp_namespace and fp2.fp_title = fp1.fp_title and fp2.fp_user_id = fp1.fp_user_id and fp2.fp_tree_id <> fp1.fp_tree_id)'; $rows = $dbw->query($sql); $errno = $dbw->lastErrno(); if ($errno > 0) { $status = FTE_DB_ERROR; } else { if ($rows !== false) { while ($row = $dbw->fetchObject($rows)) { $title = Title::makeTitle($row->fp_namespace, $row->fp_title); $wgUser->removeWatch($title); } $dbw->freeResult($rows); } } } // remove familytree_page's // If we delete pages that are unwatched by others but in someone else's tree, then this code won't delete them from the others' trees // We need to ensure that all pages in trees are watched. if ($status == FTE_SUCCESS) { $dbw->delete('familytree_page', array('fp_tree_id' => $treeId)); $errno = $dbw->lastErrno(); if ($errno > 0) { $status = FTE_DB_ERROR; } } if ($status == FTE_SUCCESS) { // remove familytree_data's $dbw->delete('familytree_data', array('fd_tree_id' => $treeId)); $errno = $dbw->lastErrno(); if ($errno > 0) { $status = FTE_DB_ERROR; } // keep familytree_gedcom in case we want to look at it later } if ($status == FTE_SUCCESS) { $dbw->commit(); return true; } else { $dbw->rollback(); if (!$this->error) { $this->error = "Error deleting tree; status={$status}\n"; } return false; } } }
/** * Remove family tree page * * @param unknown_type $args user, name, ns, title * @return FTE_SUCCESS, FTE_INVALID_ARG, FTE_NOT_LOGGED_IN, FTE_NOT_AUTHORIZED, FTE_NOT_FOUND, FTE_DUP_KEY, FTE_DB_ERROR */ function wfRemoveFamilyTreePage($args) { global $wgAjaxCachePolicy; // set cache policy $wgAjaxCachePolicy->setPolicy(0); $ns = ''; $titleString = ''; $delete = false; $deleteStatus = ''; // validate args $args = AjaxUtil::getArgs($args); $status = ftValidateUpdateFamilyTreePageArgs($args); if ($status == FTE_SUCCESS) { // get tree id $treeId = 0; $status = ftGetTreeId($args['user'], $args['name'], $treeId); $delete = @$args['delete_page'] == 1; } if ($status == FTE_SUCCESS) { // get page $ns = $args['ns']; $titleString = $args['title']; $title = Title::newFromText($titleString, $ns); if (!$title || $title->isTalkPage()) { $status = FTE_INVALID_ARG; } } if ($status == FTE_SUCCESS) { $dbw =& wfGetDB(DB_MASTER); $dbw->ignoreErrors(true); $dbw->begin(); if (!FamilyTreeUtil::removePage($dbw, $treeId, $title)) { $status = FTE_DB_ERROR; } if ($delete && $status == FTE_SUCCESS) { $status = ftDelPage($title); if ($status == FTE_NOT_AUTHORIZED) { $deleteStatus = FTE_NOT_AUTHORIZED; $status = FTE_SUCCESS; } else { if ($status == FTE_SUCCESS) { $deleteStatus = FTE_SUCCESS; } } $deleteStatus = " delete_status=\"{$deleteStatus}\""; } if ($status == FTE_SUCCESS) { $dbw->commit(); } else { $dbw->rollback(); } } // return status $titleString = StructuredData::escapeXml($titleString); return "<remove status=\"{$status}\" ns=\"{$ns}\" title=\"{$titleString}\"{$deleteStatus}></remove>"; }