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)
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)