VotingAPI and actions: Major improvements

Events happening in the community are now at Drupal community events on www.drupal.org.
eaton's picture

One of the major VotingAPI improvements that's been in the pipeline for a while is an overhaul of integration with the Actions module. At present, the voting_actions module is used to set up specific vote results that will trigger things like promoting a node to the front page, or unpublishing it. There are some problems with the approach, though. First, there was no way for module authors to provide 'built-in' voting actions. Everything had to be set up by users. Second, there was no way to make decisions about action execution based on the content rather than the vote. In other words, polls need 10 votes to be promoted, but stories need 15. Third, there's really no reason that the functionality should be in a separate module -- actions integration should be exposed as an API for module writers, and should be tweakable by users who want more customization. It's a bit like the Views module philosophy: modules can expose default bviews, but users can make their own or override the defaults. To that end, the new VotingAPI actions system has been re-written. All the core code IS present, though the end-user UI for creating and overriding actions is still being written.

To give an idea of how the system works, here's a snippet of code from a development version of SimpleVote:

function simplevote_votingapi_action_sets() {
  $sets = array(
    'simplevote_promotion' => array(
      'name' => 'SimpleVote promotion',
      'content_type' => 'node',
      'mask' => 'AND',
      'enabled' => 1,
      'source' => 'SimpleVote',
      'conditions' => array(
        array(
          'description' => 'Node is not promoted',
          'handler' => 'votingapi_node_properties_handler',
          'value' => array(
            'property' => 'promote',
            'comparison' => '!=',
            'value' => 1,
          ),
        ),
        array(
          'description' => 'More than 5 voters',
          'handler' => 'votingapi_vote_result_handler',
          'value' => array(
            'function' => 'count',
            'tag' => 'vote',
            'comparison' => '>',
            'value' => 5,
          ),
        ),
        array(
          'description' => 'Average higher than 75',
          'handler' => 'votingapi_vote_result_handler',
          'value' => array(
            'function' => 'average',
            'tag' => 'vote',
            'comparison' => '>',
            'value' => 75,
          ),
        ),
      ),
      'actions' => array(
        'action_node_promote',
      ),
    ),
  );
 
  return $sets;
}

That snippet registers an action that will promote to the front page any nodes that receive an average vote of 75 or higher AND have been voted on by at least five people AND have not already been promoted. (The last condition is just to avoid watchdog spam and unecessary db work). No user intervention is necessary to set this up, other than enabling votingapi and simplevote.

There's a lot more to it than that -- modules can register their own criteria handlers for custom condition checking, and it's possible to nest action sets for advanced conditional branching. But the path is clear, and progress is being made. Are there any thoughts from users and module developers? Requests or comments?

Sound off!

Comments

a better voting default.

augustin's picture

Hello eaton,

I hope you don't mind too much my first contributions to this group.

Requests or comments?

My main request would be that Approval voting (vote for more than one option) should be the default whenever creating a new poll. Obviously, the poll creator should be able to overide this with any other available polling method, but the current and common default, plurality voting (chose one and only one option among many) has severe faults and poll creators tend to abuse it (i.e. use it when Approval voting would be a much better choice) mostly because they are ignorant of alternatives.

In most situations (at least 95% of cases), Approval voting could be a nice default.

--
www.reuniting.info
Healing with Sexual Relationships.
www.wechange.org
We live in a world of solutions.

.

--
www.reuniting.info
Healing with Sexual Relationships.
www.wechange.org
We live in a world of solutions.

Some confusion :-)

eaton's picture

My main request would be that Approval voting (vote for more than one option) should be the default whenever creating a new poll.

Thanks for the note. Sadly, the 'poll' module that ships with Drupal by default (and is being used on this site) isn't based on VotingAPI. It should be fairly easy to whip up a patch for it that makes multiple-choice polls possible, but that would have to wait until Drupal 4.8 development is underway.

I've posted a more detailed response to your other post; the kinds of voting systems you're talking about are possible to implement using the VotingAPI, and there are even a few projects I've heard about that are using it for such things.

--Jeff Eaton

