Áttételesen hivatkozott felhasználók elérése Rules-szal

ipeto képe

Sziasztok!

Még mindig a szokásos problémámmal küzdök: Van egy Kurzus tartalom, ahhoz egy node reference mezővel kapcsolódik több Oktató tartalom, az egyes oktatókhoz pedig user reference mezővel a tényleges felhasználó. Az lenne a teendő, hogy az így áttételesen kapcsolt felhasználót adott szerepkörhöz (oktató) rendeljük a Rules modul segítségével. Hogy ez organic group-os vagy normál szerepkör, az lényegében mindegy.
Ha egy kurzusnak csak egy oktatója lenne, az nem lenne gond:
Esemény: tartalom (a Kurzus) módosítása
Feltétel: Mezőkkel rendelkező entitás (Paraméter: Entitás: [node:field-oktato], Mező: field_csatolt_user)
Akció: Felhasználói szerepkör hozzáadása (node:field-targyfelelos:field-csatolt-user - szerepkör: oktató)

A probléma ott jelentkezik, ha a field-oktato mezőnek több értéke is lehet, mivel többnyire csak az egyes mezőelőfordulásokat érem el, pl. field-oktato:0, field-oktato:1 stb.
A feltételben egy VAGY blokkban egyesével megadtam a Mezőkkel rendelkező entitást az előző mintájára (pl. Paraméter: Entitás: [node:field-oktato:0], Mező: field_csatolt_user)
Az akcióban meg gondolom, egy loopot kell definiálni valahogy így: Lista: [node:field-oktato] Listaelem: Kurzus oktatói (kurzus_oktato)
Viszont itt megállt a tudományom. Ugyanis sehogyan sem tudom rávenni, hogy a listán végiglépkedve sorban betöltse a field-oktato:0, :1 stb.-hez kapcsolt field-csatolt-user felhasználót - amit ugye szerepkörhöz kellene rendelni.

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

sehogyan sem tudom rávenni, hogy a listán végiglépkedve sorban betöltse a field-oktato:0, :1 stb.-hez kapcsolt field-csatolt-user felhasználót

Van egy tartalomtípusom (poll), amihez entityreference-vel felhasználókat lehet rendelni (field_users).

Feladat: Ha megtekintenek egy ilyen típusú beküldött tartalmat, irassuk ki a hozzárendelt felhasználók nevét.

