Index: openacs-4/packages/poll/poll.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/poll.info,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/poll.info 3 Sep 2004 10:56:49 -0000 1.1 @@ -0,0 +1,27 @@ + + + + + Poll + Polls + f + f + + + Web Master + Madhu S + Simple polling module. + 2003-04-16 + Infiniteinfo, Inc. + A module for conducting simple polls on your website. + + + + + + + + + + + Index: openacs-4/packages/poll/sql/oracle/poll-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/sql/oracle/poll-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/sql/oracle/poll-create.sql 3 Sep 2004 10:56:49 -0000 1.1 @@ -0,0 +1,230 @@ +-- A very basic and simple polling module based on the OACS 4.x code. +-- +-- +-- DATA MODEL + +-- poll: object_type + + +begin + acs_object_type.create_type ( + object_type => 'poll', + pretty_name => 'POLL', + pretty_plural => 'POLLS', + supertype => 'acs_object', + table_name => 'POLLS', + id_column => 'poll_id' + ); +end; +/ +show errors; + +-- polls: individual poll info. + +create table polls ( + poll_id integer constraint polls_pk primary key + constraint polls_poll_id_fk + references acs_objects (object_id), + name varchar(100) not null, + question varchar2(1500) not null, + start_date date , + end_date date , + enabled_p char(1) + default 'f' + constraint poll_enabl_p_chk + check(enabled_p in('t','f')) + not null , + require_registration_p char(1) + default 'f' + constraint poll_regist_p_chk + check(require_registration_p in('t','f')) + not null , + package_id integer + not null + references apm_packages on delete cascade +); +/ +show errors; + +create index polls_package_id_index on polls (package_id); + +-- poll_choices: possible answers for poll. +create table poll_choices ( + choice_id integer primary key, + poll_id integer not null references polls on delete cascade, + label varchar(500) not null, + sort_order integer not null +); + +create sequence poll_choice_id_sequence; + + +create index poll_choices_index on poll_choices (poll_id, choice_id); + +-- poll_user_choices: web site visitor answers +create table poll_user_choices ( + choice_id integer references poll_choices(choice_id) on delete cascade not null, + -- user_id can be NULL if we're not requiring registration + user_id integer references users(user_id), + ip_address varchar(50) not null, + choice_date date default sysdate not null +); + +create index poll_user_choices_choice_index on poll_user_choices(choice_id); +create index poll_user_choices_user_index on poll_user_choices(user_id); + + +-- +-- FUNCTIONS +-- + +-- +create or replace package poll +as + function new ( + p_poll_id in polls.poll_id%type, + p_name in polls.name%type, + p_question in polls.question%type, + p_start_date in polls.start_date%type, + p_end_date in polls.end_date%type, + p_enabled_p in polls.enabled_p%type, + p_require_registration_p in polls.require_registration_p%type, + p_package_id in polls.package_id%type, + p_creation_user in acs_objects.creation_user%type default null + ) return polls.poll_id%type; + + function is_active_p ( + p_start_date in date, + p_end_date in date + ) return char; + + function is_poll_open_p ( + p_start_date in date, + p_end_date in date, + p_enabled in char + ) return char ; + + procedure delete ( + p_poll_id in polls.poll_id%type + ); + + +end poll; +/ +show errors; + +create or replace package body poll +as + function new ( + p_poll_id in polls.poll_id%type, + p_name in polls.name%type, + p_question in polls.question%type, + p_start_date in polls.start_date%type, + p_end_date in polls.end_date%type, + p_enabled_p in polls.enabled_p%type, + p_require_registration_p in polls.require_registration_p%type, + p_package_id in polls.package_id%type, + p_creation_user in acs_objects.creation_user%type default null + ) return polls.poll_id%type + is + v_poll_id integer; + begin + if p_poll_id is null then + select acs_object_id_seq.nextval + into v_poll_id + from dual; + else + v_poll_id := p_poll_id; + end if; + + v_poll_id := acs_object.new ( + object_id => v_poll_id, + object_type => 'poll', + creation_date => sysdate, + creation_user => p_creation_user, + context_id => p_package_id + ); + + insert into polls + (poll_id, name, question, start_date, end_date, + enabled_p, require_registration_p, package_id) + values + (v_poll_id, p_name, p_question, p_start_date, p_end_date, + p_enabled_p, p_require_registration_p, p_package_id); + return v_poll_id; + end new; + +-- +-- function is_active_p +-- + function is_active_p ( + p_start_date in date, + p_end_date in date + ) return char + is + v_result_p char; + begin + + v_result_p := 't'; + + if (p_start_date > sysdate) + then v_result_p := 'f'; + end if; + + if (p_end_date < sysdate ) + then v_result_p := 'f'; + end if; + + return v_result_p; + + end is_active_p; +-- +-- function is_poll_open_p +-- + function is_poll_open_p( + p_start_date in date, + p_end_date in date, + p_enabled in char + ) return char + is + v_open_p char(1); + v_active_p char; + begin + v_open_p := 'f'; + v_active_p := is_active_p(p_start_date,p_end_date); + if (v_active_p = 't') and (p_enabled ='t' ) + then v_open_p := 't'; + end if; + return v_open_p; + end is_poll_open_p; +-- +-- procedure delete +-- + procedure delete ( + p_poll_id in polls.poll_id%type + ) + is + begin + -- delete from acs_permissions + -- where object_id = poll.delete.p_poll_id; + -- delete from polls + -- where poll_id = poll.delete.p_poll_id; + acs_object.delete(p_poll_id); + end delete; + +end poll; +/ +show errors; + +create view poll_info as ( + select poll_id,name,question,start_date,end_date,enabled_p,require_registration_p,package_id, + poll.is_active_p (polls.start_date, polls.end_date) as active_p , + poll.is_poll_open_p (polls.start_date, polls.end_date,polls.enabled_p) as open_p + from polls +); +/ +show errors; + + + + Index: openacs-4/packages/poll/sql/oracle/poll-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/sql/oracle/poll-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/sql/oracle/poll-drop.sql 3 Sep 2004 10:56:49 -0000 1.1 @@ -0,0 +1,32 @@ +-- drop SQL for poll package +-- +-- +-- + +-- drop all the poll data + + +drop package poll; + +-- Drop the datamodel. +drop view poll_info; + +drop table poll_user_choices; +drop trigger poll_coice_id_seq_trigger; +drop sequence poll_choice_id_sequence; +drop table poll_choices; + +drop table polls; +/ +show errors; + +-- Drop the poll acs object type. +begin +acs_object_type.drop_type ( + object_type => 'poll', + cascade_p => 't' +); +end; +/ +show errors; + Index: openacs-4/packages/poll/sql/postgresql/poll-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/sql/postgresql/poll-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/sql/postgresql/poll-create.sql 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,165 @@ +-- A very basic and simple polling module based on the OACS 3.x +-- code. +-- +-- $Id: poll-create.sql,v 1.1 2004/09/03 10:56:50 dedsc Exp $ + +-- +-- DATAMODEL +-- + +-- poll: object_type +select acs_object_type__create_type ( + 'poll', + 'Poll', + 'Polls', + 'acs_object', + 'polls', + 'poll_id', + null, + 'f', + null, + null +); + +-- polls: individual poll info. +create table polls ( + poll_id integer + references acs_objects (object_id) on delete cascade + primary key, + name varchar(100) not null, + question text not null, + -- make the dates NULL for an on-going poll + start_date timestamp, + end_date timestamp, + enabled_p boolean default 'f' not null, + require_registration_p boolean default 'f' not null, + package_id integer not null + references apm_packages on delete cascade +); + +create index polls_package_id_index on polls (package_id); + +-- poll_choices: possible answers for poll. +create table poll_choices ( + choice_id integer + primary key, + poll_id integer not null references polls on delete cascade, + label varchar(500) not null, + sort_order integer not null +); + +create sequence poll_choice_id_sequence; +create index poll_choices_index on poll_choices (poll_id, choice_id); + +-- poll_user_choices: web site visitor answers +create table poll_user_choices ( + choice_id integer references poll_choices on delete cascade + not null, + -- user_id can be NULL if we're not requiring registration + user_id integer references users, + ip_address varchar(50) not null, + choice_date timestamp default current_timestamp not null +); + +create index poll_user_choices_choice_index on poll_user_choices(choice_id); +create index poll_user_choices_user_index on poll_user_choices(user_id); + + +-- +-- FUNCTIONS +-- + +-- poll__new: create a new poll +create function poll__new (integer,varchar,text,timestamp,timestamp,boolean,boolean,integer,integer) +returns integer as ' +declare + p_poll_id alias for $1; + p_name alias for $2; + p_question alias for $3; + p_start_date alias for $4; + p_end_date alias for $5; + p_enabled_p alias for $6; + p_require_registration_p alias for $7; + p_package_id alias for $8; + p_creation_user alias for $9; + v_poll_id polls.poll_id%TYPE; +begin + if p_poll_id is null then + select acs_object_id_seq.nextval + into v_poll_id + from dual; + else + v_poll_id := p_poll_id; + end if; + + v_poll_id := acs_object__new ( + v_poll_id, + ''poll'', + null, -- defaults to null + p_creation_user, + null, + p_package_id + ); + + insert into polls + (poll_id, name, question, start_date, end_date, + enabled_p, require_registration_p, package_id) + values + (v_poll_id, p_name, p_question, p_start_date, p_end_date, + p_enabled_p, p_require_registration_p, p_package_id); + + return v_poll_id; + +end;' language 'plpgsql'; + + +-- poll__delete: nuke a poll +create function poll__delete (integer) +returns integer as ' +declare + p_poll_id alias for $1; +begin + + -- All we need do is delete the acs_object since + -- the cascade clause handles the rest. + perform acs_object__delete(p_poll_id); + + return 0; + +end;' language 'plpgsql'; + + +-- poll__is_active_p: checks if a poll is active. +create function poll__is_active_p (timestamp, timestamp) returns boolean as ' +declare + start_date alias for $1; + end_date alias for $2; + v_result_p boolean; +begin + v_result_p := ''t''; + + if (date_trunc(''day'', start_date) > current_timestamp) + then v_result_p := ''f''; + end if; + + if (date_trunc(''day'', end_date) < date_trunc(''day'', current_timestamp)) + then v_result_p := ''f''; + end if; + + return v_result_p; +end; +' language 'plpgsql'; + + +-- +-- VIEWS +-- + +-- poll_info: includes active_p. +create view poll_info as + select + *, + poll__is_active_p (start_date, end_date) as active_p, + (poll__is_active_p (start_date, end_date) and enabled_p) as open_p + from + polls; Index: openacs-4/packages/poll/sql/postgresql/poll-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/sql/postgresql/poll-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/sql/postgresql/poll-drop.sql 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,50 @@ +-- +-- Drop SQL for polls package. +-- +-- $Id: poll-drop.sql,v 1.1 2004/09/03 10:56:50 dedsc Exp $ +-- + +-- Drop all the poll data. +create function inline_0 () +returns integer as ' +declare + v_poll_id polls.poll_id%TYPE; + v_poll_cursor RECORD; +begin + -- delete all the polls. + FOR v_poll_cursor IN + select poll_id + from polls + LOOP + -- all attached types/item are deleted in news.delete - modify there + PERFORM poll__delete(v_poll_cursor.poll_id); + END LOOP; + + return 0; +end; +' language 'plpgsql'; + +select inline_0 (); +drop function inline_0 (); + + +-- Drop the functions. +select drop_package('poll'); + + +-- Drop the datamodel. +drop view poll_info; + +drop table poll_user_choices; + +drop sequence poll_choice_id_sequence; +drop table poll_choices; + +drop table polls; + + +-- Drop the poll acs object type. +select acs_object_type__drop_type ( + 'poll', -- object_type + 't' -- cascade_p +); \ No newline at end of file Index: openacs-4/packages/poll/www/index-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/index-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/index-oracle.xql 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,26 @@ + + + + +oracle8.1.6 + + + +select poll_id, name, question, + case when enabled_p = 't' then 1 else 0 end as enabled_p, + case when active_p = 't' then 1 else 0 end as active_p, + case when acs_permission.permission_p(poll_id, :user_id, 'write') = 't' then 1 else 0 end as edit_p, + case when acs_permission.permission_p(poll_id, :user_id, 'delete') = 't' then 1 else 0 end as delete_p, + (select count(*) from poll_choices c, poll_user_choices u + where c.choice_id = u.choice_id and c.poll_id = p.poll_id) as votes + from + poll_info p + where + package_id = :package_id + order by + enabled_p desc, active_p desc, start_date desc, poll_id + + + + + Index: openacs-4/packages/poll/www/index-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/index-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/index-postgresql.xql 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,29 @@ + + + +postgresql7.1 + + + + +select + poll_id, name, question, + case when enabled_p = 't' then 1 else 0 end as enabled_p, + case when active_p = 't' then 1 else 0 end as active_p, + case when acs_permission__permission_p(poll_id, :user_id, 'write') = 't' then 1 else 0 end as edit_p, + case when acs_permission__permission_p(poll_id, :user_id, 'delete') = 't' then 1 else 0 end as delete_p, + (select count(*) from poll_choices c, poll_user_choices u + where c.choice_id = u.choice_id and c.poll_id = p.poll_id) as votes + from + poll_info p + where + package_id = :package_id + order by + enabled_p desc, active_p desc, start_date desc, poll_id + + + + + + + Index: openacs-4/packages/poll/www/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/index.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/index.adp 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,58 @@ + +Polls + + + + + Sorry, but there are no polls available. + + + +

