def unpublish(self, language):
        '''
        Removes this article from the public site
        :returns: True if this article was successfully unpublished
        '''
        # Publish can only be called on draft articles
        if not self.publisher_is_draft:
            raise PublicIsUnmodifiable(
                'The public instance cannot be unpublished. Use draft.')

        # First, make sure we are in the correct state
        title = self.title_set.get(language=language)
        public_title = title.publisher_public
        title.published = False
        title.publisher_state = constants.PUBLISHER_STATE_DIRTY
        title.save()
        if hasattr(self, 'title_cache'):
            self.title_cache[language] = title
        public_title.published = False

        public_title.save()
        public_article = self.publisher_public
        public_placeholders = public_article.get_placeholders()
        for pl in public_placeholders:
            pl.cmsplugin_set.filter(language=language).delete()
        public_article.save()
        # trigger update home
        self.save()

        from cms.signals import post_unpublish
        post_unpublish.send(sender=Article, instance=self, language=language)

        return True
Example #2
0
    def revert(self):
        """Revert the draft version to the same state as the public version
        """
        # Revert can only be called on draft pages
        if not self.publisher_is_draft:
            raise PublicIsUnmodifiable(
                'The public instance cannot be reverted. Use draft.')
        if not self.publisher_public:
            # TODO: Issue an error
            return

        public = self.publisher_public
        public._copy_titles(self)
        if self.parent != (self.publisher_public.parent_id
                           and self.publisher_public.parent.publisher_draft):
            # We don't send the signals here
            self.move_to(public.parent.publisher_draft)
        public._copy_contents(self)
        public._copy_attributes(self)
        self.published = True
        self.publisher_state = self.PUBLISHER_STATE_DEFAULT
        self._publisher_keep_state = True
        self.save()
        # clean moderation log
        self.pagemoderatorstate_set.all().delete()
Example #3
0
    def unpublish(self):
        """
        Removes this page from the public site
        :returns: True if this page was successfully unpublished
        """
        # Publish can only be called on draft pages
        if not self.publisher_is_draft:
            raise PublicIsUnmodifiable(
                'The public instance cannot be unpublished. Use draft.')

        # First, make sure we are in the correct state
        self.published = False
        self.save()
        public_page = self.get_public_object()
        if public_page:
            public_page.published = False
            public_page.save()

            # Go through all children of our public instance
            descendants = public_page.get_descendants()
            for child in descendants:
                child.published = False
                child.save()
                draft = child.publisher_public
                if (draft and draft.published and draft.publisher_state
                        == Page.PUBLISHER_STATE_DEFAULT):
                    draft.publisher_state = Page.PUBLISHER_STATE_PENDING
                    draft._publisher_keep_state = True
                    draft.save()

        return True
Example #4
0
    def unpublish(self, language):
        # Unpublish only be called on non draft articles
        if self.is_draft:
            raise PublicIsUnmodifiable(
                'The draft instance cannot be published. Use public.')

        self.is_published = False
        self.save()
Example #5
0
def revise_page(page, language, user, version_id=None):
    """
    Copy a page [ and all its descendants to a new location ]
    Doesn't checks for add page permissions anymore, this is done in PageAdmin.

    Note for issue #1166: when copying pages there is no need to check for
    conflicting URLs as pages are copied unpublished.
    --> get_queryset_by_path(...).get() will fail
    """
    if not page.publisher_is_draft:
        raise PublicIsUnmodifiable(
            "revise page is not allowed for public pages")

    # if the active version is not dirty -> do not create a revision
    if page.page_versions.filter(active=True, dirty=False,
                                 language=language).count() > 0:
        return None

    # Error if the parent isn't published...
    if PUBLISH_HIDDEN_PAGE and \
            page.publisher_public_id and \
            page.publisher_public.get_publisher_state(language) == PUBLISHER_STATE_PENDING or \
            page.get_publisher_state(language) == PUBLISHER_STATE_PENDING:
        raise Exception('Parent Page is not published')

    # avoid muting input param
    page = Page.objects.get(pk=page.pk)

    # Get Version root page
    site = page.node.site
    version_page_root = get_or_create_version_page_root(site=site, user=user)

    # create a copy of this page
    new_page = copy_page(page,
                         version_id=version_id,
                         parent_page=version_page_root,
                         language=language)

    # Publish the page if required
    if PUBLISH_HIDDEN_PAGE:
        new_page = publish_page(new_page, user, language)

    # invalidate the menu for this site
    new_page.clear_cache(menu=True)

    print('Created new version {ver} for: "{page}"'.format(
        ver=version_id, page=new_page.get_title(language=language)))

    return new_page