Megoldás:

  1. { "rules_node_view_test" : {
  2. "LABEL" : "node_view_test",
  3. "PLUGIN" : "reaction rule",
  4. "OWNER" : "rules",
  5. "REQUIRES" : [ "rules" ],
  6. "ON" : { "node_view--poll" : { "bundle" : "poll" } },
  7. "IF" : [
  8. { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_users" } }
  9. ],
  10. "DO" : [
  11. { "LOOP" : {
  12. "USING" : { "list" : [ "node:field-users" ] },
  13. "ITEM" : { "list_item" : "Current list item" },
  14. "DO" : [ { "drupal_message" : { "message" : [ "list-item:name" ] } } ]
  15. }
  16. }
  17. ]
  18. }
  19. }

0
0
ipeto képe

Köszi szépen, de az a gond, hogy nálam még egy réteg van: Kurzus tartalomtípus --> Oktató tartalomtípus --> User (közöttük reference-mezőkkel)
A szabály exportja így néz ki:

  1. { "rules_oktato_hozzaadas_oktato" : {
  2. "LABEL" : "Oktat\u00f3 hozz\u00e1ad\u00e1sa - oktat\u00f3",
  3. "PLUGIN" : "reaction rule",
  4. "OWNER" : "rules",
  5. "TAGS" : [ "Oktat\u00f3" ],
  6. "REQUIRES" : [ "rules" ],
  7. "ON" : { "node_update--course" : { "bundle" : "course" } },
  8. "IF" : [
  9. { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_oktato" } },
  10. { "OR" : [
  11. { "entity_has_field" : { "entity" : [ "node:field-oktato:0" ], "field" : "field_csatolt_user" } },
  12. { "entity_has_field" : { "entity" : [ "node:field-oktato:1" ], "field" : "field_csatolt_user" } },
  13. { "entity_has_field" : { "entity" : [ "node:field-oktato:2" ], "field" : "field_csatolt_user" } },
  14. { "entity_has_field" : { "entity" : [ "node:field-oktato:3" ], "field" : "field_csatolt_user" } }
  15. ]
  16. }
  17. ],
  18. "DO" : [
  19. { "LOOP" : {
  20. "USING" : { "list" : [ "node:field-oktato" ] },
  21. "ITEM" : { "tantargy_oktato" : "Tant\u00e1rgy oktat\u00f3i" },
  22. "DO" : [
  23. { "drupal_message" : { "message" : "Kurzus oktat\u00f3i: [tantargy-oktato:field-csatolt-user]" } }
  24. ]
  25. }
  26. }
  27. ]
  28. }
  29. }

Tehát az egyedi felhasználókat a loop-ba rakott [tantargy-oktato:field-csatolt-user] adattal lehetne elérni. Amit aztán végképp nem értek, hogy a fenti példában (az üzenet kiírása) ez teljesen jól működik, viszont ez az adat csak direkt input mód helyettesítési mintái között látható, az adatkiválasztóból nem böngészhető ki. Ebből következik(?), hogy a felhasználó szerepváltása akcióban sem fogadja el.

0
0
nevergone képe

Oké, akkor a fenti példában szereplő "poll" tartalomtípus marad, a "blog" tartalomtípus pedig kap egy entityreference mezőt (field_poll), amivel szavazásra lehet hivatkozni. Mindegyik mező korlátlan számú értéket vehet fel.

Feladat: Egy blogbejegyzés megtekintésekor irassuk ki a benne hivatkozott szavazáshoz rendelt felhasználókat.

Megoldás:

Szükséged lesz a Conditional Rules modulra.

  1. { "rules_node_view_blog" : {
  2. "LABEL" : "node_view_blog",
  3. "PLUGIN" : "reaction rule",
  4. "OWNER" : "rules",
  5. "REQUIRES" : [ "rules_conditional", "rules" ],
  6. "ON" : { "node_view--blog" : { "bundle" : "blog" } },
  7. "DO" : [
  8. { "LOOP" : {
  9. "USING" : { "list" : [ "node:field-poll" ] },
  10. "ITEM" : { "selected_poll" : "Selected poll" },
  11. "DO" : [
  12. { "CONDITIONAL" : [
  13. {
  14. "IF" : { "entity_has_field" : { "entity" : [ "selected-poll" ], "field" : "field_users" } },
  15. "DO" : [
  16. { "LOOP" : {
  17. "USING" : { "list" : [ "selected-poll:field-users" ] },
  18. "ITEM" : { "selected_user" : "Selected user" },
  19. "DO" : [ { "drupal_message" : { "message" : [ "selected-user:name" ] } } ]
  20. }
  21. }
  22. ]
  23. }
  24. ]
  25. }
  26. ]
  27. }
  28. }
  29. ]
  30. }
  31. }
1
0
ipeto képe

Úúú, nagyon köszönöm, sikerült!
Mondjuk a belső loop-ra nem volt szükség, ilyesformán működni látszik:

  1. { "rules_oktato_hozzaadas_oktato" : {
  2. "LABEL" : "Oktat\u00f3 hozz\u00e1ad\u00e1sa - oktat\u00f3",
  3. "PLUGIN" : "reaction rule",
  4. "OWNER" : "rules",
  5. "TAGS" : [ "Oktat\u00f3" ],
  6. "REQUIRES" : [ "rules_conditional", "rules" ],
  7. "ON" : { "node_update--course" : { "bundle" : "course" } },
  8. "DO" : [
  9. { "LOOP" : {
  10. "USING" : { "list" : [ "node:field-oktato" ] },
  11. "ITEM" : { "list_oktato" : "Oktat\u00f3k list\u00e1ja" },
  12. "DO" : [
  13. { "CONDITIONAL" : [
  14. {
  15. "IF" : { "entity_has_field" : { "entity" : [ "list-oktato" ], "field" : "field_csatolt_user" } },
  16. "DO" : [
  17. { "user_add_role" : {
  18. "account" : [ "list-oktato:field-csatolt-user" ],
  19. "roles" : { "value" : { "13" : "13" } }
  20. }
  21. }
  22. ]
  23. }
  24. ]
  25. }
  26. ]
  27. }
  28. }
  29. ]
  30. }
  31. }
0
0
nevergone képe

Szia!

Gondolom nálad az oktató tartalomtípus elemeihez csak egy-egy felhasználó tartozhat, ezért volt elég az egy ciklus. Az én példámban pedig mindegyik mező korlátlan számú értéket vehet fel.

Csak egy kérdés a végére: miért kellett az oktató tartalomtípus? (hint)

0
0
ipeto képe

Igen-igen, annak idején dilemmáztunk rajta egy sort, hogy melyik legyen, nagyjából ezek voltak az okok.

0
0
ipeto képe

Üdv!

Újabb probléma vetődött fel az ügyben: Egy olyan szabályra van szükség, amivel karbantarthatók az oktatók, vagyis ha egy tárgyból valaki kikerül, akkor a hozzá kötődő felhasználót leíratkoztatjuk a csoportból, ha valaki bekerül, akkor meg a megfelelő szerepkörrel felvesszük. (Közben áttértem a többek által javasolt Organic Groupra, de a szabály szempontjából ez nem nagy különbség.

A gond onnan fakad, hogy ehhez a feladathoz a következők kellenek:

  • Egy ciklus a mentett tartalom új állapotaihoz: node:field-oktato-entity
  • Egy ciklus a mentett tartalom eredeti állapotaihoz: node-unchanged:field-oktato-entity
  • Egy feltétel, miszerint az eredeti állapotban nem üres a mező
  • Egy feltétel, miszerint az eredeti és az új állapotban eltérő oktató szerepel a mezőben
  • Egy-egy "entity has field" feltétel, amely a field-oktato-entity mező régi és új állapotát kapcsolja az érintett felhasználóhoz
  • Összesen négy akció: a kikerülő felhasználó "oktató" szerepének eltávolítás ill. leíratkoztatása a csoportból, ill. az új felhasználónál ennek a fordítottja.

Namost erre a következő monumentális szabályt rakosgattam össze:

  1. { "rules_og_oktato_karbantart_oktato_entity" : {
  2. "LABEL" : "OG - Oktat\u00f3k karbantart\u00e1sa - oktat\u00f3 - entity",
  3. "PLUGIN" : "reaction rule",
  4. "OWNER" : "rules",
  5. "REQUIRES" : [ "rules_conditional", "og", "rules" ],
  6. "ON" : { "node_update--course" : { "bundle" : "course" } },
  7. "DO" : [
  8. { "LOOP" : {
  9. "USING" : { "list" : [ "node:field-oktato-entity" ] },
  10. "ITEM" : { "list_oktato" : "Oktat\u00f3k list\u00e1ja" },
  11. "DO" : [
  12. { "LOOP" : {
  13. "USING" : { "list" : [ "node-unchanged:field-oktato-entity" ] },
  14. "ITEM" : { "list_oktato_regi" : "Oktat\u00f3k r\u00e9gi list\u00e1ja" },
  15. "DO" : [
  16. { "CONDITIONAL" : [
  17. {
  18. "IF" : { "entity_has_field" : { "entity" : [ "list-oktato" ], "field" : "field_csatolt_user" } },
  19. "DO" : [
  20. { "CONDITIONAL" : [
  21. {
  22. "IF" : { "entity_has_field" : { "entity" : [ "list-oktato-regi" ], "field" : "field_csatolt_user" } },
  23. "DO" : [
  24. { "CONDITIONAL" : [
  25. {
  26. "IF" : { "NOT data_is_empty" : { "data" : [ "list-oktato-regi" ] } },
  27. "DO" : [
  28. { "CONDITIONAL" : [
  29. {
  30. "IF" : { "data_is" : { "data" : [ "list-oktato-regi" ], "value" : [ "list-oktato" ] } },
  31. "DO" : [
  32. { "og_revoke_og_role" : {
  33. "account" : [ "list-oktato-regi:field-csatolt-user" ],
  34. "group" : [ "node" ],
  35. "roles" : { "value" : { "oktat\u00f3" : "oktat\u00f3" } }
  36. }
  37. },
  38. { "og_group_content_remove" : {
  39. "entity" : [ "list-oktato-regi:field-csatolt-user" ],
  40. "group" : [ "node" ]
  41. }
  42. },
  43. { "og_group_content_add" : { "entity" : [ "list-oktato:field-csatolt-user" ], "group" : [ "node" ] } },
  44. { "og_grant_og_role" : {
  45. "account" : [ "list-oktato:field-csatolt-user" ],
  46. "group" : [ "node" ],
  47. "roles" : { "value" : { "oktat\u00f3" : "oktat\u00f3" } }
  48. }
  49. }
  50. ]
  51. }
  52. ]
  53. }
  54. ]
  55. }
  56. ]
  57. }
  58. ]
  59. }
  60. ]
  61. }
  62. ]
  63. }
  64. ]
  65. }
  66. ]
  67. }
  68. }
  69. ]
  70. }
  71. }
  72. ]
  73. }
  74. }

Ezzel egyrészt az a gond, hogy a leíratkoztatás rész nem működik, a másik pedig hogy lényegében tetszőleges mennyiségű memóriát el tud fogyasztani (így igazán tesztelni se könnyű).
Abban szeretnék segítséget kérni, hogyan lehetne ezt takarékosabbra hangolni?

0
0
ipeto képe

Igazából most részben működni látszik a fenti rule, ám az OG-szerepkör megvonásával van némi gond, ezzel a hibaüzenettel száll el:

Recoverable fatal error: Argument 2 passed to og_rules_revoke_og_role() must be an instance of EntityDrupalWrapper, instance of stdClass given og_rules_revoke_og_role() függvényben (.../sites/all/modules/og/og.rules.inc 385 sor).

Számomra ez teljességgel értelmezhetetlen, és igazából hasonlót sem nagyon találtam az OG issue-i között. Tudna valaki segíteni, hogy ez bug vagy én szúrtam el valamit a rule-ban?

0
0
ipeto képe

Nem tudom, ez közelebb visz-e a megoldáshoz, mindenesetre ezt a viselkedést se értem. Kicsit átírtam a fenti rule-t, akcióként csak üzenetet kiírva. Tehát azt kellene csinálnia, hogy egy több értéket kezelő mezőnél kiírja a régi és új értéket ott, ahol az változott:

  1. { "rules_og_oktato_karbantart_oktato_teszt" : {
  2. "LABEL" : "OG - Oktat\u00f3k karbantart\u00e1sa - oktat\u00f3 - teszt",
  3. "PLUGIN" : "reaction rule",
  4. "OWNER" : "rules",
  5. "REQUIRES" : [ "rules_conditional", "rules" ],
  6. "ON" : { "node_update--course" : { "bundle" : "course" } },
  7. "DO" : [
  8. { "LOOP" : {
  9. "USING" : { "list" : [ "node:field-oktato" ] },
  10. "ITEM" : { "list_oktato" : "Oktat\u00f3k list\u00e1ja" },
  11. "DO" : [
  12. { "LOOP" : {
  13. "USING" : { "list" : [ "node-unchanged:field-oktato" ] },
  14. "ITEM" : { "list_oktato_regi" : "Oktat\u00f3k r\u00e9gi list\u00e1ja" },
  15. "DO" : [
  16. { "CONDITIONAL" : [
  17. {
  18. "IF" : { "data_is" : { "data" : [ "list-oktato:type" ], "value" : "munkatars" } },
  19. "DO" : [
  20. { "CONDITIONAL" : [
  21. {
  22. "IF" : { "data_is" : { "data" : [ "list-oktato-regi:type" ], "value" : "munkatars" } },
  23. "DO" : [
  24. { "CONDITIONAL" : [
  25. {
  26. "IF" : { "NOT data_is_empty" : { "data" : [ "list-oktato-regi" ] } },
  27. "DO" : [
  28. { "CONDITIONAL" : [
  29. {
  30. "IF" : { "NOT data_is" : { "data" : [ "list-oktato-regi" ], "value" : [ "list-oktato" ] } },
  31. "DO" : [
  32. { "drupal_message" : { "message" : "R\u00e9gi: [list-oktato-regi:nid]-[list-oktato-regi:title] \u00daj: [list-oktato:nid]-[list-oktato:title]" } }
  33. ]
  34. }
  35. ]
  36. }
  37. ]
  38. }
  39. ]
  40. }
  41. ]
  42. }
  43. ]
  44. }
  45. ]
  46. }
  47. ]
  48. }
  49. ]
  50. }
  51. }
  52. ]
  53. }
  54. }
  55. ]
  56. }
  57. }

A tesztelésnél két értéke volt a mezőnek: régi1 és régi2, utóbbit átírtam új2-re. Tehát véleményem szerint a fenti szabálynak így csak egy üzenetet kellene kiírnia, merthogy benne van a list-oktato-regi <> list-oktato feltétel.
Ehhez képest a következő hármat adta vissza:
régi2 - régi1
régi1 - új2
régi2 - új2

Ezek alapján nyilván elronthatok valamit a rule összerakásában, de nem igazán találom, hogy mit.:S

SZERK.

Ja, és ami még érdekes, hogy akkor is lefuta a szabály, amikor változás nélkül mentem el, rádásul két üzenettel tér vissza:
régi1 - régi2
régi2 - régi1

0
0
ipeto képe

Közben rájöttem, hogy az előző probléma onnan eredhet, hogy a két egymásba ágyazott ciklusban leképződik minden lehetséges kombináció, noha nekem csak a régi1 vs. új1, régi2 vs. új2 stb. összehasonlításokra lenne szükségem.
Lehet olyan feltételk készíteni, amiben a mezők aktuális delta-értékét hasonlítom össze?

0
0