Hi

I was looking for some help using the Views API. I want to query on custom fields when I make my node listing so I dont' think I can use the form to generate my page. I am trying to use the various handlers to just make a simple listing available as a first step. I took the example table description from the API.txt file and put it in my module with no changes except the name:

function fhsstadmin_views_tables()
{
  $tables['fhsstadmin_users'] = array(
    "name" => "fhsstadmin_users",
    "join" => array(
      "left" => array(
        "table" => "node",
        "field" => "uid"
      ),
      "right" => array(
        "field" => "uid"
      ),
    ),
// The rest is identical to the API.txt version

  );
  return $tables;
}

From my limited understanding that should actually make the table viewable already? But how to view it?
I tried ?q=fhsstadmin_users , ?q=views/fhsstadmin_users and ?q=fhsstadmin/fhsstadmin_users but none of them do anything? I don't think I need any special handlers or anything like that?

Its probably trivial but how do I bring up the view listing?

Thanks,

Mark

Comments

marknewlyn’s picture

Hi

I am still trying to get this to work. I have realised that, although still not understanding it all, I was really really lost when I first posted my question. My goal :

I have a custom node with data stored in a table "fhsstadmin_evaluation". It has a field "evaluatorid" and it also has nid. I want to list all my nodes where evaluatorid is the current user id. I think this should be very simple with the views module.

Here is where I am now:

I realised what "expose table" means. So I try to make my table available:

<?php
function fhsstadmin_views_tables() {
  $tables['fhsstadmin_evaluation'] = array(
    "name" => "fhsstadmin_evaluation",
    "join" => array(
      "left" => array(
        "table" => "node",
        "field" => "nid"
      ),
      "right" => array(
        "field" => "nid"
      ),
    ),
?>

That should make it available and it has nid so I can join on node.nid=fhsstevaluation.nid.

Then I need to make the correct field from my table available to do the sorting on.

<?php
      "fields" => array(
      "evaluatorid" => array(
        'name' => "Evaluator ID",
//        'handler' => 'views_handler_field_username',
        'sortable' => false,
        'evaluatorid' => "evaluatorid",
        'addlfields' => array("evaluatorid")
      ),
    ),
?>

Now I start to lose it - do I need a handler? Can I use the handler from the views module?

And the last thing I need is a filter to make sure that it actually filters on the available field:

<?php
    "filters" => array(
      "currentuidevaluated" => array(
        'field' => 'evaluatorid',
        'name' => "FHSST: Current User Authored",
        'operator' => array('=' => "touched by"),
        'list' => "views_handler_filter_usercurrent",
        'list-type' => 'select',
        'handler' => "views_handler_filter_uid_evaluated",
        'help' => "This allows you to filter by whether or not the logged in user authored or commented on the node.",
      ),
    ),
  );
  return $tables;
}
?>

Here I think the I need a special handler so I stole the one from the views module and made some approx. random changes to get the function below but I don't really understand what I am doing here - just changed uid to be my field and used the global table stuff.

<?php
function views_handler_filter_uid_evaluated($op, $filter, $filterinfo, &$query) {
  global $VIEWS_TABLES;
  $table_data = $VIEWS_TABLES;
  $joininfo = $table_data['fhsstadmin_evaluation']['join'];
  $joininfo['extra'] = array('evaluatorid' => $filter['value']);
  $tblnum = $query->add_table("fhsstadmin_evaluation", false, 1, $joininfo);
  $table = $query->get_table_name('fhsstadmin_evaluation', $tblnum);

  $query->set_distinct(); // once you do this, there's just one node.
  $query->add_where(" $table.evaluatorid = '%s'", $filter['value'], $filter['value']);
}
?>

The end result is an error from mysql which looks like this:

user warning: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '= fhsstadmin_evaluation. AND fhsstadmin_evaluation.evaluatorid = query: SELECT count(*) AS numrecs FROM node LEFT JOIN fhsstadmin_evaluation fhsstadmin_evaluation ON . = fhsstadmin_evaluation. AND fhsstadmin_evaluation.evaluatorid = '1' WHERE ( fhsstadmin_evaluation.evaluatorid = '1') ORDER BY node.created ASC, node.title ASC, node.title ASC in /var/www/FHSST2/includes/database.mysql.inc on line 124.

I think that there is hope - some of the stuff in the error looks correct. I am sure anyone who has used views successfully can quickly point me in the right direction and I'd really appreciate some help with this.

Thanks,

Mark

--
Mark Horner
Jabber/AIM/Yahoo/Gizmo/Skype/Google: marknewlyn

Co-author:
http://www.nongnu.org/fhsst
http://savannah.gnu.org/projects/fhsst

"Life is but a seg-fault away ...

Life received signal SIGSEGV, Segmentation fault.
0x42074d40 in

patrickharris’s picture

Hi Mark - I'm wanting to do this as well, but I'm afraid I can't help with a solution!
I have a lot of information that I want to be able to search with, and it's hard to decide what info should be part of taxonomy, and what info should be part of a node's data field.

