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:
{ "rules_felhasznalo_og_hozzaad" : { "LABEL" : "Felhasznalok OG-hez rendelese", "PLUGIN" : "reaction rule", "ACTIVE" : false, "OWNER" : "rules", "REQUIRES" : [ "rules", "og" ], "ON" : { "node_update--thesis" : { "bundle" : "thesis" } }, "IF" : [ { "NOT data_is_empty" : { "data" : [ "node:field-user-access" ] } }, { "og_entity_in_group" : { "entity" : [ "node" ], "group" : [ "node:og-group-ref" ] } } ], "DO" : [ { "LOOP" : { "USING" : { "list" : [ "node-unchanged:field-user-access" ] }, "ITEM" : { "list_old_user" : "Eredeti listaelem" }, "DO" : [ { "LOOP" : { "USING" : { "list" : [ "node:field-dolgozat-user-access" ] }, "ITEM" : { "list_user" : "Uj listaelem" }, "DO" : [ { "drupal_message" : { "message" : "Regi: [list_old_user:name] - Uj: [list_user:name]", "type" : "warning" } } ] } } ] } } ] } }
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?
Régi és új értékek
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:
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?
rollback lesz a kulcs
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
Palócz István
https://palocz.hu | https://tanarurkerem.hu
Valami hasonlóval próbálkozom
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.
Igazából az általad írtakból
Igazából az általad írtakból kiindulva jóval egyszerűbb a megoldás, mint amibe belebonyolódtam: