Műveletek hook_views_data mező értékével

Dibusz Tamás képe

Sziasztok!

Adott mymodule modul és egy adatbázis, melyből adatokat olvasunk ki, gyönyörű táblázatok formájában a Views modul segítségével. Minden szép, minden működik. Viszont a kiolvasott adatokkal műveleteket szeretnék végezni, méghozzá a modulon belül.
Gúgli barát és az API (felületes) tanulmányozása után sem vagyok biztos benne, hogy jó-e az elképzelésem, mely szerint ezt egy saját views handleren keresztül lehet megoldani. Nem értem ugyanis maradéktalanul a views működését.
Abban kérném a segítségeteket, hogy a mellékelt példánál maradva, hogyan tudok modulból, számított értéket megjeleníteni. Az lenne a lényeg, hogy ne a nézetben kerüljön az érték kiszámításra, hanem itt a hook_views_data függvényen belül tudjam módosítani.
Alant mellékelem az elképzelést, amely nem működik.

<?php
 
/**
 *                                                          
 * mymodule.views.inc nevű fájl tartalma
 *
 */
 
/**
 *
 * Implementation of hook_views_data.
 *
 */
 
 function mymodule_views_data () {
  $data['mytable']['table']['group'] = t('My DataBase table');
 
 
   $data['mytable']['table']['base'] = array (
      'field' => 'number',
      'title' => t('Number'),
      'help' => t('Nr. of item.'),
      );
 
 
   $data['mytable']['price'] = array(  //ennek a mezőnek az ÉRTÉKÉVEL szeretnék dolgozni. mondjuk netto értékem van, bruttót szeretnék megjeleníteni.
    'title' => t('Price'),
    'help' => t('Item price'),
    'field' => array(
      'handler' => 'mymodule_views_handler_field',
      'format' => FILTER_FORMAT_DEFAULT,
      'click sortable' => FALSE,
    ),
    'argument' => array(
      'handler' => 'views_handler_argument_numeric',
    ),
    'filter' => array(
      'title' => t('Item code'),
      'handler' => 'views_handler_filter_numeric',
    ),
    'sort' => array(
      'handler' => 'views_handler_sort',
    ),
  );
 
    return $data;
 
  }
 
function mymodule_views_handlers() {  //létrehoztam a saját handler-t
  return array(
    'info' => array(
      'path' => drupal_get_path('module', 'mymodule') . '/includes/views',
    ),
    'handlers' => array(
      'mymodule_views_handler_field' => array( //<-
        'parent' => 'views_handler_field',
      ),
    ),
  );
}

/**
 *
 * mymodule_views_handler_field_inc nevű fájl tartalma
 *
 */
 
<?php
 
class mymodule_views_handler_field extends views_handler_field {
 
  $sales_tax = 1.27; // pl. áfa értéke, ezzel szeretném felszorozni a mező netto értékét.
 
// ide nem tudom mi jön. hogyan kérdezem le a mező értékét? hogyan adom vissza? az alábbi megoldással próbálkoztam:
 
  function get_value($values, $field = NULL) {
 
  if (isset($this->definition['title'])) {
      if ($this->definition['title'] == 'Price') {
	$field_value = $this->value;
	$this->value = ($field_value * $sales_tax);
     }
    }
 
  return $this->value;
  }
}
Melyik modulhoz, modulokhoz kapcsolódik a téma?: 
Drupal verzió: 
Dibusz Tamás képe

A feladat a hook_views_pre_render(&$view) függvény segítségével oldódott meg. Alant a kód.

<?php
 
/**
 * mymodule.module fájl tartalma                            
 */
 
//yourcode
 
function mymodule_views_pre_render(&$view) {
 
   if ($view->name=='myviewmachinename') {
 
     drupal_set_message('<pre>' . print_r($view, TRUE). '</pre>');
 
   }
}
 
// yourcode
0
0
Sk8erPeter képe

Ez biztos jó megoldás? Csak kérdezem, mert akkor nem vágom, mi lesz a handlereddel, akkor lényegében azt kiiktattad?
Igazából nem írtad le, hogy mit értettél azalatt, hogy "nem működik", pedig engem érdekelne. Nem ad kimenetet egyáltalán? Vagy ad, csak nem szorzódik be az ÁFA értékével?
Nem mellékes az sem (sőt), hogy lokális változót próbáltál használni a kódodban:

  1. class mymodule_views_handler_field extends views_handler_field {
  2.  
  3. $sales_tax = 1.27; // pl. áfa értéke, ezzel szeretném felszorozni a mező netto értékét.
  4.  
  5. function get_value($values, $field = NULL) {
  6. // ...............
  7.  
  8. // az alábbi sorban $sales_tax helyett
  9. // $this->sales_tax kéne, hogy szerepeljen
  10. $this->value = ($field_value * $sales_tax);
  11.  
  12. // ...............
  13. }
  14.  
  15. }

Szóval a $sales_tax helyett $this->sales_tax kéne.
A konkrét megoldást nem tudom, de észrevettem a hibát, és engem is érdekel a végkifejlet.
0
0
Dibusz Tamás képe

