Example #1
0
    def get_context_data(self, parent_context):
        context = super().get_context_data(parent_context)
        user_perms = UserPagePermissionsProxy(self.request.user)
        page = self.object

        if page.id:
            context.update({
                "history_url":
                reverse("wagtailadmin_pages:history", args=(page.id, )),
                "lock_url":
                reverse("wagtailadmin_pages:lock", args=(page.id, )),
                "unlock_url":
                reverse("wagtailadmin_pages:unlock", args=(page.id, )),
                "user_can_lock":
                user_perms.for_page(page).can_lock(),
                "user_can_unlock":
                user_perms.for_page(page).can_unlock(),
                "locale":
                None,
                "translations": [],
            })
        else:
            context.update({
                "locale": None,
                "translations": [],
            })

        if getattr(settings, "WAGTAIL_I18N_ENABLED", False):
            url_name = "wagtailadmin_pages:edit"
            if self.in_explorer:
                url_name = "wagtailadmin_explore"

            context.update({
                "locale":
                page.locale,
                "translations":
                [{
                    "locale": translation.locale,
                    "url": reverse(url_name, args=[translation.id]),
                } for translation in page.get_translations().only(
                    "id", "locale", "depth").select_related("locale")
                 if user_perms.for_page(translation).can_edit()],
                # The sum of translated pages plus 1 to account for the current page
                "translations_total":
                page.get_translations().count() + 1,
            })

        context.update({
            "model_name": self.model.get_verbose_name(),
            "model_description": self.model.get_page_description(),
            "status_templates": self.get_status_templates(context),
        })

        return context
Example #2
0
    def __init__(self, request, **kwargs):
        self.request = request
        self.context = kwargs
        self.context["request"] = request
        page = self.context.get("page")
        user_page_permissions = UserPagePermissionsProxy(self.request.user)
        self.context["user_page_permissions"] = user_page_permissions
        if page:
            self.context[
                "user_page_permissions_tester"] = user_page_permissions.for_page(
                    page)

        self.menu_items = []

        if page:
            task = page.current_workflow_task
            current_workflow_state = page.current_workflow_state
            is_final_task = (current_workflow_state
                             and current_workflow_state.is_at_final_task)
            if task:
                actions = task.get_actions(page, request.user)
                workflow_menu_items = []
                for name, label, launch_modal in actions:
                    icon_name = "edit"
                    if name == "approve":
                        if is_final_task and not getattr(
                                settings,
                                "WAGTAIL_WORKFLOW_REQUIRE_REAPPROVAL_ON_EDIT",
                                False,
                        ):
                            label = _("%(label)s and Publish") % {
                                "label": label
                            }
                        icon_name = "success"

                    item = WorkflowMenuItem(name,
                                            label,
                                            launch_modal,
                                            icon_name=icon_name)

                    if item.is_shown(self.context):
                        workflow_menu_items.append(item)
                self.menu_items.extend(workflow_menu_items)

        for menu_item in _get_base_page_action_menu_items():
            if menu_item.is_shown(self.context):
                self.menu_items.append(menu_item)

        self.menu_items.sort(key=lambda item: item.order)

        for hook in hooks.get_hooks("construct_page_action_menu"):
            hook(self.menu_items, self.request, self.context)

        try:
            self.default_item = self.menu_items.pop(0)
        except IndexError:
            self.default_item = None
