Commit 82806fa6 by Bridger Maxwell

An article is now considered deleted if a parent is instead of explicitly…

An article is now considered deleted if a parent is instead of explicitly needing to mark all children as deleted.
parent 02275fb4
...@@ -101,13 +101,16 @@ def get_article(func=None, can_read=True, can_write=False, deleted_contents=Fals ...@@ -101,13 +101,16 @@ def get_article(func=None, can_read=True, can_write=False, deleted_contents=Fals
else: else:
c = RequestContext(request, {'urlpath' : urlpath}) c = RequestContext(request, {'urlpath' : urlpath})
return HttpResponseForbidden(render_to_string("wiki/permission_denied.html", context_instance=c)) return HttpResponseForbidden(render_to_string("wiki/permission_denied.html", context_instance=c))
# If the article has been deleted, show a special page.
if not deleted_contents and article.current_revision and article.current_revision.deleted: if not deleted_contents:
if urlpath: if urlpath:
return redirect('wiki:deleted', path=urlpath.path) if urlpath.is_deleted(): # This also checks all ancestors
return redirect('wiki:deleted', path=urlpath.path)
else: else:
return redirect('wiki:deleted', article_id=article.id) if article.current_revision and article.current_revision.deleted:
return redirect('wiki:deleted', article_id=article.id)
kwargs['urlpath'] = urlpath kwargs['urlpath'] = urlpath
......
...@@ -72,6 +72,18 @@ class URLPath(MPTTModel): ...@@ -72,6 +72,18 @@ class URLPath(MPTTModel):
return "/".join(slugs) + "/" return "/".join(slugs) + "/"
def is_deleted(self):
"""
Returns True if this article or any of its ancestors have been deleted
"""
return self.first_deleted_ancestor() is not None
def first_deleted_ancestor(self):
for ancestor in self.cached_ancestors + [self]:
if ancestor.article.current_revision.deleted == True:
return ancestor
return None
@classmethod @classmethod
def root(cls): def root(cls):
site = Site.objects.get_current() site = Site.objects.get_current()
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
<div class="span6"> <div class="span6">
<div class="well"> <div class="well">
<h2>{% trans "Restore" %}</h2> <h2>{% trans "Restore" %}</h2>
<p>{% trans "You may restore this article and its children by clicking restore. Note that this restores ALL children." %}</p> <p>{% trans "You may restore this article and its children by clicking restore." %}</p>
<p> <p>
<a href="?restore=1" class="btn"> <a href="?restore=1" class="btn">
<span class="icon-repeat"></span> <span class="icon-repeat"></span>
......
...@@ -130,8 +130,10 @@ class Delete(FormView, ArticleMixin): ...@@ -130,8 +130,10 @@ class Delete(FormView, ArticleMixin):
if urlpath and urlpath.parent: if urlpath and urlpath.parent:
self.next = reverse('wiki:get', kwargs={'path': urlpath.parent.path}) self.next = reverse('wiki:get', kwargs={'path': urlpath.parent.path})
elif urlpath: elif urlpath:
# We are a urlpath with no parent. This is the root
self.cannot_delete_root = True self.cannot_delete_root = True
else: else:
# We have no urlpath. Get it if a urlpath exists
for art_obj in article.articleforobject_set.filter(is_mptt=True): for art_obj in article.articleforobject_set.filter(is_mptt=True):
if art_obj.content_object.parent: if art_obj.content_object.parent:
self.next = reverse('wiki:get', kwargs={'article_id': art_obj.content_object.parent.article.id}) self.next = reverse('wiki:get', kwargs={'article_id': art_obj.content_object.parent.article.id})
...@@ -156,38 +158,30 @@ class Delete(FormView, ArticleMixin): ...@@ -156,38 +158,30 @@ class Delete(FormView, ArticleMixin):
return kwargs return kwargs
@disable_notify @disable_notify
def delete_children(self, purge=False, restore=False): def delete_children(self, purge=False):
assert not (restore and purge), "You cannot purge a restore"
if purge: if purge:
for child in self.article.get_children(articles__article__current_revision__deleted=False): for child in self.article.get_children(articles__article__current_revision__deleted=False):
child.delete() child.delete()
else: # If it is not a purge there is no need to delete the children. Having a deleted parent is enough
for child in self.article.get_children(articles__article__current_revision__deleted=restore):
revision = models.ArticleRevision()
revision.inherit_predecessor(child.article)
revision.set_from_request(self.request)
if restore:
revision.automatic_log = _(u'Restoring children of "%s"') % self.article.current_revision.title
else:
revision.automatic_log = _(u'Deleting children of "%s"') % self.article.current_revision.title
revision.deleted = not restore
child.article.add_revision(revision)
def form_valid(self, form): def form_valid(self, form):
cd = form.cleaned_data cd = form.cleaned_data
purge = cd['purge']
#If we are purging, only moderators can delete articles with children
cannot_delete_children = False cannot_delete_children = False
if self.children_slice and not self.request.user.has_perm('wiki.moderator'): if purge and self.children_slice and not self.request.user.has_perm('wiki.moderator'):
cannot_delete_children = True cannot_delete_children = True
if self.cannot_delete_root or cannot_delete_children: if self.cannot_delete_root or cannot_delete_children:
messages.error(self.request, _(u'This article cannot be deleted because it has children or is a root article.')) messages.error(self.request, _(u'This article cannot be deleted because it has children or is a root article.'))
return redirect('wiki:get', article_id=self.article.id) return redirect('wiki:get', article_id=self.article.id)
# First, remove children if self.request.user.has_perm('wiki.moderator') and purge:
self.delete_children(purge=cd['purge']) # First, remove children
self.delete_children(purge=purge)
if self.request.user.has_perm('wiki.moderator') and cd['purge']:
self.article.delete() self.article.delete()
messages.success(self.request, _(u'This article together with all its contents are now completely gone! Thanks!')) messages.success(self.request, _(u'This article together with all its contents are now completely gone! Thanks!'))
else: else:
...@@ -326,16 +320,23 @@ class Deleted(Delete): ...@@ -326,16 +320,23 @@ class Deleted(Delete):
self.urlpath = kwargs.get('urlpath', None) self.urlpath = kwargs.get('urlpath', None)
self.article = article self.article = article
if not article.current_revision.deleted: if self.urlpath:
if self.urlpath: deleted_ancestor = self.urlpath.first_deleted_ancestor()
if deleted_ancestor is None:
# No one is deleted!
return redirect('wiki:get', path=self.urlpath.path) return redirect('wiki:get', path=self.urlpath.path)
else: elif deleted_ancestor != self.urlpath:
# An ancestor was deleted, so redirect to that deleted page
return redirect('wiki:deleted', path=deleted_ancestor.path)
else:
if not article.current_revision.deleted:
return redirect('wiki:get', article_id=article.id) return redirect('wiki:get', article_id=article.id)
# Restore # Restore
if (request.GET.get('restore', False) and if (request.GET.get('restore', False) and
(not article.current_revision.locked or request.user.has_perm('wiki.moderator'))): (not article.current_revision.locked or request.user.has_perm('wiki.moderator'))):
self.delete_children(restore=True)
revision = models.ArticleRevision() revision = models.ArticleRevision()
revision.inherit_predecessor(self.article) revision.inherit_predecessor(self.article)
revision.set_from_request(request) revision.set_from_request(request)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment