Exemple #1
0
    def copy_plugins(self, request):
        """
        POST request should have the following data:

        - cms_path
        - source_language
        - source_placeholder_id
        - source_plugin_id (optional)
        - target_language
        - target_placeholder_id
        - target_plugin_id (deprecated/unused)
        """
        source_placeholder_id = request.POST['source_placeholder_id']
        target_language = request.POST['target_language']
        target_placeholder_id = request.POST['target_placeholder_id']
        source_placeholder = get_object_or_404(Placeholder,
                                               pk=source_placeholder_id)
        target_placeholder = get_object_or_404(Placeholder,
                                               pk=target_placeholder_id)

        if not target_language or not target_language in get_language_list():
            return HttpResponseBadRequest(
                force_text(_("Language must be set to a supported language!")))

        copy_to_clipboard = target_placeholder.pk == request.toolbar.clipboard.pk
        source_plugin_id = request.POST.get('source_plugin_id', None)

        if copy_to_clipboard and source_plugin_id:
            new_plugin = self._copy_plugin_to_clipboard(
                request,
                source_placeholder,
                target_placeholder,
            )
            new_plugins = [new_plugin]
        elif copy_to_clipboard:
            new_plugin = self._copy_placeholder_to_clipboard(
                request,
                source_placeholder,
                target_placeholder,
            )
            new_plugins = [new_plugin]
        else:
            new_plugins = self._add_plugins_from_placeholder(
                request,
                source_placeholder,
                target_placeholder,
            )
        data = get_plugin_tree_as_json(request, new_plugins)
        return HttpResponse(data, content_type='application/json')
    def render_close_frame(self, request, obj, extra_context=None):
        try:
            root = obj.parent.get_bound_plugin() if obj.parent else obj
        except ObjectDoesNotExist:
            # This is a nasty edge-case.
            # If the parent plugin is a ghost plugin, fetching the plugin tree
            # will fail because the downcasting function filters out all ghost plugins.
            # Currently this case is only present in the djangocms-text-ckeditor app
            # which uses ghost plugins to create inline plugins on the text.
            root = obj

        plugins = [root] + list(root.get_descendants().order_by('path'))
        # simulate the call to the unauthorized CMSPlugin.page property
        cms_page = obj.placeholder.page if obj.placeholder_id else None

        child_classes = self.get_child_classes(
            slot=obj.placeholder.slot,
            page=cms_page,
            instance=obj,
        )

        parent_classes = self.get_parent_classes(
            slot=obj.placeholder.slot,
            page=cms_page,
            instance=obj,
        )

        data = get_plugin_toolbar_info(
            obj,
            children=child_classes,
            parents=parent_classes,
        )
        data['plugin_desc'] = escapejs(force_str(obj.get_short_description()))

        context = {
            'plugin': obj,
            'is_popup': True,
            'plugin_data': json.dumps(data),
            'plugin_structure': get_plugin_tree_as_json(request, plugins),
        }

        if extra_context:
            context.update(extra_context)
        return render_to_response(request,
                                  'admin/cms/page/plugin/confirm_form.html',
                                  context)
Exemple #3
0
def render_replace_response(request,
                            new_plugins,
                            source_placeholder=None,
                            source_plugin=None):
    move_plugins, add_plugins = [], []
    for plugin in new_plugins:
        root = plugin.parent.get_bound_plugin() if plugin.parent else plugin

        plugins = [root] + list(root.get_descendants())

        plugin_order = plugin.placeholder.get_plugin_tree_order(
            plugin.language,
            parent_id=plugin.parent_id,
        )
        plugin_tree = get_plugin_tree_as_json(request, plugins)
        move_data = get_plugin_toolbar_info(plugin)
        move_data['plugin_order'] = plugin_order
        move_data.update(json.loads(plugin_tree))
        move_plugins.append(json.dumps(move_data))
        add_plugins.append((
            json.dumps(get_plugin_toolbar_info(plugin)),
            plugin_tree,
        ))
    context = {
        'added_plugins': add_plugins,
        'moved_plugins': move_plugins,
        'is_popup': True,
    }
    if source_plugin is not None:
        context['replaced_plugin'] = json.dumps(
            get_plugin_toolbar_info(source_plugin), )
    if source_placeholder is not None:
        context['replaced_placeholder'] = json.dumps({
            'placeholder_id':
            source_placeholder.pk,
            'deleted':
            True,
        })
    return render(request, 'djangocms_alias/alias_replace.html', context)
    def paste_from_clipboard(self, request, form):
        placeholder = form.cleaned_data['placeholder']
        language = form.cleaned_data['language']
        cascade_clipboard = form.cleaned_data['clipboard']
        tree_order = placeholder.get_plugin_tree_order(language)
        deserialize_to_clipboard(request, cascade_clipboard.data)
        cascade_clipboard.last_accessed_at = now()
        cascade_clipboard.save(update_fields=['last_accessed_at'])

        # detach plugins from clipboard and reattach them to current placeholder
        cb_placeholder_plugin = request.toolbar.clipboard.cmsplugin_set.filter(
            plugin_type='PlaceholderPlugin').first()
        cb_placeholder_instance, _ = cb_placeholder_plugin.get_plugin_instance(
        )
        new_plugins = cb_placeholder_instance.placeholder_ref.get_plugins()
        new_plugins.update(placeholder=placeholder)

        # reorder root plugins in placeholder
        root_plugins = placeholder.get_plugins(language).filter(
            parent__isnull=True).order_by('changed_date')
        for position, plugin in enumerate(root_plugins.iterator()):
            plugin.update(position=position)
        placeholder.mark_as_dirty(language, clear_cache=False)

        # create a list of pasted plugins to be added to the structure view
        all_plugins = placeholder.get_plugins(language)
        if all_plugins.exists():
            new_plugins = placeholder.get_plugins(language).exclude(
                pk__in=tree_order)
            data = json.loads(
                get_plugin_tree_as_json(request, list(new_plugins)))
            data['plugin_order'] = tree_order + ['__COPY__']
        else:
            return render(request, 'cascade/admin/clipboard_reload_page.html')
        data['target_placeholder_id'] = placeholder.pk
        context = {'structure_data': json.dumps(data)}
        return render(request, 'cascade/admin/clipboard_paste_plugins.html',
                      context)
    def move_plugin(self, request):
        """
        Performs a move or a "paste" operation (when «move_a_copy» is set)

        POST request with following parameters:
        - plugin_id
        - placeholder_id
        - plugin_language (optional)
        - plugin_parent (optional)
        - plugin_order (array, optional)
        - move_a_copy (Boolean, optional) (anything supplied here except a case-
                                        insensitive "false" is True)
        NOTE: If move_a_copy is set, the plugin_order should contain an item
              '__COPY__' with the desired destination of the copied plugin.
        """
        # plugin_id and placeholder_id are required, so, if nothing is supplied,
        # an ValueError exception will be raised by get_int().
        try:
            plugin_id = get_int(request.POST.get('plugin_id'))
        except TypeError:
            raise RuntimeError("'plugin_id' is a required parameter.")

        plugin = self._get_plugin_from_id(plugin_id)

        try:
            placeholder_id = get_int(request.POST.get('placeholder_id'))
        except TypeError:
            raise RuntimeError("'placeholder_id' is a required parameter.")
        except ValueError:
            raise RuntimeError("'placeholder_id' must be an integer string.")

        placeholder = Placeholder.objects.get(pk=placeholder_id)

        # The rest are optional
        parent_id = get_int(request.POST.get('plugin_parent', ""), None)
        language = request.POST.get('plugin_language', None) or plugin.language
        move_a_copy = request.POST.get('move_a_copy')
        move_a_copy = (move_a_copy and move_a_copy != "0" and
                       move_a_copy.lower() != "false")
        move_to_clipboard = placeholder == request.toolbar.clipboard

        source_language = plugin.language
        source_placeholder = plugin.placeholder

        order = request.POST.getlist("plugin_order[]")

        if placeholder != source_placeholder:
            try:
                template = self.get_placeholder_template(request, placeholder)
                has_reached_plugin_limit(placeholder, plugin.plugin_type,
                                         plugin.language, template=template)
            except PluginLimitReached as er:
                return HttpResponseBadRequest(er)

        # order should be a list of plugin primary keys
        # it's important that the plugins being referenced
        # are all part of the same tree.
        exclude_from_order_check = ['__COPY__', str(plugin.pk)]
        ordered_plugin_ids = [int(pk) for pk in order if pk not in exclude_from_order_check]
        plugins_in_tree_count = (
            placeholder
            .get_plugins(language)
            .filter(parent=parent_id, pk__in=ordered_plugin_ids)
            .count()
        )

        if len(ordered_plugin_ids) != plugins_in_tree_count:
            # order does not match the tree on the db
            message = _('order parameter references plugins in different trees')
            return HttpResponseBadRequest(force_text(message))

        # True if the plugin is not being moved from the clipboard
        # to a placeholder or from a placeholder to the clipboard.
        move_a_plugin = not move_a_copy and not move_to_clipboard

        if parent_id and plugin.parent_id != parent_id:
            target_parent = get_object_or_404(CMSPlugin, pk=parent_id)

            if move_a_plugin and target_parent.placeholder_id != placeholder.pk:
                return HttpResponseBadRequest(force_text(
                    _('parent must be in the same placeholder')))

            if move_a_plugin and target_parent.language != language:
                return HttpResponseBadRequest(force_text(
                    _('parent must be in the same language as '
                      'plugin_language')))
        elif parent_id:
            target_parent = plugin.parent
        else:
            target_parent = None

        new_plugin = None
        fetch_tree = False

        if move_a_copy and plugin.plugin_type == "PlaceholderPlugin":
            new_plugins = self._paste_placeholder(
                request,
                plugin=plugin,
                target_language=language,
                target_placeholder=placeholder,
                tree_order=order,
            )
        elif move_a_copy:
            fetch_tree = True
            new_plugin = self._paste_plugin(
                request,
                plugin=plugin,
                target_parent=target_parent,
                target_language=language,
                target_placeholder=placeholder,
                tree_order=order,
            )
        elif move_to_clipboard:
            new_plugin = self._cut_plugin(
                request,
                plugin=plugin,
                target_language=language,
                target_placeholder=placeholder,
            )
            new_plugins = [new_plugin]
        else:
            fetch_tree = True
            new_plugin = self._move_plugin(
                request,
                plugin=plugin,
                target_parent=target_parent,
                target_language=language,
                target_placeholder=placeholder,
                tree_order=order,
            )

        if new_plugin and fetch_tree:
            root = (new_plugin.parent or new_plugin)
            new_plugins = [root] + list(root.get_descendants().order_by('path'))

        # Mark the target placeholder as dirty
        placeholder.mark_as_dirty(language)

        if placeholder != source_placeholder:
            # Plugin is being moved or copied into a separate placeholder
            # Mark source placeholder as dirty
            source_placeholder.mark_as_dirty(source_language)
        data = get_plugin_tree_as_json(request, new_plugins)
        return HttpResponse(data, content_type='application/json')
    def import_plugins_view(cls, request):
        if not request.user.is_staff:
            raise PermissionDenied

        new_form = ExportImportForm(request.GET or None)

        if new_form.is_valid():
            initial_data = new_form.cleaned_data
        else:
            initial_data = None

        if request.method == 'GET' and not new_form.is_valid():
            return HttpResponseBadRequest(
                _('Form received unexpected values.'))

        import_form = PluginImportForm(
            data=request.POST or None,
            files=request.FILES or None,
            initial=initial_data,
        )

        if not import_form.is_valid():
            opts = cls.model._meta
            context = {
                'form': import_form,
                'has_change_permission': True,
                'opts': opts,
                'root_path': reverse('admin:index'),
                'is_popup': True,
                'app_label': opts.app_label,
                'media': (cls().media + import_form.media),
            }
            return render(request, 'djangocms_transfer/import_plugins.html',
                          context)

        plugin = import_form.cleaned_data.get('plugin')
        language = import_form.cleaned_data['language']

        if plugin:
            root_id = plugin.pk
            placeholder = plugin.placeholder
        else:
            root_id = None
            placeholder = import_form.cleaned_data.get('placeholder')

        if not placeholder:
            # Page placeholders/plugins import
            # TODO: Check permissions
            import_form.run_import()
            return HttpResponse(
                '<div><div class="messagelist"><div class="success"></div></div></div>'
            )

        tree_order = placeholder.get_plugin_tree_order(language,
                                                       parent_id=root_id)
        # TODO: Check permissions
        import_form.run_import()

        if LTE_CMS_3_4:
            return HttpResponse(
                '<div><div class="messagelist"><div class="success"></div></div></div>'
            )

        if plugin:
            new_plugins = plugin.reload().get_descendants().exclude(
                pk__in=tree_order)
            return plugin.get_plugin_class_instance().render_close_frame(
                request, obj=new_plugins[0])

        from cms.toolbar.utils import get_plugin_tree_as_json

        # Placeholder plugins import
        new_plugins = placeholder.get_plugins(language).exclude(
            pk__in=tree_order)
        data = json.loads(get_plugin_tree_as_json(request, list(new_plugins)))
        data['plugin_order'] = tree_order + ['__COPY__']
        data['target_placeholder_id'] = placeholder.pk
        context = {'structure_data': json.dumps(data)}
        return render(request,
                      'djangocms_transfer/placeholder_close_frame.html',
                      context)