Election is a module for Drupal 7 allowing online voting.

It is intended to allow for other modules to provide election types which can have completely different settings, voting methods, counting methods, etc., which can all use the same core features (e.g. access control). Two types of elections are included with Election as submodules: referendums and STV elections.

Election is also very flexible in other ways. For example, elections, posts, and candidates are all 'fieldable entities'.

Audience

Election was developed by a student union — UCLU (University College London Union) — to provide online voting to its ~25,000 members. The module will hopefully be useful to other SUs and any other democratic organizations that need to hold online elections.

Sandbox

Please install it and try it!
git clone --recursive --branch 7.x-1.x http://git.drupal.org/sandbox/pjcdawkins/1167066.git election

More detail can be found on the sandbox project page: http://drupal.org/sandbox/pjcdawkins/1167066.

Don't forget to read the README.txt file.

Existing similar modules

The closest existing module is Advanced Poll. There's also the Decisions module for Drupal 5 and 6. Some principal distinguishing features of Election are:

  • Election contains a system for candidates, allowing users to submit nominations and displaying candidate profiles.
  • Multiple positions can be grouped together under a single 'election' entity, and in turn, multiple candidates belong to each position. At UCLU we needed this hierarchical structure, and easily navigable interface, because in one election many different positions can be contended (each with their own eligibility criteria, etc).
  • Election allows modules to define new election types (see summary above).
  • Access control in Election is per role (and per 'post'), and if election_condition is enabled, other modules can define any number of eligibility conditions (at UCLU we needed this to verify access dynamically, for example to check whether students are postgraduates or undergraduates).

Reviews of other projects

Composed Field: http://drupal.org/node/1678380#comment-6225516
Webform Boolean: http://drupal.org/node/1722252#comment-6339670
Headbar: http://drupal.org/node/1676528#comment-6343082

Comments

j2r’s picture

Status: Needs review » Needs work

Please check all coding standard related issue. Here is the link where you can check the list of error/warning.
http://ventral.org/pareview/httpgitdrupalorgsandboxpjcdawkins1167066git-...

pjcdawkins’s picture

Issue summary: View changes

Added Reviews of other projects (1 so far).

pjcdawkins’s picture

Status: Needs work » Needs review

Thanks, I've now checked and fixed those issues that I thought were actual coding standards problems. The list is now quite a bit shorter. I think I can ignore the remaining warnings/errors:

  • I've left most of the lines that are > 80 chars, as they're clearer in one line.
  • I've left the Views handler classes, I agree they're against coding standards, but they follow what the Views module does.
  • pareview.sh seems to have problems with switch structures, unless I'm mistaken.
  • I've left the non drupal_ string functions (identified in Coder Review) alone, as they definitely don't need Unicode support.
alansaviolobo’s picture

election.module
-------------------
line 372:

