Entity::getValueMap() doesn't read data of linked "many-to-many" entities

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • kanstantin
    Junior Member
    • May 2018
    • 5

    Entity::getValueMap() doesn't read data of linked "many-to-many" entities

    Hello,

    I've been working on a custom "beforeSave" hook, the aim is to invoke dynamic logic on the server side for the rules defined for an entity so that the same logic would also be triggered during REST API calls (no UI).

    Inside the hook method, the data for an entity is read using:

    $data = $entity->getValueMap();

    It works perfectly for the "Create" scenario, but it fails during the "Update" operation when the target entity has a link of "many-to-many" type to another (in my case, it is Contact -> Subaccount) and the payload doesn't include this data for the linked entity. For example, I am going to modify the description with REST API call like this:

    PUT http://localhost:8080/api/v1/Contact/64b7f1f4c15f5ea87
    Content-Type: application/json
    X-Api-Key: cfb6ac9c33a56b79a8c31c17eece7
    0c1

    {
    "description": "sample text as a description"
    }


    This way, the rule, which is based on a value of Contact.subAccount attribute would provide a false result considering the subaccount is empty (and it should not be), and the reason for this is - Entity::getValueMap() method doesn't set the proper value for Contact.subaccountsIds in this case

    $contactEntity->hasAttribute('subaccountsIds'); /* returns true */
    $contactEntity->get('subaccountsIds'); /* returns null even though SubAccount is defined for this entity */


    Hence, a rule which ensures that Contact.subAccount attribute is not empty would always fail.

    Perhaps, I am doing something wrong and there is a better approach, which might allow getting entity's data for joined entities without looping through the list of attributes ($entity->getRelationList() )

    Please advise.​
  • yuri
    Member
    • Mar 2014
    • 8440

    #2
    Hi, Maybe you don't a have link-multiple-field parameter enabled for your relationship. Attribute exists, but the link-multiple functionality is disabled. Or use the relation repository $entityManager->getRDBRepository(Contact::ENTITY_TYPE)->getRelation($entity, 'subaccounts')-> ...
    If you find EspoCRM good, we would greatly appreciate if you could give the project a star on GitHub. We believe our work truly deserves more recognition. Thanks.

    Comment


    • kanstantin
      kanstantin commented
      Editing a comment
      Yuri, thank you for the reply! "Link Multiple Field" option was enabled already on SubAccounts side, and I tried to enable it on the "Contacts" side - nothing changed, unfortunately. For now the workaround looks like this:

      Code:
          private function getValueMapWithManyToMany(Entity $entity)
          {
              $changedAttributes = array_filter($entity->getAttributeList(),
                  function ($attr) use ($entity) {
                      return $entity->isAttributeChanged($attr);
              });
              $changedAttributeStartsWith = function ($startWithString) use ($changedAttributes) {
                  return array_filter($changedAttributes, function($attr) use ($startWithString) {
                      return str_starts_with($attr, $startWithString);
                  });
              };
              foreach ($entity->getRelationList() as $relation) {
                  if ($entity->getRelationType($relation) == 'manyMany' && !$changedAttributeStartsWith($relation)) {
                      $entity->loadLinkMultipleField($relation);
                  }
              }
              return $entity->getValueMap();
          }
Working...