You are here

6.1 hook_entity_property_info

admin 的头像
Submitted by admin on 星期五, 2015-08-28 09:25

作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com

Entity API模块定义了一个新的钩子,hook_entity_property_info(),通过这个钩子函数,就可以定义实体包含哪些属性信息了,这个信息里面还包括,属性的数据类型、获取、设置属性的回调函数。注意,很多常用的模块,都用到了这里定义的属性,比如Rules模块。而前面的entity_get_property_info,则是用来获取hook_entity_property_info()里面的定义信息的。这个钩子函数比较抽象,我们可以看一个例子,在sites\all\modules\entity\modules下面可以找到,Drupal核心中各个子系统的钩子实现。下面这个是用户系统的实现:

/**

 * Implements hook_entity_property_info() on top of user module.

 *

 * @see entity_entity_property_info()

 */

function entity_metadata_user_entity_property_info() {

  $info = array();

  // Add meta-data about the user properties.

  $properties = &$info['user']['properties'];

 

  $properties['uid'] = array(

    'label' => t("User ID"),

    'type' => 'integer',

    'description' => t("The unique ID of the user account."),

    'schema field' => 'uid',

  );

  $properties['name'] = array(

    'label' => t("Name"),

    'description' => t("The login name of the user account."),

    'getter callback' => 'entity_metadata_user_get_properties',

    'setter callback' => 'entity_property_verbatim_set',

    'sanitize' => 'filter_xss',

    'required' => TRUE,

    'access callback' => 'entity_metadata_user_properties_access',

    'schema field' => 'name',

  );

下面的这段则是节点系统的实现:

  $properties['created'] = array(

    'label' => t("Date created"),

    'type' => 'date',

    'description' => t("The date the node was posted."),

    'setter callback' => 'entity_property_verbatim_set',

    'setter permission' => 'administer nodes',

    'schema field' => 'created',

  );

  $properties['changed'] = array(

    'label' => t("Date changed"),

    'type' => 'date',

    'schema field' => 'changed',

    'description' => t("The date the node was most recently updated."),

  );

  $properties['author'] = array(

    'label' => t("Author"),

    'type' => 'user',

    'description' => t("The author of the node."),

    'setter callback' => 'entity_property_verbatim_set',

    'setter permission' => 'administer nodes',

    'required' => TRUE,

    'schema field' => 'uid',

  );

除了这些实体系统以外,字段系统也都被包含了进来,不过字段系统的代码比较抽象:

/**

 * Implements hook_entity_property_info() on top of field module.

 *

 * @see entity_field_info_alter()

 * @see entity_entity_property_info()

 */

function entity_metadata_field_entity_property_info() {

  $info = array();

  // Loop over all field instances and add them as property.

  foreach (field_info_fields() as $field_name => $field) {

    $field += array('bundles' => array());

    if ($field_type = field_info_field_types($field['type'])) {

      // Add in our default callback as the first one.

      $field_type += array('property_callbacks' => array());

      array_unshift($field_type['property_callbacks'], 'entity_metadata_field_default_property_callback');

 

      foreach ($field['bundles'] as $entity_type => $bundles) {

        foreach ($bundles as $bundle) {

          $instance = field_info_instance($entity_type, $field_name, $bundle);

 

          if ($instance && empty($instance['deleted'])) {

            foreach ($field_type['property_callbacks'] as $callback) {

              $callback($info, $entity_type, $field, $instance, $field_type);

            }

          }

        }

      }

    }

  }

  return $info;

}

 

/**

 * Callback to add in property info defaults per field instance.

 * @see entity_metadata_field_entity_property_info().

 */

function entity_metadata_field_default_property_callback(&$info, $entity_type, $field, $instance, $field_type) {

  if (!empty($field_type['property_type'])) {

    if ($field['cardinality'] != 1) {

      $field_type['property_type'] = 'list<' . $field_type['property_type'] . '>';

    }

    // Add in instance specific property info, if given and apply defaults.

    $name = $field['field_name'];

    $property = &$info[$entity_type]['bundles'][$instance['bundle']]['properties'][$name];

    $instance += array('property info' => array());

    $property = $instance['property info'] + array(

      'label' => $instance['label'],

      'type' => $field_type['property_type'],

      'description' => t('Field "@name".', array('@name' => $name)),

      'getter callback' => 'entity_metadata_field_property_get',

      'setter callback' => 'entity_metadata_field_property_set',

      'access callback' => 'entity_metadata_field_access_callback',

      'query callback' => 'entity_metadata_field_query',

      'translatable' => !empty($field['translatable']),

      // Specify that this property stems from a field.

      'field' => TRUE,

      'required' => !empty($instance['required']),

    );

    // For field types of the list module add in the options list callback.

    if (strpos($field['type'], 'list') === 0) {

      $property['options list'] = 'entity_metadata_field_options_list';

    }

  }

}

Drupal核心系统,默认是不支持这个钩子的,但是Entity API模块把核心系统里面的所有涉及到的部分,都实现出来了。这里是包括所有的Drupal核心的字段类型的。我们在这里,前期不需要完全明白这些代码的含义,大致看一下,知道有这么回事就可以了,我们只需要记住,这里面,在属性数组信息里面,包含哪些常用的键就可以了。'label''description''getter callback''setter callback''sanitize''required''access callback''schema field'。有兴趣的话,可以沿着我们提示,把sites\all\modules\entity\modules下面,所有inc文件里面的代码都阅读一遍。注意,verbatim的中文意思为完全)照字面的(地),逐字的(地),里面的代码会遇到这个单词。


Drupal版本: