diff --git a/eck.entity.inc b/eck.entity.inc index 4b41679..a720a94 100644 --- a/eck.entity.inc +++ b/eck.entity.inc @@ -377,15 +377,39 @@ function eck__entity__form($form, $form_state, $entity) { '#value' => $entity ); - // Property Widget Handling + // Property Widget Handling through property_info by entity api $property_info = entity_get_property_info($entity->entityType()); $properties = array(); + $found_widget = FALSE; foreach($property_info['properties'] as $pname => $pi){ if(array_key_exists('widget', $pi)){ $widget_callback = $pi['widget']; $widget = $widget_callback($entity); $properties[$pname] = $widget_callback; $form[$pname] = $widget_callback($entity); + $found_widget = TRUE; + } + } + + if(!$found_widget){ + //If there was no widget given through the property_info array, we look for + //a widget in the property behaviors implemented + $entity_type = $entity->entityType(); + $entity_type = EntityType::loadByName($entity_type); + $properties = $entity_type->properties; + + foreach($properties as $property => $info){ + //If there is a behavior associated with this property we need to call the appropiate hooks + if(array_key_exists('behavior', $info) && !empty($info['behavior'])){ + $behavior = $info['behavior']; + + $plugin = ctools_get_plugins('eck', 'property_behavior', $behavior); + + $widget = _eck_apply_plugin_widget($plugin, $entity, $property); + if($widget){ + $form[$property] = $widget; + } + } } } @@ -432,6 +456,7 @@ function eck__entity__form_submit($form, &$state) { } } } + //dpm($entity, "Before Save"); $entity->save(); @@ -456,6 +481,28 @@ function _eck_form_property_value($state, $property){ return NULL; } +function _eck_apply_plugin_widget($plugin, $entity, $property){ + + //Now we get the funtions from the plugin to handle save, insert and update + $function = ctools_plugin_get_function($plugin, 'default_widget'); + + if($function){ + return $function($entity, $property); + } + return NULL; +} + +function _eck_apply_plugin_formatter($plugin, $entity, $property){ + + //Now we get the funtions from the plugin to handle save, insert and update + $function = ctools_plugin_get_function($plugin, 'default_formatter'); + + if($function){ + return $function($entity, $property); + } + return NULL; +} + /** * Creates a renderable array to show an entity @@ -468,11 +515,33 @@ function _eck_form_property_value($state, $property){ * (int) the Id of the entity to be deleted */ function eck__entity__view($entity_type_name, $bundle_name, $id) { + $entity = entity_load($entity_type_name, array($id)); + $entity = $entity[$id]; + $entity_type = entity_type_load($entity_type_name); $bundle = bundle_load($entity_type_name, $bundle_name); $build = array(); $entity_view = eck__entity__build($entity_type, $bundle, $id); + + $properties = $entity_type->properties; + $property_view = array(); + foreach($properties as $property => $info){ + //If there is a behavior associated with this property we need to call the appropiate hooks + if(array_key_exists('behavior', $info) && !empty($info['behavior'])){ + $behavior = $info['behavior']; + + $plugin = ctools_get_plugins('eck', 'property_behavior', $behavior); + $formatter = _eck_apply_plugin_formatter($plugin, $entity, $property); + + if($formatter){ + $property_view[$property] = $formatter; + } + } + } + + $entity_view[$entity->entityType()][$entity->id] = array_merge($property_view, $entity_view[$entity->entityType()][$entity->id]); + $build["{$entity_type->name}_{$bundle->name}_page"] = $entity_view; return $build; diff --git a/eck.install b/eck.install index f073476..5acf79b 100644 --- a/eck.install +++ b/eck.install @@ -115,7 +115,7 @@ function eck_schema() { 'not null' => TRUE ) ), - 'primary key' => array('id', 'machine_name'), + 'primary key' => array('id'/*, 'machine_name'*/), //sad.. taken this out until I figure out how to make it work 'indexes' => array( /*'entity_type_bundle' => array('entity_type', 'name'),*/ //Nope, Don't need it ), @@ -330,9 +330,134 @@ function eck_update_7005() { function eck_update_7006() { //lets start with then entity type table - //first lets take the properties and translate them to the new form. + //lets add an id field to the entity_type table, and set it up as a primary key + //db_add_primary_key('eck_entity_type', array('id')); + db_drop_primary_key('eck_entity_type'); + db_add_field('eck_entity_type', 'id', array( + 'description' => "The primary identifier for an entity type", + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), array('primary key' => array('id', 'name'))); + + //lets take the properties and translate them to the new form. + $results = db_select('eck_entity_type', 't')->fields('t')->execute(); + + foreach ($results as $record) { + + //@todo for each entity type we want to drop all the indexes.. they will have to be managed dynamically by the + //behaviors even though I don't know how to do that yet + $entity_table = "eck_{$record->name}"; + + if(db_index_exists($entity_table, 'uid')){ + db_drop_index($entity_table, 'uid'); + } + if(db_index_exists($entity_table, "{$record->name}_created")){ + db_drop_index($entity_table, "{$record->name}_created"); + } + if(db_index_exists($entity_table, "{$record->name}_changed")){ + db_drop_index($entity_table, "{$record->name}_changed"); + } + + $new_properties = array(); + + $properties = $record->properties; + $properties = unserialize($properties); + foreach($properties as $property => $status){ + switch($property){ + case 'uuid': + $new_properties['uuid'] = array('label' => 'UUID', 'type' => 'uuid'); + break; + + case 'uid': + $new_properties['uid'] = array('label' => 'Author', 'type' => 'integer', 'behavior' => 'author'); + break; + + case 'created': + $new_properties['created'] = array('label' => 'Created', 'type' => 'integer', 'behavior' => 'created'); + break; + + case 'changed': + $new_properties['changed'] = array('label' => 'Changed', 'type' => 'integer', 'behavior' => 'changed'); + break; + + case 'state': + $new_properties['state'] = array('label' => 'State', 'type' => 'positive_integer'); + break; + } + } + + $custom_properties = $record->custom_properties; + $custom_properties = unserialize($custom_properties); + foreach($custom_properties as $property => $info){ + + $type = $info['type']; + $label = $info['label']; + switch($type){ + case 'text': + $new_properties[$property] = array('label' => $label, 'type' => $type); + break; + + case 'decimal': + $new_properties[$property] = array('label' => $label, 'type' => $type); + break; + + default: + $new_properties[$property] = array('label' => $label, 'type' => 'integer'); + break; + } + } + + $encode_new = drupal_json_encode($new_properties); + + db_update('eck_entity_type') // Table name no longer needs {} + ->fields(array( + 'properties' => $encode_new + )) + ->condition('name', $record->name, '=') + ->execute(); + } + + //Now we can drop the custom_properties field now that everything has been moved + db_drop_field('eck_entity_type', 'custom_properties'); + + //now the changes to the eck_bundle table + + //first lets drop that index + db_drop_index('eck_bundle', 'entity_type_bundle_name'); + + db_add_field('eck_bundle', 'machine_name', array( + 'description' => "A combination of the entity type and the name of + this bundle, this combination is unique", + 'type' => 'varchar', + 'length' => 128, + 'default' =>"", + 'not null' => TRUE + )); + + // + + +} + +function eck_update_7007() { + + //lets generate the machine names for each bundle + $results = db_select('eck_bundle', 't')->fields('t')->execute(); + + foreach ($results as $record) { + $name = $record->name; + $entity_type = $record->entity_type; + $record->machine_name = "{$entity_type}_{$name}"; + db_update('eck_bundle') // Table name no longer needs {} + ->fields(array( + 'machine_name' => $record->machine_name + )) + ->condition('id', $record->id, '=') + ->execute(); + } } diff --git a/eck.properties.inc b/eck.properties.inc index 7a1b985..e408de8 100644 --- a/eck.properties.inc +++ b/eck.properties.inc @@ -3,6 +3,8 @@ function eck_set_properties_schema(&$schema, $entity_type){ $properties = $entity_type->properties; + //dpm($properties, "Properties in schema"); + foreach($properties as $name => $info){ $type = $info['type']; $schema['fields'][$name] = eck_property_type_schema($type); @@ -298,14 +300,17 @@ function eck__properties__form_submit($form, &$state){ } else if($state['values']['op'] == "Save"){ //Here we want to add the properties to the entity type and save it - dpm($state, "State"); $entity_type = $state['values']['entity_type']; //dpm($entity_type, "Entity Type"); foreach($state['values']['new_properties_table'] as $property => $active){ if($active){ $info = $state['values']['new_properties'][$property]; - $entity_type->addProperty($property, $info['label'], $info['type'], $info['behavior']); + if(array_key_exists('behavior', $info)){ + $entity_type->addProperty($property, $info['label'], $info['type'], $info['behavior']); + }else{ + $entity_type->addProperty($property, $info['label'], $info['type']); + } }else{ $entity_type->removeProperty($property); } diff --git a/eck_spb/eck_spb.info b/eck_spb/eck_spb.info new file mode 100644 index 0000000..e6c8ced --- /dev/null +++ b/eck_spb/eck_spb.info @@ -0,0 +1,4 @@ +name = ECK Sample Property Behavior +description = A module exposing a simple property behavior, that allows us to set a property through an entities input form +package = ECK +core = 7.x \ No newline at end of file diff --git a/eck_spb/eck_spb.module b/eck_spb/eck_spb.module new file mode 100644 index 0000000..780f1f4 --- /dev/null +++ b/eck_spb/eck_spb.module @@ -0,0 +1,12 @@ + "ECK SPB", + 'entity_save' => 'eck_spb_entity_save', + 'default_widget' => 'eck_spb_widget', + 'default_formatter' => 'eck_spb_formatter' +); + +function eck_spb_entity_save($entity, $property, $value = NULL){ + $entity->{$property} = $value; +} + +/** + * Define a rendarble array to input a value for the property using this behavior + * + * @param $entity: and entity object that contains the property for which this behavior is relevant + * @param $property: the name of the property (string) that is using this behavior + * + * @return a rendarable array use when the input form for this entity is displayed + */ +function eck_spb_widget($entity, $property){ + $title = _eck_spb_extract_title($entity, $property); + return array( + '#type' => 'textfield', + '#title' => ucfirst($property), + '#default_value' => $title + ); +} + +function eck_spb_formatter($entity, $property){ + $title = _eck_spb_extract_title($entity, $property); + return array('#markup' => "