Archived/Future Polls +

+

Disabled Polls +

+
+ + +

Add a new poll. + Index: openacs-4/packages/poll/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/index.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/index.tcl 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,47 @@ +ad_page_contract { + + Displays active polls on the site. + + @author Robert Locke (rlocke@infiniteinfo.com) + @creation-date 2003-01-12 + + +} { +} + +set package_id [ad_conn package_id] +set user_id [ad_conn user_id] + +# Check if the user has the proper rights. +set create_p [ad_permission_p $package_id create] + +# +# List all the polls. +# +set archive_label_set 0 +set disabled_label_set 0 + +db_multirow -extend {archive_label_p disabled_label_p name_js} polls polls_select {} { + set archive_label_p 0 + set disabled_label_p 0 + + # Don't show disabled polls unless the user has + # edit or delete privileges. + if { !$enabled_p && !$edit_p && !$delete_p } { + continue + } + + # Show the archive label if it hasn't been shown yet. + if { !$active_p && !$archive_label_set && $enabled_p } { + set archive_label_p 1 + set archive_label_set 1 + } + + # Show the disabled label if it hasn't been shown yet. + if { !$enabled_p && !$disabled_label_set } { + set disabled_label_p 1 + set disabled_label_set 1 + } + + regsub -all {'} $name {\'} name_js +} Index: openacs-4/packages/poll/www/poll-ae-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/poll-ae-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/poll-ae-oracle.xql 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,23 @@ + + + + +oracle8.1.6 + + + + declare + id integer; + begin + id := poll.new( + p_poll_id => :poll_id, + $field_insert_list, + p_package_id => :package_id, + p_creation_user => :user_id + ); + end; + + + + + Index: openacs-4/packages/poll/www/poll-ae-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/poll-ae-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/poll-ae-postgresql.xql 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,16 @@ + + + postgresql7.1 + + + + select poll__new( + :poll_id, + $field_insert_list_pg, + :package_id, + :user_id + ); + + + + Index: openacs-4/packages/poll/www/poll-ae.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/poll-ae.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/poll-ae.adp 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,52 @@ + +Polls +@context@ + + + + + +

