Page 1 of 1

Action Condition: field exists?

PostPosted: Tue Feb 02, 2010 5:49 pm
by 00Davo
I've got an "email" action set up, which lists all the email addresses in the current set in a nice, tidy, comma-delimited list, ready to copy-and-paste for sending. However, I'm having trouble with the condition for it. I want it to show up if the current table has an "email" field. All I can figure out is checking $query['-table'], which works fine for normal lists, but fails if I have a relationship list. Is there a specific way to check if a field exists?

My current condition, incidentally, looks like this:
Code: Select all
$table == "adult" || $table == "student"

It shows up just fine on the Adult and Student tables, but doesn't appear at all in, say, the relationship from Production to Student.

Re: Action Condition: field exists?

PostPosted: Thu Feb 04, 2010 12:03 pm
by shannah
Your condition can actually call any php function. So you can define your own function to check this and refer to the function from your condition.

e.g.
In one of your included files:
Code: Select all
function containsEmailField($table){
    ....
}

In your condition directive in the actions.ini file:
Code: Select all
condition="containsEmailField($query['-table'])"

Re: Action Condition: field exists?

PostPosted: Thu Feb 04, 2010 10:35 pm
by 00Davo
Yes, I had realised that. This wasn't my actual issue. As I said, I can check $query['-table'] just fine. The problem is that, when you're viewing a relationship, $query['-table'] == the source table, and not the one you can actually see. So if I created the function:
Code: Select all
condition="containsEmailField($query['-table'])"

$query['table'] == "student"
student contains "email"
true

$query['table'] == "production"
$query['relationship'] == "students"
student does contain email, however
production does not contain "email"
false

The second result should really return a true, since it's the relationship we're actually concerned with.

Re: Action Condition: field exists?

PostPosted: Mon Feb 08, 2010 12:58 pm
by shannah
Perhaps your function could take the entire query array as a parameter instead of just the table name.
e.g.
Code: Select all
condition="containsEmailField($query)"


Then this $query array will contain all of the necessary tidbits you need. E.g.
$query['-table'] = the current table name
$query['-relationship'] = The current relationship name
$query['-action'] = The current action (e.g. list, find, view)

You might have something like this:

Code: Select all
function containsEmailField($query){
    if ( is_string($query) ){
        // $query is just a table name so lets figure out whether this table has an email field.
        .... etc...
        return ....
    } else if ( is_array($query) ){
        if ( isset($query['-table']) and isset($query['-relationship']) and $query['-action'] == 'related_records_list' ){
            $domainTable = Dataface_Table::loadTable($query['-table'])->getRelationship($query['-relationship'])->getDomainTable();
            return containsEmailField($domainTable);
        } else if ( isset($query['-table']) ){
            return containsEmailField($query['-table']);
        }
    }
    return false;
}

Re: Action Condition: field exists?

PostPosted: Mon Feb 08, 2010 10:23 pm
by 00Davo
This seemed like a good idea, so I stole your function (with slight changes):
Code: Select all
function containsField($query, $field){
    if ( is_string($query) ){
        return Dataface_Table::loadTable($query)->hasField($field);
    }
   else if ( is_array($query) ){
        if ( isset($query['-table']) and isset($query['-relationship'])){
            $domainTable = Dataface_Table::loadTable($query['-table'])->getRelationship($query['-relationship'])->getDomainTable();
            return containsField($domainTable, $field);
        } else if ( isset($query['-table']) ){
            return containsField($query['-table'], $field);
        }
    }
    return false;
}

The code looks just fine. However, it only seems to work, like the previous code, when I'm on the table directly, and not through a relationship.

Experimentally, I tacked this line in for debug:
Code: Select all
...
        if ( isset($query['-table']) and isset($query['-relationship'])){
            $domainTable = Dataface_Table::loadTable($query['-table'])->getRelationship($query['-relationship'])->getDomainTable();
         echo "The domainTable is equal to $domainTable"; // this one here
            return containsField($domainTable, $field);
...


And in viewing the source, I get this little message at the top:
"The domainTable is equal to student "
Note that there appears to be a space on the end of student, which (I assume) is why it doesn't load it properly. So, what's up with that? :?

Re: Action Condition: field exists?

PostPosted: Mon Feb 08, 2010 11:04 pm
by shannah
That is bizarre. I can't see any way there should be a space there. Can you retry with the output:
Code: Select all
echo "The domainTable is equal to [$domainTable]";

instead so that you can see definitively whether a space exists?

Re: Action Condition: field exists?

PostPosted: Mon Feb 08, 2010 11:08 pm
by 00Davo
Looks like the space isn't actually part of the variable, since I got this afterwards:
"The domainTable is equal to [student] "
This still doesn't explain why that function isn't working, though. If it matters, I'm actually calling it like this:
Code: Select all
condition="containsField($query, 'Email')"

Re: Action Condition: field exists?

PostPosted: Mon Feb 08, 2010 11:17 pm
by shannah
Hard for me to comment on where the problem is. Best if you can write a short minimal test case with expected result and actual result, and I can comment on how we might narrow it down.

Re: Action Condition: field exists?

PostPosted: Mon Feb 08, 2010 11:26 pm
by 00Davo
No need. I'd like to facepalm now, because I am an idiot. Y'know how there's categories for actions? Here was my previous email action:
Code: Select all
[email]
   label = Email Address List
   description = "Provides a list of email addresses for the current set. Use this to send an email to everyone in the current set."
   url = "{$this->url('-action=email')}"
   category = result_list_actions
   icon = "{$dataface_url}/images/mail_icon.gif"
   condition="containsField($query, 'Email')"
   permission = view

It doesn't appear in related lists, naturally. Guess what happens when I add this to the end?
Code: Select all
[rel_email > email]
   category=related_list_actions

It shows up, the way it's supposed to. Immediately after I refresh. :lol:

I think I need to tweak the action slightly to make it actually work on related lists, but this problem is solved.

EDIT: Ding! Looks like it all works now. Thanks very much. :D