繁体   English   中英

附加文件停止了octobercms电子邮件ajax表单的工作

[英]Attaching files stopped working octobercms email ajax form

下面的设置一直有效,直到停止为止,现在我感到困惑。 我在OctoberCMS中创建了一个带有文件附件的联系表格,如下所示

{{ form_ajax('ContactForm::onSend', { files: 'true',  flash: 'true', 'data-request-files':true, 'data-request-validate': true }) }}
    <input type="hidden" name="handler" value='onSave'>
    <fieldset class="form">
        <input type="name" name="name" placeholder="Imię i nazwisko" required>
        <input type="email" name="email" placeholder="E-mail" required>
        <input type="phone" name="phone" placeholder="Telefon">
        <input type="text" name="subject" placeholder="Temat" >
        <textarea name="theMessage" placeholder="Zapytanie" required style="width: 100%; height: 140px;"></textarea>
        <input type="file" name="fileAttachment" id="fileAttachment" class="inputfile"  data-multiple-caption="wybrano {count}" /><label for="fileAttachment">wybierz plik </label><span class='attachmentName'></span>

    </fieldset>
        <button type="submit" class="send" data-attach-loading>Wyślij</button>
    </fieldset>

{{ form_close() }}

发送电子邮件的组件

<?php namespace Depcore\Parts\Components;
use Cms\Classes\ComponentBase;

use Mail;
use Lang;
use Flash;
use Input;
use Validator;
use ValidationException;
use Redirect;
use System\Models\File;

class ContactForm extends ComponentBase
{
    public function componentDetails()
    {
        return [
            'name'        => 'depcore.parts::lang.components.contactFormTitle',
            'description' => 'depcore.parts::lang.components.contactFormDescription'
        ];
    }

    public function defineProperties()
    {
        return [
              'emailTo' => [
                    'title' => 'depcore.parts::components.emailAddress',
                    'description' => 'depcore.parts::components.destinationEmailDescription',
                    'default' => 'zamowienia@kludi.pl',
                    'validationPattern' => "\A[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\z",
                    'ValidationMessage' => ''
            ]
        ];
    }

    public function onSend(){

        $data = post();
        $vars = [
            'name' => Input::get('name'),
            'subject' => Input::get('subject'),
            'phone' => Input::get('phone'),
            'theMessage' => Input::get('theMessage'),
            'fileAttachment' => Input::file('fileAttachment'),
        ];

        $rules = [
                'name' => 'required',
                'email' => 'required|email'
            ];

        $validator = Validator::make($data, $rules);

        if ($validator->fails())
            throw new ValidationException( $validator );
        else {

        Mail::send('depcore.parts::mail.message', $vars, function( $message )  use  ( $vars )  {

            // $message->to($this->property('emailTo'));
            $message->to('adam@depcore.pl');

            if ($vars['fileAttachment']) {
                $file = (new File())->fromPost($vars['fileAttachment']);
                $message->attach($file['path']);
            }

            $message->subject($vars['subject']);
            Flash::success('Wiadomość została wysłana.');
        });

      }
    }

}

据我所知, Input::file('fileAttachemnt')始终返回null,因此我认为JavaScript框架(?)可能存在问题。

这是一件很奇怪的事情,在我被卡住的项目中工作时,让我感到惊讶。

从您的代码看来,您错误地使用了错误的方法

 $vars = [
        'name' => Input::get('name'),
        'subject' => Input::get('subject'),
        'phone' => Input::get('phone'),
        'theMessage' => Input::get('theMessage'),
        'fileAttachment' => Input::get('fileAttachment'), <-- here
 ];

您的代码正在使用此

输入:: get ('fileAttachemnt');

实际上应该是这样

输入:: 文件 ('fileAttachemnt');

可能是您更新了代码而没有注意到;)

UPDATE

好的,我想文件外观代码(新File())存在一些问题,请不要使用它,而可以直接使用文件,因为您也不会保存该文件,

您可以替换代码并检查一次吗

$file = (new File())->fromPost($vars['fileAttachment']);
$message->attach($file['path']);

$file = $vars['fileAttachment'];
$pathToFile = $file->getPathname();
$fileName = $file->getClientOriginalName();
$mime = $file->getMimeType()
$message->attach($pathToFile, ['as' => $fileName, 'mime' => $mime]);

然后检查它,它应该可以工作。