Example #6
0
    def publish(self, language):
        """
        :returns: the publicated Article.
        """
        # Publish only be called on draft articles
        if not self.is_draft:
            raise PublicIsUnmodifiable(
                'The public instance cannot be published. Use draft.')

        if not self.pk:
            self.save()

        # be sure we have the newest data including tree information
        self.refresh_from_db()

        if self.public_id:
            # Ensure we have up to date mptt properties
            public_article = self.public
        else:
            public_article = Article(created_by=self.created_by)

        if not self.publishing_date:
            self.publishing_date = timezone.now()

        # we need to set relate this new public copy to its draft page (self)
        public_article.public = self
        public_article.is_draft = False

        public_article.save()

        # store the relationship between draft and public
        self.public = public_article
        self.save()

        self._copy_attributes(public_article, language)

        public_article.is_published = True
        public_article.save()

        # The target page now has a pk, so can be used as a target
        self._copy_contents(public_article, language)

        return public_article
    def publish(self, language):
        # Publish can only be called on draft articles
        if not self.publisher_is_draft:
            raise PublicIsUnmodifiable(
                'The public instance cannot be published. Use draft.')

        if not self.pk:
            self.save()

        if self.publisher_public_id:
            public_article = self.publisher_public
        else:
            public_article = Article(created_by=self.created_by)

        if not self.publication_date:
            self.publication_date = now()

        self._copy_attributes(public_article)

        # we need to set relate this new public copy to its draft article (self)
        public_article.publisher_public = self
        public_article.publisher_is_draft = False
        public_article.save()

        public_article = public_article.reload()

        # The target article now has a pk, so can be used as a target
        self._copy_titles(public_article, language)
        self._copy_contents(public_article, language)
        self._copy_relations(public_article)

        self.publisher_public = public_article
        self._publisher_keep_state = True
        self.save()

        from ..signals import post_publish_article
        post_publish_article.send(sender=Article,
                                  instance=self,
                                  language=language)

        return True
Example #8
0
    def revert_to_live(self, language):
        """Revert the draft version to the same state as the public version
        """
        if not self.publisher_is_draft:
            # Revert can only be called on draft articles
            raise PublicIsUnmodifiable('The public instance cannot be reverted. Use draft.')

        if not self.publisher_public:
            raise PublicVersionNeeded('A public version of this article is needed')

        public = self.publisher_public
        public._copy_titles(self, language)
        public._copy_contents(self, language)
        public._copy_attributes(self)

        self.title_set.filter(language=language).update(
            publisher_state=constants.PUBLISHER_STATE_DEFAULT,
            published=True,
        )

        self._publisher_keep_state = True
        self.save()
Example #9
0
    def publish(self):
        """Overrides Publisher method, because there may be some descendants, which
        are waiting for parent to publish, so publish them if possible.

        :returns: True if page was successfully published.
        """
        # Publish can only be called on draft pages
        if not self.publisher_is_draft:
            raise PublicIsUnmodifiable(
                'The public instance cannot be published. Use draft.')

        # publish, but only if all parents are published!!
        published = None

        if not self.pk:
            self.save()
        if not self.parent_id:
            self.clear_home_pk_cache()
        if self._publisher_can_publish():
            if self.publisher_public_id:
                # Ensure we have up to date mptt properties
                public_page = Page.objects.get(pk=self.publisher_public_id)
            else:
                public_page = Page(created_by=self.created_by)

            self._copy_attributes(public_page)
            # we need to set relate this new public copy to its draft page (self)
            public_page.publisher_public = self
            public_page.publisher_is_draft = False

            # Ensure that the page is in the right position and save it
            public_page = self._publisher_save_public(public_page)
            public_page.published = (public_page.parent_id is None
                                     or public_page.parent.published)
            public_page.save()

            # The target page now has a pk, so can be used as a target
            self._copy_titles(public_page)
            self._copy_contents(public_page)

            # invalidate the menu for this site
            menu_pool.clear(site_id=self.site_id)

            # taken from Publisher - copy_page needs to call self._publisher_save_public(copy) for mptt insertion
            # insert_at() was maybe calling _create_tree_space() method, in this
            # case may tree_id change, so we must update tree_id from db first
            # before save
            if getattr(self, 'tree_id', None):
                me = self._default_manager.get(pk=self.pk)
                self.tree_id = me.tree_id

            self.publisher_public = public_page
            published = True
        else:
            # Nothing left to do
            pass

        if self.publisher_public and self.publisher_public.published:
            self.publisher_state = Page.PUBLISHER_STATE_DEFAULT
        else:
            self.publisher_state = Page.PUBLISHER_STATE_PENDING

        self.published = True
        self._publisher_keep_state = True
        self.save()
        # If we are publishing, this page might have become a "home" which
        # would change the path
        if self.is_home():
            for title in self.title_set.all():
                if title.path != '':
                    title.save()

        # clean moderation log
        self.pagemoderatorstate_set.all().delete()

        if not published:
            # was not published, escape
            return

        # Check if there are some children which are waiting for parents to
        # become published.
        publish_set = self.get_descendants().filter(
            published=True).select_related('publisher_public')
        for page in publish_set:
            if page.publisher_public:
                if page.publisher_public.parent.published:
                    if not page.publisher_public.published:
                        page.publisher_public.published = True
                        page.publisher_public.save()
                    if page.publisher_state == Page.PUBLISHER_STATE_PENDING:
                        page.publisher_state = Page.PUBLISHER_STATE_DEFAULT
                        page._publisher_keep_state = True
                        page.save()
            elif page.publisher_state == Page.PUBLISHER_STATE_PENDING:
                page.publish()

        # fire signal after publishing is done
        import cms.signals as cms_signals

        cms_signals.post_publish.send(sender=Page, instance=self)

        return published