+ + + + + This poll currently has no choices. + + + Available choices for poll: + +

+ + +
\ No newline at end of file Index: openacs-4/packages/poll/www/poll-ae.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/poll-ae.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/poll-ae.tcl 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,189 @@ +ad_page_contract { + + Displays a form for creating/editing a poll. + + @author Robert Locke (rlocke@infiniteinfo.com) + @creation-date 2003-01-13 +} { + poll_id:naturalnum,optional +} + +# +# 1) Set some useful variables. +# +set fields {name question start_date end_date enabled_p require_registration_p} +set dfield "" +set pfiled "" + +foreach field $fields { + if { ![regexp date $field] } { + lappend field_select_list $field + } else { + lappend field_select_list "to_char($field, 'YYYY MM DD') as $field" + } +} + +set field_select_list [join $field_select_list ", "] + +set date_format "MONTH DD, YYYY" +set clock_format "%Y %m %d" +set survey_duration "1 week" + +set package_id [ad_conn package_id] +set user_id [ad_conn user_id] + + + +# +# 2) Set up the form. +# +template::form create poll + +template::element create poll name -label "Name" \ + -widget text -datatype text + +template::element create poll question -label "Question" \ + -widget textarea -datatype text -html {rows 4 cols 40} + +template::element create poll start_date -label "Start Date" \ + -widget date -datatype date -format $date_format -value [template::util::date::now] -optional + +template::element create poll end_date -label "End Date" \ + -widget date -datatype date -format $date_format \ + -value [clock format \ + [clock scan $survey_duration -base [clock seconds]] -format $clock_format] \ + -optional + +template::element create poll enabled_p -label " " \ + -widget checkbox -datatype text -options {{"Enabled" t}} -optional + +template::element create poll require_registration_p -label " " \ + -widget checkbox -datatype text -options {{"Requires Registration" t}} -optional + +template::element create poll poll_id -widget hidden -datatype integer +template::element create poll insert_p -widget hidden -datatype integer + +template::element create poll submit -label "Save" \ + -widget submit -datatype text + +# +# 3) If this is a request, set some default values. +# +if { [template::form is_request poll] } { + if { ![info exists poll_id] } { + # This is an insert. Get the next sequence value + # for double-click protection. + ad_require_permission $package_id create + + set poll_id [db_nextval acs_object_id_seq] + set insert_p 1 + + template::element set_value poll enabled_p "t" + } else { + ad_require_permission $poll_id write + + # This is an update... + db_1row fetch_info " + select + $field_select_list + from + polls + where + poll_id = :poll_id + " + + foreach field $fields { + template::element set_value poll $field [set $field] + } + + set insert_p 0 + } + + template::element set_value poll poll_id $poll_id + template::element set_value poll insert_p $insert_p +} + +# +# 4) If this is a valid submission. +# +if { [template::form is_valid poll] } { + foreach field $fields { + set $field [template::element get_value poll $field] + + if { [regexp {_p$} $field] } { + if { [empty_string_p [set $field]] } { + set $field "f" + } + } + + if { ![regexp {_date$} $field] } { + lappend field_insert_list "p_$field => :$field" + lappend field_insert_list_pg ":$field " + lappend field_update_list "$field = :$field" + } else { + set dfield [template::util::date::get_property sql_date [set $field]] + set pfield $dfield + lappend field_insert_list "p_$field => $dfield" + lappend field_insert_list_pg "$pfield" + lappend field_update_list "$field = $dfield" + } + } + + set field_insert_list [join $field_insert_list ", "] + set field_insert_list_pg [join $field_insert_list_pg ", "] + set field_update_list [join $field_update_list ", "] + set insert_p [template::element get_value poll insert_p] + + set db_error 0 + + if { $insert_p } { + ad_require_permission $package_id create + + if { ![db_string check_exists "select 1 from polls where poll_id = :poll_id" -default "0"] } { + if { [catch {db_exec_plsql new_poll " " } ] } { + set db_error 1 + } + } + } else { + ad_require_permission $poll_id write + + set sql "update polls set $field_update_list where poll_id = :poll_id" + if { [catch {db_dml edit_poll $sql}] } { + set db_error 1 + } + } + + + if { $db_error } { + template::element set_error poll name "Sorry, but there was an error processing your request." + } else { + ad_returnredirect "poll-ae?poll_id=$poll_id" + } +} + +# +# 5) Show the choices for this poll, if any. +# +if { ![set insert_p [template::element get_value poll insert_p]] } { + set context Edit + + set write_p [ad_permission_p $poll_id write] + + db_multirow -extend label_js poll_choices list_poll_choices { + select + choice_id, label, sort_order, + (select count(*) from poll_user_choices + where choice_id = c.choice_id) as votes + from + poll_choices c + where + poll_id = :poll_id + order by + sort_order + } { + regsub -all {'} $label {\'} label_js + } + +} else { + set context "New" +} Index: openacs-4/packages/poll/www/poll-delete-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/poll-delete-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/poll-delete-oracle.xql 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,13 @@ + + + +oracle8.1.6 + + + begin + poll.delete(p_poll_id => :poll_id); + end; + + + + Index: openacs-4/packages/poll/www/poll-delete-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/poll-delete-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/poll-delete-postgresql.xql 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,12 @@ + + + + postgresql7.1 + + + + select poll__delete(:poll_id); + + + + Index: openacs-4/packages/poll/www/poll-delete.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/poll-delete.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/poll-delete.tcl 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,16 @@ +ad_page_contract { + + Delete a poll. + + @author Robert Locke (rlocke@infiniteinfo.com) + @creation-date 2003-01-13 +} { + poll_id:naturalnum +} + + +ad_require_permission $poll_id delete + +db_exec_plsql del_poll " " + +ad_returnredirect index Index: openacs-4/packages/poll/www/poll_choice-ae.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/poll_choice-ae.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/poll_choice-ae.adp 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,5 @@ + +Poll Choice +@context@ + + Index: openacs-4/packages/poll/www/poll_choice-ae.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/poll_choice-ae.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/poll_choice-ae.tcl 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,99 @@ +ad_page_contract { + + Displays a form for creating/editing a poll choice. + + @author Robert Locke (rlocke@infiniteinfo.com) + @creation-date 2003-01-13 +} { + poll_id:naturalnum + choice_id:naturalnum,optional + after:naturalnum,optional +} + +ad_require_permission $poll_id write + +# +# 1) Set up the form. +# +template::form create poll_choice + +template::element create poll_choice label -label "Label" \ + -widget text -datatype text + +template::element create poll_choice poll_id -widget hidden -datatype integer \ + -value $poll_id +template::element create poll_choice choice_id -widget hidden -datatype integer +template::element create poll_choice after -widget hidden -datatype integer -optional +template::element create poll_choice insert_p -widget hidden -datatype integer + +template::element create poll_choice submit -label "Save" \ + -widget submit -datatype text + +# +# 2) If this is a request, set some default values. +# +if { [template::form is_request poll_choice] } { + if { ![info exists choice_id] } { + # This is an insert. Get the next sequence value + # for double-click protection. + set choice_id [db_nextval poll_choice_id_sequence] + set insert_p 1 + template::element set_value poll_choice after $after + } else { + # This is an update... + db_1row fetch_info " + select + label + from + poll_choices + where + choice_id = :choice_id + " + + template::element set_value poll_choice label $label + + set insert_p 0 + } + + template::element set_value poll_choice choice_id $choice_id + template::element set_value poll_choice insert_p $insert_p +} + +# +# 3) If this is a valid submission. +# +if { [template::form is_valid poll_choice] } { + set label [template::element get_value poll_choice label] + set insert_p [template::element get_value poll_choice insert_p] + + if { $insert_p } { + if { ![db_string check_exists "select 1 from poll_choices where choice_id = :choice_id" -default "0"] } { + + # "after" should be defined for all inserts. + incr after + + db_transaction { + db_dml incr_sort "update poll_choices set sort_order = sort_order + 1 + where sort_order >= :after and poll_id = :poll_id" + + db_dml new_choice "insert into poll_choices (choice_id, poll_id, label, sort_order) + values (:choice_id, :poll_id, :label, :after)" + } + } + } else { + db_dml edit_choice "update poll_choices set label = :label where choice_id = :choice_id" + } + + ad_returnredirect "poll-ae?poll_id=$poll_id" +} + +# +# 5) Set the context bar. +# +if { [template::element get_value poll_choice insert_p] } { + set action New +} else { + set action Edit +} + +set context [list [list "poll-ae?poll_id=$poll_id" "One Poll"] $action] \ No newline at end of file Index: openacs-4/packages/poll/www/poll_choice-delete.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/poll_choice-delete.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/poll_choice-delete.tcl 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,22 @@ +ad_page_contract { + + Delete a poll choice. + + @author Robert Locke (rlocke@infiniteinfo.com) + @creation-date 2003-01-13 +} { + poll_id:naturalnum + choice_id:naturalnum +} + +ad_require_permission $poll_id write + +db_transaction { + db_dml dec_sort "update poll_choices set sort_order = sort_order - 1 + where sort_order > (select sort_order from poll_choices where choice_id = :choice_id) + and poll_id = :poll_id" + + db_dml del_poll_choice "delete from poll_choices where choice_id = :choice_id" +} + +ad_returnredirect "poll-ae?poll_id=$poll_id" Index: openacs-4/packages/poll/www/poll_choice-swap.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/poll_choice-swap.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/poll_choice-swap.tcl 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,23 @@ +ad_page_contract { + + Swap a poll choice with a previous one. + + @author Robert Locke (rlocke@infiniteinfo.com) + @creation-date 2003-01-13 +} { + poll_id:naturalnum + choice_id:naturalnum +} + +ad_require_permission $poll_id write + +db_transaction { + db_dml incr_prev "update poll_choices set sort_order = sort_order + 1 + where choice_id = (select choice_id from poll_choices + where sort_order = (select sort_order - 1 from poll_choices where choice_id = :choice_id) + and poll_id = :poll_id)" + + db_dml dec_cur "update poll_choices set sort_order = sort_order - 1 where choice_id = :choice_id" +} + +ad_returnredirect "poll-ae?poll_id=$poll_id" Index: openacs-4/packages/poll/www/results-breakdown.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/results-breakdown.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/results-breakdown.adp 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,43 @@ + +Results Breakdown +@context@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
@question@ +
Sorry, but there have been no votes..
@results.label@   + + + + + +
 @percentage@% (@results.votes@ votes) + +