更多更新

我添加了ajax框架的修改版(添加了js片段),代码取自October CMS官方git repo,并删除了其中的一部分,以便可以覆盖现有代码而不会发生冲突。

我建议采用此代码并创建ajax-fw-override.js文件,然后在页面上包含文件或只是重复布局,然后将其添加到最底部,无论十月后默认ajax {%framework%}应该如何处理,因此它可以覆盖其Request

这不是一个好的解决方案,但是考虑到您无法更新您的cms版本,我们可以使用它。 (同样,通过制作重复的布局,我们确保它不会影响其他任何地方)。

我使用控制台在您的站点上对其进行了测试,并且可以正常工作。 所以就检查一下,让我知道。


 + function($) { "use strict"; var Request = function(element, handler, options) { var $el = this.$el = $(element); this.options = options || {}; /* * Validate handler name */ if (handler === undefined) { throw new Error('The request handler name is not specified.') } if (!handler.match(/^(?:\\w+\\:{2})?on*/)) { throw new Error('Invalid handler name. The correct handler name format is: "onEvent".') } /* * Prepare the options and execute the request */ var $form = options.form ? $(options.form) : $el.closest('form'), $triggerEl = !!$form.length ? $form : $el, context = { handler: handler, options: options } $el.trigger('ajaxSetup', [context]) var _event = jQuery.Event('oc.beforeRequest') $triggerEl.trigger(_event, context) if (_event.isDefaultPrevented()) return var loading = options.loading !== undefined ? options.loading : null, isRedirect = options.redirect !== undefined && options.redirect.length, useFlash = options.flash !== undefined, useFiles = options.files !== undefined if (useFiles && typeof FormData === 'undefined') { console.warn('This browser does not support file uploads via FormData') useFiles = false } if ($.type(loading) == 'string') { loading = $(loading) } /* * Request headers */ var requestHeaders = { 'X-OCTOBER-REQUEST-HANDLER': handler, 'X-OCTOBER-REQUEST-PARTIALS': this.extractPartials(options.update) } if (useFlash) { requestHeaders['X-OCTOBER-REQUEST-FLASH'] = 1 } /* * Request data */ var requestData, inputName, data = {} $.each($el.parents('[data-request-data]').toArray().reverse(), function extendRequest() { $.extend(data, paramToObj('data-request-data', $(this).data('request-data'))) }) if ($el.is(':input') && !$form.length) { inputName = $el.attr('name') if (inputName !== undefined && options.data[inputName] === undefined) { options.data[inputName] = $el.val() } } if (options.data !== undefined && !$.isEmptyObject(options.data)) { $.extend(data, options.data) } if (useFiles) { requestData = new FormData($form.length ? $form.get(0) : null) if ($el.is(':file') && inputName) { $.each($el.prop('files'), function() { requestData.append(inputName, this) }) delete data[inputName] } $.each(data, function(key) { requestData.append(key, this) }) } else { requestData = [$form.serialize(), $.param(data)].filter(Boolean).join('&') } /* * Request options */ var requestOptions = { url: window.location.href, crossDomain: false, context: context, headers: requestHeaders, success: function(data, textStatus, jqXHR) { /* * Halt here if beforeUpdate() or data-request-before-update returns false */ if (this.options.beforeUpdate.apply(this, [data, textStatus, jqXHR]) === false) return if (options.evalBeforeUpdate && eval('(function($el, context, data, textStatus, jqXHR) {' + options.evalBeforeUpdate + '}.call($el.get(0), $el, context, data, textStatus, jqXHR))') === false) return /* * Trigger 'ajaxBeforeUpdate' on the form, halt if event.preventDefault() is called */ var _event = jQuery.Event('ajaxBeforeUpdate') $triggerEl.trigger(_event, [context, data, textStatus, jqXHR]) if (_event.isDefaultPrevented()) return if (useFlash && data['X_OCTOBER_FLASH_MESSAGES']) { $.each(data['X_OCTOBER_FLASH_MESSAGES'], function(type, message) { requestOptions.handleFlashMessage(message, type) }) } /* * Proceed with the update process */ var updatePromise = requestOptions.handleUpdateResponse(data, textStatus, jqXHR) updatePromise.done(function() { $triggerEl.trigger('ajaxSuccess', [context, data, textStatus, jqXHR]) options.evalSuccess && eval('(function($el, context, data, textStatus, jqXHR) {' + options.evalSuccess + '}.call($el.get(0), $el, context, data, textStatus, jqXHR))') }) return updatePromise }, error: function(jqXHR, textStatus, errorThrown) { var errorMsg, updatePromise = $.Deferred() if ((window.ocUnloading !== undefined && window.ocUnloading) || errorThrown == 'abort') return /* * Disable redirects */ isRedirect = false options.redirect = null /* * Error 406 is a "smart error" that returns response object that is * processed in the same fashion as a successful response. */ if (jqXHR.status == 406 && jqXHR.responseJSON) { errorMsg = jqXHR.responseJSON['X_OCTOBER_ERROR_MESSAGE'] updatePromise = requestOptions.handleUpdateResponse(jqXHR.responseJSON, textStatus, jqXHR) } /* * Standard error with standard response text */ else { errorMsg = jqXHR.responseText ? jqXHR.responseText : jqXHR.statusText updatePromise.resolve() } updatePromise.done(function() { $el.data('error-message', errorMsg) /* * Trigger 'ajaxError' on the form, halt if event.preventDefault() is called */ var _event = jQuery.Event('ajaxError') $triggerEl.trigger(_event, [context, errorMsg, textStatus, jqXHR]) if (_event.isDefaultPrevented()) return /* * Halt here if the data-request-error attribute returns false */ if (options.evalError && eval('(function($el, context, errorMsg, textStatus, jqXHR) {' + options.evalError + '}.call($el.get(0), $el, context, errorMsg, textStatus, jqXHR))') === false) return requestOptions.handleErrorMessage(errorMsg) }) return updatePromise }, complete: function(data, textStatus, jqXHR) { $triggerEl.trigger('ajaxComplete', [context, data, textStatus, jqXHR]) options.evalComplete && eval('(function($el, context, data, textStatus, jqXHR) {' + options.evalComplete + '}.call($el.get(0), $el, context, data, textStatus, jqXHR))') }, /* * Custom function, requests confirmation from the user */ handleConfirmMessage: function(message) { var _event = jQuery.Event('ajaxConfirmMessage') _event.promise = $.Deferred() if ($(window).triggerHandler(_event, [message]) !== undefined) { _event.promise.done(function() { options.confirm = null new Request(element, handler, options) }) return false } if (_event.isDefaultPrevented()) return if (message) return confirm(message) }, /* * Custom function, display an error message to the user */ handleErrorMessage: function(message) { var _event = jQuery.Event('ajaxErrorMessage') $(window).trigger(_event, [message]) if (_event.isDefaultPrevented()) return if (message) alert(message) }, /* * Custom function, focus fields with errors */ handleValidationMessage: function(message, fields) { $triggerEl.trigger('ajaxValidation', [context, message, fields]) var isFirstInvalidField = true $.each(fields, function focusErrorField(fieldName, fieldMessages) { fieldName = fieldName.replace(/\\.(\\w+)/g, '[$1]') var fieldElement = $form.find('[name="' + fieldName + '"], [name="' + fieldName + '[]"], [name$="[' + fieldName + ']"], [name$="[' + fieldName + '][]"]').filter(':enabled').first() if (fieldElement.length > 0) { var _event = jQuery.Event('ajaxInvalidField') $(window).trigger(_event, [fieldElement.get(0), fieldName, fieldMessages, isFirstInvalidField]) if (isFirstInvalidField) { if (!_event.isDefaultPrevented()) fieldElement.focus() isFirstInvalidField = false } } }) }, /* * Custom function, display a flash message to the user */ handleFlashMessage: function(message, type) {}, /* * Custom function, redirect the browser to another location */ handleRedirectResponse: function(url) { window.location.href = url }, /* * Custom function, handle any application specific response values * Using a promisary object here in case injected assets need time to load */ handleUpdateResponse: function(data, textStatus, jqXHR) { /* * Update partials and finish request */ var updatePromise = $.Deferred().done(function() { for (var partial in data) { /* * If a partial has been supplied on the client side that matches the server supplied key, look up * it's selector and use that. If not, we assume it is an explicit selector reference. */ var selector = (options.update[partial]) ? options.update[partial] : partial if ($.type(selector) == 'string' && selector.charAt(0) == '@') { $(selector.substring(1)).append(data[partial]).trigger('ajaxUpdate', [context, data, textStatus, jqXHR]) } else if ($.type(selector) == 'string' && selector.charAt(0) == '^') { $(selector.substring(1)).prepend(data[partial]).trigger('ajaxUpdate', [context, data, textStatus, jqXHR]) } else { $(selector).trigger('ajaxBeforeReplace') $(selector).html(data[partial]).trigger('ajaxUpdate', [context, data, textStatus, jqXHR]) } } /* * Wait for .html() method to finish rendering from partial updates */ setTimeout(function() { $(window) .trigger('ajaxUpdateComplete', [context, data, textStatus, jqXHR]) .trigger('resize') }, 0) }) /* * Handle redirect */ if (data['X_OCTOBER_REDIRECT']) { options.redirect = data['X_OCTOBER_REDIRECT'] isRedirect = true } if (isRedirect) { requestOptions.handleRedirectResponse(options.redirect) } /* * Handle validation */ if (data['X_OCTOBER_ERROR_FIELDS']) { requestOptions.handleValidationMessage(data['X_OCTOBER_ERROR_MESSAGE'], data['X_OCTOBER_ERROR_FIELDS']) } /* * Handle asset injection */ if (data['X_OCTOBER_ASSETS']) { assetManager.load(data['X_OCTOBER_ASSETS'], $.proxy(updatePromise.resolve, updatePromise)) } else { updatePromise.resolve() } return updatePromise } } if (useFiles) { requestOptions.processData = requestOptions.contentType = false } /* * Allow default business logic to be called from user functions */ context.success = requestOptions.success context.error = requestOptions.error context.complete = requestOptions.complete requestOptions = $.extend(requestOptions, options) requestOptions.data = requestData /* * Initiate request */ if (options.confirm && !requestOptions.handleConfirmMessage(options.confirm)) { return } if (loading) loading.show() $(window).trigger('ajaxBeforeSend', [context]) $el.trigger('ajaxPromise', [context]) return $.ajax(requestOptions) .fail(function(jqXHR, textStatus, errorThrown) { if (!isRedirect) { $el.trigger('ajaxFail', [context, textStatus, jqXHR]) } if (loading) loading.hide() }) .done(function(data, textStatus, jqXHR) { if (!isRedirect) { $el.trigger('ajaxDone', [context, data, textStatus, jqXHR]) } if (loading) loading.hide() }) .always(function(dataOrXhr, textStatus, xhrOrError) { $el.trigger('ajaxAlways', [context, dataOrXhr, textStatus, xhrOrError]) }) } Request.DEFAULTS = { update: {}, type: 'POST', beforeUpdate: function(data, textStatus, jqXHR) {}, evalBeforeUpdate: null, evalSuccess: null, evalError: null, evalComplete: null } /* * Internal function, build a string of partials and their update elements. */ Request.prototype.extractPartials = function(update) { var result = [] for (var partial in update) result.push(partial) return result.join('&') } // REQUEST PLUGIN DEFINITION // ============================ var old = $.fn.request $.fn.request = function(handler, option) { var args = arguments var $this = $(this).first() var data = { evalBeforeUpdate: $this.data('request-before-update'), evalSuccess: $this.data('request-success'), evalError: $this.data('request-error'), evalComplete: $this.data('request-complete'), confirm: $this.data('request-confirm'), redirect: $this.data('request-redirect'), loading: $this.data('request-loading'), flash: $this.data('request-flash'), files: $this.data('request-files'), form: $this.data('request-form'), update: paramToObj('data-request-update', $this.data('request-update')), data: paramToObj('data-request-data', $this.data('request-data')) } if (!handler) handler = $this.data('request') var options = $.extend(true, {}, Request.DEFAULTS, data, typeof option == 'object' && option) return new Request($this, handler, options) } $.fn.request.Constructor = Request $.request = function(handler, option) { return $(document).request(handler, option) } // REQUEST NO CONFLICT // ================= $.fn.request.noConflict = function() { $.fn.request = old return this } // REQUEST DATA-API // ============== function paramToObj(name, value) { if (value === undefined) value = '' if (typeof value == 'object') return value try { return JSON.parse(JSON.stringify(eval("({" + value + "})"))) } catch (e) { throw new Error('Error parsing the ' + name + ' attribute value. ' + e) } } }(window.jQuery); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM