BeforeSave CakePHP 数学

Posted

技术标签:

【中文标题】BeforeSave CakePHP 数学【英文标题】:BeforeSave CakePHP Math 【发布时间】:2011-12-02 23:54:03 【问题描述】:

我正在尝试获取用户通过我的表单提交的数据,或者什么都不做,除以 100,或者乘以 1,000,000,具体取决于字段。

我在编写可以成功执行此操作的 beforeSave() 函数时遇到问题。当我禁用验证时,数据会提交,但我打算进行的数学运算并没有发生。

我这样做的原因是,如果用户输入 2.16 的 2.16%,我们希望将其存储为 0.0216。提交表单后,这只是基本的数学运算,在我的一生中,我无法让它工作。

任何建议将不胜感激。没有找到关于这个主题的任何好的教程,所以如果有人知道任何会很棒的东西。

这是我从提交中获得的原始数据数组:

Array
(
    [Subfirmdetail] => Array
        (
            [subfirm_id] => 4
            [subfirmdetailtype_id] => 55
            [value] => 20
            [date] => 2011-12-02
            [active] => yes
            [modified] => 2011-12-02 19:00:06
            [created] => 2011-12-02 19:00:06
        )

)
Array
(
    [Subfirmdetail] => Array
        (
            [subfirm_id] => 4
            [subfirmdetailtype_id] => 56
            [value] => 20
            [date] => 2011-12-02
            [active] => yes
            [modified] => 2011-12-02 19:00:06
            [created] => 2011-12-02 19:00:06
        )

)
Array
(
    [Subfirmdetail] => Array
        (
            [subfirm_id] => 4
            [subfirmdetailtype_id] => 57
            [value] => 20
            [date] => 2011-12-02
            [active] => yes
            [modified] => 2011-12-02 19:00:06
            [created] => 2011-12-02 19:00:06
        )

)
Array
(
    [Subfirmdetail] => Array
        (
            [subfirm_id] => 4
            [subfirmdetailtype_id] => 58
            [value] => 20
            [date] => 2011-12-02
            [active] => yes
            [modified] => 2011-12-02 19:00:06
            [created] => 2011-12-02 19:00:06
        )

)
Array
(
    [Subfirmdetail] => Array
        (
            [subfirm_id] => 4
            [subfirmdetailtype_id] => 59
            [value] => 20
            [date] => 2011-12-02
            [active] => yes
            [modified] => 2011-12-02 19:00:06
            [created] => 2011-12-02 19:00:06
        )

)

这是我的 beforeSave 函数:

function beforeSave() 
        switch($this->data['Subfirmdetailtype']['calculation']) 
            case 0:
                $this->data['Subfirmdetail']['value'] = $this->data['Subfirmdetail']['value'];
                break;
            case 1:
                $this->data['Subfirmdetail']['value'] = $this->divide($this->data['Subfirmdetail']['value']);
                break;
            case 2:
                $this->data['Subfirmdetail']['value'] = $this->multiply($this->data['Subfirmdetail']['value']);
                break;
        
        pr($this->data);

        return true;
    

最后是我的 add.ctp

    <div class="subfirmdetails form">