+
     @results.user@ (@results.choice_votes@)
@total@ total votes
Index: openacs-4/packages/poll/www/results-breakdown.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/results-breakdown.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/results-breakdown.tcl 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,44 @@ +ad_page_contract { + + Shows the breakdown of the results of a poll. + + @author Robert Locke (rlocke@infiniteinfo.com) + @creation-date 2003-11-01 +} { + poll_id:naturalnum +} + +permission::require_permission -object_id $poll_id -privilege admin + +# +# Show the results. +# +set total 0 +set context [list [list "vote?poll_id=$poll_id" "Vote"] \ + [list "results?poll_id=$poll_id" "Results"] Breakdown] + +set question [db_string get_desc { + select question from polls where poll_id = :poll_id}] + +db_multirow results fetch_results { + select + c2.label, + case when v.user_id is null then 'Unregistered Users' + else p2.first_names || ' ' || p2.last_name || ' (' || p.email || ')' end + as user, + (select count(*) from poll_user_choices where choice_id = v.choice_id) as votes, + v.choice_votes + from + (select c.choice_id, u.user_id, count(u.choice_id) as choice_votes + from poll_user_choices u + right join poll_choices c using (choice_id) + where c.poll_id = :poll_id + group by c.choice_id, u.user_id) as v inner join + poll_choices c2 using (choice_id) left join + parties p on v.user_id = p.party_id left join + persons p2 on v.user_id = p2.person_id + order by + votes desc, c2.sort_order; +} { + incr total $choice_votes +} Index: openacs-4/packages/poll/www/results.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/results.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/results.adp 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,38 @@ + +Results +@context@ + + + + + + + + + + + + + + + + + + + + + +
@question@ + + (You have already voted.) + +
Sorry, but there have been no votes..
@results.label@   + + + + + +
 @percentage@% (@results.votes@ votes)