Eaton, A few months ago, I

augustin's picture

Eaton,

A few months ago, I have read a comment about the core poll.module saying that Approval voting was possible for 4.7. Apparently, it is not :(

(I hope you understand what I mean when I say 'approval voting' and 'plurality voting').

As far as your voting API is concerned, if I understand the description on your page, Approval voting is already possible, but I am not sure.

When modules use your API, do they have to precise explicitely all the time the voting method to be used, or is there an implicit default?

A.

--
www.reuniting.info
Healing with Sexual Relationships.
www.wechange.org
We live in a world of solutions.

.

--
www.reuniting.info
Healing with Sexual Relationships.
www.wechange.org
We live in a world of solutions.

Default...

eaton's picture

The default is a simple 'apply a numerical rating to a piece of content' voting style. By adding separate vote-tags, changing the value_tyle, or implementing a custom calcuation rule, however, any voting system can leverage the API to completely alter the behavior of its voting while still leveraging the API's other advantages (ballot-stuffing prevention, storage independence, actions integration, views integration for filtering and display of results, etc.)

In other words, yes. Approval voting is definitely possible. I'm working on more complete docs for the API that make it obvious how to leverage the features to accomplish goals like that.

Poll.module is pretty simple: it was originally included in (I believe) Drupal 3.0! Several people have mentioned porting poll.module to VotingAPI, which would allow it to support things like approval voting and write-in choices. But that's something I haven't had a chance to tackle yet. Finising work on the 'moderation queue' concept, and comment moderation, is high on the priority list right now ;)

--Jeff

Whoops.

eaton's picture

Just did a bit of checking; the system I mentioned would NOT in fact be Condorcet voting, but 'Borda Count' voting. Condorcet is still possible, it'd just require more of the work to be done in a custom 'calculation' handler.

--Jeff

Some quick thoughts.

eaton's picture

I'm still meandering through my thouhgts on this.

If you're looking at making something that's usable by ALL CMS packages, have you considered NOT writing any plugin modules, but rather writing a package of helpful PHP functions that JUST accept ballot/vote data, and return a list of ranked winners/results?

It seems to me that the algorithms for these different styles of voting, nd implementing them properly, are the tricky part for most voting systems. If you were to release it as a GPL'd system-agnostic set of PHP functions (rather than a specific class library or plug-in), voting systems for almost any CMS would be able to take advantage of it by linking it in or integrating the code directly...

Any thoughts?

Moral, if not technical support

simplulo's picture

I am in strong and complete agreement with you about the need to spread better voting systems; I was one of those responsible for seeing that the Free State Project use a more fair voting system:
http://freestateproject.org/archives/state_vote/votingmethods.php
I am quite keen to see that (at least) Drupal offer some of the better, fairer systems--anything but Plurality! Americans and French can both remember recent high-profile Plurality anomalies: Le Pen knocking out Jospin, and Nader spoiling the race for Gore.

I wish I were still a programmer and able to contribute code, but I let that skill atrophy many years ago. Let me know if I can contribute in some other way. The FSP web site at least would demo such a module, and I can think of other applications.

-Steve

La vero vin liberigos.

I'm looking forward to

frjo's picture

I'm looking forward to implement this in my Vote up/down module. I will make the values user settings.

Is the function vote_up_down_votingapi_action_sets() all I need to add? Seems very straight forward.

Correct.

eaton's picture

Implementing that function and returning the array of action stes is all you really need to do. Although I haven't yet worked out a proper AI for managing them, it's also possible to make a single action set that encompasses multiple 'paths' -- for example, an initial round of checks to determine if the node is one that you're monitoring, then two 'sub-sets' for actions with high or low ratings. I'm working on putting togteher some documentation for this shortly.

One thing to keep in mind is that the action sets (and thus, comparison values) that you pass in via this function will be cached. If you alter the values that the conditions compare against based on user settings, you'll probably want to flush the VotingAPI cache in your settings management code. the votingapi_rebuild_action_cache() function will do the trick.

--Jeff

Voting Systems

Group organizers

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds: