Adott szótát kifejezései egyszerre csak egy node-hoz tartozhassanak

brtamas képe

Sziasztok!

Van egy oldal, ahol kérés volt, hogy a tartalmakat tetszőlegesen lehessen pozicionálni (tehát mondjuk mi kerüljön címlap első helyre, baloldalt második helyre, stb.).

Ehhez létrehoztam egy szótárt, amiben lévő kifejezések jelölik a pozíciókat.
Azt szeretném elérni, hogy egy pozíció kifejezés egyszerre csak egy node-hoz tartozhasson.
Ezt úgy érem el, hogy új node mentésekor vagy node módosításakor a korábbi nodokról (ha volt rajtuk, akkor) leveszi az adott kifejezést.
Ezt a levételt egyenesen az adatbázisban hajtom végre. A következő táblákat manipulálom (a megfelelő field neve: structure):

field_data_field_structure
field_revision_field_stucture
taxonomy_index
cache_field

Ezekből törlöm a megfelelő sorokat.

Az a kérdésem, hogy a drupal 7 máshol is tárolja azt az információt, hogy egy node adott fieldjéhez milyen termek vannak hozzárendelve, vagy elég ezekből kitörölnöm?

Kösz a segítséget!
Minden jót!

brtamas képe

Beillesztem a kódot is, hátha valaki tudja majd használni még...

function unique_term_node_insert($node){
   unique_term_make_term_unique($node); 
}
 
function unique_term_node_update($node){
   unique_term_make_term_unique($node); 
}
 
function unique_term_make_term_unique($node){
    if(!empty($node->status) && $node->status && !empty($node->field_structure)){
        $tids= field_get_items('node', $node, 'field_structure');
        if(is_array($tids)){
            foreach($tids as $tid){
                $query= db_select('field_data_field_structure', 'fdfs');
                $query->condition('fdfs.entity_type', 'node');
                $query->condition('fdfs.field_structure_tid', $tid['tid']);
                $query->condition('fdfs.entity_id', $node->nid, '<>');
                $query->fields('fdfs', array('entity_id'));
                $result= $query->execute()->fetchAll();
 
                if(is_array($result)){
                    foreach($result as $record){
                        if(!empty($record->entity_id)){
                            $update_nid= $record->entity_id;
                            $update_node= node_load($update_nid);
 
                            // Deleting
 
                            // Field data
                            $query= db_delete('field_data_field_structure');
                            $query->condition('field_structure_tid', $tid['tid']);
                            $query->condition('entity_type', 'node');
                            $query->condition('entity_id', $update_nid);
                            $query->execute();
 
                            // Revision data
                            $query= db_delete('field_revision_field_structure');
                            $query->condition('field_structure_tid', $tid['tid']);
                            $query->condition('entity_type', 'node');
                            $query->condition('entity_id', $update_nid);
                            $query->condition('revision_id', $update_node->vid);
                            $query->execute();
 
                            // Term index
                            $query= db_delete('taxonomy_index');
                            $query->condition('tid', $tid['tid']);
                            $query->condition('nid', $update_nid);
                            $query->execute();
 
                            // Field cache
                            $query= db_delete('cache_field');
                            $query->condition('cid', 'field:node:'.$update_nid);
                            $query->execute();
                        }
                    }  
                }
            }
        }
    }
}
0
0
aruna képe

"Az a kérdésem, hogy a drupal 7 máshol is tárolja azt az információt, hogy egy node adott fieldjéhez milyen termek vannak hozzárendelve, vagy elég ezekből kitörölnöm?"

nem tudom a választ. De igazából nem szerencsés így csinálni (bár megismered így a táblákat), mert pont erre vannak az API függvények, amiknek az a dolguk, hogy minden táblában takarítsanak, ahol kell.

Én így állnék neki:

- A hook_node_presave() hook-ot implementálnám csak.

- Ebben a hook-ban a $node tartalmazza a term id-t ($tid). A term id-vel betöltheted az összes node-ot, ami még ehhez a term-hez van hozzárendelve a taxonomy_select_nodes() függvénnyel.

- A betöltött node-okon végigtekersz egy ciklussal, és megszünteted a hozzárendelésüket az adott term-hez, és elmented mindegyik node-ot.

SZERK: Valahogy így, nem próbáltam a kódot!

