Completed
Branch FET-11170-model-use-money-enti... (303cb4)
by
unknown
68:01 queued 57:04
created

EE_Money_Field::ensureMoney()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
use EventEspresso\core\domain\values\currency\Money;
4
use EventEspresso\core\services\currency\MoneyFactory;
5
use EventEspresso\core\services\currency\formatters\MoneyFormatter;
6
use EventEspresso\core\services\loaders\LoaderFactory;
7
8
defined('EVENT_ESPRESSO_VERSION') || exit;
9
10
/**
11
 * EE_Money_Field
12
 * Model field for dealing with money amounts. Originally this accepted and returns float
13
 * values, but now it also deals in Money entities.
14
 */
15
class EE_Money_Field extends EE_Float_Field
16
{
17
18
    /**
19
     * @var $money_factory MoneyFactory
20
     */
21
    protected $money_factory;
22
23
24
25
    /**
26
     * @param string       $table_column
27
     * @param string       $nicename
28
     * @param bool         $nullable
29
     * @param null         $default_value
30
     * @param MoneyFactory $factory
31
     * @throws \InvalidArgumentException
32
     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
33
     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
34
     */
35
    public function __construct(
36
        $table_column,
37
        $nicename,
38
        $nullable,
39
        $default_value = null,
40
        MoneyFactory $factory = null
41
    ) {
42
        if (! $factory instanceof MoneyFactory) {
43
            $factory = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\currency\MoneyFactory');
44
        }
45
        $this->money_factory = $factory;
46
        parent::__construct($table_column, $nicename, $nullable, $default_value);
47
        $this->setSchemaType('object');
48
    }
49
50
51
52
    /**
53
     * Schemas:
54
     *    'localized_float': "3,023.00"
55
     *    'no_currency_code': "$3,023.00"
56
     *    null: "$3,023.00<span>USD</span>"
57
     *
58
     * @param string|Money $value_on_field_to_be_outputted
59
     * @param string       $schema
60
     * @return string
61
     * @throws \EE_Error
62
     */
63
    public function prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema = null)
64
    {
65
        //has someone hooked into the old currency formatter helper's filters?
66
        //if so, we had better stick with it
67
        if (apply_filters(
68
            'FHEE__EE_Money_Field__prpeare_for_pretty_echoing',
69
            has_filter('FHEE__EEH_Template__format_currency__raw_amount')
70
            || has_filter('FHEE__EEH_Template__format_currency__CNT_ISO')
71
            || has_filter('FHEE__EEH_Template__format_currency__amount')
72
            || has_filter('FHEE__EEH_Template__format_currency__display_code')
73
            || has_filter('FHEE__EEH_Template__format_currency__amount_formatted'),
74
            $this
75
        )) {
76
            $pretty_float = parent::prepare_for_pretty_echoing($value_on_field_to_be_outputted);
77
78
            if ($schema === 'localized_float') {
79
                return $pretty_float;
80
            }
81
            if ($schema === 'no_currency_code') {
82
                //			echo "schema no currency!";
83
                $display_code = false;
84
            } else {
85
                $display_code = true;
86
            }
87
            //we don't use the $pretty_float because format_currency will take care of it.
88
            return EEH_Template::format_currency($value_on_field_to_be_outputted, false, $display_code);
89
        }
90
        //ok let's just use the new formatting code then
91
        switch ($schema) {
92
            case MoneyFormatter::ADD_CURRENCY_CODE:
93
                $formatting_level = MoneyFormatter::ADD_CURRENCY_CODE;
94
                break;
95
            case 'no_currency_code':
96
            case MoneyFormatter::ADD_CURRENCY_SIGN:
97
                $formatting_level = MoneyFormatter::ADD_CURRENCY_SIGN;
98
                break;
99
            case MoneyFormatter::ADD_THOUSANDS:
100
            case 'localized_float':
101
                $formatting_level = MoneyFormatter::ADD_THOUSANDS;
102
                break;
103
            case MoneyFormatter::DECIMAL_ONLY:
104
                $formatting_level = MoneyFormatter::DECIMAL_ONLY;
105
                break;
106
            default:
107
                $formatting_level = MoneyFormatter::INTERNATIONAL;
108
        }
109
        $value_on_field_to_be_outputted = $this->ensureMoney($value_on_field_to_be_outputted);
110
        return $value_on_field_to_be_outputted->format($formatting_level);
111
    }