Egyenlőre handler nélkül gondolom megoldani.
Ez alapján indultam el http://techblog.zabuchy.net/2010/non-database-field-in-custom-drupal-vie... de csak részleteiben értem.
Saját példára vonatkoztatva, nem adott kimenetet. De nagyon este volt már, az általad említett hibát sem vettem észre.

A hook_views_pre_render viszont egy gyönyörű $view tömböt ad vissza, benne minden adattal, ami a nézetben meg lesz jelenítve. Így csak végigmegyek a tömbön, elvégzem a megfelelő műveleteket és kész.

De egyszer még a handleres példának is nekifutok.

0
0
Sk8erPeter képe

egyeLőre

Ez alapján indultam el http://techblog.zabuchy.net/2010/non-database-field-in-custom-drupal-vie... de csak részleteiben értem.

Megnéztem az általad linkelt példát, itt sehol sem használja a get_value() metódust. Te miért azzal próbálkozol?
A render() metódust használja fel, szerintem neked is azzal kellene próbálkoznod!
Az pedig így néz ki:
http://api.drupal.org/api/views/handlers%21views_handler_field.inc/funct...

  1. // ...
  2.  
  3. /**
  4.   * Render the field.
  5.   *
  6.   * @param $values
  7.   * The values retrieved from the database.
  8.   */
  9. function render($values) {
  10. $value = $this->get_value($values);
  11. return $this->sanitize_value($value);
  12. }
  13.  
  14. // ...

Tehát szerintem nálad is ezt a metódust kellene felhasználni. Elvileg itt is tudnál mit kezdeni a saját, adatbázisból jövő értékeiddel.
Nézd meg ezt a példát is (mondjuk ez már Views 3 API, de most itt nagy különbség nincs):
http://www.heididev.com/custom-field-handlers-views-3
a példa 3-as pontjában pont a render()-ben végzi el a saját adatainak tetszőleges kiíratását:

  1. class video_handler_field_video_duration extends views_handler_field {
  2.  
  3. function render($values) {
  4. if (!empty($values->video_queue_duration))
  5. return gmdate("H:i:s", $values->video_queue_duration);
  6. else
  7. return NULL;
  8. }
  9.  
  10. }
0
0
Dibusz Tamás képe

Köszönöm, átnézem.

Azért próbálkoztam a get_value() -val, mert azt hittem a render a megjelenítésre szolgál. Hiszen az említett példában csak karakterláncot ad vissza.
Ezek szerint az alap elképzelés, mely szerint ez egy saját handlerrel megoldható, működőképes lehet. Nem értettem hogyan olvasom ki a mező értékét. De már kezd összeállni a kép.
Elég felületes az angolom, ebből adódóan nem miden részét értem az API-nak. A hiányosságokat a lelkesedés pótolja. :)
Ha működik, leírom a megoldást.

0
0
Sk8erPeter képe

azt hittem a render a megjelenítésre szolgál

Ezt nagyon jól hitted. De nem egészen értem, miért "baj", hogy megjelenítésre szolgál... :) Ha jól értettem, Te egy adott fieldből annak az ÁFÁ-val növelt értékét szeretnéd megjeleníteni, és kész. Nem?

0
0
Dibusz Tamás képe

Mindenki okulására, ha valaki ilyesmibe vágná a fejszéjét...

A views (egy előzőleg becsatolt tábláblát, létrehozott nézetet feltételezünk) visszaad egy view nevű objektumot. Ennek az objektumnak a felépítését a nézet megjelenítési oldalára kiírathatjuk az alábbi kóddal:

/**
 * mymodule.module fájl tartalma               
 */
 
function mymodule_views_pre_render(&$view) {
 
   if ($view->name=='my_views_machine_name') { //a nézet (gépi) neve
 
                drupal_set_message('<pre>' . print_r($view, TRUE). '</pre>'); // vagy $view->result
 
     }

Ebből jelen esetben a [result] tömb érdekes, ebben szerepelnek ugyanis a megjeleníteni kívánt adatok. Innen könnyedén kiolvasható a saját handlerhez szükséges mezőnév (v. mezőnevek).

A mellékelt példa a machine_name_of_MYFIELD nevű mezőre van vonatkoztatva, és borzasztóan bonyolult eljárást alkalmaz, hogy szemléltesse a mező értékének felülírását a kimenetre. Megjegyzendő, hogy a mező értéke nem változik meg, pusztán a nézetben való megjelenését befolyásolja!

<?php
 
/**
 * mymodule_views_handler_field fájl tartalma               
 */
 
class mymodule_views_handler_field extends views_handler_field {
 
  function render($values) {
 
    //yourcode, variables, etc...
 
/**
 * pl. $values->machine_name_of_MYFIELD = 1;                
 */
 
  return $values->machine_name_of_MYFIELD; //a lényeg, hogy a mező nevét meg kell adni a visszatérési értéknél.
 
  }
}
0
0
Sk8erPeter képe

Tehát akkor ezek szerint az volt a megoldás, amit itt már leírtam.

Javaslom, hogy debuggolásra használd inkább a Devel modul dsm() függvényét.
Példa:

  1. dsm($view, '$view in '.__FUNCTION__.'()'); // vagy $view->result
1
0