2

I have been creating some custom entities to Drupal 8 and they pretty much work as expected but a small thing of getting any value of a field.

Lets say I have basefielddefinition like this:

$fields['level'] = BaseFieldDefinition::create('integer')->setLabel(t('Level'))
      ->setDescription(t('Level of the event.'))
      ->setSettings(array(
        'max_length' => 10,
        'text_processing' => 0,
      ))
      ->setDefaultValue(1);

It works as expected and the field I have in SQL looks pretty much like this:

level int(11) DEFAULT NULL,

But I seem to be unable to get the value of the field itself with any logical operation.

If I try this (in member method) $this->get('level')->value I get a String no matter what is the type of the field. Is there an actual way to get the data in correct type or do I need to start creating a huge typecast device somewhere here?

I tried going a lot deeper with the TypedDataInterface but could not find a correct way to get the typed data from there. Also if it is somehow doable there I would really like to point out that, for me at least coming from strongly typed languages, it would seem to logically be the first thing one wants to do, not something that needs to be accessed trough a huge load of different methods. Also isn't that what PDO is for, getting rightly typed data from the SQL in the first place?

0
$this->get('level')->get('value')->getCastedValue();

This works for integer, float and other numeric typed data. I think the majority use case is going to get output as a string anyway, which is why $this->get('level')->get('value')->getValue() is generically a string.

Content entity storage does not do any type casting to strings when it maps from the result set, and Typed Data should not be doing this either. The PDO MySQL driver (using mysqlnd) should set the type in PHP (and so should the PostgreSQL driver). You may need to check how PDO is behaving with respect to your database system.

Update

Note that that the default TypedDataNormalizer does not normalize into a casted value, but uses PrimitiveBase::getValue instead. It would probably be possible to target IntegerInterface in a custom normalizer to call getCastedValue, but I haven't tried that.

Update 2

$this->get('level')->getValue() would return the array of the field item. I should be `$this->get('level')->get('value'), and that should be IntegerData.

  • Nice, thanks for the answer! I will try it as soon as I'm on that project next time (next week). Though for now I can say that my Eclipse intellisense did not find that method but I will see if it executes as soon as I'm able. – user2637046 Aug 25 '16 at 7:10
  • It did not work :( And it does not work because the getCastedValue() is method of a PrimitiveInterface and the Object that is being returned from the method Drupal\Core\Entity\ContentEntityBase::get($field_name) is an Object that extends the \Drupal\Core\Field\FieldItemListInterface and I'm again having hard time to bridge the gap from \Drupal\Core\Field\FieldItemListInterface to any Object that implements the PrimitiveInterface. – user2637046 Aug 31 '16 at 7:25
  • Thank you for the feedback! I think $this->get('level')->getValue()->getCastedValue() will work instead. I did not remember the hirerarchy correctly. – mradcliffe Aug 31 '16 at 12:02
  • Sorry but that does not work either. I tried to figure out a correct way but there seems to be none which is HUGE blowback. And this in context where I created some REST plugins to serve some lighter representations of the entities and now I have messed up types which mess up my ES6 front-end totally. – user2637046 Sep 7 '16 at 7:06
  • IntegerData::getCastedValue absolutely type casts to an integer. Your issues is with the Normalizer, which does not cast the value. This does seem like a shortcoming, but not a huge blowback (as javascript is not strongly-typed either). Your only option is to implement a custom normalizer instead of those typed data interfaces using TypedDataNormalizer. This could be tricky. – mradcliffe Sep 7 '16 at 21:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.