carpehora/extrapropertiesbehavior

ExtraPropertiesBehavior 是一个 propel 行为,用于在 propel 模型中存储键/值扩展字段。

1.1.0 2013-08-26 10:00 UTC

This package is not auto-updated.

Last update: 2024-09-20 14:04:37 UTC


README

Build Status

ExtraPropertiesBehavior 为对象提供键/值扩展。

基本示例

给定一个产品模型,ExtraPropertiesBehavior 将添加一个键/值扩展接口。

<table name="product">
  <column name="id" type="INTEGER" primaryKey="true" autoincrement="true" />
  <column name="name" type="VARCHAR" size="255" />
  <behavior name="extra_properties" />
</table>
<?php
$tvSet = new Product();
$tvSet->setName('My big TV');
$tvSet->setProperty('size', '12 inches');
$tvSet->setProperty('frequency', '11 Hz');
$tvSet->save();

$tvSet->getProperty('size'); // will result in '12 inches'
$tvSet->getProperty('frequency'); // will result in '11 Hz'

安装

首先在您的 vendor 目录中克隆行为

git clone git://github.com/Carpe-Hora/ExtraPropertiesBehavior.git

或者使用 Composer

{
    "require": {
        "carpehora/propel-extraproperties-behavior": "1.*"
    }
}

然后在您的 propel.inibuid.properties 配置文件中注册行为

propel.behavior.extra_properties.class = path.to.ExtraPropertiesBehavior

使用方法

只需将行为添加到您的表定义中

<!-- in schema.xml -->
<table name="product">
  <!-- ... -->

  <behavior name="extra_properties" />
</table>

此时,行为将创建一个额外的表来存储属性,并在活动记录对象中添加以下方法集

常用方法

  • hasProperty('property_name')
  • countPropertiesByName('property_name')
  • initializeProperties()
  • deletePropertiesByName('property_name')

单实例属性

  • setProperty('property_name', 'value')
  • getProperty('property_name', 'default value')

多实例属性

  • addProperty('property_name', 'value')
  • getPropertiesByName('property_name')

这很好,但通常开发者希望直接通过获取器和设置器进行访问。要做到这一点,可以使用以下方法声明额外的属性列表

  • registerProperty('property_name, 'default value')
  • registerMultipleProperty('property_name')

### 属性提取方法

  • getProperties() 返回一个属性数组

配置

首先在您的 schema.xml 中声明行为

<database name="user">
  <table name="user_preference">
    <column name="id" type="INTEGER" primaryKey="true" autoincrement="true" />
    <column name="key" type="VARCHAR" size="50" />
    <column name="value" type="LONGVARCHAR" />
    <column name="user_id" type="integer" required="true" />
    <foreign-key foreignTable="user" onDelete="cascade" refPhpName="Preference">
      <reference local="user_id" foreign="id" />
    </foreign-key>
  </table>

  <table name="user">
    <column name="id" type="INTEGER" primaryKey="true" autoincrement="true" />
    <column name="name" type="VARCHAR" size="255" />
    <behavior name="extra_properties" >
      <!-- related table -->
      <parameter name="properties_table" value="user_preference" />
      <!-- property label column -->
      <parameter name="property_name_column" value="key" />
      <!-- property value column -->
      <parameter name="property_value_column" value="value" />
      <!-- normalize property names and values using peer normalize methods ? -->
      <parameter name="normalize" value="true" />
      <!-- throw an error if shortcut get{PropertyName} cannot resolve PropertyName ? -->
      <parameter name="throw_error" value="true" />
      <!-- property denomination, if instead of properties, you think in terms of parameters/details/whatever -->
      <parameter name="property_name" value="property" />
    </behavior>
  </table>
</database>

要启用人类化获取器,在您的模型中声明一个 initializeProperties() 方法,如下所示

<?php
class User extends BaseUser
{
  protected function initializeProperties()
  {
    $this->registerProperty('MY_MODULE_PREFERENCE', 'default_value');
  }
}

然后您可以直接使用获取器和设置器与您的模型对象一起使用

<?php
// get/set methods created by initializeProperties()
$user->getMyModulePreference();             // or call $user->getProperty('my_module_preference');
$user->setMyModulePreference('preference'); // or call $user->setProperty('my_module_preference', 'preference');

// extend dynamicly
$user->registerProperty('MY_OTHER_PREFERENCE', 'default_value');
$user->getMyOtherPreference();             // or call $user->getProperty('my_other_preference');
$user->setMyOtherPreference('preference'); // or call $user->setProperty('my_other_preference', 'preference');

// simply deal with multiple occurences
$user->registerMultipleProperty('MY_MULTIPLE_PREFERENCE');
$user->addMyMultiplePreference('pref1');
$user->addMyMultiplePreference('pref2');
$user->save();

// extract properties
$user->getProperties();
// will result in
// array(
//   'MY_MODULE_PREFERENCE' => 'preference',
//   'MY_OTHER_PREFERENCE' => 'preference',
//   'MY_MULTIPLE_PREFERENCE' => array('pref1', 'pref2'),
// )

$user->getMyMultiplePreferences();        // will result in array('id_pref1' => 'pref1', 'id_pref2' => 'pref2')
$user->clearMyMultiplePreferences();      // remove all MY_MULTIPLE_PREFERENCE preferences
$user->save();

与单继承一起使用

有时根据继承类键扩展模型很有用。 ExtraPropertiesBehavior 可以为您做到这一点。

想象一个具有多个内容类型的 CMS

<database name="content">
  <table name="content">
    <column name="id" type="INTEGER" primaryKey="true" autoincrement="true" />
    <column name="title" type="VARCHAR" size="255" />
    <column name="type" type="VARCHAR" inheritance="single">
    <behavior name="extra_properties" />
  </table>
</database>

给定默认内容结构,只需在 initializeProperties() 方法中定义您的选项,以定义可能的键/值

<?php
class Article extends Content
{
  protected function initializeProperties()
  {
    $this->registerProperty('CONTENT');
    $this->registerProperty('AUTHOR');
  }

  public function getOMClass()
  {
    return 'Article';
  }
}

然后

<?php
class Video extends Content
{
  protected function initializeProperties()
  {
    $this->registerProperty('URL');
    $this->registerProperty('LENGTH');
  }

  public function getOMClass()
  {
    return 'Video';
  }
}

然后,只需像使用内置字段一样使用额外属性即可

<?php
$article = new Article();
$article->setTitle('Propel, greatest php ORM ever');
$article->setContent('Try it you\'ll see');
$article->save();

$video = new Video();
$video->setTitle('Propel + phpsh');
$video->setUrl('http://vimeo.com/15140218');
$video->setLength('2:01');
$video->save();

待办事项

  • 实现默认属性(生成方法并在初始化中注册)
  • 参数以选择设置器和获取器名称。
  • 添加一个回调来转换属性值
  • 添加命名空间