danielebarchiesi@4: $info) { danielebarchiesi@4: // Automatically enable the controller only if the module does not implement danielebarchiesi@4: // the hook itself. danielebarchiesi@4: if (!isset($info['metadata controller class']) && !empty($info['base table']) && (!isset($info['module']) || !module_hook($info['module'], 'entity_property_info'))) { danielebarchiesi@4: $info['metadata controller class'] = 'EntityDefaultMetadataController'; danielebarchiesi@4: } danielebarchiesi@4: if (!empty($info['metadata controller class'])) { danielebarchiesi@4: $controller = new $info['metadata controller class']($type); danielebarchiesi@4: $items += $controller->entityPropertyInfo(); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: // Add in info for all core entities. danielebarchiesi@4: foreach (_entity_metadata_core_modules() as $module) { danielebarchiesi@4: module_load_include('inc', 'entity', "modules/$module.info"); danielebarchiesi@4: if (function_exists($function = "entity_metadata_{$module}_entity_property_info")) { danielebarchiesi@4: if ($return = $function()) { danielebarchiesi@4: $items = array_merge_recursive($items, $return); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: return $items; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Implements hook_entity_property_info_alter(). danielebarchiesi@4: */ danielebarchiesi@4: function entity_entity_property_info_alter(&$entity_info) { danielebarchiesi@4: // Add in info for all core entities. danielebarchiesi@4: foreach (_entity_metadata_core_modules() as $module) { danielebarchiesi@4: module_load_include('inc', 'entity', "modules/$module.info"); danielebarchiesi@4: if (function_exists($function = "entity_metadata_{$module}_entity_property_info_alter")) { danielebarchiesi@4: $function($entity_info); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function _entity_metadata_core_modules() { danielebarchiesi@4: return array_filter(array('book', 'comment', 'field', 'locale', 'node', 'taxonomy', 'user', 'system', 'statistics'), 'module_exists'); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Default controller for generating some basic metadata for CRUD entity types. danielebarchiesi@4: */ danielebarchiesi@4: class EntityDefaultMetadataController { danielebarchiesi@4: danielebarchiesi@4: protected $type, $info; danielebarchiesi@4: danielebarchiesi@4: public function __construct($type) { danielebarchiesi@4: $this->type = $type; danielebarchiesi@4: $this->info = entity_get_info($type); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: public function entityPropertyInfo() { danielebarchiesi@4: $entity_label = drupal_strtolower($this->info['label']); danielebarchiesi@4: danielebarchiesi@4: // Provide defaults based on the schema. danielebarchiesi@4: $info['properties'] = $this->convertSchema(); danielebarchiesi@4: foreach ($info['properties'] as $name => &$property) { danielebarchiesi@4: // Add a description. danielebarchiesi@4: $property['description'] = t('@entity "@property" property.', array('@entity' => drupal_ucfirst($entity_label), '@property' => $name)); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: // Set better metadata for known entity keys. danielebarchiesi@4: $id_key = $this->info['entity keys']['id']; danielebarchiesi@4: danielebarchiesi@4: if (!empty($this->info['entity keys']['name']) && $key = $this->info['entity keys']['name']) { danielebarchiesi@4: $info['properties'][$key]['type'] = 'token'; danielebarchiesi@4: $info['properties'][$key]['label'] = t('Machine-readable name'); danielebarchiesi@4: $info['properties'][$key]['description'] = t('The machine-readable name identifying this @entity.', array('@entity' => $entity_label)); danielebarchiesi@4: $info['properties'][$id_key]['label'] = t('Internal, numeric @entity ID', array('@entity' => $entity_label)); danielebarchiesi@4: $info['properties'][$id_key]['description'] = t('The ID used to identify this @entity internally.', array('@entity' => $entity_label)); danielebarchiesi@4: } danielebarchiesi@4: else { danielebarchiesi@4: $info['properties'][$id_key]['label'] = t('@entity ID', array('@entity' => drupal_ucfirst($entity_label))); danielebarchiesi@4: $info['properties'][$id_key]['description'] = t('The unique ID of the @entity.', array('@entity' => $entity_label)); danielebarchiesi@4: } danielebarchiesi@4: // Care for the bundle. danielebarchiesi@4: if (!empty($this->info['entity keys']['bundle']) && $key = $this->info['entity keys']['bundle']) { danielebarchiesi@4: $info['properties'][$key]['type'] = 'token'; danielebarchiesi@4: $info['properties'][$key]['options list'] = array(get_class($this), 'bundleOptionsList'); danielebarchiesi@4: } danielebarchiesi@4: // Care for the label. danielebarchiesi@4: if (!empty($this->info['entity keys']['label']) && $key = $this->info['entity keys']['label']) { danielebarchiesi@4: $info['properties'][$key]['label'] = t('Label'); danielebarchiesi@4: $info['properties'][$key]['description'] = t('The human readable label.'); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: // Add a computed property for the entity URL and expose it to views. danielebarchiesi@4: if (empty($info['properties']['url']) && !empty($this->info['uri callback'])) { danielebarchiesi@4: $info['properties']['url'] = array( danielebarchiesi@4: 'label' => t('URL'), danielebarchiesi@4: 'description' => t('The URL of the entity.'), danielebarchiesi@4: 'getter callback' => 'entity_metadata_entity_get_properties', danielebarchiesi@4: 'type' => 'uri', danielebarchiesi@4: 'computed' => TRUE, danielebarchiesi@4: 'entity views field' => TRUE, danielebarchiesi@4: ); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: return array($this->type => $info); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * A options list callback returning all bundles for an entity type. danielebarchiesi@4: */ danielebarchiesi@4: public static function bundleOptionsList($name, $info) { danielebarchiesi@4: if (!empty($info['parent']) && $type = $info['parent']) { danielebarchiesi@4: $entity_info = $info['parent']->entityInfo(); danielebarchiesi@4: $options = array(); danielebarchiesi@4: foreach ($entity_info['bundles'] as $name => $bundle_info) { danielebarchiesi@4: $options[$name] = $bundle_info['label']; danielebarchiesi@4: } danielebarchiesi@4: return $options; danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Return a set of properties for an entity based on the schema definition danielebarchiesi@4: */ danielebarchiesi@4: protected function convertSchema() { danielebarchiesi@4: return entity_metadata_convert_schema($this->info['base table']); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Converts the schema information available for the given table to property info. danielebarchiesi@4: * danielebarchiesi@4: * @param $table danielebarchiesi@4: * The name of the table as used in hook_schema(). danielebarchiesi@4: * @return danielebarchiesi@4: * An array of property info as suiting for hook_entity_property_info(). danielebarchiesi@4: */ danielebarchiesi@4: function entity_metadata_convert_schema($table) { danielebarchiesi@4: $schema = drupal_get_schema($table); danielebarchiesi@4: $properties = array(); danielebarchiesi@4: foreach ($schema['fields'] as $name => $info) { danielebarchiesi@4: if ($type = _entity_metadata_convert_schema_type($info['type'])) { danielebarchiesi@4: $properties[$name] = array( danielebarchiesi@4: 'type' => $type, danielebarchiesi@4: 'label' => drupal_ucfirst($name), danielebarchiesi@4: 'schema field' => $name, danielebarchiesi@4: // As we cannot know about any setter access, leave out the setter danielebarchiesi@4: // callback. For getting usually no further access callback is needed. danielebarchiesi@4: ); danielebarchiesi@4: if ($info['type'] == 'serial') { danielebarchiesi@4: $properties[$name]['validation callback'] = 'entity_metadata_validate_integer_positive'; danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: return $properties; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function _entity_metadata_convert_schema_type($type) { danielebarchiesi@4: switch ($type) { danielebarchiesi@4: case 'int': danielebarchiesi@4: case 'serial': danielebarchiesi@4: return 'integer'; danielebarchiesi@4: case 'float': danielebarchiesi@4: case 'numeric': danielebarchiesi@4: return 'decimal'; danielebarchiesi@4: case 'char': danielebarchiesi@4: case 'varchar': danielebarchiesi@4: case 'text': danielebarchiesi@4: return 'text'; danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Interface for extra fields controller. danielebarchiesi@4: * danielebarchiesi@4: * Note: Displays extra fields exposed by this controller are rendered by danielebarchiesi@4: * default by the EntityAPIController. danielebarchiesi@4: */ danielebarchiesi@4: interface EntityExtraFieldsControllerInterface { danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Returns extra fields for this entity type. danielebarchiesi@4: * danielebarchiesi@4: * @see hook_field_extra_fields(). danielebarchiesi@4: */ danielebarchiesi@4: public function fieldExtraFields(); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Default controller for generating extra fields based on property metadata. danielebarchiesi@4: * danielebarchiesi@4: * By default a display extra field for each property not being a field, ID or danielebarchiesi@4: * bundle is generated. danielebarchiesi@4: */ danielebarchiesi@4: class EntityDefaultExtraFieldsController implements EntityExtraFieldsControllerInterface { danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * @var string danielebarchiesi@4: */ danielebarchiesi@4: protected $entityType; danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * @var array danielebarchiesi@4: */ danielebarchiesi@4: protected $entityInfo; danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Constructor. danielebarchiesi@4: */ danielebarchiesi@4: public function __construct($type) { danielebarchiesi@4: $this->entityType = $type; danielebarchiesi@4: $this->entityInfo = entity_get_info($type); danielebarchiesi@4: $this->propertyInfo = entity_get_property_info($type); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Implements EntityExtraFieldsControllerInterface::fieldExtraFields(). danielebarchiesi@4: */ danielebarchiesi@4: public function fieldExtraFields() { danielebarchiesi@4: $extra = array(); danielebarchiesi@4: foreach ($this->propertyInfo['properties'] as $name => $property_info) { danielebarchiesi@4: // Skip adding the ID or bundle. danielebarchiesi@4: if ($this->entityInfo['entity keys']['id'] == $name || $this->entityInfo['entity keys']['bundle'] == $name) { danielebarchiesi@4: continue; danielebarchiesi@4: } danielebarchiesi@4: $extra[$this->entityType][$this->entityType]['display'][$name] = $this->generateExtraFieldInfo($name, $property_info); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: // Handle bundle properties. danielebarchiesi@4: $this->propertyInfo += array('bundles' => array()); danielebarchiesi@4: foreach ($this->propertyInfo['bundles'] as $bundle_name => $info) { danielebarchiesi@4: foreach ($info['properties'] as $name => $property_info) { danielebarchiesi@4: $extra[$this->entityType][$bundle_name]['display'][$name] = $this->generateExtraFieldInfo($name, $property_info); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: return $extra; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Generates the display field info for a given property. danielebarchiesi@4: */ danielebarchiesi@4: protected function generateExtraFieldInfo($name, $property_info) { danielebarchiesi@4: $info = array( danielebarchiesi@4: 'label' => $property_info['label'], danielebarchiesi@4: 'weight' => 0, danielebarchiesi@4: ); danielebarchiesi@4: if (!empty($property_info['description'])) { danielebarchiesi@4: $info['description'] = $property_info['description']; danielebarchiesi@4: } danielebarchiesi@4: return $info; danielebarchiesi@4: } danielebarchiesi@4: }