{$title}

"); +} + +function _eck_spb_extract_title($entity, $property){ + $title = ""; + if(isset($entity->{$property})){ + $title = $entity->{$property}; + } + + return $title; +} diff --git a/properties/README.txt b/properties/README.txt deleted file mode 100644 index a8570b6..0000000 --- a/properties/README.txt +++ /dev/null @@ -1,8 +0,0 @@ -One of the main purposes of ECK is to exploit and make accessible the flexibility to model data that has been created by the introduction of the entity system. The Entity API (contrib module) has done a great job at making the entity system useful, but ECK attempts to build upon that. -One of the most useful things that I could think of in terms of flexibility, was the ability to add or take of way packages of functionality from an entity type. For example, if we wanted to make a certain entity type have a simple publishing system like nodes do. This functionality should be simple to package and make accessible to the users to activate or deactivate with ease. -In this folder I am adding a couple of modules that will do exactly this. - -I am hoping to create a title property module that will behave like node titles. -The module will allos for the entity title to be set during creation and modify during edition, when that entity is going to be viewed, the title will be the pages title, and the title property will be set as the label propety so that we can have autocomplete functionality with ease with a module like entity_autocomplete. - -The second property module will implement a simple publishing workflow like the one for entities, so an entity can be hidden until published. It will probably not be as sophisticated as the publishing system in node, but the whole purpose is to show the capabilities of packaging this functionality in ways that it can easily be reused, and shared. diff --git a/properties/title/eck_property_title.info b/properties/title/eck_property_title.info deleted file mode 100644 index 0643fe2..0000000 --- a/properties/title/eck_property_title.info +++ /dev/null @@ -1,6 +0,0 @@ -name = ECK Property Title -description = A title property for entities -package = ECK -core = 7.x -dependencies[] = eck - diff --git a/properties/title/eck_property_title.module b/properties/title/eck_property_title.module deleted file mode 100644 index 0225e96..0000000 --- a/properties/title/eck_property_title.module +++ /dev/null @@ -1,52 +0,0 @@ - "Title", - 'schema' => - array( - 'description' => 'The title is always treated as non-markup plain text.', - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - ) - ); - - return $info; -} - -function eck_property_title_entity_property_title_info_alter(&$info){ - //dpm($info, "Title alter Info"); - $info['widget'] = 'eck_property_title_widget'; -} - -function eck_property_title_widget($entity){ - $widget = array( - '#type' => 'textfield', - '#title' => t('Title'), - '#default_value' => isset($entity->title)?$entity->title:" ", - '#size' => 60, - '#maxlength' => 128, - '#required' => TRUE, - ); - - return $widget; -} - -function eck_property_title_widget_submit($entity, $value){ - //dpm($value, "Title Submit"); - $entity->title = $value; -} diff --git a/properties/uuid/eck_property_uuid.info b/properties/uuid/eck_property_uuid.info deleted file mode 100644 index c063090..0000000 --- a/properties/uuid/eck_property_uuid.info +++ /dev/null @@ -1,6 +0,0 @@ -name = ECK Property UUID -description = A UUID property for entities -package = ECK -core = 7.x -dependencies[] = eck - diff --git a/properties/uuid/eck_property_uuid.module b/properties/uuid/eck_property_uuid.module deleted file mode 100644 index 60083ea..0000000 --- a/properties/uuid/eck_property_uuid.module +++ /dev/null @@ -1,29 +0,0 @@ - "UUID", - 'schema' => - array( - 'description' => 'The Universally Unique Identifier.', - 'type' => 'char', - 'length' => 36, - 'not null' => TRUE, - 'default' => '', - ) - ); - - return $info; -} \ No newline at end of file