Example #10
0
def revise_page(page, language):
    """
    Copy a page [ and all its descendants to a new location ]
    Doesn't checks for add page permissions anymore, this is done in PageAdmin.

    Note for issue #1166: when copying pages there is no need to check for
    conflicting URLs as pages are copied unpublished.
    --> get_queryset_by_path(...).get() will fail
    """
    if not page.publisher_is_draft:
        raise PublicIsUnmodifiable(
            "revise page is not allowed for public pages")

    # if the active version is not dirty -> do not create a revision
    if page.page_versions.filter(active=True, dirty=False,
                                 language=language).count() > 0:
        return None

    # avoid muting input param
    page = Page.objects.get(pk=page.pk)

    site = page.site
    version_page_root = get_version_page_root(site=site)

    origin_id = page.pk  # still needed to retrieve titles, placeholders

    # create a copy of this page by setting pk = None (=new instance)
    new_page = _copy_model(page, parent=version_page_root)

    # copy titles of this page
    for title in Title.objects.filter(page=origin_id,
                                      language=language).iterator():
        _copy_model(title, page=new_page)

    print(new_page.title_set.all())

    # copy the placeholders (and plugins on those placeholders!)
    for ph in Placeholder.objects.filter(page=origin_id).iterator():
        plugins = ph.get_plugins_list(language=language)
        try:
            # why might the placeholder already exist?
            ph = new_page.placeholders.get(slot=ph.slot)
        except Placeholder.DoesNotExist:
            ph = _copy_model(ph)
            page.placeholders.add(ph)
        if plugins:
            copy_plugins_to(plugins, ph, to_language=language)

    extension_pool.copy_extensions(Page.objects.get(pk=origin_id),
                                   new_page,
                                   languages=[language])

    new_page = new_page.move(version_page_root, pos="last-child")

    # Copy the permissions from the old page and its parents to the new page

    # MAP the parent permission to new child permissions
    mapping = {
        ACCESS_DESCENDANTS: ACCESS_PAGE_AND_DESCENDANTS,
        ACCESS_CHILDREN: ACCESS_PAGE
    }
    # for_page sadly doesn't work as expected
    if get_cms_setting('PERMISSION'):
        origin_page = Page.objects.get(pk=origin_id)
        # store the new permissions
        new_permissions = []
        # Copy page's permissions
        for perm in origin_page.pagepermission_set.all():
            new_permissions.append(_copy_model(perm, page=new_page))
        # the permission of all relevant parents
        perms = inherited_permissions(origin_page)
        for perm in perms:
            latest = _copy_model(perm, page=new_page)
            if latest.grant_on in mapping.keys():
                new_permissions.append(latest)
                # apply the mapping (see some lines above)
                latest.grant_on = mapping[latest.grant_on]
                latest.save()

    # invalidate the menu for this site
    menu_pool.clear(site_id=site.pk)
    return new_page