SUBSCRIBE VIA RSS


Subscribe to our feed

Symfony Experts

Symfony Experts
If you have an urgent question for a symfony-related issue, this is the place to ask.

Topics

TWITTER

Stack Overflow


The old fashioned way

RECENT TUNES

March 14, 2009 – 2:46pm Symfony Propel Enum types

Propel does not support enum column types in its schemas, since the enum type is not support across all database types. There are a few ways around this.

1) Use another table to list the enum options. Pros: most flexible. Works nicely within symfony. Cons: means more joins in your queries.

2) Use enum anyway. You can add custom column types using a little known trick in your schema:

status:
  id:
  name: { type: varchar, sqltype:enum, size: "'inactive','active'", default: inactive }

Pros: You get your enum. Cons: Not very portable, a bit of a hack.

3) Simulate an enum column using your model. I typically end up doing this for columns that have a finite number of defined options *that will not change*. Pros: Fast. Cons: Not as flexible as optino 1. Example:


class UserProfilePeer extends BaseUserProfilePeer
{
  static protected $USER_TYPE_INTEGERS = array('student', 'supervisor', 'coordinator', 'researcher', 'admin');
  static protected $USER_TYPE_VALUES = null;

  /**
   * Returns a user type label from an index value.
   *
   * @param integer $index
   * @return string user type label
   * @author Scott Meves
   */
  static public function getUserTypeFromIndex($index)
  {
    return self::$USER_TYPE_INTEGERS[$index];
  }

  /**
   * Returns the user type index from a string value
   *
   * @param string $value
   * @return integer $index
   * @author Scott Meves
   */
  static public function getUserTypeFromValue($value)
  {
    if (!self::$USER_TYPE_VALUES)
    {
      self::$USER_TYPE_VALUES = array_flip(self::$USER_TYPE_INTEGERS);
    }

    $values = strtolower($value);

    if (!isset(self::$USER_TYPE_VALUES[$value]))
    {
      throw new PropelException(sprintf('User type cannot take "%s" as a value', $value));
    }

    return self::$USER_TYPE_VALUES[strtolower($value)];
  }

  public static function getUserTypeOptions()
  {
    return self::$USER_TYPE_INTEGERS;
  }
}
Posted in  Uncategorized   |     |  delicious  Digg

4 Responses to “Symfony Propel Enum types”

  1. Scott, curious why you wouldn’t use constants? You write you pull the last trick for “a finite number of defined options *that will not change*.”

    But then you put them in an array:

    static protected $USER_TYPE_INTEGERS = array(’student’, ’supervisor’, ‘coordinator’, ‘researcher’, ‘admin’);

    I like how fast and flexible this is. But wouldn’t constants better suggest that the intent was a fixed, unchanging, limited set? PHP arrays seem very flexible to me, even if you do apply the “protected” keyword. Seems like the only time I’d want to imitate an ENUM is when I wanted something that was not flexible.

    By Lawrence Krubner on Jun 6, 2009

  2. @lawrence, I don’t use constants in this case because I wanted to have my user types stored in an array, and php doesn’t support “constant” arrays.

    By Scott Meves on Jun 6, 2009

  3. It’s too bad that not all DB support enum data types, but it’s nice to have at least some options to implement this.
    A few weeks ago I was trying to use enum, but at the end I decided to go for the adding table option.
    Perhaps the best possible solution yet is to simulate it like in this post.

    By Jorge Chávez on Aug 19, 2009

  4. class Section extends BaseSection
    {
      const TYPE_LIST      = 'list'
           ,TYPE_LINK      = 'link'
           ,TYPE_PAGE      = 'page'
           ,TYPE_VOTE      = 'vote'
           ,TYPE_AUTHORS   = 'authors'
     
    // add new above this line
            ;
      static public function getValidTypesAsArray($context = null)
      {
        $results = array();
        $ext = new ReflectionClass('Section');
        $constants = $ext->getConstants();
        foreach($constants as $name => $value)
        {
          if (!strncmp($name,'TYPE_',5))
          {
            // i18n translation
            $results[$value] = myTools::__($value);
          }
        }
        if($context)
        {
          $event = new sfEvent($this, 'section.update_valid_types');
          $context->dispatcher->filter($event, $results);
          $results = $event->getReturnValue();
        }
     
        return $results;
      }
    }

    By ksn135 on Sep 15, 2009

Post a Comment

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word