<?php echo $this->Form->create('Subfirmdetail', array('name' => 'subfirmdetail'));?>
    <fieldset>
        <legend><?php __('Add Subfirmdetails'); ?></legend>
    <?php if(!empty($this->params['named']))  ?>    
    <div class="span-7" style="text-align: left;">
    <?php
                //asset allocation entry section
                echo "<b><u><h3>Asset Allocation</h3></u></b>\n";
                $num = 0;
                foreach($allocations as $allocation) 
                    echo "<b>" . $allocation['Subfirmdetailtype']['description'] . "</b><br>\n";
                    echo $form->hidden('Subfirmdetail.' . $num . '.subfirm_id', array('value' => $this->params['named']['subfirm_id'])) . "\n";
                    echo $this->Form->hidden('Subfirmdetail.' . $num . '.subfirmdetailtype_id', array('value' => $allocation['Subfirmdetailtype']['id'])) . "\n";
                    echo $this->Form->input('Subfirmdetail.' . $num . '.value', array('class' => 'quantity', 'label' => '', 'onblur' => 'calculateTotal();', 'onkeydown' => 'ForceNumericInput(this, true, true)')) . "\n";
                    echo $this->Form->hidden('Subfirmdetail.' . $num . '.date', array('value' => date("Y-m-d"))) . "\n";
                    echo $this->Form->hidden('Subfirmdetail.' . $num . '.active', array('value' => 'yes')) . "\n";
                    echo $this->Form->hidden('Subfirmdetailtype.' . $num . '.calculation') . "\n";
                    $num++; 
                
                echo "<b>Total * (must equal 100%)</b>" . $this->Form->input('total', array('label' => '', 'id' => 'total_quantity', 'value' => 0, 'disabled' => 'disabled'));
    ?>
    </div>
    <div class="span-8">

        <?php
                //asset allocation entry section
                echo "<b><u><h3>General Statistics</h3></u></b>\n";
                //pr($generals);
                foreach($generals as $general) 
                    echo "<b>" . $general['Subfirmdetailtype']['description'] . "</b><br>\n";
                    echo $form->hidden('Subfirmdetail.' . $num . '.subfirm_id', array('value' => $this->params['named']['subfirm_id'])) . "\n";
                    echo $this->Form->hidden('Subfirmdetail.' . $num . '.subfirmdetailtype_id', array('value' => $general['Subfirmdetailtype']['id'])) . "\n";
                    if($general['Datatype']['name'] == "select") 
                        echo $this->Form->input('Subfirmdetail.' . $num . '.value', array('label' => '', 'options' => $options[$general['Subfirmdetailtype']['id']]));
                     else 
                        echo $this->Form->input('Subfirmdetail.' . $num . '.value', array('label' => ''));
                    
                    echo $this->Form->hidden('Subfirmdetail.' . $num . '.date', array('value' => date("Y-m-d"))) . "\n";
                    echo $this->Form->hidden('Subfirmdetail.' . $num . '.active', array('value' => 'yes')) . "\n";
                    echo $this->Form->hidden('Subfirmdetailtype.' . $num . '.calculation') . "\n";
                    $num++;
                
    ?>

    </div>

    <div class="span-8 last">
        <?php
                //asset allocation entry section
                echo "<b><u><h3>Returns</h3></u></b>\n";
                foreach($returns as $return) 
                    echo "<b>" . $return['Subfirmdetailtype']['description'] . "</b><br>\n";
                    echo $form->hidden('Subfirmdetail.' . $num . '.subfirm_id', array('value' => $this->params['named']['subfirm_id'])) . "\n";
                    echo $this->Form->hidden('Subfirmdetail.' . $num . '.subfirmdetailtype_id', array('value' => $return['Subfirmdetailtype']['id'])) . "\n";
                    echo $this->Form->input('Subfirmdetail.' . $num . '.value', array('label' => '', 'onkeydown' => 'ForceNumericInput(this, true, true)')) . "\n";
                    echo $this->Form->hidden('Subfirmdetail.' . $num . '.date', array('value' => date("Y-m-d"))) . "\n";
                    echo $this->Form->hidden('Subfirmdetail.' . $num . '.active', array('value' => 'yes')) . "\n";
                    echo $this->Form->hidden('Subfirmdetailtype.' . $num . '.calculation') . "\n";
                    $num++;
                
    ?>
    </div>

    <div class="span-8" style="margin-top: 25px;">
    <?php
                //asset allocation entry section
                echo "<b><u><h3>Volatility</h3></u></b>\n";
                foreach($volatilities as $volatility) 
                    echo "<b>" . $volatility['Subfirmdetailtype']['description'] . "</b><br>\n";
                    echo $form->hidden('Subfirmdetail.' . $num . '.subfirm_id', array('value' => $this->params['named']['subfirm_id'])) . "\n";
                    echo $this->Form->hidden('Subfirmdetail.' . $num . '.subfirmdetailtype_id', array('value' => $volatility['Subfirmdetailtype']['id'])) . "\n";
                    echo $this->Form->input('Subfirmdetail.' . $num . '.value', array('label' => '', 'onkeydown' => 'ForceNumericInput(this, true, true)')) . "\n";
                    echo $this->Form->hidden('Subfirmdetail.' . $num . '.date', array('value' => date("Y-m-d"))) . "\n";
                    echo $this->Form->hidden('Subfirmdetail.' . $num . '.active', array('value' => 'yes')) . "\n";
                    echo $this->Form->hidden('Subfirmdetailtype.' . $num . '.calculation') . "\n";
                    $num++;
                
    ?>
    </div>
    <div class="span-7 last" style="margin-top: 25px;">

        <?php
                //asset allocation entry section
                echo "<b><u><h3>Upside/Downside</h3></u></b>\n";
                foreach($upsidedownsides as $upsidedownside) 
                    echo "<b>" . $upsidedownside['Subfirmdetailtype']['description'] . "</b><br>\n";
                    echo $form->hidden('Subfirmdetail.' . $num . '.subfirm_id', array('value' => $this->params['named']['subfirm_id'])) . "\n";
                    echo $this->Form->hidden('Subfirmdetail.' . $num . '.subfirmdetailtype_id', array('value' => $upsidedownside['Subfirmdetailtype']['id'])) . "\n";
                    echo $this->Form->input('Subfirmdetail.' . $num . '.value', array('label' => '', 'onkeydown' => 'ForceNumericInput(this, true, true)')) . "\n";
                    echo $this->Form->hidden('Subfirmdetail.' . $num . '.date', array('value' => date("Y-m-d"))) . "\n";
                    echo $this->Form->hidden('Subfirmdetail.' . $num . '.active', array('value' => 'yes')) . "\n";
                    echo $this->Form->hidden('Subfirmdetailtype.' . $num . '.calculation') . "\n";
                    $num++;
                
    ?>

    </div>


    </fieldset>
    <?php echo $this->Form->end(__('Submit', true));?>
    </div>

     <?php  else 
        echo "Sorry, you have not come from an appropriate subfirm page to add these details.  Please visit a subfirm page before adding data.";
      //pr($generals); ?>

