I want to add a message to my entity that might be longer than 255 characters so the text property type will not work.

How do I extend the property types? It looks like UUID was added later as a property type but I don't think my normal text field will be patched into the module. I can add the text field through the eck_property_types_alter hook. However, I can't define the schema for it.

Within the eck_property_type_schema() function only the defined types get passed to the alter function. Can we include the $type variable as a parameter to the eck_property_type_schema_alter() hook so I can extend the custom property type?

OR...

Looking at other entity tables such as node and comment in the database it seems none of them use a field larger than 255 characters. Does this mean that if I need a text field that is at least 3000 characters I should just go ahead and use a text field attached in a bundle?

Comments

fmizzell’s picture

Look at eck.properties.inc. There are 2 relevant functions there: eck_property_types() and eck_property_type_schema(). Each of this function has an alter hook that will allow you to define new property types, and a schema for each of your new property types.

Adam S’s picture

Because the $type is not passed through the alter hook I can't tell what type it is working on. I guess it will work when one extra property type defined but not any more than that.

function eck_property_type_schema($type) {
  $schema = array();
  
  switch ($type) {
    case 'text':
      $schema = array(
        'description' => 'Text',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      );
      break;

    case 'decimal':
      $schema = array(
        'description' => 'Decimal',
        'type' => 'float',
        'not null' => TRUE,
        'default' => 0,
      );
      break;

    case 'integer':
      $schema = array(
        'type' => 'int',
        'description' => "Integer",
        'not null' => TRUE,
        'default' => 0,
      );
      break;
    case 'positive_integer':
      $schema = array(
        'type' => 'int',
        'description' => "Integer",
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
      );
      break;
      
      
    case 'uuid':
      $schema = array(
        'type' => 'char',
        'length' => 36,
        'not null' => TRUE,
        'default' => '',
        'description' => 'The Universally Unique Identifier.',
      );
      break;
      
    default:
      $schema = NULL;
      break;
  }
  
  drupal_alter('eck_property_type_schema', $schema);
  
  return $schema;
}
fmizzell’s picture

Ok, I understand, we need to add a regular module_invoke_all so modules that are defining new types can define a schema to begin with.. do you want to get this stuff working and submit the patch :)

Adam S’s picture

Looking at the manage property UI I realized that some types can't go with some behaviors. For example, the Author behavior can't be a text type. Throwing in a module_invoke_all will just confuse the problems a little more. This needs to be thought about.

fmizzell’s picture

I agree, I was simply suggesting what would be the fastest solution at the moment. I am currently working on a better architecture for how properties are handled, but there is still quite a bit of work to be done in that end. In the new system the type of the property will be the central factor, and all other metadata and functionality will be anchor by the property types. So the db schemas, the formatters, and widgets, they will all be dependent upon the property types. Since property types will be classed objects it will be easy to create hierarchies upon the basic types to handle more interesting cases. Maybe this was not what you had in mind when you said "This needs to be thought about", but if you are interested I have some code in a sandbox named "D8 Complex Data". Otherwise I am all ears on partial solution that would solve the problem according to your needs.

Adam S’s picture

In the new system the type of the property will be the central factor, and all other metadata and functionality will be anchor by the property types.

This is what I was thinking. Is is possible to make extensible like Views handlers?

Adam S’s picture

StatusFileSize
new320 bytes

The most straight forward approach is to simply replace drupal_alter() with module_invoke_all(). This is, however, not a very elegant solution.

EDIT: It should be drupal_alter however both $type and $schema should be passed as arguments.

function MY_MODULE_eck_property_type_schema_alter ($type, &$schema) {
  if ($type == 'varchar40') {
    $schema = array(
      'description' => 'Varchar (40)',
      'type' => 'varchar',
      'length' => 40,
      'not null' => TRUE,
      'default' => '',
    );
  }
}
Adam S’s picture

StatusFileSize
new2.3 KB
new521 bytes

Here is a template for creating a simple entity programmatically with ECK. It require the patch to add the $type variable to the drupal_alter () function. If this is useful I can document it with comments.

Adam S’s picture

StatusFileSize
new521 bytes

Oops. That patch doesn't work.

kolier’s picture

Status: Active » Needs review

Vote for Adam S' eck-1650990-8.patch, add a $type variable will work.

fmizzell’s picture

@kolier: does #10 mean that you tried the patch and everything works as expected?

Adam S’s picture

@fmizzel You can download the example module I created and see it working.

kolier’s picture

@fmizzell

Though after this change, any module implements 'hook_eck_property_type_schema_alter' will break.
But it's easy to fix, and the original hook is not much useful.

-  drupal_alter('eck_property_type_schema', $schema);
+  drupal_alter('eck_property_type_schema', $type, $schema);

The change make the hook has a true meaning.

fmizzell’s picture

Status: Needs review » Reviewed & tested by the community