112
113
114
115
    /**
116
     * Make sure this value is a money object
117
     *
118
     * @param string|float|int|Money $value
119
     * @return Money
120
     * @throws \InvalidArgumentException
121
     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
122
     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
123
     * @throws \EE_Error
124
     */
125
    private function ensureMoney($value)
126
    {
127
        if (! $value instanceof Money) {
128
            return $this->money_factory->createForSite($value);
129
        }
130
        return $value;
131
    }
132
133
134
135
    /**
136
     * Ensures we're dealing with something that isn't Money
137
     * (for passing off to legacy systems or the parent field)
138
     * @param  string|float|int|Money $value
139
     * @return string|float|int
140
     */
141
    private function ensureNotMoney($value)
142
    {
143
        if( $value instanceof Money) {
144
            return $value->amount();
145
        }
146
        return $value;
147
    }
148
149
    /**
150
     * If provided with a string, strips out money-related formatting to turn it into a proper float.
151
     * Rounds the float to the correct number of decimal places for this country's currency.
152
     * Also, interprets periods and commas according to the country's currency settings.
153
     * So if you want to pass in a string that NEEDS to interpret periods as decimal marks, call floatval() on it first.
154
     *
155
     * @param string|Money $value_inputted_for_field_on_model_object
156
     * @return Money
157
     */
158
    public function prepare_for_set($value_inputted_for_field_on_model_object)
159
    {
160
        if ($value_inputted_for_field_on_model_object instanceof Money) {
161
            return $value_inputted_for_field_on_model_object;
162
        }
163
        //now it's a float-style string or number
164
        return $this->ensureMoney(
165
            parent::prepare_for_set($value_inputted_for_field_on_model_object)
166
        );
167
    }
168
169
170
171
    /**
172
     * @param string|float|int|Money $value_of_field_on_model_object
173
     * @return float
174
     * @throws \InvalidArgumentException
175
     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
176
     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
177
     */
178
    public function prepare_for_get($value_of_field_on_model_object)
179
    {
180
        $value_of_field_on_model_object = $this->ensureNotMoney($value_of_field_on_model_object);
181
        $c = EE_Registry::instance()->CFG->currency;
182
        return round(parent::prepare_for_get($value_of_field_on_model_object), $c->dec_plc);
183
    }
184
185
186
187
    /**
188
     * Takes the incoming float and create a money entity for the model object
189
     *
190
     * @param mixed $value_found_in_db_for_model_object
191
     * @return Money
192
     * @throws \InvalidArgumentException
193
     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
194
     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
195
     * @throws \EE_Error
196
     */
197
    public function prepare_for_set_from_db($value_found_in_db_for_model_object)
198
    {
199
        return $this->money_factory->createForSite($value_found_in_db_for_model_object);
200
    }
201
202
203
204
    /**
205
     * Prepares a value for use in the DB
206
     * @param string|float|int|Money $value_of_field_on_model_object
207
     * @return float
208
     */
209
    public function prepare_for_use_in_db($value_of_field_on_model_object)
210
    {
211
        $value_of_field_on_model_object = $this->ensureNotMoney($value_of_field_on_model_object);
212
        return parent::prepare_for_use_in_db($value_of_field_on_model_object);
213
    }
214
215
216
217 View Code Duplication
    public function getSchemaProperties()
218
    {
219
        return array(
220
            'raw' => array(
221
                'description' =>  sprintf(
222
                    __('%s - the raw value as it exists in the database as a simple float.', 'event_espresso'),
223
                    $this->get_nicename()
224
                ),
225
                'type' => 'number'
226
            ),
227
            'pretty' => array(
228
                'description' =>  sprintf(
229
                    __('%s - formatted for display in the set currency and decimal places.', 'event_espresso'),
230
                    $this->get_nicename()
231
                ),
232
                'type' => 'string'
233
            )
234
        );
235
    }
236
}