</div>

<script language="javascript">
    //function to convert percentages entered in by users (e.g. 20% to 0.20)
    function calculateTotal() 
        var total = 0;
        <?php $num = 0; ?>
        $(".quantity").each(function() 
            if (!isNaN(this.value) && this.value.length != 0) 
                total += parseFloat(this.value);
            
        ); 

        total = total;

        if (total != 100) 
            total = total + "% - Sorry, total must equal 100%";
            $("#total_quantity").val(total);
         else 
            total = total + "%";
            $("#total_quantity").val(total);
        

    

    //function to force returns inputs to be numbers between 1 - 100

</script>

【问题讨论】:

刚刚添加,抱歉! divide()multiply() 函数中发生了什么? 【参考方案1】:

您确定 switch 语句正确执行吗?我在您的代码示例中的任何地方都没有看到对此数据的引用,但您在 switch 中调用它。

$this->data['Subfirmdetailtype']['calculation']

我建议把这些放在通篇中,看看你会遇到什么情况:

debug('Hello case n'); 
die;

【讨论】:

【参考方案2】:

这就是我最终使用的。必须对我的模型进行一些更改,并将数据拉入适当的部分。如果有人需要做类似的事情......我会在这里提供帮助。

function divide($number) 
            return $number / 100;
        

        function multiply($number) 
            return $number * 1000000;
        

        function beforeSave() 
            switch($this->data['Subfirmdetail']['calculation']) 
                case "divide":
                    $this->data['Subfirmdetail']['value'] = $this->divide($this->data['Subfirmdetail']['value']);
                    break;
                case "multiply":
                    $this->data['Subfirmdetail']['value'] = $this->multiply($this->data['Subfirmdetail']['value']);
                    break;
                case "none":
                default:
                    $this->data['Subfirmdetail']['value'] = $this->data['Subfirmdetail']['value'];
                    break;
            

            return true;
        

【讨论】:

以上是关于BeforeSave CakePHP 数学的主要内容,如果未能解决你的问题,请参考以下文章

CakePHP beforeSave false 防止不刷新就提交

CakePHP 3 - beforeSave 回调在编辑时不起作用

有没有办法在 cakePHP 中将数据从 beforeSave() 传递到 afterSave()?

Cakephp 的 beforeSave() 不使用 $model::save() 保留新数据

CakePHP 数据在验证期间发生更改,并且 beforeSave 未随更改一起保存

调用未定义的方法 Cake\ORM\Entity::query() CakePhp