在现有插件中实现imgur的多重上传

如何解决在现有插件中实现imgur的多重上传

一段时间以来,我一直在尝试扩展插件。插件本身可以通过简单的上传工作,但我无法让多重上传工作。

脚本结构如下

Javascript

$.Redactor.prototype.QnetImgur = function() {
    "use strict";
    
    return {
        _file: null,_url: '',init: function() {
            var button = this.button.add('qnetImgur','');
            this.button.addCallback(button,this.QnetImgur.add);
            
            // overwrite modal template
            this.opts.modal['imgur-edit'] = '<div class="section">'
                    + '<dl id="redactor-imgur-source-container">'
                        + '<dt><label for="redactorImgurUpload">' + WCF.Language.get('wcf.editor.imgur.source') + '</label></dt>'
                        + '<dd><input type="file" id="redactorImgurUpload" class="long"></dd>'
                    + '</dl>'
                    + '<dl>'
                        + '<dt></dt>'
                        + '<dd>' + WCF.Language.get('wcf.editor.imgur.or') + '</dd>'
                    + '</dl>'
                    + '<dl id="redactor-imgur-url-container">'
                        + '<dt><label for="redactorImgurSource">' + WCF.Language.get('wcf.editor.imgur.url') + '</label></dt>'
                        + '<dd><input type="text" id="redactorImgurSource" class="long"></dd>'
                    + '</dl>'
                    + '<dl>'
                        + '<dt><label for="imageSize">' + WCF.Language.get('wcf.editor.imgur.imagesize') + '</label></dt>'
                            + '<dd class="floated">'
                                + '<label><input type="radio" name="imagesize" value="t"> ' + WCF.Language.get('wcf.editor.imgur.small') + '</label>'
                                + '<label><input type="radio" name="imagesize" value="m" checked=""> ' + WCF.Language.get('wcf.editor.imgur.medium') + '</label>'
                                + '<label><input type="radio" name="imagesize" value="l"> ' + WCF.Language.get('wcf.editor.imgur.big') + '</label>'
                                + '<label><input type="radio" name="imagesize" value="h"> ' + WCF.Language.get('wcf.editor.imgur.original') + '</label>'
                            + '</dd>'
                    + '</dl>'
                    + '<dl>'
                        + '<dt></dt>'
                        + '<dd><p class="info" role="status">' + WCF.Language.get('wcf.editor.imgur.imagesizeinfo') + '</p></dd>'
                    + '</dl>'
                    + '<dl>'
                        + '<dt><label for="redactorReflink">' + WCF.Language.get('wcf.editor.imgur.reflink') + '</label></dt>'
                        + '<dd><input type="text" id="redactorReflink" class="long"></dd>'
                    + '</dl>'
                    + '<input id="redactor-imgur-title" style="display: none">' /* dummy because redactor expects it to be present */
                    + '<input id="redactor-imgur-caption" style="display: none">' /* dummy because redactor expects it to be present */
                    + '<div class="formSubmit">'
                        + '<button id="redactor-modal-button-action" class="buttonPrimary">Insert</button>'
                    + '</div>'
                + '</div>';
        },add: function() {
            this.modal.load('imgur-edit',WCF.Language.get('wcf.editor.imgur.insert'));
            
            this.modal.show();
            
            this.modal.getDeleteButton().hide();
            var button = this.modal.getActionButton()[0];
            button.addEventListener(WCF_CLICK_EVENT,this.QnetImgur.insert);
            button.textContent = WCF.Language.get('wcf.global.button.insert');
            
            this.WoltLabModal.rebuild();
        },insert: function(event) {
            event.preventDefault();

            var uploadInput = elById('redactorImgurUpload');
            var sourceInput = elById('redactorImgurSource');

            var showError = function(inputElement,message) {
                $('<small class="innerError" />').text(message).insertAfter(inputElement);
            };
            
            // check if source is valid only when there was no file uploaded
            var source = sourceInput.value.trim();

            if(uploadInput.files.length == 0) {
                if (source === '') {
                    return showError(sourceInput,WCF.Language.get('wcf.global.form.error.empty'));
                }
                else if (!source.match(this.opts.regexps.url)) {
                    return showError(sourceInput,WCF.Language.get('wcf.editor.image.source.error.invalid'));
                }
            }

            // progress
            var progress = elCreate('progress');
            elAttr(progress,'max',100);
            elAttr(progress,'style','width: 100%');

            var dt = elCreate('dt');

            var dd = elCreate('dd');
            dd.appendChild(progress);

            var dl = elCreate('dl');
            dl.appendChild(dt);
            dl.appendChild(dd);
            elAttr(dl,'id','redactorImgurProgressContainer');
                
            sourceInput.parentNode.insertBefore(dl,sourceInput.nextSibling);
            
            // Upload ajax process
            require(['AjaxRequest'],(function (AjaxRequest) {
                var imgurUploadObject = elById('redactorImgurUpload');
                var imgurUrlObject = elById('redactorImgurSource');

                var file = null;
                var url = '';

                if(imgurUploadObject.files.length > 0) {
                    file = imgurUploadObject.files[0];
                }

                url = imgurUrlObject.value;

                var formData = new FormData();

                formData.append('imgurUrl',url);
                formData.append('imgurImage',file);
                formData.append('action','upload');

                var request = new AjaxRequest({
                    data: formData,contentType: false,failure: this.QnetImgur._failure.bind(this),silent: true,success: this.QnetImgur._success.bind(this),uploadProgress: this.QnetImgur._progress.bind(this),url: 'index.php?imgur-upload/&t=' + SECURITY_TOKEN,withCredentials: true
                });

                request.sendRequest();
            }).bind(this));
        },_progress: function(event) {
            var percentComplete = Math.round(event.loaded / event.total * 100);

            var sourceInput = elById('redactorImgurSource');
            
            var progress = elByTag('PROGRESS',sourceInput.nextSibling);
            if (progress.length === 1) {
                elAttr(progress[0],'value',percentComplete);
            }
        },_success: function(data) {
            // remove any existing error messages first
            this.modal.getModal().find('.innerError').remove();
            
            var source = data.link;

            var imagesize = document.querySelector('input[name=imagesize]:checked').value;
            var filename = source.match(/([^\/]+)(?=\.\w+$)/)[0];
            var extension = (source.match(/\.([^.]*?)(?=\?|#|$)/) || [])[1];
            
            var html = '<img src="https://i.imgur.com/'+ WCF.String.escapeHTML(filename + imagesize + '.' + extension) +'">';

            var reflink = elById('redactorReflink').value;
            
            var linkUuid;
            if (reflink) {
                linkUuid = WCF.getUUID();
                html = '<a href="' + WCF.String.escapeHTML(reflink) + '" data-uuid="' + linkUuid + '">' + html + '</a>';
            }
            
            this.modal.close();
            
            this.buffer.set();
            
            this.insert.html(html);
            
            if (linkUuid) {
                window.setTimeout((function() {
                    var link = elBySel('a[data-uuid="' + linkUuid + '"]',this.core.editor()[0]);
                    if (link) {
                        link.removeAttribute('data-uuid');
                        this.caret.after(link);
                    }
                }).bind(this),1);
            }
        },_failure: function() {
            this.modal.getModal().find('#redactorImgurProgressContainer').remove();
        }
    };
};

动作类

<?php
namespace wcf\action;
use wcf\system\exception\ValidateActionException;
use wcf\util\HTTPRequest;
use wcf\util\JSON;
use wcf\util\StringUtil;

/**
 * Action for uploading imgur images
 * 
 * @author  QNET17
 */
class ImgurUploadAction extends AJAXProxyAction {
    /**
     * @inheritDoc
     */ 
    public $imageFile = null;

    public $imageUrl = null;

    /**
     * @inheritDoc
     */
    public function readParameters() {
        AbstractAction::readParameters();

        if (isset($_FILES['imgurImage'])) $this->imageFile = $_FILES['imgurImage'];
        if (isset($_REQUEST['imgurUrl'])) $this->imageUrl = StringUtil::trim($_REQUEST['imgurUrl']);
    }
    
    /**
     * @inheritDoc
     */
    public function execute() {
        AbstractAction::execute();

        if(IMGUR_CLIENT_ID == '') {
            throw new ValidateActionException('imgurClientID');
        }

        if($this->imageFile == null && $this->imageUrl == null) {
            throw new ValidateActionException('image');
        }

        $returnValues = null;
        $base64Image = '';

        $isFile = $this->imageFile != null;

        if($isFile) {
            $filename = $this->imageFile['tmp_name'];

            try {
                $handle = fopen($filename,"r");
                $data = fread($handle,filesize($filename));
                $base64Image = base64_encode($data);
                fclose($handle);
            }
            catch(Exception $ex) {
                throw new ValidateActionException('base64Image');
            }
        }

        $postData = [
            'image' => $isFile ? $base64Image : $this->imageUrl,'type' => $isFile ? 'base64' : 'url'
        ];

        $request = new HTTPRequest('https://api.imgur.com/3/upload',[],$postData);
        $request->addHeader('Authorization','Client-ID '.IMGUR_CLIENT_ID);
        $request->execute();
        $reply = $request->getReply();
        $content = $reply['body'];

        $decodedContent = JSON::decode($content);

        if($decodedContent == null || !is_array($decodedContent)) {
            throw new ValidateActionException('reply');
        }

        $returnValues = [
            'link' => $decodedContent['data']['link']
        ];
        
        $this->executed();

        if ($returnValues !== null) {
            // send JSON-encoded response
            header('Content-type: application/json');
            echo JSON::encode($returnValues);
        }
        
        exit;
    }
}

我已经相应地扩展了 javascript

+ '<dd><input name="file[]" type="file" multiple="multiple" id="redactorImgurUpload" class="long"></dd>'

由于我不是开发人员,我不明白如何扩展操作类。

我发现了这个:https://stackoverflow.com/a/19978000/11419476

但我无法让实现工作,然后我得到 为 foreach() 提供的参数无效

如果有任何提示,我将不胜感激

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-