代码之家  ›  专栏  ›  技术社区  ›  adam

附加文件已停止工作10月CMS电子邮件ajax表单

  •  0
  • adam  · 技术社区  · 8 年前

    下面的设置一直工作到它停止,现在我很困惑为什么。 我在10月创建了一个带有文件附件的联系表格,如下所示

    {{ 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框架的问题(?)。

    这是一个奇怪的事情,让我惊讶时,与该项目的工作,现在我卡住了。

    1 回复  |  直到 8 年前
        1
  •  1
  •   Hardik Satasiya    8 年前

    从你的代码来看,你使用错了 方法

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

    您的代码正在使用此

    输入: 收到 (“文件附件”);

    实际上应该是这样

    输入: 文件 (“文件附件”);

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

    更新

    好吧,我想这有点问题 文件 立面代码 (新文件()) 我们可以直接使用该文件,因为您没有保存该文件,

    你能替换代码并检查一下吗

    $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代码段),代码取自10月份cms官方git repo,只是删除了其中的一部分,这样它就可以覆盖现有代码而不会产生冲突。

    我建议,把这个代码 创建ajax fw覆盖。js文件 然后在页面上包含文件,或者只是复制布局并将其添加到最底部,不管它是如何在10月份默认ajax之后出现的 {%framework%} ,因此它可以覆盖其 要求 .

    这不是一个好的解决方案 但是考虑到你不能更新你的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);