Question

I have a model defined as follows:

class User extends ActiveRecord\Model {
  function get_name() {
    return $this->first_name . " " . $this->surname;
  }
}

however when I show $item->attributes(); then name doesn't appear. Am I being an idiot here? If so, how do I get my custom attributes into the model?

Thanks, Gareth

Était-ce utile?

La solution

Here's my simple solution. I've overriding the attributes method and adding any methods that start with "get_attribute_" so I can use them during serialization:

class BaseModel extends ActiveRecord\Model
{
    public function attributes()
    {
        $attrs = parent::attributes();
        $modelReflector = new ReflectionClass(get_class($this));
        $methods = $modelReflector->getMethods(~ReflectionMethod::IS_STATIC & ReflectionMethod::IS_PUBLIC);
        foreach ($methods as $method)
        {
            if (preg_match("/^get_attribute_/", $method->getName()))
            {
                $attrs[str_replace('get_attribute_', '', $method->getName())] = $method->invoke($this);
            }   
        }
        return $attrs;
    }
}

The resulting models that use this would look like this:

class User extends BaseModel
{
    public $loginSessionId;

    function get_attribute_loginSessionId(){
        return $this->loginSessionId;
    }
}

This way I can manually tack on the loginSessionId (or whatever else I want) and have it show up in the serialized values.

Autres conseils

The attributes() method will indeed return only the values for your model's table columns (not aliased).

But $item->name should give you the expected result. You can also add the setter.

To get an array of all the attributes, you can add this method to your model:

public function all_attributes() {
    $custom_attr = [];
    foreach (static::$getters as $getter) {
        $key = substr($getter, 4);
        $custom_attr[$key] = $this->$key;
    }
    return $custom_attr + $this->attributes();
}

(don't forget to add your getters to the $getters array, the ActiveRecord model will use it)

You have to check what the attributes function does. You might need to override it to take into account your custom attributes, or you might have to add your custom attributes to some _properties property in the ancestor

Can you show us how you created $item? PHPActiveRecord needs you to set the attributes in the constructor call (new User($attributes)) or directly on the properties ($user->first_name = 'Gareth').


EDIT

I'm not sure the attributes() method would pick up the custom getter. It seems that it just returns the attributes property of the model.

https://github.com/kla/php-activerecord/blob/master/lib/Model.php#L566

I solved this as follows:

Create a class that derives from ActiveRecord\Model and include this function:

public function properties()
{
  $attrs = $this->attributes();
  $modelReflector = new ReflectionClass(get_class($this));
  $methods = $modelReflector->getMethods(~ReflectionMethod::IS_STATIC & ReflectionMethod::IS_PUBLIC);
  foreach ($methods as $method)
  {
    if (preg_match("/^get_/", $method->getName()))
    {
      $attrs[str_replace('get_', '', $method->getName())] = $method->invoke($this);
    }
  }
  return $attrs;
}

This returns all of the attributes, custom or otherwise, as long as I derive my models from the right class (not ActiveRecord\Model).

Actually, it is easily implemented like this @ add this to https://github.com/kla/php-activerecord/blob/master/lib/Model.php#L520:

// check for attribute as getter
if ( method_exists( $this, "get_{$name}" ) ){
  $method = "get_{$name}";
  $var = $this->$method();
  return $var;
}

But I prefer to do it like this (cleaner/optimized code) :

SomeModel.php:

  /** 
   * gets templatefile of outputplugin, wrapper function for template comfortability 
   * 
   * NOTE 2: never implement functions in model, try redirecting
   * to manager class (=lowmemory footprint, imagine xxxxx models with xxxx similar functions)
   *
   * @param string $varname variable description 
   * @return string 
   */ 
  public function get( $varname )
  { 
    switch( $varname ){
      case "foo" : return SomeModel::getManager()->getFoo(); break;
      default: return "";
    }
  }

add this to https://github.com/kla/php-activerecord/blob/master/lib/Model.php#L520:

// check for attribute as getter
if ( method_exists( $this, "get" ) && $this->get( $name ) ){ 
  $var = $this->get( $name );
  return $var;
} 
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top