Example #3
0
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context.update({
            "page":
            self.page,
            "page_for_status":
            self.page_for_status,
            "content_type":
            self.page_content_type,
            "edit_handler":
            self.edit_handler,
            "errors_debug":
            self.errors_debug,
            "action_menu":
            PageActionMenu(self.request, view="edit", page=self.page),
            "preview_modes":
            self.page.preview_modes,
            "form":
            self.form,
            "next":
            self.next_url,
            "has_unsaved_changes":
            self.has_unsaved_changes,
            "page_locked":
            self.page_perms.page_locked(),
            "workflow_state":
            self.workflow_state
            if self.workflow_state and self.workflow_state.is_active else None,
            "current_task_state":
            self.page.current_workflow_task_state,
            "publishing_will_cancel_workflow":
            self.workflow_tasks
            and getattr(settings, "WAGTAIL_WORKFLOW_CANCEL_ON_PUBLISH", True),
            "locale":
            None,
            "translations": [],
        })

        if getattr(settings, "WAGTAIL_I18N_ENABLED", False):
            user_perms = UserPagePermissionsProxy(self.request.user)

            context.update({
                "locale":
                self.page.locale,
                "translations":
                [{
                    "locale":
                    translation.locale,
                    "url":
                    reverse("wagtailadmin_pages:edit", args=[translation.id]),
                } for translation in self.page.get_translations().only(
                    "id", "locale", "depth").select_related("locale")
                 if user_perms.for_page(translation).can_edit()],
            })

        return context
Example #4
0
    def execute(self, skip_permission_checks=False):
        super().execute(skip_permission_checks)

        if self.include_descendants:
            from wagtail.models import UserPagePermissionsProxy

            user_perms = UserPagePermissionsProxy(self.user)
            for live_descendant_page in (self.object.get_descendants().live(
            ).defer_streamfields().specific().iterator()):
                action = UnpublishPageAction(live_descendant_page)
                if user_perms.for_page(live_descendant_page).can_unpublish():
                    action.execute(skip_permission_checks=True)
Example #5
0
    def get_context_data(self, parent_context):
        context = super().get_context_data(parent_context)
        user_perms = UserPagePermissionsProxy(self.request.user)

        if self.page.id:
            context.update({
                "lock_url":
                reverse("wagtailadmin_pages:lock", args=(self.page.id, )),
                "unlock_url":
                reverse("wagtailadmin_pages:unlock", args=(self.page.id, )),
                "user_can_lock":
                user_perms.for_page(self.page).can_lock(),
                "user_can_unlock":
                user_perms.for_page(self.page).can_unlock(),
                "locale":
                None,
                "translations": [],
            })
        else:
            context.update({
                "locale": None,
                "translations": [],
            })

        if getattr(settings, "WAGTAIL_I18N_ENABLED", False):
            context.update({
                "locale":
                self.page.locale,
                "translations":
                [{
                    "locale":
                    translation.locale,
                    "url":
                    reverse("wagtailadmin_pages:edit", args=[translation.id]),
                } for translation in self.page.get_translations().only(
                    "id", "locale", "depth").select_related("locale")
                 if user_perms.for_page(translation).can_edit()],
            })

        return context
Example #6
0
def unpublish(request, page_id):
    page = get_object_or_404(Page, id=page_id).specific

    user_perms = UserPagePermissionsProxy(request.user)
    if not user_perms.for_page(page).can_unpublish():
        raise PermissionDenied

    next_url = get_valid_next_url_from_request(request)

    if request.method == "POST":
        include_descendants = request.POST.get("include_descendants", False)

        for fn in hooks.get_hooks("before_unpublish_page"):
            result = fn(request, page)
            if hasattr(result, "status_code"):
                return result

        action = UnpublishPageAction(page,
                                     user=request.user,
                                     include_descendants=include_descendants)
        action.execute(skip_permission_checks=True)

        for fn in hooks.get_hooks("after_unpublish_page"):
            result = fn(request, page)
            if hasattr(result, "status_code"):
                return result

        messages.success(
            request,
            _("Page '{0}' unpublished.").format(
                page.get_admin_display_title()),
            buttons=[
                messages.button(
                    reverse("wagtailadmin_pages:edit", args=(page.id, )),
                    _("Edit"))
            ],
        )

        if next_url:
            return redirect(next_url)
        return redirect("wagtailadmin_explore", page.get_parent().id)

    return TemplateResponse(
        request,
        "wagtailadmin/pages/confirm_unpublish.html",
        {
            "page": page,
            "next": next_url,
            "live_descendant_count": page.get_descendants().live().count(),
        },
    )
