1
\$\begingroup\$

We have a large number of defined constants that are used as enum values when storing records. We convert the int values into language for our web portals. This was very straightforward when only dealing with one language, but now are tasked with making the portals support multiple languages.

The functions doing the value to language are easy enough to change and I have a solution, but I was wondering if there wasn't a better way as what I've come up with involves a little too much copy/paste for my taste. What I can't change are how we define the constants/enums.

The language files are written in json as key/value pairs. Language::_($key) handles looking up the proper language files and returning the string.

Another thought I had was to do the lookup based off the constant's value, but I couldn't find a way to pass constant's name (ACTION_ACCOUNT_NEW) to Language::_($key); I believe constants are evaluated before execution. I also don't want to pass the constant's value (1024) to Language::_($key) as I believe that would make a json file that would be very difficult to read.

Would there be a better way of doing this that involves less cut/paste of the defined constant names?

define('ACTION_ACCOUNT_NEW', 1024);
define('ACTION_ACCOUNT_DELETE', 1025);

function ActionToString($action){

    $actions_map = array(
        ACTION_ACCOUNT_NEW => Language::_('ACTION_ACCOUNT_NEW'),
        ACTION_ACCOUNT_DELETE => Language::_('ACTION_ACCOUNT_DELETE')
    );

    return isset($actions_map[$action])
        ? $actions_map[$action]
        : Language::_('Unknown');
}

json

{
    "ACTION_ACCOUNT_NEW": "Account Created",
    "ACTION_ACCOUNT_DELETE": "Account Deleted",

    "Unknown": "Unknown"
}
\$\endgroup\$
  • \$\begingroup\$ You've two typos in your array declaration (; instead of ,). \$\endgroup\$ – Alix Axel Feb 25 '12 at 21:56
1
\$\begingroup\$

In all honesty, that seems a bit redundant... But since you can't change the constant values here it goes:

define('ACTION_ACCOUNT_NEW', 1024);
define('ACTION_ACCOUNT_DELETE', 1025);

function ActionToString($action)
{
    $actions_map = array();
    $defined_constants = get_defined_constants(true); // use true to get "user" key

    if (isset($defined_constants['user']))
    {
        $defined_constants = $defined_constants['user'];

        // only process constants that start with "ACTION_"
        $defined_constants = array_intersect_key($defined_constants, array_flip(preg_grep('~^ACTION_~i', array_keys($defined_constants))));

        foreach ($defined_constants as $key => $value)
        {
            $actions_map[$value] = Language::_($key);
        }

        return isset($actions_map[$action]) ? $actions_map[$action] : Language::_('Unknown');
    }

    return Language::_('Unknown');
}

It assumes you only want to parse constants that start with ACTION_, other than that it should work just fine (although, a bit slower due to the looping - still, you could probably fix it with static variables).

One other alternative would be to use class constants but I'm not sure if that option is available to you.

\$\endgroup\$
  • \$\begingroup\$ Thanks, I didn't find get_defined_constants in my original searches. I'll play around with your example and see how it works out of us. \$\endgroup\$ – Paul DelRe Feb 27 '12 at 15:40
  • \$\begingroup\$ Thanks for the lead on get_defined_constants. I was able to use it to reduce the occurrences of redundant strings. I still need to pass a list as there are some constant 'groups' that share a similar prefix and values. Next is to petition to start using class constants. \$\endgroup\$ – Paul DelRe Feb 29 '12 at 18:12
  • \$\begingroup\$ @PaulDelRe: No problem my friend, glad it made your life a bit easier. \$\endgroup\$ – Alix Axel Mar 1 '12 at 10:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.