0

I have in Cakephp a form which is loaded by an ajax request. After sending the form via another ajax request, the magic is done in the controller and the controller is sending back new html code. So far so good. It works pretty well as long as I send a get request. If I change the ajax script to force a post request, the result is blackholed. I read a lot about the security component and tried to change a lot of things, but it does not work.

Here is my code of the "OffersController.php":

App::uses('AppController', 'Controller');
App::uses('Folder', 'Utility');
App::uses('File', 'Utility');


class OffersController extends AppController {

public $components = array('Paginator');


public function beforeFilter() {
    parent::beforeFilter();
    $this->Auth->allow('createform');
    $this->Security->unlockedActions = array('createform');
}


public function createform() {
    $this->request->onlyAllow('ajax'); // No direct access via browser URL
    //$this->autoRender = 'false; // We don't render a view in this example
    $this->Security->validatePost = false;
    if ($this->request->is('post')) {
        $this->Session->setFlash(__('Post sent.').' <tt class="pull-right">(C:Offers, F:createform, A:2)</tt>', 'default', array('class' => 'alert alert-success'));
    } else {

    }

    $this->layout = false;
    $this->render('offerform');
}

}

And this is the "createform.ctp" which will be loaded through ajax (if the page is loaded and then if the ajax request is sent:

        <div class="container">
        <div class="row">
            <div class="col-lg-12 text-center">
                <h2 class="section-heading">Offerte</h2>
                <h3 class="section-subheading text-muted">Fordere unverbindlich eine Offerte an.</h3>
            </div>
        </div>
        <div class="row">
            <div class="col-lg-12">
                <?php echo $this->Form->create('Offers', array('name' => 'Offer', 'action' => 'createform', 'role' => 'form', 'type' => 'post', 'id' => 'ajaxForm')); ?>
                    <div class="row">
                        <div class="col-md-8">
                            <?php

                                echo $this->Form->input('firstname', array('type' => 'text', 'label' => false, 'div' => 'form-group col-md-6', 'class' => 'form-control', 'placeholder' => 'Vorname'));
                                echo $this->Form->input('lastname', array('type' => 'text', 'label' => false, 'div' => 'form-group col-md-6', 'class' => 'form-control', 'placeholder' => 'Nachname'));
                                echo $this->Form->input('address', array('type' => 'text', 'label' => false, 'div' => 'form-group col-md-6', 'class' => 'form-control', 'placeholder' => 'Adresse'));
                                echo $this->Form->input('zip', array('type' => 'text', 'label' => false, 'div' => 'form-group col-md-6', 'class' => 'form-control', 'placeholder' => 'Postleitzahl'));
                                echo $this->Form->input('city', array('type' => 'text', 'label' => false, 'div' => 'form-group col-md-6', 'class' => 'form-control', 'placeholder' => 'Ort'));
                                echo $this->Form->input('country', array('options' => array('CH' => 'Schweiz', 'DE' => 'Deutschland', 'AT' => 'Österreich'), 'label' => false, 'div' => 'form-group col-md-6', 'class' => 'form-control', 'before' => '', 'between' => '', 'after' => ''));
                                echo $this->Form->input('emailaddress', array('type' => 'text', 'label' => false, 'div' => 'form-group col-md-6', 'class' => 'form-control', 'placeholder' => 'Emailadresse'));
                                echo $this->Form->input('telephone', array('type' => 'text', 'label' => false, 'div' => 'form-group col-md-6', 'class' => 'form-control', 'placeholder' => 'Telefonnummer'));
                                echo $this->Form->input('desireddate', array('type' => 'text', 'label' => false, 'div' => 'form-group col-md-6', 'class' => 'form-control', 'placeholder' => 'gewünschter Reinigungstermin'));

                                $feesarray = Configure::read('feesarray');
                                $currency = 'CHF';
                                $optionroom['0'] = 'Anzahl Zimmer / Preis';
                                foreach($feesarray as $key => $val) {
                                    $value = $key.' Zimmer / '.$currency.' '.$val[$currency];
                                    $optionroom[$value] = $value;
                                }
                                echo $this->Form->input('rooms', array('options' => $optionroom, 'label' => false, 'div' => 'form-group col-md-6', 'class' => 'form-control', 'before' => '', 'between' => '', 'after' => ''));

                            ?>
                        </div>
                        <div class="col-md-4">
                            <?php echo $this->Form->input('message', array('type' => 'textarea', 'label' => false, 'div' => 'form-group col-md-12', 'class' => 'form-control', 'placeholder' => 'Nachricht')); ?>
                        </div>
                    </div>
                    <div class="clearfix"></div>
                    <div class="row">
                        <div class="col-lg-12 text-center">
                            <p>&nbsp;</p>
                            <?php
                                $formButtonOptions = array(
                                    'type' => 'submit',
                                    'id' => 'btnSave',
                                    'div' => false,
                                    'class' => 'btn btn-xl'
                                );
                                echo $this->Form->button(__('Offerte anfordern'), $formButtonOptions);
                            ?>
                            <p>&nbsp;</p>
                        </div>
                    </div>
                <?php echo $this->Form->end(); ?>
            </div>
        </div>
    </div>
    <script>
        $(function () {
            $("#btnSave").click(function(e){
            //$("#ajaxForm").submit(function(e){
                e.preventDefault(); // avoid to execute the actual submit of the form.
                var formData = $(this).serializeArray();
                var formURL = $(this).attr("action");
                $('#ajaxLoadForm').html('<?php echo __('loading ...'); ?>');    // has to be placed after the var formData, because the form gets replaced after this line...

                $.ajax({
                    type: "post",
                    cache: false,
                    dataType: "html",
                    data: formData,
                    //processData: true,
                    url: formURL,
                    success: function (data, textStatus, jqXHR) {
                        // replace div's content with returned data
                        $('#ajaxLoadForm').html(data);
                    },
                    error: function(jqXHR, textStatus, errorThrown) {
                        alert("An error occurred: " + jqXHR.responseText.message);
                        console.log(jqXHR);
                    }
                });

            });
        });
    </script>

And this is my Model "Offer.php":

class Offer extends AppModel {
public $name = 'Offer';

}

Thank you for any help and hints. Any ideas?

FishWave
  • 308
  • 2
  • 16

3 Answers3

1

I had to change this lines

//$("#btnSave").click(function(e){
$("#ajaxForm").submit(function(e){

In the first version (main question above) I hat the #btnSave used, now I tried it with the outcomment line #ajaxForm. Now it works. I don't know why I didn't use this line in my first version. But the problem is now fixed.

FishWave
  • 308
  • 2
  • 16
0

add following to beforeFilter

if ($this->action === 'create form') {
    $this->Security->validatePost = false;
    $this->Security->csrfCheck = false;
}

That should fix your problem

  • additional to the other existing lines or instead of the other existing lines? – FishWave Jan 27 '15 at 10:22
  • No, this is not fixing my problem. I think I told cakephp already that an ajax request is coming with this $this->Security->unlockedActions = array('createform'); – FishWave Jan 27 '15 at 16:10
0

Try This

 public function edit_comment() {
        $this->layout = 'ajax';
        $this->autoRender = false;
        if ($this->request->is('ajax')) {
            if ($this->FaComment->save($this->request->data, false)) {
                $response['status'] = 'success';
                $response['action'] = 'edit_comment';
                $response['data'] = $this->request->data['FaComment'];
                $response['message'] = __d('vanderdeals', 'Comment saved successfully');
        } else {
            $response['status'] = 'error';
            $response['model'] = 'FaComment';
            $response['message'] = __d('vanderdeals', 'Internal server error occurred. Please try again later.');
        }

        echo json_encode($response);
    }
}
Ashish Pathak
  • 827
  • 8
  • 16