Example #7
0
def revisions_unschedule(request, page_id, revision_id):
    page = get_object_or_404(Page, id=page_id).specific

    user_perms = UserPagePermissionsProxy(request.user)
    if not user_perms.for_page(page).can_unschedule():
        raise PermissionDenied

    revision = get_object_or_404(page.revisions, id=revision_id)

    next_url = get_valid_next_url_from_request(request)

    subtitle = _('revision {0} of "{1}"').format(
        revision.id, page.get_admin_display_title())

    if request.method == "POST":
        revision.approved_go_live_at = None
        revision.save(user=request.user, update_fields=["approved_go_live_at"])

        messages.success(
            request,
            _('Version {0} of "{1}" unscheduled.').format(
                revision.id, page.get_admin_display_title()),
            buttons=[
                messages.button(
                    reverse("wagtailadmin_pages:edit", args=(page.id, )),
                    _("Edit"))
            ],
        )

        if next_url:
            return redirect(next_url)
        return redirect("wagtailadmin_pages:history", page.id)

    return TemplateResponse(
        request,
        "wagtailadmin/pages/revisions/confirm_unschedule.html",
        {
            "page": page,
            "revision": revision,
            "next": next_url,
            "subtitle": subtitle
        },
    )
Example #8
0
    def execute(self, skip_permission_checks=False):
        self.check(skip_permission_checks=skip_permission_checks)

        self._unpublish_page(
            self.page,
            set_expired=self.set_expired,
            commit=self.commit,
            user=self.user,
            log_action=self.log_action,
        )

        if self.include_descendants:
            from wagtail.models import UserPagePermissionsProxy

            user_perms = UserPagePermissionsProxy(self.user)
            for live_descendant_page in (self.page.get_descendants().live().
                                         defer_streamfields().specific()):
                action = UnpublishPageAction(live_descendant_page)
                if user_perms.for_page(live_descendant_page).can_unpublish():
                    action.execute(skip_permission_checks=True)
Example #9
0
def workflow_history(request, page_id):
    page = get_object_or_404(Page, id=page_id)

    user_perms = UserPagePermissionsProxy(request.user)
    if not user_perms.for_page(page).can_edit():
        raise PermissionDenied

    workflow_states = WorkflowState.objects.filter(
        page=page).order_by("-created_at")

    paginator = Paginator(workflow_states, per_page=20)
    workflow_states = paginator.get_page(request.GET.get("p"))

    return TemplateResponse(
        request,
        "wagtailadmin/pages/workflow_history/index.html",
        {
            "page": page,
            "workflow_states": workflow_states,
        },
    )