marknewlyn’s picture

I have made much progress through trial and error. I find it hard to debug because I keep modifying my module but things are cached so you need to be careful about making sure you see what you changed. For example I got it working, delete the handler and the view still worked so I thought it didn't matter. Anyway here is the code which has allowed me to make custom views for my module where the nodes listed where written by the current user but the node.uid is different:

<?php
function fhsstadmin_views_tables() {
  $tables['fhsstadmin_evaluation'] = array(
    "name" => "fhsstadmin_evaluation",
    "join" => array(
      "left" => array(
        "table" => "node",
        "field" => "nid"
      ),
      "right" => array(
        "field" => "nid"
      ),
    ),
    "fields" => array(
      "evaluatorid" => array(
        'name' => "Evaluator ID",
        'sortable' => true,
        'evaluatoruid' => "evaluatoruid",
        'addlfields' => array("evaluatoruid")
      ),
    ),
    "filters" => array(
      "currentuidevaluated" => array(
        'field' => 'evaluatoruid',
        'list' => "views_handler_filter_usercurrent",
        'handler' => "views_handler_filter_uid_evaluated",
        'name' => "FHSST: Current User Authored Evaluation",
        'operator' => array('=' => "touched by"),
        'list-type' => 'select',
        'help' => "This allows you to filter by whether or not the logged in user authored or commented on the node.",
      ),
    ),
  );

  $tables['fhsstadmin_mediation'] = array(
    "name" => "fhsstadmin_mediation",
    "join" => array(
      "left" => array(
        "table" => "node",
        "field" => "nid"
      ),
      "right" => array(
        "field" => "nid"
      ),
    ),
    "fields" => array(
      "evaluatorid" => array(
        'name' => "Mediator ID",
        'sortable' => true,
        'evaluatoruid' => "mediatoruid",
        'addlfields' => array("mediatoruid")
      ),
    ),
    "filters" => array(
      "currentuidmediated" => array(
        'list' => "views_handler_filter_usercurrent",
        'handler' => "views_handler_filter_uid_mediated",
        'field' => 'mediatoruid',
        'name' => "FHSST: Current User Authored Mediation",
        'operator' => array('=' => "touched by"),
        'list-type' => 'select',
        'help' => "This allows you to filter by whether or not the logged in user authored or commented on the node.",
      ),
    ),
  );

  return $tables;
}
function views_handler_filter_uid_evaluated($op, $filter, $filterinfo, &$query) {
  global $VIEWS_TABLES;
  $table_data = $VIEWS_TABLES;
  $joininfo = $table_data['fhsstadmin_evaluation']['join'];
  $joininfo['extra'] = array('evaluatoruid' => $filter['value']);
  $tblnum = $query->add_table("fhsstadmin_evaluation", false, 1, $joininfo);
  $table = $query->get_table_name('fhsstadmin_evaluation', $tblnum);

  $query->set_distinct(); // once you do this, there's just one node.
  $query->add_where(" $table.evaluatoruid = '%s'", $filter['value'], $filter['value']);
}


function views_handler_filter_uid_mediated($op, $filter, $filterinfo, &$query) {
  global $VIEWS_TABLES;
  $table_data = $VIEWS_TABLES;
  $joininfo = $table_data['fhsstadmin_mediation']['join'];
  $joininfo['extra'] = array('mediatoruid' => $filter['value']);
  $tblnum = $query->add_table("fhsstadmin_mediation", false, 1, $joininfo);
  $table = $query->get_table_name('fhsstadmin_mediation', $tblnum);

  $query->set_distinct(); // once you do this, there's just one node.
  $query->add_where(" $table.mediatoruid = '%s'", $filter['value'], $filter['value']);
}
?>

I cannot explain why it works necessarily but I am getting there :) Maybe we can turn this into a tutorial for people like me!

It would still be great to have an expert weigh in.

Cheers,

Mark

--
Mark Horner
Jabber/AIM/Yahoo/Gizmo/Skype/Google: marknewlyn

Co-author:
http://www.nongnu.org/fhsst
http://savannah.gnu.org/projects/fhsst

"Life is but a seg-fault away ...

Life received signal SIGSEGV, Segmentation fault.
0x42074d40 in

marknewlyn’s picture

The custom handlers weren't necessary - it should just be:

<?php
    "filters" => array(
      "currentuidevaluated" => array(
        'field' => 'evaluatoruid',
        'list' => "views_handler_filter_usercurrent",
   //     'handler' => "views_handler_filter_uid_evaluated",
        'name' => "FHSST: Current User Authored Evaluation",
        'operator' => array('=' => "touched by"),
        'list-type' => 'select',
        'help' => "This allows you to filter by whether or not the logged in user authored or commented on the node.",
      ),
    ),
  );
?>
 

But now its working properly I think.

-
Mark Horner
Jabber/AIM/Yahoo/Gizmo/Skype/Google: marknewlyn