+
@total@ total votes + (breakdown) +
Index: openacs-4/packages/poll/www/results.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/results.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/results.tcl 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,36 @@ +ad_page_contract { + + Shows the results of a particular poll. + + @author Robert Locke (rlocke@infiniteinfo.com) + @creation-date 2003-01-13 +} { + poll_id:naturalnum + {voted:naturalnum 0} +} + +ad_require_permission $poll_id read + +# +# Show the results. +# +set total 0 +set context [list [list "vote?poll_id=$poll_id" "Vote"] Results] + +set question [db_string get_desc { + select question from polls where poll_id = :poll_id}] + +db_multirow results fetch_results { + select label, + (select count(*) from poll_user_choices where choice_id = p.choice_id) as votes + from poll_choices p + where poll_id = :poll_id + order by votes desc, sort_order +} { + incr total $votes +} + +# +# Check if the user has admin privileges on this poll. +# +set admin_p [permission::permission_p -object_id $poll_id -privilege admin] Index: openacs-4/packages/poll/www/vote-form.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/vote-form.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/vote-form.adp 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1 @@ + Index: openacs-4/packages/poll/www/vote-form.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/vote-form.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/vote-form.tcl 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,89 @@ +ad_require_permission $poll_id read + +# +# 1) Generate the form for voting. +# +db_1row get_poll { + select question, + require_registration_p, + case when open_p = 't' then 1 else 0 end as open_p + from poll_info where poll_id = :poll_id} + +set options [db_list_of_lists get_options { + select + label, choice_id + from + poll_choices + where + poll_id = :poll_id + order by + sort_order +}] + +if { ![info exists poll_url] } { + set poll_url "" +} + +# We are being included from a page other than vote. +template::form create vote -has_submit 1 -action ${poll_url}vote + +template::element create vote question -label "" \ + -widget inform -datatype text -value "$question (results)" + +template::element create vote choice_id -label " " \ + -widget radio -datatype text -options $options + +template::element create vote poll_id -widget hidden \ + -datatype integer -value $poll_id + +if { $open_p } { + template::element create vote submit -label "Vote" \ + -widget submit -datatype text +} else { + template::element create vote closed -label "" \ + -widget inform -datatype text -value "This poll is closed." +} + +# +# 2) If the user has voted, then log the vote and go to +# the results page. +# +if { [template::form is_valid vote] } { + + # Check if the user is required to register. + if { [string match "t" $require_registration_p] } { + ad_maybe_redirect_for_registration + } + + # If the user is logged in, check to see if they've + # already voted. If not, check to see if they were cookied. + set voted 0 + + if { ![set user_id [ad_conn user_id]] } { + set user_id "" + if { ![empty_string_p [ad_get_cookie poll_${poll_id}]] } { + set voted 1 + } + } else { + if [db_string num_votes "select count(*) from poll_user_choices u, poll_choices c + where u.choice_id = c.choice_id and c.poll_id = :poll_id + and u.user_id = :user_id"] { + set voted 1 + } + } + + if { !$voted && $open_p } { + set choice_id [template::element get_value vote choice_id] + set ip_address [ad_conn peeraddr] + + db_dml log_vote "insert into poll_user_choices + (choice_id, user_id, ip_address) + values + (:choice_id, :user_id, :ip_address)" + + # Tag the user with a cookie. + ad_set_cookie -max_age inf poll_${poll_id} $choice_id + } + + ad_returnredirect "results?poll_id=$poll_id&voted=$voted" +} \ No newline at end of file Index: openacs-4/packages/poll/www/vote.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/vote.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/vote.adp 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,5 @@ + +Polls +@context@ + + Index: openacs-4/packages/poll/www/vote.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/vote.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/vote.tcl 3 Sep 2004 10:56:50 -0000 1.1 @@ -0,0 +1,11 @@ +ad_page_contract { + + Displays a form for voting. + + @author Robert Locke (rlocke@infiniteinfo.com) + @creation-date 2003-01-13 +} { + poll_id:naturalnum +} + +set context "Vote" Index: openacs-4/packages/poll/www/doc/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/poll/www/doc/index.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/poll/www/doc/index.adp 3 Sep 2004 10:56:52 -0000 1.1 @@ -0,0 +1,122 @@ + +Poll + +

