Többértékű mező alapján való frissítés szabállyal

ipeto képe

Sziasztok!

Több esetben előkerült már az a feladat, hogy egy többértékű entity (vagy user)reference mező értékei alapján kell frissíteni egy másik valamit: pl. egy másik entity reference-t vagy egy organic group felhasználóit. Viszonylag logikusnak tűnik, hogy ezt a node frissítésére hatására egy rule végezze el, összehasonlítva a mező régi és új értékeit és cselekedjen, ha eltérnek egymástól. Valami ilyesmi koncepciót gondoltam két egymásba ágyazott ciklussal:

  1. { "rules_felhasznalo_og_hozzaad" : {
  2. "LABEL" : "Felhasznalok OG-hez rendelese",
  3. "PLUGIN" : "reaction rule",
  4. "ACTIVE" : false,
  5. "OWNER" : "rules",
  6. "REQUIRES" : [ "rules", "og" ],
  7. "ON" : { "node_update--thesis" : { "bundle" : "thesis" } },
  8. "IF" : [
  9. { "NOT data_is_empty" : { "data" : [ "node:field-user-access" ] } },
  10. { "og_entity_in_group" : { "entity" : [ "node" ], "group" : [ "node:og-group-ref" ] } }
  11. ],
  12. "DO" : [
  13. { "LOOP" : {
  14. "USING" : { "list" : [ "node-unchanged:field-user-access" ] },
  15. "ITEM" : { "list_old_user" : "Eredeti listaelem" },
  16. "DO" : [
  17. { "LOOP" : {
  18. "USING" : { "list" : [ "node:field-dolgozat-user-access" ] },
  19. "ITEM" : { "list_user" : "Uj listaelem" },
  20. "DO" : [
  21. { "drupal_message" : {
  22. "message" : "Regi: [list_old_user:name] - Uj: [list_user:name]",
  23. "type" : "warning"
  24. }
  25. }
  26. ]
  27. }
  28. }
  29. ]
  30. }
  31. }
  32. ]
  33. }
  34. }

Ezzel ugye az a baj, hogy a régi és új állapot összes kombinációját leképezi, két elemű mezőnél pl:

  • régi1-új1
  • régi1-új2
  • régi2-új1
  • régi2-új2

Így hiába rakom bele az a feltételt, hogy a régi_érték <> új_érték, akkor is fog találni ilyeneket, ha változtatás nélkül mentem el a node-ot. Tehát azt szeretném megtudni, hogyan lehet úgy szűrni, hogy csak az azonos mező-előfordulásokat (delta-értékeket) hasonlítsa össze?

Melyik modulhoz, modulokhoz kapcsolódik a téma?: 
Drupal verzió: 
ipeto képe

Igazából máshol is vannak ezzel kapcsolatban gondjaim. Teljesen lebutítottam a szabályt, hogy egyáltalán lássam, ki kivel van:

  1. { "rules_reviewers_update" : {
  2. "LABEL" : "Update reviewers",
  3. "PLUGIN" : "reaction rule",
  4. "OWNER" : "rules",
  5. "REQUIRES" : [ "rules", "devel" ],
  6. "ON" : { "node_update--thesis" : { "bundle" : "thesis" } },
  7. "IF" : [
  8. { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_reviews" } },
  9. { "entity_has_field" : { "entity" : [ "node-unchanged" ], "field" : "field_reviews" } }
  10. ],
  11. "DO" : [
  12. { "LOOP" : {
  13. "USING" : { "list" : [ "node-unchanged:field_reviews" ] },
  14. "ITEM" : { "old_reviewer" : "Old reviewer" },
  15. "DO" : [ { "devel_debug" : { "value" : [ "old-reviewer" ] } } ]
  16. }
  17. },
  18. { "LOOP" : {
  19. "USING" : { "list" : [ "node:field_reviews" ] },
  20. "ITEM" : { "new_reviewer" : "New reviewer" },
  21. "DO" : [ { "devel_debug" : { "value" : [ "new-reviewer" ] } } ]
  22. }
  23. }
  24. ]
  25. }
  26. }

Szerintem ennek annyit kellene csinálnia, hogy külön kiírja a mező objektumának mentés előtti és utáni állapotát. Viszont előbbire nem tudom rávenni, mindkét esetben csak a mentés utánit kapom meg. Ha pedig lecserélem az eseményt "mentés előtt"-re, akkor csak az egyik ciklus fut le és a mentés előtti értéket kapom meg.

Hogyan lehetne mindkét fázishoz hozzáférni?

0
0
pp képe

mivel több értékű mezőről van szó, ezért nem fogod tudni összehasonlítani a dolgokat. Ez nem hinném, hogy a jó irány.

Ilyenkor én mindig úgy gondolkodom, hogy a módosítatlan entitásnál található értékeket rollback-elem, majd a módosítottnál találhatóakkal pedig megteszem azt amit tenni kell.

Mondjuk, ha az a feladat, hogy referenciákat kell szinkronizálni, pl. könyv szerzői és szerző könyvei, akkor először végigmegyek a módosítattaln könyvön és minden szerzőnél törlöm a könyvet az adott szerzőtől, majd végigmegyek a módosított könyvön, és minden szerzőnél felveszem a könyvet. (szerző módosításoknál detto, a rules rekurzió védelme miatt pedig nem kerülök végtelen ciklusba, hisz ugye amikor módosítom a könyvet, módosul a szerző, amiért módosítani kéne a könyveket, stb. szóval ez nem lesz)

Így persze ha csak egy elem adódik hozzá a listához, akkor is első körben mindegyiket törlöm, és utána mindegyiket felveszem, szóval nem csak a változással foglalkozom, de a rules úgy se tud igazi elágazást, szóval ezen nem szoktam sokat problémázni. :)

pp

0
0
ipeto képe

Valami hasonlóval próbálkozom most már én is, köszi szépen a javaslatot. Ezt az egészet egyetlen rule-ban végzed, a "tartalom módosítása után" eseményre?
Nálam az a gond, hogy az egyik entity reference mező egy field collection-ben van, erre vonatkozik az előző kód is. Ebben az esetben mind a két ciklusban a mentés utáni objektumot írja ki. Találtam ehhez hasonló jelentés a drupal.org-on, de ott se jutottak semmire.
Még azzal próbálkoztam, hogy két külön szabállyal oldom meg az ügyet: Az első a node mentése előtt indul és törli a második mezőből az elsőben a mentés előtt benne lévő elemeket. A második pedig a frissítés után hozzáadja a mentés utáni állapotnak megfelelő elemeket. Ennek kellene működnie? Nagyon sokat nem tudtam vele kísérletezni, de úgy vettem észre, hogy 1) abban a formában az eredménye még nem jó, 2) a két szabály beleszaladt egy ciklusba.

0
0
ipeto képe

Igazából az általad írtakból kiindulva jóval egyszerűbb a megoldás, mint amibe belebonyolódtam:

  1. A "cél"referencia-mezőt teljesen kiürítem
  2. Készítek egy ciklust a "forrás"referencia mező értékeire
  3. Ezeket az értékeket a "listához hozzáadás" akcióval hozzárakom a célmezőhöz
1
0