Co-author:
http://www.nongnu.org/fhsst
http://savannah.gnu.org/projects/fhsst

"Life is but a seg-fault away ...

Life received signal SIGSEGV, Segmentation fault.
0x42074d40 in

patrickharris’s picture

Which part of the code is the un-necessary custom handlers?

marknewlyn’s picture

The commented out line in the filter must go and then you don't need to declare the handler it points at.

<?php
        'handler' => "views_handler_filter_uid_evaluated",
?>

So bascially I made my field available to the views system and then I have the filter which lets me make that field equal to the current users id.

Mark

patrickharris’s picture

I didn't see that commented out line in the code - thanks!

merlinofchaos’s picture

Wow, really really missed this one. Sorry! Here are some comments.

function fhsstadmin_views_tables() {
  $tables['fhsstadmin_evaluation'] = array(
    "name" => "fhsstadmin_evaluation",
    "join" => array(
      "left" => array(
        "table" => "node",
        "field" => "nid"
      ),
      "right" => array(
        "field" => "nid"
      ),
    ),

The above is exactly perfect.

    "fields" => array(
      "evaluatorid" => array(
        'name' => "Evaluator ID",
        'sortable' => true,
        'evaluatoruid' => "evaluatoruid",
        'addlfields' => array("evaluatoruid")
      ),
    ),

There is no point in an additional field here unless you have a handler that uses it; I would remove that. Also, in general Drupal doesn't have IDs available for display, and that's what a 'field' actually means here. I could be wrong, though -- the ID could be meaningful to a user, and I'm making an assumptions.

Second, 'name' => "Module: Evaluator ID" if you would. It helps keep the list of fields readable.

    "filters" => array(
      "currentuidevaluated" => array(
        'field' => 'evaluatoruid',
        'list' => "views_handler_filter_usercurrent",
        'handler' => "views_handler_filter_uid_evaluated",
        'name' => "FHSST: Current User Authored Evaluation",
        'operator' => array('=' => "touched by"),
        'list-type' => 'select',
        'help' => "This allows you to filter by whether or not the logged in user authored or commented on the node.",
      ),
    ),
  );

The above looks good.

  $tables['fhsstadmin_mediation'] = array(
    "name" => "fhsstadmin_mediation",
    "join" => array(
      "left" => array(
        "table" => "node",
        "field" => "nid"
      ),
      "right" => array(
        "field" => "nid"
      ),
    ),

The above looks good.

    "fields" => array(
      "evaluatorid" => array(
        'name' => "Mediator ID",
        'sortable' => true,
        'evaluatoruid' => "mediatoruid",
        'addlfields' => array("mediatoruid")
      ),
    ),

Comment similar to above. My initial guess is that you misunderstand the 'fields' section, likely due to it not being explained very well.

    "filters" => array(
      "currentuidmediated" => array(
        'list' => "views_handler_filter_usercurrent",
        'handler' => "views_handler_filter_uid_mediated",
        'field' => 'mediatoruid',
        'name' => "FHSST: Current User Authored Mediation",
        'operator' => array('=' => "touched by"),
        'list-type' => 'select',
        'help' => "This allows you to filter by whether or not the logged in user authored or commented on the node.",
      ),
    ),
  );
  return $tables;
}

Same comments as above.

function views_handler_filter_uid_evaluated($op, $filter, $filterinfo, &$query) {
  global $VIEWS_TABLES;
  $table_data = $VIEWS_TABLES;

Please don't do this with a global -- use the misnamed _views_get_tables(). This is a clear indication that function is named incorrectly because obviously outside modules may need to call it.

  $joininfo = $table_data['fhsstadmin_evaluation']['join'];
  $joininfo['extra'] = array('evaluatoruid' => $filter['value']);
  $tblnum = $query->add_table("fhsstadmin_evaluation", false, 1, $joininfo);
  $table = $query->get_table_name('fhsstadmin_evaluation', $tblnum);
  $query->set_distinct(); // once you do this, there's just one node.

distinct is its own filter; I wouldn't force it here unless absolutely neccesary.

I realize you found the handlers unnecessary, which is good -- they weren't in this case.

-- Merlin

[Point the finger: Assign Blame!]
[Read my writing: ehalseymiles.com]
[Read my Coding blog: Angry Donuts]

-- Merlin

[Read my writing: ehalseymiles.com]
[Read my Coding blog: Angry Donuts]

marknewlyn’s picture

Thanks for the detailed reply. I'll go through it properly. I think I am getting the hang of things now so it'll hopefully reinforce the things I might understand!

Mark

patrickharris’s picture

It would be great if sometime you could post a tutorial on how to use views module to search a custom node or flexinode.
I'd love to know how to use the api to search, sort, and display info based on both taxonomy, and data within the node.

coupet’s picture

We need a tutorial section called: CUSTOM MODULE and add this thread to it.

Actually, add views to example module

http://drupaldocs.org/api/head/file/contributions/docs/developer/example...

Apache is bandwidth limited, PHP is CPU limited, and MySQL is memory limited.