Poll

+ +by Infiniteinfo, Inc. +
Oracle port by Madhu S + +
+ +

The Big Idea

+ +This is a very simple polling module which: +
    +
  • allows administrators the ability to add, edit, and remove polls as well as +
  • add, edit, and remove poll choices; +
  • allows users to respond to a poll question by picking from a list +of available choices; +
  • allows both users and administrators to view the results of the poll. +
+ +

Datamodel and Permissions

+ +The datamodel is very simple, consisting basically of the following +tables: +
    +
  • polls: poll information +
  • poll_choices: possible answers for a poll +
  • poll_user_choices: web site visitor answers (or votes) +
+ +

For simplicity, polls are acs_objects, but poll choices and +votes are not. Also, this package does not create any custom +permissions. + +

You must have create permission for the package in order to +create a new poll. You must have write permission on a given +poll in order to edit the poll information or add/edit/delete poll +choices. And you must have delete permission in order to +remove a poll. + +

In practical use, it is envisioned that a group or +user will be granted admin permissions for the package, which +would allow them to fully manage all polls. + +

Lastly, the package is instance-aware, meaning that each instance +of the polls module contains its own polls. + +

User Interface

+ +To add a poll: +
    +
  • Assuming you have the proper permission, go to the poll index page +and click on Add a new poll. +
  • Name is required and is a short identifier for the poll (eg, +"Club Size"). +
  • Question is also required (eg, "How many members are in your +club?"). +
  • The Start Date and End Date define how long the poll +will run. Leaving the end date blank indicates that the poll will +never expire. Leaving the start date blank indicates that the poll +should start immediately. +
  • If the Enabled" flag is unchecked, then the poll is +disabled and will never be shown to regular users. +
  • Setting the Requires Registration flag will only allow +registered site users to answer the poll. +
  • After saving the poll, you can add poll choices by clicking on +insert a new poll choice. +
  • Poll choices can be edited, deleted, and re-ordered. +