function unique_term_node_presave($node) {
  if(!empty($node->status) && $node->status && !empty($node->field_structure)){
    $tids= field_get_items('node', $node, 'field_structure');
    if(is_array($tids)){
      foreach($tids as $tid){
        if ($nids = taxonomy_select_nodes($tid) ) {
          $nodes = node_load_multiple($nids);
          foreach ($nodes as $node_obj) {
            foreach($node_obj->field_structure[$node_obj->language] as $index => $tag) {
              if($tag['tid'] == $tid) {
                unset($node_obj->field_structure[$node_obj->language][$index]);
              }   
            }
            node_save($node_obj);
            watchdog('content', 'Node saved: %title.', array('%title' => $node_obj->title), WATCHDOG_NOTICE, l(t('view'), 'node/' . $node_obj->nid));
          }
        }
      }
    }
  }
}
1
0
brtamas képe

Igen, először én is így próbáltam.

De ha jól gondolom ezzel az a gond, hogy amikor a többi noderól leveszi a termet és meghívja azokra a node_save függvényt, akkor azoknál is lefut a node_presave hook, és így szépen (ha jól sejtem) végtelen ciklusba esik a rendszer.

Jól gondolom?

Köszönet a hozzászólásokért!

0
0
aruna képe

erre nem is gondoltam.

A node_save() tényleg meghívja a hook_node_presave() hook-ot:

// Let modules modify the node before it is saved to the database.
module_invoke_all('node_presave', $node);
module_invoke_all('entity_presave', $node, 'node');

Nekem is úgy tűnik, hogy végtelen ciklusba kerül a fenti kód.

Érdekelne, mi az elegáns megoldás erre.

0
0
brtamas képe

field_sql_storage_field_storage_write
Találtam egy ilyet:

http://timonweb.com/how-insert-and-update-only-specific-fields-your-enti...

Itt a field_sql_storage_field_storage_write függvényt ajánlja plusz cache ürítést. Nagyjából azt csinálja, amit én, bár ha jól látom akkor a taxonomy_index táblával nem foglalkozik.

Nodequeue

A nodequeue modul nagyon ígéretes, valóban termenként lehet csinálni egy sort, aminek ráadásul meg lehet határozni a max hosszát. Tehát ha mondjuk a pozíciók szótárra kérem ezt, akkor az összes termnél lesz egy egy hosszú sor.

Ennek a szépséghibája az az, hogy a node szerkesztésénél külön tab-on kell szerkeszteni a queue-ket (hozzáadás, eltávolítása). Egyenlőre beta állapotú a modul. Van ebben olyan funkció, hogy a node szerkesztő űrlapon kért termek esetében a node-ot automatikusan berakja a term-queue elejére, és a queue-ből kitolódó nodeokról meg leveszi? Ha ez menne, akkor meg lenne a megoldás, még több is annál. Így valóban csak a modult kellene telepítenem, és az oldal üzemeltetőinek se kellene új használatot megtanulni.

Én ezt nem találtam meg, esetleg valaki jobban ismeri ezt a modult?

Kösz a segítséget!

0
0
gazsesz képe

Ezt Rules modullal a d6-ban meg símán meg lehet csinálni, de d7-ben tudtommal még nincs a Nodequeue modulnak Rules integrációja.

Azt viszont tudja, hogy nem is kell szerkeszteni a node-ot, mert full node nézetben alatta megjelennek a létrehozott és engedélyezett queue-k, így csak egy kattintás és kész.

Persze a sorrendet manuálisan kell módosítani.

1
0

Gazsesz

chx képe

"Ezt a levételt egyenesen az adatbázisban hajtom végre"

"Az a kérdésem, hogy a drupal 7 máshol is tárolja azt az információt, hogy egy node adott fieldjéhez milyen termek vannak hozzárendelve, vagy elég ezekből kitörölnöm?"

Ha nem az adatbazisban matatnal kezzel nem kene ilyesmit kerdezned. Arra vannak kulonbozo API-ok hogy ilyesmit ne kelljen megkerdezni mert erre a valasz csak es kizarolag az lehet: fogalmunk sincs. Ez attol fugg milyen module-okat futtatsz milyen beallitasokkal. Egy ennyire kiterjesztheto rendszerben csak akkor nyulunk kozvetlenul az adatbazishoz ha eg a haz.

3
0
gazsesz képe

Szerintem erre a legjobb megoldás a Nodequeue modul. Pontosan ezt a funkciót valósítja meg, drag&drop módon is tudod a sorrendet változtatni, views integráció, etc minden van.

2
0

Gazsesz