if (!empty($type['post key'])) {
      $post_key = $type['post key'];
      $post_name = _election_get_posts_name($type_mn);
      $post_name_plural = _election_get_posts_name($type_mn, TRUE);
      $items['admin/config/election/' . $type_mn . '/' . $post_key] = array(

I think what you are trying to accomplish here can be done using arguments, e.g. $items['admin/config/election/%type_mn/%post_key']

line 315

'title' => 'Elections',
    'description' => 'Administer elections and referendums.',

all the titles and descriptions would have to be wrapped in t()

correct me if I am wrong but do we really need function election_menu_alter(&$items) { ? is it not possible to achieve the functionality in function election_menu(&$items) { itself ?

drupwash’s picture

Manual Review:
1. First I download your module and try to install it gives me an error "date_popup" is required. I try to download "date_popup" via drush but its failed. Then I'm trying to googling and found date_popup comes under date module. So It should require to add date module as a dependency instead of date_popup
2. After installing this I have found "Add new referendum" and "Add new STV election" which have some voting status configuration but not able to identify what it actually does? Then I follow your README.txt and found its dependent on other module which are "election_post" and "election_candidate".
3. So its required more detail documentation on how to use.
Electronics Review:
Its have lots of coding-standard issue which people already mentioned above.

charlietoleary’s picture

Status: Needs review » Needs work

Hi pjcdawkins,

Manual Review:

Drupal API

  • I suggest that all instances of require() and require_once() be replaced with the Drupal API function: module_load_include()
  • Functions that process output or utilize the Drupal theme API may need to be moved into a new file: perhaps election.theme.inc - for better code segmentation.
  • For ease of edit-ability - it is encouraged that you use the Drupal Theme API wherever possible: for instance in the table being generated in election_vote_stv_vote_form()
  • any hardcoded <a> links should be replaced with the l() function wherever possible.
  • vote.js might be able to make use of the Drupal Behaviors functionality.
  • vote.min.js may not be needed. All script passed through Drupal's #attached functionality will be subsequently aggregated and Gzip'd by Drupal's caching engine. It's up to you, but personally: for such a small amount of Javascript I would just include the source.
  • It is suggested that Drupal's Database Abstraction Layer be used wherever possible. Notably in election_statistics_preprocess_election_statistics() in election_statistics.module

Entity API

The functions near line 166 of election.module can probably greater utilize the functions available in the entity API module.

I would suggest that election_load_multiple() on line 183 of election.module be removed, and replaced with just a regular entity_load().

While election_load() on line 166 of election.module seems to be replicating functionality similar to entity_load_single().

I would suggest that both of these methods be replaced with the methods already available in the entity module.

I have had a further look and have noticed that the module defines quite a few functions that seem to replicate functionality already available in the entity API module. I would suggest that you review your implementations of election_delete() and election_save() and any other functions that replicate functionality present in the entity API module and replace where applicable.

Great job on the module BTW, i'm sure it will see a lot of use upon release. Cheers, Charlie.

pjcdawkins’s picture

Thanks for your reviews (I've been abroad for a few weeks and just returned). I'm glad to see no-one has yet found any bugs affecting security, data integrity or functionality. I'm going to work ASAP on the issues identified (API usage, documentation, coding standards) and then I will ask for further reviews. If any of you are going to DrupalCon Munich 2012, I'll see you there.

pjcdawkins’s picture

#3 (alansaviolobo)
Yes, the hook_menu() implementations can certainly be cleaned up quite a bit, I'll do so. But titles and descriptions should not usually be wrapped in t() (see the docs). EDIT: And I'm using loops instead of arguments in order that the menu items will be gathered and listed by system_admin_menu_block_page(), and so that descriptions can be customised (there is no 'description callback' property yet), as is done in node.module.

#4 (drupwash)
Yes, better documentation is needed, although it's advisable to read the README.txt of any module first before installing. The coding standards issues which remain are a low priority for me (see #2).

#5 (charlietoleary)
Re. Drupal API, yes to all, except including minified JS seems to be the preferred method for now - see http://drupal.org/node/119441#comment-6269722. Re. Entity API, yes there are a lot of redundant functions, but according to the Model Entities project, they are good practice for entity modules. And they follow core, such as the node_load() and node_load_multiple() functions.

Correct me if I'm wrong.

pjcdawkins’s picture

#3 is now addressed as far as I think it should be, in commit 1895eaf (diff). Now working on #4 and #5.

pjcdawkins’s picture

Response to manual review in #4 (drupwash):

1. I've added Date as a dependency.
2. I've clarified the README.txt a bit. You should read the README before enabling a module, as described here: http://drupal.org/documentation/install/modules-themes/modules-7/
3. Yes better documentation is needed, although I think this will take a while to develop, after responding to support issues, etc. I think what I've provided is clear enough at least to get me full project access (which is what this issue is all about).

Now working on #5.

pjcdawkins’s picture

Status: Needs work » Needs review

Response to manual review in #5 (charlietoleary, Charlie O'Leary) regarding Drupal APIs. All quotes are charlietoleary.

I suggest that all instances of require() and require_once() be replaced with the Drupal API function: module_load_include()

I haven't found an instance where this change would be helpful. Other modules can interact with Election via two hooks, many forms, and several templates, but there's no area (for now) where dynamically included files are needed. I know some always use module_load_include() as a substitute for require_once() but that seems like overkill.

Functions that process output or utilize the Drupal theme API may need to be moved into a new file: perhaps election.theme.inc - for better code segmentation.

Yes. Fixed (6e7cac5).

For ease of edit-ability - it is encouraged that you use the Drupal Theme API wherever possible: for instance in the table being generated in election_vote_stv_vote_form()

That uses the Drupal Form API, so for edit-ability other modules would use hook_form_FORM_ID_alter(), etc. But yes, the whole module could be made more theme-y at some point.

any hardcoded <a> links should be replaced with the l() function wherever possible

I've looked at all instances of these, and changed one or two (6e7cac5). Elsewhere it seems <a> makes for clearer code than l(), and I haven't hard-coded any internal paths.

vote.js might be able to make use of the Drupal Behaviors functionality.

Yes. Fixed (6e7cac5).

vote.min.js may not be needed.

Probably not, but I'll include it anyway. I think including minified JS is a good principle, at least while there aren't any dynamic alternatives.

It is suggested that Drupal's Database Abstraction Layer be used wherever possible. Notably in election_statistics_preprocess_election_statistics() in election_statistics.module

Well, I am using the database abstraction layer, just not in a very abstracted way. I'm following the db_query() docs, which say "Use this function for SELECT queries if it is just a simple query string. If the caller or other modules need to change the query, use db_select() instead."

I think my use of Entity API is OK, as I explain in #7.

Setting back to 'needs review' because I've at least addressed everything mentioned.

pjcdawkins’s picture

Issue summary: View changes

Minor clarification to 'Access control' bullet point.

pjcdawkins’s picture

Issue summary: View changes

Added another review link.

pjcdawkins’s picture

Issue summary: View changes

Updated review links.

pjcdawkins’s picture

Issue summary: View changes

Updated to reflect restructuring into submodules.

pjcdawkins’s picture

Issue summary: View changes

Added another project review link.

pjcdawkins’s picture

Issue summary: View changes

Multiple comments for the Webform Boolean reviews - linking to the correct one (the manual one).

pjcdawkins’s picture

Issue tags: +PAreview: review bonus

I've made a little change: the election types (STV and Referendum) are now separated into two more (yes, more) submodules. So if you review this again, after pulling the new code you'll have to clear caches and read the README.txt again. I've also done my homework so I'm tagging this with a review bonus.

pjcdawkins’s picture

Issue summary: View changes

Extended the summary of the module.

pjcdawkins’s picture

Issue summary: View changes

Moved some text into the sandbox page.

nedjo’s picture

Thanks for posting this module!

Last year when we ran the Drupal Association elections we used the Decisions module, http://drupal.org/project/decisions (D6 only). Did you look at Decisions? How does it compare to what you've done? Are there points of potential convergence?

pjcdawkins’s picture

#12 (nedjo)

Good point, I should mention that in the summary above alongside Advanced Poll, and I can probably reference both on the project page.

I did have a look through Decisions, months ago, but it was quite far from what I needed. Being D6, it isn't nearly so flexible as this, which is very much set up for entities/fields/views, etc. It was going to be very hard to add capability for STV, exporting ballot files, nominations, etc. I've just had a fresh look through the Decisions code and my brain is in knots (though I'm not experienced with D6).

aitala’s picture

To do a recent online election I actually used the Webform module in place of Decisions based on the necessity to have write-in candidates. With the 'Select or other' add-on, that's doable in Webforms...

Eric

aitala’s picture

Issue summary: View changes

Minor changes.

pjcdawkins’s picture

I've added a little mention of Advanced Poll and Decisions on the sandbox project page, and at the top of this issue.

I still need a review - would the previous reviewers mind looking at my responses?

nedjo’s picture

While this module overlaps with what Decisions tries to do, this looks to be one of the cases where multiple models and a fresh approach make good sense. Possible some Decisions plugins could be rewritten for Election, or they could adopt a common plugin format.

I've had a look through the code. I posted some minor issues, none of which should hold up approval of the module. I didn't find time to review all code--there is a lot of it! But from what I did review, I am very impressed with this as a first substantial module contribution.

The module makes excellent use of both core and contrib APIs. It is well abstracted. And it addresses a clear use case that needs attention.

If this is an example of initial contributions these days, we've come a long way since I posted my first module is all I can say ;)

pjcdawkins’s picture

#16 (nedjo)

Many thanks for looking at this so carefully, and for the kind words.

Yes, I'll look into working with Decisions and/or Advanced Poll, perhaps when this module has a mature enough API (I want to introduce more OOP, etc, in the not too distant future, as a new major version).

I've responded to your issues in the queue, I've got a decent to-do list for the coder lounge in Munich.

I appreciate there's a lot of code to get through. I'm wondering idly, since the ultimate goal of this issue (for me) is full project access, do reviewers really need to examine 100% of the module to get an idea of my work?

klausi’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -PAreview: review bonus

manual review:

  1. "See: http://api.drupal.org/api/drupal/includes--common.inc/function/entity_uri/7.": do not hardcode such links, just use "@see entity_uri()". Docs: http://drupal.org/node/1354#general
  2. The automated review shows that some comment lines exceed 80 characters.
  3. election_menu_alter(): why do you need that hook? Please add a comment.
  4. election_entity_update(): if you are only targeting your own entity type you should use hook_ENTITY_TYPE_update(). Same for the delete and insert hook.

Otherwise looks RTBC to me. Removing review bonus tag, you can add it again if you have done another 3 reviews of other projects.

pjcdawkins’s picture

Thanks klausi, points taken. A few more tasks for me in Munich.

pjcdawkins’s picture

@nedjo
I've fixed most of your issues and created a whole bunch more of my own (I don't think mine are blocking issues!).

@klausi
I never found any documentation for a hook_ENTITY_TYPE_update(), etc., and I'm not sure any of that exists at least since #836754: API change: entity_invoke() got removed. See system.api.php.

But I've fixed your other points.

manarth’s picture

The election_candidate_download_form_submit() function currently does 3 separate tasks: parses the choice of properties to output, queries the DB to build the CSV output, and provides output (and http headers). Ideally these should be split into separate APIs so that other modules can make use of them.

Generally, exit() shouldn't be called; drupal_exit() should be used instead.

All instances of 'und' (e.g. $value['und'][0]['safe_value']) should be replaced with the language constant LANGUAGE_NONE.

The menu-alter function election_candidate_menu_alter() could use a comment to explain why it's being used (rather than standard hook_menu, for example).

There's a typo in election_candidate_menu_local_tasks_alter(), with the a call to user_access('bypass nomination schedule'): there are 2 spaces after 'bypass', so this check will fail for everyone except user 1.

The election module implements hook_hook_info() for hook_election_type_info(). The hook's group param allows the hook to be implemented in modulename.election.inc, and these files will be automatically included on demand, so the implementations of that hook within the election modules should be moved to new foo.election.inc files too.

So a couple of minor nit-picking issues, but certainly nothing to hold this module back: +1 for RTBC.

pjcdawkins’s picture

Many thanks, I'll deal with those issues in #1746822: Fix manarth's issues

patrickd’s picture

Assigned: Unassigned » patrickd
patrickd’s picture

Status: Reviewed & tested by the community » Fixed

I didn't have a look at all of the code, but where I looked at it's pretty clean and I don't thing here are major issues.

So I went over to test the module

  • After installing the submodules I had to re-clear the cache, so the admin items actually appeared. strange
  • All requirements of libraries should also be validated on the status reports page by hook_requirements()
  • When editing and creating positions, you don't check whether the "number of vacancies" really is a number

Beside this I was not able to find any major issues regarding security,
therefore

Thanks for your contribution!

I updated your account to let you promote this to a full project and also create new projects as either a sandbox or a "full" project.

Here are some recommended readings to help with excellent maintainership:

You can find lots more contributors chatting on IRC in #drupal-contribute. So, come hang out and get involved!

Thanks, also, for your patience with the review process. Anyone is welcome to participate in the review process. Please consider reviewing other projects that are pending review. I encourage you to learn more about that process and join the group of reviewers.

Thanks to the dedicated reviewer(s) as well.

pjcdawkins’s picture

Thanks Patrick. I've created an issue for the problems you found, and I'll go ahead and make it a full project.

klonos’s picture

Once this is mature enough, we can use it on d.o for voting on the location of the next DrupalCon! :P

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

Anonymous’s picture

Issue summary: View changes

Added mention of Decisions module.