We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Number Format

Hello, my English is very bad. Sorry :)

I would like to form element input = 1.234,56 (thousands of marks = '.' and decimal point = ',') Save the input in the database in format = 1234.56 (decimal point = '.')

And Read from databse to form output = 1.234,56 (thousands of marks = '.' and decimal point = ',')

Thanks in advance Pet



2.9k

Ok, i know that already.

How does it work with filters?

Pet

My example with volt:

Part of services.php:

/*
 * Read configuration
 */
$config = include __DIR__.'/config/config.php';

/*
 * Setting up the view component
 */
$di->set('view', function () use ($config) {
    $view = new View();
    $view->setViewsDir($config->module->loader->views);
    $view->registerEngines(array(
        '.volt' => function ($view, $di) use ($config) {
            $volt = new Volt($view, $di);
            $volt->setOptions(array(
                'compiledPath' => __DIR__.'/../../cache/',
                'compiledSeparator' => '_',
                'compileAlways' => true,
            ));
            $compiler = $volt->getCompiler();
            $compiler->addFunction('number_format', function ($resolvedArgs, $exprArgs) use ($compiler) {
                $firstArgument = $compiler->expression($exprArgs[0]['expr']);
                return 'number_format('.$firstArgument.", 2, '.', ' ')";
            });
            return $volt;
        },
        '.phtml' => 'Phalcon\Mvc\View\Engine\Php',
    ));
    return $view;
}, true);

Usage in volt:

{{ number_format(price) }}


12.2k

The question is actually very good and tricky to solve. One can use ',' as a decimal separator or '.' (especially when coming from the form input). So you can't use float filter if one uses ',' as a separator.

My best solution was to create a filter:


/**
 * Class Comma2Dot
 *
 * Converts decimals with dots or commas to correct float value without
 * thousand separator.
 * Correct float value = (float) [int].[decimals]
 *
 * @package App\Filter
 */
class Comma2Dot
{
    public function filter($value)
    {
        if(null == $value) {
            return null;
        }

        $dotPos   = strrpos($value, '.');
        $commaPos = strrpos($value, ',');
        $sep      = (($dotPos > $commaPos) && $dotPos)
            ? $dotPos
            : ((($commaPos > $dotPos) && $commaPos)
                ? $commaPos
                : false);

        if(!$sep) {
            return floatval(preg_replace("/[^0-9]/", "", $value));
        }

        return (float)
        preg_replace("/[^0-9]/", "", substr($value, 0, $sep)) .
        '.' .
        preg_replace("/[^0-9]/", "", substr($value, $sep + 1, strlen($value)));
    }
}

And then use this to filter form elements (type=number or type=text). You will get a number suitable for database input.



43.9k

Thanks for sharing: Piotr Woszczyk and mraspor



2.1k

this code really works thank you

My example with volt:

Part of services.php:

/*
* Read configuration
*/
$config = include __DIR__.'/config/config.php';

/*
* Setting up the view component
*/
$di->set('view', function () use ($config) {
  $view = new View();
  $view->setViewsDir($config->module->loader->views);
  $view->registerEngines(array(
      '.volt' => function ($view, $di) use ($config) {
          $volt = new Volt($view, $di);
          $volt->setOptions(array(
              'compiledPath' => __DIR__.'/../../cache/',
              'compiledSeparator' => '_',
              'compileAlways' => true,
          ));
          $compiler = $volt->getCompiler();
          $compiler->addFunction('number_format', function ($resolvedArgs, $exprArgs) use ($compiler) {
              $firstArgument = $compiler->expression($exprArgs[0]['expr']);
              return 'number_format('.$firstArgument.", 2, '.', ' ')";
          });
          return $volt;
      },
      '.phtml' => 'Phalcon\Mvc\View\Engine\Php',
  ));
  return $view;
}, true);

Usage in volt:

{{ number_format(price) }}


105
edited Apr '20

Hello Friend,

This function is exactly what I need. Follow the instructions, but when I tested it didn't work. The message appeared: Macro 'number_format' does not exist.

If you can help me I would be very grateful. This is my tested code:


use Phalcon\Mvc\View;
use Phalcon\Mvc\View\Engine\Php as PhpEngine;
use Phalcon\Mvc\Url as UrlResolver;
use Phalcon\Mvc\View\Engine\Volt as VoltEngine;
use Phalcon\Mvc\Model\Metadata\Memory as MetaDataAdapter;
use Phalcon\Session\Adapter\Files as SessionAdapter;
use Phalcon\Flash\Direct as Flash;

/**
 * Shared configuration service
 */
$di->setShared('config', function () {
    return include APP_PATH . "/config/config.php";
});

/**
 * The URL component is used to generate all kind of urls in the application
 */
$di->setShared('url', function () {
    $config = $this->getConfig();

    $url = new UrlResolver();
    $url->setBaseUri($config->application->baseUri);

    return $url;
});

/**
 * Setting up the view component
 */
$di->setShared('view', function () {
    $config = $this->getConfig();

    $view = new View();
    $view->setDI($this);
    $view->setViewsDir($config->application->viewsDir);

    $view->registerEngines([
        '.volt' => function ($view) {
            $config = $this->getConfig();

            $volt = new VoltEngine($view, $this);

            $volt->setOptions([
                'compiledPath' => $config->application->cacheDir,
                'compiledSeparator' => '_'
            ]);

            return $volt;
        },
        '.phtml' => PhpEngine::class

    ]);

    return $view;
});

/**
 * Database connection is created based in the parameters defined in the configuration file
 */
$di->setShared('db', function () {
    $config = $this->getConfig();

    $class = 'Phalcon\Db\Adapter\Pdo\\' . $config->database->adapter;
    $params = [
        'host'     => $config->database->host,
        'username' => $config->database->username,
        'password' => $config->database->password,
        'dbname'   => $config->database->dbname,
        'charset'  => $config->database->charset
    ];

    if ($config->database->adapter == 'Postgresql') {
        unset($params['charset']);
    }

    $connection = new $class($params);

    return $connection;
});

/**
 * If the configuration specify the use of metadata adapter use it or use memory otherwise
 */
$di->setShared('modelsMetadata', function () {
    return new MetaDataAdapter();
});

/**
 * Register the session flash service with the Twitter Bootstrap classes
 */
$di->set('flash', function () {
    return new Flash([
        'error'   => 'alert alert-danger',
        'success' => 'alert alert-success',
        'notice'  => 'alert alert-info',
        'warning' => 'alert alert-warning'
    ]);
});

/**
 * Start the session the first time some component request the session service
 */
$di->setShared('session', function () {
    $session = new SessionAdapter();
    $session->start();

    return $session;
});

$di->set('view', function () use ($config) {
    $view = new View();
    $view->setViewsDir($config->module->loader->views);
    $view->registerEngines(array(
        '.volt' => function ($view, $di) use ($config) {
            $volt = new Volt($view, $di);
            $volt->setOptions(array(
                'compiledPath' => __DIR__.'/../../cache/',
                'compiledSeparator' => '_',
                'compileAlways' => true,
            ));
            $compiler = $volt->getCompiler();
            $compiler->addFunction('number_format', function ($resolvedArgs, $exprArgs) use ($compiler) {
                $firstArgument = $compiler->expression($exprArgs[0]['expr']);
                return 'number_format('.$firstArgument.", 2, '.', ' ')";
            });
            return $volt;
        },
        '.phtml' => 'Phalcon\Mvc\View\Engine\Php',
    ));
    return $view;
}, true);