def copy_plugins(self, request): if 'history' in request.path or 'recover' in request.path: return HttpResponse(str("error")) if request.method == "POST": copy_from = request.POST['copy_from'] placeholder_id = request.POST['placeholder'] placeholder = get_object_or_404(Placeholder, pk=placeholder_id) page = get_item_from_placeholder_if_exists(placeholder) language = request.POST['language'] or get_language_from_request(request) if not page.has_change_permission(request): return HttpResponseForbidden(_("You do not have permission to change this page")) if not language or not language in [ l[0] for l in settings.CMS_LANGUAGES ]: return HttpResponseBadRequest(_("Language must be set to a supported language!")) if language == copy_from: return HttpResponseBadRequest(_("Language must be different than the copied language!")) plugins = list(placeholder.cmsplugin_set.filter(language=copy_from).order_by('tree_id', '-rght')) copy_plugins_to(plugins, placeholder, language) if page and "reversion" in settings.INSTALLED_APPS: make_revision_with_plugins(page) reversion.revision.user = request.user reversion.revision.comment = _(u"Copied %(language)s plugins to %(placeholder)s") % {'language':dict(settings.LANGUAGES)[language], 'placeholder':placeholder} plugin_list = CMSPlugin.objects.filter(language=language, placeholder=placeholder, parent=None).order_by('position') return render_to_response('admin/cms/page/widgets/plugin_item.html', {'plugin_list':plugin_list}, RequestContext(request)) raise Http404
def remove_plugin(self, request): if request.method == "POST" and not 'history' in request.path: plugin_id = request.POST['plugin_id'] plugin = get_object_or_404(CMSPlugin, pk=plugin_id) placeholder = plugin.placeholder page = get_item_from_placeholder_if_exists(placeholder) if page and not page.has_change_permission(request): raise Http404 if page and settings.CMS_MODERATOR and page.is_under_moderation(): # delete the draft version of the plugin plugin.delete() # set the page to require approval and save page.moderator_state = NewsItem.MODERATOR_NEED_APPROVEMENT page.save() else: plugin.delete_with_public() plugin_name = unicode(plugin_pool.get_plugin(plugin.plugin_type).name) comment = _(u"%(plugin_name)s plugin at position %(position)s in %(placeholder)s was deleted.") % {'plugin_name':plugin_name, 'position':plugin.position, 'placeholder':plugin.placeholder} if page and 'reversion' in settings.INSTALLED_APPS: make_revision_with_plugins(page) reversion.revision.user = request.user reversion.revision.comment = comment return HttpResponse("%s,%s" % (plugin_id, comment)) raise Http404
def move_page(self, request, page_id, extra_context=None): """ Move the page to the requested target, at the given position """ raise Http404() target = request.POST.get('target', None) position = request.POST.get('position', None) if target is None or position is None: return HttpResponseRedirect('../../') try: page = self.model.objects.get(pk=page_id) target = self.model.objects.get(pk=target) except self.model.DoesNotExist: return HttpResponseBadRequest("error") # does he haves permissions to do this...? if not page.has_move_page_permission(request) or \ not target.has_add_permission(request): return HttpResponseForbidden("Denied") # move page page.move_page(target, position) if "reversion" in settings.INSTALLED_APPS: make_revision_with_plugins(page) return render_admin_menu_item(request, page)
def test_recover_with_apphook(self): """ Test that you can recover a page """ from cms.utils.helpers import make_revision_with_plugins from cms.utils.reversion_hacks import create_revision, revision_manager self.assertEqual(Page.objects.count(), 2) with self.login_user_context(self.user): page_data = self.get_new_page_data_dbfields() page_data['apphook'] = 'SampleApp' page_data['apphook_namespace'] = 'SampleApp' with create_revision(): # Need to create page manually to add apphooks page = create_page(**page_data) # Assert page has apphooks self.assertEqual(page.application_urls, 'SampleApp') self.assertEqual(page.application_namespace, 'SampleApp') # Create revision make_revision_with_plugins(page, user=None, message="Initial version") page_pk = page.pk # Delete the page through the admin data = {'post': 'yes'} response = self.client.post(URL_CMS_PAGE_DELETE % page.pk, data) self.assertRedirects(response, URL_CMS_PAGE) # Assert page was truly deleted self.assertEqual(Page.objects.filter(pk=page_pk).count(), 0) versions_qs = revision_manager.get_deleted(Page).order_by("-pk") version = versions_qs[0] recover_url = URL_CMS_PAGE + "recover/%s/" % version.pk # Recover deleted page page_form_data = self.get_pagedata_from_dbfields(page_data) self.client.post(recover_url, page_form_data) # Verify page was recovered correctly self.assertEqual(Page.objects.filter(pk=page_pk).count(), 1) # Get recovered page page = Page.objects.get(pk=page_pk) # Verify apphook and apphook namespace are set on page. self.assertEqual(page.application_urls, 'SampleApp') self.assertEqual(page.application_namespace, 'SampleApp')
def _create_revision(obj, user=None, message=None): from cms.utils.helpers import make_revision_with_plugins from cms.utils.reversion_hacks import create_revision with create_revision(): make_revision_with_plugins( obj=obj, user=user, message=message, )
def change_template(self, request, object_id): page = get_object_or_404(NewsItem, pk=object_id) if page.has_change_permission(request): to_template = request.POST.get("template", None) if to_template in dict(settings.NEWSY_TEMPLATES): page.template = to_template page.save() if "reversion" in settings.INSTALLED_APPS: make_revision_with_plugins(page) return HttpResponse(str("ok")) else: return HttpResponseBadRequest("template not valid") else: return HttpResponseForbidden()
def move_plugin(self, request): if request.method == "POST" and not 'history' in request.path: pos = 0 page = None success = False if 'plugin_id' in request.POST: plugin = CMSPlugin.objects.get(pk=int(request.POST['plugin_id'])) old_placeholder = plugin.placeholder page = get_item_from_placeholder_if_exists(old_placeholder) placeholder_slot = request.POST['placeholder'] placeholders = get_placeholders(page.get_template()) if not placeholder_slot in placeholders: return HttpResponse(str("error")) placeholder = page.placeholders.get(slot=placeholder_slot) plugin.placeholder = placeholder # plugin positions are 0 based, so just using count here should give us 'last_position + 1' position = CMSPlugin.objects.filter(placeholder=placeholder).count() plugin.position = position plugin.save() success = True if 'ids' in request.POST: for plugin_id in request.POST['ids'].split("_"): plugin = CMSPlugin.objects.get(pk=plugin_id) page = get_item_from_placeholder_if_exists(plugin.placeholder) if page and not page.has_change_permission(request): raise Http404 if plugin.position != pos: plugin.position = pos plugin.save() pos += 1 success = True if not success: HttpResponse(str("error")) if page and 'reversion' in settings.INSTALLED_APPS: make_revision_with_plugins(page) reversion.revision.user = request.user reversion.revision.comment = unicode(_(u"Plugins where moved")) return HttpResponse(str("ok")) else: return HttpResponse(str("error"))
def save(self, **kwargs): from cms.api import create_page, add_plugin from cms.utils.permissions import has_page_add_permission # Check to see if this user has permissions to make this page. We've # already checked this when producing a list of wizard entries, but this # is to prevent people from possible form-hacking. if 'sub_page' in self.cleaned_data: sub_page = self.cleaned_data['sub_page'] else: sub_page = False if self.page: if sub_page: parent = self.page position = "last-child" else: parent = self.page.parent position = "right" else: parent = None position = "last-child" # Before we do this, verify this user has perms to do so. if not (self.user.is_superuser or has_page_add_permission(self.user, self.page, position=position, site=self.page.site)): raise NoPermissionsException( _(u"User does not have permission to add page.")) page = create_page( title=self.cleaned_data['title'], slug=self.cleaned_data['slug'], template=get_cms_setting('PAGE_WIZARD_DEFAULT_TEMPLATE'), language=self.language_code, created_by=smart_text(self.user), parent=parent, in_navigation=True, published=False ) page_type = self.cleaned_data.get("page_type") if page_type: copy_target = Page.objects.filter(pk=page_type).first() else: copy_target = None if copy_target: # If the user selected a page type, copy that. if not user_has_view_permission(self.user, copy_target): raise PermissionDenied() # Copy page attributes copy_target._copy_attributes(page, clean=True) page.save() # Copy contents (for each language) for lang in copy_target.get_languages(): copy_target._copy_contents(page, lang) # Copy extensions from cms.extensions import extension_pool extension_pool.copy_extensions(copy_target, page) else: # If the user provided content, then use that instead. content = self.cleaned_data.get('content') plugin_type = get_cms_setting('PAGE_WIZARD_CONTENT_PLUGIN') plugin_body = get_cms_setting('PAGE_WIZARD_CONTENT_PLUGIN_BODY') slot = get_cms_setting('PAGE_WIZARD_CONTENT_PLACEHOLDER') if plugin_type in plugin_pool.plugins and plugin_body: if content and permissions.has_plugin_permission( self.user, plugin_type, "add"): placeholder = self.get_placeholder(page, slot=slot) if placeholder: opts = { 'placeholder': placeholder, 'plugin_type': plugin_type, 'language': self.language_code, plugin_body: content, } add_plugin(**opts) # is it home? publish it right away if not self.page and page.is_home: page.publish(self.language_code) if is_installed('reversion'): from cms.utils.helpers import make_revision_with_plugins from cms.constants import REVISION_INITIAL_COMMENT from cms.utils.reversion_hacks import create_revision with create_revision(): make_revision_with_plugins( obj=page, user=self.user, message=ugettext(REVISION_INITIAL_COMMENT), ) return page
def edit_plugin(self, request, plugin_id): plugin_id = int(plugin_id) if not 'history' in request.path and not 'recover' in request.path: cms_plugin = get_object_or_404(CMSPlugin, pk=plugin_id) page = get_item_from_placeholder_if_exists(cms_plugin.placeholder) instance, plugin_admin = cms_plugin.get_plugin_instance(self.admin_site) if page and not page.has_change_permission(request): raise Http404 else: # history view with reversion from reversion.models import Version pre_edit = request.path.split("/edit-plugin/")[0] version_id = pre_edit.split("/")[-1] Version.objects.get(pk=version_id) version = get_object_or_404(Version, pk=version_id) rev_objs = [] for related_version in version.revision.version_set.all(): try: rev = related_version.object_version except models.FieldDoesNotExist: continue else: rev_objs.append(rev.object) # TODO: check permissions for obj in rev_objs: if obj.__class__ == CMSPlugin and obj.pk == plugin_id: cms_plugin = obj break inst, plugin_admin = cms_plugin.get_plugin_instance(self.admin_site) instance = None if cms_plugin.get_plugin_class().model == CMSPlugin: instance = cms_plugin else: for obj in rev_objs: if hasattr(obj, "cmsplugin_ptr_id") and int(obj.cmsplugin_ptr_id) == int(cms_plugin.pk): instance = obj break if not instance: raise Http404("This plugin is not saved in a revision") plugin_admin.cms_plugin_instance = cms_plugin try: plugin_admin.placeholder = cms_plugin.placeholder # TODO: what for reversion..? should it be inst ...? except Placeholder.DoesNotExist: pass if request.method == "POST": # set the continue flag, otherwise will plugin_admin make redirect to list # view, which actually does'nt exists request.POST['_continue'] = True if 'reversion' in settings.INSTALLED_APPS and ('history' in request.path or 'recover' in request.path): # in case of looking to history just render the plugin content context = RequestContext(request) return render_to_response(plugin_admin.render_template, plugin_admin.render(context, instance, plugin_admin.placeholder)) if not instance: # instance doesn't exist, call add view response = plugin_admin.add_view(request) else: # already saved before, call change view # we actually have the instance here, but since i won't override # change_view method, is better if it will be loaded again, so # just pass id to plugin_admin response = plugin_admin.change_view(request, str(plugin_id)) if request.method == "POST" and plugin_admin.object_successfully_changed: # if reversion is installed, save version of the page plugins if 'reversion' in settings.INSTALLED_APPS and page: make_revision_with_plugins(page) reversion.revision.user = request.user plugin_name = unicode(plugin_pool.get_plugin(cms_plugin.plugin_type).name) reversion.revision.comment = _(u"%(plugin_name)s plugin edited at position %(position)s in %(placeholder)s") % {'plugin_name':plugin_name, 'position':cms_plugin.position, 'placeholder': cms_plugin.placeholder.slot} # read the saved object from plugin_admin - ugly but works saved_object = plugin_admin.saved_object context = { 'CMS_MEDIA_URL': settings.CMS_MEDIA_URL, 'plugin': saved_object, 'is_popup': True, 'name': unicode(saved_object), "type": saved_object.get_plugin_name(), 'plugin_id': plugin_id, 'icon': force_escape(escapejs(saved_object.get_instance_icon_src())), 'alt': force_escape(escapejs(saved_object.get_instance_icon_alt())), } return render_to_response('admin/cms/page/plugin_forms_ok.html', context, RequestContext(request)) return response
def add_plugin(self, request): ''' Could be either a page or a parent - if it's a parent we get the page via parent. ''' if 'history' in request.path or 'recover' in request.path: return HttpResponse(str("error")) if request.method == "POST": plugin_type = request.POST['plugin_type'] placeholder_id = request.POST.get('placeholder', None) parent_id = request.POST.get('parent_id', None) if placeholder_id: placeholder = get_object_or_404(Placeholder, pk=placeholder_id) page = get_item_from_placeholder_if_exists(placeholder) else: placeholder = None page = None parent = None # page add-plugin if page: language = request.POST['language'] or get_language_from_request(request) position = CMSPlugin.objects.filter(language=language, placeholder=placeholder).count() limits = settings.CMS_PLACEHOLDER_CONF.get("%s %s" % (page.get_template(), placeholder.slot), {}).get('limits', None) if not limits: limits = settings.CMS_PLACEHOLDER_CONF.get(placeholder.slot, {}).get('limits', None) if limits: global_limit = limits.get("global") type_limit = limits.get(plugin_type) if global_limit and position >= global_limit: return HttpResponseBadRequest("This placeholder already has the maximum number of plugins") elif type_limit: type_count = CMSPlugin.objects.filter(language=language, placeholder=placeholder, plugin_type=plugin_type).count() if type_count >= type_limit: return HttpResponseBadRequest("This placeholder already has the maximum number allowed %s plugins.'%s'" % plugin_type) # in-plugin add-plugin elif parent_id: parent = get_object_or_404(CMSPlugin, pk=parent_id) placeholder = parent.placeholder page = get_item_from_placeholder_if_exists(placeholder) if not page: # Make sure we do have a page raise Http404 language = parent.language position = None # placeholder (non-page) add-plugin else: # do NOT allow non-page placeholders to use this method, they # should use their respective admin! raise Http404 if not page.has_change_permission(request): # we raise a 404 instead of 403 for a slightly improved security # and to be consistent with placeholder admin raise Http404 # Sanity check to make sure we're not getting bogus values from JavaScript: if not language or not language in [ l[0] for l in settings.LANGUAGES ]: return HttpResponseBadRequest(unicode(_("Language must be set to a supported language!"))) plugin = CMSPlugin(language=language, plugin_type=plugin_type, position=position, placeholder=placeholder) if parent: plugin.parent = parent plugin.save() if 'reversion' in settings.INSTALLED_APPS and page: make_revision_with_plugins(page) reversion.revision.user = request.user plugin_name = unicode(plugin_pool.get_plugin(plugin_type).name) reversion.revision.comment = unicode(_(u"%(plugin_name)s plugin added to %(placeholder)s") % {'plugin_name':plugin_name, 'placeholder':placeholder}) return HttpResponse(str(plugin.pk)) raise Http404
def delete_translation(self, request, object_id, extra_context=None): raise Http404() language = get_language_from_request(request) opts = NewsItem._meta titleopts = Title._meta app_label = titleopts.app_label pluginopts = CMSPlugin._meta try: obj = self.queryset(request).get(pk=unquote(object_id)) except self.model.DoesNotExist: # Don't raise Http404 just yet, because we haven't checked # permissions yet. We don't want an unauthenticated user to be able # to determine whether a given object exists. obj = None if not self.has_delete_permission(request, obj): raise PermissionDenied if obj is None: raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_unicode(opts.verbose_name), 'key': escape(object_id)}) if not len(obj.get_languages()) > 1: raise Http404(_('There only exists one translation for this page')) titleobj = get_object_or_404(Title, page__id=object_id, language=language) plugins = CMSPlugin.objects.filter(placeholder__page__id=object_id, language=language) deleted_objects, perms_needed = get_deleted_objects([titleobj], titleopts, request.user, self.admin_site) to_delete_plugins, perms_needed_plugins = get_deleted_objects(plugins, pluginopts, request.user, self.admin_site) deleted_objects.append(to_delete_plugins) perms_needed = set( list(perms_needed) + list(perms_needed_plugins) ) if request.method == 'POST': if perms_needed: raise PermissionDenied message = _('Title and plugins with language %(language)s was deleted') % { 'language': [name for code, name in settings.CMS_LANGUAGES if code == language][0]} self.log_change(request, titleobj, message) self.message_user(request, message) titleobj.delete() for p in plugins: p.delete() public = obj.publisher_public if public: public.save() if "reversion" in settings.INSTALLED_APPS: make_revision_with_plugins(obj) if not self.has_change_permission(request, None): return HttpResponseRedirect("../../../../") return HttpResponseRedirect("../../") context = { "title": _("Are you sure?"), "object_name": force_unicode(titleopts.verbose_name), "object": titleobj, "deleted_objects": deleted_objects, "perms_lacking": perms_needed, "opts": titleopts, "root_path": self.admin_site.root_path, "app_label": app_label, } context.update(extra_context or {}) context_instance = template.RequestContext(request, current_app=self.admin_site.name) return render_to_response(self.delete_confirmation_template or [ "admin/%s/%s/delete_confirmation.html" % (app_label, titleopts.object_name.lower()), "admin/%s/delete_confirmation.html" % app_label, "admin/delete_confirmation.html" ], context, context_instance=context_instance)
def save(self, **kwargs): from cms.api import create_page, add_plugin from cms.utils.permissions import has_page_add_permission # Check to see if this user has permissions to make this page. We've # already checked this when producing a list of wizard entries, but this # is to prevent people from possible form-hacking. if 'sub_page' in self.cleaned_data: sub_page = self.cleaned_data['sub_page'] else: sub_page = False if self.page: if sub_page: parent = self.page position = "last-child" else: parent = self.page.parent position = "right" else: parent = None position = "last-child" # Before we do this, verify this user has perms to do so. if not (self.user.is_superuser or has_page_add_permission( self.user, self.page, position=position, site=self.page.site)): raise NoPermissionsException( _(u"User does not have permission to add page.")) page = create_page( title=self.cleaned_data['title'], slug=self.cleaned_data['slug'], template=get_cms_setting('PAGE_WIZARD_DEFAULT_TEMPLATE'), language=self.language_code, created_by=smart_text(self.user), parent=parent, in_navigation=True, published=False) page_type = self.cleaned_data.get("page_type") if page_type: copy_target = Page.objects.filter(pk=page_type).first() else: copy_target = None if copy_target: # If the user selected a page type, copy that. if not user_has_view_permission(self.user, copy_target): raise PermissionDenied() # Copy page attributes copy_target._copy_attributes(page, clean=True) page.save() # Copy contents (for each language) for lang in copy_target.get_languages(): copy_target._copy_contents(page, lang) # Copy extensions from cms.extensions import extension_pool extension_pool.copy_extensions(copy_target, page) else: # If the user provided content, then use that instead. content = self.cleaned_data.get('content') plugin_type = get_cms_setting('PAGE_WIZARD_CONTENT_PLUGIN') plugin_body = get_cms_setting('PAGE_WIZARD_CONTENT_PLUGIN_BODY') slot = get_cms_setting('PAGE_WIZARD_CONTENT_PLACEHOLDER') if plugin_type in plugin_pool.plugins and plugin_body: if content and permissions.has_plugin_permission( self.user, plugin_type, "add"): placeholder = self.get_placeholder(page, slot=slot) if placeholder: opts = { 'placeholder': placeholder, 'plugin_type': plugin_type, 'language': self.language_code, plugin_body: content, } add_plugin(**opts) # is it home? publish it right away if not self.page and page.is_home: page.publish(self.language_code) if is_installed('reversion'): from cms.utils.helpers import make_revision_with_plugins from cms.constants import REVISION_INITIAL_COMMENT from cms.utils.reversion_hacks import create_revision with create_revision(): make_revision_with_plugins( obj=page, user=self.user, message=ugettext(REVISION_INITIAL_COMMENT), ) return page