Example #10
0
def workflow_history_detail(request, page_id, workflow_state_id):
    page = get_object_or_404(Page, id=page_id)

    user_perms = UserPagePermissionsProxy(request.user)
    if not user_perms.for_page(page).can_edit():
        raise PermissionDenied

    workflow_state = get_object_or_404(WorkflowState,
                                       page=page,
                                       id=workflow_state_id)

    # Get QuerySet of all revisions that have existed during this workflow state
    # It's possible that the page is edited while the workflow is running, so some
    # tasks may be repeated. All tasks that have been completed no matter what
    # revision needs to be displayed on this page.
    page_revisions = PageRevision.objects.filter(
        page=page,
        id__in=TaskState.objects.filter(
            workflow_state=workflow_state).values_list("page_revision_id",
                                                       flat=True),
    ).order_by("-created_at")

    # Now get QuerySet of tasks completed for each revision
    task_states_by_revision_task = [(
        page_revision,
        {
            task_state.task: task_state
            for task_state in TaskState.objects.filter(
                workflow_state=workflow_state, page_revision=page_revision)
        },
    ) for page_revision in page_revisions]

    # Make sure task states are always in a consistent order
    # In some cases, they can be completed in a different order to what they are defined
    tasks = workflow_state.workflow.tasks.all()
    task_states_by_revision = [
        (page_revision,
         [task_states_by_task.get(task, None) for task in tasks])
        for page_revision, task_states_by_task in task_states_by_revision_task
    ]

    # Generate timeline
    completed_task_states = (TaskState.objects.filter(
        workflow_state=workflow_state).exclude(
            finished_at__isnull=True).exclude(
                status=TaskState.STATUS_CANCELLED))

    timeline = [{
        "time": workflow_state.created_at,
        "action": "workflow_started",
        "workflow_state": workflow_state,
    }]

    if workflow_state.status not in (
            WorkflowState.STATUS_IN_PROGRESS,
            WorkflowState.STATUS_NEEDS_CHANGES,
    ):
        last_task = completed_task_states.order_by("finished_at").last()
        if last_task:
            timeline.append({
                "time":
                last_task.finished_at + timedelta(milliseconds=1),
                "action":
                "workflow_completed",
                "workflow_state":
                workflow_state,
            })

    for page_revision in page_revisions:
        timeline.append({
            "time": page_revision.created_at,
            "action": "page_edited",
            "revision": page_revision,
        })

    for task_state in completed_task_states:
        timeline.append({
            "time": task_state.finished_at,
            "action": "task_completed",
            "task_state": task_state,
        })

    timeline.sort(key=lambda t: t["time"])
    timeline.reverse()

    return TemplateResponse(
        request,
        "wagtailadmin/pages/workflow_history/detail.html",
        {
            "page": page,
            "workflow_state": workflow_state,
            "tasks": tasks,
            "task_states_by_revision": task_states_by_revision,
            "timeline": timeline,
        },
    )
Example #11
0
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        bound_panel = self.edit_handler.get_bound_panel(request=self.request,
                                                        instance=self.page,
                                                        form=self.form)
        action_menu = PageActionMenu(self.request,
                                     view="create",
                                     parent_page=self.parent_page)

        context.update({
            "content_type":
            self.page_content_type,
            "page_class":
            self.page_class,
            "parent_page":
            self.parent_page,
            "edit_handler":
            bound_panel,
            "action_menu":
            action_menu,
            "preview_modes":
            self.page.preview_modes,
            "form":
            self.form,
            "next":
            self.next_url,
            "has_unsaved_changes":
            self.has_unsaved_changes,
            "locale":
            None,
            "translations": [],
            "media":
            bound_panel.media + self.form.media + action_menu.media,
        })

        if getattr(settings, "WAGTAIL_I18N_ENABLED", False):
            # Pages can be created in any language at the root level
            if self.parent_page.is_root():
                translations = [{
                    "locale":
                    locale,
                    "url":
                    reverse(
                        "wagtailadmin_pages:add",
                        args=[
                            self.page_content_type.app_label,
                            self.page_content_type.model,
                            self.parent_page.id,
                        ],
                    ) + "?" + urlencode({"locale": locale.language_code}),
                } for locale in Locale.objects.all()]

            else:
                user_perms = UserPagePermissionsProxy(self.request.user)
                translations = [
                    {
                        "locale":
                        translation.locale,
                        "url":
                        reverse(
                            "wagtailadmin_pages:add",
                            args=[
                                self.page_content_type.app_label,
                                self.page_content_type.model,
                                translation.id,
                            ],
                        ),
                    } for translation in self.parent_page.get_translations(
                    ).only("id", "locale").select_related("locale")
                    if user_perms.for_page(translation).can_add_subpage()
                    and self.page_class in
                    translation.specific_class.creatable_subpage_models()
                    and self.page_class.can_create_at(translation)
                ]

            context.update({
                "locale": self.locale,
                "translations": translations,
            })

        return context