+ +

To edit a poll: +

    +
  • Click on the edit link next to the desired poll. +
  • Edit the poll information as desired. +
  • Edit and re-order the poll choices. +
  • Deleting a poll choice will also delete its corresponding votes, +if any. You will be asked to confirm the deletion. +
+ +

To remove a poll: +

    +
  • Click on the delete link next to the desired poll. +
  • Deleting a poll will also delete its corresponding poll choices +and votes, if any. You will be asked to confirm the deletion. +
+ +

To take a poll: +

    +
  • Click on the poll name from the poll index page. +
  • Select an option (required) and click on Vote +
  • If Requires Registration is disabled, you will be taken to +the results page which summarizes all the votes to date. Otherwise, +you will be asked to login before your vote will be accepted. +
  • You can also simply click on the results link without +voting. +
  • Duplicate votes are currently detected in 2 ways: +
      +
    1. If the user is registered, we log their user_id and + check if they have voted previously. +
    2. We also cookie the user and check for the presence of the + cookie in subsequent votes. +
    +
  • You cannot vote on a poll which has expired or is disabled. +However, you can always view the results. +
+ +

ToDo

+
    +
  • Use ad_form instead of the template::form +procedures. +
  • Move all queries to xql files and port to Oracle. +
  • Some work would need to be done to have the poll included in any +page, as well as pop up the results in a separate window, as seems to +be common practice in many sites. The voting form and results table +would probably need to be separated as "includes". +
  • Improve anti-vote-dumping measures. +
  • Add more detailed reports. +
+ + +