This is definitely a simple patch, I doubt anybody is using the hook otherwise this issue would have been filed a sooner. Anyways, I think we need this fix to make that functionality of eck useful.

@kolier I understand your concern, I think I will just make it clear in the next release's notes of the change to the hook.

@Adam S: thanks for your work, I will try to get this committed as soon as possible

fmizzell’s picture

Status: Reviewed & tested by the community » Needs work

Ok.. I think I see a problem with this solution. @Adam S: in your module you redefine the schema for "decimal". Maybe that was what you needed for your stuff to work, but I don't guess that allowing people to do that is a good idea. The reason is that any module can unsync the schema array and the actual settings in the db. I am not sure this would have any adverse effects, but it just does not sound like a good idea.

Maybe that hook should be a module_invoke_all type of hook, that way we can check uniqueness (just enough for different modules not to override one another) on the schema definitions.

Any thoughts?

Adam S’s picture

@fmizzell, A while back I started to ponder how an effective interface for creating database fields would function. I don't remember exactly what the problems I encountered are while thinking about it but I do remember that the more I thought about it the more it would approach the interface for adding fields to nodes. What I was doing was adding fields without using the Field API. I'm sure that a lot of people will get the temptation to do that. However, in my case I needed to have simple tables because of third party integration that needed to add information to the table without bootstrapping Drupal and the ECK makes this information available to Views. What is the line between using bundles and just adding fields to an entity table.

I also caught that problem with the decimal field. The third party developer requested it and I didn't know there was conflict until later. Now I still have to explain to the third party why they have to change their code. Oops.

The problem is very complicated and I stopped thinking about it hoping you kept working on the plugin module you linked to.

What if we created a scema object that is saved in a database cache? To create the object choose a datatype, then set the description, length, default, not null properties and also if it is a user or date property. Then attached allowed widgets for that data type and attach allowed formatters. It's really just like the Field API but there are cases when for example importing the complete geocode table to be able to extend a numeric datatype to integrate with the many geo spatial maps is nice and simple. Serialize and cache that object or export it to file and load it when that entity is about to be used. Creating an object like this will also allow an opportunity to inject more schema information such as indexes.

_randy’s picture

I too am trying to extend the properties available and as such, Adam S patch in #9 is good, however I think to be technically accurate to the drupal_alter function (http://api.drupal.org/api/drupal/includes!module.inc/function/drupal_alt...) declaration, the fields should be the other way around:

drupal_alter('eck_property_type_schema', $schema, $type);

as the 2nd parameter is technically the "data" while the tertiary parameter is context.

geek-merlin’s picture

as for #15: I think this is what you want as architecture:
* create a new info hook, say hook_eck_property_type_schema_info()
* take the stuff from #2 code into a single array and return it from the implementation eck_eck_property_type_schema_info()
* collect all info with module_invoke('eck_property_type_schema_info');
* so other modules can also pass in some info, but not alter
* (if we really want other modules to be able to alter schema info, they should be responsible to provide a suitable update function. i'm not sure this is a good idea but i'm sure we should separate info hook from info alter hook.)

mojzis’s picture

I vote for the solution suggested by axel in #18 - combine eck_property_types and eck_property_type_schema and make it one (normal, not alter) hook.

fmizzell’s picture

Version: 7.x-2.x-dev » 7.x-3.x-dev
Status: Needs work » Fixed

In 3.x we have a better architected system around property types. Check it out and give some feedback :)

fmizzell’s picture

Status: Fixed » Closed (fixed)
fmizzell’s picture

A fix in 2.x was done also, while 3.x is out of the picture: https://drupal.org/commitlog/commit/22480/91bc0e0c18504ac74a4e4d059d774a...

primozsusa’s picture

hello,
i am also reading this because of the DECIMAL property type. Why is decimal a problem?
Cheers
Primoz

primozsusa’s picture

ok, it works for me like this... latest dev

/**
 * Implements hook_eck_property_types_alter()
 */
function hook_eck_property_types_alter(&$default_types) {
  $default_types['double'] = 'Double';
  $default_types['bigint'] = 'BigInt';
  $default_types['tdecimal'] = 'TDecimal';
}

/**
 * Implements hook_eck_property_type_schema_alter()
 */
function hook_eck_property_type_schema_alter(&$schema, &$type) {
  if ($type == 'double') {
    $schema = array(
      'type' => 'float',
      'size' => 'big',
      'description' => 'Double',
      'not null' => TRUE,
      'default' => 0
    );
  } else if ($type == 'bigint') {
    $schema = array(
      'type' => 'int',
      'size' => 'big',
      'description' => 'BigInt',
      'not null' => TRUE,
      'default' => 0
    );
  } else if ($type == 'tdecimal') {
    $schema = array(
      'type' => 'numeric',
      'precision' => 18,
      'scale' => 12,
      'not null' => FALSE,
    );
  }
}