<commit_before><?php

namespace DoctrineMoneyModule\Form;

use InvalidArgumentException;
use Exception;
use Zend\Form\Fieldset;
use Zend\Form\Element\Number;
use Zend\Form\Element\Text;
use Money\Money as MoneyValueObject;
use Money\Currency as CurrencyValueObject;
use DoctrineMoneyModule\Hydrator\MoneyHydrator;
use Zend\InputFilter\InputFilterProviderInterface;
use Zend\I18n\Filter\NumberFormat;

/**
 * Money form element that will make it very easy to work with money and currencies
 *
 * @author <NAME> <<EMAIL>>
 * @license MIT
 */
class Money extends Fieldset implements InputFilterProviderInterface
{
    protected $currency;

    public function init()
    {
        $this->setHydrator(new MoneyHydrator());
        $this->setObject(MoneyValueObject::BRL(0));

        parent::add([
            'type' => Number::class,
            'name' => 'amount',
            'options' => [
                'label' => 'Amount'
            ],
            'attributes' => [
                'step' => '0.01',
            ]
        ]);

        parent::add([
            'type' => Text::class,
            'name' => 'currency',
            'options' => [
                'label' => 'Currency'
            ]
        ]);
    }

    public function getCurrency()
    {
        if (null === $this->currency) {
            $this->currency = new CurrencyValueObject("USD");
        }

        return $this->currency;
    }

    public function setCurrency($currency)
    {
        $this->currency = new CurrencyValueObject($currency);
    }

    public function add($elementOrFieldset, array $flags = array())
    {
        throw new Exception('You can\'t add elements to money fieldset');
    }

    public function extract()
    {
        $data = parent::extract();
        $data['amount'] = money_format("%.2n", $data['amount']/100);
        return $data;
    }

    public function bindValues(array $values = array())
    {
        try {
            $values['amount'] = MoneyValueObject::stringToUnits($values['amount']);
        } catch (Exception $e) {
            throw new InvalidArgumentException(sprintf(
                '%s expects an parsable string or integer in amount index, "%s" given',
                __METHOD__,
                is_object($values['amount']) ? get_class($values['amount']) : gettype($values['amount'])
            ));
        }

        if (isset($values['currency'])) {
            $this->setCurrency($values['currency']);
        }

        return parent::bindValues($values);
    }

    public function getInputFilterSpecification()
    {
        return [
            [
                'name' => 'amount',
                'filters' => [
                    [
                        'name' => NumberFormat::class
                    ]
                ]
            ]
        ];
    }
}<commit_msg>Using currency as Select instead of Text input<commit_after><?php

namespace ZFBrasil\DoctrineMoneyModule\Form;

use ZFBrasil\DoctrineMoneyModule\Exception\BadMethodCallException;
use Zend\Filter\StringToUpper;
use Zend\Form\Fieldset;
use Zend\Form\Element\Number;
use Money\Money as MoneyValueObject;
use Money\Currency as CurrencyValueObject;
use ZFBrasil\DoctrineMoneyModule\Form\Element\CurrencySelect;
use ZFBrasil\DoctrineMoneyModule\Hydrator\MoneyHydrator;
use Zend\InputFilter\InputFilterProviderInterface;
use Zend\I18n\Filter\NumberFormat;
use Zend\Validator\NotEmpty;

/**
 * Money form element that will make it very easy to work with money and currencies
 *
 * @author <NAME> <<EMAIL>>
 * @license MIT
 */
class Money extends Fieldset implements InputFilterProviderInterface
{
    /**
     * @var CurrencyValueObject|null
     */
    protected $currency;

    /**
     * {@inheritDoc}
     */
    public function init()
    {
        $this->setHydrator(new MoneyHydrator());
        $this->setObject(MoneyValueObject::BRL(0));

        parent::add([
            'type' => Number::class,
            'name' => 'amount',
            'options' => [
                'label' => 'Amount'
            ],
            'attributes' => [
                'step' => '0.01',
            ]
        ]);

        parent::add([
            'type' => CurrencySelect::class,
            'name' => 'currency',
            'options' => [
                'label' => 'Currency'
            ]
        ]);
    }

    /**
     * @return CurrencyValueObject
     */
    public function getCurrency()
    {
        if (null === $this->currency) {
            $this->currency = new CurrencyValueObject("USD");
        }

        return $this->currency;
    }

    /**
     * @param string $currency
     */
    public function setCurrency($currency)
    {
        $this->currency = new CurrencyValueObject($currency);
    }

    /**
     * {@inheritDoc}
     *
     * @throws BadMethodCallException
     */
    public function add($elementOrFieldset, array $flags = [])
    {
        throw new BadMethodCallException('You can\'t add elements to money fieldset');
    }

    /**
     * {@inheritDoc}
     */
    public function extract()
    {
        $data = parent::extract();
        $data['amount'] = money_format("%.2n", $data['amount'] / 100);

        return $data;
    }

    /**
     * {@inheritDoc}
     */
    public function bindValues(array $values = [])
    {
        $values['amount'] = MoneyValueObject::stringToUnits($values['amount']);

        if (isset($values['currency'])) {
            $this->setCurrency($values['currency']);
        }

        return parent::bindValues($values);
    }

    /**
     * {@inheritDoc}
     */
    public function getInputFilterSpecification()
    {
        return [
            [
                'name' => 'amount',
                'required' => true,
                'filters' => [
                    ['name' => NumberFormat::class]
                ],
                'validators' => [
                    ['name' => NotEmpty::class]
                ]
            ],
            [
                'name' => 'currency',
                'required' => true,
                'filters' => [
                    ['name' => StringToUpper::class]
                ],
                'validators' => [
                    ['name' => NotEmpty::class]
                ]
            ]
        ];
    }
}
{'fraction_non_alphanumeric': 0.1359347513193667, 'fraction_numerical': 0.0031984647369262755, 'mean_word_length': 1.831145314622001, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 58, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2803762', 'n_tokens_mistral': 1758, 'n_tokens_neox': 1678, 'n_words': 346}