Example #12
0
def unpublish(request, page_id):
    page = get_object_or_404(Page, id=page_id).specific

    user_perms = UserPagePermissionsProxy(request.user)
    if not user_perms.for_page(page).can_unpublish():
        raise PermissionDenied

    next_url = get_valid_next_url_from_request(request)

    pages_to_unpublish = {page}

    if getattr(settings, "WAGTAIL_I18N_ENABLED", False):
        for fn in hooks.get_hooks(
                "construct_translated_pages_to_cascade_actions"):
            fn_pages = fn([page], "unpublish")
            if fn_pages and isinstance(fn_pages, dict):
                for additional_pages in fn_pages.values():
                    pages_to_unpublish.update(additional_pages)

    pages_to_unpublish = list(pages_to_unpublish)

    if request.method == "POST":
        include_descendants = request.POST.get("include_descendants", False)

        for fn in hooks.get_hooks("before_unpublish_page"):
            result = fn(request, page)
            if hasattr(result, "status_code"):
                return result

        for page in pages_to_unpublish:
            action = UnpublishPageAction(
                page,
                user=request.user,
                include_descendants=include_descendants)
            action.execute(skip_permission_checks=True)

        for fn in hooks.get_hooks("after_unpublish_page"):
            result = fn(request, page)
            if hasattr(result, "status_code"):
                return result

        messages.success(
            request,
            _("Page '{0}' unpublished.").format(
                page.get_admin_display_title()),
            buttons=[
                messages.button(
                    reverse("wagtailadmin_pages:edit", args=(page.id, )),
                    _("Edit"))
            ],
        )

        if next_url:
            return redirect(next_url)
        return redirect("wagtailadmin_explore", page.get_parent().id)

    return TemplateResponse(
        request,
        "wagtailadmin/pages/confirm_unpublish.html",
        {
            "page":
            page,
            "next":
            next_url,
            "live_descendant_count":
            page.get_descendants().live().count(),
            "translation_count":
            len(pages_to_unpublish[1:]),
            "translation_descendant_count":
            sum([
                p.get_descendants().filter(
                    alias_of__isnull=True).live().count()
                for p in pages_to_unpublish[1:]
            ]),
        },
    )
Example #13
0
File: edit.py Project: tnir/wagtail
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        bound_panel = self.edit_handler.get_bound_panel(instance=self.page,
                                                        request=self.request,
                                                        form=self.form)
        action_menu = PageActionMenu(
            self.request,
            view="edit",
            page=self.page,
            lock=self.lock,
            locked_for_user=self.locked_for_user,
        )
        side_panels = PageSidePanels(
            self.request,
            self.page_for_status,
            preview_enabled=True,
            comments_enabled=self.form.show_comments_toggle,
        )

        context.update({
            "page":
            self.page,
            "page_for_status":
            self.page_for_status,
            "content_type":
            self.page_content_type,
            "edit_handler":
            bound_panel,
            "errors_debug":
            self.errors_debug,
            "action_menu":
            action_menu,
            "side_panels":
            side_panels,
            "form":
            self.form,
            "next":
            self.next_url,
            "has_unsaved_changes":
            self.has_unsaved_changes,
            "page_locked":
            self.locked_for_user,
            "workflow_state":
            self.workflow_state
            if self.workflow_state and self.workflow_state.is_active else None,
            "current_task_state":
            self.page.current_workflow_task_state,
            "publishing_will_cancel_workflow":
            self.workflow_tasks
            and getattr(settings, "WAGTAIL_WORKFLOW_CANCEL_ON_PUBLISH", True),
            "locale":
            None,
            "translations": [],
            "media":
            bound_panel.media + self.form.media + action_menu.media +
            side_panels.media,
        })

        if getattr(settings, "WAGTAIL_I18N_ENABLED", False):
            user_perms = UserPagePermissionsProxy(self.request.user)

            context.update({
                "locale":
                self.page.locale,
                "translations":
                [{
                    "locale":
                    translation.locale,
                    "url":
                    reverse("wagtailadmin_pages:edit", args=[translation.id]),
                } for translation in self.page.get_translations().only(
                    "id", "locale", "depth").select_related("locale")
                 if user_perms.for_page(translation).can_edit()],
            })

        return context
Example #14
0
 def dispatch(self, request, *args, **kwargs):
     user_perms = UserPagePermissionsProxy(request.user)
     if not user_perms.for_page(self.object).can_unpublish():
         raise PermissionDenied
     return super().dispatch(request, *args, **kwargs)