0

This is a page for calculate the product order. My mentor told me that:

"The code put the code calculation logic inside JavaScript which means, user can simply inject and modified the content and get discount to make it safe, may either do a recalculation on submit at server side before display, or make the js function to call API, and return the result instead of put calculation logic inside JS"

But I really can't get it, how can I make it in server side?

views:

<?php $form = ActiveForm::begin([
'action'=>['summary'],
'id'=>'order-form',
]); ?>

    <?= Html::dropDownList('country', null,['malaysia'=>'Malaysia','singapore'=>'Singapore', 'brunei'=>'Brunei'],['id'=>'country']) ?>
    <?= Html::textInput('code','',['class'=>'form-control','placeholder'=>'promotion code','id'=>'code', 'style'=>'text-transform:uppercase'])?>
    <?= Html::button('Apply', ['class' => 'btn btn-primary', 'id'=>'apply']) ?>

    <?= Html::hiddenInput('id', $model->id) ?>
    <?= Html::hiddenInput('discount', '', ['id'=>'discount']) ?>
    <?= Html::hiddenInput('ship','',['id'=>'ship']) ?>
    <?= Html::hiddenInput('qty', $qty, ['id'=>'qty']) ?>
    <?= Html::hiddenInput('subtotal', $subtotal, ['id'=>'subtotal']) ?>

    <?= Html::submitButton('Checkout', ['class' => 'btn btn-primary']) ?>
<?php ActiveForm::end(); ?>

js:

$(document).ready(function() {
var qty=$('#qty').val();
var subtotal=$('#subtotal').val();  
$('#discount').val(0);
$("#apply").click(function()  {  
    var code=$('#code').val().toUpperCase();
    var off5=(subtotal*0.05).toFixed(2);
    var off15=15;

    if(code=='OFF5PC'){
        if (qty>=2)
            $('#discount').val(off5);
        else{
            $('#discount').val(0);
            alert('At least 2 quantities');
        }
    }
    else if(code=='GIVEME15'){
        if(subtotal>=100)
            $('#discount').val(off15);
        else{
            $('#discount').val(0);
            alert('Minumum puchase of RM100');
        }
    }
    else{
        $('#discount').val(0);
        alert('Invalid promotion code');
    }
    if ($('#discount').val()=='0'){
        $('#code').val('');
    }
});


if(qty>=2||subtotal>=150){
    $('#ship').val(0);
    $('#shipping').html('0');
}
else{
    $('#ship').val(10);
    $('#shipping').html('10');
}
$("#country").change(function() {
    var country=$('#country').val();

    if(country=='malaysia'){
        if(qty>=2||subtotal>=150){
            $('#ship').val(0);
            $('#shipping').html('0');
        }
        else{
            $('#ship').val(10);
            $('#shipping').html('10');
        }
    }
    else if(country=='singapore'){
        if(subtotal>=300){
            $('#ship').val(0);
            $('#shipping').html('0');
        }
        else{
            $('#ship').val(20);
            $('#shipping').html('20');
        }
    }
    else if(country=='brunei')  {
        if(subtotal>=300){
            $('#ship').val(0);
            $('#shipping').html('0');
        }
        else{
            $('#ship').val(25);
            $('#shipping').html('25');
        }
    }
});
});

controllers:

public function actionSummary()
{
    $id=Yii::$app->request->post('id');
    $qty=Yii::$app->request->post('qty');
    $discount=Yii::$app->request->post('discount');
    $shipping=Yii::$app->request->post('ship');
    $subtotal=Yii::$app->request->post('subtotal');
    $area=Yii::$app->request->post('country');
    $code=Yii::$app->request->post('code');
    $summary=Products::findOne($id);

    return $this->render('summary', [
        'model' => $summary,
        'quantity'=>$qty,
        'discount'=>$discount,
        'shipping'=>$shipping,
        'subtotal'=>$subtotal,
        'area'=>$area,
        'code'=>$code,
    ]); 
}
Ying Rui Wong
  • 113
  • 3
  • 17

2 Answers2

0

use browser tools inspect to determine your id of each fields. Usually the default id in Yii2 begins with view_name combine with "-" and field name.

Wilson Ng
  • 201
  • 2
  • 17
0

For validating the form onsubmit, you can enable ajaxvalidation in your form like below.

View:

<?php $form = ActiveForm::begin([
'action'=>['summary'],
'enableAjaxValidation' => true,
'id'=>'order-form',
]); ?>

    <?= $form->field($model, 'country')->dropDownList(['malaysia'=>'Malaysia','singapore'=>'Singapore', 'brunei'=>'Brunei']) ?>
    <?= $form->field($model, 'code', ['options' => ['class' => 'form-control', 'id'=>'code']])->textInput(['placeholder'=>'promotion code'])?>
    <?= Html::button('Apply', ['class' => 'btn btn-primary', 'id'=>'apply']) ?>

    <?= Html::hiddenInput('id', $model->id) ?>
    <?= Html::hiddenInput('discount', '', ['id'=>'discount']) ?>
    <?= Html::hiddenInput('ship','',['id'=>'ship']) ?>
    <?= Html::hiddenInput('qty', $qty, ['id'=>'qty']) ?>
    <?= Html::hiddenInput('subtotal', $subtotal, ['id'=>'subtotal']) ?>

    <?= Html::submitButton('Checkout', ['class' => 'btn btn-primary']) ?>
<?php ActiveForm::end(); ?>

In your controller file, please add the ajax validation code in your controller before inserting into database. Below is the example ajax validation code for validating from server side.

Controller:

public function actionYourActionName(){
   $model = new YourModelClass();
   if ($model->load(Yii::$app->request->post())) {
        if (Yii::$app->request->isAjax) {
           Yii::$app->response->format = yii\web\Response::FORMAT_JSON;
           return ActiveForm::validate($model);
        }

        if($model->save())){
           //after successful save if you want to do any thing those codes will goes here.
        }
   }
   return $this->render('your-view-file-name', ['model' => $model]);
}

Model:

<?php
namespace app\models;
use yii;
use yii\db\ActiveRecord;

class YourModelClass extends ActiveRecord
{

...
public function rules(){
    return [
      [['id', 'discount', 'ship', 'qty', 'subtotal'], 'safe'],
      [['country', 'code'], 'required']
    ];
...
}
?>
Manikandan S
  • 902
  • 1
  • 8
  • 18
  • must create a form model?then i have to change all my html field to form field? Sorry that I just start yii framework within a week. – Ying Rui Wong Oct 23 '16 at 08:03
  • @YingRuiWong Yes you have to create model for that form and have to change the form into form fields using **ActiveForm**. This will make your job more easier. – Manikandan S Oct 23 '16 at 08:06
  • and my js will put in form model or in the else clause there? – Ying Rui Wong Oct 23 '16 at 11:02
  • well, I am totally no idea how can onclick and onchange can make it in the controller, can you give more details? – Ying Rui Wong Oct 23 '16 at 11:15
  • @YingRuiWong I edited my answer with more info related to ajax validation. ajax validation will work each field cursor onblur event. Validation will happen based on your model rules. Please let me know if you have any doubt. – Manikandan S Oct 24 '16 at 15:52