Index: openacs.org-dev/foo =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/foo,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/foo 8 Oct 2002 15:46:40 -0000 1.1 @@ -0,0 +1 @@ \ No newline at end of file Index: openacs.org-dev/packages/acs-admin/www/users/modify-admin-privileges.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-admin/www/users/modify-admin-privileges.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-admin/www/users/modify-admin-privileges.adp 8 Oct 2002 15:46:41 -0000 1.1 @@ -0,0 +1,16 @@ +<master> +<property name=title>Confirm privilege modification for user #@user_id@</property> +<property name=context>@context@</property> + +Are you sure you wish to @action@ admin privileges for user #@user_id@? + +<p></p> + +<if @action@ eq "grant"> + <a href="@confirmed_url@">Grant privileges</a> | +</if> +<else> + <a href="@confirmed_url@">Revoke privileges</a> | +</else> + +<a href="@return_url@">Cancel</a> Index: openacs.org-dev/packages/acs-admin/www/users/modify-admin-privileges.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-admin/www/users/modify-admin-privileges.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-admin/www/users/modify-admin-privileges.tcl 8 Oct 2002 15:46:41 -0000 1.1 @@ -0,0 +1,35 @@ +ad_page_contract { + + Grants or revokes site-wide admin privileges. + @author Andrew Spencer (andrew@fallingblue.com) + @cvs-id $Id: modify-admin-privileges.tcl,v 1.1 2002/10/08 15:46:41 rmello Exp $ + +} { + user_id:notnull + action:notnull + confirmed_p:optional +} + +set confirmed_url "/acs-admin/users/modify-admin-privileges?user_id=$user_id&action=$action&confirmed_p=1" + +set return_url "/acs-admin/users/one?user_id=$user_id" + +set context [list [list "./" "Users"] "Modify privileges"] + +if ![info exists confirmed_p] { + set confirmed_p 0 +} + +if $confirmed_p { + if [string equal grant $action] { + permission::grant -object_id [acs_magic_object "security_context_root"] -party_id $user_id -privilege "admin" + } else { + permission::revoke -object_id [acs_magic_object "security_context_root"] -party_id $user_id -privilege "admin" + } + + ad_returnredirect $return_url + + # We need to flush all permission checks pertaining to this user. + # this is expensive so maybe we should check if we in fact are cacheing. + util_memoize_flush_regexp "^permission::.*-party_id $user_id" +} Index: openacs.org-dev/packages/acs-api-browser/www/proc/index.vuh =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-api-browser/www/proc/index.vuh,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-api-browser/www/proc/index.vuh 8 Oct 2002 15:46:41 -0000 1.1 @@ -0,0 +1,3 @@ +rp_form_put query_string [string range [ad_conn extra_url] [string length "proc/"] end] +rp_form_put search_type "Feeling Lucky" +rp_internal_redirect "/packages/[ad_conn package_key]/www/proc-search" Index: openacs.org-dev/packages/acs-content/www/doc/index.html =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-content/www/doc/index.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-content/www/doc/index.html 8 Oct 2002 15:46:41 -0000 1.1 @@ -0,0 +1,24 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> + <head> + <title>OpenACS acs-content package</title> + </head> + + <body bgcolor=white> + <h2>OpenACS acs-content package</h2> + <a href="../">OpenACS documentation</a> + <hr> + Pieces: + <ul> + <li><a href="requirements.html">Original Requirements Document</a> </li> + <li><a href="design.html">Original Design Document</a> </li> + </ul> + + <hr> + <address><a href="mailto:vkurup@massmed.org"></a></address> +<!-- Created: Mon Aug 13 14:17:34 EDT 2001 --> +<!-- hhmts start --> +Last modified: Fri Sep 13 08:26:20 EDT 2002 +<!-- hhmts end --> + </body> +</html> Index: openacs.org-dev/packages/acs-content-repository/upgrade-4.5-4.6.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-content-repository/upgrade-4.5-4.6.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-content-repository/upgrade-4.5-4.6.sql 8 Oct 2002 15:46:41 -0000 1.1 @@ -0,0 +1,61 @@ +-- change triggers to index only live revisions --DaveB 2002-09-26 +-- triggers queue search interface to modify search index after content +-- changes. +create or replace function content_search__itrg () +returns opaque as ' +begin +if (select live_revision from cr_items where item_id=new.item_id) = new.revision_id then + perform search_observer__enqueue(new.revision_id,''INSERT''); + end if; + return new; +end;' language 'plpgsql'; + +create or replace function content_search__dtrg () +returns opaque as ' +begin + select into v_live_revision live_revision from + cr_items where item_id=old.item_id; + if old.revision_id=v_live_revision then + perform search_observer__enqueue(old.revision_id,''DELETE''); + end if; + return old; +end;' language 'plpgsql'; + +create or replace function content_search__utrg () +returns opaque as ' +declare + v_live_revision integer; +begin + select into v_live_revision live_revision from + cr_items where item_id=old.revision_id; + if old.revision_id=v_live_revision then + insert into search_observer_queue ( + object_id, + event + ) values ( +old.revision_id, + ''UPDATE'' + ); + end if; + return new; +end;' language 'plpgsql'; + +-- we need new triggers on cr_items to index when a live revision +-- changes + +create function content_item_search__utrg () +returns opaque as ' +begin + if new.live_revision is not null and coalesce(old.live_revision,0) <> new.live_revision then + perform search_observer__enqueue(new.live_revision,''INSERT''); + end if; + + if old.live_revision is not null and old.live_revision <> coalesce(new.live_revision,0) then + perform search_observer__enqueue(old.live_revision,''DELETE''); + end if; + + return new; +end;' language 'plpgsql'; + +create trigger content_item_search__utrg before update on cr_items +for each row execute procedure content_item_search__utrg (); Index: openacs.org-dev/packages/acs-content-repository/sql/postgresql/upgrade/upgrade-4.1.2-4.5.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-content-repository/sql/postgresql/upgrade/upgrade-4.1.2-4.5.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-content-repository/sql/postgresql/upgrade/upgrade-4.1.2-4.5.sql 8 Oct 2002 15:46:42 -0000 1.1 @@ -0,0 +1,26 @@ +-- packages/acs-content-repository/sql/upgrade/upgrade-4.1.2-4.5.sql +-- +-- @author vinod@kurup.com +-- @creation-date 2002-05-15 +-- @cvs-id $Id: upgrade-4.1.2-4.5.sql,v 1.1 2002/10/08 15:46:42 rmello Exp $ +-- + +-- fixes bug #1502 http://openacs.org/sdm/one-baf.tcl?baf_id=1502 + +drop function content_keyword__delete(integer); +create function content_keyword__delete (integer) +returns integer as ' +declare + delete__keyword_id alias for $1; + v_rec record; +begin + + for v_rec in select item_id from cr_item_keyword_map + where keyword_id = delete__keyword_id LOOP + PERFORM content_keyword__item_unassign(v_rec.item_id, delete__keyword_id); + end LOOP; + + PERFORM acs_object__delete(delete__keyword_id); + + return 0; +end;' language 'plpgsql'; Index: openacs.org-dev/packages/acs-content-repository/tcl/acs-content-repository-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-content-repository/tcl/acs-content-repository-procs-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-content-repository/tcl/acs-content-repository-procs-oracle.xql 8 Oct 2002 15:46:42 -0000 1.1 @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="cr_delete_scheduled_files.fetch_paths"> + <querytext> + +select distinct crftd.path storage_area_key + from cr_files_to_delete crftd + and not exists (select 1 + from cr_revisions r + where r.filename = crftd.path) + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/acs-core-docs/tcl/acs-core-docs-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-core-docs/tcl/acs-core-docs-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-core-docs/tcl/acs-core-docs-procs.tcl 8 Oct 2002 15:46:42 -0000 1.1 @@ -0,0 +1,46 @@ +ad_library { + core documentation procs. + + @author Jeff Davis (davis@xarg.net) + @creation-date 2002-09-10 + @cvs-id $Id: acs-core-docs-procs.tcl,v 1.1 2002/10/08 15:46:42 rmello Exp $ +} + +ad_proc -private core_docs_uninstalled_packages_internal {} { + Returns a list (in array set format) of package.key package-name + (used for display on the index.adp page). + + @author Jeff Davis (davis@xarg.net) +} { + set uninstalled [list] + # Determine which spec files are not installed + foreach spec_file [apm_scan_packages "[acs_root_dir]/packages"] { + if { ! [catch {array set version [apm_read_package_info_file $spec_file]} errMsg] } { + if { ! [apm_package_registered_p $version(package.key)] } { + if {[empty_string_p $version(package-name)]} { + set version(package-name) $version(package.key) + } + lappend uninstalled [list $version(package.key) $version(package-name)] + } + } + } + + # sort the list and return in array set form + set out [list] + foreach pkg [lsort -dictionary -index 1 $uninstalled] { + set out [concat $out $pkg] + } + return $out + +} + +ad_proc -public core_docs_uninstalled_packages {} { + Returns a list (in array set format) of package.key package-name + (used for display on the index.adp page). + + Cached version of core_docs_uninstalled_packages_internal + + @author Jeff Davis davis@xarg.net +} { + return [util_memoize core_docs_uninstalled_packages_internal] +} Index: openacs.org-dev/packages/acs-core-docs/www/images/acs-without-apm-vs-with-apm.png =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-core-docs/www/images/acs-without-apm-vs-with-apm.png,v diff -u Binary files differ Index: openacs.org-dev/packages/acs-core-docs/www/sql/display-sql.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-core-docs/www/sql/display-sql.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-core-docs/www/sql/display-sql.adp 8 Oct 2002 15:46:43 -0000 1.1 @@ -0,0 +1,5 @@ +<master> +<property name="title">SQL Display</property> +<property name="context">@context@</property> + +@text@ Index: openacs.org-dev/packages/acs-core-docs/www/xml/developers-guide/permissions-tediously-explained.xml =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-core-docs/www/xml/developers-guide/permissions-tediously-explained.xml,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-core-docs/www/xml/developers-guide/permissions-tediously-explained.xml 8 Oct 2002 15:46:43 -0000 1.1 @@ -0,0 +1,1394 @@ +<sect1 id="permissions-tediously-explained" xreflabel="OpenACS Permissions Tediously Explained"> + <title>OpenACS 4.x Permissions Tediously Explained</title> + <para> + by Vadim Nasardinov. Modified and converted to Docbook XML by Roberto Mello + </para> + + <sect2 id="permissions-tedious-overview"> + + <title>Overview</title> + <para> + The general permissions system has a relatively complex data model in OpenACS 4.x. + Developers who haven't had the time to learn the internals of the data model + may end up writing seemingly correct code that crashes their system in + weird ways. This writeup is the result of my running into such a piece + of code and trying to understand exactly what went wrong. + It is geared towards developers who understand the general permissions + system to the extent that is described in the + <ulink url="http://openacs.org/doc/openacs-4/developer-guide/permissions.html"> + OpenACS 4.x Permisisons documentation</ulink>, + but who haven't had the opportunity to take a long, careful look at the + system internals. + </para> + + <para> + In OpenACS 4.x, most of the interesting tables are expected to extend (subtype) + the <computeroutput>acs_objects</computeroutput> table, i.e. they are expected to have an integer + primary key column that references the <computeroutput>object_id</computeroutput> column of + <computeroutput>acs_objects</computeroutput>. + </para> + + <programlisting id="acs_objects" xreflabel="acs_objects"> +create table <emphasis role="bold">acs_objects</emphasis> ( + object_id integer + not null + constraint acs_objects_pk primary key, + object_type + not null + constraint acs_objects_object_type_fk references acs_object_types (object_type), + context_id + constraint acs_objects_context_id_fk references acs_objects(object_id), + security_inherit_p char(1) default 't' + not null, + constraint acs_objects_sec_inherit_p_ck + check (security_inherit_p in ('t', 'f')), + creation_user integer, + creation_date date default sysdate not null, + creation_ip varchar2(50), + last_modified date default sysdate not null, + modifying_user integer, + modifying_ip varchar2(50), + constraint acs_objects_context_object_un + unique (context_id, object_id) disable +); + </programlisting> + + <para> + This means that any interesting entity (object) + in the system has an entry in the <computeroutput>acs_objects</computeroutput>. This + allows developers to define relationships between any two entities <emphasis>A</emphasis> + and <emphasis>B</emphasis> by defining a relationship between their corresponding entries + in the <computeroutput>acs_objects</computeroutput> table. One of the applications of this + powerful capability is the general permissions system. + </para> + + <para> + At the heart of the permission system are two tables: <computeroutput>acs_privileges</computeroutput> + and <computeroutput>acs_permissions</computeroutput>. + </para> + + + <programlisting id="acs_privileges" xreflabel="acs_privileges"> + create table <emphasis role="bold">acs_privileges</emphasis> ( + privilege varchar2(100) not null + constraint acs_privileges_pk primary key, + pretty_name varchar2(100), + pretty_plural varchar2(100) + ); + </programlisting> + + <programlisting id="acs_permissions" xreflabel="acs_permissions"> + create table <emphasis role="bold">acs_permissions</emphasis> ( + object_id + not null + constraint acs_permissions_on_what_id_fk references <xref linkend="acs_objects">acs_objects</xref> (object_id), + grantee_id + not null + constraint acs_permissions_grantee_id_fk references <xref linkend="tedious-parties">parties</xref> (party_id), + privilege + not null + constraint acs_permissions_priv_fk references <xref linkend="acs_privileges">acs_privileges</xref> (privilege), + constraint acs_permissions_pk + primary key (object_id, grantee_id, privilege) + ); + </programlisting> + + <para> + The <computeroutput>acs_privileges</computeroutput> table stores + named privileges like <emphasis>read</emphasis>, + <emphasis>write</emphasis>, <emphasis>delete</emphasis>, <emphasis>create</emphasis>, and + <emphasis>admin</emphasis>. The <computeroutput>acs_permissions</computeroutput> + table stores assertions of the form: + </para> + + <para> + Who (<computeroutput>grantee_id</computeroutput>) can do what (<computeroutput>privilege</computeroutput>) + on which object (<computeroutput>object_id</computeroutput>). + </para> + + <para> + The naive approach to managing system security would be to require application developers + to store permission information explicitly about every object, i.e. if the system has 100,000 and 1,000 users + who have the <emphasis>read</emphasis> privilege on all objects, then we would need to store 100,000,000 + entries of the form: + </para> + + <table frame="all"> + <tgroup cols="3" align="center" colsep="1" rowsep="1"> + <colspec colname="c1"/> + <colspec colname="c2"/> + <colspec colname="c3"/> + <thead> + <row> + <entry>object_id</entry> + <entry>grantee_id</entry> + <entry>privilege</entry> + </row> + </thead> + <tbody> + <row> + <entry>object_id_1</entry> + <entry>user_id_1</entry> + <entry>'read'</entry> + </row> + <row> + <entry>object_id_1</entry> + <entry>user_id_2</entry> + <entry>'read'</entry> + </row> + <row> + <entry namest="c1" nameend="c3" align="center">...</entry> + </row> + <row> + <entry>object_id_1</entry> + <entry>user_id_n</entry> + <entry>'read'</entry> + </row> + <row> + <entry>object_id_2</entry> + <entry>user_id_1</entry> + <entry>'read'</entry> + </row> + <row> + <entry>object_id_2</entry> + <entry>user_id_2</entry> + <entry>'read'</entry> + </row> + <row> + <entry namest="c1" nameend="c3" align="center">...</entry> + </row> + <row> + <entry>object_id_2</entry> + <entry>user_id_n</entry> + <entry>'read'</entry> + </row> + <row> + <entry namest="c1" nameend="c3" align="center">...</entry> + </row> + <row> + <entry namest="c1" nameend="c3" align="center">...</entry> + </row> + <row> + <entry>object_id_m</entry> + <entry>user_id_1</entry> + <entry>'read'</entry> + </row> + <row> + <entry>object_id_m</entry> + <entry>user_id_2</entry> + <entry>'read'</entry> + </row> + <row> + <entry namest="c1" nameend="c3" align="center">...</entry> + </row> + <row> + <entry>object_id_m</entry> + <entry>user_id_n</entry> + <entry>'read'</entry> + </row> + </tbody> + </tgroup> + </table> + + <para> + Although quite feasible, this approach fails to take advantage of the fact + that objects in the system are commonly organized hierarchally, + and permissions usually follow the hierarchical structure, so that if user + <emphasis>X</emphasis> has the <emphasis>read</emphasis> privilege on object <emphasis>A</emphasis>, she typically + also has the <emphasis>read</emphasis> privilege on all objects attached under <emphasis>A</emphasis>. + </para> + <para> + The general permission system, as implemented in OpenACS 4.x, takes advantage + of the hierarchical organization of objects to unburden developers of the + necessity to explicitly maintain security information for every single + object. There are three kinds of hierarchies involved. + These are discussed in the following sections. + </para> + </sect2> + + <sect2 id="permissions-tedious-context-hierarchy"> + <title>Context Hierarchy</title> + + <para> + Suppose objects <emphasis>A</emphasis>, <emphasis>B</emphasis>, ..., + and <emphasis>F</emphasis> form the following hierarchy. + </para> + + <table frame="all"> + <tgroup cols="3" align="center" colsep="1" rowsep="1"> + <colspec colname="c1"/> + <colspec colname="c2"/> + <colspec colname="c3"/> + <tbody> + <row> + <entry namest="c1" nameend="c3"> + <emphasis role="bold">A</emphasis> + <para> + <computeroutput>object_id=10</computeroutput> + </para> + </entry> + </row> + <row> + <entry namest="c1" nameend="c2"> + <emphasis role="bold">B</emphasis> + <para> + <computeroutput>object_id=20</computeroutput> + </para> + </entry> + <entry> + <emphasis role="bold">C</emphasis> + <para> + <computeroutput>object_id=30</computeroutput> + </para> + </entry> + </row> + <row> + <entry> + <emphasis role="bold">D</emphasis> + <para> + <computeroutput>object_id=40</computeroutput> + </para> + </entry> + <entry> + <emphasis role="bold">E</emphasis> + <para> + <computeroutput>object_id=50</computeroutput> + </para> + </entry> + <entry> + <emphasis role="bold">F</emphasis> + <para> + <computeroutput>object_id=60</computeroutput> + </para> + </entry> + </row> + </tbody> + </tgroup> + </table> + + <para> + This can be represented in the <computeroutput> + <xref linkend="acs_objects">acs_objects</xref></computeroutput> table + by the following entries: + </para> + + <table frame="all"> + <tgroup cols="2" align="center" colsep="1" rowsep="1"> + <colspec colname="c1"/> + <colspec colname="c2"/> + <thead> + <row> + <entry>object_id</entry> + <entry>context_id</entry> + </row> + </thead> + <tbody> + <row> + <entry>20</entry> + <entry>10</entry> + </row> + <row> + <entry>30</entry> + <entry>10</entry> + </row> + <row> + <entry>40</entry> + <entry>20</entry> + </row> + <row> + <entry>50</entry> + <entry>20</entry> + </row> + <row> + <entry>60</entry> + <entry>30</entry> + </row> + </tbody> + </tgroup> + </table> + + <para> + The first entry tells us that object 20 is the descendant of object 10, and + the third entry shows that object 40 is the descendant of object 20. By + running a <ulink url="http://www.oradoc.com/ora817/server.817/a85397/expressi.htm#1023748">CONNECT BY</ulink> query, + we can compute that object 40 is the second-generation descendant of object 10. + With this in mind, if we want to record the fact that user Joe has the <emphasis>read</emphasis> privilege on objects + <emphasis>A</emphasis>, ..., <emphasis>F</emphasis>, we only need to record one entry in the + <computeroutput><xref linkend="acs_permissions">acs_permissions</xref></computeroutput> table. + </para> + + <table frame="all"> + <tgroup cols="3" align="center" colsep="1" rowsep="1"> + <colspec colname="c1"/> + <colspec colname="c2"/> + <colspec colname="c3"/> + <thead> + <row> + <entry>object</entry> + <entry>grantee</entry> + <entry>privilege</entry> + </row> + </thead> + <tbody> + <row> + <entry align="center">A</entry> + <entry align="center">Joe</entry> + <entry align="center">read</entry> + </row> + </tbody> + </tgroup> + </table> + + <para> + The fact that Joe can also read <emphasis>B</emphasis>, <emphasis>C</emphasis>, + ..., and <emphasis>F</emphasis> can be derived by ascertaining that these objects + are children of <emphasis>A</emphasis> by traversing the context hierarchy. + As it turns out, hierarchical queries are expensive. As + Rafael Schloming put it so aptly, <emphasis>Oracle can't deal with hierarchies for shit.</emphasis> + </para> + + <para> + One way to solve this problem is to cache a flattened view of the context tree like so: + </para> + + <table frame="all"> + <tgroup cols="3" align="center" colsep="1" rowsep="1"> + <colspec colname="c1"/> + <colspec colname="c2"/> + <colspec colname="c3"/> + <thead> + <row> + <entry>object</entry> + <entry>ancestor</entry> + <entry>n_generations</entry> + </row> + </thead> + <tbody> + <row> + <entry align="center">A</entry> + <entry align="center">A</entry> + <entry align="center">0</entry> + </row> + <row> + <entry align="center">B</entry> + <entry align="center">B</entry> + <entry align="center">0</entry> + </row> + <row> + <entry align="center">B</entry> + <entry align="center">A</entry> + <entry align="center">1</entry> + </row> + <row> + <entry align="center">C</entry> + <entry align="center">C</entry> + <entry align="center">0</entry> + </row> + <row> + <entry align="center">C</entry> + <entry align="center">A</entry> + <entry align="center">1</entry> + </row> + <row> + <entry align="center">D</entry> + <entry align="center">D</entry> + <entry align="center">0</entry> + </row> + <row> + <entry align="center">D</entry> + <entry align="center">B</entry> + <entry align="center">1</entry> + </row> + <row> + <entry align="center">D</entry> + <entry align="center">A</entry> + <entry align="center">2</entry> + </row> + <row> + <entry align="center">E</entry> + <entry align="center">E</entry> + <entry align="center">0</entry> + </row> + <row> + <entry align="center">E</entry> + <entry align="center">B</entry> + <entry align="center">1</entry> + </row> + <row> + <entry align="center">E</entry> + <entry align="center">A</entry> + <entry align="center">2</entry> + </row> + <row> + <entry align="center">F</entry> + <entry align="center">F</entry> + <entry align="center">0</entry> + </row> + <row> + <entry align="center">F</entry> + <entry align="center">C</entry> + <entry align="center">1</entry> + </row> + <row> + <entry align="center">F</entry> + <entry align="center">A</entry> + <entry align="center">2</entry> + </row> + </tbody> + </tgroup> + </table> + + <para> + Note that the number of entries in the flattened view grows exponentially with + respect to the depth of the context tree. For instance, if you have a fully + populated binary tree with a depth of <emphasis>n</emphasis>, then the number of entries + in its flattened view is + </para> + + <para align="center"> + 1 + 2*2 + 3*4 + 4*8 + 5*16 + ... + (n+1)*2<superscript>n</superscript> = n*2<superscript>n+1</superscript> + 1</para> + + <para> + Despite its potentially great storage costs, maintaining a + flattened representation of the context tree is exactly what OpenACS 4.x + does. The flattened context tree is stored in the + <computeroutput>acs_object_context_index</computeroutput> table. + </para> + + <programlisting id="acs_object_context_index" xreflabel="acs_object_context_index"> + create table <emphasis role="bold">acs_object_context_index</emphasis> ( + object_id + not null + constraint acs_obj_context_idx_obj_id_fk references <xref linkend="acs_objects">acs_objects</xref>(object_id), + ancestor_id + not null + constraint acs_obj_context_idx_anc_id_fk references <xref linkend="acs_objects">acs_objects</xref>(object_id), + n_generations integer + not null + constraint acs_obj_context_idx_n_gen_ck check (n_generations <markup>></markup>= 0), + constraint acs_object_context_index_pk + primary key (object_id, ancestor_id) + ) organization index; + </programlisting> + + <para> + A few things to note about this table are these. Number one, it is + an <ulink url="http://www.oradoc.com/ora817/server.817/a85397/statem3e.htm#2061922">index-organized + table</ulink>, which means it is substantially optimized for access by primary key. + Number two, as the above computations suggest, the size of the table + grows <emphasis role="strong">polynomially</emphasis> + with respect to the average number of descendants that an object + has, and <emphasis role="strong">exponentially</emphasis> + with respect to the depth of the context tree. + </para> + + <para> + The <computeroutput>acs_object_context_index</computeroutput> is kept in sync with the + <computeroutput><xref linkend="acs_objects">acs_objects</xref></computeroutput> + table by triggers like this: + </para> + + <programlisting> +create or replace trigger acs_objects_context_id_in_tr +after insert on <xref linkend="acs_objects">acs_objects</xref> +for each row +begin + insert into <xref linkend="acs_object_context_index">acs_object_context_index</xref> + (object_id, ancestor_id, n_generations) + values + (:new.object_id, :new.object_id, 0); + + if :new.context_id is not null and :new.security_inherit_p = 't' then + insert into <xref linkend="acs_object_context_index">acs_object_context_index</xref> + (object_id, ancestor_id, + n_generations) + select + :new.object_id as object_id, ancestor_id, + n_generations + 1 as n_generations + from <xref linkend="acs_object_context_index">acs_object_context_index</xref> + where object_id = :new.context_id; + elsif :new.object_id != 0 then + -- 0 is the id of the security context root object + insert into <xref linkend="acs_object_context_index">acs_object_context_index</xref> + (object_id, ancestor_id, n_generations) + values + (:new.object_id, 0, 1); + end if; +end; +</programlisting> + + <para> + One final note about <computeroutput> + <xref linkend="acs_objects">acs_objects</xref></computeroutput>. By setting + an object's <computeroutput>security_inherit_p</computeroutput> column to 'f', you can stop permissions + from cascading down the context tree. In the following example, Joe does not have + the read permissions on <emphasis>C</emphasis> and <emphasis>F</emphasis>. + </para> + + <table frame="all"> + <tgroup cols="3" align="center" colsep="1" rowsep="1"> + <colspec colname="c1"/> + <colspec colname="c2"/> + <colspec colname="c3"/> + <tbody> + <row> + <entry namest="c1" nameend="c3"> + <literallayout> +<emphasis role="bold">A</emphasis> +<computeroutput>object_id=10</computeroutput> +<emphasis>readable by Joe</emphasis> + </literallayout> + </entry> + </row> + <row> + <entry namest="c1" nameend="c2"> + <literallayout> +<emphasis role="bold">B</emphasis> +<computeroutput>object_id=20</computeroutput> +<emphasis>readable by Joe</emphasis> + </literallayout> + </entry> + <entry> + <literallayout> +<emphasis role="bold">C</emphasis> +<computeroutput>object_id=30</computeroutput> +security_inherit_p = 'f' +<emphasis>not readable by Joe</emphasis> + </literallayout> + </entry> + </row> + <row> + <entry> + <literallayout> +<emphasis role="bold">D</emphasis> +<computeroutput>object_id=40</computeroutput> + </literallayout> + </entry> + <entry> + <literallayout> +<emphasis role="bold">E</emphasis> +<computeroutput>object_id=50</computeroutput> + </literallayout> + </entry> + <entry> + <literallayout> +<emphasis role="bold">F</emphasis> +<computeroutput>object_id=60</computeroutput> +security_inherit_p = 'f' +<emphasis>not readable by Joe</emphasis> + </literallayout> + </entry> + </row> + </tbody> + </tgroup> + </table> + + </sect2> + + <sect2 id="permissions-tedious-privilege-hierarchy"> + <title>Privilege Hierarchy</title> + + <para> + Privileges are also organized hierarchically. In addition to the five main system privileges + defined in the ACS Kernel data model, application developers may define their own. For instance, + the Bboard package defines the following privileges: + </para> + + <table frame="all"> + <tgroup cols="1" align="center" colsep="1" rowsep="1"> + <colspec colname="c1"/> + <thead> + <row> + <entry>privilege</entry> + </row> + </thead> + <tbody> + <row> + <entry>create_category</entry> + </row> + <row> + <entry>create_forum</entry> + </row> + <row> + <entry>create_message</entry> + </row> + <row> + <entry>delete_category</entry> + </row> + <row> + <entry>delete_forum</entry> + </row> + <row> + <entry>delete_message</entry> + </row> + <row> + <entry>moderate_forum</entry> + </row> + <row> + <entry>read_category</entry> + </row> + <row> + <entry>read_forum</entry> + </row> + <row> + <entry>read_message</entry> + </row> + <row> + <entry>write_category</entry> + </row> + <row> + <entry>write_forum</entry> + </row> + <row> + <entry>write_message</entry> + </row> + </tbody> + </tgroup> + </table> + + <para> + By defining parent-child relationship between privileges, the OpenACS data model + makes it easier for developers to manage permissions. Instead of granting + a user explicit <emphasis>read</emphasis>, <emphasis>write</emphasis>, <emphasis>delete</emphasis>, + and <emphasis>create</emphasis> + privileges on an object, it is sufficient to grant the user the <emphasis>admin</emphasis> + privilege to which the first four privileges are tied. To give + a more detailed example, the Bboard privileges are structured + as follows. + </para> + + <table frame="all"> + <tgroup cols="13" align="center" colsep="1" rowsep="1"> + <colspec colname="c1"/> + <colspec colname="c2"/> + <colspec colname="c3"/> + <colspec colname="c4"/> + <colspec colname="c5"/> + <colspec colname="c6"/> + <colspec colname="c7"/> + <colspec colname="c8"/> + <colspec colname="c9"/> + <colspec colname="c10"/> + <colspec colname="c11"/> + <colspec colname="c12"/> + <colspec colname="c13"/> + <tbody> + <row> + <entry namest="c1" nameend="c13">admin</entry> + </row> + <row> + <entry namest="c1" nameend="c3">create</entry> + <entry namest="c4" nameend="c6">delete</entry> + <entry namest="c7" nameend="c9">read</entry> + <entry namest="c10" nameend="c12">write</entry> + <entry morerows="1" valign="middle">moderate forum</entry> + </row> + <row> + <entry>create category</entry> + <entry>create forum</entry> + <entry>create message</entry> + <entry>delete category</entry> + <entry>delete forum</entry> + <entry>delete message</entry> + <entry>read category</entry> + <entry>read forum</entry> + <entry>read message</entry> + <entry>write category</entry> + <entry>write forum</entry> + <entry>write message</entry> + </row> + </tbody> + </tgroup> + </table> + + <para> + The parent-child relationship between privileges is represented in + the <computeroutput>acs_privilege_hierarchy</computeroutput> table: + </para> + + + <programlisting id="acs_privilege_hierarchy" xreflabel="acs_privilege_hierarchy"> + create table <emphasis role="bold">acs_privilege_hierarchy</emphasis> ( + privilege + not null + constraint acs_priv_hier_priv_fk references <xref linkend="acs_privileges">acs_privileges</xref> (privilege), + child_privilege + not null + constraint acs_priv_hier_child_priv_fk references <xref linkend="acs_privileges">acs_privileges</xref> (privilege), + constraint acs_privilege_hierarchy_pk + primary key (privilege, child_privilege) + ); + </programlisting> + + <para> + As in the case of the context hierarchy, it is convenient to have a flattened representation + of this hierarchal structure. This is accomplished by defining the following view. + </para> + + <programlisting id="acs_privilege_descendant_map" xreflabel="acs_privilege_descendant_map"> + create or replace view <emphasis role="bold">acs_privilege_descendant_map</emphasis> + as + select + p1.privilege, + p2.privilege as descendant + from + <xref linkend="acs_privileges">acs_privileges</xref> p1, + <xref linkend="acs_privileges">acs_privileges</xref> p2 + where + p2.privilege in + (select + child_privilege + from + <xref linkend="acs_privilege_hierarchy">acs_privilege_hierarchy</xref> + start with + privilege = p1.privilege + connect by + prior child_privilege = privilege + ) + or p2.privilege = p1.privilege; + </programlisting> + + <para> + As the number of different privileges in the system is expected to be + reasonably small, there is no pressing need to cache the flattened ansector-descendant + view of the privilege hierarchy in a specially maintained table like + it is done in the case of the context hierarchy. + </para> + + </sect2> + + <sect2 id="permissions-tedious-party-hierarchy"> + <title>Party Hierarchy</title> + + <para> + Now for the third hierarchy playing a promiment role in the permission system. The party + data model is set up as follows. + </para> + + <table frame="all"> + <tgroup cols="2" align="center" colsep="1" rowsep="1"> + <colspec colname="c1"/> + <colspec colname="c2"/> + <tbody> + <row> + <entry namest="c1" nameend="c2"> + <xref linkend="tedious-parties"> + <computeroutput>parties</computeroutput> + </xref> + </entry> + </row> + <row> + <entry> + <xref linkend="persons"> + <computeroutput>persons</computeroutput> + </xref> + </entry> + <entry morerows="1" valign="top"> + <xref linkend="groups"> + <computeroutput>groups</computeroutput> + </xref> + </entry> + </row> + <row> + <entry> + <xref linkend="users"> + <computeroutput>users</computeroutput> + </xref> + </entry> + </row> + </tbody> + </tgroup> + </table> + + <programlisting id="tedious-parties" xreflabel="parties"> + create table <emphasis role="bold">parties</emphasis> ( + party_id + not null + constraint parties_party_id_fk references <xref linkend="acs_objects">acs_objects</xref> (object_id) + constraint parties_pk primary key, + email varchar2(100) + constraint parties_email_un unique, + url varchar2(200) + ); + </programlisting> + + <programlisting id="persons" xreflabel="persons"> + create table <emphasis role="bold">persons</emphasis> ( + person_id + not null + constraint persons_person_id_fk references <xref linkend="tedious-parties">parties</xref> (party_id) + constraint persons_pk primary key, + first_names varchar2(100) + not null, + last_name varchar2(100) + not null + ); + </programlisting> + + <programlisting id="users" xreflabel="users"> + create table <emphasis role="bold">users</emphasis> ( + user_id + not null + constraint users_user_id_fk references <xref linkend="persons">persons</xref> (person_id) + constraint users_pk primary key, + password char(40), + -- other attributes + ); + </programlisting> + + <programlisting id="groups" xreflabel="groups"> + create table <emphasis role="bold">groups</emphasis> ( + group_id + not null + constraint groups_group_id_fk references <xref linkend="tedious-parties">parties</xref> (party_id) + constraint groups_pk primary key, + group_name varchar2(100) not null + ); + </programlisting> + + <para> + Recall that the <computeroutput>grantee_id</computeroutput> column of the + <xref linkend="acs_permissions">acs_permissions</xref> table references + <computeroutput>parties.party_id</computeroutput>. + This means that you can grant a privilege on an object to a party, person, user, or group. + Groups represent aggregations of parties. The most common scenario that you are likely + to encounter is a group that is a collection of users, although you could also + have collections of persons, groups, parties, or any mix thereof. + </para> + + <para> + Given that the most common use of groups is to partition users, how do you + build groups? One way is to grant membership explicitly. If you have + a group named <emphasis>Pranksters</emphasis>, you can assign membership to Pete, + Poly, and Penelope. The fact that these users are members of the + <emphasis>Pranksters</emphasis> group will be recorded in the + <computeroutput>membership_rels</computeroutput> and <computeroutput>acs_rels</computeroutput> tables: + </para> + + <programlisting id="acs_rels" xreflabel="acs_rels"> + create table <emphasis role="bold">acs_rels</emphasis> ( + rel_id + not null + constraint acs_rels_rel_id_fk references <xref linkend="acs_objects">acs_objects</xref> (object_id) + constraint acs_rels_pk primary key, + rel_type + not null + constraint acs_rels_rel_type_fk references acs_rel_types (rel_type), + object_id_one + not null + constraint acs_object_rels_one_fk references <xref linkend="acs_objects">acs_objects</xref> (object_id), + object_id_two + not null + constraint acs_object_rels_two_fk references <xref linkend="acs_objects">acs_objects</xref> (object_id), + constraint acs_object_rels_un + unique (rel_type, object_id_one, object_id_two) + ); + </programlisting> + + <programlisting id="membership_rels" xreflabel="membership_rels"> + create table <emphasis role="bold">membership_rels</emphasis> ( + rel_id + constraint membership_rel_rel_id_fk references <xref linkend="acs_rels">acs_rels</xref> (rel_id) + constraint membership_rel_rel_id_pk primary key, + -- null means waiting for admin approval + member_state varchar2(20) + constraint membership_rel_mem_ck + check (member_state in ('approved', 'banned', 'rejected', 'deleted')) + ); + </programlisting> + + <para> + The <computeroutput><xref linkend="acs_rels">acs_rels</xref></computeroutput> + table entries would look like so: + </para> + + <table frame="all"> + <tgroup cols="3" align="center" colsep="1" rowsep="1"> + <colspec colname="c1"/> + <colspec colname="c2"/> + <colspec colname="c3"/> + <thead> + <row> + <entry> + <computeroutput>rel_type</computeroutput> + </entry> + <entry> + <computeroutput>object_one</computeroutput> + </entry> + <entry> + <computeroutput>object_two</computeroutput> + </entry> + </row> + </thead> + <tbody> + <row> + <entry> + membership_rel + </entry> + <entry> + Pranksters + </entry> + <entry> + Pete + </entry> + </row> + <row> + <entry> + membership_rel + </entry> + <entry> + Pranksters + </entry> + <entry> + Poly + </entry> + </row> + <row> + <entry> + membership_rel + </entry> + <entry> + Pranksters + </entry> + <entry> + Penelope + </entry> + </row> + </tbody> + </tgroup> + </table> + + <para> + Another way of building up groups is by adding subgroups. Suppose + we define <emphasis>Merry Pranksters</emphasis> and <emphasis>Sad Pranksters</emphasis> as subgroups + of <emphasis>Pranksters</emphasis>. We say that the <emphasis>Pranksters</emphasis> group + is <emphasis role="strong">composed</emphasis> of + groups <emphasis>Merry Pranksters</emphasis> and <emphasis>Sad Pranksters</emphasis>. This + information is stored in the <computeroutput><xref linkend="acs_rels">acs_rels</xref></computeroutput> + and <computeroutput>composition_rels</computeroutput> tables. + </para> + + <programlisting id="composition_rels" xreflabel="composition_rels"> +create table <emphasis role="bold">composition_rels</emphasis> ( + rel_id + constraint composition_rel_rel_id_fk references <xref linkend="acs_rels">acs_rels</xref> (rel_id) + constraint composition_rel_rel_id_pk primary key +); + </programlisting> + + <para> + The relevant entries in the + <computeroutput><xref linkend="acs_rels">acs_rels</xref></computeroutput> look like so. + </para> + + <table frame="all"> + <tgroup cols="3" align="center" colsep="1" rowsep="1"> + <colspec colname="c1"/> + <colspec colname="c2"/> + <colspec colname="c3"/> + <thead> + <row> + <entry> + <computeroutput>rel_type</computeroutput> + </entry> + <entry> + <computeroutput>object_one</computeroutput> + </entry> + <entry> + <computeroutput>object_two</computeroutput> + </entry> + </row> + </thead> + <tbody> + <row> + <entry> + composition_rel + </entry> + <entry> + Pranksters + </entry> + <entry> + Merry Pranksters + </entry> + </row> + <row> + <entry> + composition_rel + </entry> + <entry> + Pranksters + </entry> + <entry> + Sad Pranksters + </entry> + </row> + </tbody> + </tgroup> + </table> + + <para> + The composition relationship means that if I add Matt, Mel, and Mary to the + <emphasis>Merry Pranksters</emphasis>, + they should also automatically become members of the <emphasis>Pranksters</emphasis> group. + The situation we are + facing in trying to determine whether or not a user is member of a group is similar to the one + discussed above in the case of the context hierarchy. Groups can form hierarchies with + respect to the composition relationship. The compositon relationship is transitive. If + <emphasis>G1</emphasis> is a subgroup of <emphasis>G2</emphasis>, and <emphasis>G2</emphasis> is a subgroup of <emphasis>G3</emphasis>, then + <emphasis>G1</emphasis> is a subgroup of <emphasis>G3</emphasis>; that is, any member of <emphasis>G1</emphasis> is also a member + of <emphasis>G3</emphasis>. + </para> + + <para> + Traversing the group composition hierarchy requires running + <ulink url="http://www.oradoc.com/ora817/server.817/a85397/expressi.htm#1023748">hierarchical queries</ulink>, + which are expensive in Oracle. As we saw in the <emphasis>Context Hierarchy</emphasis> section, one way of + reducing the performance hit incurred by hierarchical queries is to cache query results in + a table maintained by triggers. The OpenACS 4.x data model defines two such tables: + </para> + + <programlisting id="group_component_index" xreflabel="group_component_index"> + create table <emphasis role="bold">group_component_index</emphasis> ( + group_id not null + constraint group_comp_index_group_id_fk + references <xref linkend="groups">groups</xref> (group_id), + component_id not null + constraint group_comp_index_comp_id_fk + references <xref linkend="groups">groups</xref> (group_id), + rel_id not null + constraint group_comp_index_rel_id_fk + references composition_rels (rel_id), + container_id not null + constraint group_comp_index_cont_id_ck + references <xref linkend="groups">groups</xref> (group_id), + constraint group_component_index_ck + check (group_id != component_id), + constraint group_component_index_pk + primary key (group_id, component_id, rel_id) + ) organization index; + </programlisting> + + <programlisting id="group_member_index" xreflabel="group_member_index"> + create table <emphasis role="bold">group_member_index</emphasis> ( + group_id + not null + constraint group_member_index_grp_id_fk references <xref linkend="groups">groups</xref> (group_id), + member_id + not null + constraint group_member_index_mem_id_fk references <xref linkend="tedious-parties">parties</xref> (party_id), + rel_id + not null + constraint group_member_index_rel_id_fk references <xref linkend="membership_rels">membership_rels</xref> (rel_id), + container_id + not null + constraint group_member_index_cont_id_fk references <xref linkend="groups">groups</xref> (group_id), + constraint group_member_index_pk + primary key (member_id, group_id, rel_id) + ) organization index; + </programlisting> + + <para> + The <computeroutput>group_component_index</computeroutput> table stores a flattened representation of the + group composition hierarchy that is maintained in sync with the <computeroutput><xref linkend="acs_rels">acs_rels</xref></computeroutput> + and <computeroutput>composition_rels</computeroutput> tables through triggers. + </para> + + <para> + As far as the <computeroutput>group_member_index</computeroutput> table goes, I am not sure I understand its + purpose. It maintains group-member relationships that are resolved with respect + to group composition. Note that information stored in + <computeroutput><xref linkend="group_member_index">group_member_index</xref></computeroutput> can be trivially derived by joining + <computeroutput><xref linkend="membership_rels">membership_rels</xref></computeroutput>, + <computeroutput><xref linkend="acs_rels">acs_rels</xref></computeroutput>, + and <computeroutput><xref linkend="group_component_index">group_component_index</xref></computeroutput>. Here + is a view that does it. (This view is <emphasis>not</emphasis> part of the OpenACS Kernel data model.) + </para> + + <programlisting> +create or replace view group_member_view +as +select + gci.group_id, r.object_id_two as member_id +from + ( + select + group_id, group_id as component_id + from + <xref linkend="groups">groups</xref> + union + select + group_id, component_id + from + group_component_index + ) gci, + <xref linkend="membership_rels">membership_rels</xref> mr, + <xref linkend="acs_rels">acs_rels</xref> r +where + mr.rel_id = r.rel_id + and r.object_id_one = gci.component_id; + </programlisting> + + <para> + A heuristic way to verify that <computeroutput>group_member_view</computeroutput> is essentially identical + to <computeroutput><xref linkend="group_member_index">group_member_index</xref></computeroutput> is to compute the + symmetric difference between the two: + </para> + + <programlisting> +select + group_id, member_id +from + ( + select group_id, member_id from group_member_view + minus + select group_id, member_id from <xref linkend="group_member_index">group_member_index</xref> + ) +union +select + group_id, member_id +from + ( + select group_id, member_id from <xref linkend="group_member_index">group_member_index</xref> + minus + select group_id, member_id from group_member_view + ) + </programlisting> + + <para> + The query returns no rows. The important point is, if we + have a flattened view of the composition hierarchy -- like one provided + by the <computeroutput><xref linkend="group_component_index">group_component_index</xref></computeroutput> table -- + membership relationship resolution can be computed trivially with no hierarchical + queries involved. There is no need to keep the view in a denormalized + table, unless doing so results in substantial performance gains. + </para> + + </sect2> + + <sect2 id="permissions-tedious-putting-all-together"> + <title>Putting It All Together</title> + + <para> + Security information is queried by calling the <computeroutput>acs_permission.permission_p</computeroutput> + function in OpenACS 4.x. + </para> + + <programlisting> + create or replace package body acs_permission + as + -- some stuff removed for the sake of brevity + + function <emphasis role="bold">permission_p</emphasis> ( + object_id acs_objects.object_id%TYPE, + party_id parties.party_id%TYPE, + privilege acs_privileges.privilege%TYPE + ) return char + as + exists_p char(1); + begin + -- XXX This must be fixed: -1 shouldn't be hardcoded (it is the public) + select decode(count(*),0,'f','t') into exists_p + from <xref linkend="acs_object_party_privilege_map">acs_object_party_privilege_map</xref> + where object_id = permission_p.object_id + and party_id in (permission_p.party_id, -1) + and privilege = permission_p.privilege; + return exists_p; + end; + + end acs_permission; + </programlisting> + + <para> + The function simply queries + <computeroutput><xref linkend="acs_object_party_privilege_map">acs_object_party_privilege_map</xref></computeroutput>, + which is a humongous view that joins three flattened hierarchies: + the context tree, the privilege hierarchy, + the party composition (and membership) hierarchy. As such, + it contains an extremely large number of rows. About + the only kind of query you can run against it is the one + performed by the <computeroutput>acs_permission.permission_p</computeroutput> + function. Anything other than that would take forever to + finish or would ultimately result in an Oracle error. + </para> + + <para> + For example, do not try to do things like + </para> + + <programlisting> +select count(*) + from <xref linkend="acs_object_party_privilege_map">acs_object_party_privilege_map</xref>; + </programlisting> + + <para> + To give another example of things to avoid, I have seen code like this: + </para> + + <programlisting> + declare + cursor cur is + select + object_id, party_id + from + <xref linkend="acs_object_party_privilege_map">acs_object_party_privilege_map</xref> + where + privilege = 'foo_create'; + begin + -- revoke all 'foo_create' permissions + for rec in cur + loop + acs_permission.revoke_permission ( + object_id =<markup>></markup> rec.object_id, + grantee_id =<markup>></markup> rec.party_id, + privilege =<markup>></markup> 'foo_create' + ); + end loop; + + acs_privilege.remove_child('admin','foo_create'); + acs_privilege.drop_privilege('foo'); + + end; + / + </programlisting> + + <para> + The <computeroutput>acs_permission.revoke_permission</computeroutput> function merely runs a + delete statement like so: + </para> + + <programlisting> + delete from + acs_permissions + where + object_id = revoke_permission.object_id + and grantee_id = revoke_permission.grantee_id + and privilege = revoke_permission.privilege; + </programlisting> + + <para> + Note that in the above example, <computeroutput>acs_permissions</computeroutput> had only + one entry that needed to be deleted: + </para> + + <table frame="all"> + <tgroup cols="3" align="center" colsep="1" rowsep="1"> + <colspec colname="c1"/> + <colspec colname="c2"/> + <colspec colname="c3"/> + <thead> + <row> + <entry> + <computeroutput>object_id</computeroutput> + </entry> + <entry> + <computeroutput>grantee_id</computeroutput> + </entry> + <entry> + <computeroutput>privilege</computeroutput> + </entry> + </row> + </thead> + <tbody> + <row> + <entry> + default_context + </entry> + <entry> + registered_users + </entry> + <entry> + foo_create + </entry> + </row> + </tbody> + </tgroup> + </table> + + <para> + The above script would never get around to deleting this entry because it had + to loop through a gazillion rows in the humongous + <computeroutput>acs_object_party_privilege_map</computeroutput> view. + </para> + + </sect2> + + <sect2 id="permissions-tedious-appendix"> + <title>Appendix: Various View Definitions</title> + + <programlisting id="acs_object_party_privilege_map" xreflabel="acs_object_party_privilege_map"> +create or replace view <emphasis role="bold">acs_object_party_privilege_map</emphasis> +as +select + ogpm.object_id, + gmm.member_id as party_id, + ogpm.privilege +from + <xref linkend="acs_object_grantee_priv_map">acs_object_grantee_priv_map</xref> ogpm, + <xref linkend="group_member_map">group_member_map</xref> gmm +where + ogpm.grantee_id = gmm.group_id +union +select + object_id, + grantee_id as party_id, + privilege +from + <xref linkend="acs_object_grantee_priv_map">acs_object_grantee_priv_map</xref>; + </programlisting> + + <programlisting id="acs_object_grantee_priv_map" xreflabel="acs_object_grantee_priv_map"> +create or replace view <emphasis role="bold">acs_object_grantee_priv_map</emphasis> +as +select + a.object_id, + a.grantee_id, + m.descendant as privilege +from + <xref linkend="acs_permissions_all">acs_permissions_all</xref> a, + <xref linkend="acs_privilege_descendant_map">acs_privilege_descendant_map</xref> m +where + a.privilege = m.privilege; + </programlisting> + + + <programlisting id="acs_permissions_all" xreflabel="acs_permission_all"> +create or replace view <emphasis role="bold">acs_permissions_all</emphasis> +as +select + op.object_id, + p.grantee_id, + p.privilege +from + <xref linkend="acs_object_paths">acs_object_paths</xref> op, + <xref linkend="acs_permissions">acs_permissions</xref> p +where + op.ancestor_id = p.object_id; + </programlisting> + + <programlisting id="acs_object_paths" xreflabel="acs_object_paths"> +create or replace view <emphasis role="bold">acs_object_paths</emphasis> +as +select + object_id, + ancestor_id, + n_generations +from + <xref linkend="acs_object_context_index">acs_object_context_index</xref>; + </programlisting> + + <programlisting id="group_member_map" xreflabel="group_member_map"> + +create or replace view <emphasis role="bold">group_member_map</emphasis> +as +select + group_id, + member_id, + rel_id, + container_id +from + <xref linkend="group_member_index">group_member_index</xref>; + </programlisting> + + </sect2> +</sect1> + Index: openacs.org-dev/packages/acs-datetime/www/doc/pics/add.gif =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-datetime/www/doc/pics/add.gif,v diff -u Binary files differ Index: openacs.org-dev/packages/acs-datetime/www/doc/pics/diamond.gif =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-datetime/www/doc/pics/diamond.gif,v diff -u Binary files differ Index: openacs.org-dev/packages/acs-datetime/www/doc/pics/go.gif =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-datetime/www/doc/pics/go.gif,v diff -u Binary files differ Index: openacs.org-dev/packages/acs-datetime/www/doc/pics/new.gif =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-datetime/www/doc/pics/new.gif,v diff -u Binary files differ Index: openacs.org-dev/packages/acs-events/sql/postgresql/upgrade/upgrade-0.1d-0.2d.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-events/sql/postgresql/upgrade/upgrade-0.1d-0.2d.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-events/sql/postgresql/upgrade/upgrade-0.1d-0.2d.sql 8 Oct 2002 15:46:44 -0000 1.1 @@ -0,0 +1,47 @@ +-- created by arjun@openforce.net +-- from a bug fix by Deds Castillo + +drop function acs_event__recurrence_timespan_edit; + +create function acs_event__recurrence_timespan_edit ( + integer, + timestamp, + timestamp +) returns integer as ' +DECLARE + p_event_id alias for $1; + p_start_date alias for $2; + p_end_date alias for $3; + v_timespan RECORD; + v_one_start_date timestamp; + v_one_end_date timestamp; +BEGIN + -- get the initial offsets + select start_date, + end_date into v_one_start_date, + v_one_end_date + from time_intervals, + timespans, + acs_events + where time_intervals.interval_id = timespans.interval_id + and timespans.timespan_id = acs_events.timespan_id + and event_id=p_event_id; + + FOR v_timespan in + select * + from time_intervals + where interval_id in (select interval_id + from timespans + where timespan_id in (select timespan_id + from acs_events + where recurrence_id = (select recurrence_id + from acs_events where event_id = p_event_id))) + LOOP + PERFORM time_interval__edit(v_timespan.interval_id, + v_timespan.start_date + (p_start_date - v_one_start_date), + v_timespan.end_date + (p_end_date - v_one_end_date)); + END LOOP; + + return p_event_id; +END; +' language 'plpgsql'; Index: openacs.org-dev/packages/acs-interface/www/doc/index.html =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-interface/www/doc/index.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-interface/www/doc/index.html 8 Oct 2002 15:46:45 -0000 1.1 @@ -0,0 +1,24 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> + <head> + <title>OpenACS acs-interface package</title> + </head> + + <body bgcolor=white> + <h2>OpenACS acs-interface package</h2> + <a href="../">OpenACS documentation</a> + <hr> + Pieces: + <ul> + <li><a href="requirements.html">Original Requirements Document</a> </li> + <li><a href="design.html">Original Design Document</a> </li> + </ul> + + <hr> + <address><a href="mailto:vkurup@massmed.org"></a></address> +<!-- Created: Mon Aug 13 14:17:34 EDT 2001 --> +<!-- hhmts start --> +Last modified: Fri Sep 13 08:26:20 EDT 2002 +<!-- hhmts end --> + </body> +</html> Index: openacs.org-dev/packages/acs-kernel/sql/oracle/upgrade/upgrade-4.5-4.5.1.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-kernel/sql/oracle/upgrade/upgrade-4.5-4.5.1.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-kernel/sql/oracle/upgrade/upgrade-4.5-4.5.1.sql 8 Oct 2002 15:46:45 -0000 1.1 @@ -0,0 +1,720 @@ +-- acs-kernel +-- upgrade-4.5-4.5.1.sql +-- @author vinod@kurup.com +-- @creation-date 2002-08-17 + +-- acs-create.sql + +-- scalabilty change + +create or replace view registered_users +as + select p.email, p.url, pe.first_names, pe.last_name, u.*, mr.member_state + from parties p, persons pe, users u, group_member_map m, membership_rels mr + where party_id = person_id + and person_id = user_id + and u.user_id = m.member_id + and m.rel_id = mr.rel_id + and m.group_id = (select acs.magic_object_id('registered_users') from dual) + and mr.member_state = 'approved' + and u.email_verified_p = 't'; + + +-- acs-kernel-create.sql + +@@ ../tree-create +@@ ../site-node-object-map-create + +-- acs-objects-create.sql + +-- add procedure update_last_modified to package + +create or replace package acs_object +as + + function new ( + object_id in acs_objects.object_id%TYPE default null, + object_type in acs_objects.object_type%TYPE + default 'acs_object', + creation_date in acs_objects.creation_date%TYPE + default sysdate, + creation_user in acs_objects.creation_user%TYPE + default null, + creation_ip in acs_objects.creation_ip%TYPE default null, + context_id in acs_objects.context_id%TYPE default null + ) return acs_objects.object_id%TYPE; + + procedure delete ( + object_id in acs_objects.object_id%TYPE + ); + + function name ( + object_id in acs_objects.object_id%TYPE + ) return varchar2; + + -- The acs_object_types.name_method for "acs_object" + -- + function default_name ( + object_id in acs_objects.object_id%TYPE + ) return varchar2; + + -- Determine where the attribute is stored and what sql needs to be + -- in the where clause to retreive it + -- Used in get_attribute and set_attribute + procedure get_attribute_storage ( + object_id_in in acs_objects.object_id%TYPE, + attribute_name_in in acs_attributes.attribute_name%TYPE, + v_column out varchar2, + v_table_name out varchar2, + v_key_sql out varchar2 + ); + + -- Get/set the value of an object attribute, as long as + -- the type can be cast to varchar2 + function get_attribute ( + object_id_in in acs_objects.object_id%TYPE, + attribute_name_in in acs_attributes.attribute_name%TYPE + ) return varchar2; + + procedure set_attribute ( + object_id_in in acs_objects.object_id%TYPE, + attribute_name_in in acs_attributes.attribute_name%TYPE, + value_in in varchar2 + ); + + function check_representation ( + object_id in acs_objects.object_id%TYPE + ) return char; + + procedure update_last_modified ( + object_id in acs_objects.object_id%TYPE, + last_modified in acs_objects.last_modified%TYPE default sysdate + ); + +end acs_object; +/ +show errors + +create or replace package body acs_object +as + + procedure initialize_attributes ( + object_id in acs_objects.object_id%TYPE + ) + is + v_object_type acs_objects.object_type%TYPE; + begin + -- XXX This should be fixed to initialize supertypes properly. + + -- Initialize dynamic attributes + insert into acs_attribute_values + (object_id, attribute_id, attr_value) + select + initialize_attributes.object_id, a.attribute_id, a.default_value + from acs_attributes a, acs_objects o + where a.object_type = o.object_type + and o.object_id = initialize_attributes.object_id + and a.storage = 'generic' + and a.static_p = 'f'; + + -- Retreive type for static attributes + select object_type into v_object_type from acs_objects + where object_id = initialize_attributes.object_id; + + -- Initialize static attributes + begin + insert into acs_static_attr_values + (object_type, attribute_id, attr_value) + select + v_object_type, a.attribute_id, a.default_value + from acs_attributes a, acs_objects o + where a.object_type = o.object_type + and o.object_id = initialize_attributes.object_id + and a.storage = 'generic' + and a.static_p = 't' + and not exists (select 1 from acs_static_attr_values + where object_type = a.object_type); + exception when no_data_found then null; + end; + + end initialize_attributes; + + function new ( + object_id in acs_objects.object_id%TYPE default null, + object_type in acs_objects.object_type%TYPE + default 'acs_object', + creation_date in acs_objects.creation_date%TYPE + default sysdate, + creation_user in acs_objects.creation_user%TYPE + default null, + creation_ip in acs_objects.creation_ip%TYPE default null, + context_id in acs_objects.context_id%TYPE default null + ) + return acs_objects.object_id%TYPE + is + v_object_id acs_objects.object_id%TYPE; + begin + if object_id is null then + select acs_object_id_seq.nextval + into v_object_id + from dual; + else + v_object_id := object_id; + end if; + + insert into acs_objects + (object_id, object_type, context_id, + creation_date, creation_user, creation_ip) + values + (v_object_id, object_type, context_id, + creation_date, creation_user, creation_ip); + + acs_object.initialize_attributes(v_object_id); + + return v_object_id; + end new; + + procedure delete ( + object_id in acs_objects.object_id%TYPE + ) + is + v_exists_p char; + begin + + -- Delete dynamic/generic attributes + delete from acs_attribute_values where object_id = acs_object.delete.object_id; + + for object_type + in (select table_name, id_column + from acs_object_types + start with object_type = (select object_type + from acs_objects o + where o.object_id = acs_object.delete.object_id) + connect by object_type = prior supertype) + loop + -- Delete from the table if it exists. + select decode(count(*),0,'f','t') into v_exists_p + from user_tables + where table_name = upper(object_type.table_name); + + if v_exists_p = 't' then + execute immediate 'delete from ' || object_type.table_name || + ' where ' || object_type.id_column || ' = :object_id' + using in object_id; + end if; + + end loop; + + end delete; + + function name ( + object_id in acs_objects.object_id%TYPE + ) + return varchar2 + is + object_name varchar2(500); + v_object_id integer := object_id; + begin + -- Find the name function for this object, which is stored in the + -- name_method column of acs_object_types. Starting with this + -- object's actual type, traverse the type hierarchy upwards until + -- a non-null name_method value is found. + -- + for object_type + in (select name_method + from acs_object_types + start with object_type = (select object_type + from acs_objects o + where o.object_id = name.object_id) + connect by object_type = prior supertype) + loop + if object_type.name_method is not null then + + -- Execute the first name_method we find (since we're traversing + -- up the type hierarchy from the object's exact type) using + -- Native Dynamic SQL, to ascertain the name of this object. + -- + --execute immediate 'select ' || object_type.name_method || '(:1) from dual' + execute immediate 'begin :1 := ' || object_type.name_method || '(:2); end;' + using out object_name, in object_id; + --into object_name + + exit; + end if; + end loop; + + return object_name; + end name; + + function default_name ( + object_id in acs_objects.object_id%TYPE + ) return varchar2 + is + object_type_pretty_name acs_object_types.pretty_name%TYPE; + begin + select ot.pretty_name + into object_type_pretty_name + from acs_objects o, acs_object_types ot + where o.object_id = default_name.object_id + and o.object_type = ot.object_type; + + return object_type_pretty_name || ' ' || object_id; + end default_name; + + procedure get_attribute_storage ( + object_id_in in acs_objects.object_id%TYPE, + attribute_name_in in acs_attributes.attribute_name%TYPE, + v_column out varchar2, + v_table_name out varchar2, + v_key_sql out varchar2 + ) + is + v_object_type acs_attributes.object_type%TYPE; + v_static acs_attributes.static_p%TYPE := null; + v_attr_id acs_attributes.attribute_id%TYPE := null; + v_storage acs_attributes.storage%TYPE := null; + v_attr_name acs_attributes.attribute_name%TYPE := null; + v_id_column varchar2(200) := null; + v_sql varchar2(4000) := null; + v_return varchar2(4000) := null; + + -- Fetch the most inherited attribute + cursor c_attribute is + select + a.attribute_id, a.static_p, a.storage, a.table_name, a.attribute_name, + a.object_type, a.column_name, t.id_column + from + acs_attributes a, + (select + object_type, id_column + from + acs_object_types + connect by + object_type = prior supertype + start with + object_type = (select object_type from acs_objects + where object_id = object_id_in) + ) t + where + a.attribute_name = attribute_name_in + and + a.object_type = t.object_type; + + begin + + -- Determine the attribute parameters + open c_attribute; + fetch c_attribute into + v_attr_id, v_static, v_storage, v_table_name, v_attr_name, + v_object_type, v_column, v_id_column; + if c_attribute%NOTFOUND then + close c_attribute; + raise_application_error (-20000, + 'No such attribute ' || v_object_type || '::' || attribute_name_in || + ' in acs_object.get_attribute_storage.'); + end if; + close c_attribute; + + -- This should really be done in a trigger on acs_attributes, + -- instead of generating it each time in this function + + -- If there is no specific table name for this attribute, + -- figure it out based on the object type + if v_table_name is null then + + -- Determine the appropriate table name + if v_storage = 'generic' then + -- Generic attribute: table name/column are hardcoded + + v_column := 'attr_value'; + + if v_static = 'f' then + v_table_name := 'acs_attribute_values'; + v_key_sql := '(object_id = ' || object_id_in || ' and ' || + 'attribute_id = ' || v_attr_id || ')'; + else + v_table_name := 'acs_static_attr_values'; + v_key_sql := '(object_type = ''' || v_object_type || ''' and ' || + 'attribute_id = ' || v_attr_id || ')'; + end if; + + else + -- Specific attribute: table name/column need to be retreived + + if v_static = 'f' then + select + table_name, id_column + into + v_table_name, v_id_column + from + acs_object_types + where + object_type = v_object_type; + else + raise_application_error(-20000, + 'No table name specified for storage specific static attribute ' || + v_object_type || '::' || attribute_name_in || + ' in acs_object.get_attribute_storage.'); + end if; + + end if; + else + -- There is a custom table name for this attribute. + -- Get the id column out of the acs_object_tables + -- Raise an error if not found + select id_column into v_id_column from acs_object_type_tables + where object_type = v_object_type + and table_name = v_table_name; + + end if; + + if v_column is null then + + if v_storage = 'generic' then + v_column := 'attr_value'; + else + v_column := v_attr_name; + end if; + + end if; + + if v_key_sql is null then + if v_static = 'f' then + v_key_sql := v_id_column || ' = ' || object_id_in ; + else + v_key_sql := v_id_column || ' = ''' || v_object_type || ''''; + end if; + end if; + + exception when no_data_found then + if c_attribute%ISOPEN then + close c_attribute; + end if; + raise_application_error(-20000, 'No data found for attribute ' || + v_object_type || '::' || attribute_name_in || + ' in acs_object.get_attribute_storage'); + + end get_attribute_storage; + + -- Get/set the value of an object attribute, as long as + -- the type can be cast to varchar2 + function get_attribute ( + object_id_in in acs_objects.object_id%TYPE, + attribute_name_in in acs_attributes.attribute_name%TYPE + ) return varchar2 + is + v_table_name varchar2(200); + v_column varchar2(200); + v_key_sql varchar2(4000); + v_return varchar2(4000); + begin + + get_attribute_storage(object_id_in, attribute_name_in, + v_column, v_table_name, v_key_sql); + + begin + execute immediate 'select ' + || v_column || ' from ' || v_table_name || ' where ' || v_key_sql + into + v_return; + exception when no_data_found then + return null; + end; + + return v_return; + end get_attribute; + + procedure set_attribute ( + object_id_in in acs_objects.object_id%TYPE, + attribute_name_in in acs_attributes.attribute_name%TYPE, + value_in in varchar2 + ) + is + v_table_name varchar2(200); + v_column varchar2(200); + v_key_sql varchar2(4000); + v_return varchar2(4000); + v_dummy integer; + begin + + get_attribute_storage(object_id_in, attribute_name_in, + v_column, v_table_name, v_key_sql); + + execute immediate 'update ' + || v_table_name || ' set ' || v_column || ' = :value where ' || v_key_sql + using value_in; + + end set_attribute; + + function check_context_index ( + object_id in acs_objects.object_id%TYPE, + ancestor_id in acs_objects.object_id%TYPE, + n_generations in integer + ) return char + is + n_rows integer; + n_gens integer; + begin + -- Verify that this row exists in the index. + select decode(count(*),0,0,1) into n_rows + from acs_object_context_index + where object_id = check_context_index.object_id + and ancestor_id = check_context_index.ancestor_id; + + if n_rows = 1 then + -- Verify that the count is correct. + select n_generations into n_gens + from acs_object_context_index + where object_id = check_context_index.object_id + and ancestor_id = check_context_index.ancestor_id; + + if n_gens != n_generations then + acs_log.error('acs_object.check_representation', 'Ancestor ' || + ancestor_id || ' of object ' || object_id || + ' reports being generation ' || n_gens || + ' when it is actually generation ' || n_generations || + '.'); + return 'f'; + else + return 't'; + end if; + else + acs_log.error('acs_object.check_representation', 'Ancestor ' || + ancestor_id || ' of object ' || object_id || + ' is missing an entry in acs_object_context_index.'); + return 'f'; + end if; + end; + + function check_object_ancestors ( + object_id in acs_objects.object_id%TYPE, + ancestor_id in acs_objects.object_id%TYPE, + n_generations in integer + ) return char + is + context_id acs_objects.context_id%TYPE; + security_inherit_p acs_objects.security_inherit_p%TYPE; + n_rows integer; + n_gens integer; + result char(1); + begin + -- OBJECT_ID is the object we are verifying + -- ANCESTOR_ID is the current ancestor we are tracking + -- N_GENERATIONS is how far ancestor_id is from object_id + + -- Note that this function is only supposed to verify that the + -- index contains each ancestor for OBJECT_ID. It doesn''t + -- guarantee that there aren''t extraneous rows or that + -- OBJECT_ID''s children are contained in the index. That is + -- verified by seperate functions. + + result := 't'; + + -- Grab the context and security_inherit_p flag of the current + -- ancestor''s parent. + select context_id, security_inherit_p into context_id, security_inherit_p + from acs_objects + where object_id = check_object_ancestors.ancestor_id; + + if ancestor_id = 0 then + if context_id is null then + result := 't'; + else + -- This can be a constraint, can''t it? + acs_log.error('acs_object.check_representation', + 'Object 0 doesn''t have a null context_id'); + result := 'f'; + end if; + else + if context_id is null or security_inherit_p = 'f' then + context_id := 0; + end if; + + if check_context_index(object_id, ancestor_id, n_generations) = 'f' then + result := 'f'; + end if; + + if check_object_ancestors(object_id, context_id, + n_generations + 1) = 'f' then + result := 'f'; + end if; + end if; + + return result; + end; + + function check_object_descendants ( + object_id in acs_objects.object_id%TYPE, + descendant_id in acs_objects.object_id%TYPE, + n_generations in integer + ) return char + is + result char(1); + begin + -- OBJECT_ID is the object we are verifying. + -- DESCENDANT_ID is the current descendant we are tracking. + -- N_GENERATIONS is how far the current DESCENDANT_ID is from + -- OBJECT_ID. + + -- This function will verfy that each actualy descendant of + -- OBJECT_ID has a row in the index table. It does not check that + -- there aren't extraneous rows or that the ancestors of OBJECT_ID + -- are maintained correctly. + + result := 't'; + + -- First verify that OBJECT_ID and DESCENDANT_ID are actually in + -- the index. + if check_context_index(descendant_id, object_id, n_generations) = 'f' then + result := 'f'; + end if; + + -- For every child that reports inheriting from OBJECT_ID we need to call + -- ourselves recursively. + for obj in (select * + from acs_objects + where context_id = descendant_id + and security_inherit_p = 't') loop + if check_object_descendants(object_id, obj.object_id, + n_generations + 1) = 'f' then + result := 'f'; + end if; + end loop; + + return result; + end; + + function check_path ( + object_id in acs_objects.object_id%TYPE, + ancestor_id in acs_objects.object_id%TYPE + ) return char + is + context_id acs_objects.context_id%TYPE; + security_inherit_p acs_objects.security_inherit_p%TYPE; + begin + if object_id = ancestor_id then + return 't'; + end if; + + select context_id, security_inherit_p into context_id, security_inherit_p + from acs_objects + where object_id = check_path.object_id; + + if context_id is null or security_inherit_p = 'f' then + context_id := 0; + end if; + + return check_path(context_id, ancestor_id); + end; + + function check_representation ( + object_id in acs_objects.object_id%TYPE + ) return char + is + result char(1); + object_type acs_objects.object_type%TYPE; + n_rows integer; + begin + result := 't'; + acs_log.notice('acs_object.check_representation', + 'Running acs_object.check_representation on object_id = ' || + object_id || '.'); + + -- If this fails then there isn''t even an object associated with + -- this id. I'm going to let that error propogate as an exception. + select object_type into object_type + from acs_objects + where object_id = check_representation.object_id; + + acs_log.notice('acs_object.check_representation', + 'OBJECT STORAGE INTEGRITY TEST'); + + -- Let's look through every primary storage table associated with + -- this object type and all of its supertypes and make sure there + -- is a row with OBJECT_ID as theh primary key. + for t in (select t.object_type, t.table_name, t.id_column + from acs_object_type_supertype_map m, acs_object_types t + where m.ancestor_type = t.object_type + and m.object_type = check_representation.object_type + union + select object_type, table_name, id_column + from acs_object_types + where object_type = check_representation.object_type) loop + execute immediate 'select decode(count(*),0,0,1) from ' || t.table_name || + ' where ' || t.id_column || ' = ' || object_id + into n_rows; + + if n_rows = 0 then + result := 'f'; + acs_log.error('acs_object.check_representation', + 'Table ' || t.table_name || ' (primary storage for ' || + t.object_type || ') doesn''t have a row for object ' || + object_id || ' of type ' || object_type || '.'); + end if; + end loop; + + acs_log.notice('acs_object.check_representation', + 'OBJECT CONTEXT INTEGRITY TEST'); + + -- Do a bunch of dirt simple sanity checks. + + -- First let's check that all of our ancestors appear in + -- acs_object_context_index with the correct generation listed. + if check_object_ancestors(object_id, object_id, 0) = 'f' then + result := 'f'; + end if; + + -- Now let's check that all of our descendants appear in + -- acs_object_context_index with the correct generation listed. + if check_object_descendants(object_id, object_id, 0) = 'f' then + result := 'f'; + end if; + + -- Ok, we know that the index contains every entry that it is + -- supposed to have. Now let's make sure it doesn't contain any + -- extraneous entries. + for row in (select * + from acs_object_context_index + where object_id = check_representation.object_id + or ancestor_id = check_representation.object_id) loop + if check_path(row.object_id, row.ancestor_id) = 'f' then + acs_log.error('acs_object.check_representation', + 'acs_object_context_index contains an extraneous row: ' || + 'object_id = ' || row.object_id || ', ancestor_id = ' || + row.ancestor_id || ', n_generations = ' || + row.n_generations || '.'); + result := 'f'; + end if; + end loop; + + acs_log.notice('acs_object.check_representation', + 'Done running acs_object.check_representation ' || + 'on object_id = ' || object_id || '.'); + return result; + end check_representation; + + procedure update_last_modified ( + object_id in acs_objects.object_id%TYPE, + last_modified in acs_objects.last_modified%TYPE default sysdate + ) + is + v_parent_id acs_objects.context_id%TYPE; + begin + update acs_objects + set acs_objects.last_modified = acs_object.update_last_modified.last_modified + where acs_objects.object_id in (select ao.object_id + from acs_objects ao + connect by prior ao.context_id = ao.object_id + start with ao.object_id = acs_object.update_last_modified.object_id) + and acs_objects.context_id is not null + and acs_objects.object_id != 0; + end update_last_modified; + +end acs_object; +/ +show errors + + +-- acs-permissions-create.sql + + Index: openacs.org-dev/packages/acs-kernel/sql/postgresql/upgrade/upgrade-4.2-4.5.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-kernel/sql/postgresql/upgrade/upgrade-4.2-4.5.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-kernel/sql/postgresql/upgrade/upgrade-4.2-4.5.sql 8 Oct 2002 15:46:46 -0000 1.1 @@ -0,0 +1,56 @@ +-- packages/acs-kernel/sql/upgrade/upgrade-4.2-4.5.sql +-- +-- @author vinod@kurup.com +-- @creation-date 2002-05-15 +-- @cvs-id $Id: upgrade-4.2-4.5.sql,v 1.1 2002/10/08 15:46:46 rmello Exp $ +-- + +-- fixes bug #1515 http://openacs.org/sdm/one-bug.tcl?baf_id=1515 + +drop function apm_package_version__upgrade_p (varchar,varchar,varchar); +create function apm_package_version__upgrade_p (varchar,varchar,varchar) +returns integer as ' +declare + upgrade_p__path alias for $1; + upgrade_p__initial_version_name alias for $2; + upgrade_p__final_version_name alias for $3; + v_pos1 integer; + v_pos2 integer; + v_tmp apm_package_files.path%TYPE; + v_path apm_package_files.path%TYPE; + v_version_from apm_package_versions.version_name%TYPE; + v_version_to apm_package_versions.version_name%TYPE; +begin + + -- Set v_path to the tail of the path (the file name). + v_path := substr(upgrade_p__path, instr(upgrade_p__path, ''/'', -1) + 1); + + -- Remove the extension, if it is .sql. + v_pos1 := position(''.sql'' in v_path); + if v_pos1 > 0 then + v_path := substr(v_path, 1, v_pos1 - 1); + end if; + + -- Figure out the from/to version numbers for the individual file. + v_pos1 := instr(v_path, ''-'', -1, 2); + v_pos2 := instr(v_path, ''-'', -1); + if v_pos1 = 0 or v_pos2 = 0 then + -- There aren''t two hyphens in the file name. Bail. + return 0; + end if; + + v_version_from := substr(v_path, v_pos1 + 1, v_pos2 - v_pos1 - 1); + v_version_to := substr(v_path, v_pos2 + 1); + + if apm_package_version__version_name_greater(upgrade_p__initial_version_name, v_version_from) <= 0 and + apm_package_version__version_name_greater(upgrade_p__final_version_name, v_version_to) >= 0 then + return 1; + end if; + + return 0; + -- exception when others then + -- Invalid version number. + -- return 0; + +end;' language 'plpgsql'; + Index: openacs.org-dev/packages/acs-lang/www/doc/index.html =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-lang/www/doc/index.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-lang/www/doc/index.html 8 Oct 2002 15:46:46 -0000 1.1 @@ -0,0 +1,20 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<!-- saved from url=(0075)http://acs40.arsdigita.com/acs40-project-central/local-sepg/design-template --> +<HTML><HEAD><TITLE>ACS 4 Globalization</TITLE> +<META content="text/html; charset=iso-8859-1" http-equiv=Content-Type> +<META content="MSHTML 5.00.2722.2800" name=GENERATOR></HEAD> +<BODY bgColor=white> +<H2>ACS 4 Globalization</H2> +by Henry Minsky +<HR> + +<ul> + <li><a href="i18n-requirements.html">Requirements</a> + <li><a href="i18n-design.html">Design</a> +</ul> + +<HR> +<A href="mailto:hqm@arsdigita.com">hqm@arsdigita.com</A> <BR> + +</BODY></HTML> + Index: openacs.org-dev/packages/acs-ldap-authentication/www/doc/ldap-authentication.html =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-ldap-authentication/www/doc/ldap-authentication.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-ldap-authentication/www/doc/ldap-authentication.html 8 Oct 2002 15:46:46 -0000 1.1 @@ -0,0 +1,372 @@ +<html> +<head> +<title>LDAP Authentication</title> +</head> +<body bgcolor=white> + +<h2>LDAP Authentication</h2> + +For the <a href="http://arsdigita.com/doc">ArsDigita Community +System</a>, by <a href="http://www.pinds.com/lars">Lars Pind</a> on July 1, 2000. + +<hr> + +<blockquote><em> + +Note, this is still experimental, so it's not part of +this release. It'll be rolled in as part of the ACS 4.0 release. If +you're interested in helping us test this, please contact me at <a +href="mailto:lars@pinds.com">lars@pinds.com</a>, and I can provide you +with the patch. + +</em></blockquote> + +<h3>The Big Picure</h3> + +Many companies have their own LDAP directory servers where they +centrally store information on all the users of their computing +equipment, including their user ids and passwords. We want to let +users of an ACS-based web site log in using the same user id and +password as everywhere else in their computing environment. + +<p> + +Currently, We do <em>not</em> stuff users into the LDAP directory. If +a new user is to have access to the site, he must first have an entry +created in the LDAP server by some other means. + +<p> + +If you want to know more about what LDAP is, <a +href="http://www.pinds.com/software/ldap-in-general">I've actually +written up something about it</a>. + + + +<h3>The Medium-Sized Picture</h3> + +An ACS installation is hooked up against one specific, trusted LDAP +server. Every user of ACS has to be known to this LDAP server, and the +have to live under some agreed-on base DN (e.g. <code>ou=people, +dc=arsdigita, dc=com</code>). + +<p> + +This software builds on the assumption that you want all the users +under the base DN to have access to this ACS installation. This is not +always reasonable, but since we don't deal with authorization, you'll +have to modify this yourself. We also assume that you have some other +means of maintaining the information in the directory. We don't +provide tools for that yet. + +<p> + +The login process goes like this: + +<ol> + +<li>We ask for email and password. Since DN's are generally tedious to +type, we still rely on emails rather than DN. Since the user might not +have a row in the users table, we won't do the old-style "email first, +then check if he exists, then ask for password" login process. + +<li>We search the LDAP directory for a user with this email address +and get back the DN. If there's no such entry, we deny access to the +user. If there's more than one, we're in trouble, so we dump an +error. If there's exactly one entry, we grab the DN. + +<li>We do an LDAP bind operation with the DN just found and the +password provided by the user. If it doesn't succeed we complain that +the user typed in a bad password. + +<li>After the bind, we check to see if we already have a row in the +users table with the DN. If we don't, we pull out the person's +name from the directory and insert a row. + +</ol> + + +<blockquote><table bgcolor=#e6e6e6><tr><td> + +<i><b>Important Note:</b></i> We still have the two special users +<code>system</code> and <code>anonymous</code> around. Since their +password is still checked against the password in the local database, +they pose a security risk. However, they're needed for setting up the +site. See the section on <a href="#installation">installation</a> +below for more info. +</td></tr></table></blockquote> + + +<h3>Under The Hood</h3> + + +<h4>LDAP-specifics</h4> + +The attributes being searched on are + +<blockquote><pre> +mail: <i>email as typed in by user</i> +objectClass: inetOrgPerson +</pre></blockquote> + +You might want to add other requirements. How to do that is shown in +a comment in <code>LdapLogin.sqlj</code>. + +<p> + +The attributes being retrieved and stuffed into the users table are: + +<p> + +<table align=center> + +<tr bgcolor=#e6e6e6><th>LDAP +attribute</th><th>Description</th><th>Column in users table</th></tr> + +<tr bgcolor=#e6e6e6><td><code>dn</code></td> +<td>Distinguished name, the primary key of the entry</td> +<td><code>ldap_dn</code></td></tr> + +<tr bgcolor=#e6e6e6><td><code>givenName</code></td> +<td>The person's first name</td> +<td><code>first_names</code></td></tr> + +<tr bgcolor=#e6e6e6><td><code>sn</code></td> +<td>The person's last name (surname)</td> +<td><code>last_name</code></td></tr> + +<tr bgcolor=#e6e6e6><td><code>mail</code></td> +<td>The email address</td> +<td><code>email</code></td></tr> + +</table> + +<p> + +Again, you might want to get others. How to do this is shown in +<code>LdapLogin.sqlj</code>. + + + +<h4>Java API</h4> + +We don't want to implement an LDAP client in Tcl, so we rely on Sun's +JNDI LDAP client in Java 1.2 running inside Oracle. + +<p> + +There are a few Java stored procedures to handle the interfacing +between ACS and the LDAP server. Here are their interfaces: + +<blockquote><pre> +String <b>getDnByEmail</b>(String url, String base, String email) +String <b>bind</b>(String url, String dn, String password, String securityMechanism) +String <b>syncUsersTable</b>(String url, String dn) +</pre></blockquote> + +<dl> + +<dt><b>getDnByEmail</b> + +<dd>Performs an LDAP search for an <code>inetOrgPerson</code> with a +<code>mail</code> attribute that matches the email address given and +returns the DN if successful. If there's an error, the string "Error: +<i>explanation</i>" is returned. + +<p> + +<dt><b>bind</b> + +<dd>Performs the LDAP bind operation with the DN and password +supplied. It'll use the security mechanism specified in the server +parameter file. + + +Returns <code>ok</code> if the bind was successfull. If not, it +returns <code>Error: <i>explanation</i></code> + +<p> + +<dt><b>syncUsersTable</b> + +<dd>If the DN is already in the users table, it simply returns the +<code>user_id</code>. If it's not, it queries the LDAP server for the +<code>givenName</code>, <code>sn</code> and <code>mail</code> +attributes and puts them into the <code>first_names</code>, +<code>last_name</code> and <code>email</code> columns of the users +table, respectively. + +</dl> + + + + + +<h4><a name="parameters">Parameters</a></h4> + + +There are a few parameters you need to set up, one in the general ACS +section, the rest in the LDAP section: + +<blockquote><pre> +<b>[ns/server/<i>yourdomain</i>/acs]</b> + ... +; what authentication method we use +; possible values are: internal, ldap +<b>AuthenticationMethod=<i>ldap</i></b> + + ... + +<b>[ns/server/<i>yourdomain</i>/acs/ldap]</b> +; The URL of the LDAP server, including ldap:// +<b>ServerURL=<i>ldap://ldap.yourdomain.com</i></b> +; The base DN under which all the users of this website resides +<b>BaseDN=<i>ou=people,dc=yourdomain,dc=com</i></b> +; Preferred security mechanisms seperated by space, e.g. +; simple, CRAM-MD5, DIGEST-MD5 +<b>SecurityMechanism=<i>simple</i></b> +</pre></blockquote> + + + +<blockquote><table bgcolor=#e6e6e6><tr><td> +<i><b>Important Note:</b></i> You must make sure you have a login +process with email and password prompt on the same page, i.e. the +following lines in the general section of your acs .ini file: +<pre> +; use the old login process where email and password are on separate pages? +SeparateEmailPasswordPagesP=0 +</pre> +</td></tr></table></blockquote> + + +<h4>Tcl Wrappers</h4> + +There are straight-forward Tcl wrappers for both the parameters and +the Java procs in <code>/packages/acs-core/ldap-procs.tcl</code>. + + + + +<h4>Patched /www/register Pages</h4> + +The login process has been modified to accomodate LDAP +authenticaion. The following pages are affected: user-login, +user-login-2, deleted-user, restore-user. + + + +<h3><a name="installation">Installation</a></h3> + +<dl> +<dt><b>Prerequisites</b> + +<dd>We assume that you already have the LDAP server running and that +you have your directory organization decided i.e., that you know where +the users of this website will be stored. + +</dl> + +<ol> + +<li>Make sure you have the <b><code>ldap_dn</code> column in the +<code>users</code> table</b>. Here's the DDL to put it in: + +<blockquote><pre> +alter table users add ( + ldap_dn varchar(400) + constraint users_ldap_dn_unq unique +); +</pre></blockquote> + + +<li><b>Load the Java code</b> + +<blockquote><pre> +$ cd /web/<i>yourservice</i>/www/register/java +$ loadjava -user <i>yourservice/password</i> -resolve -verbose LdapLogin.sqlj +</pre></blockquote> + +It'll give you a bunch of warnings, but it should compile +nevertheless (look out for "source needs recompilation"). + +<p> + +<li><b>Create the JSP wrappers in the database</b> + +<blockquote><pre> +$ sqlplus <i>yourservice/password</i> < ldap-authentication-wrappers.sql +</pre></blockquote> + + +<li><b>Set up the parameters</b>, as described above in the <a +href="#parameters">parameters</a> section. + +<p> + +<li><b>Bootstrap yourself as administrator</b>: + +<ol> + +<li>Log in as yourself using LDAP authentication, so that you'll have +a row in the users table. + +<li>Then login as <code>system</code> using the default password +(<code>changeme</code>), and make yourself site-wide administrator +(visit <a href="/admin/ug">/admin/ug</a>, group type administration, +group site-wide administrators, add member). + +<li>Then login as yourself again, and ban the users +<code>system</code> and <code>anonymous</code>, so people can't log in +as those. + +</ol> + + +</ol> + + + + + +<h3>Future Improvements</h3> + +Obvious enhancements that would improve the usefulness without +changing the assumptions are: + +<ul> + +<li>Store mappings from LDAP attributes to columns in our users table +in the same configuration tool thing. We'd want each of them to have +synchronization options or 'never', 'on_login', 'regularly', etc. + +<li>Store additional attribute requirements for giving access to the +website. + +<li>Synchronization of the users table with their respective LDAP +entries. It could be per x number of logins or per x number of +hours/days. + + +</ul> + +Bigger things that would change the assumptions: + +<ul> + +<li>Allow us to create users and add them to LDAP. This is useful for +using LDAP to synchronize the users table between two sites, without +using LDAP for figuring out who should have access or not. + +<li>Use LDAP for authorization purposes, too, e.g. to identify +site-wide admins, or simply by storing all of our user-group info in +the directory as well. + +</ul> + + + + +<hr> +<address><a href="mailto:lars@pinds.com">lars@pinds.com</a></address> +</body> \ No newline at end of file Index: openacs.org-dev/packages/acs-person/acs-person.info =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/acs-person.info,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/acs-person.info 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,63 @@ +<?xml version="1.0"?> +<!-- Generated by the OpenACS Package Manager --> + +<package key="acs-person" url="http://openacs.org/repository/apm/packages/acs-person" type="apm_application"> + <package-name>ACS Person</package-name> + <pretty-plural>ACS Persons</pretty-plural> + <initial-install-p>f</initial-install-p> + <singleton-p>f</singleton-p> + + <version name="0.1d" url="http://openacs.org/repository/download/apm/acs-person-0.1d.apm"> + <database-support> + <database>oracle</database> + <database>postgresql</database> + </database-support> + <owner url="mailto:jon@jongriffin.com">Jon Griffin</owner> + <summary>This is an extension of the user/person acs legacy.</summary> + <vendor url="http://www.mayuli.com">Mayuli Enterprises LLC</vendor> + <description format="text/html">ACS Person follows the HR-XML PersonName DTD/Schema. It is used to add extended information to OpenACS.</description> + + <requires url="acs-kernel" version="4.5.1"/> + + <files> + <file type="package_spec" path="acs-person.info"/> + <file type="data_model_create" db_type="oracle" path="sql/oracle/acs-person-create.sql"/> + <file type="data_model_drop" db_type="oracle" path="sql/oracle/acs-person-drop.sql"/> + <file type="data_model" db_type="oracle" path="sql/oracle/acs-person-plsql.sql"/> + <file type="data_model" db_type="oracle" path="sql/oracle/acs-person-sc-create.sql"/> + <file type="data_model" db_type="oracle" path="sql/oracle/acs-person-sc-drop.sql"/> + <file type="data_model_create" db_type="postgresql" path="sql/postgresql/acs-person-create.sql"/> + <file type="data_model_drop" db_type="postgresql" path="sql/postgresql/acs-person-drop.sql"/> + <file type="data_model" db_type="postgresql" path="sql/postgresql/acs-person-plsql.sql"/> + <file type="data_model" db_type="postgresql" path="sql/postgresql/acs-person-sc-create.sql"/> + <file type="data_model" db_type="postgresql" path="sql/postgresql/acs-person-sc-drop.sql"/> + <file type="query_file" db_type="oracle" path="www/add-edit-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/add-edit-postgresql.xql"/> + <file type="content_page" path="www/add-edit.adp"/> + <file type="content_page" path="www/add-edit.tcl"/> + <file type="query_file" path="www/add-edit.xql"/> + <file type="content_page" path="www/admin/index.adp"/> + <file type="content_page" path="www/admin/index.tcl"/> + <file type="query_file" db_type="oracle" path="www/delete-2-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/delete-2-postgresql.xql"/> + <file type="content_page" path="www/delete-2.tcl"/> + <file type="content_page" path="www/delete.adp"/> + <file type="content_page" path="www/delete.tcl"/> + <file type="query_file" path="www/delete.xql"/> + <file type="query_file" db_type="oracle" path="www/index-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/index-postgresql.xql"/> + <file type="content_page" path="www/index.adp"/> + <file type="content_page" path="www/index.tcl"/> + <file type="query_file" path="www/index.xql"/> + <file type="query_file" db_type="oracle" path="www/one-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/one-postgresql.xql"/> + <file type="content_page" path="www/one.adp"/> + <file type="content_page" path="www/one.tcl"/> + <file type="query_file" path="www/one.xql"/> + </files> + <parameters> + <!-- No version parameters --> + </parameters> + + </version> +</package> Index: openacs.org-dev/packages/acs-person/sql/oracle/acs-person-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/sql/oracle/acs-person-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/sql/oracle/acs-person-create.sql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,201 @@ +-- packages/acs-person/sql/oracle/acs-person-create.sql +-- +-- @author jon@jongriffin.com +-- @creation-date 2002-09-25 +-- @cvs-id $Id: acs-person-create.sql,v 1.1 2002/10/08 15:46:47 rmello Exp $ + +-- This is a fairly direct mapping of the HR-XML PersonName v1.0 schema +-- see the docs for explanations + +-- create a package sequence +create sequence acs_persons_seq; + +-- create some lookup tables + +-- affix_type +create table affix_type ( + affix_type_id integer + constraint affix_type_id_pk + primary key, + xml_name varchar(20) + constraint affix_type_xml_name_nn + not null, + help_text varchar(400) + constraint affix_type_pretty_name_nn + not null +); + +-- add some initial data + +insert into affix_type + (affix_type_id, xml_name,help_text) +values + (nextval('acs_persons_seq'),'aristocraticTitle','i.e. Baron, Graf, Earl, etc.'); + +insert into affix_type + (affix_type_id, xml_name,help_text) +values + (nextval('acs_persons_seq'),'aristocraticPrefix','i.e. Von, etc.'); + +insert into affix_type + (affix_type_id, xml_name,help_text) +values + (nextval('acs_persons_seq'),'formOfAddress','Contains the salutation, +i.e. Mr., Mrs., Hon., Dr., etc.'); + +insert into affix_type + (affix_type_id,xml_name,help_text) +values + (nextval('acs_persons_seq'),'FamilyNamePrefix','Contains the part of the person''s +name that precedes the family name. i.e. Van den, Von, etc.'); + +insert into affix_type + (affix_type_id,xml_name,help_text) +values + (nextval('acs_persons_seq'),'generation','i.e. Sr. Jr., III'); + +insert into affix_type + (affix_type_id,xml_name,help_text) +values + (nextval('acs_persons_seq'),'qualifications','Contains the letters used to describe the academic qualifications held by a person and/or the distinctions conferred upon them. +i.e. PhD, MD, CPA, MCSD, etc.'); + + + + +-- Main table +create table acs_persons ( + acs_person_id integer + constraint acs_person_id_pk + primary key + constraint acs_person_id_fk + references acs_objects(object_id), + formatted_name varchar (200), + given_name varchar (100), + preferred_given_name varchar (100), + middle_name varchar (100), + -- The spec says that all fields should be optional + -- This data model requires at least the family_name + -- element. Madonna and Prince go here whether they + -- consider that a family name or not. + family_name varchar (100) + constraint acs_prsn_fmly_nme_nn + not null, + -- link into users + user_id integer + constraint acs_user_id_fk + references users(user_id) +); + +create index acs_persons_full_name_ix on acs_persons (given_name,family_name); +create index acs_persons_family_name_ix on acs_persons (family_name); + +comment on table acs_persons is ' +This is the main table for acs_persons. It is a direct mapping of the HR-XML +PersonName v1.0 schema +'; + +comment on column acs_persons.acs_person_id is ' +Primary key. +'; + +comment on column acs_persons.family_name is ' +The last name. +'; + +comment on column acs_persons.given_name is ' +Given or first name. +'; + +comment on column acs_persons.middle_name is ' +This could also be more than one name. +'; + +comment on column acs_persons.formatted_name is ' +This is the name as it might appear in a letter. +'; + +comment on column acs_persons.preferred_given_name is ' +'; + + +comment on column acs_persons.acs_person_id is ' +Foriegn key. This can be null as we also want to use this for non-users progams +i.e. contact manager etc. +'; + + +-- Now the map tables + +-- affix_acs_persons_map +-- +-- This is necessary due to the way HR-XML implemented the affix system. +-- Since it is many to many this is the only way. + +create table affix_acs_persons_map ( + acs_person_id integer + constraint affix_person_id_fk + references persons(person_id), + affix_type_id integer + constraint affix_type_id_fk + references affix_type(affix_type_id), + ---- add the primary key to ensure uniqueness + constraint affix_acs_prsn_map_pk + primary key (acs_person_id,affix_type_id) +); + +-- acs_persons_given_names +create table acs_persons_given_names ( + given_name_id integer + constraint acs_prsn_gvn_nme_pk + primary key, + acs_person_id integer + constraint acs_prsn_gvn_nme_fk + references acs_persons(acs_person_id), + extra_given_name varchar(100) + constraint acs_prsn_gvn_nme_name_nn + not null, + sort_order integer, + ---- add some constraints to keep data sanity + constraint acs_prsn_gvn_nme_uq + unique (acs_person_id,extra_given_name,sort_order) +); + +create table acs_persons_middle_names ( + middle_name_id integer + constraint acs_prsn_mdl_nme_pk + primary key, + acs_person_id integer + constraint acs_prsn_mdl_nme_fk + references acs_persons(acs_person_id), + extra_middle_name varchar(100) + constraint acs_prsn_mdl_nme_name_nn + not null, + sort_order integer, + ---- add some constraints to keep data sanity + constraint acs_prsn_mdl_nme_uq + unique (acs_person_id,extra_middle_name,sort_order) +); + +create table acs_persons_family_names ( + family_name_id integer + constraint acs_prsn_fmly_nme_pk + primary key, + acs_person_id integer + constraint acs_prsn_fmly_nme_fk + references acs_persons(acs_person_id), + extra_family_name varchar(100) + constraint acs_prsn_fmly_nme_name_nn + not null, + sort_order integer, + ---- add some constraints to keep data sanity + constraint acs_prsn_fmly_nme_uq + unique (acs_person_id,extra_family_name,sort_order) +); + +-- plsql procs +@@ acs-person-plsql.sql + +-- Service contract +-- Broken drop script +-- @@ acs-person-sc-create.sql Index: openacs.org-dev/packages/acs-person/sql/oracle/acs-person-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/sql/oracle/acs-person-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/sql/oracle/acs-person-drop.sql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,34 @@ +-- packages/acs-person/sql/oracle/acs-person-drop.sql +-- +-- @author jon@jongriffin.com +-- @creation-date 2002-09-25 +-- @cvs-id $Id: acs-person-drop.sql,v 1.1 2002/10/08 15:46:47 rmello Exp $ + +set server output on + +--@@ acs-person-sc-drop.sql + +-- drop sequence +drop sequence acs_persons_seq; + +-- drop functions + +drop package acs_person; + +--drop permissions +delete from acs_permissions where object_id in (select acs_person_id from acs_persons); + +-- drop the tables +drop table affix_type; +drop table affix_acs_persons_map; +drop table acs_persons_given_names; +drop table acs_persons_middle_names; +drop table acs_persons_family_names; +drop table acs_persons; + + +-- drop attributes and object types + +execute acs_object_type.drop_type('acs_person','t'); + +show errors; \ No newline at end of file Index: openacs.org-dev/packages/acs-person/sql/oracle/acs-person-plsql.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/sql/oracle/acs-person-plsql.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/sql/oracle/acs-person-plsql.sql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,202 @@ +-- packages/acs-person/sql/oracle/acs-person-plsql.sql +-- +-- @author jon@jongriffin.com +-- @creation-date 2002-09-25 +-- @cvs-id $Id: acs-person-plsql.sql,v 1.1 2002/10/08 15:46:47 rmello Exp $ + +begin + acs_object_type.create_type ( + object_type => 'acs_person', + pretty_name => 'ACS Person', + pretty_plural => 'ACS Persons', + supertype => 'acs_object', + table_name => 'acs_persons', + id_column => 'acs_person_id' + ); +end; +/ +show errors + +create or replace package acs_person +as + -- + -- + function new ( + acs_person_id in acs_persons.acs_person_id%TYPE default null, + family_name in acs_persons.family_name%TYPE, + given_name in acs_persons.given_name%TYPE, + middle_name in acs_persons.middle_name%TYPE default null, + formatted_name in acs_persons.formatted_name%TYPE default null, + preferred_given_name in acs_persons.preferred_given_name%TYPE default null, + user_id in acs_persons.user_id%TYPE default null + object_type in acs_objects.object_type%TYPE default 'acs_object', + creation_date in acs_objects.creation_date%TYPE default sysdate, + creation_use in acs_objects.creation_user%TYPE default null, + creation_ip in acs_objects.creation_ip%TYPE default null, + context_id in acs_objects.context_id%TYPE default null + ) return acs_persons.acs_person_id%TYPE; + -- + -- + procedure delete ( + acs_person_id in acs_persons.acs_person_id%TYPE + ); + procedure set ( + acs_person_id in acs_persons.acs_person_id%TYPE default null, + family_name in acs_persons.family_name%TYPE, + given_name in acs_persons.given_name%TYPE, + middle_name in acs_persons.middle_name%TYPE default null, + formatted_name in acs_persons.formatted_name%TYPE default null, + preferred_given_name in acs_persons.preferred_given_name%TYPE default null, + user_id in acs_persons.user_id%TYPE default null + ); + -- + -- +end acs_person_id; +/ +show errors + + +create or replace package body contact +as + function new ( + acs_person_id in acs_persons.acs_person_id%TYPE default null, + family_name in acs_persons.family_name%TYPE, + given_name in acs_persons.given_name%TYPE, + middle_name in acs_persons.middle_name%TYPE default null, + formatted_name in acs_persons.formatted_name%TYPE default null, + preferred_given_name in acs_persons.preferred_given_name%TYPE default null, + user_id in acs_persons.user_id%TYPE default null + object_type in acs_objects.object_type%TYPE default 'acs_object', + creation_date in acs_objects.creation_date%TYPE default sysdate, + creation_use in acs_objects.creation_user%TYPE default null, + creation_ip in acs_objects.creation_ip%TYPE default null, + context_id in acs_objects.context_id%TYPE default null + ) return acs_persons.acs_person_id%TYPE + is + v_acs_person_id acs_persons.acs_person_id%TYPE; + begin + v_acs_person_id := acs_object.new ( + object_id => acs_person_id, + object_type => object_type, + creation_date => creation_date, + creation_user => creation_user, + creation_ip => creation_ip, + context_id => context_id + ); + -- + insert into acs_persons + ( acs_person_id, + family_name, + given_name, + middle_name, + formatted_name, + preferred_given_name + ) + values + ( v_acs_person_id, + family_name, + given_name, + middle_name, + formatted_name, + preferred_given_name); + + acs_permission.grant_permission( + object_id => v_acs_person_id, + grantee_id => creation_user, + privilege => 'admin' + ); + + return v_acs_person_id; + end new; + -- + -- + procedure delete ( + acs_person_id in acs_persons.acs_person_id%TYPE + ) + is + begin + delete from acs_persons + where acs_person_id = acs_person.delete.acs_person_id; + -- + acs_object.delete(acs_person_id); + end delete; + -- + -- + procedure set ( + acs_person_id in acs_persons.acs_person_id%TYPE default null, + family_name in acs_persons.family_name%TYPE, + given_name in acs_persons.given_name%TYPE, + middle_name in acs_persons.middle_name%TYPE default null, + formatted_name in acs_persons.formatted_name%TYPE default null, + preferred_given_name in acs_persons.preferred_given_name%TYPE default null, + user_id in acs_persons.user_id%TYPE default null + ) + is + begin + update acs_persons + set + given_name = p_given_name, + middle_name = p_middle_name, + family_name = p_family_name, + formatted_name = p_formatted_name, + preferred_given_name = p_preferred_given_name, + user_id = p_user_id + where acs_person_id = p_acs_person_id; + + end set; + -- + -- + +end acs_person; +/ +show errors + +-- ancillary tables +begin + acs_object_type.create_type ( + object_type => 'acs_person_given_name', + pretty_name => 'ACS Person Given Name', + pretty_plural => 'ACS Person Given Names', + supertype => 'acs_object', + table_name => 'acs_person_given_name', + id_column => 'given_name_id' + ); +end; +/ +show errors + +create or replace package acs_person_given_name +as + procedure set ( + p_acs_person_id in acs_persons_given_name.acs_person_id%TYPE, + p_extra_given_name in acs_persons_given_name.extra_given_name%TYPE, + p_sort_order in acs_persons_given_name.sort_order%TYPE, + p_given_name_id in acs_persons_given_name.given_name_id%TYPE + ); + +end acs_person_given_name; +/ +show errors + + +create or replace package body acs_person_given_name +as + procedure set ( + p_acs_person_id in acs_persons_given_name.acs_person_id%TYPE, + p_extra_given_name in acs_persons_given_name.extra_given_name%TYPE, + p_sort_order in acs_persons_given_name.sort_order%TYPE, + p_given_name_id in acs_persons_given_name.given_name_id%TYPE + ) + is + begin + update acs_persons_given_name + set + acs_person_id = p_acs_person_id, + given_name = p_given_name, + sort_order = p_sort_order + where given_name_id = p_given_name_id; + +end acs_person_given_name; +/ +show errors + Index: openacs.org-dev/packages/acs-person/sql/oracle/acs-person-sc-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/sql/oracle/acs-person-sc-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/sql/oracle/acs-person-sc-create.sql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,58 @@ +select acs_sc_impl__new( + 'FtsContentProvider', -- impl_contract_name + 'acs_person', -- impl_name + 'acs_persons' -- impl_owner_name +); + +select acs_sc_impl_alias__new( + 'FtsContentProvider', -- impl_contract_name + 'acs_person', -- impl_name + 'datasource', -- impl_operation_name + 'acs_persons__datasource', -- impl_alias + 'TCL' -- impl_pl +); + +select acs_sc_impl_alias.new( + 'FtsContentProvider', -- impl_contract_name + 'acs_person', -- impl_name + 'url', -- impl_operation_name + 'acs_persons__url', -- impl_alias + 'TCL' -- impl_pl +); + + +create function acs_persons__itrg () +returns opaque as ' +begin + perform search_observer__enqueue(new.acs_person_id,''INSERT''); + return new; +end;' language 'plpgsql'; + +create function acs_persons__dtrg () +returns opaque as ' +begin + perform search_observer__enqueue(old.acs_person_id,''DELETE''); + return old; +end;' language 'plpgsql'; + +create function acs_persons__utrg () +returns opaque as ' +begin + perform search_observer__enqueue(old.acs_person_id,''UPDATE''); + return old; +end;' language 'plpgsql'; + + +create trigger acs_persons__itrg after insert on acs_persons +for each row execute procedure acs_persons__itrg (); + +create trigger acs_persons__dtrg after delete on acs_persons +for each row execute procedure acs_persons__dtrg (); + +create trigger acs_persons__utrg after update on acs_persons +for each row execute procedure acs_persons__utrg (); + + + + + Index: openacs.org-dev/packages/acs-person/sql/oracle/acs-person-sc-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/sql/oracle/acs-person-sc-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/sql/oracle/acs-person-sc-drop.sql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,23 @@ +select acs_sc_binding__delete( + 'FtsContentProvider', -- contract_name + 'acs_person' -- impl_name +); + +select acs_sc_impl__delete( + 'FtsContentProvider', -- impl_contract_name + 'acs_person' -- impl_name +); + + + + +drop trigger acs_persons__utrg on acs_persons; +drop trigger acs_persons__dtrg on acs_persons; +drop trigger acs_persons__itrg on acs_persons; + + + +drop function acs_persons__utrg (); +drop function acs_persons__dtrg (); +drop function acs_persons__itrg (); + Index: openacs.org-dev/packages/acs-person/sql/postgresql/acs-person-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/sql/postgresql/acs-person-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/sql/postgresql/acs-person-create.sql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,197 @@ +-- @cvs-id:$Id: acs-person-create.sql,v 1.1 2002/10/08 15:46:47 rmello Exp $ + +-- This is a fairly direct mapping of the HR-XML PersonName v1.0 schema +-- see the docs for explanations + +-- create a package sequence +create sequence acs_persons_seq; + +-- create some lookup tables + +-- affix_type +create table affix_type ( + affix_type_id integer + constraint affix_type_id_pk + primary key, + xml_name varchar(20) + constraint affix_type_xml_name_nn + not null, + help_text varchar(400) + constraint affix_type_pretty_name_nn + not null +); + +-- add some initial data + +insert into affix_type + (affix_type_id, xml_name,help_text) +values + (nextval('acs_persons_seq'),'aristocraticTitle','i.e. Baron, Graf, Earl, etc.'); + +insert into affix_type + (affix_type_id, xml_name,help_text) +values + (nextval('acs_persons_seq'),'aristocraticPrefix','i.e. Von, etc.'); + +insert into affix_type + (affix_type_id, xml_name,help_text) +values + (nextval('acs_persons_seq'),'formOfAddress','Contains the salutation, +i.e. Mr., Mrs., Hon., Dr., etc.'); + +insert into affix_type + (affix_type_id,xml_name,help_text) +values + (nextval('acs_persons_seq'),'FamilyNamePrefix','Contains the part of the person''s +name that precedes the family name. i.e. Van den, Von, etc.'); + +insert into affix_type + (affix_type_id,xml_name,help_text) +values + (nextval('acs_persons_seq'),'generation','i.e. Sr. Jr., III'); + +insert into affix_type + (affix_type_id,xml_name,help_text) +values + (nextval('acs_persons_seq'),'qualifications','Contains the letters used to describe the academic qualifications held by a person and/or the distinctions conferred upon them. +i.e. PhD, MD, CPA, MCSD, etc.'); + + + + +-- Main table +create table acs_persons ( + acs_person_id integer + constraint acs_person_id_pk + primary key + constraint acs_person_id_fk + references acs_objects(object_id), + formatted_name varchar (200), + given_name varchar (100), + preferred_given_name varchar (100), + middle_name varchar (100), + -- The spec says that all fields should be optional + -- This data model requires at least the family_name + -- element. Madonna and Prince go here whether they + -- consider that a family name or not. + family_name varchar (100) + constraint acs_prsn_fmly_nme_nn + not null, + -- link into users + user_id integer + constraint acs_user_id_fk + references users(user_id) +); + +create index acs_persons_full_name_ix on acs_persons (given_name,family_name); +create index acs_persons_family_name_ix on acs_persons (family_name); + +comment on table acs_persons is ' +This is the main table for acs_persons. It is a direct mapping of the HR-XML +PersonName v1.0 schema +'; + +comment on column acs_persons.acs_person_id is ' +Primary key. +'; + +comment on column acs_persons.family_name is ' +The last name. +'; + +comment on column acs_persons.given_name is ' +Given or first name. +'; + +comment on column acs_persons.middle_name is ' +This could also be more than one name. +'; + +comment on column acs_persons.formatted_name is ' +This is the name as it might appear in a letter. +'; + +comment on column acs_persons.preferred_given_name is ' +'; + + +comment on column acs_persons.acs_person_id is ' +Foriegn key. This can be null as we also want to use this for non-users progams +i.e. contact manager etc. +'; + + +-- Now the map tables + +-- affix_acs_persons_map +-- +-- This is necessary due to the way HR-XML implemented the affix system. +-- Since it is many to many this is the only way. + +create table affix_acs_persons_map ( + acs_person_id integer + constraint affix_person_id_fk + references persons(person_id), + affix_type_id integer + constraint affix_type_id_fk + references affix_type(affix_type_id), + ---- add the primary key to ensure uniqueness + constraint affix_acs_prsn_map_pk + primary key (acs_person_id,affix_type_id) +); + +-- acs_persons_given_names +create table acs_persons_given_names ( + given_name_id integer + constraint acs_prsn_gvn_nme_pk + primary key, + acs_person_id integer + constraint acs_prsn_gvn_nme_fk + references acs_persons(acs_person_id), + extra_given_name varchar(100) + constraint acs_prsn_gvn_nme_name_nn + not null, + sort_order integer, + ---- add some constraints to keep data sanity + constraint acs_prsn_gvn_nme_uq + unique (acs_person_id,extra_given_name,sort_order) +); + +create table acs_persons_middle_names ( + middle_name_id integer + constraint acs_prsn_mdl_nme_pk + primary key, + acs_person_id integer + constraint acs_prsn_mdl_nme_fk + references acs_persons(acs_person_id), + extra_middle_name varchar(100) + constraint acs_prsn_mdl_nme_name_nn + not null, + sort_order integer, + ---- add some constraints to keep data sanity + constraint acs_prsn_mdl_nme_uq + unique (acs_person_id,extra_middle_name,sort_order) +); + +create table acs_persons_family_names ( + family_name_id integer + constraint acs_prsn_fmly_nme_pk + primary key, + acs_person_id integer + constraint acs_prsn_fmly_nme_fk + references acs_persons(acs_person_id), + extra_family_name varchar(100) + constraint acs_prsn_fmly_nme_name_nn + not null, + sort_order integer, + ---- add some constraints to keep data sanity + constraint acs_prsn_fmly_nme_uq + unique (acs_person_id,extra_family_name,sort_order) +); + +-- plsql procs +\i acs-person-plsql.sql + +-- Service contract +-- Broken drop script +-- \i acs-person-sc-create.sql Index: openacs.org-dev/packages/acs-person/sql/postgresql/acs-person-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/sql/postgresql/acs-person-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/sql/postgresql/acs-person-drop.sql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,54 @@ +-- packages/acs-person/sql/postgresql/acs-person-drop.sql +-- +-- @author jon@jongriffin.com +-- @creation-date 2002-09-21 +-- @cvs-id $Id: acs-person-drop.sql,v 1.1 2002/10/08 15:46:47 rmello Exp $ + + +\i acs-person-sc-drop.sql + +-- drop sequence +drop sequence acs_persons_seq; + +-- drop functions + +drop function acs_person__new (varchar, varchar, varchar, varchar, varchar, +integer,integer,varchar,integer); + +drop function acs_person__del (integer); + +drop function acs_person__set (varchar, varchar, varchar, varchar, varchar, +integer,integer); + +--drop permissions +delete from acs_permissions where object_id in (select acs_person_id from acs_persons); + +--drop objects +create function inline_0 () +returns integer as ' +declare + object_rec record; +begin + for object_rec in select object_id from acs_objects where object_type=''acs_person'' + loop + perform acs_object__delete( object_rec.object_id ); + end loop; + + return 0; +end;' language 'plpgsql'; + +select inline_0(); +drop function inline_0(); + +-- drop the tables +drop table affix_type; +drop table affix_acs_persons_map; +drop table acs_persons_given_names; +drop table acs_persons_middle_names; +drop table acs_persons_family_names; +drop table acs_persons; + + +-- drop attributes and object types + +select acs_object_type__drop_type('acs_person','t'); Index: openacs.org-dev/packages/acs-person/sql/postgresql/acs-person-plsql.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/sql/postgresql/acs-person-plsql.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/sql/postgresql/acs-person-plsql.sql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,160 @@ +-- packages/acs-person/sql/postgresql/acs-person-plsql.sql +-- +-- @author jon@jongriffin.com +-- @creation-date 2002-09-21 +-- @cvs-id $Id: acs-person-plsql.sql,v 1.1 2002/10/08 15:46:47 rmello Exp $ + +-- I don't use create or replace on these temp functions +-- because I want to have them explicitly deleted + +create function inline_0 () +returns integer as ' +begin + PERFORM acs_object_type__create_type ( + ''acs_person'', -- object_type + ''ACS Person'', -- pretty_name + ''ACS Persons'', -- pretty_plural + ''acs_object'', -- supertype + ''acs_persons'', -- table_name + ''acs_person_id'', -- id_column + null, -- package_name + ''f'', -- abstract_p + null, -- type_extension_table + null -- name_method + ); + + return 0; +end;' language 'plpgsql'; + +select inline_0 (); + +drop function inline_0 (); + +create or replace function acs_person__new (integer,varchar, varchar, varchar, varchar, varchar, +integer,integer,varchar,integer) +returns integer as ' +declare + p_acs_person_id alias for $1; + p_given_name alias for $2; + p_middle_name alias for $3; + p_family_name alias for $4; + p_formatted_name alias for $5; + p_preferred_given_name alias for $6; + p_user_id alias for $7; -- this is not the creation user + p_creation_user alias for $8; + p_creation_ip alias for $9; + p_context_id alias for $10; + v_acs_person_id acs_persons.acs_person_id%TYPE; +begin + v_acs_person_id := acs_object__new ( + null, + ''acs_person'', + now(), + p_creation_user, + p_creation_ip, + p_context_id + ); + + insert into acs_persons + ( acs_person_id, + given_name, + middle_name, + family_name, + formatted_name, + preferred_given_name, + user_id + ) + values + ( + v_acs_person_id, + p_given_name, + p_middle_name, + p_family_name, + p_formatted_name, + p_preferred_given_name, + p_user_id + ); + + PERFORM acs_permission__grant_permission ( + v_acs_person_id, + p_creation_user, + ''admin'' + ); + + raise NOTICE ''Adding acs_person - %'',v_acs_person_id; + return v_acs_person_id; + +end;' language 'plpgsql'; + + +create or replace function acs_person__del (integer) +returns integer as ' +declare + p_acs_person_id alias for $1; + v_return integer := 0; +begin + + delete from acs_permissions + where object_id = p_acs_person_id; + + delete from acs_persons + where acs_person_id = p_acs_person_id; + + raise NOTICE ''Deleting acs_person - %'',p_acs_person_id; + + return v_return; + +end;' language 'plpgsql'; + +create or replace function acs_person__set (varchar, varchar, varchar, varchar, varchar, + integer,integer) +returns integer as ' +declare + p_given_name alias for $1; + p_middle_name alias for $2; + p_family_name alias for $3; + p_formatted_name alias for $4; + p_preferred_given_name alias for $5; + p_user_id alias for $6; -- this is not the creation user + p_acs_person_id alias for $7; + v_return integer := 0; +begin + + update acs_persons + set given_name = p_given_name, + middle_name = p_middle_name, + family_name = p_family_name, + formatted_name = p_formatted_name, + preferred_given_name = p_preferred_given_name, + user_id = p_user_id + where acs_person_id = p_acs_person_id; + + raise NOTICE ''Updating acs persons %'',p_acs_person_id; + + return v_return; + +end;' language 'plpgsql'; + +-- ancillary tables + +create or replace function acs_person_given_name__set (varchar, varchar, varchar,integer) +returns integer as ' +declare + p_acs_person_id alias for $1; + p_extra_given_name alias for $2; + p_sort_order alias for $3; + p_given_name_id alias for $4; + v_return integer := 0; +begin + + update acs_persons_given_name + set acs_person_id = p_acs_person_id, + given_name = p_given_name, + sort_order = p_sort_order + where given_name_id = p_given_name_id + + raise NOTICE ''Updating given_names - %'',p_given_name; + +return v_return;' language 'plpgsql'; + + Index: openacs.org-dev/packages/acs-person/sql/postgresql/acs-person-sc-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/sql/postgresql/acs-person-sc-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/sql/postgresql/acs-person-sc-create.sql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,53 @@ +select acs_sc_impl__new( + 'FtsContentProvider', -- impl_contract_name + 'acs_person', -- impl_name + 'acs_persons' -- impl_owner_name +); + +select acs_sc_impl_alias__new( + 'FtsContentProvider', -- impl_contract_name + 'acs_person', -- impl_name + 'datasource', -- impl_operation_name + 'acs_persons__datasource', -- impl_alias + 'TCL' -- impl_pl +); + +select acs_sc_impl_alias__new( + 'FtsContentProvider', -- impl_contract_name + 'acs_person', -- impl_name + 'url', -- impl_operation_name + 'acs_persons__url', -- impl_alias + 'TCL' -- impl_pl +); + + +create function acs_persons__itrg () +returns opaque as ' +begin + perform search_observer__enqueue(new.acs_person_id,''INSERT''); + return new; +end;' language 'plpgsql'; + +create function acs_persons__dtrg () +returns opaque as ' +begin + perform search_observer__enqueue(old.acs_person_id,''DELETE''); + return old; +end;' language 'plpgsql'; + +create function acs_persons__utrg () +returns opaque as ' +begin + perform search_observer__enqueue(old.acs_person_id,''UPDATE''); + return old; +end;' language 'plpgsql'; + + +create trigger acs_persons__itrg after insert on acs_persons +for each row execute procedure acs_persons__itrg (); + +create trigger acs_persons__dtrg after delete on acs_persons +for each row execute procedure acs_persons__dtrg (); + +create trigger acs_persons__utrg after update on acs_persons +for each row execute procedure acs_persons__utrg (); Index: openacs.org-dev/packages/acs-person/sql/postgresql/acs-person-sc-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/sql/postgresql/acs-person-sc-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/sql/postgresql/acs-person-sc-drop.sql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,23 @@ +select acs_sc_binding__delete( + 'FtsContentProvider', -- contract_name + 'acs_person' -- impl_name +); + +select acs_sc_impl__delete( + 'FtsContentProvider', -- impl_contract_name + 'acs_person' -- impl_name +); + + + + +drop trigger acs_persons__utrg on acs_persons; +drop trigger acs_persons__dtrg on acs_persons; +drop trigger acs_persons__itrg on acs_persons; + + + +drop function acs_persons__utrg (); +drop function acs_persons__dtrg (); +drop function acs_persons__itrg (); + Index: openacs.org-dev/packages/acs-person/www/add-edit-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/add-edit-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/add-edit-oracle.xql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,43 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="new_person"> + <querytext> + + declare + id integer; + begin + id := person.new ( + family_name => :family_name, + given_name => :given_name, + middle_name => :middle_name, + formatted_name => :formatted_name, + preferred_given_name => :preferred_given_name, + acs_user_id => :acs_user_id, + creation_user => :user_id, + creation_ip => :peeraddr, + context_id => :package_id + ); + + </querytext> +</fullquery> + +<fullquery name="set_person"> + <querytext> + begin + acs_person.set ( + :given_name, + :middle_name, + :family_name, + :formatted_name, + :preferred_given_name, + :acs_user_id, + :acs_person_id + ); + end; + + </querytext> +</fullquery> +</queryset> Index: openacs.org-dev/packages/acs-person/www/add-edit-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/add-edit-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/add-edit-postgresql.xql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,39 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="new_person"> + <querytext> + select acs_person__new ( + :acs_person_id, + :given_name, + :middle_name, + :family_name, + :formatted_name, + :preferred_given_name, + :acs_user_id, + :user_id, + :peeraddr, + :package_id + ); + + </querytext> +</fullquery> + +<fullquery name="set_person"> + <querytext> + select acs_person__set ( + :given_name, + :middle_name, + :family_name, + :formatted_name, + :preferred_given_name, + :acs_user_id, + :acs_person_id + ); + + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/acs-person/www/add-edit.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/add-edit.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/add-edit.adp 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,6 @@ +<master> +<property name="title">@page_title_c@</property> +<property name="context_bar">@context_bar@</property> + +<formtemplate id="new_person"></formtemplate> + Index: openacs.org-dev/packages/acs-person/www/add-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/add-edit.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/add-edit.tcl 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,93 @@ +# packages/acs-person/www/add-edit.tcl + +ad_page_contract { + @author Jon Griffin jon@jongriffin.com + @creation-date 2002-09-21 + @cvs-id $Id: add-edit.tcl,v 1.1 2002/10/08 15:46:47 rmello Exp $ +} { + acs_person_id:integer,optional + {family_name ""} + {given_name ""} + {middle_name ""} + {formatted_name ""} + {preferred_given_name ""} + {acs_user_id ""} +} -properties { + context_bar:onevalue + page_title:onevalue +} + +# +set package_id [ad_conn package_id] +set user_id [ad_conn user_id] +set peeraddr [ad_conn peeraddr] + +## vars for quasi localization +## since this isn't available yet this is a reminder to myself + +set cbar_title "Person Info" +#set cbar_title "Informacion de una persona" +set page_title_e "Edit Person" +set page_title_c "Create Person" + +if {[info exists acs_person_id]} { + + set page_title $page_title_e + set context_bar [ad_context_bar [list "." $cbar_title ] [list "one?acs_person_id=$acs_person_id" $cbar_title] $page_title] +} else { + ad_require_permission $package_id create + set page_title $page_title_c + set context_bar [ad_context_bar [list "." $cbar_title] $page_title ] +} + +ad_form -name new_person -form { + +acs_person_id:key + +{given_name:text(text) + {label "First Name"} + {html {size 40}} + {value {$given_name}}} + +{middle_name:text(text) + {label "Middle"} + {html { size 30 }}} + +{family_name:text(text) + {label "Last Name"} + {html { size 40 }}} + +{formatted_name:text(text) + {label "Formatted Name"} + {html { size 40 }} + optional} + +{preferred_given_name:text(text) + {label "Preferred Name"} + {html { size 40 }} + optional} + +{acs_user_id:text(text) + {label "ACS User"} + {html {size 10}} + optional} +} -select_query_name person_select -validate { + +} -new_data { + + db_exec_plsql new_person { } + ad_returnredirect "." + ad_script_abort + +} -edit_data { + ad_require_permission $acs_person_id write + + db_exec_plsql set_person { } + ad_returnredirect "." + ad_script_abort +} + +ad_return_template + + + Index: openacs.org-dev/packages/acs-person/www/add-edit.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/add-edit.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/add-edit.xql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="person_select"> + <querytext> + + select p.acs_person_id, + family_name, + given_name, + middle_name, + formatted_name, + preferred_given_name, + user_id as acs_user_id + from acs_persons p + where p.acs_person_id = :acs_person_id + + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/acs-person/www/delete-2-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/delete-2-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/delete-2-oracle.xql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,17 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="person_delete"> + <querytext> + + begin + acs_person.delete(:acs_person_id); + end; + + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/acs-person/www/delete-2-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/delete-2-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/delete-2-postgresql.xql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,14 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="person_delete"> + <querytext> + + select acs_person__del(:acs_person_id); + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/acs-person/www/delete-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/delete-2.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/delete-2.tcl 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,17 @@ +ad_page_contract { + + @author Jon Griffin jon@jongriffin.com + @creation-date 2002-09-23 + @cvs-id $Id: delete-2.tcl,v 1.1 2002/10/08 15:46:47 rmello Exp $ +} { + acs_person_id:integer,notnull +} + +ad_require_permission $acs_person_id delete + +db_exec_plsql person_delete { + +} + +ad_returnredirect "." + Index: openacs.org-dev/packages/acs-person/www/delete.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/delete.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/delete.adp 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,10 @@ +<master> +<property name="title">@title@</property> +<property name="context_bar">@context_bar@</property> + +<h3>@title@</h3> +<hr> +Are you sure you want to delete <b>@one_person.name@</b>?<br> + +<a href="delete-2?acs_person_id=@one_person.acs_person_id@">Delete</a><p> +<a href=".">Return</a> Index: openacs.org-dev/packages/acs-person/www/delete.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/delete.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/delete.tcl 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,36 @@ +ad_page_contract { + + Delete Confirmation page for acs-person + + @author jon@jongriffin.com + @creation-date 2002-09-23 + @cvs-id $Id: delete.tcl,v 1.1 2002/10/08 15:46:47 rmello Exp $ + +} { + acs_person_id:integer,notnull +} -validate { + person_exists -requires {acs_person_id} { + if ![db_0or1row person_exists { + }] { + ad_complain "Person $acs_person_id does not exist" + return 0 + } + return 1 + } +} -properties { + title:onevalue + one_person:onerow +} + +set title "Delete Person" +set context_bar [ad_context_bar] +set package_id [ad_conn package_id] +set user_id [ad_conn user_id] + +# make sure they don't perform URL surgery +ad_require_permission $acs_person_id delete + +db_1row person_select { +} -column_array one_person + + \ No newline at end of file Index: openacs.org-dev/packages/acs-person/www/delete.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/delete.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/delete.xql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="person_exists"> + <querytext> + + select 1 from acs_persons where acs_person_id = :acs_person_id + + </querytext> +</fullquery> + + +<fullquery name="person_select"> + <querytext> + + select acs_person_id, + given_name || ' ' || family_name as name + from acs_persons + where acs_person_id = :acs_person_id + + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/acs-person/www/index-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/index-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/index-oracle.xql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,23 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="persons_select"> + <querytext> + + select acs_person_id, + family_name, + given_name, + middle_name + from acs_persons p, acs_objects o + where p.acs_person_id = o.object_id + and o.context_id = :package_id + ${search_clause} + ${starts_with_clause} + order by $ordering + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/acs-person/www/index-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/index-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/index-postgresql.xql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,21 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="acs_persons_select"> + <querytext> + select acs_person_id, + family_name, + given_name, + middle_name, + acs_permission__permission_p(acs_person_id,:user_id,'write') as write_p, + acs_permission__permission_p(acs_person_id,:user_id,'delete') as delete_p + from acs_objects o,acs_persons p + where p.acs_person_id = o.object_id + and o.context_id = :package_id + order by $ordering + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/acs-person/www/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/index.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/index.adp 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,104 @@ +<master> +<property name="title">@title@</property> +<property name="context_bar">@context_bar@</property> + +<h4>@title@</h4> + +<if admin_p ne 0> + <div align="right"> + <a href="admin/">Admin</a> + </div> +</if> + + +<if @persons:rowcount@ gt 0> + +<table border="0" cellspacing="1" cellpadding="5" width="100%"> + <tr bgcolor="#ffffff"> + <td colspan="7"> + <center> + <multiple name="first_letter"> + <if @first_letter.letter@ ne @starts_with@> + <a href=".?starts_with=@first_letter.letter@">@first_letter.letter@</a> + </if> + <else> + <b>@first_letter.letter@</b> + </else> + </multiple> + <if @starts_with@ eq "all"> + <b>All</b> + </if> + <else> + <a href=".?starts_with=all"><b>All</b></a> + </else> + <if @starts_with@ eq "other"> + <b>Other</b> + </if> + <else> + <a href=".?starts_with=other"><b>Other</b></a> + </else> + </center> + <br> + + <if @starts_with@ ne ""> + <div style="background-color: #eeeeee; width:100%;"> + <font size="+1"><b>@starts_with@ :</b></font> + </div> + </if> + + <if @search_p@ ne 0 and @search_string@ ne ""> + <div style="background-color: #eeeeee; width:100%;"> + <font size="+1"><b>Search results :</b></font> + </div> + </if> + </td> + </tr> + <tr bgcolor="#cccccc"> + <th nowrap align="left"><a href=".?sort=lname&search_p=@search_p@&search_string=@search_string@&starts_with=@starts_with@">Last Name</a></th> + <th nowrap align="left"><a href=".?sort=fname&search_p=@search_p@&search_string=@search_string@&starts_with=@starts_with@">First Name</a></th> + <th> </th> + <th> </th> + </tr> + <multiple name=persons> + + <if @persons.rownum@ odd> + <tr bgcolor=#cccccc> + </if> + <else> + <tr bgcolor=#ffffff> + </else> + + <td><a href="one?acs_person_id=@persons.acs_person_id@">@persons.family_name@</a></td> + + <td>@persons.given_name@</td> + + <td> + <if @persons.write_p@ eq "t"><a href="add-edit?acs_person_id=@persons.acs_person_id@">Edit</a></if> + </td> + + <td> + <if @persons.delete_p@ eq "t"><a href="delete?acs_person_id=@persons.acs_person_id@">Delete</a></if> + </td> +</tr> +</multiple> +</table> + +<br><br> +@pagination_link@ + +</if> +<else> + <table border=0 width=100%> + <tr bgcolor=#eeeeee> + <td align=center><br>There are no people<br> </td> + </tr> + </table> +</else> + +<if @acs_persons_create_p@ ne 0> + <br> + <div align="center"> + <a href="add-edit">New Person</a> + </div> +</if> + Index: openacs.org-dev/packages/acs-person/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/index.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/index.tcl 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,124 @@ +ad_page_contract { + + Displays a list of people + + @author Jon Griffin (jon@jongriffin.com) + @creation-date 2002-09-21 + @cvs-id $Id: index.tcl,v 1.1 2002/10/08 15:46:47 rmello Exp $ +} { + {start:integer "1"} + {search_p 0} + {search_string ""} + {search_in ""} + {sort ""} + {starts_with ""} +} -properties { + context_bar:onevalue + package_id:onevalue + user_id:onevalue + persons:multirow + title:onevalue + first_letter:multirow + acs_persons_create_p:onevalue +} + + +set user_id [ad_verify_and_get_user_id] +set package_id [ad_conn package_id] + +set title "People" +set context_bar [ad_context_bar $title] + +set acs_persons_create_p [ad_permission_p $package_id create] +set admin_p [ad_permission_p $package_id admin] + + +db_multirow first_letter get_first_letters { } + + +switch $sort { + "fname" { set ordering "given_name, family_name, company_name" } + "lname" { set ordering "family_name, given_name, company_name" } + default { set ordering "family_name" } +} + +if { ![empty_string_p $starts_with] } { + switch $starts_with { + "all" { set starts_with_clause "" } + "other" { set starts_with_clause "and family_name is null" } + default { set starts_with_clause "and upper(family_name) like '${starts_with}%'" } + } + +} else { + set starts_with_clause "" +} + + +## should be able to get rid of this with search package +if { $search_p == 1 && ![string equal $search_string ""]} { + switch $search_in { + "fname" { set search_clause "and lower(given_name) like '%' || lower(:search_string) || '%'" } + "lname" { set search_clause "and lower(family_name) like '%' || lower(:search_string) || '%'" } + "any" { set search_clause "and (lower(family_name) like '%' || lower(:search_string) || '%' or + lower(given_name) like '%' || lower(:search_string) || '%')" } + } + +} else { + set search_clause "" +} + + +set max_dspl [ad_parameter MaxPersonsShow acs_persons 10] +set count 0 + +db_multirow persons acs_persons_select { } + +set total_contacts [db_string retrieved_contacts "select count(*) + from contacts c, acs_objects o + where c.contact_id = o.object_id + ${search_clause} + ${starts_with_clause}"] + +# and o.context_id = :package_id + +# make paging links +if { $count < [expr $start + $max_dspl] } { + set next_start "" +} else { + if {[expr $start + 2 * $max_dspl - $total_contacts] < 0 } { + set next_val $max_dspl + } else { + set next_val [expr $total_contacts - $start - $max_dspl + 1] + } + + set next_start "<a href=index?start=[expr $start + $max_dspl]&search_p=${search_p}&search_string=${search_string}&search_in=${search_in}&starts_with=${starts_with}&sort=${sort}>NEXT $next_val<a/>" +} + +if { $start == 1 } { + set prev_start "" +} else { + set prev_start "<a href=index?start=[expr $start - $max_dspl]&search_p=${search_p}&search_string=${search_string}&search_in=${search_in}&starts_with=${starts_with}&sort=${sort}>PREV $max_dspl</a>" +} + +if { ![empty_string_p $next_start] && ![empty_string_p $prev_start] } { + set divider " | " +} else { + set divider "" +} + +if { [expr $start + $max_dspl - 1] > $total_contacts } { + if { $total_contacts == 0 } { + set start 0 } + set showing "Showing: $start - $total_contacts" +} else { + set showing "Showing: $start - [expr $start + $max_dspl - 1]" +} + +set pagination_link " $prev_start$divider$next_start " + + +## setup a status bar +# where o.context_id = :package_id +# and acs_permission.permission_p(contact_id, :user_id, 'read') = 't' + +ad_return_template Index: openacs.org-dev/packages/acs-person/www/index.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/index.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/index.xql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="get_first_letters"> + <querytext> + + select distinct substr(upper(family_name), 0, 1) as letter from acs_persons + + </querytext> +</fullquery> + + +<fullquery name="retrieved_contacts"> + <querytext> + select count(*) + from acs_persons p, acs_objects o + where p.acs_person_id = o.object_id + ${search_clause} + ${starts_with_clause} + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/acs-person/www/one-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/one-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/one-oracle.xql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,33 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="person_select"> + <querytext> + + select acs_person_id, + given_name, + family_name, + middle_name, + preferred_given_name, + formatted_name, + given_name || ' ' || family_name as pretty_name, + decode(acs_permission.permission_p(contact_id, + :user_id, + 'write'), + 't',1, + 'f',0) as write_p, + decode(acs_permission.permission_p(contact_id, + :user_id, + 'delete'), + 't',1, + 'f',0) as delete_p + from acs_persons p + where acs_person_id = :acs_person_id + + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/acs-person/www/one-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/one-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/one-postgresql.xql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,25 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="person_select"> + <querytext> + select acs_person_id, + given_name, + family_name, + middle_name, + preferred_given_name, + formatted_name, + given_name || ' ' || family_name as pretty_name, + case when acs_permission__permission_p(acs_person_id,:user_id,'write') = 't' + then 1 else 0 end as write_p, + case when acs_permission__permission_p(acs_person_id,:user_id,'delete') = 't' + then 1 else 0 end as delete_p + from acs_persons p + where acs_person_id = :acs_person_id + + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/acs-person/www/one.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/one.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/one.adp 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,40 @@ +<master> +<property name="title">@page_title@ @person.pretty_name@</property> +<property name="context_bar">@context_bar@</property> + +<h3>@page_title@</h3> +<table width="100%"> + <tr> + <td valign="top" width="45%"> + <table> + + <tr><th valign=top align=right>First Name</th> + <td> @person.given_name@ </td></tr> + + <tr><th valign=top align=right>Middle Name</th> + <td> @person.middle_name@ </td></tr> + + <tr><th valign=top align=right>Family Name</th> + <td> @person.family_name@ </td></tr> + + <if @person.preferred_given_name@ not nil> + <tr><th valign=top align=right>Preferred Name</th> + <td> @person.preferred_given_name@ </td></tr> + </if> + + <if @person.formatted_name@ not nil> + <tr><th valign=top align=right>Formatted Name</th> + <td> @person.formatted_name@ </td></tr> + </if> + + <if @person.write_p@ eq 1> + <tr><td colspan="2" align="right"> + <a href="add-edit.tcl?acs_person_id=@person.acs_person_id@">edit info</a> + </td></tr> + </if> + </table> + </td> + </tr> +</table> + + Index: openacs.org-dev/packages/acs-person/www/one.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/one.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/one.tcl 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,42 @@ +# packages/acs-person/www/one.tcl + +ad_page_contract { + @author Jon Griffin jon@jongriffin.com + @creation-date 2002-09-21 + @cvs-id $Id: one.tcl,v 1.1 2002/10/08 15:46:47 rmello Exp $ +} { + acs_person_id:integer,notnull +} -validate { + person_exists -requires {person_id} { + if ![db_0or1row person_exists { + }] { + ad_complain "$acs_person_id does not exist" + return 0 + } + return 1 + } +} -properties { + context_bar:onevalue + page_title:onevalue + person:onerow +} + +## vars for quasi localization +## since this isn't available yet this is a reminder to myself + +set page_title "Viewing" +set cbar_title "View One Person" + +## set cbar_title "Informacion de una persona" + +set context_bar [ad_context_bar $page_title] + +set user_id [ad_verify_and_get_user_id] + +set person_write_p [ad_permission_p $acs_person_id "write"] + +db_1row person_select { + +} -column_array person + + Index: openacs.org-dev/packages/acs-person/www/one.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/one.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/one.xql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,13 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="person_exists"> + <querytext> + + select 1 from acs_persons where acs_person_id = :acs_person_id + + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/acs-person/www/admin/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/admin/index.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/admin/index.adp 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,8 @@ +<master> +<property name="title">@title@</property> +<property name="context_bar">@context_bar@</property> + +<h3>@title@</h3> +<hr> +Nothing Yet! + Index: openacs.org-dev/packages/acs-person/www/admin/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/admin/index.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/admin/index.tcl 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,27 @@ +ad_page_contract { + + Admin page for acs-person + + @author Jon Griffin (jon@jongriffin.com) + @creation-date 2002-09-21 + @cvs-id $Id: index.tcl,v 1.1 2002/10/08 15:46:47 rmello Exp $ +} { +} -properties { + context_bar:onevalue + package_id:onevalue + user_id:onevalue + contacts:multirow + title:onevalue +} + +set package_id [ad_conn package_id] + +set title "Contacts Admin" +set context_bar [ad_context_bar $title] + +set user_id [ad_verify_and_get_user_id] + +## setup a status bar + + +ad_return_template Index: openacs.org-dev/packages/acs-person/www/doc/acs-persons-schema.jpg =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/doc/acs-persons-schema.jpg,v diff -u Binary files differ Index: openacs.org-dev/packages/acs-person/www/doc/developer.html =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/doc/developer.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/doc/developer.html 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,109 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> +<title>acs-person Developer Docs</title> +</head> +<body> +<h1>acs-person Developer Documentation</h1> + +Version 0.1 <acronym>By Jon Griffin</acronym><br> + This document is Copyright © 2002 Jon Griffin. + +<p>Permission is granted to copy, distribute and/or modify this +document under the terms of the GNU Free Documentation License, +Version 1.1 or any later version published by the Free Software +Foundation with no Invariant Sections, no Front-Cover Texts, and +no Back-Cover Texts. A copy of the license is included in the +section entitled "GNU Free Documentation License".</p> + +<h2>Table of Contents</h2> + +<h2>Introduction</h2> + +acs-person is a superset of person in the OpenACS system. It can +be used as a standalone module or to augment/replace person. + +<h3>Data Model</h3> +<a href="acs-persons-schema.jpg">Schema</a> +Changes from HR-XML + +<p>The HR-XML specification describes several optional, +multi-valued attributes. Since we aren't dealing with XML as +the native format several changes/compromises had to be made.</p> + +<p>Certainly, multi-valued attributes could have been completely +normalized and been technically correct. It wasn't felt that +this was an efficient or proper use and in most cases only the +base table <code>acs_persons</code> will be used.</p> + +<p>With that in mind here is a rundown of the differences from +the specification:<br> +</p> + +<ul> +<li>FamilyName is a 0=>many attribute that also has an +attribute of primary. The purpose of this is to designate an +order when there are multiple family names. In acs-person, a map +table is created: <code>family_name_acs_persons_map</code>. This +creates an optional space for storing multiple family names. It +also includes a field called: <code>order</code>, which allows +for putting the family names in the correct order for multiple +family names. By default the family_name in the acs_persons table +will always appear first. The order field also allows for sorting +in the case of querys.</li> + +<li>GivenName is a 0=>many attribute. In acs_person, a map +table is created: <code>given_name_acs_persons_map</code>. This +creates an optional space for storing multiple given names. It +also includes a field called: <code>order</code>, which allows +for putting the given names in the correct order for multiple +given names. By default the given_name in the acs_persons table +will always appear first. The order field also allows for sorting +in the case of querys.</li> + +<li>MiddleName is a 0=>many attribute. In acs_person, a map +table is created: <code>middle_name_acs_persons_map</code>. This +creates an optional space for storing multiple middle names. It +also includes a field called: <code>order</code>, which allows +for putting the middle names in the correct order for multiple +middle names. By default the middle_name in the acs_persons table +will always appear first. The order field also allows for sorting +in the case of querys.</li> + +<li>Affix is a 0=>many attribute. In acs_person, a map table +is created: <code>affix_acs_persons_map</code>. This creates an +optional space for storing multiple affixes. It is linked to a +lookup table that def ines the valid <code>affix_types</code>. +This is complicated and may need additional thought as it is +really storing multiple unrelated attributes in one field. I +would not have modelled this like it is, but this is the standard +so I will leave it as is.</li> + +<li>AffixType defines the context for the Affix and is a lookup +table. This is required if any Affixes are present.</li> +</ul> + +<h2>Glossary</h2> + +Formatted Name<br> +Given Name<br> +Preferred Given Name<br> +Family Name<br> + +<h2>Credits</h2> + +<h2>License</h2> + +<a href="http://www.gnu.org/licenses/fdl.html">GNU Free +Documentation License</a> <br> +<h1>Revision History</h1> + +$Log: developer.html,v $ +Revision 1.2 2002/09/27 00:09:48 jong +updated some links +<br> +Revision 1.1 2002/08/09 23:34:02 jon +Initial Revision + +</body> +</html> \ No newline at end of file Index: openacs.org-dev/packages/acs-person/www/doc/index.html =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-person/www/doc/index.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-person/www/doc/index.html 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,131 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> +<title>acs-person</title> +</head> +<body> +<h1>acs-person Documentation</h1> +Version 0.1 <acronym>By Jon Griffin</acronym><br> + This document is Copyright © 2002 Jon Griffin. + +<p>Permission is granted to copy, distribute and/or modify this +document under the terms of the GNU Free Documentation License, +Version 1.1 or any later version published by the Free Software +Foundation with no Invariant Sections, no Front-Cover Texts, and +no Back-Cover Texts. A copy of the license is included in the +section entitled "GNU Free Documentation License".</p> + +<br> +<h2>Introduction</h2> + +acs-person is a superset of person in the OpenACS system. It can +be used as a standalone module or to augment/replace person. + +<h2>Table of Contents</h2> + +<a href="developer">Developers Guide</a><br> +<a href="administrator">Administrators Guide</a><br> +<a href="user">Users Guide</a><br> + +<h2>Design Goal</h2> + +<h2>History</h2> + +Probably since humankind started writing and keeping track of +others, there has been a debate about the easy way to store +information. This problem has only gotten worse as time went on. + +<p>The problem (along with addresses) seems relatively simple +until you think of all the variables that come along with it. Not +even taking into account alphabets there are many gotchas in +storing names correctly.</p> + +<p>Take for instance names in the Latin American Countries and +Spain:<br> +<code>Luis Alvaro Hernandez Garcia</code><br> +How would that be stored? In most US-centric databases this is +stored as either:<br> +</p> + +<pre> +<code>first_name — Luis +middle_name — Alvaro +last_name — Hernandez Garcia</code> +</pre> + +OR (as the case of OpenACS) + +<pre> +<code>first_name — Luis Alvaro +last_name — Hernandez Garcia</code> +</pre> + +While certainly this model is useful, it has its limitations. +What if you decide to sort your data by Last Name? What is the +correct part of last_name to sort on? Is it Hernandez or Garcia? +These are easy Western Language problems that get much more +complicated when dealing with Eastern European or other cultures +where names aren't written in a first, middle, last order. + +<p>Here are some examples of cultural differences and you can see +the problems that are created:<br> +<b>Indonesia</b> — Many (not all) Indonesians have only one +name.<br> +<b>Korea</b> — Some put family name first, others put +family names last.<br> +<b>Hispanic</b> — As well as the above example the rules +can get very complex. Spanish men, for example, sometimes use +their father's name and mother's name and separate them +with a y (and).<br> +<code>Luis Alvaro Hernandez y Garcia</code><br> +Other times they may hyphenate the last names:<br> +<code>Luis Alvaro Hernandez-Garcia</code><br> +Now onto Hispanic women (and this also changes somewhat by +country). In general a single women is similar to men. She takes +her father's last name and adds her mothers maiden name. The +difference comes about when the women marries. In this case the +women still has the fathers last name but appends the +husband's last name preceded by de (of):<br> +<code>Luisa Benavides Hernandez de Fernandez</code><br> +As a side note, in Cuba the Wife keeps her name and so does the +husband.<br> +To complicate matters more, the Wife may be refered to as Luisa +de Fernandez or simply Luisa Fernandez, as well as Sra +Fernandez.</p> + + +<h2>Glossary</h2> + +Formatted Name<br> +Given Name<br> +Preferred Given Name<br> +Family Name<br> + +<h2>Credits</h2> + +<h2>License</h2> + +<a href="http://www.gnu.org/licenses/fdl.html">GNU Free +Documentation License</a> <br> +<h1>Revision History</h1> + +$Log: index.html,v $ +Revision 1.2 2002/09/27 00:09:55 jong +updated some links +<br> +Revision 1.4 2002/08/09 23:51:27 jon<br> +Added new links +<br> +Revision 1.3 2002/08/09 23:35:17 jon<br> +Fixed bad typo in link<br> + +Revision 1.2 2002/08/09 23:34:32 jon<br> +Updated format and fixed typos<br> + +Revision 1.1 2002/08/09 23:16:02 jon<br> +Initial Revision<br> + +</body> +</html> + + Index: openacs.org-dev/packages/acs-service-contract/sql/oracle/upgrade/upgrade-4.5-4.5.1.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/acs-service-contract/sql/oracle/upgrade/upgrade-4.5-4.5.1.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/acs-service-contract/sql/oracle/upgrade/upgrade-4.5-4.5.1.sql 8 Oct 2002 15:46:47 -0000 1.1 @@ -0,0 +1,338 @@ +-- packages/acs-service-contract/sql/oracle/upgrade/upgrade-4.5-4.5.1.sql +-- +-- @author Vinod Kurup (vinod@kurup.com) +-- @creation_date 2002-08-14 +-- +-- $Id: upgrade-4.5-4.5.1.sql,v 1.1 2002/10/08 15:46:47 rmello Exp $ + +-- UPGRADE ISSUE 1 +-- PG version has 2 packages acs_sc_impl and acs_sc_impl_alias +-- For consistency, we're making it the same in Oracle +-- Oracle function acs_sc_impl.new_alias -> acs_sc_impl_alias.new +-- acs_sc_impl.delete_alias -> acs_sc_impl_alias.delete +-- Old functions deprecated, but still work. + +create or replace package acs_sc_impl_alias +as + function new ( + impl_contract_name acs_sc_contracts.contract_name%TYPE, + impl_name acs_sc_impls.impl_name%TYPE, + impl_operation_name acs_sc_operations.operation_name%TYPE, + impl_alias acs_sc_impl_aliases.impl_alias%TYPE, + impl_pl acs_sc_impl_aliases.impl_pl%TYPE + ) return acs_sc_impl_aliases.impl_id%TYPE; + + function delete ( + impl_contract_name acs_sc_contracts.contract_name%TYPE, + impl_name acs_sc_impls.impl_name%TYPE, + impl_operation_name acs_sc_operations.operation_name%TYPE + ) return acs_sc_impls.impl_id%TYPE; + +end acs_sc_impl_alias; +/ +show error + +-- now the new package bodies + +create or replace package body acs_sc_impl +as + + function new ( + impl_contract_name acs_sc_impls.impl_contract_name%TYPE, + impl_name acs_sc_impls.impl_name%TYPE, + impl_owner_name acs_sc_impls.impl_owner_name%TYPE + ) return acs_sc_impls.impl_id%TYPE + is + v_impl_id acs_sc_impls.impl_id%TYPE; + begin + v_impl_id := acs_object.new (object_type => 'acs_sc_implementation'); + + insert into acs_sc_impls ( + impl_id, + impl_name, + impl_owner_name, + impl_contract_name + ) values ( + v_impl_id, + impl_name, + impl_owner_name, + impl_contract_name + ); + + return v_impl_id; + end new; + + function get_id ( + impl_contract_name acs_sc_impls.impl_contract_name%TYPE, + impl_name acs_sc_impls.impl_name%TYPE + ) return acs_sc_impls.impl_id%TYPE + as + v_impl_id acs_sc_impls.impl_id%TYPE; + begin + + select impl_id into v_impl_id + from acs_sc_impls + where impl_name = get_id.impl_name + and impl_contract_name = get_id.impl_contract_name; + + return v_impl_id; + + end get_id; + + + function get_name ( + impl_id acs_sc_impls.impl_id%TYPE + ) return acs_sc_impls.impl_name%TYPE + as + v_impl_name acs_sc_impls.impl_name%TYPE; + begin + + select impl_name into v_impl_name + from acs_sc_impls + where impl_id = get_name.impl_id; + + return v_impl_name; + + end get_name; + + procedure delete ( + impl_contract_name acs_sc_impls.impl_contract_name%TYPE, + impl_name acs_sc_impls.impl_name%TYPE + ) + as + begin + delete from acs_sc_impls + where impl_contract_name = acs_sc_impl.delete.impl_contract_name + and impl_name = acs_sc_impl.delete.impl_name; + end delete; + + + /* next 2 functions are deprecated. */ + + function new_alias ( + impl_contract_name acs_sc_contracts.contract_name%TYPE, + impl_name acs_sc_impls.impl_name%TYPE, + impl_operation_name acs_sc_operations.operation_name%TYPE, + impl_alias acs_sc_impl_aliases.impl_alias%TYPE, + impl_pl acs_sc_impl_aliases.impl_pl%TYPE + ) return acs_sc_impl_aliases.impl_id%TYPE + is + v_impl_id acs_sc_impls.impl_id%TYPE; + begin + -- FUNCTION DEPRECATED. USE acs_sc_impl_alias.new + dbms_output.put_line('acs_sc_impl.new_alias DEPRECATED. Use acs_sc_impl_alias.new'); + + v_impl_id := acs_sc_impl_alias.new( + impl_contract_name, + impl_name, + impl_operation_name, + impl_alias, + impl_pl + ); + + return v_impl_id; + + end new_alias; + + function delete_alias ( + impl_contract_name acs_sc_contracts.contract_name%TYPE, + impl_name acs_sc_impls.impl_name%TYPE, + impl_operation_name acs_sc_operations.operation_name%TYPE + ) return acs_sc_impls.impl_id%TYPE + is + v_impl_id acs_sc_impls.impl_id%TYPE; + begin + -- FUNCTION DEPRECATED. USE acs_sc_impl_alias.delete + dbms_output.put_line('acs_sc_impl.delete_alias DEPRECATED. Use acs_sc_impl_alias.delete'); + + v_impl_id := acs_sc_impl_alias.delete( + impl_contract_name, + impl_name, + impl_operation_name + ); + + return v_impl_id; + + end delete_alias; + +end acs_sc_impl; +/ +show errors + + + +create or replace package body acs_sc_impl_alias +as + + function new ( + impl_contract_name acs_sc_contracts.contract_name%TYPE, + impl_name acs_sc_impls.impl_name%TYPE, + impl_operation_name acs_sc_operations.operation_name%TYPE, + impl_alias acs_sc_impl_aliases.impl_alias%TYPE, + impl_pl acs_sc_impl_aliases.impl_pl%TYPE + ) return acs_sc_impl_aliases.impl_id%TYPE + is + v_impl_id acs_sc_impls.impl_id%TYPE; + begin + + v_impl_id := acs_sc_impl.get_id(impl_contract_name,impl_name); + + insert into acs_sc_impl_aliases ( + impl_id, + impl_name, + impl_contract_name, + impl_operation_name, + impl_alias, + impl_pl + ) values ( + v_impl_id, + impl_name, + impl_contract_name, + impl_operation_name, + impl_alias, + impl_pl + ); + + return v_impl_id; + + end new; + + function delete ( + impl_contract_name acs_sc_contracts.contract_name%TYPE, + impl_name acs_sc_impls.impl_name%TYPE, + impl_operation_name acs_sc_operations.operation_name%TYPE + ) return acs_sc_impls.impl_id%TYPE + is + v_impl_id acs_sc_impls.impl_id%TYPE; + begin + v_impl_id := acs_sc_impl.get_id(impl_contract_name,impl_name); + + delete from acs_sc_impl_aliases + where impl_contract_name = acs_sc_impl_alias.delete.impl_contract_name + and impl_name = acs_sc_impl_alias.delete.impl_name + and impl_operation_name = acs_sc_impl_alias.delete.impl_operation_name; + + return v_impl_id; + + end delete; + +end acs_sc_impl_alias; +/ +show errors + +-- UPGRADE ISSUE 2 +-- acs_sc_binding.exists_p was broken on Oracle if you installed +-- tested a binding for which the implementation was installed, but the +-- contract wasn't. + +create or replace package body acs_sc_binding +as + -- you can pick a pair of args, either ids or names to pass in. + procedure new ( + contract_id acs_sc_operations.contract_id%TYPE default null, + impl_id acs_sc_bindings.impl_id%TYPE default null, + contract_name acs_sc_contracts.contract_name%TYPE default null, + impl_name acs_sc_impls.impl_name%TYPE default null + ) + is + v_contract_name acs_sc_contracts.contract_name%TYPE; + v_contract_id acs_sc_contracts.contract_id%TYPE; + v_impl_name acs_sc_impls.impl_name%TYPE; + v_impl_id acs_sc_impls.impl_id%TYPE; + v_count integer; + begin + + if impl_id is not null and contract_id is not null + then + + v_contract_name := acs_sc_contract.get_name(contract_id); + v_impl_name := acs_sc_impl.get_name(impl_id); + v_contract_id := contract_id; + v_impl_id := impl_id; + + elsif contract_name is not null and impl_name is not null + then + v_contract_id := acs_sc_contract.get_id(contract_name); + v_impl_id := acs_sc_impl.get_id(contract_name,impl_name); + v_impl_name := impl_name; + v_contract_name := contract_name; + + else + raise_application_error(-20001, 'Service Contracts:Invalid args to binding new'); + end if; + + + select count(*) into v_count + from acs_sc_operations + where contract_id = new.contract_id + and operation_name not in (select impl_operation_name + from acs_sc_impl_aliases + where impl_contract_name = v_contract_name + and impl_id = v_impl_id); + + if v_count > 0 + then + raise_application_error(-20001, 'Binding of ' || + v_contract_name || + ' to ' || + v_impl_name || + ' failed.'); + end if; + + insert into acs_sc_bindings ( + contract_id, + impl_id + ) values ( + v_contract_id, + v_impl_id + ); + + end new; + + procedure delete( + contract_id acs_sc_contracts.contract_id%TYPE default null, + contract_name acs_sc_contracts.contract_name%TYPE default null, + impl_id acs_sc_impls.impl_id%TYPE default null, + impl_name acs_sc_impls.impl_name%TYPE default null + ) + is + v_contract_id acs_sc_contracts.contract_id%TYPE; + v_impl_id acs_sc_impls.impl_id%TYPE; + begin + + if impl_id is not null and contract_id is not null + then + v_impl_id := impl_id; + v_contract_id := contract_id; + + elsif impl_name is not null and contract_name is not null + then + v_impl_id := acs_sc_impl.get_id(contract_name,impl_name); + v_contract_id := acs_sc_contract.get_id(contract_name); + else + raise_application_error(-20001, 'Service contract binding delete invalid args'); + end if; + + delete from acs_sc_bindings + where contract_id = v_contract_id + and impl_id = v_impl_id; + end delete; + + function exists_p ( + contract_name acs_sc_contracts.contract_name%TYPE, + impl_name acs_sc_impls.impl_name%TYPE + ) return integer + is + v_exists_p integer; + begin + select decode(count(*),0, 0, 1) into v_exists_p + from acs_sc_bindings + where contract_id = acs_sc_contract.get_id(contract_name) + and impl_id = acs_sc_impl.get_id(contract_name,impl_name); + + return v_exists_p; + end exists_p; + +end acs_sc_binding; +/ +show errors Index: openacs.org-dev/packages/adserver/www/default.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/adserver/www/default.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/adserver/www/default.tcl 8 Oct 2002 15:46:55 -0000 1.1 @@ -0,0 +1,12 @@ +if { ![info exists title] } { + set title "" +} +if { ![info exists context] } { + set context [list $title] +} +if { [info exists admin_p] && $admin_p } { + set page_content "$admin_link $page_content" +} + + + Index: openacs.org-dev/packages/adserver/www/admin/default.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/adserver/www/admin/default.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/adserver/www/admin/default.tcl 8 Oct 2002 15:46:55 -0000 1.1 @@ -0,0 +1,12 @@ +if { ![info exists title] } { + set title "" +} +if { ![info exists context] } { + set context [list [list $title]] +} +if { [info exists admin_p] && $admin_p } { + set page_content "$admin_link $page_content" +} + + + Index: openacs.org-dev/packages/attachments/sql/oracle/upgrade/upgrade-0.1d-0.2.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/attachments/sql/oracle/upgrade/upgrade-0.1d-0.2.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/attachments/sql/oracle/upgrade/upgrade-0.1d-0.2.sql 8 Oct 2002 15:46:55 -0000 1.1 @@ -0,0 +1,16 @@ +-- +-- upgrade attachments to include approved_p column +-- +-- @author <a href="mailto:yon@openforce.net">yon@openforce.net</a> +-- @creation-date 2002-08-29 +-- @version $Id: upgrade-0.1d-0.2.sql,v 1.1 2002/10/08 15:46:55 rmello Exp $ +-- + +alter table attachments add ( + approved_p char(1) + default 't' + constraint attachments_approved_p_ck + check (approved_p in ('t', 'f')) + constraint attachments_approved_p_nn + not null +); Index: openacs.org-dev/packages/attachments/sql/postgresql/upgrade/upgrade-0.1d-0.2.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/attachments/sql/postgresql/upgrade/upgrade-0.1d-0.2.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/attachments/sql/postgresql/upgrade/upgrade-0.1d-0.2.sql 8 Oct 2002 15:46:55 -0000 1.1 @@ -0,0 +1,40 @@ +-- +-- upgrade attachments to include approved_p column +-- +-- @author <a href="mailto:yon@openforce.net">yon@openforce.net</a> +-- @creation-date 2002-08-29 +-- @version $Id: upgrade-0.1d-0.2.sql,v 1.1 2002/10/08 15:46:55 rmello Exp $ +-- + +alter table attachments rename to attachments_old; + +drop index attachments_pk; + +create table attachments ( + object_id integer + constraint attachments_object_id_fk + references acs_objects(object_id) + on delete cascade, + item_id integer + constraint attachments_item_id_fk + references acs_objects(object_id) + on delete cascade, + approved_p char(1) + default 't' + constraint attachments_approved_p_ck + check (approved_p in ('t', 'f')) + constraint attachments_approved_p_nn + not null, + constraint attachments_pk + primary key (object_id, item_id) +); + +insert +into attachments +(object_id, item_id, approved_p) +select object_id, + item_id, + 't' +from attachments_old; + +drop table attachments_old; Index: openacs.org-dev/packages/attachments/www/attach.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/attachments/www/attach.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/attachments/www/attach.xql 8 Oct 2002 15:46:55 -0000 1.1 @@ -0,0 +1,22 @@ +<?xml version="1.0"?> + +<queryset> + <fullquery name="select_folder_contents"> + <querytext> + select fs_objects.object_id, + fs_objects.name, + fs_objects.live_revision, + fs_objects.type, + to_char(fs_objects.last_modified, 'Month DD YYYY HH24:MI') as last_modified, + fs_objects.content_size, + fs_objects.url, + fs_objects.key, + fs_objects.sort_key, + fs_objects.file_upload_name, + '0' as new_p + from fs_objects + where fs_objects.parent_id = :folder_id + order by sort_key, name + </querytext> + </fullquery> +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/attachments/www/toggle-approved.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/attachments/www/toggle-approved.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/attachments/www/toggle-approved.tcl 8 Oct 2002 15:46:55 -0000 1.1 @@ -0,0 +1,16 @@ +ad_page_contract { + + @author yon@openforce.net + @creation-date 2002-08-29 + @cvs-id $Id: toggle-approved.tcl,v 1.1 2002/10/08 15:46:55 rmello Exp $ + +} -query { + {object_id:integer,notnull} + {item_id:integer,notnull} + {approved_p ""} + {return_url:notnull} +} + +attachments::toggle_approved -object_id $object_id -item_id $item_id -approved_p $approved_p + +ad_returnredirect $return_url Index: openacs.org-dev/packages/bug-tracker/lib/pagination.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/lib/pagination.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/lib/pagination.adp 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,10 @@ +<form action="map-patch-to-bugs" method="POST"> +@pagination_form_export_vars@ +<table> +<tr> +<td> +Page with @pretty_plural@: [ @pagination_filter@ ] Show <input type="text" name="interval_size" value="@interval_size@" /> @pretty_plural@ per page <input type="submit" value="Go" /> +</td> +</tr> +</table> +</form> Index: openacs.org-dev/packages/bug-tracker/lib/pagination.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/lib/pagination.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/lib/pagination.tcl 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,36 @@ +# @arg row_count The total number of rows. +# @arg offset The current row offset, i.e. the number of rows to skip. Must be an URL parameter. +# @arg interval_size The number of rows per page. Must be an optional URL parameter +# @arg variable_set_to_export An ns_set that should exclude the offset and interval_size variables. You may +# use ad_tcl_vars_to_ns_set to create this set. +# @arg pretty_plural The plural form of whatever items we are paginating (i.e. in the Bug Tracker patches, or bugs) + +set pagination_filter_list [list] +set interval_high $interval_size +set interval_low "1" + +# Set all the variables to export to this template +set export_var_list [list] +for { set i 0 } { $i < [ns_set size $variable_set_to_export] } { incr i } { + set var_name [ns_set key $variable_set_to_export $i] + set $var_name [ns_set value $variable_set_to_export $i] + lappend export_var_list $var_name +} + +set pagination_filter_base_url "[ad_conn url]?[export_vars -url -override { { offset 0 } } $export_var_list]" +set pagination_form_export_vars "[export_vars -form -override { { offset 0 } } $export_var_list]" + +while { $interval_low <= $row_count } { + + if { $interval_high > $row_count } { + set interval_high $row_count + } + + set interval_label [ad_decode $interval_low $row_count "$interval_high" "$interval_low - $interval_high"] + lappend pagination_filter_list [ad_decode [expr 1 + $offset] $interval_low "$interval_label" "<a href=\"$pagination_filter_base_url&offset=[expr $interval_low - 1]\">$interval_label</a>"] + + set interval_high [expr $interval_high + $interval_size] + set interval_low [expr $interval_high - [expr $interval_size - 1]] +} + +set pagination_filter [join $pagination_filter_list " | "] Index: openacs.org-dev/packages/bug-tracker/sql/postgresql/bug-tracker-notifications-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/sql/postgresql/bug-tracker-notifications-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/sql/postgresql/bug-tracker-notifications-drop.sql 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,76 @@ +-- +-- This script drops all notifications setup +-- by the Bug Tracker application +-- +-- FIXME TODO: This code was copied and pasted from the forums package +-- and I don't fully understand it. +-- Much of this code should probably be moved into the +-- Notifications package, i.e. there should be a method +-- to fully drop a notification type with all associated +-- service contract data. +-- +-- @author Peter Marklund (peter@collaboraid.biz) + +-- Delete the notification data +create function inline_0 () + returns integer as ' + declare + row record; + begin + for row in select nt.type_id + from notification_types nt + where nt.short_name in (''bug_tracker_project_notif'', ''bug_tracker_bug_notif'') + loop + perform notification_type__delete(row.type_id); + delete from notifications where type_id = row.type_id; + delete from notification_types where type_id = row.type_id; + delete from notification_types_intervals where type_id = row.type_id; + delete from notification_types_del_methods where type_id = row.type_id; + end loop; + + return null; + end;' language 'plpgsql'; + + select inline_0(); + drop function inline_0 (); + +-- Delete the service contract data +create function bt_service_contract_delete(varchar,varchar) +returns integer as ' +declare + p_impl_name alias for $1; + p_impl_short_name alias for $2; + impl_id integer; + v_foo integer; +begin + + -- the notification type impl + impl_id := acs_sc_impl__get_id ( + ''NotificationType'', -- impl_contract_name + p_impl_name -- impl_name + ); + + PERFORM acs_sc_binding__delete ( + ''NotificationType'', + p_impl_name + ); + + v_foo := acs_sc_impl_alias__delete ( + ''NotificationType'', -- impl_contract_name + p_impl_name, -- impl_name + ''GetURL'' -- impl_operation_name + ); + + v_foo := acs_sc_impl_alias__delete ( + ''NotificationType'', -- impl_contract_name + p_impl_name, -- impl_name + ''ProcessReply'' -- impl_operation_name + ); + + return 0; +end; +' language 'plpgsql'; + +select bt_service_contract_delete('bug_tracker_project_notif_type','but_tracker_project_notif'); +select bt_service_contract_delete('bug_tracker_bug_notif_type','but_tracker_bug_notif'); +drop function bt_service_contract_delete(varchar,varchar); Index: openacs.org-dev/packages/bug-tracker/sql/postgresql/bug-tracker-notifications-init.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/sql/postgresql/bug-tracker-notifications-init.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/sql/postgresql/bug-tracker-notifications-init.sql 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,144 @@ +-- +-- This script registers the notifications of the +-- Bug Tracker with the Notifications service. It also +-- implements the NotificationType service contract. +-- +-- @author Peter Marklund (peter@collaboraid.biz) + +create function inline_0() returns integer as ' +declare + impl_id integer; + v_foo integer; +begin + -- Project level notifications START + + -- Create a project level implementation of the NotificationType + -- service contract + impl_id := acs_sc_impl__new ( + ''NotificationType'', + ''bug_tracker_project_notif_type'', + ''bug_tracker'' + ); + + -- Note: all operations of a service contract *must* be + -- implemented before we can bind the implementation + -- to the service contract + + -- Implement the GetURL operation + v_foo := acs_sc_impl_alias__new ( + ''NotificationType'', + ''bug_tracker_project_notif_type'', + ''GetURL'', + ''bug_tracker::notification::get_url'', + ''TCL'' + ); + + -- Implement the ProcessReply operation + v_foo := acs_sc_impl_alias__new ( + ''NotificationType'', + ''bug_tracker_project_notif_type'', + ''ProcessReply'', + ''bug_tracker::notification::process_reply'', + ''TCL'' + ); + + -- Bind the project level implementation to + -- the NotificationType service contract + PERFORM acs_sc_binding__new ( + ''NotificationType'', + ''bug_tracker_project_notif_type'' + ); + + -- Create the project notification type + v_foo:= notification_type__new ( + NULL, + impl_id, + ''bug_tracker_project_notif'', + ''Bug Tracker Project Notification'', + ''Notifications for entire project (package) in the Bug Tracker'', + now(), + NULL, + NULL, + NULL + ); + + -- Project notification intervals + insert into notification_types_intervals + (type_id, interval_id) + select v_foo, interval_id + from notification_intervals where name in (''instant'',''hourly'',''daily''); + + -- Project delivery type + insert into notification_types_del_methods + (type_id, delivery_method_id) + select v_foo, delivery_method_id + from notification_delivery_methods where short_name in (''email''); + + -- Project level notifications END + + -- Bug level notifications START + + -- The bug service contract implementation + impl_id := acs_sc_impl__new ( + ''NotificationType'', + ''bug_tracker_bug_notif_type'', + ''bug_tracker'' + ); + + -- Bug level implementation of GetURL operation + v_foo := acs_sc_impl_alias__new ( + ''NotificationType'', + ''bug_tracker_bug_notif_type'', + ''GetURL'', + ''bug_tracker::notification::get_url'', + ''TCL'' + ); + + -- Bug level implementation of ProcessReply operation + v_foo := acs_sc_impl_alias__new ( + ''NotificationType'', + ''bug_tracker_bug_notif_type'', + ''ProcessReply'', + ''bug_tracker::notification::process_reply'', + ''TCL'' + ); + + -- Bind the bug level implementation to the NotificationType contract + PERFORM acs_sc_binding__new ( + ''NotificationType'', + ''bug_tracker_bug_notif_type'' + ); + + -- Create the bug notification type + v_foo:= notification_type__new ( + NULL, + impl_id, + ''bug_tracker_bug_notif'', + ''Bug Tracker Bug Notification'', + ''Notifications for a bug in the Bug Tracker'', + now(), + NULL, + NULL, + NULL + ); + + -- Enable all notification intervals for bug notifications + insert into notification_types_intervals + (type_id, interval_id) + select v_foo, interval_id + from notification_intervals where name in (''instant'',''hourly'',''daily''); + + -- Bug notification are per email + insert into notification_types_del_methods + (type_id, delivery_method_id) + select v_foo, delivery_method_id + from notification_delivery_methods where short_name in (''email''); + + -- Bug level notifications END + + return (0); +end; +' language 'plpgsql'; + +select inline_0(); +drop function inline_0(); Index: openacs.org-dev/packages/bug-tracker/sql/postgresql/upgrade-0.7d2-0.7d3.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/sql/postgresql/upgrade-0.7d2-0.7d3.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/sql/postgresql/upgrade-0.7d2-0.7d3.sql 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,8 @@ + +-- Added resolution code to bt_bug_actions + +alter table bt_bug_actions add column + resolution varchar(50) + constraint bt_bugs_resolution_ck + check (resolution is null or + resolution in ('fixed','bydesign','wontfix','postponed','duplicate','norepro')); Index: openacs.org-dev/packages/bug-tracker/sql/postgresql/upgrade-0.7d3-0.7d4.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/sql/postgresql/upgrade-0.7d3-0.7d4.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/sql/postgresql/upgrade-0.7d3-0.7d4.sql 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,128 @@ +-- +-- bt_bugs: add 'needinfo' to resolution check constraint +-- + +drop index bt_bugs_pk; +drop index bt_bugs_bug_number_un; +alter table bt_bugs rename to bt_bugs_old; + +create table bt_bugs ( + bug_id integer + constraint bt_bugs_pk + primary key + constraint bt_bugs_bug_id_fk + references acs_objects(object_id), + project_id integer + constraint bt_bugs_projects_fk + references bt_projects(project_id), + + component_id integer + constraint bt_bugs_components_fk + references bt_components(component_id), + bug_number integer not null, + status varchar(50) not null + constraint bt_bugs_status_ck + check (status in ('open', 'resolved', 'closed')) + default 'open', + resolution varchar(50) + constraint bt_bugs_resolution_ck + check (resolution is null or + resolution in ('fixed','bydesign','wontfix','postponed','duplicate','norepro','needinfo')), + bug_type varchar(50) not null + constraint bt_bugs_bug_type_ck + check (bug_type in ('bug', 'suggestion','todo')), + severity integer not null + constraint bt_bugs_severity_fk + references bt_severity_codes(severity_id), + priority integer not null + constraint bt_bugs_priority_fk + references bt_priority_codes(priority_id), + user_agent varchar(500), + original_estimate_minutes integer, + latest_estimate_minutes integer, + elapsed_time_minutes integer, + found_in_version integer + constraint bt_bugs_found_in_version_fk + references bt_versions(version_id), + fix_for_version integer + constraint bt_bugs_fix_for_version_fk + references bt_versions(version_id), + fixed_in_version integer + constraint bt_bugs_fixed_in_version_fk + references bt_versions(version_id), + summary varchar(500) not null, + assignee integer + constraint bt_bug_assignee_fk + references users(user_id), + constraint bt_bugs_bug_number_un + unique (project_id, bug_number) +); + +-- We do this in an inline function, so that we won't delete the _old table if the insert fails. + +create function inline_0 () +returns integer as ' +begin + insert into bt_bugs select * from bt_bugs_old; + + drop table bt_bugs_old; + + return 0; +end;' language 'plpgsql'; + +select inline_0 (); + +drop function inline_0 (); + + +-- +-- bt_bug_actions: add 'needinfo' to resolution check constraint +-- + +drop index bt_bug_actions_pk; + +alter table bt_bug_actions rename to bt_bug_actions_old; + +create table bt_bug_actions ( + action_id integer not null + constraint bt_bug_actions_pk + primary key, + bug_id integer not null + constraint bt_bug_actions_bug_fk + references bt_bugs(bug_id) + on delete cascade, + action varchar(50) + constraint bt_bug_actions_action_ck + check (action in ('open','edit','comment','reassign','resolve','reopen','close')), + resolution varchar(50) + constraint bt_bugs_actions_resolution_ck + check (resolution is null or + resolution in ('fixed','bydesign','wontfix','postponed','duplicate','norepro','needinfo')), + actor integer not null + constraint bt_bug_actions_actor_fk + references users(user_id), + action_date timestamp not null + default now(), + comment text, + comment_format varchar(30) default 'plain' not null + constraint bt_bug_actions_comment_format_ck + check (comment_format in ('html', 'plain', 'pre')) +); + +create function inline_0 () +returns integer as ' +begin + insert into bt_bug_actions (action_id, bug_id, action, resolution, actor, action_date, comment, comment_format) + select action_id, bug_id, action, resolution, actor, action_date, comment, comment_format from bt_bug_actions_old; + + drop table bt_bug_actions_old; + + return 0; +end;' language 'plpgsql'; + +select inline_0 (); + +drop function inline_0 (); + + + Index: openacs.org-dev/packages/bug-tracker/sql/postgresql/upgrade-0.7d4-0.7d5.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/sql/postgresql/upgrade-0.7d4-0.7d5.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/sql/postgresql/upgrade-0.7d4-0.7d5.sql 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,3 @@ +alter table bt_projects add column email_subject_name text; +alter table bt_components add column url_name text; + Index: openacs.org-dev/packages/bug-tracker/sql/postgresql/upgrade-0.7d5-0.8.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/sql/postgresql/upgrade-0.7d5-0.8.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/sql/postgresql/upgrade-0.7d5-0.8.sql 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,205 @@ +-- For stability, URLs contain patch numbers rather than ACS Object ids. +-- This avoids dependence on the ACS kernel and makes upgrades easier. +create sequence t_bt_patch_number_seq; +create view bt_patch_number_seq as +select nextval('t_bt_patch_number_seq') as nextval; + +create table bt_patches ( + patch_id integer + constraint bt_patches_pk + primary key + constraint bt_patches_pid_fk + references acs_objects(object_id), + patch_number integer not null, + project_id integer + constraint bt_patches_projects_fk + references bt_projects(project_id), + component_id integer + constraint bt_patches_components_fk + references bt_components(component_id), + summary text, + content text, + generated_from_version integer + constraint bt_patches_vid_fk + references bt_versions(version_id), + apply_to_version integer + constraint bt_patchs_apply_to_version_fk + references bt_versions(version_id), + applied_to_version integer + constraint bt_patchs_applied_to_version_fk + references bt_versions(version_id), + status varchar(50) not null + constraint bt_patchs_status_ck + check (status in ('open', 'accepted', 'refused', 'deleted')) + default 'open', + constraint bt_patches_un + unique(patch_number, project_id) +); + +create table bt_patch_actions ( + action_id integer not null + constraint bt_patch_actions_pk + primary key, + patch_id integer not null + constraint bt_patch_actions_patch_fk + references bt_patches(patch_id) + on delete cascade, + action varchar(50) + constraint bt_patch_actions_action_ck + check (action in ('open', 'edit', 'comment', 'accept', + 'reopen', 'refuse', 'delete')) + default 'open', + actor integer not null + constraint bt_patch_actions_actor_fk + references users(user_id), + action_date timestamp not null + default now(), + comment text, + comment_format varchar(30) default 'plain' not null + constraint bt_patch_actions_comment_format_ck + check (comment_format in ('html', 'plain', 'pre')) +); + +-- Create the bt_patch object type +create function inline_0 () +returns integer as ' +begin + PERFORM acs_object_type__create_type ( + ''bt_patch'', + ''Patch'', + ''Patches'', + ''acs_object'', + ''bt_patches'', + ''patch_id'', + null, + ''f'', + null, + ''bt_patch__name'' + ); + + return 0; +end;' language 'plpgsql'; + +select inline_0 (); + +drop function inline_0 (); + +create function bt_patch__new( + integer, -- patch_id + integer, -- project_id + integer, -- component_id + text, -- summary + text, -- description + text, -- description_format + text, -- content + integer, -- generated_from_version + integer, -- creation_user + varchar -- creation_ip +) returns int +as ' +declare + p_patch_id alias for $1; + p_project_id alias for $2; + p_component_id alias for $3; + p_summary alias for $4; + p_description alias for $5; + p_description_format alias for $6; + p_content alias for $7; + p_generated_from_version alias for $8; + p_creation_user alias for $9; + p_creation_ip alias for $10; + + v_patch_id integer; + v_patch_number integer; + v_action_id integer; +begin + + v_patch_id := acs_object__new( + p_patch_id, -- object_id + ''bt_patch'', -- object_type + now(), -- creation_date + p_creation_user, -- creation_user + p_creation_ip, -- creation_ip + p_project_id, -- context_id + ''t'' -- security_inherit_p + ); + + select coalesce(max(patch_number),0) + 1 + into v_patch_number + from bt_patches + where project_id = p_project_id; + + insert into bt_patches + (patch_id, + project_id, + component_id, + summary, + content, + generated_from_version, + patch_number) + values + (v_patch_id, + p_project_id, + p_component_id, + p_summary, + p_content, + p_generated_from_version, + v_patch_number); + + select nextval(''t_acs_object_id_seq'') + into v_action_id; + + insert into bt_patch_actions + (action_id, patch_id, action, actor, comment, comment_format) + values + (v_action_id, v_patch_id, ''open'', p_creation_user, p_description, p_description_format); + + return 0; +end; +' language 'plpgsql'; + +create function bt_patch__name( + integer -- patch_id +) returns varchar +as ' +declare + p_patch_id alias for $1; + v_name varchar; +begin + select summary + into v_name + from bt_patches + where patch_id = p_patch_id; + + return v_name; +end; +' language 'plpgsql'; + +create function bt_patch__delete( + integer -- patch_id +) returns integer +as ' +declare + p_patch_id alias for $1; +begin + perform acs_object__delete(p_patch_id); + + return 0; +end; +' language 'plpgsql'; + +-- There is a many to many relationship between patches and bugs +create table bt_patch_bug_map ( + patch_id integer not null + constraint bt_patch_bug_map_pid_fk + references bt_patches(patch_id) + on delete cascade, + bug_id integer not null + constraint bt_patch_bug_map_bid_fk + references bt_bugs(bug_id) + on delete cascade, + constraint bt_patch_bug_map_un + unique (patch_id, bug_id) +); + +\i bug-tracker-notifications-init.sql Index: openacs.org-dev/packages/bug-tracker/tcl/bug-tracker-notification-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/tcl/bug-tracker-notification-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/tcl/bug-tracker-notification-procs.tcl 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,20 @@ +# +# Procedures of the Bug Tracker application related +# to notifications. +# +# @author Peter Marklund (peter@collaboraid.biz) + +namespace eval bug_tracker::notification { + + ad_proc -public get_url { + object_id + } { + # Todo: Implement this proc + } + + ad_proc -public process_reply { + reply_id + } { + # Todo: Implement this proc + } +} Index: openacs.org-dev/packages/bug-tracker/www/bug-submission-instructions.html =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/www/bug-submission-instructions.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/www/bug-submission-instructions.html 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,70 @@ +<html> + <head> + <link rel="STYLESHEET" type="text/css" href="../local.css"> + <title>Writing a good bug report</title> + </head> + + <body> + <h1>Writing a good bug report</h1> + +There are some simple guidelines to writing ticket which will make +prioritizing, tracking, and resolving problems more efficient. + <p> + <UL> + <LI> Each ticket should relate to a single problem or feature. + <LI> Provide a descriptive subject. + <LI> Be as specific as possible about what is wrong. + <LI> Put the URL to the offending page in the ticket. + <LI> Describe the steps you took to produce the problem. + <LI> Provide sensible priorities and deadlines. + </UL> + <h2>Justification</h2> + + <h3>Each ticket should relate to a single problem or feature</h3> + In order to easily prioritize and track tasks we need to have a + state associated with each issue. The problem with "laundry list" + tickets is that some tasks get done, some get defered, and some + cancelled. It is never clear when the ticket is done and + individual fixes can't be approved so even if it nominally is done + things are likely to fall through the cracks. + + <h3> Provide a descriptive subject </h3> + We look at summaries of tickets with subjects only and it is + much easier to find the relevant ticket with a descriptive subject. + + <h3> Be as specific as possible about what is wrong </h3> + + Problem descriptions that are too short or ambiguous are less + likely to get fixed than those that can be easily interpreted. + + <h3> Put the URL to the offending page in the ticket </h3> + + Having the URL in the problem description will streamline finding, +fixing, and + verifying the ticket. You do not have to enter it as an HTML + href, simply including the full url ( including the http:// and + the trailing variables ) is sufficient. + + <h3> Describe the steps you took to produce the problem </h3> + + If we cannot reproduce your problem it will be much harder to find. + The problem can be related to the page visited proir to the page on + which the error occurs or may be related to the specific data you + input to a form. + + <h3> Provide sensible priorities and deadlines </h3> + + We make an effort to meet deadlines and fix things in priority + order but if all tickets are critical with a short deadline + we will not necessarily fix them in the order you would really + like. + + <hr> + <address><a href="mailto:davis@arsdigita.com">Jeff +Davis</a></address> +<!-- Created: Wed Feb 21 08:26:26 EST 2001 --> +<!-- hhmts start --> +Last modified: Fri Mar 2 10:24:36 EST 2001 +<!-- hhmts end --> + </body> +</html> Index: openacs.org-dev/packages/bug-tracker/www/map-patch-to-bugs.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/www/map-patch-to-bugs.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/www/map-patch-to-bugs.adp 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,63 @@ +<master src="../lib/master"> +<property name="title">@page_title@</property> +<property name="context_bar">@context_bar@</property> + +<if @open_bugs:rowcount@ not eq 0> +Select one or more of the following bugs for patch "@patch_summary@" (you may select more bugs later): +</if> + +<p> +Components: @component_filter@ +</p> + +<p> +Bug status: [ @open_filter@ ] +</p> + +<p> +<include src="../lib/pagination" row_count="@bug_count@" offset="@offset@" interval_size="@interval_size@" variable_set_to_export="@pagination_export_var_set@" pretty_plural="bugs"> +</p> + +<blockquote> + +<form method="POST" action="map-patch-to-bugs"> + <input type="hidden" name="patch_number" value="@patch_number@" /> + <table> + <if @open_bugs:rowcount@ not eq 0> + <tr> + <th> </th> + <th>Bug Number</th> + <th>Summary</th> + <th>Creation Date</th> + </tr> + </if> + + <multiple name="open_bugs"> + <tr> + <td><input type="checkbox" value="@open_bugs.bug_number@" name="bug_number"></td> + <td align="center">@open_bugs.bug_number@</td> + <td><a href="bug?bug_number=@open_bugs.bug_number@">@open_bugs.summary@</a></td> + <td align="center">@open_bugs.creation_date_pretty@</td> + </tr> + </multiple> + </table> + + <if @open_bugs:rowcount@ eq 0> + <i>There are no open bugs to map the patch to. Try changing the component filter above.</i> + + <p> + <center> + <input type="submit" name="cancel" value="Ok" /> + </center> + </p> + </if> + <else> + <p> + <center> + <input type="submit" name="do_map" value="Map Bugs" /> + <input type="submit" name="cancel" value="Cancel" /> + </center> + </p> + </else> +</form> +</blockquote> Index: openacs.org-dev/packages/bug-tracker/www/map-patch-to-bugs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/www/map-patch-to-bugs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/www/map-patch-to-bugs.tcl 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,114 @@ +ad_page_contract { + Page for viewing and editing one patch. + + @author Peter Marklund (peter@collaboraid.biz) + @date 2002-09-04 + @cvs-id $Id: map-patch-to-bugs.tcl,v 1.1 2002/10/08 15:46:57 rmello Exp $ +} { + patch_number:integer,notnull + bug_number:integer,optional,multiple + component_id:integer,optional + {show_all_components_p "0"} + {show_only_open_p "1"} + {offset:integer "0"} + {interval_size "50"} + cancel:optional + {return_url ""} +} + +set package_id [ad_conn package_id] +set user_id [ad_conn user_id] +set redirect_url [ad_decode $return_url "" "patch?patch_number=$patch_number" $return_url] + +if { [exists_and_not_null cancel] } { + # The user chose to abort the mapping so redirect without further processing + ad_returnredirect $redirect_url + ad_script_abort +} + +set write_p [ad_permission_p $package_id write] +set user_is_submitter_p [expr $user_id == [bug_tracker::get_patch_submitter -patch_number $patch_number]] + +if { ![expr $user_is_submitter_p || $write_p] } { + ad_return_forbidden "Security Violation" "You do not have permission to map this patch to a bug. Only the submitter of the patch and users with write permission on this Bug Tracker project (package instance) may do so." + ad_script_abort +} + + +if { [exists_and_not_null bug_number] } { + # Do the mapping + foreach one_bug_number $bug_number { + set bug_id [db_string get_bug_id_for_number "select bug_id from bt_bugs where bug_number = :one_bug_number and project_id = :package_id"] + set patch_id [db_string get_patch_id_for_number "select patch_id from bt_patches where patch_number = :patch_number and project_id = :package_id"] + + bug_tracker::map_patch_to_bug -patch_id $patch_id -bug_id $bug_id + } + + ad_returnredirect $redirect_url + ad_script_abort +} + +set patch_summary [db_string get_patch_summary "select summary from bt_patches where patch_number = :patch_number and project_id = :package_id"] +set page_title "Mapping Patch #$patch_number \"$patch_summary\" to a Bug" +set context_bar [ad_context_bar "$page_title"] + +# Build the component filter +if { ![exists_and_not_null component_id] } { + set component_id [db_string component_id_for_patch "select component_id from bt_patches where patch_number = :patch_number and project_id = :package_id"] +} +set component_where_clause "" +set component_filter "" +if { ![empty_string_p $component_id] } { + set component_name [db_string component_name "select component_name from bt_components where component_id = :component_id"] + set component_filter_url "map-patch-to-bugs?[export_vars -url {patch_number component_id return_url offset show_only_open_p interval_size}]" + if { $show_all_components_p } { + set component_filter "\[ <a href=\"$component_filter_url&show_all_components_p=0\">Only Component \"$component_name\"</a> | All Components \]" + } else { + set component_where_clause "\n and bt_bugs.component_id = :component_id" + + set component_filter "\[ Only Component \"$component_name\" | <a href=\"$component_filter_url&show_all_components_p=1\">All Components</a> \]" + } +} + +# Build the bug status filter +set open_filter_url "map-patch-to-bugs?[export_vars -url {patch_number component_id return_url offset show_all_components_p interval_size}]" +set only_open_label "Only Open Bugs" +set any_status_label "Bugs of any Status" +if { $show_only_open_p } { + set open_where_clause "and bt_bugs.status = 'open'" + set open_filter "$only_open_label | <a href=\"$open_filter_url&show_only_open_p=0\">$any_status_label</a>" +} else { + set open_where_clause "" + set open_filter "<a href=\"$open_filter_url&show_only_open_p=1\">$only_open_label</a> | $any_status_label" +} + +set sql_where_clause "bt_bugs.project_id = :package_id + $open_where_clause + $component_where_clause + and bt_bugs.bug_id not in (select bug_id + from bt_patch_bug_map + where patch_id = (select patch_id + from bt_patches + where patch_number = :patch_number + and project_id = :package_id + ) + )" + +# Build the pagination filter +set bug_count [db_string bug_count_for_mapping \ + "select count(*) + from bt_bugs + where $sql_where_clause"] +set pagination_export_var_set [ad_tcl_vars_to_ns_set patch_number component_id return_url show_all_components_p show_only_open_p] + +db_multirow open_bugs select_open_bugs \ + "select bt_bugs.bug_number, + bt_bugs.summary, + to_char(acs_objects.creation_date, 'fmMM/DDfm/YYYY') as creation_date_pretty + from bt_bugs, acs_objects + where bt_bugs.bug_id = acs_objects.object_id + and $sql_where_clause + order by acs_objects.creation_date desc + limit $interval_size offset $offset" + +ad_return_template Index: openacs.org-dev/packages/bug-tracker/www/patch-add.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/www/patch-add.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/www/patch-add.adp 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,13 @@ +<master src="../lib/master"> +<property name="title">@page_title@</property> +<property name="context_bar">@context_bar@</property> + +<table align="right"> +<tr> +<td align="right"> +<a href="patch-submission-instructions.html" target="#" class="bt_link">How to submit a patch</a> +</td> +</tr> +</table> + +<formtemplate id="patch" style="standard-lars"></formtemplate> Index: openacs.org-dev/packages/bug-tracker/www/patch-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/www/patch-add.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/www/patch-add.tcl 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,182 @@ +ad_page_contract { + Page with a form for adding a patch. If the page + is requested without a bug number then the user + will optionally be taken to a page where bugs + that the patch covers can be chosen. + + @author Peter Marklund (peter@collaboraid.biz) + @date 2002-09-10 + @cvs-id $Id: patch-add.tcl,v 1.1 2002/10/08 15:46:57 rmello Exp $ +} { + bug_number:integer,optional + cancel:optional + component_id:optional + {return_url ""} +} + +# If the user hit cancel, ignore everything else +if { [exists_and_not_null cancel] } { + set bug_view_url "bug?[export_vars { bug_number }]" + ad_returnredirect $bug_view_url + ad_script_abort +} + +ad_require_permission [ad_conn package_id] create + +# User needs to be logged in here +ad_maybe_redirect_for_registration + +# Set some common bug-tracker variables +set project_name [bug_tracker::conn project_name] +set package_id [ad_conn package_id] +set package_key [ad_conn package_key] +set page_title "New Patch" +set context_bar [ad_context_bar $page_title] +set user_id [ad_conn user_id] + +# Create the form +form create patch -html { enctype multipart/form-data } + +element create patch patch_id \ + -datatype integer \ + -widget hidden + +element create patch component_id \ + -datatype integer \ + -widget select \ + -label "Component" \ + -options [bug_tracker::components_get_options] + +element create patch summary \ + -datatype text \ + -label "Summary" \ + -html { size 50 } + +element create patch description \ + -datatype text \ + -widget textarea \ + -label "Description" \ + -html { cols 50 rows 10 } \ + -optional + +element create patch description_format \ + -datatype text \ + -widget select \ + -label "Description format" \ + -options { { "Plain" plain } { "HTML" html } { "Preformatted" pre } } + +element create patch version_id \ + -datatype text \ + -widget select \ + -label "Generated from Version" \ + -options [bug_tracker::version_get_options -include_unknown] \ + -optional + +element create patch patch_file \ + -datatype file \ + -widget file \ + -label "Patch file" \ + +if { [exists_and_not_null bug_number] } { + # Export the bug number + element create patch bug_number \ + -datatype integer \ + -widget hidden + +} else { + # There is no bug number. + # Let the user indicate if he wants to select bugs that this + # patch covers if no bug number was supplied + element create patch select_bugs_p \ + -datatype text \ + -widget radio \ + -label "Choose Bugs for this Patch" \ + -options { {Yes 1} {No 0} } \ + -values { 1 } +} + + +if { [form is_request patch] } { + # Form requested + + if { [exists_and_not_null bug_number] } { + element set_properties patch bug_number -value $bug_number + } + + element set_properties patch patch_id -value [db_nextval "acs_object_id_seq"] + + element set_properties patch version_id \ + -value [bug_tracker::conn user_version_id] + + if { [info exists component_id] } { + element set_properties patch component_id -value $component_id + } +} + +if { [form is_valid patch] } { + # Form submitted + + db_transaction { + + form get_values patch patch_id component_id summary description description_format version_id patch_file + + # Get the file contents as a string + set content [bug_tracker::get_uploaded_patch_file_content] + + set ip_address [ns_conn peeraddr] + + db_exec_plsql new_patch { + select bt_patch__new( + :patch_id, + :package_id, + :component_id, + :summary, + :description, + :description_format, + :content, + :version_id, + :user_id, + :ip_address + ) + } + + # Redirect to the view page for the created patch by default + if { [empty_string_p $return_url] } { + set patch_number [db_string patch_number_for_id "select patch_number + from bt_patches + where patch_id = :patch_id"] + + set redirect_url "patch?[export_vars { patch_number }]" + } else { + set redirect_url $return_url + } + + # Fetch any provided bug id to map the patch to + catch {set bug_number [element get_value patch bug_number]} + if { [info exists bug_number] } { + # There is a bug id provided - map it to the patch + set bug_id [bug_tracker::get_bug_id -bug_number $bug_number -project_id $package_id] + bug_tracker::map_patch_to_bug -patch_id $patch_id -bug_id $bug_id + + # Trigger notifications for the bug that we are mapping to + bug_tracker::bug_notify \ + -bug_id $bug_id \ + -action "patched" \ + -patch_summary $summary + + } else { + # No bug id provided so redirect to page for selecting bugs if the + # user wishes to go there + set select_bugs_p [element get_value patch select_bugs_p] + + if { $select_bugs_p } { + set redirect_url "map-patch-to-bugs?[export_vars -url { return_url patch_number component_id }]" + } + } + } + + ad_returnredirect $redirect_url + ad_script_abort +} + +ad_return_template Index: openacs.org-dev/packages/bug-tracker/www/patch-list.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/www/patch-list.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/www/patch-list.adp 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,42 @@ +<master src="../lib/master"> +<property name="title">@page_title@</property> +<property name="context_bar">@context_bar@</property> + +<p> +Component: [ +<multiple name="components"> + <if @components.rownum@ gt 1> | </if> + <if @components.selected_p@ true><b>@components.label@</b></if> + <else><a href="@components.url@">@components.label@</a></else> +</multiple> +] +</p> + +<p> +Apply to version: [ @version_filter@ ] +</p> + +<blockquote> +<table> +<if @patch_list:rowcount@ not eq 0> +<tr> + <th>Patch Summary</th> + <th>Status</th> + <th>Creation Date</th> +</tr> +</if> + +<multiple name="patch_list"> +<tr> + <td align="left"><a href="patch?patch_number=@patch_list.patch_number@">@patch_list.summary@</a></td> + <td align="center">@patch_list.status@</td> + <td align="center">@patch_list.creation_date_pretty@</td> +</tr> +</multiple> +</table> + +<if @patch_list:rowcount@ eq 0> +<i>No patches match these criteria.</i> +</if> + +</blockquote> Index: openacs.org-dev/packages/bug-tracker/www/patch-list.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/www/patch-list.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/www/patch-list.tcl 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,96 @@ +ad_page_contract { + Page that lists patches in this Bug Tracker + project. + + @author Peter Marklund (peter@collaboraid.biz) + @date 2002-09-10 + @cvs-id $Id: patch-list.tcl,v 1.1 2002/10/08 15:46:57 rmello Exp $ +} { + {component_id:integer ""} + {version_id:integer ""} +} + +set package_id [ad_conn package_id] +set user_id [ad_conn user_id] + +set page_title "Patches" +set context_bar [ad_context_bar $page_title] + +# Create the component filter +set component_filter_list [list] + +multirow create components url label selected_p + +multirow append components "patch-list?[export_vars { version_id }]" "All Components" [empty_string_p $component_id] + +multirow extend components loop_component_id + +db_multirow -append -extend { url selected_p } components components { + select c.component_id as loop_component_id, + c.component_name as label + from bt_components c + where exists (select 1 from bt_patches p + where p.component_id = c.component_id) +} { + set selected_p [string equal $component_id $loop_component_id] + set url "patch-list?[export_vars { version_id { component_id $loop_component_id} }]" +} + +if { ![empty_string_p $component_id] } { + set component_where_clause "and bt_patches.component_id = :component_id" +} else { + set component_where_clause "" +} + + +# Create the apply to version filter +set version_filter_list [list] +if { [empty_string_p $version_id] } { + lappend version_filter_list "<b>All Versions</b>" +} else { + lappend version_filter_list "<a href=\"patch-list?[export_vars -url -override {{version_id {}}} {component_id}]\">All Versions</a>" +} +db_foreach versions_for_patches { + select version_id as loop_version_id, + version_name + from bt_versions + where exists (select 1 from bt_patches + where apply_to_version = bt_versions.version_id) +} { + + if { $version_id == $loop_version_id } { + lappend version_filter_list "<b>$version_name</b>" + } else { + lappend version_filter_list "<a href=\"patch-list?[export_vars -url -override {{version_id $loop_version_id}} {component_id}]\">$version_name</a>" + } +} +set version_filter [join $version_filter_list " | "] +if { ![empty_string_p $version_id] } { + set version_where_clause " and bt_patches.apply_to_version = :version_id" +} else { + set version_where_clause "" +} + + +# Create the pagination filter +set where_clause "bt_patches.project_id = :package_id + $component_where_clause + $version_where_clause" +set patch_count [db_string patch_count "select count(*) + from bt_patches + where $where_clause"] +set pagination_export_var_set [ad_tcl_vars_to_ns_set component_id version_id] + +db_multirow patch_list patch_list " + select bt_patches.patch_number, + bt_patches.summary, + bt_patches.status, + to_char(acs_objects.creation_date, 'fmMM/DDfm/YYYY') as creation_date_pretty + from bt_patches, + acs_objects + where bt_patches.patch_id = acs_objects.object_id + and $where_clause + order by acs_objects.creation_date desc +" + +ad_return_template Index: openacs.org-dev/packages/bug-tracker/www/patch-submission-instructions.html =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/www/patch-submission-instructions.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/www/patch-submission-instructions.html 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,115 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> + <head> + <title>Submitting a Patch</title> + </head> + + <body> + <h1>Submitting a Patch</h1> + + <p> + The very short answer is <code>diff -u</code> or + better, <code>cvs diff -u</code> and in either case you should + then inspect the resulting patch file to insure that it is what + you expect and manually remove any changes which should not be + part of the submitted patch. + </p> + + <h2>The best way: Make changes in a current cvs checkout</h2> + + <p> + If you have made changes in a cvs checkout just type + <blockquote> + <code>cvs diff -Nu package-dir > patch-file</code> + </blockquote> + in the package /web/openacs-4/package directory to generate + the patch (see below if you have also added files). + </p> + + <h2>The bad way</h2> + <p> + If you are working from code that is not a cvs checkout + (definitely less desirable, see below) then you should type + either: + <blockquote> + <code>diff -u package-dir/.../old-file package-dir/.../new-file > patch-file</code> + </blockquote> + or if you have modified more than one file you might want to do + <blockquote> + <code>diff -rNu old-package-dir new-package-dir > patch-file</code> + </blockquote> + which will do a recursive context diff of the old directory versus the + new directory (the <code>-r</code> flag) and generate patches which + will create new files if you have added files (the <code>-N</code> + flag). + </p> + + <h2>Gory Details</h2> + + <h3>General</h3> + <p> + We prefer patches be generated from the top-level directory of + the package so that it is clear from the patch where the file + belongs. + </p> + <p> + The <code>-N</code> flag will generate a chunk in the patch file + to create any new files you have added but please be careful + that the files that will created really should be part of the + patch. It is easy to have editor backup file and others show up + (although cvs diff generally does not have this problem). + </p> + <p> + Try to avoid reformatting large blocks of code unless absolutely + necessary. It is quite important that the changes be as small as + possible so the the patch maintainer can inspect the patch quickly + and apply it if needed. + </p> + + <h3>cvs diff</h3> + + <p> + If you have cvs commit and are going to commit your changes but + want to produce a diff for documentation purposes you should + <code>cvs add</code> any new files you have made first so that + cvs diff will produce a diff which will create the new files. + </p> + <p> + If you are working from an anonymous checkout you should do the + following to add diffs for new files to the patch file: + <blockqoute> + <code>diff -u /dev/null package-dir/.../new-file >> patch-file</code> + </blockquote> + </p> + + <h3>Non-cvs checkout</h3> + <p> + In an ideal world you would do a checkout from the head, make + your changes, test them, and submit a <code>cvs diff</code> as + above. If you are unwilling to do so, a diff based patch is + still useful to the project but is less likely to be applied + as quickly (if at all). Posting entire changed files is almost + useless since it is difficult and time consuming to find + what you have changed and such postings are entirely likely + to be rejected outright. + </p> + <p> + if you have new files to add to your patch, add them to the + patch file via: + <blockqoute> + <code>diff -u /dev/null new-file >> patch-file</code> + </blockquote> + </p> + + + + + + <hr> + <address><a href="mailto:davis@netcomuk.co.uk">Jeff Davis</a></address> + <!-- Created: Sun Sep 15 12:11:31 EDT 2002 --> + <!-- hhmts start --> +Last modified: Tue Sep 17 04:57:41 EDT 2002 +<!-- hhmts end --> + </body> +</html> Index: openacs.org-dev/packages/bug-tracker/www/patch.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/www/patch.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/www/patch.adp 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,45 @@ +<master src="../lib/master"> +<property name="title">@page_title@</property> +<property name="context_bar">@context_bar@</property> + +<formtemplate id="patch" style="standard-lars"></formtemplate> + +<p> +<if @button_form_export_vars@ not nil> + <blockquote> + <form method="GET" action="patch"> + @button_form_export_vars@ + <multiple name="button"> + <input type="submit" name="@button.name@" value=" @button.label@ "> + </multiple> + </form> + </blockquote> +</if> +</p> + +<if @mode@ eq "view"> + +<p> +<table border=0" cellspacing="0" cellpadding="2" bgcolor="lightgrey" width="100%"> + <tr> + <td> + <pre><%= [template::util::quote_html "$patch(content)"] %></pre> + </td> + </tr> +</table> +</p> + +<center> +<p> +<a href="patch?patch_number=@patch_number@&download=1">Download patch content</a> +</p> +</center> + +</if> + + + + + + + Index: openacs.org-dev/packages/bug-tracker/www/patch.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/www/patch.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/www/patch.tcl 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,529 @@ +ad_page_contract { + Page for viewing and editing one patch. + + @author Peter Marklund (peter@collaboraid.biz) + @date 2002-09-04 + @cvs-id $Id: patch.tcl,v 1.1 2002/10/08 15:46:57 rmello Exp $ +} { + patch_number:integer,notnull + mode:optional + cancel_edit:optional + edit:optional + accept:optional + refuse:optional + delete:optional + reopen:optional + comment:optional + download:optional +} + +# Assert read permission (should this check be in the request processor?) +ad_require_permission [ad_conn package_id] read + +# Initialize variables related to the request that we'll need +set package_id [ad_conn package_id] +set user_id [ad_conn user_id] +# Does the user have write privilege on the project? +set write_p [ad_permission_p $package_id write] +set user_is_submitter_p [expr $user_id == [bug_tracker::get_patch_submitter -patch_number $patch_number]] +set write_or_submitter_p [expr $write_p || $user_is_submitter_p] +set project_name [bug_tracker::conn project_name] +set package_key [ad_conn package_key] +set view_patch_url "[ad_conn url]?[export_vars -url { patch_number }]" +set patch_status [db_string patch_status "select status from bt_patches where patch_number = :patch_number and project_id = :package_id"] + +# Abort editing and return to view mode if the user hit cancel on the edit form +if { [exists_and_not_null cancel_edit] } { + ad_returnredirect $view_patch_url + ad_script_abort +} + +# If the download link was clicked - return the text content of the patch +if { [exists_and_not_null download] } { + + set patch_content [db_string get_patch_content "select content from bt_patches where patch_number = :patch_number and project_id = :package_id"] + + doc_return 200 "text/plain" $patch_content + ad_script_abort +} + +# Initialize the page mode variable +# We are in view mode per default +if { ![info exists mode] } { + if { [exists_and_not_null edit] } { + set mode "edit" + } elseif { [exists_and_not_null accept] } { + set mode "accept" + } elseif { [exists_and_not_null refuse] } { + set mode "refuse" + } elseif { [exists_and_not_null delete] } { + set mode "delete" + } elseif { [exists_and_not_null reopen] } { + set mode "reopen" + } elseif { [exists_and_not_null comment] } { + set mode "comment" + } else { + set mode "view" + } +} + +# Specify which fields in the form are editable +# And check that the user is permitted to take the chosen action +switch -- $mode { + edit { + if { ![expr $write_p || $user_is_submitter_p] } { + ad_return_forbidden "Serurity Violation" "You do not have permission to edit this patch. Only the submitter of the patch and users with write permission on the Bug Tracker project (package instance) may do so." + ad_script_abort + } + + set edit_fields {component_id summary generated_from_version apply_to_version} + } + accept { + ad_require_permission $package_id write + + # The user should indicate which version the patch is applied to + set edit_fields { applied_to_version } + } + refuse { + ad_require_permission $package_id write + + set edit_fields {} + } + reopen { + # User must have write permission to reopen a refused patch + if { [string equal $patch_status "refused"] && !$write_p } { + ad_return_forbidden "Serurity Violation" "You do not have permission to reopen this refused patch, only users with write permission on the Bug Tracker package instance (project) may do so." + ad_script_abort + } elseif { [string equal $patch_status "deleted"] && !($user_is_submitter_p || $write_p)} { + ad_return_forbidden "Serurity Violation" "You do not have permission to reopen this deleted patch, only users with write permission on the Bug Tracker package instance (project) and the submitter of the patch may do so." + ad_script_abort + } + + set edit_fields {} + } + delete { + # Only the submitter can delete a patch (admins can refuse it) + if { !$user_is_submitter_p } { + ad_return_forbidden "Serurity Violation" "You do not have permission to cancel this patch - only the submitter of the patch may do so. If you are an administrator you can however refuse the patch." + ad_script_abort + } + set edit_fields {} + } + comment { + set edit_fields {} + } + view { + set edit_fields {} + } +} + +foreach field $edit_fields { + set field_editable_p($field) 1 +} + +if { ![string equal $mode "view"] } { + ad_maybe_redirect_for_registration +} + +# Create the form +switch -- $mode { + view { + form create patch -has_submit 1 + } + default { + form create patch -html { enctype multipart/form-data } + } +} + +# Create the elements of the form +element create patch patch_number \ + -datatype integer \ + -widget hidden + +element create patch patch_number_i \ + -datatype integer \ + -widget inform \ + -label "Patch #" + +element create patch component_id \ + -datatype integer \ + -widget [ad_decode [info exists field_editable_p(component_id)] 1 select inform] \ + -label "Component" \ + -options [bug_tracker::components_get_options] + +if { [string equal $mode "view"] } { + element create patch fixes_bugs \ + -datatype text \ + -widget inform \ + -label "Fix for Bugs" +} + +element create patch summary \ + -datatype text \ + -widget [ad_decode [info exists field_editable_p(summary)] 1 text inform] \ + -label "Summary" \ + -html { size 50 } + +element create patch submitter \ + -datatype text \ + -widget inform \ + -label "Submitted by" + +element create patch status \ + -widget inform \ + -datatype text \ + -label "Status" + +element create patch generated_from_version \ + -datatype text \ + -widget [ad_decode [info exists field_editable_p(generated_from_version)] 1 select inform] \ + -label "Generated from Version" \ + -options [bug_tracker::version_get_options -include_unknown] \ + -optional + +element create patch apply_to_version \ + -datatype text \ + -widget [ad_decode [info exists field_editable_p(apply_to_version)] 1 select inform] \ + -label "Apply to Version" \ + -options [bug_tracker::version_get_options -include_undecided] \ + -optional + +element create patch applied_to_version \ + -datatype text \ + -widget [ad_decode [info exists field_editable_p(applied_to_version)] 1 select inform] \ + -label "Applied to Version" \ + -options [bug_tracker::version_get_options -include_undecided] \ + -optional + +switch -- $mode { + edit - comment - accept - refuse - reopen - delete { + element create patch description \ + -datatype text \ + -widget comment \ + -label "Description" \ + -html { cols 60 rows 13 } \ + -optional + + element create patch desc_format \ + -datatype text \ + -widget select \ + -label "Description format" \ + -options { { "Plain" plain } { "HTML" html } { "Preformatted" pre } } + + } + default { + # View mode + element create patch description \ + -datatype text \ + -widget inform \ + -label "Description" + } +} + +# In accept mode - give the user the ability to select associated +# bugs to be resolved +if { [string equal $mode "accept"] } { + + element create patch resolve_bugs \ + -datatype integer \ + -widget checkbox \ + -label "Resolve Bugs" \ + -options [bug_tracker::get_mapped_bugs -patch_number $patch_number -only_open_p 1] \ + -optional +} + +if { [string equal $mode "edit"] } { + # Edit mode - display the file upload widget for patch content + element create patch content \ + -datatype filename \ + -widget file \ + -label "Patch file (leave blank to keep current file):" \ + -optional +} + +element create patch mode \ + -datatype text \ + -widget hidden \ + -value $mode + +set page_title "Patch #$patch_number" +set context_bar [ad_context_bar $page_title] + +if { [form is_request patch] } { + # The form was requested + + db_1row patch { + select bt_patches.patch_id, + bt_patches.patch_number, + bt_patches.project_id, + bt_patches.component_id, + bt_patches.summary, + bt_patches.content, + bt_patches.generated_from_version, + bt_patches.apply_to_version, + bt_patches.applied_to_version, + bt_patches.status, + bt_components.component_name, + acs_objects.creation_user as submitter_user_id, + submitter.first_names as submitter_first_names, + submitter.last_name as submitter_last_name, + submitter.email as submitter_email, + acs_objects.creation_date, + to_char(acs_objects.creation_date, 'fmMM/DDfm/YYYY') as creation_date_pretty, + coalesce((select version_name + from bt_versions + where bt_versions.version_id = bt_patches.generated_from_version), 'Unknown') as generated_from_version_name, + coalesce((select version_name + from bt_versions + where bt_versions.version_id = bt_patches.apply_to_version), 'Unknown') as apply_to_version_name, + coalesce((select version_name + from bt_versions + where bt_versions.version_id = bt_patches.applied_to_version), 'Unknown') as applied_to_version_name, + to_char(now(), 'fmMM/DDfm/YYYY') as now_pretty + from bt_patches, + acs_objects, + cc_users submitter, + bt_components + + where bt_patches.patch_number = :patch_number + and bt_patches.project_id = :package_id + and bt_patches.patch_id = acs_objects.object_id + and bt_patches.component_id = bt_components.component_id + and submitter.user_id = acs_objects.creation_user + + } -column_array patch + + # When the user is taking an action that should change the status of the patch + # - update the status (the new status will show up in the form) + switch -- $mode { + accept { + set patch(status) "accepted" + } + refuse { + set patch(status) "refused" + } + delete { + set patch(status) "deleted" + } + reopen { + set patch(status) "open" + } + } + + element set_properties patch patch_number \ + -value $patch(patch_number) + element set_properties patch patch_number_i \ + -value $patch(patch_number) + element set_properties patch component_id \ + -value [ad_decode [info exists field_editable_p(component_id)] 1 $patch(component_id) $patch(component_name)] + if { [string equal $mode "view"] } { + set map_new_bug_link [ad_decode $write_or_submitter_p "1" "\[ <a href=\"map-patch-to-bugs?patch_number=$patch(patch_number)\">Map to bugs</a> \]" ""] + element set_properties patch fixes_bugs \ + -value "[bug_tracker::get_bug_links -patch_id $patch(patch_id) -patch_number $patch(patch_number) -write_or_submitter_p $write_or_submitter_p] $map_new_bug_link" + } + element set_properties patch summary \ + -value [ad_decode [info exists field_editable_p(summary)] 1 $patch(summary) "<b>$patch(summary)</b>"] + element set_properties patch submitter \ + -value " + [acs_community_member_link -user_id $patch(submitter_user_id) \ + -label "$patch(submitter_first_names) $patch(submitter_last_name)"] + (<a href=\"mailto:$patch(submitter_email)\">$patch(submitter_email)</a>)" + + element set_properties patch status \ + -value [ad_decode [info exists field_editable_p(status)] 1 $patch(status) [bug_tracker::patch_status_pretty $patch(status)]] + + element set_properties patch generated_from_version \ + -value [ad_decode [info exists field_editable_p(generated_from_version)] 1 $patch(generated_from_version) $patch(generated_from_version_name)] + element set_properties patch apply_to_version \ + -value [ad_decode [info exists field_editable_p(apply_to_version)] 1 $patch(apply_to_version) $patch(apply_to_version_name)] + element set_properties patch applied_to_version \ + -value [ad_decode [info exists field_editable_p(applied_to_version)] 1 $patch(applied_to_version) $patch(applied_to_version_name)] + + if { ( [string equal $patch(status) open] && ![string equal $mode "accept"]) || [string equal $patch(status) "refused"] } { + element set_properties patch applied_to_version -widget hidden + } + + # Description/Actions/History + set patch_id $patch(patch_id) + set action_html "" + db_foreach actions { + select bt_patch_actions.action_id, + bt_patch_actions.action, + bt_patch_actions.actor as actor_user_id, + actor.first_names as actor_first_names, + actor.last_name as actor_last_name, + actor.email as actor_email, + bt_patch_actions.action_date, + to_char(bt_patch_actions.action_date, 'fmMM/DDfm/YYYY') as action_date_pretty, + bt_patch_actions.comment, + bt_patch_actions.comment_format + from bt_patch_actions, + cc_users actor + where bt_patch_actions.patch_id = :patch_id + and actor.user_id = bt_patch_actions.actor + order by action_date + } { + append action_html "<b>$action_date_pretty [bug_tracker::patch_action_pretty $action] by $actor_first_names $actor_last_name</b> + <blockquote>[bug_tracker::bug_convert_comment_to_html -comment $comment -format $comment_format]</blockquote>" + } + + if { [string equal $mode "view"] } { + element set_properties patch description -value $action_html + } else { + element set_properties patch description \ + -history $action_html \ + -header "$patch(now_pretty) [bug_tracker::patch_action_pretty $mode] by [bug_tracker::conn user_first_names] [bug_tracker::conn user_last_name]" \ + -value "" + } + + # Now that we have the patch summary we can make the page title more informative + set page_title "Patch #$patch_number: $patch(summary)" + + # Create the buttons + # If the user has submitted the patch he gets full write access on the patch + set user_is_submitter_p [expr $patch(submitter_user_id) == [ad_conn user_id]] + if { [string equal $mode "view"] } { + set button_form_export_vars [export_vars -form { patch_number }] + multirow create button name label + + if { $write_p || $user_is_submitter_p } { + multirow append button "comment" "Comment" + multirow append button "edit" "Edit" + } + + switch -- $patch(status) { + open { + if { $write_p } { + multirow append button "accept" "Accept" + multirow append button "refuse" "Refuse" + } + + # Only the submitter can cancel the patch + if { $user_is_submitter_p } { + multirow append button "delete" "Delete" + } + } + accepted { + if { $write_p } { + multirow append button "reopen" "Reopen" + } + } + refused { + if { $write_p } { + multirow append button "reopen" "Reopen" + } + } + deleted { + if { $write_p || $user_is_submitter_p } { + multirow append button "reopen" "Reopen" + } + } + } + } + + # Check that the user is permitted to change the patch + if { ![string equal $mode "view"] && !$write_p && !$user_is_submitter_p } { + ns_log notice "$patch(submitter_user_id) doesn't have write on object $patch(patch_id)" + ad_return_forbidden "Security Violation" "<blockquote> + You don't have permission to edit this patch. + <br> + This incident has been logged. + </blockquote>" + ad_script_abort + } +} + +if { [form is_valid patch] } { + # A valid submit of the form + + set update_exprs [list] + + form get_values patch patch_number + + foreach column $edit_fields { + set $column [element get_value patch $column] + lappend update_exprs "$column = :$column" + } + + switch -- $mode { + accept { + set status "accepted" + lappend update_exprs "status = :status" + } + refuse { + set status "refused" + lappend update_exprs "status = :status" + } + reopen { + set status "open" + lappend update_exprs "status = :status" + } + edit { + # Get the contents of any new uploaded patch file + set content [bug_tracker::get_uploaded_patch_file_content] + + if { ![empty_string_p $content] } { + lappend update_exprs "content = :content" + } + } + delete { + set status "deleted" + lappend update_exprs "status = :status" + } + } + + db_transaction { + set patch_id [db_string patch_id "select patch_id from bt_patches where patch_number = :patch_number and project_id = :package_id"] + + if { [llength $update_exprs] > 0 } { + db_dml update_patch "update bt_patches \n set [join $update_exprs ",\n "] \n where patch_id = :patch_id" + } + + set action_id [db_nextval "acs_object_id_seq"] + + foreach column { description desc_format } { + set $column [element get_value patch $column] + } + + db_dml patch_action { + insert into bt_patch_actions + (action_id, patch_id, action, actor, comment, comment_format) + values + (:action_id, :patch_id, :mode, :user_id, :description, :desc_format) + } + + if { [string equal $mode "accept"] } { + # Resolve any bugs that the user selected + set resolve_bugs [element get_values patch resolve_bugs] + + foreach bug_number $resolve_bugs { + + db_transaction { + set bug_id [bug_tracker::get_bug_id -bug_number $bug_number -project_id $package_id] + + db_dml resolve_bug { + update bt_bugs + set status = 'resolved' + where bug_id = :bug_id + } + + set bug_action_id [db_nextval "acs_object_id_seq"] + + set resolve_description "Fixed by <a href=\"patch?patch_number=$patch_number\">patch #$patch_number</a>" + + db_dml bug_action_resolve { + insert into bt_bug_actions + (action_id, bug_id, action, resolution, actor, comment, comment_format) + values + (:bug_action_id, :bug_id, 'resolve', 'fixed', :user_id, :resolve_description, 'html') + } + } + } + } + } + + ad_returnredirect $view_patch_url + ad_script_abort +} + +ad_return_template Index: openacs.org-dev/packages/bug-tracker/www/unmap-patch-from-bug.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/www/unmap-patch-from-bug.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/www/unmap-patch-from-bug.tcl 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,25 @@ +ad_page_contract { + Unmapping a patch from a bug. + + @author Peter Marklund (peter@collaboraid.biz) + @date 2002-09-06 + @cvs-id $Id: unmap-patch-from-bug.tcl,v 1.1 2002/10/08 15:46:57 rmello Exp $ +} { + patch_number:integer,notnull + bug_number:integer,notnull +} + +set package_id [ad_conn package_id] +set user_id [ad_conn user_id] + +set write_p [ad_permission_p $package_id write] +set user_is_submitter_p [expr $user_id == [bug_tracker::get_patch_submitter -patch_number $patch_number]] + +if { ![expr $user_is_submitter_p || $write_p] } { + ad_return_forbidden "Security Violation" "You do not have permission to unmap a bug from this patch. Only the submitter of the patch and users with write permission on the Bug Tracker package instance (project) may do so." + ad_script_abort +} + +bug_tracker::unmap_patch_from_bug -patch_number $patch_number -bug_number $bug_number + +ad_returnredirect "patch?patch_number=$patch_number" Index: openacs.org-dev/packages/bug-tracker/www/com/index.vuh =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/www/com/index.vuh,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/www/com/index.vuh 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,24 @@ +if { ![regexp {com/([^/]+)/(.*)$} [ad_conn extra_url] match url_name rest] } { + # Try adding a slash + ad_returnredirect "[ad_conn url]/" + return +} + +set package_id [ad_conn package_id] + +set found_p [db_0or1row component { select component_id from bt_components where project_id = :package_id and url_name = :url_name }] + +if { $found_p } { + + if { [empty_string_p $rest] } { + set rest "index" + } + + bug_tracker::conn -set component_id $component_id + + set redirect_to [file join / packages bug-tracker www $rest] + + rp_internal_redirect $redirect_to +} else { + ns_returnnotfound +} Index: openacs.org-dev/packages/bug-tracker/www/doc/bug-tracker-outline.sql.txt =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/www/doc/bug-tracker-outline.sql.txt,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/www/doc/bug-tracker-outline.sql.txt 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,116 @@ +-- +-- A "project" is one instance of the bug-tracker. +-- + +-- In SDM: sdm_packages +-- In BT: +create table bt_projects ( + project_id integer references apm_packages(package_id) primary key, + project_name varchar, + description varchar +); + +-- In SDM: sdm_package_admins +-- In BT: assign admin privilege using permissions + + +-- In SDM: sdm_package_releases +-- In BT: +create table bt_versions ( + version_id integer primary key, + project_id integer references bt_projects(project_id), + version_number varchar, -- like apm_package_versions.version_name + anticipated_freeze_date date, + actual_freeze_date date, + anticipated_release_date date, + actual_release_date date, + --other stuff-- +); +-- Versions are global to the project. + +-- In SDM: sdm_modules +-- In BT: +create table bt_components ( + component_id integer primary key, + project_id integer references bt_projects(project_id), + name varchar, + description varchar, + owner integer references cc_users(user_id) +); + +-- In SDM: sdm_module_users +-- In BT: permissions or acs_rels, probably the latter + +-- In SDM: sdm_ticket_status, sdm_ticket_severity +-- In BT: +create table bt_code_types ( + code_type_id integer primary key, + code_type_name varchar, + description varchar, + system_required_p char (t/f) +); + +create table bt_code_values ( + value_id integer primary key, + code_type_id integer, + value_name varchar, + description varchar, + open_p char (t/f), + order_key integer +); + +-- In SDM: sdm_tickets +-- In BT: +create table bt_tickets ( + ticket_id integer primary key, + project_id integer references bt_projects, + component_id integer references bt_components, + ticket_type integer references bt_code_values, + ticket_status integer references bt_code_values, + + expected_completion + original_estimate + latest_estimate + time_used + fix_for_release + + summary + description + desc_format (html/plaintext/preformatted) + + ... + +); + +-- In SDM: sdm_patches +-- In SDM, this is a relationship between a general comment and a ticket +-- supposedly the patch itself is stored as a special comment +-- In BT: Probably something similar, not sure. + +-- In SDM: sdm_ticket_ratings +-- In BT: We'll leave that out for now, but supposedly we could use a modified +-- version of my ratings package from pinds.com + +-- All of the following should be doable with acs_rels of some sort +-- (I'm not too strong in that data model, but I suppose I'll learn over the next few days) + +-- sdm_ticket_assignments +-- sdm_bug_release_maps +-- sdm_user_ticket_interest_map +-- sdm_user_module_interest_map +-- sdm_user_package_interest_map +-- sdm_related_tickets_map + + +-- In SDM: sdm_notifications +-- This seems to be a table to hold notifications until they're actually sent out in batch +-- depending on the user's preferences +-- In BT: We'd probably do something similar. + +-- In SDM: sdm_notification_prefs +-- In BT: +create table bt_user_prefs ( + user_id integer references cc_users(user_id), + ... +); + Index: openacs.org-dev/packages/bug-tracker/www/doc/bug-tracker-spec.html =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/www/doc/bug-tracker-spec.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/www/doc/bug-tracker-spec.html 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,369 @@ +<html> +<head> +<title>Bug-tracker Specification</title> +</head> +<body bgcolor=white> +<h2>Bug-tracker Specification</h2> +By <a href="http://pinds.com/lars/">Lars Pind</a>. +<hr> + +<h3>Overview</h3> + +The bug-tracker will be a software tool for tracking bugs and feature +requests for software projects. It will be based on the existing SDM +(don't throw a good thing out), but it will also incorporate great +ideas from BugZilla, Bughost.com, and FogBUGZ. + +<p> + +Development will focus on getting a working version up and running +within about a week and a half, and then have a product that we can +incrementally improve on as we have the time and need. + +<h3>Scenarios</h3> + +<h4>Scenario 1: Tom finds a bug</h4> + +Tom is using the software and it's not behaving like he thought it +would. He visits the bug-tracker and is greeted with a list of known +bugs in his version of the software (he's previously told the +bug-tracker what version he's using, and this version is being shown +clearly on each page, along with what version is the latest released +version, and which is the current development version). (Had he had +any bugs assigned to him, he would've been greeted with the list of +bugs assigned to him instead.) He drills down the list of known bugs +by clicking on the name of the component that's causing him +trouble. Nope, still not there. He clicks the "new bug" link and +enters the info on the new bug: What he did, what he expected to +happen, what happened instead. His version and the component has +already been filled in. He can upload a file right here, and he can +also upload more files later. There's a checkbox letting Tom choose +whether to get email alerts on all activity on this bug. + +<h4>Scenario 2: Jack maintains a package</h4> + +Jack gets an email alert saying there's a new bug. He checks out the +bug description in the email and decides that this is worth looking +at. He visits the page, sets the priority to High, assigns it to one +of his trusted slaves, and goes back to the beach. + +<p> + +Later, he visits bug-tracker, and is greeted with a list of bugs he's +assigned to. Phew. Then he checks the activity report for the past +week for the bugs he's the maintainer of, whether assigned to them or +not, to see if bugs are getting closed or if they're piling up. He +decides it's time to go squash some bugs. He goes back to the "my +bugs" list, which is already sorted by priority, then user rating +(user rating is going to be in a later version), then date of entry +(descending). Clicks the first, fixes, then hits "Next", fixes, then +hits "Next", fixes ... + +<h4>Other Scenarios</h4> + +<ul> + +<li>Janis is looking at a CVS log entry, which contains a reference to +ticket #819. She visits the bug-tracker for the project and enters the +number in the "look up by #" input field to view the bug. + +</ul> + +<h3>Differences from SDM</h3> + +<ul> + +<li>Different terminology: The bug-tracker will say "project" for the +top-level, releasable chunk of code, what is now called a "package" in +the SDM. The unit below that is today called a "module" in the SDM, +but will be called a "component" in the bug-tracker. Why? Project +definitely makes more sense than "package", especially given that +package is also used about APM packages. Maybe there's no good reason +to change module to component, but component is what BugZilla uses, +and it sounds more appropriate to me. Feedback is in order. + +<li>One SDM instance per project: The front page of the bug-tracker +will show the list of open bugs for this project, not just a list of +projects to choose from. + +<li>More status codes: A bug can be resolved in many ways: Not a bug, +not reproducible, by design, etc. + +<li>More types of relationships between bugs: Duplicates, depends +on/blocks, side-effect of fix to other bug (not in initial version) + +<li>Filters: Filters a' la FogBUGZ that lets you define and save your +own views (deferred to a later version). + +<li>Estimates: Original estimate, latest estimate, time spent so +far. (not in initial version) + +<li>Severity, type of ticket, and other status codes are fully +configurable, and you can even add your own types of codes. + +</ul> + +<h3>Deferred features</h3> + +<ul> + +<li>One system-wide "my tasks" list: We'll build a separate "task +list" application at some later point, and see how the two should be +naturally integrated. + +<li>Ratings: They're not really used today. When we do reintroduce +them, we're going to make sure they have impact over how bugs are +prioritized. + +<li>Custom-defined filters: We'll try to get the "engine" in place, +but we won't bother with implementing the UI for defining new ones +just now. Soon, though. + +<li>Patches: This is a must-have, but not for the initial +release. + +<li>We're not going to use workflow. We want the UI to be just right, +so we won't let workflow get in the way. We do want to use this +bug-tracker as a prime driver for getting ACS workflow finsihed, the +way it was originally intended to. + +<li>We're not going to let you define your own status, resolution, or +other codes, because integrating custom codes with the UI is hard, and +we emphasize usability over flexibility in this release. + +<li>We're not going to include triage (before-resolution) or QA +(after-resolution) steps in the workflow. + + +</ul> + +<h3>Non goals</h3> + +<ul> + +<li>It's not going to be a general-purpose ticket-tracker. We'll write +a separate instrument for that later, but hopefully we can reuse key +ideas, and factor out some common underpinnings. + +</ul> + +<h3>Page Flowchart</h3> + +This is the pages there are and how they're related: + +<p> + +<img src="flowchart.jpg" width="482" height="276" alt="Bug-tracker page flowchart" border="0"> + +<h3>Workflow (A Bug's Life)</h3> + +We have separate STATUS and RESOLUTION codes. Possible STATUS codes are: + +<ul> +<li>Open +<li>Resolved +<li>Closed +</ul> + +Here's what the workflow looks like in ACS Workflow Petri Net style: + +<p> + +<img src="workflow.jpg" width="338" height="218" alt="Workflow for bug-tracker" border="0"> + +<p> + +We will not, in this version, bother with triage and QA steps. The +submitter of a bug is also the person to close that bug. The +maintainer of the project or component is the first assignee, and +takes it from there. There is no unassigned state. + +<p> + +BugZilla has <a +href="http://bugzilla.mozilla.org/bug_status.html">many more status +codes</a>. For example they have a confirmation step, in which it's +checked that the bug is "a true bug". They have a status to say that the bug +has been assigned. They have a special "reopened" step. And they have +a "Verified" step, and only allow the bug in "Closed" when the release +in which the bug has been fixed has actually shipped. We won't go +there in this version of the bug-tracker. + +<p> + +The RESOLUTION code to one of the following: + +<ul> +<li>Fixed +<li>By design +<li>Won't fix +<li>Postponed +<li>Duplicate +<li>Not reproducable +</ul> + +Again, BugZilla is more rigorous than most: They have an "invalid" +resolution step, with the comment "the problem described is not a +bug". I don't think we need this -- if it's not a bug, tell us what it +is: By design, not reproducable, or some other reason? + + +<h3>Other Bug Classifications</h3> + +<h4>Type of bug (hard-coded)</h4> + +<ul> + <li>Bug + <li>Suggestion (coming from the outside) + <li>To do (a developer to himself) +</ul> + +<h4>Severity (can be modified)</h4> + +<ul> + <li>Critical + <li>Major + <li>Normal + <li>Minor + <li>Trivial + <li>Enhancement +</ul> + +<h4>Priority (can be modified)</h4> + +<ul> + <li>High + <li>Medium + <li>Low +</ul> + + + +<h3>Pages</h3> + +<h4>Main Navigation</h4> + +There's a navigation bar which is present on all pages in the +bug-tracker, and contains links to: + +<ul> + +<li>List: Defaults to the last list shown this session, or to "My Bugs") + +<li>New Bug: Submit a new bug report + +<li>Search: Opens up a search form + +<li>Filters: Define filters + +<li>Patches: List patches, review and approve. + +<li>Prefs: User preferences, e.g. notification, etc. + +<li>Project admin: Setup the project (if you're an administrator) + +<li>Go to bug # + +</ul> + + +<h4>Index page: Ticket list</h4> + +(<a href="mockup-index">Mock-up</a>) + +<p> + +The index page of the package is the ticket list page. The ticket list +page displays a list of tickets in a combination of <a +href="http://www.google.com/search?q=ticket%20list">Google style</a> +and webmail style, i.e., each bug is displayed like this: + +<p> + +<table border=0 cellpadding="1" cellspacing="0" bgcolor="#0000ee" width="400" align="center"> + <tr> + <td> + <table border=0 width="100%" cellspacing="0" bgcolor=white> + <tr> + <td valign=top><input type=checkbox> </td> + <td valign=top> + <a href="#">#1932. This is the bug summary line</a><br> + <font size="-1">Here's the more complete description, which can at times be very long, so it'll + be abbreviated, cut off after a certain number of characters (HTML stripped ...<br> + <font color="#6f6f6f">Component:</font> Rendering engine - opened 3/15/2002<br> + <font color="#6f6f6f">Priority:</font> 1 - Must fix / <font color="#6f6f6f">Severity:</font> 3 - major<br> + <font color="#6f6f6f">Assigned to:</font> <a href="#">Jack</a><br> + <font color="#008000">OPEN <i>(fix for version 4.5 (4/1/2002))</i> <b>Est: 6 hrs</b></font></font> + </td> + </tr> + </table> + </td> + </tr> +</table> + +<p> + +It's Google, because each bug takes up several lines, and information +is shown "organically" for each bug. It's webmail, because each bug +has a checkbox next to it, which can be used for bulk operations. + +<p> + +Tickets are shown 20/50/100/200 per page, and you can page browse +through them like in a typical web mail interface. + +<p> + +Predefined filters include: "My bugs", "Open bugs in the current +version", "All bugs in my version", "Open bugs that I'm the maintainer +of", etc. + +<p> + +You can enter what version you're using, so that it defaults to +that version when you're entering bugs and searching for known +bugs. The version you've selected will be displayed very clearly on +each page. + +<p> + +The ticket list page can be scoped to one component. The contents will +look just the same and you can use the same filters, only everything +will be scoped to the component you selected. When you submit a bug +from inside a component level, the component name is already filled +out and cannot be changed. + + + +<h4>Enter New Ticket</h4> + + + +<h4>View Ticket</h4> + +When viewing a ticket, you have the usual webmail operators: +First/Last/Next/Prev. + + +<h4>Upload Patch</h4> + +<h4>Patch List</h4> + +<h4>Search</h4> + +<h4>User Preferences</h4> + +<h4>Project Administration</h4> + +<h4>Define Filters</h4> + +A later version will allow users to define their own filters. It would +be cool if users could also exchange filters with each other, and +perhaps an administrator can manage the set of predefined filters +available to everyone. + + +<hr> +<a href="mailto:lars@pinds.com"><address>lars@pinds.com</address></a> +</body> +</html> \ No newline at end of file Index: openacs.org-dev/packages/bug-tracker/www/doc/flowchart.jpg =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/www/doc/flowchart.jpg,v diff -u Binary files differ Index: openacs.org-dev/packages/bug-tracker/www/doc/index.html =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/www/doc/index.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/www/doc/index.html 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,18 @@ +<html> +<head> +<title>Bug-Tracker Documentation</title> +</head> +<body bgcolor=white> +<h2>Bug-Tracker Documentation</h2> +By <a href="http://www.pinds.com/lars/">Lars Pind</a> +<hr> + +<ul> + <li><a href="bug-tracker-spec">Specification</a></li> +</ul> + +<hr> +<address><a href="mailto:lars@pinds.com">lars@pinds.com</a></address> + +</body> +</html> \ No newline at end of file Index: openacs.org-dev/packages/bug-tracker/www/doc/mockup-index.html =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/www/doc/mockup-index.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/bug-tracker/www/doc/mockup-index.html 8 Oct 2002 15:46:57 -0000 1.1 @@ -0,0 +1,335 @@ +<html> +<head> +<title>Bug-Tracker</title> +<style> +.bt_navbar { font-family: tahoma,verdana,arial,helvetica; font-size: 70%; font-weight: bold; color: #ccccff; text-decoration: none; } +a.bt_navbar { color: white; } +.bt_navbar:hover { color: white; text-decoration: underline; } +INPUT.bt_navbar { font-family: tahoma,verdana,arial,helvetica; font-weight: bold; font-size: 70%; color: black; } +.bt_summary { font-size: 70%; font-family: verdana,arial,helvetica; } +.bt_summary_bold { font-size: 70%; font-family: verdana,arial,helvetica; font-weight: bold; } + +</style> +</head> +<body> + +<h2>OpenACS Bug-Tracker</h2> +<a href="/">Home</a> : OpenACS Bug-Tracker +<hr> + +<table border=0" cellspacing="0" cellpadding="2" bgcolor="#41329c" width="100%"> + <form action="#" method="get" name="navbar1"> + <tr> + <td align="left"> + <span class="bt_navbar">Your version: </span><a href="#" class="bt_navbar">4.3</a><span class="bt_navbar"> | Latest: 4.5</span> + </td> + <td align="right"> + <table border="0" cellspacing="0" cellpadding="0"> + <tr> + <td> + <a href="#" class="bt_navbar">List</a><span class="bt_navbar"> | </span> + <a href="#" class="bt_navbar">New Bug</a><span class="bt_navbar"> | </span> + <a href="#" class="bt_navbar">Search</a><span class="bt_navbar"> | </span> + <a href="#" class="bt_navbar">Filters</a><span class="bt_navbar"> | </span> + <a href="#" class="bt_navbar">Patches</a><span class="bt_navbar"> | </span> + <a href="#" class="bt_navbar">Prefs</a><span class="bt_navbar"> | </span> + <a href="#" class="bt_navbar">Project admin</a><span class="bt_navbar"> | </span> + <input name="bug_no" type="text" size="5" class="bt_navbar" value="Bug #" onFocus="javascript:document.navbar1.bug_no.value='';"> <input type="submit" value="Go" class="bt_navbar"> + </td> + </tr> + </table> + </td> + </tr> + </form> +</table> + +<p> + + +<table border="0" cellpadding="0" cellspacing="0" width="100%"> + <tr> + <td valign="top" width="200" style="border: solid 1px gray;" bgcolor="#ccccff" class="bt_summary_bold"> + 210 <a href="#">Open Bugs</a><br> + 1398 <a href="#">Closed Bugs</a> + <p> + Open bugs summary: + <p> + <table border="0" width="100%"> + <tr> + <td colspan="2" class="bt_summary_bold"> + Fix for + </td> + </tr> + <tr> + <td width="75%" class="bt_summary"> + <a href="#">Undecided</a> + </td> + <td align="right" class="bt_summary"> + 15 + </td> + </tr> + <tr> + <td width="75%" class="bt_summary"> + <a href="#">4.5</a> + </td> + <td align="right" class="bt_summary"> + 92 + </td> + </tr> + </table> + <p> + <table border="0" width="100%"> + <tr> + <td colspan="2" class="bt_summary_bold"> + Priority + </td> + </tr> + <tr> + <td width="75%" class="bt_summary"> + <a href="#">1-Must fix</a> + </td> + <td align="right" class="bt_summary"> + 15 + </td> + </tr> + <tr> + <td width="75%" class="bt_summary"> + <a href="#">4-Fix If Time</a> + </td> + <td align="right" class="bt_summary"> + 92 + </td> + </tr> + </table> + <p> + <table border="0" width="100%"> + <tr> + <td colspan="2" class="bt_summary_bold"> + Assigned To + </td> + </tr> + <tr> + <td width="75%" class="bt_summary"> + <a href="#">Don Baccus</a> + </td> + <td align="right" class="bt_summary"> + 823 + </td> + </tr> + <tr> + <td width="75%" class="bt_summary"> + <a href="#">Jack Cameleo</a> + </td> + <td align="right" class="bt_summary"> + 2 + </td> + </tr> + </table> + <p> + <table border="0" width="100%"> + <tr> + <td colspan="2" class="bt_summary_bold"> + My Filters + </td> + </tr> + <tr> + <td width="75%" class="bt_summary"> + <a href="#">My Bugs</a> + </td> + <td align="right" class="bt_summary"> + 13 + </td> + </tr> + <tr> + <td width="75%" class="bt_summary"> + <a href="#">Open bugs my version</a> + </td> + <td align="right" class="bt_summary"> + 12 + </td> + </tr> + <tr> + <td width="75%" class="bt_summary"> + <a href="#">Open bugs latest version</a> + </td> + <td align="right" class="bt_summary"> + 2 + </td> + </tr> + <tr> + <td width="75%" class="bt_summary"> + <a href="#">Open bugs my components</a> + </td> + <td align="right" class="bt_summary"> + 8 + </td> + </tr> + </table> + <p> + + </td> + <td width="25"> </td> + <td valign="top"> + <table border=0 width="100%" cellspacing="0" bgcolor=white> + <tr> + <td colspan="2"> + <b><a href="#">Filter</a>:</b> All open bugs assigned to Jack Cameleo + <hr> + Result Page: <b>1</b> <a href="#">2</a> <a href="#">3</a> <a href="#">4</a> <a href="#">5</a> <a href="#">Next ></a> + <hr> + <p> + </td> + </tr> + <tr> + <td valign=top><input type=checkbox> </td> + <td valign=top> + <a href="#">#1932. This is the bug summary line</a><br> + <font size="-1">Here's the more complete description, which can at times be very long, so it'll + be abbreviated, cut off after a certain number of characters (HTML stripped ...<br> + <font color="#6f6f6f">Component:</font> Rendering engine - opened 3/15/2002<br> + <font color="#6f6f6f">Priority:</font> 1 - Must fix / <font color="#6f6f6f">Severity:</font> 3 - major<br> + <font color="#6f6f6f">Assigned to:</font> <a href="#">Jack</a><br> + <font color="#008000">OPEN <i>(fix for version 4.5 (4/1/2002))</i> <b>Est: 6 hrs</b></font></font> + <p> + </td> + </tr> + <tr> + <td valign=top><input type=checkbox> </td> + <td valign=top> + <a href="#">#1932. This is the bug summary line</a><br> + <font size="-1">Here's the more complete description, which can at times be very long, so it'll + be abbreviated, cut off after a certain number of characters (HTML stripped ...<br> + <font color="#6f6f6f">Component:</font> Rendering engine - opened 3/15/2002<br> + <font color="#6f6f6f">Priority:</font> 1 - Must fix / <font color="#6f6f6f">Severity:</font> 3 - major<br> + <font color="#6f6f6f">Assigned to:</font> <a href="#">Jack</a><br> + <font color="#008000">OPEN <i>(fix for version 4.5 (4/1/2002))</i> <b>Est: 6 hrs</b></font></font> + <p> + </td> + </tr> + <tr> + <td valign=top><input type=checkbox> </td> + <td valign=top> + <a href="#">#1932. This is the bug summary line</a><br> + <font size="-1">Here's the more complete description, which can at times be very long, so it'll + be abbreviated, cut off after a certain number of characters (HTML stripped ...<br> + <font color="#6f6f6f">Component:</font> Rendering engine - opened 3/15/2002<br> + <font color="#6f6f6f">Priority:</font> 1 - Must fix / <font color="#6f6f6f">Severity:</font> 3 - major<br> + <font color="#6f6f6f">Assigned to:</font> <a href="#">Jack</a><br> + <font color="#008000">OPEN <i>(fix for version 4.5 (4/1/2002))</i> <b>Est: 6 hrs</b></font></font> + <p> + </td> + </tr> + <tr> + <td valign=top><input type=checkbox> </td> + <td valign=top> + <a href="#">#1932. This is the bug summary line</a><br> + <font size="-1">Here's the more complete description, which can at times be very long, so it'll + be abbreviated, cut off after a certain number of characters (HTML stripped ...<br> + <font color="#6f6f6f">Component:</font> Rendering engine - opened 3/15/2002<br> + <font color="#6f6f6f">Priority:</font> 1 - Must fix / <font color="#6f6f6f">Severity:</font> 3 - major<br> + <font color="#6f6f6f">Assigned to:</font> <a href="#">Jack</a><br> + <font color="#008000">OPEN <i>(fix for version 4.5 (4/1/2002))</i> <b>Est: 6 hrs</b></font></font> + <p> + </td> + </tr> + <tr> + <td valign=top><input type=checkbox> </td> + <td valign=top> + <a href="#">#1932. This is the bug summary line</a><br> + <font size="-1">Here's the more complete description, which can at times be very long, so it'll + be abbreviated, cut off after a certain number of characters (HTML stripped ...<br> + <font color="#6f6f6f">Component:</font> Rendering engine - opened 3/15/2002<br> + <font color="#6f6f6f">Priority:</font> 1 - Must fix / <font color="#6f6f6f">Severity:</font> 3 - major<br> + <font color="#6f6f6f">Assigned to:</font> <a href="#">Jack</a><br> + <font color="#008000">OPEN <i>(fix for version 4.5 (4/1/2002))</i> <b>Est: 6 hrs</b></font></font> + <p> + </td> + </tr> + <tr> + <td valign=top><input type=checkbox> </td> + <td valign=top> + <a href="#">#1932. This is the bug summary line</a><br> + <font size="-1">Here's the more complete description, which can at times be very long, so it'll + be abbreviated, cut off after a certain number of characters (HTML stripped ...<br> + <font color="#6f6f6f">Component:</font> Rendering engine - opened 3/15/2002<br> + <font color="#6f6f6f">Priority:</font> 1 - Must fix / <font color="#6f6f6f">Severity:</font> 3 - major<br> + <font color="#6f6f6f">Assigned to:</font> <a href="#">Jack</a><br> + <font color="#008000">OPEN <i>(fix for version 4.5 (4/1/2002))</i> <b>Est: 6 hrs</b></font></font> + <p> + </td> + </tr> + <tr> + <td valign=top><input type=checkbox> </td> + <td valign=top> + <a href="#">#1932. This is the bug summary line</a><br> + <font size="-1">Here's the more complete description, which can at times be very long, so it'll + be abbreviated, cut off after a certain number of characters (HTML stripped ...<br> + <font color="#6f6f6f">Component:</font> Rendering engine - opened 3/15/2002<br> + <font color="#6f6f6f">Priority:</font> 1 - Must fix / <font color="#6f6f6f">Severity:</font> 3 - major<br> + <font color="#6f6f6f">Assigned to:</font> <a href="#">Jack</a><br> + <font color="#008000">OPEN <i>(fix for version 4.5 (4/1/2002))</i> <b>Est: 6 hrs</b></font></font> + <p> + </td> + </tr> + <tr> + <td valign=top><input type=checkbox> </td> + <td valign=top> + <a href="#">#1932. This is the bug summary line</a><br> + <font size="-1">Here's the more complete description, which can at times be very long, so it'll + be abbreviated, cut off after a certain number of characters (HTML stripped ...<br> + <font color="#6f6f6f">Component:</font> Rendering engine - opened 3/15/2002<br> + <font color="#6f6f6f">Priority:</font> 1 - Must fix / <font color="#6f6f6f">Severity:</font> 3 - major<br> + <font color="#6f6f6f">Assigned to:</font> <a href="#">Jack</a><br> + <font color="#008000">OPEN <i>(fix for version 4.5 (4/1/2002))</i> <b>Est: 6 hrs</b></font></font> + <p> + </td> + </tr> + <tr> + <td colspan="2"> + <hr> + <input type=checkbox> Assign selected bugs to <select><option><option>Don Baccus<option>Jack Cameleo</select><br> + <input type=checkbox> Mark selected bugs for fixing in version <select><option><option>4.5<option>4.5<option>Undecided</select><br> + <input type=checkbox> Set priority of selected bugs to <select><option><option>1-Must fix<option>2-Must fix<option>3-Mus fix<option>4-Maybe<option>...</select><br> + <input type=checkbox> Set severity of selected bugs to <select><option><option>1-Showstopper<option>2-Blocker<option>3-Pretty bad<option>4-Annoying<option>...</select><br> + <input type="submit" value="Update selected bugs"> + <hr> + Result Page: <b>1</b> <a href="#">2</a> <a href="#">3</a> <a href="#">4</a> <a href="#">5</a> <a href="#">Next ></a> + </td> + </tr> + </table> + </td> + </tr> +</table> + +<p> + +<table border=0" cellspacing="0" cellpadding="2" bgcolor="#41329c" width="100%"> + <form action="#" method="get" name="navbar1"> + <tr> + <td align="left"> + <span class="bt_navbar">Your version: </span><a href="#" class="bt_navbar">4.3</a><span class="bt_navbar"> | Latest: 4.5</span> + </td> + <td align="right"> + <table border="0" cellspacing="0" cellpadding="0"> + <tr> + <td> + <a href="#" class="bt_navbar">List</a><span class="bt_navbar"> | </span> + <a href="#" class="bt_navbar">New Bug</a><span class="bt_navbar"> | </span> + <a href="#" class="bt_navbar">Search</a><span class="bt_navbar"> | </span> + <a href="#" class="bt_navbar">Filters</a><span class="bt_navbar"> | </span> + <a href="#" class="bt_navbar">Patches</a><span class="bt_navbar"> | </span> + <a href="#" class="bt_navbar">Prefs</a><span class="bt_navbar"> | </span> + <a href="#" class="bt_navbar">Project admin</a><span class="bt_navbar"> | </span> + <input name="bug_no" type="text" size="5" class="bt_navbar" value="Bug #" onFocus="javascript:document.navbar1.bug_no.value='';"> <input type="submit" value="Go" class="bt_navbar"> + </td> + </tr> + </table> + </td> + </tr> + </form> +</table> + +<hr> + +<a href="mailto:admin@yourdomain.com"><address>admin@yourdomain.com</address></a> +</body> \ No newline at end of file Index: openacs.org-dev/packages/bug-tracker/www/doc/workflow.jpg =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/bug-tracker/www/doc/workflow.jpg,v diff -u Binary files differ Index: openacs.org-dev/packages/calendar/www/calendar-choose.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/calendar/www/calendar-choose.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/calendar/www/calendar-choose.adp 8 Oct 2002 15:46:58 -0000 1.1 @@ -0,0 +1,22 @@ +<master> +<property name="title">Calendar: Choose Calendar</property> +<property name="context">Choose</property> + +<table width="95%"> + + <tr> + <td valign=top width=150> + <p> + @cal_nav@ + <p> + <include src="cal-options"> + </td> + + <td valign=top> + + <formtemplate id="cals"></formtemplate> + + </td> + </tr> +</table> +</if> Index: openacs.org-dev/packages/calendar/www/calendar-choose.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/calendar/www/calendar-choose.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/calendar/www/calendar-choose.tcl 8 Oct 2002 15:46:58 -0000 1.1 @@ -0,0 +1,54 @@ + +ad_page_contract { + + Choose a Calendar + + @author Brad Duell (bduell@ncacasi.org) + @creation-date 2002-08-06 + @cvs-id $Id: calendar-choose.tcl,v 1.1 2002/10/08 15:46:58 rmello Exp $ +} { + {return_url ""} + {date ""} + {julian_date ""} + {start_time ""} + {end_time ""} +} + +set package_id [ad_conn package_id] + +set date [calendar::adjust_date -date $date -julian_date $julian_date] + +set calendar_list [calendar::calendar_list] + +set calendar_id [lindex $calendar_list 0] + +set cals_calendar_list [list] +for { set i 0 } { $i < [llength $calendar_list] } { incr i } { + db_1row select_name "select calendar_name from calendars where calendar_id=[lindex $calendar_list $i]" + lappend cals_calendar_list [list $calendar_name [lindex $calendar_list $i]] +} + +# Create the form +form create cals + +element create cals return_url \ + -label "return_url" \ + -datatype text -widget hidden -value $return_url + +element create cals calendar_id \ + -label "Calendar" -datatype text -widget select \ + -options $cals_calendar_list + +# Process the form +if {[form is_valid cals]} { + template::form get_values cals return_url calendar_id + + ad_returnredirect "$return_url&calendar_id=$calendar_id" + + # Stop here + ad_script_abort +} + +set cal_nav [dt_widget_calendar_navigation "view" day $date "calendar_id=$calendar_id"] + +ad_return_template Index: openacs.org-dev/packages/calendar/www/index.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/calendar/www/index.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/calendar/www/index.xql 8 Oct 2002 15:46:58 -0000 1.1 @@ -0,0 +1,13 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="private_calendar_count_qry"> +<querytext> +select count(*) from calendars +where package_id= :package_id +and owner_id= :user_id +and private_p = 't' +</querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/calendar/www/doc/index.html =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/calendar/www/doc/index.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/calendar/www/doc/index.html 8 Oct 2002 15:46:58 -0000 1.1 @@ -0,0 +1,26 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> + <head> + <title>OpenACS Calendar package</title> + </head> + + <body bgcolor=white> + <h2>OpenACS Calendar package</h2> + <a href="../">OpenACS documentation</a> + <hr> + <ul> + <li><a href="requirements.html">Original Requirements Document</a> </li> + <li><a href="permissions.html">permissions</a></li> + <li><a href="regressionTest.htm">Regression Test</a></li> + <li><a href="thesisUsabilityTest.htm">Usability Test thesis</a></li> + </ul> + + + <hr> + <address><a href="mailto:vkurup@massmed.org">Vinod Kurup</a></address> +<!-- Created: Mon Aug 13 14:17:34 EDT 2001 --> +<!-- hhmts start --> +Last modified: Fri Sep 13 08:44:30 EDT 2002 +<!-- hhmts end --> + </body> +</html> Index: openacs.org-dev/packages/cms/www/modules/items/symlink-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/cms/www/modules/items/symlink-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/cms/www/modules/items/symlink-oracle.xql 8 Oct 2002 15:47:02 -0000 1.1 @@ -0,0 +1,18 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="do_folder_check"> + <querytext> + + select parent_id, + content_folder.is_folder(item_id) as folder_p + from cr_items + where item_id = :resolved_id + + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/cms/www/modules/items/symlink-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/cms/www/modules/items/symlink-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/cms/www/modules/items/symlink-postgresql.xql 8 Oct 2002 15:47:02 -0000 1.1 @@ -0,0 +1,17 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name=""> + <querytext> + + select parent_id, + content_folder__is_folder(item_id) as folder_p + from cr_items + where item_id = :resolved_id + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/cronjob/www/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/cronjob/www/index.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/cronjob/www/index.adp 8 Oct 2002 15:47:04 -0000 1.1 @@ -0,0 +1,10 @@ + <master> + <property name="title">@title@</property> + <property name="context">@context@</property> + + <p>This package has no user pages.</p> + <if @admin_p@ eq 1> + [ <a href="admin/">Administer</a> ] + </if> + + \ No newline at end of file Index: openacs.org-dev/packages/cronjob/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/cronjob/www/index.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/cronjob/www/index.tcl 8 Oct 2002 15:47:04 -0000 1.1 @@ -0,0 +1,38 @@ +ad_page_contract { + + A place holder for access to the admin pages. + + @author Bart Teeuwisse <bart.teeuwisse@7-sisters.com> + @creation-date April 2002 + +} { +} -properties { + title:onevalue + context:onevalue +} + +# Authenticate the user + +set user_id [ad_maybe_redirect_for_registration] + +# Check for admin privileges + +set package_id [ad_conn package_id] +set admin_p [ad_permission_p $package_id admin] + +# Get the name of the package + +if {[db_0or1row get_package_name " + select p.instance_name + from apm_packages p, apm_package_versions v + where p.package_id = :package_id + and p.package_key = v.package_key + and v.enabled_p = 't'"]} { + set title "$instance_name" +} else { + set title "Authorize.net Gateway" +} + +# Set the context bar. + +set context [list] Index: openacs.org-dev/packages/cronjob/www/admin/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/cronjob/www/admin/index.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/cronjob/www/admin/index.tcl 8 Oct 2002 15:47:04 -0000 1.1 @@ -0,0 +1,2 @@ +# $Id: index.tcl,v 1.1 2002/10/08 15:47:04 rmello Exp $ +ad_returnredirect "cronjobs" Index: openacs.org-dev/packages/ecommerce/www/browse-categories.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/browse-categories.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/browse-categories.adp 8 Oct 2002 15:47:06 -0000 1.1 @@ -0,0 +1,29 @@ +<h4>Browse</h4> + +<table> + <tbody> + <grid name="categories" cols="3"> + + <if @categories.col@ eq 1> + <tr> + </if> + + <td> + <if @categories.rownum@ le @categories:rowcount@> + <ul> + <li><a href="@categories.url@" title="Browse @categories.name@">@categories.name@</a></li> + </ul> + </if> + <else> + <!-- Placeholder to retain cell formatting --> + + </else> + </td> + + <if @categories.col@ eq "3"> + </tr> + </if> + + </grid> + </tbody> +</table> Index: openacs.org-dev/packages/ecommerce/www/browse-categories.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/browse-categories.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/browse-categories.tcl 8 Oct 2002 15:47:06 -0000 1.1 @@ -0,0 +1,14 @@ +ad_page_contract { + + Present a list of top level product categories to browse. + + @author Bart Teeuwisse <bart.teeuwisse@7-sisters.com> + @creation-date September 2002 + @cvs_id + +} { +} + +template::query get_categories categories multirow "select category_id as id, category_name as name from ec_categories order by sort_key" -eval { + set row(url) "category-browse?category_id=$row(id)" +} Index: openacs.org-dev/packages/ecommerce/www/category-browse-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/category-browse-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/category-browse-oracle.xql 8 Oct 2002 15:47:06 -0000 1.1 @@ -0,0 +1,38 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms> + <type>oracle</type> + <version>8.1.6</version> + </rdbms> + + <fullquery name="get_recommended_products"> + <querytext> + select p.product_id, p.product_name, p.dirname, r.recommendation_text, o.offer_code + from ec_product_recommendations r, + ec_products_displayable p, ec_user_session_offer_codes o + where (p.product_id=o.product_id(+) and (user_session_id=:user_session_id or user_session_id is null)) + and p.product_id = r.product_id + and r.${sub}category_id=:${sub}category_id + and r.active_p='t' + and (r.user_class_id is null or r.user_class_id in (select user_class_id + from ec_user_class_user_map m + where user_id=:user_id + $user_class_approved_p_clause)) + order by p.product_name + </querytext> + </fullquery> + + <fullquery name="get_regular_product_list"> + <querytext> + select p.product_id, p.product_name, p.one_line_description, o.offer_code + from $product_map($sub) m, ec_products_searchable p, ec_user_session_offer_codes o + where (p.product_id=o.product_id(+) and (user_session_id=:user_session_id or user_session_id is null)) + and p.product_id = m.product_id + and m.${sub}category_id = :${sub}category_id + $exclude_subproducts + order by p.product_name + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/ecommerce/www/category-browse-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/category-browse-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/category-browse-postgresql.xql 8 Oct 2002 15:47:06 -0000 1.1 @@ -0,0 +1,37 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms> + <type>postgresql</type> + <version>7.1</version> + </rdbms> + + <fullquery name="get_recommended_products"> + <querytext> + select p.product_id, p.product_name, p.dirname, r.recommendation_text, o.offer_code + from ec_product_recommendations r, + ec_products_displayable p left outer join ec_user_session_offer_codes o on + (p.product_id = o.product_id and user_session_id = :user_session_id) + where p.product_id = r.product_id + and r.${sub}category_id=:${sub}category_id + and r.active_p='t' + and (r.user_class_id is null or r.user_class_id in (select user_class_id + from ec_user_class_user_map m + where user_id=:user_id + $user_class_approved_p_clause)) + order by p.product_name + </querytext> + </fullquery> + + <fullquery name="get_regular_product_list"> + <querytext> + select p.product_id, p.product_name, p.one_line_description, o.offer_code + from $product_map($sub) m, ec_products_searchable p left outer join ec_user_session_offer_codes o on (p.product_id = o.product_id and user_session_id = :user_session_id) + where p.product_id = m.product_id + and m.${sub}category_id = :${sub}category_id + $exclude_subproducts + order by p.product_name + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/ecommerce/www/category-browse-subcategory-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/category-browse-subcategory-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/category-browse-subcategory-oracle.xql 8 Oct 2002 15:47:06 -0000 1.1 @@ -0,0 +1,38 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms> + <type>oracle</type> + <version>8.1.6</version> + </rdbms> + + <fullquery name="get_recommended_products"> + <querytext> + select p.product_id, p.product_name, p.dirname, r.recommendation_text, o.offer_code + from ec_product_recommendations r, + ec_products_displayable p, ec_user_session_offer_codes o + where (p.product_id=o.product_id(+) and (user_session_id=:user_session_id or user_session_id is null)) + and p.product_id = r.product_id + and r.${sub}category_id=:${sub}category_id + and r.active_p='t' + and (r.user_class_id is null or r.user_class_id in (select user_class_id + from ec_user_class_user_map m + where user_id=:user_id + $user_class_approved_p_clause)) + order by p.product_name + </querytext> + </fullquery> + + <fullquery name="get_regular_product_list"> + <querytext> + select p.product_id, p.product_name, p.one_line_description, o.offer_code + from $product_map($sub) m, ec_products_searchable p, ec_user_session_offer_codes o + where (p.product_id=o.product_id(+) and (user_session_id=:user_session_id or user_session_id is null)) + and p.product_id = m.product_id + and m.${sub}category_id = :${sub}category_id + $exclude_subproducts + order by p.product_name + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/ecommerce/www/category-browse-subcategory-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/category-browse-subcategory-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/category-browse-subcategory-postgresql.xql 8 Oct 2002 15:47:06 -0000 1.1 @@ -0,0 +1,37 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms> + <type>postgresql</type> + <version>7.1</version> + </rdbms> + + <fullquery name="get_recommended_products"> + <querytext> + select p.product_id, p.product_name, p.dirname, r.recommendation_text, o.offer_code + from ec_product_recommendations r, ec_products_displayable p left outer join ec_user_session_offer_codes o on + (p.product_id = o.product_id and user_session_id = :user_session_id) + where p.product_id = r.product_id + and r.${sub}category_id=:${sub}category_id + and r.active_p='t' + and (r.user_class_id is null or r.user_class_id in (select user_class_id + from ec_user_class_user_map m + where user_id=:user_id + $user_class_approved_p_clause)) + order by p.product_name + </querytext> + </fullquery> + + <fullquery name="get_regular_product_list"> + <querytext> + select p.product_id, p.product_name, p.one_line_description, o.offer_code + from $product_map($sub) m, ec_products_searchable p left outer join ec_user_session_offer_codes o on + (p.product_id = o.product_id and user_session_id = :user_session_id) + where p.product_id = m.product_id + and m.${sub}category_id = :${sub}category_id + $exclude_subproducts + order by p.product_name + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/ecommerce/www/checkout-progress.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/checkout-progress.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/checkout-progress.adp 8 Oct 2002 15:47:06 -0000 1.1 @@ -0,0 +1,19 @@ +<table width="100%" bgcolor="lightgray"> + <tbody> + <tr> + <td align="center"><if @step@ ge 1><b></if>Select Shipping Address<if @step@ ge 1></b></if></td> + <td align="center"><code>---></code></td> + <td align="center"><if @step@ ge 2><b></if>Verify Order<if @step@ ge 2><b></if></td> + <td align="center"><code>---></code></td> + <if @express_shipping_avail_p@> + <td align="center"><if @step@ ge 3><b></if>Select Shipping Method<if @step@ ge 3><b></if></td> + <td align="center"><code>---></code></td> + </if> + <td align="center"><if @step@ ge 4><b></if>Select Billing Address<if @step@ ge 4><b></if></td> + <td align="center"><code>---></code></td> + <td align="center"><if @step@ ge 5><b></if>Enter Payment Info<if @step@ ge 5><b></if></td> + <td align="center"><code>---></code></td> + <td align="center"><if @step@ ge 6><b></if>Confirm Order<if @step@ ge 6><b></if></td> + </tr> + </tbody> +</table> Index: openacs.org-dev/packages/ecommerce/www/checkout-progress.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/checkout-progress.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/checkout-progress.tcl 8 Oct 2002 15:47:06 -0000 1.1 @@ -0,0 +1 @@ +set express_shipping_avail_p [ad_parameter -package_id [ec_id] ExpressShippingP ecommerce] Index: openacs.org-dev/packages/ecommerce/www/contextbar.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/contextbar.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/contextbar.adp 8 Oct 2002 15:47:06 -0000 1.1 @@ -0,0 +1 @@ +<table width ="100%"> <tbody> <tr> <td>@context_bar@</td> <if @ec_admin_p@><td align="right">[ <a href="@ec_admin_link@" title="Administer @ec_system_name@">Administer</a> ]</td></if> </tr> </tbody> </table> Index: openacs.org-dev/packages/ecommerce/www/contextbar.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/contextbar.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/contextbar.tcl 8 Oct 2002 15:47:06 -0000 1.1 @@ -0,0 +1,32 @@ +# Add a [ Administer ] link at the far right to the context bar. + +# @param context_addition + +# @author Bart Teeuwisse <bart.teeuwisse@7-sisters.com> +# @cvs-id $Id: contextbar.tcl,v 1.1 2002/10/08 15:47:06 rmello Exp $ +# @creation-date September 2002 + +# Create an empty context_addition list if no addition has been passed +# in. + +if {![info exists context_addition]} { + set context_addition {} +} + +# Create a context bar with the passed in addition(s) if any. + +if {[empty_string_p $context_addition]} { + set context_bar [ad_context_bar] +} else { + set context_bar [eval ad_context_bar $context_addition] +} + +# Check for admin rights to this (the ecommerce) package. + +set ec_admin_p [ad_permission_p [ad_conn package_id] admin] +set ec_admin_link admin/ + +# Get the name of the ecommerce package + +set ec_system_name [ec_system_name] + Index: openacs.org-dev/packages/ecommerce/www/gift-certificate-claim-2.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/gift-certificate-claim-2.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/gift-certificate-claim-2.adp 8 Oct 2002 15:47:06 -0000 1.1 @@ -0,0 +1,22 @@ +<master> + <property name="title">@title@</property> + <property name="context_bar">@context_bar@</property> + <property name="signatory">@ec_system_owner@</property> + + <include src="checkout-progress" step="5"> + + <blockquote> + <if @certificate_added_p@> + <p><%= [ec_pretty_price @amount@] %> has been added to your gift + certificate account!</p> + </if> + <else> + <p>Your gift certificate has already been claimed. Either you + hit submit twice on the form, or it was claimed previously. + Once you claim it, it goes into your gift certificate balance + and you don't have to claim it again.</p> + </else> + <p><a href="payment?address_id=@address_id@">Continue with your + order</a></p> + </blockquote> + Index: openacs.org-dev/packages/ecommerce/www/select-shipping-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/select-shipping-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/select-shipping-oracle.xql 8 Oct 2002 15:47:06 -0000 1.1 @@ -0,0 +1,21 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms> + <type>oracle</type> + <version>8.1.6</version> + </rdbms> + + <fullquery name="select_hard_goods"> + <querytext> + select i.product_id, i.color_choice, i.size_choice, i.style_choice, count(*) as item_count, u.offer_code + from ec_products p, ec_items i, ec_user_session_offer_codes u + where u.product_id(+)=i.product_id and (u.user_session_id is null or u.user_session_id=:user_session_id) + and i.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + and i.order_id = :order_id + group by i.product_id, i.color_choice, i.size_choice, i.style_choice, u.offer_code + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/ecommerce/www/select-shipping-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/select-shipping-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/select-shipping-postgresql.xql 8 Oct 2002 15:47:06 -0000 1.1 @@ -0,0 +1,21 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms> + <type>postgresql</type> + <version>7.1</version> + </rdbms> + + <fullquery name="select_hard_goods"> + <querytext> + select i.product_id, i.color_choice, i.size_choice, i.style_choice, count(*) as item_count, u.offer_code + from ec_products p, ec_items i + left join ec_user_session_offer_codes u on (u.product_id = i.product_id and u.user_session_id = :user_session_id) + where i.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + and i.order_id = :order_id + group by i.product_id, i.color_choice, i.size_choice, i.style_choice, u.offer_code + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/ecommerce/www/toolbar.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/toolbar.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/toolbar.adp 8 Oct 2002 15:47:06 -0000 1.1 @@ -0,0 +1,20 @@ +<table width="100%"> + <tbody> + <tr> + <td>@ec_search_widget@</td> + <td align="right"> + <if @gift_certificates_are_allowed@ true and @current_location@ ne "gift-certificate"> + [ <a href="gift-certificate-order">Order a Gift Certificate</a> ] + </if> + <if @current_location@ ne "shopping-cart"> + [ <a href="@ec_cart_link@" title="View the contents of your shopping cart">Shopping Cart</a> ] + </if> + <if @current_location@ ne "your-account"> + [ <a href="@ec_account_link@" title="View your @ec_system_name@ account">Your Account</a> ] + </if> + </td> + </tr> + </tbody> +</table> +<p> + Index: openacs.org-dev/packages/ecommerce/www/toolbar.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/toolbar.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/toolbar.tcl 8 Oct 2002 15:47:06 -0000 1.1 @@ -0,0 +1,38 @@ +# Display the ecommerce toolbar containing a product search widget, +# a link to order gift certificates (if they are allowed) and links +# to the shopping cart and store account. + +# @param category_id +# @param subcategory_id +# @param search_text +# @current_location + +# @author Bart Teeuwisse <bart.teeuwisse@7-sisters.com> +# @cvs-id $Id: toolbar.tcl,v 1.1 2002/10/08 15:47:06 rmello Exp $ +# @creation-date September 2002 + +# Create empty lists for each optional parameter that has not been +# passed in. + +foreach parameter {category_id subcategory_id search_text current_location} { + if {![info exists $parameter]} { + set $parameter {} + } +} + +# Create a context aware search widget to search for products. + +set ec_search_widget [ec_search_widget "$category_id|$subcategory_id" $search_text] + +# Determine the URLs to the Shopping Cart and store Account. + +set ec_cart_link [ec_insecurelink [ad_parameter -package_id [ec_id] EcommercePath]shopping-cart] +set ec_account_link [ec_insecurelink [ad_parameter -package_id [ec_id] EcommercePath]account] + +# Get the name of the ecommerce package + +set ec_system_name [ec_system_name] + +# Check if gift certificates can be bought. + +set gift_certificates_are_allowed [ad_parameter -package_id [ec_id] SellGiftCertificatesP ecommerce] Index: openacs.org-dev/packages/ecommerce/www/admin/orders/index-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/admin/orders/index-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/admin/orders/index-oracle.xql 8 Oct 2002 15:47:08 -0000 1.1 @@ -0,0 +1,19 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms> + <type>oracle</type> + <version>8.1.6</version> + </rdbms> + + <fullquery name="shipping_method_counts"> + <querytext> + select shipping_method, nvl(count(*),0) as shipping_method_count + from ec_orders_shippable + where shipping_method not in ('no_shipping', 'pickup') + and shipping_method is not null + group by shipping_method + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/ecommerce/www/admin/orders/index-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/admin/orders/index-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/admin/orders/index-postgresql.xql 8 Oct 2002 15:47:08 -0000 1.1 @@ -0,0 +1,19 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms> + <type>postgresql</type> + <version>7.1</version> + </rdbms> + + <fullquery name="shipping_method_counts"> + <querytext> + select shipping_method, coalesce(count(*), 0) as shipping_method_count + from ec_orders_shippable + where shipping_method not in ('no_shipping', 'pickup') + and shipping_method is not null + group by shipping_method + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/ecommerce/www/admin/products/recommendations-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/admin/products/recommendations-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/admin/products/recommendations-oracle.xql 8 Oct 2002 15:47:08 -0000 1.1 @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<queryset> + + <rdbms> + <type>oracle</type> + <version>8.1.6</version> + </rdbms> + + <fullquery name="recommendations_select"> + <querytext> + select r.recommendation_id, r.the_category_name, r.the_subcategory_name, r.the_subsubcategory_name, p.product_name, c.user_class_name + from ec_recommendations_cats_view r, ec_products p, ec_user_classes c + where r.product_id=p.product_id and r.user_class_id = c.user_class_id(+) and r.active_p='t' + order by DECODE(the_category_name,null,0,1), upper(the_category_name), + upper(the_subcategory_name), + upper(the_subsubcategory_name) + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/ecommerce/www/admin/products/recommendations-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/admin/products/recommendations-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/admin/products/recommendations-postgresql.xql 8 Oct 2002 15:47:08 -0000 1.1 @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<queryset> + + <rdbms> + <type>postgresql</type> + <version>7.1</version> + </rdbms> + + <fullquery name="recommendations_select"> + <querytext> + select r.recommendation_id, r.the_category_name, r.the_subcategory_name, r.the_subsubcategory_name, p.product_name, c.user_class_name + from ec_recommendations_cats_view r + join ec_products p using (product_id) + left join ec_user_classes c on (r.user_class_id = c.user_class_id) + where r.active_p='t' + order by case when the_category_name is null then 0 else 1 end, upper(the_category_name), upper(the_subcategory_name), upper(the_subsubcategory_name) + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/ecommerce/www/admin/products/toggle-active-p.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/admin/products/toggle-active-p.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/admin/products/toggle-active-p.xql 8 Oct 2002 15:47:09 -0000 1.1 @@ -0,0 +1,13 @@ +<?xml version="1.0"?> + +<queryset> + + <fullquery name="is_product_active_p"> + <querytext> + select active_p + from ec_products + where product_id = :product_id + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/ecommerce/www/doc/contextbar.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/doc/contextbar.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/doc/contextbar.adp 8 Oct 2002 15:47:09 -0000 1.1 @@ -0,0 +1 @@ +<table width ="100%"> <tbody> <tr> <td>@context_bar@</td> <if @ec_admin_p@><td align="right">[ <a href="@ec_admin_link@" title="Administer @ec_system_name@">Administer</a> ]</td></if> </tr> </tbody> </table> Index: openacs.org-dev/packages/ecommerce/www/doc/contextbar.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ecommerce/www/doc/contextbar.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ecommerce/www/doc/contextbar.tcl 8 Oct 2002 15:47:09 -0000 1.1 @@ -0,0 +1,32 @@ +# Add a [ Administer ] link at the far right to the context bar. + +# @param context_addition + +# @author Bart Teeuwisse <bart.teeuwisse@7-sisters.com> +# @cvs-id $Id: contextbar.tcl,v 1.1 2002/10/08 15:47:09 rmello Exp $ +# @creation-date September 2002 + +# Create an empty context_addition list if no addition has been passed +# in. + +if {![info exists context_addition]} { + set context_addition {} +} + +# Create a context bar with the passed in addition(s) if any. + +if {[empty_string_p $context_addition]} { + set context_bar [ad_context_bar] +} else { + set context_bar [eval ad_context_bar $context_addition] +} + +# Check for admin rights to this (the ecommerce) package. + +set ec_admin_p [ad_permission_p [ad_conn package_id] admin] +set ec_admin_link [apm_package_url_from_id [ec_id]]admin/ + +# Get the name of the ecommerce package + +set ec_system_name [ec_system_name] + Index: openacs.org-dev/packages/file-storage/www/folder-chunk-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/file-storage/www/folder-chunk-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/file-storage/www/folder-chunk-oracle.xql 8 Oct 2002 15:47:12 -0000 1.1 @@ -0,0 +1,23 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + <fullquery name="select_folder_contents"> + <querytext> + select fs_objects.object_id, + fs_objects.name, + fs_objects.live_revision, + fs_objects.type, + to_char(fs_objects.last_modified, 'Month DD YYYY HH24:MI') as last_modified, + fs_objects.content_size, + fs_objects.url, + fs_objects.key, + fs_objects.sort_key, + fs_objects.file_upload_name, + case when fs_objects.last_modified >= (sysdate - :n_past_days) then 1 else 0 end as new_p + from fs_objects + where fs_objects.parent_id = :folder_id + order by sort_key, name + </querytext> + </fullquery> +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/file-storage/www/folder-chunk-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/file-storage/www/folder-chunk-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/file-storage/www/folder-chunk-postgresql.xql 8 Oct 2002 15:47:12 -0000 1.1 @@ -0,0 +1,23 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + <fullquery name="select_folder_contents"> + <querytext> + select fs_objects.object_id, + fs_objects.name, + fs_objects.live_revision, + fs_objects.type, + to_char(fs_objects.last_modified, 'Month DD YYYY HH24:MI') as last_modified, + fs_objects.content_size, + fs_objects.url, + fs_objects.key, + fs_objects.sort_key, + fs_objects.file_upload_name, + case when fs_objects.last_modified >= (now() - $n_past_days) then 1 else 0 end as new_p + from fs_objects + where fs_objects.parent_id = :folder_id + order by sort_key, name + </querytext> + </fullquery> +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/file-storage/www/folder-edit-2-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/file-storage/www/folder-edit-2-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/file-storage/www/folder-edit-2-oracle.xql 8 Oct 2002 15:47:12 -0000 1.1 @@ -0,0 +1,17 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="folder_rename"> + <querytext> + begin + content_folder.rename ( + folder_id => :folder_id, + label => :folder_name + ); + end; + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/file-storage/www/folder-edit-2-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/file-storage/www/folder-edit-2-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/file-storage/www/folder-edit-2-postgresql.xql 8 Oct 2002 15:47:12 -0000 1.1 @@ -0,0 +1,17 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="folder_rename"> + <querytext> + select content_folder__rename ( + :folder_id, + null, -- name + :folder_name, -- label + null -- description + ); + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/file-storage/www/folder-edit-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/file-storage/www/folder-edit-2.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/file-storage/www/folder-edit-2.tcl 8 Oct 2002 15:47:12 -0000 1.1 @@ -0,0 +1,36 @@ +ad_page_contract { + Script to rename a folder. + + @author Andrew Grumet (aegrumet@alum.mit.edu) + @creation-date 24 Jun 2002 + @cvs-id $Id: folder-edit-2.tcl,v 1.1 2002/10/08 15:47:12 rmello Exp $ +} { + folder_id:integer,notnull + folder_name:trim,notnull +} -validate { + valid_folder -requires {folder_id:integer} { + if ![fs_folder_p $folder_id] { + ad_complain "The specified folder does not exist." + } + } +} + +set user_id [ad_conn user_id] + +ad_require_permission $folder_id admin + +# get their IP + +set creation_ip [ad_conn peeraddr] + +# strip out spaces from the name + +#We can't rename the item because this breaks the syllabus +#portlet. aegrumet/2002-08-28 +#regsub -all { +} [string tolower $folder_name] {_} name + +db_exec_plsql folder_rename {} + +ad_returnredirect "?folder_id=$folder_id" + + Index: openacs.org-dev/packages/file-storage/www/folder-edit.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/file-storage/www/folder-edit.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/file-storage/www/folder-edit.adp 8 Oct 2002 15:47:12 -0000 1.1 @@ -0,0 +1,20 @@ +<master> +<property name="title">Edit Folder</property> +<property name="context">@context_bar@</property> + + +<form method=POST action=folder-edit-2> +<input type=hidden name=folder_id value="@folder_id@"> + +<table> + <tr> + <td align=right>Folder Name:</td> + <td><input type=text name=folder_name value="@folder_name@" size=20></td> + </tr> + <tr> + <td> </td> + <td><input type=submit value="Save"></td> + </tr> +</table> + +</form> \ No newline at end of file Index: openacs.org-dev/packages/file-storage/www/folder-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/file-storage/www/folder-edit.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/file-storage/www/folder-edit.tcl 8 Oct 2002 15:47:12 -0000 1.1 @@ -0,0 +1,28 @@ +ad_page_contract { + form to edit a folder + + @author Andrew Grumet (aegrumet@alum.mit.edu) + @creation-date 24 Jun 2002 + @cvs-id $Id: folder-edit.tcl,v 1.1 2002/10/08 15:47:12 rmello Exp $ +} { + folder_id:integer,notnull +} -validate { + valid_folder -requires {parent_id:integer} { + if ![fs_folder_p $folder_id] { + ad_complain "The specified folder does not exist." + } + } +} -properties { + folder_id:onevalue + context_bar:onevalue +} + +ad_require_permission $folder_id admin + +# set templating datasources + +set context_bar [fs_context_bar_list -final "Edit" $folder_id] + +set folder_name [fs_get_folder_name $folder_id] + +ad_return_template Index: openacs.org-dev/packages/file-storage/www/graphics/new.gif =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/file-storage/www/graphics/new.gif,v diff -u Binary files differ Index: openacs.org-dev/packages/forums/tcl/forum-reply-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/forums/tcl/forum-reply-procs-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/forums/tcl/forum-reply-procs-oracle.xql 8 Oct 2002 15:47:12 -0000 1.1 @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + + <fullquery name="forum::notification::get_url.select_forums_package_url"> + <querytext> + select site_node.url(node_id) + from site_nodes + where object_id = (select package_id + from forums_forums + where forums_forums.forum_id = :forum_id) + </querytext> + </fullquery> + + +</queryset> + + + + + + + + + + Index: openacs.org-dev/packages/forums/tcl/forum-reply-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/forums/tcl/forum-reply-procs-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/forums/tcl/forum-reply-procs-postgresql.xql 8 Oct 2002 15:47:12 -0000 1.1 @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + + <fullquery name="forum::notification::get_url.select_forums_package_url"> + <querytext> + select site_node__url(node_id) + from site_nodes + where object_id = (select package_id + from forums_forums + where forums_forums.forum_id = :forum_id) + </querytext> + </fullquery> + +</queryset> + + + Index: openacs.org-dev/packages/forums/tcl/forum-reply-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/forums/tcl/forum-reply-procs.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/forums/tcl/forum-reply-procs.xql 8 Oct 2002 15:47:12 -0000 1.1 @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<queryset> + + <fullquery name="forum::notification::get_url.select_object_type"> + <querytext> + select object_type + from acs_objects + where object_id = :object_id + </querytext> + </fullquery> + +</queryset> + + + + + + + + + + Index: openacs.org-dev/packages/lars-blogger/lars-blogger.info =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/lars-blogger.info,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/lars-blogger.info 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,116 @@ +<?xml version="1.0"?> +<!-- Generated by the OpenACS Package Manager --> + +<package key="lars-blogger" url="http://openacs.org/repository/apm/packages/lars-blogger" type="apm_application"> + <package-name>Lars Blogger</package-name> + <pretty-plural>Lars Bloggers</pretty-plural> + <initial-install-p>f</initial-install-p> + <singleton-p>f</singleton-p> + + <version name="0.8.2" url="http://openacs.org/repository/download/apm/lars-blogger-0.8.2.apm"> + <database-support> + <database>oracle</database> + <database>postgresql</database> + </database-support> + <owner url="mailto:lars@pinds.com">Lars Pind</owner> + <summary>Write your own web log</summary> + <release-date>2002-09-16</release-date> + <vendor url="http://www.collaboraid.biz">Collaboraid</vendor> + <description format="text/html">Manages multiple web logs for your site. Just mount multiple instances, and you can do all the blogging you want.</description> + + <requires url="acs-datetime" version="4.0"/> + <requires url="general-comments" version="4.0"/> + <requires url="notifications" version="0.1"/> + + <files> + <file type="package_spec" path="lars-blogger.info"/> + <file type="data_model_create" db_type="oracle" path="sql/oracle/lars-blogger-create.sql"/> + <file type="data_model_drop" db_type="oracle" path="sql/oracle/lars-blogger-drop.sql"/> + <file type="data_model" db_type="oracle" path="sql/oracle/lars-blogger-package-create.sql"/> + <file type="data_model" db_type="oracle" path="sql/oracle/lars-blogger-package-drop.sql"/> + <file type="data_model" db_type="oracle" path="sql/oracle/notifications-drop.sql"/> + <file type="data_model" db_type="oracle" path="sql/oracle/notifications-init.sql"/> + <file type="data_model" db_type="oracle" path="sql/oracle/rss-register.sql"/> + <file type="data_model" db_type="oracle" path="sql/oracle/rss-unregister.sql"/> + <file type="data_model_upgrade" db_type="oracle" path="sql/oracle/upgrade/upgrade-0.7d-0.8.sql"/> + <file type="data_model_create" db_type="postgresql" path="sql/postgresql/lars-blogger-create.sql"/> + <file type="data_model_drop" db_type="postgresql" path="sql/postgresql/lars-blogger-drop.sql"/> + <file type="data_model" db_type="postgresql" path="sql/postgresql/notifications-drop.sql"/> + <file type="data_model" db_type="postgresql" path="sql/postgresql/notifications-init.sql"/> + <file type="data_model" db_type="postgresql" path="sql/postgresql/rss-register.sql"/> + <file type="data_model" db_type="postgresql" path="sql/postgresql/rss-unregister.sql"/> + <file type="data_model_upgrade" db_type="postgresql" path="sql/postgresql/upgrade/upgrade-0.6.4d-0.7d.sql"/> + <file type="data_model_upgrade" db_type="postgresql" path="sql/postgresql/upgrade/upgrade-0.7d-0.8.sql"/> + <file type="tcl_procs" path="tcl/entry-procs.tcl"/> + <file type="query_file" path="tcl/entry-procs.xql"/> + <file type="query_file" db_type="oracle" path="tcl/lars-blogger-procs-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="tcl/lars-blogger-procs-postgresql.xql"/> + <file type="tcl_procs" path="tcl/lars-blogger-procs.tcl"/> + <file type="query_file" db_type="oracle" path="tcl/rss-procs-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="tcl/rss-procs-postgresql.xql"/> + <file type="tcl_procs" path="tcl/rss-procs.tcl"/> + <file type="query_file" path="tcl/rss-procs.xql"/> + <file type="tcl_procs" path="tcl/weblogs-procs.tcl"/> + <file type="query_file" path="tcl/weblogs-procs.xql"/> + <file type="content_page" path="www/admin/drafts.adp"/> + <file type="content_page" path="www/admin/drafts.tcl"/> + <file type="query_file" path="www/admin/drafts.xql"/> + <file type="content_page" path="www/admin/entry-delete.tcl"/> + <file type="query_file" path="www/admin/entry-delete.xql"/> + <file type="content_page" path="www/admin/entry-edit.adp"/> + <file type="query_file" db_type="oracle" path="www/admin/entry-edit-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/admin/entry-edit-postgresql.xql"/> + <file type="content_page" path="www/admin/entry-edit.tcl"/> + <file type="query_file" path="www/admin/entry-edit.xql"/> + <file type="content_page" path="www/admin/entry-preview.adp"/> + <file type="content_page" path="www/admin/entry-preview.tcl"/> + <file type="query_file" path="www/admin/entry-preview.xql"/> + <file type="query_file" db_type="oracle" path="www/admin/entry-publish-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/admin/entry-publish-postgresql.xql"/> + <file type="content_page" path="www/admin/entry-publish.tcl"/> + <file type="content_page" path="www/admin/entry-revoke.tcl"/> + <file type="query_file" path="www/admin/entry-revoke.xql"/> + <file type="content_page" path="www/admin/index.adp"/> + <file type="content_page" path="www/admin/index.tcl"/> + <file type="query_file" path="www/admin/index.xql"/> + <file type="content_page" path="www/admin/recently-published.adp"/> + <file type="query_file" db_type="oracle" path="www/admin/recently-published-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/admin/recently-published-postgresql.xql"/> + <file type="content_page" path="www/admin/recently-published.tcl"/> + <file type="content_page" path="www/archive/index.vuh"/> + <file type="content_page" path="www/blog.adp"/> + <file type="content_page" path="www/blog-months.adp"/> + <file type="query_file" db_type="oracle" path="www/blog-months-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/blog-months-postgresql.xql"/> + <file type="content_page" path="www/blog-months.tcl"/> + <file type="query_file" db_type="oracle" path="www/blog-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/blog-postgresql.xql"/> + <file type="content_page" path="www/blog.tcl"/> + <file type="content_page" path="www/calendar.adp"/> + <file type="content_page" path="www/calendar.tcl"/> + <file type="query_file" path="www/calendar.xql"/> + <file type="documentation" path="www/doc/index.html"/> + <file type="content_page" path="www/entry-chunk.adp"/> + <file type="content_page" path="www/entry-chunk.tcl"/> + <file type="content_page" path="www/flush-cache.tcl"/> + <file type="content_page" path="www/graphics/arrow-box.gif"/> + <file type="content_page" path="www/index.adp"/> + <file type="content_page" path="www/index.tcl"/> + <file type="query_file" path="www/index.xql"/> + <file type="content_page" path="www/one-entry.adp"/> + <file type="content_page" path="www/one-entry.tcl"/> + </files> + <parameters> + <parameter datatype="string" min_n_values="1" max_n_values="1" name="HeaderBackgroundColor" default="#dcdcdc" description="Background color for the header bars, those with the entry date, calendar, etc."/> + <parameter datatype="number" min_n_values="1" max_n_values="1" name="ShowPosterP" default="1" description="Show who posted the entry and when"/> + <parameter datatype="string" min_n_values="1" max_n_values="1" name="public_url" description="The public URL for this blog (in case you've put the blog on your front page, for example)" section_name="weblogs-com"/> + <parameter datatype="number" min_n_values="1" max_n_values="1" name="weblogs_update_ping_p" default="1" description="Should we ping weblogs.com on updates to this blog?" section_name="weblogs-com"/> + <parameter datatype="string" min_n_values="1" max_n_values="1" name="weblogs_ping_url" default="http://rpc.weblogs.com/RPC2" description="The URL to post the update ping message to" section_name="weblogs-com"/> + <parameter datatype="string" min_n_values="1" max_n_values="1" name="channel_image_url" description="The URL, relative to this server, to the image that corresponds to this blog in the rss channel" section_name="rss"/> + <parameter datatype="number" min_n_values="1" max_n_values="1" name="channel_image_width" description="Width in pixels of the image to be used for this blog as an RSS channel" section_name="rss"/> + <parameter datatype="number" min_n_values="1" max_n_values="1" name="channel_image_height" description="Height in pixels of the image to be used for this blog as an RSS channel" section_name="rss"/> + <parameter datatype="string" min_n_values="1" max_n_values="1" name="rss_file_url" description="What URL should we advertise the RSS feed under, relative to the site root. Leave blank if no RSS feed." section_name="rss"/> + </parameters> + + </version> +</package> Index: openacs.org-dev/packages/lars-blogger/sql/oracle/lars-blogger-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/sql/oracle/lars-blogger-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/sql/oracle/lars-blogger-create.sql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,50 @@ +-- +-- lars-blogger-create.sql +-- +-- @author Lars Pind +-- @author Yon (Yon@milliped.com) Oracle Port +-- +-- @cvs-id $Id: lars-blogger-create.sql,v 1.1 2002/10/08 15:47:13 rmello Exp $ +-- + +declare +begin + acs_object_type.create_type( + object_type => 'pinds_blog_entry', + pretty_name => 'Blog Entry', + pretty_plural => 'Blog Entries', + supertype => 'acs_object', + table_name => 'pinds_blog_entries', + id_column => 'entry_id', + package_name => null, + abstract_p => 'f', + type_extension_table => null, + name_method => 'pinds_blog_entry.title' + ); +end; +/ +show errors + +create table pinds_blog_entries ( + entry_id constraint pinds_blog_entry_id_fk + references acs_objects(object_id) + constraint pinds_blog_entries_pk + primary key, + package_id constraint pinds_blog_entry_package_id_fk + references apm_packages(package_id), + title varchar(500), + content clob, + entry_date date, + posted_date date, + draft_p char(1) default 'f' + constraint pinds_blog_entries_draft_ck + check (draft_p in ('t','f')), + deleted_p char(1) default 'f' + constraint pinds_blog_entries_deleted_ck + check (deleted_p in ('t','f')) +); + + +@@ lars-blogger-package-create +@@ rss-register +@@ notifications-init Index: openacs.org-dev/packages/lars-blogger/sql/oracle/lars-blogger-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/sql/oracle/lars-blogger-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/sql/oracle/lars-blogger-drop.sql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,37 @@ +-- +-- lars-blogger-drop.sql +-- +-- @author Lars Pind +-- @author Yon (Yon@milliped.com) Oracle Port +-- @author Vinod Kurup (vinod@kurup.com) +-- +-- @cvs-id $Id: lars-blogger-drop.sql,v 1.1 2002/10/08 15:47:13 rmello Exp $ +-- + +@@ notifications-drop +@@ rss-unregister + +begin + + for blog_entry in (select entry_id from pinds_blog_entries) loop + -- delete comments (which are acs_message's) + for comment in (select comment_id from general_comments + where object_id = blog_entry.entry_id) loop + acs_message.delete(comment.comment_id); + end loop; + + pinds_blog_entry.delete(blog_entry.entry_id); + end loop; + + acs_object_type.drop_type( + object_type => 'pinds_blog_entry', + cascade_p => 't' + ); + +end; +/ +show errors + +@@ lars-blogger-package-drop + +drop table pinds_blog_entries; Index: openacs.org-dev/packages/lars-blogger/sql/oracle/lars-blogger-package-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/sql/oracle/lars-blogger-package-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/sql/oracle/lars-blogger-package-create.sql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,121 @@ +-- +-- lars-blogger-package-create.sql +-- +-- @author Lars Pind +-- @author Yon (Yon@milliped.com) Oracle Port +-- +-- @cvs-id $Id: lars-blogger-package-create.sql,v 1.1 2002/10/08 15:47:13 rmello Exp $ +-- + +create or replace package pinds_blog_entry +as + + function new ( + entry_id in pinds_blog_entries.entry_id%TYPE default null, + package_id in pinds_blog_entries.package_id%TYPE, + title in pinds_blog_entries.title%TYPE default null, + content in varchar default null, + entry_date in pinds_blog_entries.entry_date%TYPE default null, + draft_p in pinds_blog_entries.draft_p%TYPE default 'f', + creation_user in acs_objects.creation_user%TYPE default null, + creation_ip in acs_objects.creation_ip%TYPE default null + ) return pinds_blog_entries.entry_id%TYPE; + + procedure delete ( + entry_id in pinds_blog_entries.entry_id%TYPE + ); + + function title ( + entry_id in pinds_blog_entries.entry_id%TYPE + ) return pinds_blog_entries.title%TYPE; + +end pinds_blog_entry; +/ +show errors + +create or replace package body pinds_blog_entry +as + + function new ( + entry_id in pinds_blog_entries.entry_id%TYPE default null, + package_id in pinds_blog_entries.package_id%TYPE, + title in pinds_blog_entries.title%TYPE default null, + content in varchar default null, + entry_date in pinds_blog_entries.entry_date%TYPE default null, + draft_p in pinds_blog_entries.draft_p%TYPE default 'f', + creation_user in acs_objects.creation_user%TYPE default null, + creation_ip in acs_objects.creation_ip%TYPE default null + ) return pinds_blog_entries.entry_id%TYPE + is + v_entry_id pinds_blog_entries.entry_id%TYPE; + begin + + v_entry_id := acs_object.new( + object_id => pinds_blog_entry.new.entry_id, + object_type => 'pinds_blog_entry', + creation_date => sysdate, + creation_user => pinds_blog_entry.new.creation_user, + creation_ip => pinds_blog_entry.new.creation_ip, + context_id => pinds_blog_entry.new.package_id + ); + + insert into pinds_blog_entries ( + entry_id, + package_id, + title, + content, + entry_date, + posted_date, + draft_p, + deleted_p + ) values ( + v_entry_id, + pinds_blog_entry.new.package_id, + pinds_blog_entry.new.title, + pinds_blog_entry.new.content, + pinds_blog_entry.new.entry_date, + sysdate, + pinds_blog_entry.new.draft_p, + 'f' + ); + + return v_entry_id; + + end new; + + procedure delete ( + entry_id in pinds_blog_entries.entry_id%TYPE + ) + is + begin + + delete + from pinds_blog_entries + where entry_id = pinds_blog_entry.delete.entry_id; + + acs_object.delete(pinds_blog_entry.delete.entry_id); + + end delete; + + function title ( + entry_id in pinds_blog_entries.entry_id%TYPE + ) return pinds_blog_entries.title%TYPE + is + v_title pinds_blog_entries.title%TYPE; + begin + + select title + into v_title + from pinds_blog_entries + where entry_id = pinds_blog_entry.title.entry_id; + + return v_title; + + exception when no_data_found then + return ''; + + end title; + +end pinds_blog_entry; +/ +show errors Index: openacs.org-dev/packages/lars-blogger/sql/oracle/lars-blogger-package-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/sql/oracle/lars-blogger-package-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/sql/oracle/lars-blogger-package-drop.sql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,11 @@ +-- +-- lars-blogger-package-drop.sql +-- +-- @author Lars Pind +-- @author Yon (Yon@milliped.com) Oracle Port +-- +-- @cvs-id $Id: lars-blogger-package-drop.sql,v 1.1 2002/10/08 15:47:13 rmello Exp $ +-- + +drop package body pinds_blog_entry; +drop package pinds_blog_entry; Index: openacs.org-dev/packages/lars-blogger/sql/oracle/notifications-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/sql/oracle/notifications-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/sql/oracle/notifications-drop.sql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,19 @@ +-- +-- The Forums Package +-- +-- @author gwong@orchardlabs.com,ben@openforce.biz +-- @creation-date 2002-05-16 +-- +-- This code is newly concocted by Ben, but with significant concepts and code +-- lifted from Gilbert's UBB forums. Thanks Orchard Labs. +-- + +declare +begin + for row in (select type_id + from notification_types + where short_name in ('lars_blogger_notif_type')) + loop + notification_type.delete(row.type_id); + end loop; +end; Index: openacs.org-dev/packages/lars-blogger/sql/oracle/notifications-init.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/sql/oracle/notifications-init.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/sql/oracle/notifications-init.sql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,69 @@ + +-- +-- The Forums Package +-- +-- @author gwong@orchardlabs.com,ben@openforce.biz +-- @creation-date 2002-05-16 +-- +-- This code is newly concocted by Ben, but with significant concepts and code +-- lifted from Gilbert's UBB forums. Thanks Orchard Labs. +-- + +-- the integration with Notifications + +declare + impl_id integer; + v_foo integer; +begin + -- the notification type impl + impl_id := acs_sc_impl.new ( + 'NotificationType', + 'lars_blogger_notif_type', + 'lars-blogger' + ); + + v_foo := acs_sc_impl.new_alias ( + 'NotificationType', + 'lars_blogger_notif_type', + 'GetURL', + 'lars_blogger::notification::get_url', + 'TCL' + ); + + v_foo := acs_sc_impl.new_alias ( + 'NotificationType', + 'lars_blogger_notif_type', + 'ProcessReply', + 'lars_blogger::notification::process_reply', + 'TCL' + ); + + acs_sc_binding.new ( + contract_name => 'NotificationType', + impl_name => 'lars_blogger_notif_type' + ); + + v_foo:= notification_type.new ( + short_name => 'lars_blogger_notif', + sc_impl_id => impl_id, + pretty_name => 'Blog Notification', + description => 'Notifications for Blog', + creation_user => NULL, + creation_ip => NULL + ); + + -- enable the various intervals and delivery methods + insert into notification_types_intervals + (type_id, interval_id) + select v_foo, interval_id + from notification_intervals where name in ('instant','hourly','daily'); + + insert into notification_types_del_methods + (type_id, delivery_method_id) + select v_foo, delivery_method_id + from notification_delivery_methods where short_name in ('email'); + + +end; +/ +show errors Index: openacs.org-dev/packages/lars-blogger/sql/oracle/rss-register.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/sql/oracle/rss-register.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/sql/oracle/rss-register.sql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,37 @@ +-- +-- rss-register.sql +-- +-- @author Lars Pind +-- +-- @cvs-id $Id: rss-register.sql,v 1.1 2002/10/08 15:47:13 rmello Exp $ +-- + +declare + foo integer; +begin + + foo := acs_sc_impl.new( + impl_contract_name => 'RssGenerationSubscriber', + impl_name => 'pinds_blog_entries', + impl_owner_name => 'lars-blogger' + ); + + foo := acs_sc_impl_alias.new( + impl_contract_name => 'RssGenerationSubscriber', + impl_name => 'pinds_blog_entries', + impl_operation_name => 'datasource', + impl_alias => 'lars_blog__rss_datasource', + impl_pl => 'TCL' + ); + + foo := acs_sc_impl_alias.new( + impl_contract_name => 'RssGenerationSubscriber', + impl_name => 'pinds_blog_entries', + impl_operation_name => 'lastUpdated', + impl_alias => 'lars_blog__rss_lastUpdated', + impl_pl => 'TCL' + ); + +end; +/ +show errors Index: openacs.org-dev/packages/lars-blogger/sql/oracle/rss-unregister.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/sql/oracle/rss-unregister.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/sql/oracle/rss-unregister.sql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,21 @@ +-- +-- rss-unregister.sql +-- +-- Unregister the RSS Service contract +-- +-- @author Lars Pind +-- @author Vinod Kurup (vinod@kurup.com) Oracle Port +-- +-- @cvs-id $Id: rss-unregister.sql,v 1.1 2002/10/08 15:47:13 rmello Exp $ +-- + +begin + + acs_sc_impl.delete( + impl_contract_name => 'RssGenerationSubscriber', + impl_name => 'pinds_blog_entries' + ); + +end; +/ +show errors Index: openacs.org-dev/packages/lars-blogger/sql/oracle/upgrade/upgrade-0.7d-0.8.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/sql/oracle/upgrade/upgrade-0.7d-0.8.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/sql/oracle/upgrade/upgrade-0.7d-0.8.sql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,11 @@ +-- +-- upgrade-0.7d-0.8.sql +-- +-- @author Lars Pind +-- +-- @cvs-id $Id: upgrade-0.7d-0.8.sql,v 1.1 2002/10/08 15:47:13 rmello Exp $ +-- + +-- added notifications + +@@ ../notifications-init Index: openacs.org-dev/packages/lars-blogger/sql/postgresql/lars-blogger-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/sql/postgresql/lars-blogger-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/sql/postgresql/lars-blogger-create.sql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,128 @@ +-- +-- lars-blogger-create.sql +-- +-- @author Lars Pind +-- +-- @cvs-id $Id: lars-blogger-create.sql,v 1.1 2002/10/08 15:47:13 rmello Exp $ +-- + +select acs_object_type__create_type ( + 'pinds_blog_entry', -- object_type + 'Blog Entry', -- pretty_name + 'Blog Entries', -- pretty_plural + 'acs_object', -- supertype + 'PINDS_BLOG_ENTRIES', -- table_name + 'ENTRY_ID', -- id_column + null, -- package_name + 'f', -- abstract_p + null, -- type_extension_table + 'PINDS_BLOG_ENTRY__TITLE' -- name_method +); + +create table pinds_blog_entries ( + entry_id integer + constraint pinds_blog_entry_id_fk + references acs_objects(object_id) + constraint pinds_blog_entries_pk + primary key, + package_id integer + constraint pinds_blog_entry_package_id_kf + references apm_packages(package_id), + title varchar(500), + content varchar(32000), + entry_date datetime, + posted_date datetime, + draft_p char(1) default 'f' + constraint pinds_blog_entries_draft_ck + check (draft_p in ('t','f')), + deleted_p char(1) default 'f' + constraint pinds_blog_entries_deleted_ck + check (deleted_p in ('t','f')) +); + +create index pinds_blog_entry_pck_entr_idx on pinds_blog_entries (package_id, entry_date); + +create function pinds_blog_entry__title (integer) +returns varchar as ' +declare + p_entry_id alias for $1; + v_title varchar; +begin + select title into v_title + from pinds_blog_entries + where entry_id = p_entry_id; + return v_title; +end; +' language 'plpgsql'; + + +create function pinds_blog_entry__new ( + integer, -- entry_id + integer, -- package_id + varchar, -- title + varchar, -- content + datetime, -- entry_date + char, -- draft_p + integer, -- creation_user + varchar -- creation_ip +) returns integer as ' +declare + p_entry_id alias for $1; + p_package_id alias for $2; + p_title alias for $3; + p_content alias for $4; + p_entry_date alias for $5; + p_draft_p alias for $6; + p_creation_user alias for $7; + p_creation_ip alias for $8; + v_entry_id integer; +begin + v_entry_id := acs_object__new ( + p_entry_id, + ''pinds_blog_entry'', + current_timestamp, + p_creation_user, + p_creation_ip, + p_package_id + ); + + insert into pinds_blog_entries ( + entry_id, + package_id, + title, + content, + entry_date, + posted_date, + draft_p, + deleted_p + ) values ( + v_entry_id, + p_package_id, + p_title, + p_content, + p_entry_date, + current_timestamp, + p_draft_p, + ''f'' + ); + + return v_entry_id; +end; +' language 'plpgsql'; + + +create function pinds_blog_entry__delete (integer) +returns integer as ' +declare + p_entry_id alias for $1; +begin + delete from pinds_blog_entries + where entry_id = p_entry_id; + PERFORM acs_object__delete(p_entry_id); + return 0; +end; +' language 'plpgsql'; + + +\i rss-register.sql +\i notifications-init.sql Index: openacs.org-dev/packages/lars-blogger/sql/postgresql/lars-blogger-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/sql/postgresql/lars-blogger-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/sql/postgresql/lars-blogger-drop.sql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,52 @@ +-- +-- lars-blogger-drop.sql +-- +-- @author Lars Pind +-- +-- @cvs-id $Id: lars-blogger-drop.sql,v 1.1 2002/10/08 15:47:13 rmello Exp $ +-- + +\i notifications-drop.sql +\i rss-unregister.sql + +create function inline_0 () +returns integer as ' +declare + comment_rec record; + entry_rec record; +begin + -- iterate through all comments on entries + for comment_rec in select gc.comment_id + from general_comments gc, + pinds_blog_entries e + where gc.object_id = e.entry_id loop + perform acs_message__delete(comment_rec.comment_id); + end loop; + + -- iterate through all entries + for entry_rec in select entry_id from pinds_blog_entries loop + perform pinds_blog_entry__delete( entry_rec.entry_id ); + end loop; + + return 0; +end;' language 'plpgsql'; + +select inline_0(); +drop function inline_0(); + + +drop function pinds_blog_entry__title (integer); +drop function pinds_blog_entry__new( + integer, -- entry_id + integer, -- package_id + varchar, -- title + varchar, -- content + datetime, -- entry_date + char, -- draft_p + integer, -- creation_user + varchar -- creation_ip +); +drop function pinds_blog_entry__delete (integer); + +drop table pinds_blog_entries; +select acs_object_type__drop_type ('pinds_blog_entry', true); Index: openacs.org-dev/packages/lars-blogger/sql/postgresql/notifications-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/sql/postgresql/notifications-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/sql/postgresql/notifications-drop.sql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,90 @@ +-- +-- +-- The Weblogger Package +-- +-- @author lars@pinds.com +-- @creation-date 2002-09-14 +-- + +-- drop integration with Notifications + +create function inline_0 () +returns integer as ' +declare + row record; +begin + for row in select nt.type_id + from notification_types nt + where nt.short_name in (''lars_blogger_notif_type'') + loop + perform notification_type__delete(row.type_id); + end loop; + + return null; +end;' language 'plpgsql'; + +select inline_0(); +drop function inline_0 (); + +-- +-- Service contract drop stuff was missing - Roberto Mello +-- + +create function inline_0() returns integer as ' +declare + impl_id integer; + v_foo integer; +begin + + -- the notification type impl + impl_id := acs_sc_impl__get_id ( + ''NotificationType'', -- impl_contract_name + ''lars_blogger_notif_type'' -- impl_name + ); + + PERFORM acs_sc_binding__delete ( + ''NotificationType'', + ''lars_blogger_notif_type'' + ); + + v_foo := acs_sc_impl_alias__delete ( + ''NotificationType'', -- impl_contract_name + ''lars_blogger_notif_type'', -- impl_name + ''GetURL'' -- impl_operation_name + ); + + v_foo := acs_sc_impl_alias__delete ( + ''NotificationType'', -- impl_contract_name + ''lars_blogger_notif_type'', -- impl_name + ''ProcessReply'' -- impl_operation_name + ); + + select into v_foo type_id + from notification_types + where sc_impl_id = impl_id + and short_name = ''lars_blogger_notif''; + + perform notification_type__delete (v_foo); + + delete from notification_types_intervals + where type_id = v_foo + and interval_id in ( + select interval_id + from notification_intervals + where name in (''instant'',''hourly'',''daily'') + ); + + delete from notification_types_del_methods + where type_id = v_foo + and delivery_method_id in ( + select delivery_method_id + from notification_delivery_methods + where short_name in (''email'') + ); + + return (0); +end; +' language 'plpgsql'; + +select inline_0(); +drop function inline_0(); Index: openacs.org-dev/packages/lars-blogger/sql/postgresql/notifications-init.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/sql/postgresql/notifications-init.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/sql/postgresql/notifications-init.sql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,71 @@ +-- +-- The Weblogger Package +-- +-- @author lars@pinds.com +-- @creation-date 2002-09-14 +-- + +-- the integration with Notifications + +create function inline_0() returns integer as ' +declare + impl_id integer; + v_foo integer; +begin + -- the notification type impl + impl_id := acs_sc_impl__new ( + ''NotificationType'', + ''lars_blogger_notif_type'', + ''lars-blogger'' + ); + + v_foo := acs_sc_impl_alias__new ( + ''NotificationType'', + ''lars_blogger_notif_type'', + ''GetURL'', + ''lars_blogger::notification::get_url'', + ''TCL'' + ); + + v_foo := acs_sc_impl_alias__new ( + ''NotificationType'', + ''lars_blogger_notif_type'', + ''ProcessReply'', + ''lars_blogger::notification::process_reply'', + ''TCL'' + ); + + PERFORM acs_sc_binding__new ( + ''NotificationType'', + ''lars_blogger_notif_type'' + ); + + v_foo:= notification_type__new ( + NULL, + impl_id, + ''lars_blogger_notif'', + ''Blog Notification'', + ''Notifications for Blog'', + now(), + NULL, + NULL, + NULL + ); + + -- enable the various intervals and delivery methods + insert into notification_types_intervals + (type_id, interval_id) + select v_foo, interval_id + from notification_intervals where name in (''instant'',''hourly'',''daily''); + + insert into notification_types_del_methods + (type_id, delivery_method_id) + select v_foo, delivery_method_id + from notification_delivery_methods where short_name in (''email''); + + return (0); +end; +' language 'plpgsql'; + +select inline_0(); +drop function inline_0(); \ No newline at end of file Index: openacs.org-dev/packages/lars-blogger/sql/postgresql/rss-register.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/sql/postgresql/rss-register.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/sql/postgresql/rss-register.sql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,29 @@ +-- +-- rss-register.sql +-- +-- @author Lars Pind +-- +-- @cvs-id $Id: rss-register.sql,v 1.1 2002/10/08 15:47:13 rmello Exp $ +-- + +select acs_sc_impl__new( + 'RssGenerationSubscriber', -- impl_contract_name + 'pinds_blog_entries', -- impl_name + 'lars-blogger' -- impl_owner_name +); + +select acs_sc_impl_alias__new( + 'RssGenerationSubscriber', -- impl_contract_name + 'pinds_blog_entries', -- impl_name + 'datasource', -- impl_operation_name + 'lars_blog__rss_datasource', -- impl_alias + 'TCL' -- impl_pl +); + +select acs_sc_impl_alias__new( + 'RssGenerationSubscriber', -- impl_contract_name + 'pinds_blog_entries', -- impl_name + 'lastUpdated', -- impl_operation_name + 'lars_blog__rss_lastUpdated', -- impl_alias + 'TCL' -- impl_pl +); Index: openacs.org-dev/packages/lars-blogger/sql/postgresql/rss-unregister.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/sql/postgresql/rss-unregister.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/sql/postgresql/rss-unregister.sql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,13 @@ +-- +-- rss-unregister.sql +-- +-- @author Lars Pind +-- +-- @cvs-id $Id: rss-unregister.sql,v 1.1 2002/10/08 15:47:13 rmello Exp $ +-- + +select acs_sc_impl__delete( + 'RssGenerationSubscriber', -- impl_contract_name + 'pinds_blog_entries' -- impl_name +); + Index: openacs.org-dev/packages/lars-blogger/sql/postgresql/upgrade/upgrade-0.6.4d-0.7d.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/sql/postgresql/upgrade/upgrade-0.6.4d-0.7d.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/sql/postgresql/upgrade/upgrade-0.6.4d-0.7d.sql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,27 @@ +-- +-- upgrade-0.6.4d-0.7d.sql +-- +-- @author Vinod Kurup (vinod@kurup.com) +-- +-- @cvs-id $Id: upgrade-0.6.4d-0.7d.sql,v 1.1 2002/10/08 15:47:13 rmello Exp $ +-- + +-- the only change is in the name of a proc that we send to +-- asc_sc_impl_alias. So, we just delete the old alias +-- and create a new one with the proper proc name (lars_blog...) + +select acs_sc_impl_alias__delete( + 'RssGenerationSubscriber', -- impl_contract_name + 'pinds_blog_entries', -- impl_name + 'lastUpdated' -- impl_operation_name +); + + +select acs_sc_impl_alias__new( + 'RssGenerationSubscriber', -- impl_contract_name + 'pinds_blog_entries', -- impl_name + 'lastUpdated', -- impl_operation_name + 'lars_blog__rss_lastUpdated', -- impl_alias + 'TCL' -- impl_pl +); + Index: openacs.org-dev/packages/lars-blogger/sql/postgresql/upgrade/upgrade-0.7d-0.8.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/sql/postgresql/upgrade/upgrade-0.7d-0.8.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/sql/postgresql/upgrade/upgrade-0.7d-0.8.sql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,11 @@ +-- +-- upgrade-0.7d-0.8.sql +-- +-- @author Lars Pind +-- +-- @cvs-id $Id: upgrade-0.7d-0.8.sql,v 1.1 2002/10/08 15:47:13 rmello Exp $ +-- + +-- added notifications + +\i ../notifications-init.sql Index: openacs.org-dev/packages/lars-blogger/tcl/entry-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/tcl/entry-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/tcl/entry-procs.tcl 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,46 @@ +ad_library { + Entry procs for blogger. +} + + +namespace eval lars_blogger::entry { + + ad_proc -public get { + -entry_id:required + -array:required + } { + # Select the info into the upvar'ed Tcl Array + upvar $array row + + db_1row select_entry { *SQL* } -column_array row + } + + + ad_proc -public do_notifications { + {-entry_id:required} + } { + # Select all the important information + get -entry_id $entry_id -array blog + + set blog_url "[ad_url][lars_blog_public_package_url -package_id $blog(package_id)]" + set entry_url "[ad_url][lars_blog_public_package_url -package_id $blog(package_id)]one-entry?[export_vars { entry_id }]" + set blog_name [lars_blog_name -package_id $blog(package_id)] + + set new_content "" + append new_content "$blog(poster_first_names) $blog(poster_last_name) posted to $blog_name at $blog(posted_time_pretty) on $blog(entry_date_pretty):\n\n" + append new_content "$blog(title)\n\n" + append new_content "[ad_convert_to_text -- [ns_adp_parse -string $blog(content)]]\n\n" + append new_content "This entry: $entry_url\n\n" + append new_content "$blog_name: $blog_url\n" + + # Do the notification for the forum + notification::new \ + -type_id [notification::type::get_type_id \ + -short_name lars_blogger_notif] \ + -object_id $blog(package_id) \ + -response_id $blog(entry_id) \ + -notif_subject $blog(title) \ + -notif_text $new_content + } + +} \ No newline at end of file Index: openacs.org-dev/packages/lars-blogger/tcl/entry-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/tcl/entry-procs.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/tcl/entry-procs.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,30 @@ +<?xml version="1.0"?> + +<queryset> + + <fullquery name="lars_blogger::entry::get.select_entry"> + <querytext> + select b.entry_id, + b.title, + b.content, + b.draft_p, + to_char(b.entry_date, 'YYYY-MM-DD') as entry_date, + to_char(b.entry_date, 'fmDayfm, Month fmDDfm, YYYY') as entry_date_pretty, + p.first_names as poster_first_names, + p.last_name as poster_last_name, + to_char(b.posted_date , 'HH24:MI') as posted_time_pretty, + b.package_id, + (select count(gc.comment_id) + from general_comments gc, cr_revisions cr + where gc.object_id = entry_id + and content_item__get_live_revision(gc.comment_id) = cr.revision_id) as num_comments + from pinds_blog_entries b, + acs_objects o, + persons p + where b.entry_id = :entry_id + and o.object_id = b.entry_id + and p.person_id = o.creation_user + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/tcl/lars-blogger-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/tcl/lars-blogger-procs-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/tcl/lars-blogger-procs-oracle.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,23 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + + <fullquery name="lars_blog_entry_add.entry_add"> + <querytext> + begin + :1 := pinds_blog_entry.new ( + entry_id => :entry_id, + package_id => :package_id, + title => :title, + content => :content, + entry_date => to_date(:entry_date, 'YYYY-MM-DD'), + draft_p => :draft_p, + creation_user => :creation_user, + creation_ip => :creation_ip + ); + end; + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/tcl/lars-blogger-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/tcl/lars-blogger-procs-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/tcl/lars-blogger-procs-postgresql.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,21 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + + <fullquery name="lars_blog_entry_add.entry_add"> + <querytext> + select pinds_blog_entry__new ( + :entry_id, + :package_id, + :title, + :content, + to_date(:entry_date, 'YYYY-MM-DD'), + :draft_p, + :creation_user, + :creation_ip + ) + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/tcl/lars-blogger-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/tcl/lars-blogger-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/tcl/lars-blogger-procs.tcl 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,97 @@ +ad_library { + Procs used by the blogger module. + @author Lars Pind (lars@pinds.com) + @creation-date 2002 + @cvs-id $Id: lars-blogger-procs.tcl,v 1.1 2002/10/08 15:47:13 rmello Exp $ +} + +ad_proc -public lars_blog_entry_add { + {-entry_id:required} + {-package_id:required} + {-title:required} + {-content:required} + {-entry_date:required} + {-draft_p:required} +} { + Add the blog entry and then flush the cache so that the new entry shows up. +} { + set creation_user [ad_conn user_id] + set creation_ip [ns_conn peeraddr] + + set entry_id [db_exec_plsql entry_add { *SQL* }] + + lars_blog_flush_cache $package_id + + return $entry_id +} + + + +ad_proc -private lars_blog_get_as_string_mem { + package_id + admin_p +} { + return [template::adp_parse "[acs_package_root_dir "lars-blogger"]/www/blog" [list package_id $package_id]] +} + + +ad_proc -public lars_blog_get_as_string { + -package_id + -url +} { + if { ![exists_and_not_null package_id] } { + array set blog_site_node [site_node $url] + set package_id $blog_site_node(object_id) + } + set admin_p [ad_permission_p $package_id admin] + return [util_memoize "lars_blog_get_as_string_mem $package_id $admin_p" 600] +} + +ad_proc lars_blog_flush_cache { + {package_id ""} +} { + if { [empty_string_p $package_id] } { + set package_id [ad_conn package_id] + } + # Flush both admin and non-admin version + util_memoize_flush "lars_blog_get_as_string_mem $package_id 0" + util_memoize_flush "lars_blog_get_as_string_mem $package_id 1" +} + +ad_proc -public lars_blog_public_package_url { + -package_id +} { + if { ![exists_and_not_null package_id] } { + # No package_id given, so we'll just use ad_conn + set package_id [ad_conn package_id] + set default_url [ad_conn package_url] + } else { + if { [catch { + # This will fail if the package has been mounted on more than one URL ... hm. + set default_url [apm_package_url_from_id $package_id] + }] } { + # In that case, we'll just hope that they set up the parameter + set default_url "" + } + } + return [ad_parameter -package_id $package_id "public_url" "lars-blogger" $default_url] +} + +ad_proc -public lars_blog_name { + -package_id +} { + if { ![exists_and_not_null package_id] } { + set package_id [ad_conn package_id] + } + array set site_node [site_node::get_from_object_id -object_id $package_id] + return $site_node(instance_name) +} + +ad_proc -public lars_blog_header_background_color { + -package_id +} { + if { ![exists_and_not_null package_id] } { + set package_id [ad_conn package_id] + } + return [ad_parameter -package_id $package_id "HeaderBackgroundColor" "lars-blogger" "#dcdcdc"] +} Index: openacs.org-dev/packages/lars-blogger/tcl/rss-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/tcl/rss-procs-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/tcl/rss-procs-oracle.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,43 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + + <fullquery name="lars_blog__rss_datasource.now"> + <querytext> + select to_char(sysdate,'DD Mon YYYY hh12:MI am') + </querytext> + </fullquery> + + <fullquery name="lars_blog__rss_datasource.blog_rss_items"> + <querytext> + select * + from (select entry_id, + title, + content, + entry_date, + posted_date, + to_char(posted_date, 'YYYY-MM-DD') as posted_date_string, + to_char(posted_date, 'HH:MI') as posted_time_string, + to_char(entry_date, 'DD Mon YYYY hh12:MI am') as entry_date_pretty, + to_char(entry_date, 'YYYY/MM/') as entry_archive_url + from pinds_blog_entries + where package_id = :package_id + and draft_p = 'f' + and deleted_p = 'f' + order by entry_date desc, posted_date desc) + where rownum < 11 + </querytext> + </fullquery> + + <fullquery name="lars_blog__rss_lastUpdated.get_last_update"> + <querytext> + select nvl ((max(posted_date)-to_date('1970-01-01'))*60*60*24,0) as last_update + from pinds_blog_entries + where package_id = :package_id + and draft_p = 'f' + and deleted_p = 'f' + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/tcl/rss-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/tcl/rss-procs-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/tcl/rss-procs-postgresql.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,42 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + + <fullquery name="lars_blog__rss_datasource.now"> + <querytext> + select to_char(current_timestamp,'DD Mon YYYY hh12:MI am') + </querytext> + </fullquery> + + <fullquery name="lars_blog__rss_datasource.blog_rss_items"> + <querytext> + select entry_id, + title, + content, + entry_date, + posted_date, + to_char(posted_date, 'YYYY-MM-DD') as posted_date_string, + to_char(posted_date, 'HH:MI') as posted_time_string, + to_char(entry_date, 'DD Mon YYYY hh12:MI am') as entry_date_pretty, + to_char(entry_date, 'YYYY/MM/') as entry_archive_url + from pinds_blog_entries + where package_id = :package_id + and draft_p = 'f' + and deleted_p = 'f' + order by entry_date desc, posted_date desc + limit 10 + </querytext> + </fullquery> + + <fullquery name="lars_blog__rss_lastUpdated.get_last_update"> + <querytext> + select coalesce (date_part('epoch',max(posted_date)),0) as last_update + from pinds_blog_entries + where package_id = :package_id + and draft_p = 'f' + and deleted_p = 'f' + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/tcl/rss-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/tcl/rss-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/tcl/rss-procs.tcl 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,96 @@ +ad_library { + Procs used by the to set up the rss service contract for the blogger module. + @author Lars Pind + @creation-date + @cvs-id $Id: rss-procs.tcl,v 1.1 2002/10/08 15:47:13 rmello Exp $ +} + +ad_proc -private lars_blog__rss_datasource { + package_id +} { + This procedure implements the "datasource" operation of the + RssGenerationSubscriber service contract. + + @author Lars Pind (lars@pinds.com) +} { + set package_url [lars_blog_public_package_url -package_id $package_id] + + set blog_title [db_string package_name { *SQL* }] + + set blog_url "[ad_url]$package_url" + + set column_array(channel_title) $blog_title + set column_array(channel_description) $blog_title + set column_array(channel_pubDate) [db_string now { *SQL* }] + + set column_array(version) 1.00 + + set column_array(channel_link) $blog_url + + set image_url [ad_parameter -package_id $package_id "channel_image_url"] + if { [empty_string_p $image_url] } { + set column_array(image) "" + } else { + set column_array(image) [list \ + url "[ad_url]$image_url" \ + title $blog_title \ + link $blog_url \ + width [ad_parameter -package_id $package_id "channel_image_width"] \ + height [ad_parameter -package_id $package_id "channel_image_height"]] + } + + set items [list] + set counter 0 + + db_foreach blog_rss_items { *SQL* } { + set entry_url "[ad_url]${package_url}archive/${entry_archive_url}#blog-entry-$entry_id" + + set content [ns_adp_parse -string $content] + + regsub -all {<[^>]*>} $content {} content_as_text + + set truncate_len 100 + if { [string length $content_as_text] > $truncate_len } { + set description "[string range $content_as_text 0 [expr {$truncate_len-3}]]..." + } else { + set description $content_as_text + } + + lappend items [list link $entry_url title $title description $description value $content timestamp "${posted_date_string}T${posted_time_string}-0600"] + if { $counter == 0 } { + set column_array(channel_lastBuildDate) $entry_date_pretty + incr counter + } + } + set column_array(items) $items + set column_array(channel_language) "" + set column_array(channel_copyright) "" + set column_array(channel_managingEditor) "" + set column_array(channel_webMaster) "" + set column_array(channel_rating) "" + set column_array(channel_skipDays) "" + set column_array(channel_skipHours) "" + + return [array get column_array] +} + +ad_proc -private lars_blog__rss_lastUpdated { + package_id +} { + Returns the time that the last blog entry was posted, + in Unix time. Returns 0 otherwise. + + @author Lars Pind (lars@pinds.com) +} { + db_0or1row get_last_update { + select coalesce (date_part('epoch',max(posted_date)),0) as last_update + from pinds_blog_entries + where package_id = :package_id + and draft_p = 'f' + and deleted_p = 'f' + } + + return $last_update +} + + Index: openacs.org-dev/packages/lars-blogger/tcl/rss-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/tcl/rss-procs.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/tcl/rss-procs.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,11 @@ +<?xml version="1.0"?> + +<queryset> + + <fullquery name="lars_blog__rss_datasource.package_name"> + <querytext> + select instance_name from apm_packages where package_id = :package_id + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/tcl/weblogs-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/tcl/weblogs-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/tcl/weblogs-procs.tcl 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,117 @@ +ad_library { + Weblog support routines + + @author Lars Pind (lars@pinds.com) + @creation-date 2002 + @cvs-id $Id: weblogs-procs.tcl,v 1.1 2002/10/08 15:47:13 rmello Exp $ +} + +ad_proc -private lars_blog_weblogs_com_update_ping { + {-package_id ""} + {-location} + {-timeout 30} + {-depth 0} +} { + Sends the xml/rpc message weblogUpldates.ping to weblogs.com + returns 1 if successful and logs the result. + @author Jerry Asher (jerry@theashergroup.com) + @author Lars Pind (lars@pinds.com) +} { + set package_url [lars_blog_public_package_url -package_id $package_id] + + if { ![exists_and_not_null package_id] } { + set package_id [ad_conn package_id] + } + + # Should we ping? + set ping_p [ad_parameter -package_id $package_id "weblogs_update_ping_p" "lars-blogger" 0] + if { !$ping_p } { + return + } + + if { ![info exists location] } { + set location [ad_parameter -package_id $package_id "weblogs_ping_url"] + } + if { [empty_string_p $location] } { + ns_log Error "lars_blog_weblogs_com_update_ping: No URL to ping" + return + } + + set blog_title [db_string package_name { *SQL* }] + + set blog_url "[ad_url]$package_url" + + ns_log notice "lars_blog_weblogs_com_update_ping:" + if [catch { + if {[incr depth] > 10} { + return -code error "rss_weblogUpdatesping: Recursive redirection: $location" + } + set req_hdrs [ns_set create] + + set message "<?xml version=\"1.0\"?> +<methodCall> + <methodName>weblogUpdates.ping</methodName> + <params> + <param> + <value>[ad_quotehtml $blog_title]</value> + </param> + <param> + <value>[ad_quotehtml $blog_url]</value> + </param> + </params> +</methodCall>" + + # headers necesary for a post and the form variables + ns_set put $req_hdrs "Content-type" "text/xml" + ns_set put $req_hdrs "Content-length" [string length $message] + set http [ns_httpopen POST $location $req_hdrs 30 $message] + set rfd [lindex $http 0] + set wfd [lindex $http 1] + set rpset [lindex $http 2] + + flush $wfd + close $wfd + + ns_log notice "lars_blog_weblogs_com_update_ping: pinging for blog $blog_title and url $blog_url" + ns_log notice message: \"$message\" + + set headers $rpset + set response [ns_set name $headers] + set status [lindex $response 1] +if {$status == 302} { + set location [ns_set iget $headers location] + if {$location != ""} { + ns_set free $headers + close $rfd + return [lars_blog_weblogs_com_update_ping -package_id $package_id -location $location -timeout $timeout -depth $depth] + } +} + set length [ns_set iget $headers content-length] +if [string match "" $length] {set length -1} + set err [catch { + while 1 { + set buf [_ns_http_read $timeout $rfd $length] + append page $buf + if [string match "" $buf] break + if {$length > 0} { + incr length -[string length $buf] + if {$length <= 0} break + } + } + } errMsg] + ns_set free $headers + close $rfd + if $err { + global errorInfo + return -code error -errorinfo $errorInfo $errMsg + } + } errmsg ] { + ns_log error "lars_blog_weblogs_com_update_ping error: $errmsg" + return -1 + } else { + ns_log notice "lars_blog_weblogs_com_update_ping: $page" + return 1 + } +} + + Index: openacs.org-dev/packages/lars-blogger/tcl/weblogs-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/tcl/weblogs-procs.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/tcl/weblogs-procs.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,12 @@ +<?xml version="1.0"?> + +<queryset> + + <fullquery name="lars_blog_weblogs_com_update_ping.package_name"> + <querytext> + select instance_name from apm_packages + where package_id = :package_id + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/www/blog-months-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/blog-months-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/blog-months-oracle.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,21 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + + <fullquery name="months"> + <querytext> + select trunc(entry_date, 'month') as month_date, + to_char(trunc(entry_date, 'month'), 'fmMonthfm YYYY') + as date_pretty, + to_char(trunc(entry_date, 'month'), 'YYYY/MM/') + as month_url_stub + from pinds_blog_entries + where draft_p = 'f' + and package_id = :package_id + group by trunc(entry_date, 'month') + order by month_date desc + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/www/blog-months-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/blog-months-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/blog-months-postgresql.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,21 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + + <fullquery name="months"> + <querytext> + select date_trunc('month', entry_date) as month_date, + to_char(date_trunc('month', entry_date), 'fmMonthfm YYYY') + as date_pretty, + to_char(date_trunc('month', entry_date), 'YYYY/MM/') + as month_url_stub + from pinds_blog_entries + where draft_p = 'f' + and package_id = :package_id + group by month_date + order by month_date desc + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/www/blog-months.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/blog-months.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/blog-months.adp 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,5 @@ +<if @months:rowcount@ gt 0> + <multiple name="months"> + <a href="@months.url@" title="View archive for @months.date_pretty@">@months.date_pretty@</a><br> + </multiple> +</if> \ No newline at end of file Index: openacs.org-dev/packages/lars-blogger/www/blog-months.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/blog-months.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/blog-months.tcl 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,7 @@ +set package_id [ad_conn package_id] + +db_multirow -extend { url } months months { *SQL* } { + set url "[ad_conn package_url]archive/$month_url_stub" +} + +ad_return_template \ No newline at end of file Index: openacs.org-dev/packages/lars-blogger/www/blog-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/blog-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/blog-oracle.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,56 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + + <partialquery name="date_clause_archive"> + <querytext> + trunc(entry_date, :archive_interval) = :archive_date + </querytext> + </partialquery> + + <partialquery name="date_clause_default"> + <querytext> + entry_date > sysdate - 30 + </querytext> + </partialquery> + + <fullquery name="blog"> + <querytext> + select entry_id, + to_char(entry_date, 'fmDayfm, Month fmDDfm, YYYY') as entry_date_pretty, + to_char(entry_date, 'YYYY/MM/DD/') as entry_archive_url, + entry_date, + title, + content, + draft_p, + 'f' as new_date_p, + p.first_names as poster_first_names, + p.last_name as poster_last_name, + to_char(posted_date , 'HH24:MI') as posted_time_pretty, + (select count(gc.comment_id) + from general_comments gc, cr_revisions cr + where gc.object_id = entry_id + and content_item.get_live_revision(gc.comment_id) = cr.revision_id) as num_comments, + 0 as row_number, + '' as edit_url, + '' as delete_url, + '' as publish_url, + '' as revoke_url, + '' as comments_view_url, + '' as comment_add_url, + '' as google_url + from pinds_blog_entries e, + acs_objects o, + persons p + where e.entry_id = o.object_id + and p.person_id = o.creation_user + and package_id = :package_id + and $date_clause + and draft_p = 'f' + and deleted_p = 'f' + order by entry_date desc, posted_date desc + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/www/blog-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/blog-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/blog-postgresql.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,45 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + + <partialquery name="date_clause_archive"> + <querytext> + date_trunc(:archive_interval, entry_date) = :archive_date + </querytext> + </partialquery> + + <partialquery name="date_clause_default"> + <querytext> + entry_date > current_timestamp - interval '30 days' + </querytext> + </partialquery> + + <fullquery name="blog"> + <querytext> + select entry_id, + to_char(entry_date, 'fmDayfm, Month fmDDfm, YYYY') as entry_date_pretty, + to_char(entry_date, 'YYYY/MM/DD/') as entry_archive_url, + entry_date, + title, + content, + draft_p, + p.first_names as poster_first_names, + p.last_name as poster_last_name, + to_char(posted_date , 'HH24:MI') as posted_time_pretty, + (select count(gc.comment_id) + from general_comments gc, cr_revisions cr + where gc.object_id = entry_id + and content_item__get_live_revision(gc.comment_id) = cr.revision_id) as num_comments + from pinds_blog_entries e join + acs_objects o on (o.object_id = e.entry_id) join + persons p on (p.person_id = o.creation_user) + where package_id = :package_id + and $date_clause + and draft_p = 'f' + and deleted_p = 'f' + order by entry_date desc, posted_date desc + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/www/blog.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/blog.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/blog.adp 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,41 @@ +<multiple name="blog"> + <table cellspacing="0" cellpadding="2" border="0" width="100%"> + <tr> + <th bgcolor="@header_background_color@" align="left"> + <b><a name="blog-date-@blog.entry_date@"><font size="-1">@blog.entry_date_pretty@</font></a></b> + </th> + <if @blog.rownum@ eq 1> + <th bgcolor="@header_background_color@" align="right"> + <font size="-1"> + <if @admin_p@ eq 1> + <a href="@entry_add_url@" title="Add an entry to @blog_name@">+</a> + </if> + <if @blog_url@ not nil> + <a href="@blog_url@" title="Visit @blog_name@ home">@blog_name@</a> + </if> + </font> + </th> + </if> + </tr> + </table> + <group column="entry_date"> + <div style="border-bottom:1px dashed #3366cc;"> + <include src="entry-chunk" &="blog" package_id="@package_id@"> + </div> + </group> +</multiple> + +<p> + <if @blog_url@ not nil> + <a href="@blog_url@"><img src="@arrow_url@" width="11" height="11" border="0" alt="Visit @blog_name@ home" title="Visit @blog_name@ home"></a> + <a href="@blog_url@" title="Visit @blog_name@ home" class="action_link">@blog_name@</a><br> + </if> + + <a href="@archive_url@"><img src="@arrow_url@" width="11" height="11" border="0" alt="Visit the archive for @blog_name@" title="Visit the archive for @blog_name@"></a> + <a href="@archive_url@" title="Visit the archive for @blog_name@" class="action_link">Archive</a><br> + + <if @admin_p@ eq 1> + <a href="@entry_add_url@"><img src="@arrow_url@" width="11" height="11" border="0" alt="Add an entry to @blog_name@" title="Add an entry to @blog_name@"></a> + <a href="@entry_add_url@" title="Add an entry to @blog_name@" class="action_link">Add entry</a> + </if> +</p> \ No newline at end of file Index: openacs.org-dev/packages/lars-blogger/www/blog.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/blog.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/blog.tcl 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,57 @@ +# Expects: +# package_id:optional +# url:optional +# type:optional (current, archive) +# archive_interval:optional +# archive_date:optional + +# If the caller specified a URL, then we gather the package_id from that URL +if { [info exists url] } { + array set blog_site_node [site_node $url] + set package_id $blog_site_node(object_id) +} + +# If they supplied neither url nor package_id, then we just use ad_conn package_id +if { ![info exists package_id] } { + set package_id [ad_conn package_id] +} + +if { ![info exists type] } { + set type "current" +} + +switch -exact $type { + archive { + set date_clause "[db_map date_clause_archive]" + } + default { + set date_clause "[db_map date_clause_default]" + } +} + +set show_poster_p [ad_parameter "ShowPosterP" "" "1"] + +set package_url [lars_blog_public_package_url -package_id $package_id] + +set blog_name [lars_blog_name -package_id $package_id] + +if { [ad_conn isconnected] && ![string equal $package_url [string range [ad_conn url] 0 [string length $package_url]]] } { + set blog_url $package_url +} else { + set blog_url {} +} + +set admin_p [ad_permission_p $package_id admin] + +set count 0 + +db_multirow blog blog { *SQL* } + +set archive_url "${package_url}archive/" +set arrow_url "${package_url}graphics/arrow-box.gif" + +set entry_add_url "${package_url}admin/entry-edit" + +set header_background_color [lars_blog_header_background_color] + +ad_return_template Index: openacs.org-dev/packages/lars-blogger/www/calendar.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/calendar.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/calendar.adp 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,6 @@ +@widget@ +<p> +<a href="@prev_month_url@" title="View archive for @prev_month_name@">@prev_month_name@</a> - +<a href="@next_month_url@" title="View archive for @next_month_name@">@next_month_name@</a> + + Index: openacs.org-dev/packages/lars-blogger/www/calendar.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/calendar.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/calendar.tcl 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,36 @@ +# +# Expects: +# date:onevalue,optional +# + +if { ![info exist date] } { + set date [dt_sysdate] +} + +dt_get_info $date + +# first_julian_date +# last_julian_date + +set calendar_details [ns_set create calendar_details] + +set package_url [lars_blog_public_package_url] +set month_number [clock format [clock scan $date] -format %m] + +set package_id [ad_conn package_id] + +db_foreach entry_dates { * SQL * } { + ns_set put $calendar_details $entry_date_julian "1" +} + +set widget [dt_widget_month_small \ + -date $date \ + -calendar_details $calendar_details \ + -day_number_template "\[ad_decode \[ns_set get \$calendar_details \$julian_date\] 1 \"<a href=\\\"${package_url}archive/\$year/$month_number/\[format \"%02d\" \$day_number\]/\\\" title=\\\"View the entries for this date\\\"><b>\$day_number</b></a>\" \$day_number\]"] + +set prev_month_url "${package_url}archive/[clock format [clock scan $prev_month] -format %Y/%m]/" +set next_month_url "${package_url}archive/[clock format [clock scan $next_month] -format %Y/%m]/" + +# Add year to the link +append next_month_name " [string range $next_month 0 3]" +append prev_month_name " [string range $prev_month 0 3]" Index: openacs.org-dev/packages/lars-blogger/www/calendar.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/calendar.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/calendar.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,14 @@ +<?xml version="1.0"?> + +<queryset> + <fullquery name="entry_dates"> + <querytext> + select to_char(entry_date, 'J') as entry_date_julian + from pinds_blog_entries + where package_id = :package_id + and draft_p = 'f' + and deleted_p = 'f' + group by entry_date_julian + </querytext> + </fullquery> +</queryset> Index: openacs.org-dev/packages/lars-blogger/www/entry-chunk.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/entry-chunk.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/entry-chunk.adp 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,52 @@ +<if @blog.title@ not nil> + <h4>@blog.title@</h4> +</if> +<p> + @blog.content@ + <br> + <table cellpadding="0" cellspacing="0" border="0" width="100%"> + <if @show_poster_p@ true> + <tr> + <td> + <font size="-2" color="#999999"> + <br> + Posted by @blog.poster_first_names@ @blog.poster_last_name@ at @blog.posted_time_pretty@ + <if @admin_p@ eq 1> + + <a href="@blog.edit_url@">Edit</a> - + <if @blog.draft_p@ true> + <a href="@blog.publish_url@">Publish</a> + </if> + <else> + <a href="@blog.revoke_url@">Draft</a> + </else> + </if> + </font> + </td> + </tr> + </if> + <tr> + <td align="right"> + <a href="@blog.entry_archive_url@" title="Permanent URL for this entry">#</a> - + <a href="@blog.google_url@" title="Search for @blog.title@ on Google">G</a> - + <if @comments_html@ nil> + <if @blog.comments_view_url@ not nil> + <if @blog.num_comments@ gt 0> + <a href="@blog.comments_view_url@" title="View comments on this entry">@blog.num_comments@ <if @blog.num_comments@ eq 1>comment</if><else>comments</else></a> - + </if> + </if> + </if> + <a href="@blog.comment_add_url@" title="Comment on this entry">Add comment</a> + </td> + </tr> + </table> +</p> + +<if @comments_html@ not nil> + <table align=center width="50%"><tr><td><hr></td></tr></table> + <h4>Comments</h4> + <blockquote> + @comments_html@ + </blockquote> + <center><a href="@blog.comment_add_url@" title="Comment on this entry">Add comment</a></center> +</if> Index: openacs.org-dev/packages/lars-blogger/www/entry-chunk.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/entry-chunk.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/entry-chunk.tcl 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,46 @@ +# Expects: +# blog:onerow +# show_comments_p:onevalue,optional +# retrun_url:onevalue,optional +# package_id:optional + +if { ![exists_and_not_null show_comments_p] } { + set show_comments_p "f" +} + +# Maybe package_id is supplied, but maybe not +if { ![info exists package_id] } { + set package_id [ad_conn package_id] +} + +set admin_p [ad_permission_p $package_id admin] + +if { ![exists_and_not_null return_url] } { + set return_url "[ad_conn url]?[ad_conn query]" +} + +set package_url [lars_blog_public_package_url -package_id $package_id] + +set show_poster_p [ad_parameter "ShowPosterP" "" "1"] + +set blog(title) [ad_quotehtml $blog(title)] +set blog(content) [ns_adp_parse -string $blog(content)] + +set entry_id $blog(entry_id) + +set blog(edit_url) "${package_url}admin/entry-edit?[export_vars { entry_id return_url }]" +set blog(delete_url) "${package_url}admin/entry-delete?[export_vars { entry_id return_url }]" + +set blog(publish_url) "${package_url}admin/entry-publish?[export_vars { entry_id return_url }]" +set blog(revoke_url) "${package_url}admin/entry-revoke?[export_vars { entry_id return_url }]" + +set blog(entry_archive_url) "${package_url}one-entry?[export_vars { entry_id }]" +set blog(google_url) "http://www.google.com/search?[export_vars { {q $blog(title) } }]" +set blog(comment_add_url) "[general_comments_package_url]comment-add?[export_vars { { object_id $entry_id } { object_name $blog(title) } { return_url "${package_url}flush-cache?[export_vars { return_url }]"} }]" +set blog(comments_view_url) "${package_url}one-entry?[export_vars { entry_id }]" + +if { [string equal $show_comments_p "t"] } { + set comments_html [general_comments_get_comments -print_content_p 1 $entry_id] +} + +ad_return_template \ No newline at end of file Index: openacs.org-dev/packages/lars-blogger/www/flush-cache.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/flush-cache.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/flush-cache.tcl 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,11 @@ +ad_page_contract { + Flush the blog cache. +} { + {return_url .} +} + +lars_blog_flush_cache [ad_conn package_id] + +ad_returnredirect $return_url + + Index: openacs.org-dev/packages/lars-blogger/www/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/index.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/index.adp 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,104 @@ +<master> +<property name="title">@page_title@</property> +<if @rss_file_url@ not nil> + <property name="header_stuff"> + <link rel="alternate" type="application/rss+xml" title="RSS" target=_test href="@rss_file_url@" /> + </property> +</if> +<property name="context_bar">@context_bar@</property> + +<table width="100%"> + <tr> + <td valign="top"> + <include src="blog" type="@type@" archive_interval="@interval@" archive_date="@archive_date@"> + </td> + <td valign="top"> + + <table width="100%" cellspacing="0" cellpadding="2"> + <tr> + <th bgcolor="@header_background_color@"> + Calendar + </th> + </tr> + <tr> + <td nowrap align="center"> + <include src="calendar" date="@date@"> + </td> + </tr> + <tr> + <td height="16"> + <table><tr><td></td></tr></table> + </td> + </tr> + + <if @admin_p@ true> + <tr> + <th bgcolor="@header_background_color@"> + Actions + </th> + </tr> + <tr> + <td align="center"> + <a href="admin/entry-edit" title="Add an entry to this blog">Add entry</a><br> + <a href="admin/drafts" title="View draft entries">Draft entries<a/> + </td> + </tr> + <tr> + <td height="16"> + <table><tr><td></td></tr></table> + </td> + </tr> + </if> + + <tr> + <th bgcolor="@header_background_color@"> + Notifications + </th> + </tr> + <tr> + <td align="center"> + @notification_chunk@ + </td> + </tr> + <tr> + <td height="16"> + <table><tr><td></td></tr></table> + </td> + </tr> + + <include-optional src="blog-months"> + <tr> + <th bgcolor="@header_background_color@"> + Archive + </th> + </tr> + <tr> + <td nowrap align="center"> + <include-output> + </td> + </tr> + <tr> + <td height="16"> + <table><tr><td></td></tr></table> + </td> + </tr> + </include-optional> + + <if @rss_file_url@ not nil> + <tr> + <th bgcolor="@header_background_color@" nowrap> + Syndication Feed + </th> + </tr> + <tr> + <td nowrap> + <a href="@rss_file_url@" title="Link to the RSS feed">RSS 1.0/RDF/XML</a> + </td> + </tr> + </if> + </table> + + </td> + </tr> +</table> + Index: openacs.org-dev/packages/lars-blogger/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/index.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/index.tcl 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,61 @@ +ad_page_contract { + The Weblogger index page. + + @author Lars Pind (lars@pinds.com) + @creation-date February 2002 +} { + year:optional,string_length_range(4|4) + month:optional,string_length_range(2|2) + day:optional,string_length_range(2|2) +} -properties { + context_bar + page_title +} + +set context_bar [ad_context_bar] + +set page_title [lars_blog_name] + +if { ![empty_string_p [ad_parameter "rss_file_url"]] } { + set rss_file_url "[ad_url][ad_parameter "rss_file_url"]" +} + +set admin_p [ad_permission_p [ad_conn package_id] admin] + +set notification_chunk [notification::display::request_widget \ + -type lars_blogger_notif \ + -object_id [ad_conn package_id] \ + -pretty_name [lars_blog_name] \ + -url [lars_blog_public_package_url] \ +] + +set header_background_color [lars_blog_header_background_color] + +if { [exists_and_not_null year] } { + if { ![exists_and_not_null month] } { + ad_return_complaint 1 "<li>You must specify both year and month." + ad_script_abort + } + + if { [exists_and_not_null day] } { + set interval "day" + db_1row archive_date_month_day { *SQL* } + set context_bar [ad_context_bar [list "[ad_conn package_url]archive/" "Archive"] [list "[ad_conn package_url]archive/$year/$month/" $archive_month_pretty] $archive_date_pretty] + } else { + set interval "month" + db_1row archive_date_month { *SQL* } + set context_bar [ad_context_bar [list "[ad_conn package_url]archive/" "Archive"] $archive_date_pretty] + } + + append page_title " Archive" + set date "$year-$month-[ad_decode $day "" "01" $day]" + set type "archive" + +} else { + set date "" + set type "current" + set interval "" + set archive_date "" +} + +ad_return_template \ No newline at end of file Index: openacs.org-dev/packages/lars-blogger/www/index.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/index.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/index.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,27 @@ +<?xml version="1.0"?> + +<queryset> + + <fullquery name="archive_date_month"> + <querytext> + select to_date(:year || :month, 'YYYYMM') + as archive_date, + to_char(to_date(:year || :month, 'YYYYMM'), 'fmMonthfm YYYY') + as archive_date_pretty + from dual + </querytext> + </fullquery> + + <fullquery name="archive_date_month_day"> + <querytext> + select to_date(:year || :month || :day, 'YYYYMMDD') + as archive_date, + to_char(to_date(:year || :month || :day, 'YYYYMMDD'), 'fmMonthfm YYYY') + as archive_month_pretty, + to_char(to_date(:year || :month || :day, 'YYYYMMDD'), 'DD') + as archive_date_pretty + from dual + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/www/one-entry.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/one-entry.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/one-entry.adp 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,13 @@ +<master> +<property name="title">@page_title@</property> +<property name="context_bar">@context_bar@</property> + +<table cellspacing="0" cellpadding="2" border="0" width="100%"> + <tr> + <th bgcolor="@header_background_color@" align=left> + <b><a name="blog-date-@blog.entry_date@">@blog.entry_date_pretty@</a></b> + </th> + </tr> +</table> + +<include src="entry-chunk" &="blog" show_comments_p="t"> \ No newline at end of file Index: openacs.org-dev/packages/lars-blogger/www/one-entry.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/one-entry.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/one-entry.tcl 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,32 @@ +ad_page_contract {} { + entry_id:integer + {return_url ""} +} -properties { + context_bar + title_html + content_html + draft_p_checked + entry_date_html + form_export_vars + return_url +} + +set package_id [ad_conn package_id] + +set admin_p [ad_permission_p $package_id admin] + +if { [empty_string_p $return_url] } { + set return_url "[ad_conn url]?[ad_conn query]" +} + +set show_poster_p [ad_parameter "ShowPosterP" "" "1"] + +lars_blogger::entry::get -entry_id $entry_id -array blog + +set page_title $blog(title) + +set context_bar [ad_context_bar $page_title] + +set header_background_color [lars_blog_header_background_color] + +ad_return_template \ No newline at end of file Index: openacs.org-dev/packages/lars-blogger/www/admin/drafts.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/admin/drafts.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/admin/drafts.adp 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,41 @@ +<master> +<property name="title">@page_title@</property> +<property name="context_bar">@context_bar@</property> + +<if @draft_entries:rowcount@ eq 0> + <i>No draft entries.</i> +</if> +<else> + <table cellspacing=0 cellpadding=0 border=0> + <tr> + <td bgcolor="#cccccc"> + <table cellspacing=1 cellpadding=2 border=0 width="100%"> + <tr bgcolor="@header_background_color@"> + <th>Date</th> + <th>Title</th> + <th>Content</th> + <th>Action</th> + </tr> + <multiple name="draft_entries"> + <tr bgcolor="#eeeeee"> + <td>@draft_entries.entry_date_pretty@</td> + <td>@draft_entries.title@</td> + <td>@draft_entries.content@</td> + <td align="center"> + <a href="@draft_entries.preview_url@">Preview</a> + <a href="@draft_entries.publish_url@">Publish</a> + <a href="@draft_entries.edit_url@">Edit</a> + <a href="@draft_entries.delete_url@">Delete</a> + </td> + </tr> + </multiple> + </table> + </td> + </tr> + </table> +</else> + +<p> + <a href="@entry_add_url@"><img src="@arrow_url@" width="11" height="11" border="0" alt="Add entry"></a> + <a href="@entry_add_url@" class="action_link">Add entry</a> +</p> Index: openacs.org-dev/packages/lars-blogger/www/admin/drafts.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/admin/drafts.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/admin/drafts.tcl 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,30 @@ +ad_page_contract {} { +} -properties { + context_bar +} + +set package_id [ad_conn package_id] + +set admin_p [ad_require_permission $package_id admin] + +set page_title "Draft Entries" + +set context_bar [ad_context_bar $page_title] + +db_multirow -extend { edit_url publish_url delete_url preview_url } draft_entries draft_entries { *SQL* } { + set return_url "[ad_conn url][ad_decode [ad_conn query] "" "" "?[ad_conn query]"]" + set edit_url "[ad_conn package_url]admin/entry-edit?[export_vars { entry_id return_url }]" + set delete_url "[ad_conn package_url]admin/entry-delete?[export_vars { entry_id return_url }]" + set preview_url "[ad_conn package_url]one-entry?[export_vars { entry_id return_url }]" + set publish_url "[ad_conn package_url]admin/entry-publish?[export_vars { entry_id return_url }]" + set content [ns_adp_parse -string $content] +} + +set entry_add_url "entry-edit" + +set arrow_url "[ad_conn package_url]graphics/arrow-box.gif" + +set header_background_color [lars_blog_header_background_color] + +ad_return_template + Index: openacs.org-dev/packages/lars-blogger/www/admin/drafts.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/admin/drafts.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/admin/drafts.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,19 @@ +<?xml version="1.0"?> + +<queryset> + + <fullquery name="draft_entries"> + <querytext> + select entry_id, + to_char(entry_date, 'YYYY-MM-DD') as entry_date_pretty, + title, + content + from pinds_blog_entries + where package_id = :package_id + and draft_p = 't' + and deleted_p = 'f' + order by entry_date desc, posted_date desc + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/www/admin/entry-delete.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/admin/entry-delete.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/admin/entry-delete.tcl 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,12 @@ +ad_page_contract {} { + entry_id:integer + {return_url ""} +} + +db_dml delete { + update pinds_blog_entries + set deleted_p = 't' + where entry_id = :entry_id +} + +ad_returnredirect $return_url \ No newline at end of file Index: openacs.org-dev/packages/lars-blogger/www/admin/entry-delete.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/admin/entry-delete.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/admin/entry-delete.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,13 @@ +<?xml version="1.0"?> + +<queryset> + + <fullquery name="delete"> + <querytext> + update pinds_blog_entries + set deleted_p = 't' + where entry_id = :entry_id + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/www/admin/entry-edit-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/admin/entry-edit-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/admin/entry-edit-oracle.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,18 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + + <fullquery name="today"> + <querytext> + select to_char(sysdate, 'YYYY-MM-DD') from dual + </querytext> + </fullquery> + + <partialquery name="now"> + <querytext> + posted_date = sysdate + </querytext> + </partialquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/www/admin/entry-edit-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/admin/entry-edit-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/admin/entry-edit-postgresql.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,18 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + + <fullquery name="today"> + <querytext> + select to_char(current_timestamp, 'YYYY-MM-DD') + </querytext> + </fullquery> + + <partialquery name="now"> + <querytext> + posted_date = current_timestamp + </querytext> + </partialquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/www/admin/entry-edit.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/admin/entry-edit.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/admin/entry-edit.adp 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,13 @@ +<master> +<property name="title">@page_title@</property> +<property name="focus">entry.title</property> +<property name="context_bar">@context_bar@</property> + +<script langauge="javascript"> + function setEntryDateToToday() { + document.forms['entry'].entry_date.value = '@today_html@'; + } +</script> + +<formtemplate id="entry" style="standard-lars"></formtemplate> + Index: openacs.org-dev/packages/lars-blogger/www/admin/entry-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/admin/entry-edit.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/admin/entry-edit.tcl 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,116 @@ +ad_page_contract {} { + {entry_id:integer ""} + {return_url ""} + cancel:optional +} -properties { + context_bar + today_html +} + +if { [info exists cancel] } { + catch { set return_url [element get_value entry return_url] } + if { [empty_string_p $return_url] } { + set return_url "." + } + ad_returnredirect $return_url + ad_script_abort +} + +set today [db_string today { *SQL* }] +set today_html [ad_quotehtml $today] + +form create entry + +element create entry title -label "Title" -datatype text -html { size 50 } +element create entry content -label "Content" -datatype text -widget textarea -html { cols 80 rows 20 } +element create entry entry_date -label "Entry date" -datatype text \ + -help_text "If you set this to something other than today's date, you must use this form to publish your entry, otherwise the entry date will be set to the date you publish the item." \ + -after_html {(<a href="javascript:setEntryDateToToday()">Set to today</a>)} + +element create entry draft_p -label "Post Status" -datatype text -widget select -options { { "Draft" "t" } { "Publish" "f" } } + +element create entry entry_id -widget hidden -datatype text +element create entry insert_or_update -widget hidden -datatype text +element create entry return_url -widget hidden -datatype text -value $return_url + +if { [form is_request entry] } { + + if { [empty_string_p $entry_id] } { + set insert_or_update insert + set entry_id [db_nextval "acs_object_id_seq"] + element set_properties entry entry_date -value $today + element set_properties entry draft_p -value "t" + } else { + set insert_or_update update + + db_1row entry { *SQL* } + + element set_properties entry title -value $title + element set_properties entry content -value $content + element set_properties entry entry_date -value $entry_date + element set_properties entry draft_p -value $draft_p + } + + element set_properties entry entry_id -value $entry_id + element set_properties entry insert_or_update -value $insert_or_update +} + + +if { [form is_valid entry] } { + set entry_id [element get_value entry entry_id] + set title [element get_value entry title] + set content [element get_value entry content] + set entry_date [element get_value entry entry_date] + set draft_p [element get_value entry draft_p] + set draft_p [ad_decode $draft_p "" "f" $draft_p] + + set return_url [element get_value entry return_url] + set insert_or_update [element get_value entry insert_or_update] + + if { [string equal $insert_or_update "insert"] } { + lars_blog_entry_add \ + -entry_id $entry_id \ + -package_id [ad_conn package_id] \ + -title $title \ + -content $content \ + -entry_date $entry_date \ + -draft_p "$draft_p" + } else { + set set_clauses { "title = :title" "content = :content" "entry_date = to_date(:entry_date, 'YYYY-MM-DD')" "draft_p = :draft_p" } + + set org_draft_p [db_string org_draft_p { select draft_p from pinds_blog_entries where entry_id = :entry_id } ] + + if { [string equal $draft_p "t"] && [string equal $org_draft_p "f"] } { + # If this is a publish, set the posted_date to now + lappend set_clauses [db_map now] + } + + db_dml update_entry { *SQL* } + + lars_blog_flush_cache [ad_conn package_id] + } + + if { [empty_string_p $return_url] } { + set return_url "[ad_conn package_url]one-entry?[export_vars { entry_id }]" + } + + ad_returnredirect $return_url + ad_script_abort +} + +if { ![form is_request entry] && ![form is_valid entry] } { + set insert_or_update [element get_value entry insert_or_update] +} + +switch -- $insert_or_update { + insert { + set page_title "Add Blog Entry" + } + update { + set page_title "Edit Blog Entry" + } +} + +set context_bar [ad_context_bar $page_title] + +ad_return_template \ No newline at end of file Index: openacs.org-dev/packages/lars-blogger/www/admin/entry-edit.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/admin/entry-edit.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/admin/entry-edit.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,21 @@ +<?xml version="1.0"?> + +<queryset> + + <fullquery name="entry"> + <querytext> + select title, content, draft_p, to_char(entry_date, 'YYYY-MM-DD') as entry_date + from pinds_blog_entries + where entry_id = :entry_id + </querytext> + </fullquery> + + <fullquery name="update_entry"> + <querytext> + update pinds_blog_entries + set [join $set_clauses ", "] + where entry_id = :entry_id + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/www/admin/entry-publish-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/admin/entry-publish-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/admin/entry-publish-oracle.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,16 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + + <fullquery name="update_entry"> + <querytext> + update pinds_blog_entries + set entry_date = trunc(sysdate), + draft_p = 'f', + posted_date = sysdate + where entry_id = :entry_id + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/www/admin/entry-publish-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/admin/entry-publish-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/admin/entry-publish-postgresql.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,16 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + + <fullquery name="update_entry"> + <querytext> + update pinds_blog_entries + set entry_date = date_trunc('day', current_timestamp), + draft_p = 'f', + posted_date = current_timestamp + where entry_id = :entry_id + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/www/admin/entry-publish.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/admin/entry-publish.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/admin/entry-publish.tcl 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,19 @@ +ad_page_contract {} { + entry_id:integer + {return_url "index"} +} + +db_dml update_entry { *SQL* } + +ad_returnredirect $return_url + +#ns_conn close + +# Notifications +lars_blogger::entry::do_notifications -entry_id $entry_id + +# Ping weblogs.com +lars_blog_weblogs_com_update_ping + +# Flush cache +lars_blog_flush_cache Index: openacs.org-dev/packages/lars-blogger/www/admin/entry-revoke.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/admin/entry-revoke.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/admin/entry-revoke.tcl 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,12 @@ +ad_page_contract {} { + entry_id:integer + {return_url "index"} +} + +db_dml update_entry { *SQL* } + +ad_returnredirect $return_url +ns_conn close + +# Flush cache +lars_blog_flush_cache Index: openacs.org-dev/packages/lars-blogger/www/admin/entry-revoke.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/admin/entry-revoke.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/admin/entry-revoke.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,13 @@ +<?xml version="1.0"?> + +<queryset> + + <fullquery name="update_entry"> + <querytext> + update pinds_blog_entries + set draft_p = 't' + where entry_id = :entry_id + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/www/admin/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/admin/index.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/admin/index.adp 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,8 @@ +<master> +<property name="title">@title@</property> + +<ul> + <li><a href="entry-edit">Add blog entry</a> + <li><a href="drafts">Draft entries</a> +</ul> + Index: openacs.org-dev/packages/lars-blogger/www/admin/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/admin/index.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/admin/index.tcl 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,15 @@ +ad_page_contract {} { +} -properties { + context_bar +} + +set package_id [ad_conn package_id] + +set admin_p [ad_require_permission $package_id admin] + +set context_bar [ad_context_bar] + +set title [db_string package_name { *SQL* }] + +ad_return_template + Index: openacs.org-dev/packages/lars-blogger/www/admin/index.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/admin/index.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/admin/index.xql 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,12 @@ +<?xml version="1.0"?> + +<queryset> + + <fullquery name="package_name"> + <querytext> + select instance_name from apm_packages + where package_id = :package_id + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/lars-blogger/www/archive/index.vuh =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/archive/index.vuh,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/archive/index.vuh 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,19 @@ +set extra_url_list [split [ad_conn extra_url] "/"] + +set year [lindex $extra_url_list 1] +set month [lindex $extra_url_list 2] +set day [lindex $extra_url_list 3] + +if { [empty_string_p $year] && [empty_string_p $month] && [empty_string_p $day] } { + # get year, month, day + set date_list [dt_ansi_to_list [dt_sysdate]] + + ad_returnredirect "[ad_conn package_url]archive/[lindex $date_list 0]/[format "%02d" [lindex $date_list 1]]/" +} else { + rp_form_put year $year + rp_form_put month $month + rp_form_put day $day + + rp_internal_redirect "/packages/lars-blogger/www/index" +} + Index: openacs.org-dev/packages/lars-blogger/www/doc/index.html =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/doc/index.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/lars-blogger/www/doc/index.html 8 Oct 2002 15:47:13 -0000 1.1 @@ -0,0 +1,190 @@ +<html> +<head> +<title>Lars Pind's Blogger Documentation</title> +</head> +<body bgcolor=white> +<h2>Lars Pind's Blogger Documentation</h2> +By <a href="http://www.pinds.com/lars/">Lars Pind</a> +<hr> + +<h3>Why</h3> + +<p> + I wrote this blogger package for my own web site at <a + href="http://www.pinds.com/">pinds.com</a>. For background + information, please visit <a + href="http://www.pinds.com/download/">http://www.pinds.com/download</a>. +</p> + +<h3>Download</h3> + +<p> + The blogger now lives in the <a + href="http://openacs.org">OpenACS</a> cvs repository. +</p> + +<h3>Getting started</h3> + +<p> + Install the package on your system, mount a new instance somewhere + on the site map, make sure you have admin permission on the + instance, and then visit /admin under the URL where you mounted + it. Now you can add your first blog entry. +</p> + +<h3>Syndicating a blog (putting it on your front page)</h3> + +<p> + If you want to include a blog as part of another page, that's pretty + simple. +</p> + +<p> + If you're including in an ADP, say: +</p> + +<blockquote><pre> +<include src="/packages/lars-blogger/www/blog" url="/blog"> +</pre></blockquote> + +<p> + Or from a Tcl page: +</p> + +<blockquote><pre> +set blog_html [template::adp_parse "[acs_package_root_dir "lars-blogger"]/www/blog" [list url "/blog"]] +</pre></blockquote> + +<p> + If you supply a URL, then the blog that matches that URL is served + (assuming that a lars-blogger package is mounted at that + URL). Alternatively, you can supply a <code>package_id</code> + parameter directly. If nothing is supplied, <code>[ad_conn + package_id]</code> is used. +</p> + +<p> + Alternatively, there's a cached version of the same, which is useful + if you're including a blog on the front page of a highly trafficked + site. +</p> + +<blockquote><pre>[lars_blog_get_as_string -url "/blog"]</pre></blockquote> + +<p> + This takes either a package_id or a url argument, just like the + others. To include this in an ADP, you can also say: +</p> + +<blockquote><pre><%=[lars_blog_get_as_string -url "/blog"]%></pre></blockquote> + + +<h3>Technical Info</h3> + +The package fully supports multiple instances, i.e., you can mount +several instances in your site map, and they'll stay properly isolated +from each other. + +<p> + +Only supports PostgreSQL (please do port to Oracle if you want to). + +<p> + +Contents in your blog entries are assumed to be full-blood ADP-ified +HTML, so don't give people access to post a blog unless you trust +them. I guess it should be made configurable whether to allow this or +not, but since I'm developing this for my own site primarily, I +haven't done so. This also means that if you've added custom ADP tags, +those are also available to you in your blog. + +<h3>weblogs.com update ping</h3> + +There are a couple parameters governing this feature. You can turn it +on or off on a per-package basis. And you can specify which URL you +want to export to weblogs.com, in case it's not the one the package +instance is mounted at. This can be useful if you're including the +blog on other pages, for example your site's front page. Thanks to +Jerry Asher for the code to do this. + +<h3>RSS Feed</h3> + +The RSS feed is version 1.0 only, and requires the rss-support package +if you want to use it. I found that getting rss-support to register +the Report Generation Subscripion (whatever that means) was +hard. There seemed to be a bug, but the rss-support package was so +hard for me to figure out that I'm not sure. In the end, I hacked on +some page scripts and added a channel_title through SQL. Phew! Let me +know if you try to get this running, so we can either fix the bug(s) +or write some clear docs on how to. + +<p> + +You can supply your own channel image through the parameters. And you +can specify which URL we should advertise the RSS fil under. Leave +blank if you haven't set up an RSS feed for this package. + + +<h3>Road Map</h3> + +<ul> + +<li>Categorize and full-text-search-index blog entries so the archives are more useful. + +<li>Dave Bauer is implementing this as an ETP application, interesting +to see where that goes. + +<li>Calendar widget + +<li>Easier to set up RSS support (probably requires mucking with the rss-support package) + +<li>Nicer interface + +<li>Make it safe to use in a not-so-protected environment, e.g., +disable <% ... %> ADP notation. + +<li>More thorough documentation and some setup/config pages. + +</ul> + +<h3>Version History</h3> + +<ul> + +<li><b>0.7d</b> Finished port to Oracle. Upgraded PG drop script. Renamed RSS proc which requires running the SQL upgrade script (for PG). Bug-fix to bypass 'draft' and publish directly. -vinodk (August 15, 2002) + +<li><b>0.6.4d</b> Added poster information, optional per +parameter. Added "url" shortcut variable to the blog template. Updated +documentation. (July 23, 2002) + +<li><b>0.6.3d</b> Added drop scripts, and made the create script call rss-register. Fixed minor bugs. (July 22, 2002) + +<li><b>0.6.1d</b> Fixed RSS last update bug. (Jun 2, 2002) + +<li><b>0.6d</b> Added RSS feed. Woohoo! (June 1, 2002) + +<li><b>0.5d</b> Added weblogs.com update ping. (June 1, 2002) + +<li><b>0.4d</b> Added Google link, new style. (May 31, 2002) + +<li><b>0.3.3d</b> Added Peter Marklund's arrow-box.gif patch. (May 13, 2002) + +<li><b>0.3.2d</b> Missing files from the distribution. + +<li><b>0.3d</b> Improved admin interface, added documentation. (March 24, 2002) + +<li><b>0.2d</b> Allow and show comments on blog. (March 23, 2002) + +<li><b>0.1d</b> Initial version. (February 18, 2002) + +</ul> + +<h3>License</h3> + +Released under the <a href="http://www.gnu.org/licenses/gpl.txt">GPL</a>. + +<hr> +<address><a href="mailto:lars@pinds.com">lars@pinds.com</a></address> + +</body> +</html> \ No newline at end of file Index: openacs.org-dev/packages/lars-blogger/www/graphics/arrow-box.gif =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/lars-blogger/www/graphics/arrow-box.gif,v diff -u Binary files differ Index: openacs.org-dev/packages/monitoring/sql/oracle/monitoring-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/monitoring/sql/oracle/monitoring-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/monitoring/sql/oracle/monitoring-drop.sql 8 Oct 2002 15:47:14 -0000 1.1 @@ -0,0 +1,19 @@ +-- +-- /packages/monitoring/sql/oracle/monitoring-drop.sql +-- +-- Monitoring drop script +-- +-- @author Vinod Kurup (vinod@kurup.com) +-- @creation-date 2002-08-17 +-- @cvs-id $Id: monitoring-drop.sql,v 1.1 2002/10/08 15:47:14 rmello Exp $ +-- + +drop sequence ad_monitoring_tab_est_seq start; +drop table ad_monitoring_tables_estimated; + +drop sequence ad_monitoring_top_proc_proc_id; +drop table ad_monitoring_top_proc; + +drop sequence ad_monitoring_top_top_id; +drop table ad_monitoring_top; + Index: openacs.org-dev/packages/monitoring/sql/postgresql/monitoring-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/monitoring/sql/postgresql/monitoring-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/monitoring/sql/postgresql/monitoring-create.sql 8 Oct 2002 15:47:14 -0000 1.1 @@ -0,0 +1,114 @@ +-- +-- /packages/monitoring/sql/postgresql/monitoring-drop.sql +-- +-- Description: Definition for general system monitoring +-- +-- @author Vinod Kurup (vinod@kurup.com) PG Port only +-- @creation-date 2002-08-17 +-- @cvs-id $Id: monitoring-create.sql,v 1.1 2002/10/08 15:47:14 rmello Exp $ +-- +-- Just doing a straight port right now. I'm not sure how much of this +-- stuff is Oracle-specific and thus useless for PG. + + +-- simple table to gather stats from top +-- where top's output looks like this (from dev0103-001:/usr/local/bin/top): + +-- load averages: 0.21, 0.18, 0.23 21:52:56 +-- 322 processes: 316 sleeping, 3 zombie, 1 stopped, 2 on cpu +-- CPU states: 3.7% idle, 9.2% user, 7.1% kernel, 80.0% iowait, 0.0% swap +-- Memory: 1152M real, 17M free, 593M swap in use, 1432M swap free +-- +-- PID USERNAME THR PRI NICE SIZE RES STATE TIME CPU COMMAND +-- 17312 oracle 1 33 0 222M 189M sleep 17:54 0.95% oracle +-- 9834 root 1 33 0 2136K 1528K sleep 0:00 0.43% sshd1 + + +create sequence ad_monitoring_top_top_id start 1; + +create table ad_monitoring_top ( + top_id integer + constraint ad_mntr_top_id_pk primary key, + timestamp timestamp default current_timestamp, + -- denormalization: an indexable column for fast time comparisons. + timehour numeric(2), + -- the three load averages taken from uptime/top + load_avg_1 numeric, + load_avg_5 numeric, + load_avg_15 numeric, + -- basic stats on current memory usage + memory_real numeric, + memory_free numeric, + memory_swap_free numeric, + memory_swap_in_use numeric, + -- basic stats on the number of running procedures + procs_total integer, + procs_sleeping integer, + procs_zombie integer, + procs_stopped integer, + procs_on_cpu integer, + -- basic stats on cpu usage + cpu_idle numeric, + cpu_user numeric, + cpu_kernel numeric, + cpu_iowait numeric, + cpu_swap numeric +); + + +-- this table stores information about each of the top 10 or so +-- processes running. Every time we take a snapshot, we record +-- this basic information to help track down stray or greedy +-- processes +create sequence ad_monitoring_top_proc_proc_id start 1; +create table ad_monitoring_top_proc ( + proc_id integer + constraint ad_mntr_top_proc_pk primary key, + top_id integer not null + constraint ad_mntr_top_proc_top_id_fk + references ad_monitoring_top, + pid integer not null, -- the process id + username varchar(10) not null, -- user running this command + threads integer, -- the # of threads this proc is running + priority integer, + nice integer, -- the value of nice for this process + proc_size varchar(10), + resident_memory varchar(10), + state varchar(10), + cpu_total_time varchar(10), -- total cpu time used to date + cpu_pct varchar(10), -- percentage of cpu currently used + -- the command this process is running + command varchar(30) not null +); + +-- the following table is lifted from the Oracle version, but is likely +-- not useful here. 2002-08-19 vinodk + +-- Begin Estimation module datamodel. +-- the following table lists tables which are to be estimated. +-- A scheduled proc runs +-- analyze table <table_name> estimate statistics sample <percent_estimating> +-- where table-name is pulled from the table as is percent_estimating + +create table ad_monitoring_tables_estimated ( + table_entry_id integer + constraint ad_mntr_table_estim_pk primary key, + -- This is a table name, but we don't want it to + -- reference user_tables since then deleting a table + -- would be problematic, since this would reference it + -- Instead, in the proc we use to run this (a scheduled + -- proc, we check to make sure the table exists. + table_name varchar(40) + constraint amte_table_name_nn not null, + -- The percent of the table we estimate, defaults to 20% + percent_estimating integer default 20, + last_percent_estimated integer, + --Do we actually want to run this? + enabled_p boolean, + last_estimated timestamp +); + +--Sequence for above table +create sequence ad_monitoring_tab_est_seq start 1000; + +-- EOF Index: openacs.org-dev/packages/monitoring/sql/postgresql/monitoring-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/monitoring/sql/postgresql/monitoring-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/monitoring/sql/postgresql/monitoring-drop.sql 8 Oct 2002 15:47:14 -0000 1.1 @@ -0,0 +1,19 @@ +-- +-- /packages/monitoring/sql/postgresql/monitoring-drop.sql +-- +-- Monitoring drop script +-- +-- @author Vinod Kurup (vinod@kurup.com) +-- @creation-date 2002-08-17 +-- @cvs-id $Id: monitoring-drop.sql,v 1.1 2002/10/08 15:47:14 rmello Exp $ +-- + +drop sequence ad_monitoring_tab_est_seq; +drop table ad_monitoring_tables_estimated; + +drop sequence ad_monitoring_top_proc_proc_id; +drop table ad_monitoring_top_proc; + +drop sequence ad_monitoring_top_top_id; +drop table ad_monitoring_top; + Index: openacs.org-dev/packages/monitoring/tcl/monitoring-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/monitoring/tcl/monitoring-procs-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/monitoring/tcl/monitoring-procs-oracle.xql 8 Oct 2002 15:47:14 -0000 1.1 @@ -0,0 +1,37 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="ad_monitor_top.top_misc_info_insert"> + <querytext> + + insert into ad_monitoring_top ( + top_id, + timestamp, + timehour, + load_avg_1, + load_avg_5, + load_avg_15, + memory_real, + memory_free, + memory_swap_in_use, + memory_swap_free + ) values ( + :top_id, + sysdate, + to_char(sysdate, 'HH24'), + :load_1, + :load_5, + :load_15, + :memory_real, + :memory_free, + :memory_swap_in_use, + :memory_swap_free + ) + + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/monitoring/tcl/monitoring-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/monitoring/tcl/monitoring-procs-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/monitoring/tcl/monitoring-procs-postgresql.xql 8 Oct 2002 15:47:14 -0000 1.1 @@ -0,0 +1,37 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="ad_monitor_top.top_misc_info_insert"> + <querytext> + + insert into ad_monitoring_top ( + top_id, + timestamp, + timehour, + load_avg_1, + load_avg_5, + load_avg_15, + memory_real, + memory_free, + memory_swap_in_use, + memory_swap_free + ) values ( + :top_id, + current_timestamp, + to_char(current_timestamp, 'HH24')::integer, + :load_1, + :load_5, + :load_15, + :memory_real, + :memory_free, + :memory_swap_in_use, + :memory_swap_free + ) + + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/monitoring/tcl/monitoring-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/monitoring/tcl/monitoring-procs.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/monitoring/tcl/monitoring-procs.xql 8 Oct 2002 15:47:14 -0000 1.1 @@ -0,0 +1,41 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="ad_monitor_top.top_proc_info_insert"> +<querytext> + + insert into ad_monitoring_top_proc ( + proc_id, + top_id, + pid, + command, + username, + threads, + priority, + nice, + proc_size, + resident_memory, + state, + cpu_total_time, + cpu_pct + ) values ( + :proc_id, + :top_id, + :pid, + :command, + :username, + :threads, + :priority, + :nice, + :proc_size, + :resident_memory, + :state, + :cpu_total_time, + :cpu_pct + ) + +</querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/monitoring/www/index-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/monitoring/www/index-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/monitoring/www/index-oracle.xql 8 Oct 2002 15:47:14 -0000 1.1 @@ -0,0 +1,18 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="get_package_url"> + <querytext> + + select site_node.url(s.node_id) as url + from site_nodes s + where s.object_id = :dev_support_id + and rownum = 1 + + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/monitoring/www/index-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/monitoring/www/index-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/monitoring/www/index-postgresql.xql 8 Oct 2002 15:47:14 -0000 1.1 @@ -0,0 +1,18 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="get_package_url"> + <querytext> + + select site_node__url(s.node_id) as url + from site_nodes s + where s.object_id = :dev_support_id + limit 1 + + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/monitoring/www/top/details-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/monitoring/www/top/details-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/monitoring/www/top/details-oracle.xql 8 Oct 2002 15:47:14 -0000 1.1 @@ -0,0 +1,65 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="mon_current_hour"> + <querytext> + + select to_char(sysdate,'HH24') from dual + + </querytext> +</fullquery> + +<partialquery name="hour_correction"> + <querytext> + + + (24 - (:end_time - :current_hour)) / 24 + + </querytext> +</partialquery> + +<partialquery name="proc_query"> + <querytext> + + select pid, command, username, + $proc_time_sql, + count(*) as count, + round(avg(threads),0) as threads, + round(avg(to_number(rtrim(cpu_pct, '%'))),2) as cpu_pct + from (select * from ad_monitoring_top_proc + where to_number(rtrim(cpu_pct, '%')) > :min_cpu_pct) p, + (select * from ad_monitoring_top where $time_clause) t + where p.top_id = t.top_id + and $details_clause + group by pid, command, username, $proc_group_by + [ad_order_by_from_sort_spec $orderby $top_proc_table_def] + + </querytext> +</partialquery> + +<partialquery name="load_and_memory_averages_sql"> + <querytext> + + round(nvl(avg(load_avg_1), 0), 2) as load_average, + round(nvl(avg(memory_free),0), -2) as memory_free_average, + round(nvl(avg(memory_swap_free), 0), -2) as memory_swap_free_average, + round(nvl(avg(memory_swap_in_use),0), -2) as memory_swap_in_use_average + + </querytext> +</partialquery> + +<fullquery name="mon_top_entries"> + <querytext> + + select count(*) + from (select * from ad_monitoring_top where $time_clause) t, + (select * from ad_monitoring_top_proc + where to_number(rtrim(cpu_pct, '%')) > :min_cpu_pct) p + where t.top_id = p.top_id + and $details_clause + + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/monitoring/www/top/details-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/monitoring/www/top/details-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/monitoring/www/top/details-postgresql.xql 8 Oct 2002 15:47:14 -0000 1.1 @@ -0,0 +1,65 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="mon_current_hour"> + <querytext> + + select to_char(current_timestamp,'HH24') + + </querytext> +</fullquery> + +<partialquery name="hour_correction"> + <querytext> + + + (24 - (:end_time ::integer - $current_hour ::integer)) / 24 + + </querytext> +</partialquery> + +<partialquery name="proc_query"> + <querytext> + + select pid, command, username, + $proc_time_sql, + count(*) as count, + round(avg(threads),0) as threads, + round(avg(to_number(rtrim(cpu_pct, '%'), '9999D99')), 2) as cpu_pct + from ( select * from ad_monitoring_top_proc + where to_number(rtrim(cpu_pct, '%'), '9999D99') > :min_cpu_pct ) p, + (select * from ad_monitoring_top $time_clause) t + where p.top_id = t.top_id + and $details_clause + group by pid, command, username, $proc_group_by + [ad_order_by_from_sort_spec $orderby $top_proc_table_def] + + </querytext> +</partialquery> + +<partialquery name="load_and_memory_averages_sql"> + <querytext> + + round(coalesce(avg(load_avg_1), 0), 2) as load_average, + round(coalesce(avg(memory_free),0), -2) as memory_free_average, + round(coalesce(avg(memory_swap_free), 0), -2) as memory_swap_free_average, + round(coalesce(avg(memory_swap_in_use),0), -2) as memory_swap_in_use_average + + </querytext> +</partialquery> + +<fullquery name="mon_top_entries"> + <querytext> + + select count(*) + from (select * from ad_monitoring_top $time_clause) t, + (select * from ad_monitoring_top_proc + where to_number(rtrim(cpu_pct, '%'), '9999D99') > :min_cpu_pct) p + where t.top_id = p.top_id + and $details_clause + + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/monitoring/www/top/details.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/monitoring/www/top/details.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/monitoring/www/top/details.xql 8 Oct 2002 15:47:14 -0000 1.1 @@ -0,0 +1,27 @@ +<?xml version="1.0"?> + +<queryset> + +<partialquery name="time_clause_1"> + <querytext> + + where timehour >= :start_time and timehour < :end_time + + </querytext> +</partialquery> + +<partialquery name="system_query"> + <querytext> + + select $load_and_memory_averages_sql, + count(*) as count, + $system_time_sql + from ad_monitoring_top $time_clause + and $details_clause + group by $system_group_by + [ad_order_by_from_sort_spec $orderbysystem $top_system_table_def] + + </querytext> +</partialquery> + +</queryset> Index: openacs.org-dev/packages/monitoring/www/top/index-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/monitoring/www/top/index-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/monitoring/www/top/index-oracle.xql 8 Oct 2002 15:47:14 -0000 1.1 @@ -0,0 +1,69 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="mon_current_hour"> + <querytext> + + select to_char(sysdate,'HH24') from dual + + </querytext> +</fullquery> + +<partialquery name="hour_correction"> + <querytext> + + + (24 - (:end_time - :current_hour)) / 24 + + </querytext> +</partialquery> + +<partialquery name="time_clause_2"> + <querytext> + + and (timestamp + :n_days $hour_correction) > sysdate + + </querytext> +</partialquery> + +<partialquery name="avg_proc_query"> + <querytext> + + select pid, command, username, + count(*) as count, + $hour_sql as timestamp, + round(avg(threads)) as threads, + round(avg(to_number(rtrim(cpu_pct, '%'))), 2) as cpu_pct + from ( select * from ad_monitoring_top $time_clause ) t, + ( select * from ad_monitoring_top_proc + where to_number(rtrim(cpu_pct, '%')) > :min_cpu_pct ) p + where p.top_id = t.top_id + group by pid, command, username, $hour_sql + [ad_order_by_from_sort_spec $orderby $top_proc_avg_table_def] + + </querytext> +</partialquery> + +<partialquery name="load_and_memory_averages_sql"> + <querytext> + + round(nvl(avg(load_avg_1), 0), 2) as load_average, + round(nvl(avg(memory_free),0), -2) as memory_free_average, + round(nvl(avg(memory_swap_free), 0), -2) as memory_swap_free_average, + round(nvl(avg(memory_swap_in_use),0), -2) as memory_swap_in_use_average + + </querytext> +</partialquery> + +<fullquery name="num_days_for_query"> + <querytext> + + select round(max(timestamp) - min(timestamp) + 0.5) + from ad_monitoring_top $time_clause + + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/monitoring/www/top/index-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/monitoring/www/top/index-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/monitoring/www/top/index-postgresql.xql 8 Oct 2002 15:47:14 -0000 1.1 @@ -0,0 +1,68 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="mon_current_hour"> + <querytext> + + select to_char(current_timestamp,'HH24') + + </querytext> +</fullquery> + +<partialquery name="hour_correction"> + <querytext> + + + (24 - (:end_time ::integer - $current_hour ::integer)) / 24 + + </querytext> +</partialquery> + +<partialquery name="time_clause_2"> + <querytext> + + and (timestamp + :n_days ::integer $hour_correction) > current_timestamp + + </querytext> +</partialquery> + +<partialquery name="avg_proc_query"> + <querytext> + + select pid, command, username, + count(*) as count, + $hour_sql as timestamp, + round(avg(threads)) as threads, + round(avg(to_number(rtrim(cpu_pct, '%'), '9999D99')), 2) as cpu_pct + from ( select * from ad_monitoring_top $time_clause ) t, + ( select * from ad_monitoring_top_proc + where to_number(rtrim(cpu_pct, '%'), '9999D99') > :min_cpu_pct ) p + where p.top_id = t.top_id + group by pid, command, username, $hour_sql + [ad_order_by_from_sort_spec $orderby $top_proc_avg_table_def] + + </querytext> +</partialquery> + +<partialquery name="load_and_memory_averages_sql"> + <querytext> + + round(coalesce(avg(load_avg_1), 0), 2) as load_average, + round(coalesce(avg(memory_free),0), -2) as memory_free_average, + round(coalesce(avg(memory_swap_free), 0), -2) as memory_swap_free_average, + round(coalesce(avg(memory_swap_in_use),0), -2) as memory_swap_in_use_average + + </querytext> +</partialquery> + +<fullquery name="num_days_for_query"> + <querytext> + + select max(timestamp) - min(timestamp) + '12 hours'::interval + from ad_monitoring_top $time_clause + + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/monitoring/www/top/index.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/monitoring/www/top/index.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/monitoring/www/top/index.xql 8 Oct 2002 15:47:14 -0000 1.1 @@ -0,0 +1,43 @@ +<?xml version="1.0"?> + +<queryset> + +<partialquery name="time_clause_1"> + <querytext> + + where timehour >= :start_time and timehour < :end_time + + </querytext> +</partialquery> + +<partialquery name="hour_sql"> + <querytext> + + to_char(timestamp, 'MM/DD HH24') || ':00' + + </querytext> +</partialquery> + +<partialquery name="day_sql"> + <querytext> + + to_char(timestamp, 'Mon DD') + + </querytext> +</partialquery> + +<partialquery name="avg_system_query"> + <querytext> + + select $load_and_memory_averages_sql, + count(*) as count, + $day_sql as day + from ad_monitoring_top + $time_clause + group by $day_sql + [ad_order_by_from_sort_spec $orderbysystem $top_system_avg_table_def] + + </querytext> +</partialquery> + +</queryset> Index: openacs.org-dev/packages/notifications/sql/oracle/upgrade/upgrade-0.1d-0.2d.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/notifications/sql/oracle/upgrade/upgrade-0.1d-0.2d.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/notifications/sql/oracle/upgrade/upgrade-0.1d-0.2d.sql 8 Oct 2002 15:47:15 -0000 1.1 @@ -0,0 +1 @@ +@@ ../notifications-package-create.sql Index: openacs.org-dev/packages/notifications/sql/postgresql/upgrade/upgrade-0.1d-0.2d.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/notifications/sql/postgresql/upgrade/upgrade-0.1d-0.2d.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/notifications/sql/postgresql/upgrade/upgrade-0.1d-0.2d.sql 8 Oct 2002 15:47:15 -0000 1.1 @@ -0,0 +1,13 @@ +drop function notification__delete; + +create function notification__delete(integer) +returns integer as ' +declare + p_notification_id alias for $1; +begin + delete from notifications where notification_id = p_notification_id; + perform acs_object__delete(p_notification_id); + return 0; +end; +' language 'plpgsql'; + Index: openacs.org-dev/packages/notifications/tcl/notifications-security-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/notifications/tcl/notifications-security-procs.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/notifications/tcl/notifications-security-procs.xql 8 Oct 2002 15:47:15 -0000 1.1 @@ -0,0 +1,14 @@ +<?xml version="1.0"?> + +<queryset> + + <fullquery name="notification::security::can_notify_user.user_approved_p"> + <querytext> + select case when member_state = 'approved' then 1 else 0 end as send_p + from cc_users + where user_id = :user_id + </querytext> + </fullquery> + +</queryset> + \ No newline at end of file Index: openacs.org-dev/packages/notifications/www/manage-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/notifications/www/manage-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/notifications/www/manage-oracle.xql 8 Oct 2002 15:47:15 -0000 1.1 @@ -0,0 +1,39 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="select_notifications"> + <querytext> + select request_id, + (select pretty_name + from notification_types + where notification_types.type_id = + notification_requests.type_id) as type, + decode ((select short_name + from notification_types + where notification_types.type_id = + notification_requests.type_id), + 'forums_forum_notif', + (select name + from forums_forums + where forum_id = + notification_requests.object_id), + 'forums_message_notif', + (select subject + from forums_messages + where message_id = + notification_requests.object_id), + '') as object_name, + (select name + from notification_intervals + where notification_intervals.interval_id = + notification_requests.interval_id) as interval, + object_id + from notification_requests + where user_id = :user_id + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/notifications/www/manage-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/notifications/www/manage-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/notifications/www/manage-postgresql.xql 8 Oct 2002 15:47:15 -0000 1.1 @@ -0,0 +1,44 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="select_notifications"> + <querytext> + select request_id, + (select pretty_name + from notification_types + where notification_types.type_id = + notification_requests.type_id) as type, + case when (select short_name + from notification_types + where notification_types.type_id = + notification_requests.type_id) = 'forums_forum_notif' + then + (select name + from forums_forums + where forum_id = + notification_requests.object_id) + when (select short_name + from notification_types + where notification_types.type_id = + notification_requests.type_id) = 'forums_message_notif' + then + (select subject + from forums_messages + where message_id = + notification_requests.object_id) + else + acs_object__name(notification_requests.object_id) + end as object_name, + (select name + from notification_intervals + where notification_intervals.interval_id = + notification_requests.interval_id) as interval, + object_id + from notification_requests + where user_id = :user_id + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/notifications/www/manage.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/notifications/www/manage.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/notifications/www/manage.adp 8 Oct 2002 15:47:15 -0000 1.1 @@ -0,0 +1,33 @@ +<master> +<property name="title">Manage Notifications</property> +<property name="context">"manage notifications"</property> + +<table width="85%" class="table-display" cellpadding="5" cellspacing="0"> + <tr class="table-header"> + <td>Notification type</td> + <td>Item</td> + <td>Frequency</td> + <td>Action</td> + </tr> +<multiple name="notifications"> +<if @notifications.rownum@ odd> + <tr class="odd"> +</if> +<else> + <tr class="even"> +</else> + <td>@notifications.type@</td> + <td><a href=object-goto.tcl?object_id=@notifications.object_id@>@notifications.object_name@</a></td> + <td>@notifications.interval@</td> + <td><a href=request-delete.tcl?return_url=@return_url@&request_id=@notifications.request_id@>Unsubscribe</a></td> +</tr> +</multiple> + +<if @notifications:rowcount@ eq 0> + <tr> + <td colspan=4><i>You have no notifications.</i></td> + </tr> +</if> + +</table> + Index: openacs.org-dev/packages/notifications/www/manage.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/notifications/www/manage.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/notifications/www/manage.tcl 8 Oct 2002 15:47:15 -0000 1.1 @@ -0,0 +1,15 @@ +ad_page_contract { + + Manage notifications for one user + + @author Tracy Adams (teadams@alum.mit.edu) + @creation-date 2002-07-22 + @cvs-id $Id: manage.tcl,v 1.1 2002/10/08 15:47:15 rmello Exp $ +} {} + +set user_id [ad_conn user_id] +set return_url [ad_conn url] + +db_multirow notifications select_notifications {} + +ad_return_template \ No newline at end of file Index: openacs.org-dev/packages/notifications/www/object-goto.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/notifications/www/object-goto.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/notifications/www/object-goto.tcl 8 Oct 2002 15:47:15 -0000 1.1 @@ -0,0 +1,23 @@ +ad_page_contract { + go to an object + + @author Tracy Adams (teadams@alum.mit.edu) + @creation-date 22 July 2002 + @cvs-id $Id: object-goto.tcl,v 1.1 2002/10/08 15:47:15 rmello Exp $ +} { + object_id:notnull +} + + +# At the time of writing, the only supported +# notification types were on the object types +# forum_forums and forum_messages. get_url +# will handle both these types. If there are +# more type of notifications added, this file +# has to be changed to handle them. Perhaps +# it could be handles in a generic way, using +# meta-data about the object_type to auto-generate +# the url. + +ad_returnredirect [forum::notification::get_url $object_id] + Index: openacs.org-dev/packages/openfts-driver/www/doc/index.html =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/openfts-driver/www/doc/index.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/openfts-driver/www/doc/index.html 8 Oct 2002 15:47:15 -0000 1.1 @@ -0,0 +1,21 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> + <head> + <title>OpenFTS Driver</title> + </head> + + <body> + <h1>OpenFTS Driver</h1> + <a href="../">OpenACS documentation</a> + <hr> + <a href="INSTALL">Installation document</a> + + + <hr> + <address><a href="mailto:vkurup@massmed.org">Vinod Kurup</a></address> +<!-- Created: Fri Sep 13 08:35:01 EDT 2002 --> +<!-- hhmts start --> +Last modified: Fri Sep 13 08:44:05 EDT 2002 +<!-- hhmts end --> + </body> +</html> Index: openacs.org-dev/packages/press/www/unauthorized.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/press/www/unauthorized.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/press/www/unauthorized.adp 8 Oct 2002 15:47:18 -0000 1.1 @@ -0,0 +1,7 @@ +<master> +<property name="title">Permission denied</property> +<property name="context">"permission denied"</property> + +You do not have permission to access this page. + + Index: openacs.org-dev/packages/search/www/doc/index.html =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/search/www/doc/index.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/search/www/doc/index.html 8 Oct 2002 15:47:25 -0000 1.1 @@ -0,0 +1,21 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> + <head> + <title>Search</title> + </head> + + <body> + <h1>Search</h1> + <a href="../">OpenACS documentation</a> + <hr> + <ul> + <li><a href="./guidelines.html">How to make an object searchable</a></li> + </ul> + <hr> + <address><a href="mailto:vkurup@massmed.org">Vinod Kurup</a></address> +<!-- Created: Fri Sep 13 08:36:28 EDT 2002 --> +<!-- hhmts start --> +Last modified: Fri Sep 13 08:44:16 EDT 2002 +<!-- hhmts end --> + </body> +</html> Index: openacs.org-dev/packages/static-pages/tcl/static-pages-sc-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/static-pages/tcl/static-pages-sc-procs.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/static-pages/tcl/static-pages-sc-procs.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,27 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="static_page__datasource.sp_datasource"> + <querytext> + select r.revision_id as object_id, + r.title as title, + '$path_stub' || r.content as content, + 'text/html' as mime, + '' as keywords, + 'file' as storage_type + from cr_revisions r + where revision_id = :object_id + </querytext> +</fullquery> + +<fullquery name="static_page__url.sp_url"> + <querytext> + select r.content as url + from cr_revisions r + where revision_id = :object_id + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/static-pages/www/admin/display-policy-toggle-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/static-pages/www/admin/display-policy-toggle-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/static-pages/www/admin/display-policy-toggle-oracle.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> +<fullquery name="toggle_display_policy"> + <querytext> + + update static_pages + set show_comments_p = decode(show_comments_p,'t','f','t') + where static_page_id = :item_id + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/survey.info =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/survey.info,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/survey.info 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,194 @@ +<?xml version="1.0"?> +<!-- Generated by the OpenACS Package Manager --> + +<package key="survey" url="http://openacs.org/repository/apm/packages/survey" type="apm_application"> + <package-name>Survey</package-name> + <pretty-plural>Surveys</pretty-plural> + <initial-install-p>f</initial-install-p> + <singleton-p>f</singleton-p> + + <version name="0.1d" url="http://openacs.org/repository/download/apm/survey-0.1d.apm"> + <database-support> + <database>oracle</database> + <database>postgresql</database> + </database-support> + <owner url="mailto:dave@thedesignexperience.org">Dave Bauer</owner> + <owner url="mailto:luke@museatech.net">Luke Pond</owner> + <summary>New version of survey package for dotLRN/OpenACS4.5</summary> + <vendor url="http://dotlrn.mit.edu">dotLRN</vendor> + <description format="text/plain">New version of survey package for dotLRN/OpenACS4.5</description> + + <provides url="survey" version="0.1d"/> + <requires url="notifications" version="0.1"/> + + <files> + <file type="data_model_create" db_type="oracle" path="sql/oracle/survey-create.sql"/> + <file type="data_model_drop" db_type="oracle" path="sql/oracle/survey-drop.sql"/> + <file type="data_model" db_type="oracle" path="sql/oracle/survey-notifications-init.sql"/> + <file type="data_model" db_type="oracle" path="sql/oracle/survey-package-create.sql"/> + <file type="data_model" db_type="oracle" path="sql/oracle/survey-package-drop.sql"/> + <file type="data_model_create" db_type="postgresql" path="sql/postgresql/survey-create.sql"/> + <file type="data_model_drop" db_type="postgresql" path="sql/postgresql/survey-drop.sql"/> + <file type="data_model" db_type="postgresql" path="sql/postgresql/survey-notifications-init.sql"/> + <file type="package_spec" path="survey.info"/> + <file type="query_file" db_type="oracle" path="tcl/survey-procs-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="tcl/survey-procs-postgresql.xql"/> + <file type="tcl_procs" path="tcl/survey-procs.tcl"/> + <file type="query_file" path="tcl/survey-procs.xql"/> + <file type="content_page" path="www/admin/description-edit.adp"/> + <file type="content_page" path="www/admin/description-edit.tcl"/> + <file type="query_file" path="www/admin/description-edit.xql"/> + <file type="content_page" path="www/admin/index.adp"/> + <file type="content_page" path="www/admin/index.tcl"/> + <file type="query_file" path="www/admin/index.xql"/> + <file type="content_page" path="www/admin/master.adp"/> + <file type="content_page" path="www/admin/modify-responses-2.tcl"/> + <file type="query_file" path="www/admin/modify-responses-2.xql"/> + <file type="content_page" path="www/admin/modify-responses.tcl"/> + <file type="query_file" path="www/admin/modify-responses.xql"/> + <file type="content_page" path="www/admin/name-edit.adp"/> + <file type="content_page" path="www/admin/name-edit.tcl"/> + <file type="query_file" path="www/admin/name-edit.xql"/> + <file type="query_file" db_type="oracle" path="www/admin/one-respondent-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/admin/one-respondent-postgresql.xql"/> + <file type="content_page" path="www/admin/one-respondent.adp"/> + <file type="content_page" path="www/admin/one-respondent.tcl"/> + <file type="query_file" path="www/admin/one-respondent.xql"/> + <file type="content_page" path="www/admin/one.adp"/> + <file type="content_page" path="www/admin/one.tcl"/> + <file type="query_file" path="www/admin/one.xql"/> + <file type="query_file" db_type="oracle" path="www/admin/question-active-toggle-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/admin/question-active-toggle-postgresql.xql"/> + <file type="content_page" path="www/admin/question-active-toggle.tcl"/> + <file type="content_page" path="www/admin/question-add-2.adp"/> + <file type="content_page" path="www/admin/question-add-2.tcl"/> + <file type="query_file" path="www/admin/question-add-2.xql"/> + <file type="query_file" db_type="oracle" path="www/admin/question-add-3-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/admin/question-add-3-postgresql.xql"/> + <file type="content_page" path="www/admin/question-add-3.tcl"/> + <file type="query_file" path="www/admin/question-add-3.xql"/> + <file type="content_page" path="www/admin/question-add.adp"/> + <file type="content_page" path="www/admin/question-add.tcl"/> + <file type="query_file" db_type="postgresql" path="www/admin/question-copy-postgresql.xql"/> + <file type="content_page" path="www/admin/question-copy.tcl"/> + <file type="query_file" path="www/admin/question-copy.xql"/> + <file type="content_page" path="www/admin/question-delete-2.tcl"/> + <file type="query_file" path="www/admin/question-delete-2.xql"/> + <file type="query_file" db_type="oracle" path="www/admin/question-delete-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/admin/question-delete-postgresql.xql"/> + <file type="content_page" path="www/admin/question-delete.adp"/> + <file type="content_page" path="www/admin/question-delete.tcl"/> + <file type="query_file" path="www/admin/question-delete.xql"/> + <file type="content_page" path="www/admin/question-modify-text.adp"/> + <file type="content_page" path="www/admin/question-modify-text.tcl"/> + <file type="query_file" path="www/admin/question-modify-text.xql"/> + <file type="content_page" path="www/admin/question-modify.adp"/> + <file type="content_page" path="www/admin/question-modify.tcl"/> + <file type="query_file" path="www/admin/question-modify.xql"/> + <file type="query_file" db_type="oracle" path="www/admin/question-required-toggle-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/admin/question-required-toggle-postgresql.xql"/> + <file type="content_page" path="www/admin/question-required-toggle.tcl"/> + <file type="content_page" path="www/admin/question-swap.tcl"/> + <file type="query_file" path="www/admin/question-swap.xql"/> + <file type="content_page" path="www/admin/respondents.adp"/> + <file type="content_page" path="www/admin/respondents.tcl"/> + <file type="query_file" path="www/admin/respondents.xql"/> + <file type="query_file" db_type="oracle" path="www/admin/response-delete-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/admin/response-delete-postgresql.xql"/> + <file type="content_page" path="www/admin/response-delete.adp"/> + <file type="content_page" path="www/admin/response-delete.tcl"/> + <file type="content_page" path="www/admin/response-drill-down.adp"/> + <file type="content_page" path="www/admin/response-drill-down.tcl"/> + <file type="query_file" path="www/admin/response-drill-down.xql"/> + <file type="query_file" db_type="oracle" path="www/admin/response-editable-toggle-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/admin/response-editable-toggle-postgresql.xql"/> + <file type="content_page" path="www/admin/response-editable-toggle.tcl"/> + <file type="query_file" db_type="oracle" path="www/admin/response-limit-toggle-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/admin/response-limit-toggle-postgresql.xql"/> + <file type="content_page" path="www/admin/response-limit-toggle.tcl"/> + <file type="query_file" db_type="oracle" path="www/admin/responses-export-oracle.xql"/> + <file type="content_page" path="www/admin/responses-export.tcl"/> + <file type="query_file" path="www/admin/responses-export.xql"/> + <file type="content_page" path="www/admin/responses.adp"/> + <file type="content_page" path="www/admin/responses.tcl"/> + <file type="query_file" path="www/admin/responses.xql"/> + <file type="query_file" db_type="oracle" path="www/admin/send-mail-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/admin/send-mail-postgresql.xql"/> + <file type="content_page" path="www/admin/send-mail.adp"/> + <file type="content_page" path="www/admin/send-mail.tcl"/> + <file type="query_file" path="www/admin/send-mail.xql"/> + <file type="query_file" db_type="oracle" path="www/admin/survey-category-add-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/admin/survey-category-add-postgresql.xql"/> + <file type="content_page" path="www/admin/survey-category-add.tcl"/> + <file type="query_file" path="www/admin/survey-category-add.xql"/> + <file type="query_file" db_type="postgresql" path="www/admin/survey-copy-postgresql.xql"/> + <file type="content_page" path="www/admin/survey-copy.adp"/> + <file type="content_page" path="www/admin/survey-copy.tcl"/> + <file type="query_file" path="www/admin/survey-copy.xql"/> + <file type="content_page" path="www/admin/survey-create-choice.tcl"/> + <file type="content_page" path="www/admin/survey-create-confirm.adp"/> + <file type="query_file" db_type="oracle" path="www/admin/survey-create-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/admin/survey-create-postgresql.xql"/> + <file type="content_page" path="www/admin/survey-create.adp"/> + <file type="content_page" path="www/admin/survey-create.tcl"/> + <file type="query_file" path="www/admin/survey-create.xql"/> + <file type="query_file" db_type="oracle" path="www/admin/survey-delete-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/admin/survey-delete-postgresql.xql"/> + <file type="content_page" path="www/admin/survey-delete.adp"/> + <file type="content_page" path="www/admin/survey-delete.tcl"/> + <file type="content_page" path="www/admin/survey-display-type-edit.tcl"/> + <file type="query_file" path="www/admin/survey-display-type-edit.xql"/> + <file type="content_page" path="www/admin/survey-preview.adp"/> + <file type="content_page" path="www/admin/survey-preview.tcl"/> + <file type="query_file" path="www/admin/survey-preview.xql"/> + <file type="content_page" path="www/admin/survey-toggle.tcl"/> + <file type="query_file" path="www/admin/survey-toggle.xql"/> + <file type="query_file" db_type="oracle" path="www/admin/user-responses-delete-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/admin/user-responses-delete-postgresql.xql"/> + <file type="content_page" path="www/admin/user-responses-delete.adp"/> + <file type="content_page" path="www/admin/user-responses-delete.tcl"/> + <file type="query_file" db_type="oracle" path="www/admin/view-text-responses-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/admin/view-text-responses-postgresql.xql"/> + <file type="content_page" path="www/admin/view-text-responses.adp"/> + <file type="content_page" path="www/admin/view-text-responses.tcl"/> + <file type="query_file" path="www/admin/view-text-responses.xql"/> + <file type="documentation" path="www/doc/index.html"/> + <file type="query_file" db_type="oracle" path="www/index-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/index-postgresql.xql"/> + <file type="content_page" path="www/index.adp"/> + <file type="content_page" path="www/index.tcl"/> + <file type="content_page" path="www/master.adp"/> + <file type="content_page" path="www/one-respondent.adp"/> + <file type="content_page" path="www/one-respondent.tcl"/> + <file type="query_file" path="www/one-respondent.xql"/> + <file type="query_file" db_type="oracle" path="www/one-survey-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/one-survey-postgresql.xql"/> + <file type="content_page" path="www/one-survey.adp"/> + <file type="content_page" path="www/one-survey.tcl"/> + <file type="content_page" path="www/one_list.adp"/> + <file type="content_page" path="www/one_paragraph.adp"/> + <file type="content_page" path="www/one_table.adp"/> + <file type="query_file" db_type="oracle" path="www/process-response-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/process-response-postgresql.xql"/> + <file type="content_page" path="www/process-response.adp"/> + <file type="content_page" path="www/process-response.tcl"/> + <file type="query_file" path="www/process-response.xql"/> + <file type="query_file" db_type="oracle" path="www/respond-oracle.xql"/> + <file type="query_file" db_type="postgresql" path="www/respond-postgresql.xql"/> + <file type="content_page" path="www/respond.adp"/> + <file type="content_page" path="www/respond.tcl"/> + <file type="query_file" path="www/respond.xql"/> + <file type="query_file" db_type="postgresql" path="www/response-postgresql.xql"/> + <file type="content_page" path="www/view-attachment.tcl"/> + <file type="query_file" path="www/view-attachment.xql"/> + <file type="query_file" path="www/admin/site-wide-survey-oracle.xql"/> + <file type="content_page" path="www/admin/site-wide-survey.adp"/> + <file type="content_page" path="www/admin/site-wide-survey.tcl"/> + </files> + <parameters> + <parameter datatype="number" min_n_values="1" max_n_values="1" name="allow_question_deavtivation_p" default="0" description="Allow questions to be set inactive"/> + <parameter datatype="number" min_n_values="1" max_n_values="1" name="survey_enabled_default_p" default="0" description="Are surveys enabled by default upon creation?"/> + </parameters> + + </version> +</package> Index: openacs.org-dev/packages/survey/sql/oracle/survey-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/sql/oracle/survey-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/sql/oracle/survey-create.sql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,242 @@ +-- based on student work from 6.916 in Fall 1999 +-- which was in turn based on problem set 4 +-- in http://photo.net/teaching/one-term-web.html +-- +-- by philg@mit.edu and raj@alum.mit.edu on February 9, 2000 +-- converted to ACS 4.0 by nstrug@arsdigita.com on 29th September 2000 +-- modified for dotLRN/OpenACS4.5 and renamed from "simple-survey" to "survey" +-- by dave@thedesignexperience.org on 13 July 2002 +-- +-- $Id: survey-create.sql,v 1.1 2002/10/08 15:47:41 rmello Exp $ + +begin + + acs_privilege.create_privilege('survey_create_survey'); + acs_privilege.create_privilege('survey_modify_survey'); + acs_privilege.create_privilege('survey_delete_survey'); + acs_privilege.create_privilege('survey_create_question'); + acs_privilege.create_privilege('survey_modify_question'); + acs_privilege.create_privilege('survey_delete_question'); + acs_privilege.create_privilege('survey_take_survey'); + + acs_privilege.create_privilege('survey_admin_survey'); + + acs_privilege.add_child('survey_admin_survey','survey_create_survey'); + acs_privilege.add_child('survey_admin_survey','survey_modify_survey'); + acs_privilege.add_child('survey_admin_survey','survey_delete_survey'); + acs_privilege.add_child('survey_admin_survey','survey_create_question'); + acs_privilege.add_child('survey_admin_survey','survey_modify_question'); + acs_privilege.add_child('survey_admin_survey','survey_delete_question'); + + acs_privilege.add_child('read','survey_take_survey'); + acs_privilege.add_child('admin','survey_admin_survey'); + + acs_object_type.create_type ( + supertype => 'acs_object', + object_type => 'survey', + pretty_name => 'Survey', + pretty_plural => 'Surveys', + table_name => 'SURVEYS', + id_column => 'SURVEY_ID', + name_method => 'survey.name' + ); + acs_object_type.create_type ( + supertype => 'acs_object', + object_type => 'survey_section', + pretty_name => 'Survey_Section', + pretty_plural => 'Survey_Sections', + table_name => 'SURVEY_SECTIONS', + id_column => 'SECTION_ID' + ); + + acs_object_type.create_type ( + supertype => 'acs_object', + object_type => 'survey_question', + pretty_name => 'Survey Question', + pretty_plural => 'Survey Questions', + table_name => 'SURVEY_QUESTIONS', + id_column => 'QUESTION_ID' + ); + + acs_object_type.create_type ( + supertype => 'acs_object', + object_type => 'survey_response', + pretty_name => 'Survey Response', + pretty_plural => 'Survey Responses', + table_name => 'SURVEY_RESPONSES', + id_column => 'RESPONSE_ID' + ); + + +end; +/ +show errors + +create table surveys ( + survey_id constraint surveys_survey_id_fk + references acs_objects (object_id) + constraint surveys_pk + primary key, + name varchar(4000) + constraint surveys_name_nn + not null, + description varchar(4000) + constraint surveys_desc_nn + not null, + description_html_p char(1) + constraint surveys_desc_html_p_ck + check(description_html_p in ('t','f')), + enabled_p char(1) + constraint surveys_enabled_p_ck + check(enabled_p in ('t','f')), + -- limit to one response per user + single_response_p char(1) + constraint surveys_single_resp_p_ck + check(single_response_p in ('t','f')), + editable_p char(1) + constraint surveys_single_edit_p_ck + check(editable_p in ('t','f')), + single_section_p char(1) + constraint surveys_single_section_p_ck + check(single_section_p in ('t','f')), + type varchar(20), + display_type varchar(20), + package_id integer + constraint surveys_package_id_nn not null + constraint surveys_package_id_fk references + apm_packages (package_id) on delete cascade +); + +create table survey_sections ( + section_id constraint survey_sections_section_id_fk + references acs_objects (object_id) + constraint survey_sections_pk + primary key, + survey_id integer + constraint survey_sections_survey_id_nn + not null + constraint survey_sections_survey_id_fk + references surveys, + name varchar(4000) + constraint survey_sections_name_nn + not null, + description clob + constraint survey_sections_desc_nn + not null, + description_html_p char(1) + constraint survey_sections_desc_html_p_ck + check(description_html_p in ('t','f')) +); + +create index survey_sections_survey_id_fk on survey_sections(survey_id); + +create table survey_questions ( + question_id constraint survey_q_question_id_fk + references acs_objects (object_id) + constraint survey_q_question_id_pk + primary key, + section_id constraint survey_q_section_id_fk + references survey_sections, + sort_order integer + constraint survey_q_sort_order_nn + not null, + question_text clob + constraint survey_q_question_text_nn + not null, + abstract_data_type varchar(30) + constraint survey_q_abs_data_type_ck + check (abstract_data_type in ('text', 'shorttext', 'boolean', 'number', 'integer', 'choice', 'date','blob')), + required_p char(1) + constraint survey_q_required_p_ck + check (required_p in ('t','f')), + active_p char(1) + constraint survey_q_qctive_p_ck + check (active_p in ('t','f')), + presentation_type varchar(20) + constraint survey_q_pres_type_nn + not null + constraint survey_q_pres_type_ck + check(presentation_type in ('textbox','textarea','select','radio', 'checkbox', 'date', 'upload_file')), + -- for text, "small", "medium", "large" sizes + -- for textarea, "rows=X cols=X" + presentation_options varchar(50), + presentation_alignment varchar(15) + constraint survey_q_pres_alignment_ck + check(presentation_alignment in ('below','beside')) +); + +create index survey_q_sort_order on survey_questions(sort_order); +create index survey_q_active_p on survey_questions(active_p); + +-- for when a question has a fixed set of responses + +create sequence survey_choice_id_sequence start with 1; + +create table survey_question_choices ( + choice_id integer constraint survey_qc_choice_id_nn + not null + constraint survey_qc_choice_id_pk + primary key, + question_id constraint survey_qc_question_id_nn + not null + constraint survey_qc_question_id_fk + references survey_questions, + -- human readable + label varchar(500) constraint survey_qc_label_nn + not null, + -- might be useful for averaging or whatever, generally null + numeric_value number, + -- lower is earlier + sort_order integer +); + +create index survey_q_c_question_id on survey_question_choices(question_id); +create index survey_q_c_sort_order on survey_question_choices(sort_order); + +-- this records a response by one user to one survey +-- (could also be a proposal in which case we'll do funny +-- things like let the user give it a title, send him or her +-- email if someone comments on it, etc.) +create table survey_responses ( + response_id constraint survey_resp_response_id_fk + references acs_objects (object_id) + constraint srvsimp_resp_response_id_pk + primary key, + initial_response_id constraint init_resp_id_fk + references survey_responses (response_id), + survey_id constraint survey_resp_survey_id_fk + references surveys, + title varchar(100), + notify_on_comment_p char(1) + constraint survey_resp_noton_com_p_ck + check(notify_on_comment_p in ('t','f')) +); + + + +-- this table stores the answers to each question for a survey +-- we want to be able to hold different data types in one long skinny table +-- but we also may want to do averages, etc., so we can't just use CLOBs + +create table survey_question_responses ( + response_id not null references survey_responses, + question_id not null references survey_questions, + -- if the user picked a canned response + choice_id references survey_question_choices, + boolean_answer char(1) check(boolean_answer in ('t','f')), + clob_answer clob, + number_answer number, + varchar_answer varchar(4000), + date_answer date, + attachment_answer integer + constraint survey_q_resp_rev_id_fk + references cr_revisions(revision_id) + on delete cascade +); + +create index survey_response_index on survey_question_responses (response_id, question_id); +create index survey_q_r_choice_id on survey_question_responses(choice_id); +create index survey_q_r_attachment_answer on survey_question_responses(attachment_answer); + +@@ survey-package-create.sql +@@ survey-notifications-init.sql \ No newline at end of file Index: openacs.org-dev/packages/survey/sql/oracle/survey-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/sql/oracle/survey-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/sql/oracle/survey-drop.sql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,59 @@ +-- +-- drop SQL for survey package +-- +-- by nstrug@arsdigita.com on 29th September 2000 +-- +-- $Id: survey-drop.sql,v 1.1 2002/10/08 15:47:41 rmello Exp $ + +@@ survey-package-drop.sql + +drop view survey_ques_responses_latest; +drop table survey_question_responses cascade constraints; +drop view survey_responses_latest; +drop table survey_responses cascade constraints; +drop table survey_question_choices cascade constraints; + +drop sequence survey_choice_id_sequence; +drop table survey_questions cascade constraints; +drop table survey_sections cascade constraints; +drop table surveys cascade constraints; + +-- nuke all created objects +-- need to do this before nuking the types +delete from acs_objects where object_type = 'survey_response'; +delete from acs_objects where object_type = 'survey_question'; +delete from acs_objects where object_type = 'survey_section'; +delete from acs_objects where object_type = 'survey'; + +begin + acs_rel_type.drop_type('user_blob_response_rel'); + + acs_object_type.drop_type ('survey_response'); + acs_object_type.drop_type ('survey_question'); + acs_object_type.drop_type ('survey_section'); + acs_object_type.drop_type ('survey'); + + acs_privilege.remove_child ('admin','survey_admin_survey'); + acs_privilege.remove_child ('read','survey_take_survey'); + acs_privilege.remove_child ('survey_admin_survey','survey_delete_question'); + acs_privilege.remove_child ('survey_admin_survey','survey_modify_question'); + acs_privilege.remove_child ('survey_admin_survey','survey_create_question'); + acs_privilege.remove_child ('survey_admin_survey','survey_delete_survey'); + acs_privilege.remove_child ('survey_admin_survey','survey_modify_survey'); + acs_privilege.remove_child ('survey_admin_survey','survey_create_survey'); + + acs_privilege.drop_privilege('survey_admin_survey'); + acs_privilege.drop_privilege('survey_take_survey'); + acs_privilege.drop_privilege('survey_delete_question'); + acs_privilege.drop_privilege('survey_modify_question'); + acs_privilege.drop_privilege('survey_create_question'); + acs_privilege.drop_privilege('survey_delete_survey'); + acs_privilege.drop_privilege('survey_modify_survey'); + acs_privilege.drop_privilege('survey_create_survey'); + + +end; +/ +show errors + + Index: openacs.org-dev/packages/survey/sql/oracle/survey-notifications-init.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/sql/oracle/survey-notifications-init.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/sql/oracle/survey-notifications-init.sql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,62 @@ +-- +-- Survey +-- +-- -- @author dave@thedesignexperience.org, ben@openforce.biz +-- @creation-date 2002-08-03 +-- +-- integration with Notifications +declare + impl_id integer; + v_foo integer; +begin + -- the notification type impl + impl_id := acs_sc_impl.new ( + 'NotificationType', + 'survey_response_notif_type', + 'survey' + ); + + v_foo := acs_sc_impl.new_alias ( + 'NotificationType', + 'survey_response_notif_type', + 'GetURL', + 'survey::notification::get_url', + 'TCL' + ); + + v_foo := acs_sc_impl.new_alias ( + 'NotificationType', + 'survey_response_notif_type', + 'ProcessReply', + 'survey::notification::process_reply', + 'TCL' + ); + + acs_sc_binding.new ( + contract_name => 'NotificationType', + impl_name => 'survey_response_notif_type' + ); + + v_foo:= notification_type.new ( + short_name => 'survey_response_notif', + sc_impl_id => impl_id, + pretty_name => 'Survey Response', + description => 'Notifications for Survey', + creation_user => NULL, + creation_ip => NULL + ); + + -- enable the various intervals and delivery methods + insert into notification_types_intervals + (type_id, interval_id) + select v_foo, interval_id + from notification_intervals where name in ('instant','hourly','daily'); + + insert into notification_types_del_methods + (type_id, delivery_method_id) + select v_foo, delivery_method_id + from notification_delivery_methods where short_name in ('email'); + +end; +/ +show errors Index: openacs.org-dev/packages/survey/sql/oracle/survey-package-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/sql/oracle/survey-package-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/sql/oracle/survey-package-create.sql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,484 @@ +-- start off with package declarations + + +create or replace package survey +as + function new ( + survey_id in surveys.survey_id%TYPE default null, + name in surveys.name%TYPE, + description in surveys.description%TYPE, + description_html_p in surveys.description_html_p%TYPE default 'f', + single_response_p in surveys.single_response_p%TYPE default 'f', + editable_p in surveys.editable_p%TYPE default 't', + enabled_p in surveys.enabled_p%TYPE default 'f', + single_section_p in surveys.single_section_p%TYPE default 't', + type in surveys.type%TYPE default 'general', + display_type in surveys.display_type%TYPE default 'list', + package_id in surveys.package_id%TYPE, + object_type in acs_objects.object_type%TYPE default 'survey', + creation_date in acs_objects.creation_date%TYPE default sysdate, + creation_user in acs_objects.creation_user%TYPE default null, + creation_ip in acs_objects.creation_ip%TYPE default null, + context_id in acs_objects.context_id%TYPE default null +) return acs_objects.object_id%TYPE; + + procedure remove ( + survey_id in surveys.survey_id%TYPE + ); + + function name ( + survey_id in surveys.survey_id%TYPE + ) return varchar; + +end survey; +/ +show errors + + + +-- survey_section + +create or replace package survey_section +as + function new ( + section_id in survey_sections.section_id%TYPE default null, + survey_id in survey_sections.survey_id%TYPE default null, + name in survey_sections.name%TYPE default null, + description in survey_sections.description%TYPE default null, + description_html_p in survey_sections.description_html_p%TYPE default null, + object_type in acs_objects.object_type%TYPE default 'survey_section', + creation_date in acs_objects.creation_date%TYPE default sysdate, + creation_user in acs_objects.creation_user%TYPE default null, + creation_ip in acs_objects.creation_ip%TYPE default null, + context_id in acs_objects.context_id%TYPE default null + ) return acs_objects.object_id%TYPE; + + procedure remove ( + section_id in survey_sections.section_id%TYPE + ); +end survey_section; +/ +show errors + +-- +-- constructor for a survey_question +-- + +create or replace package survey_question +as + function new ( + question_id in survey_questions.question_id%TYPE default null, + section_id in survey_questions.section_id%TYPE default null, + sort_order in survey_questions.sort_order%TYPE default null, + question_text in survey_questions.question_text%TYPE default null, + abstract_data_type in survey_questions.abstract_data_type%TYPE default null, + required_p in survey_questions.required_p%TYPE default 't', + active_p in survey_questions.active_p%TYPE default 't', + presentation_type in survey_questions.presentation_type%TYPE default null, + presentation_options in survey_questions.presentation_options%TYPE default null, + presentation_alignment in survey_questions.presentation_alignment%TYPE default 'below', + object_type in acs_objects.object_type%TYPE default 'survey_question', + creation_date in acs_objects.creation_date%TYPE default sysdate, + creation_user in acs_objects.creation_user%TYPE default null, + creation_ip in acs_objects.creation_ip%TYPE default null, + context_id in acs_objects.context_id%TYPE default null + ) return acs_objects.object_id%TYPE; + + procedure remove ( + question_id in survey_questions.question_id%TYPE + ); +end survey_question; +/ +show errors + + +-- +-- constructor for a survey_response +-- + +create or replace package survey_response +as + function new ( + response_id in survey_responses.response_id %TYPE default null, + survey_id in survey_responses.survey_id%TYPE default null, + title in survey_responses.title%TYPE default null, + notify_on_comment_p in survey_responses.notify_on_comment_p%TYPE default 'f', + object_type in acs_objects.object_type%TYPE default 'survey_response', + creation_date in acs_objects.creation_date%TYPE default sysdate, + creation_user in acs_objects.creation_user%TYPE default null, + creation_ip in acs_objects.creation_ip%TYPE default null, + context_id in acs_objects.context_id%TYPE default null, + initial_response_id in survey_responses.initial_response_id%TYPE default null + ) return acs_objects.object_id%TYPE; + + function initial_response_id ( + response_id in survey_responses.response_id%TYPE + ) return survey_responses.response_id%TYPE; + + function initial_user_id ( + response_id in survey_responses.response_id%TYPE + ) return acs_objects.creation_user%TYPE; + + procedure remove ( + response_id in survey_responses.response_id%TYPE + ); + + procedure del ( + response_id in survey_responses.response_id%TYPE + ); + + function boolean_answer ( + answer varchar, + question_id survey_questions.question_id%TYPE + ) return varchar; + +end survey_response; +/ +show errors + + +-- next we define the package bodies + +create or replace package body survey +as + function new ( + survey_id in surveys.survey_id%TYPE default null, + name in surveys.name%TYPE, + description in surveys.description%TYPE, + description_html_p in surveys.description_html_p%TYPE default 'f', + single_response_p in surveys.single_response_p%TYPE default 'f', + editable_p in surveys.editable_p%TYPE default 't', + enabled_p in surveys.enabled_p%TYPE default 'f', + single_section_p in surveys.single_section_p%TYPE default 't', + type in surveys.type%TYPE default 'general', + display_type in surveys.display_type%TYPE default 'list', + package_id in surveys.package_id%TYPE, + object_type in acs_objects.object_type%TYPE default 'survey', + creation_date in acs_objects.creation_date%TYPE default sysdate, + creation_user in acs_objects.creation_user%TYPE default null, + creation_ip in acs_objects.creation_ip%TYPE default null, + context_id in acs_objects.context_id%TYPE default null + ) return acs_objects.object_id%TYPE + is + v_survey_id surveys.survey_id%TYPE; + begin + v_survey_id := acs_object.new ( + object_id => survey_id, + object_type => object_type, + creation_date => creation_date, + creation_user => creation_user, + creation_ip => creation_ip, + context_id => context_id + ); + insert into surveys + (survey_id, name, description, description_html_p, + single_response_p, editable_p, enabled_p, single_section_p, type, display_type, package_id) + values + (v_survey_id, new.name, new.description, new.description_html_p, + new.single_response_p, new.editable_p, new.enabled_p, new.single_section_p, new.type, new.display_type, new.package_id); + + return v_survey_id; + end new; + + procedure remove ( + survey_id surveys.survey_id%TYPE + ) + is + v_response_row survey_responses%ROWTYPE; + v_section_row survey_sections%ROWTYPE; + begin + + for v_response_row in (select response_id + from survey_responses + where survey_id=remove.survey_id + and initial_response_id is NULL) loop + survey_response.remove(v_response_row.response_id); + end loop; + + for v_section_row in (select section_id + from survey_sections + where survey_id=remove.survey_id) loop + survey_section.remove(v_section_row.section_id); + end loop; + + delete from surveys where survey_id=remove.survey_id; + acs_object.delete(survey_id); + end remove; + + function name ( + survey_id in surveys.survey_id%TYPE + ) return varchar + is + v_name surveys.name%TYPE; + begin + select name + into v_name + from surveys + where survey_id = name.survey_id; + + return v_name; + end name; +end survey; +/ +show errors + + +create or replace package body survey_section +as + function new ( + section_id in survey_sections.section_id%TYPE default null, + survey_id in survey_sections.survey_id%TYPE default null, + name in survey_sections.name%TYPE default null, + description in survey_sections.description%TYPE default null, + description_html_p in survey_sections.description_html_p%TYPE default null, + object_type in acs_objects.object_type%TYPE default 'survey_section', + creation_date in acs_objects.creation_date%TYPE default sysdate, + creation_user in acs_objects.creation_user%TYPE default null, + creation_ip in acs_objects.creation_ip%TYPE default null, + context_id in acs_objects.context_id%TYPE default null + + ) return acs_objects.object_id%TYPE + is + v_section_id survey_sections.section_id%TYPE; + begin + v_section_id := acs_object.new ( + object_id => section_id, + object_type => object_type, + creation_date => creation_date, + creation_user => creation_user, + creation_ip => creation_ip, + context_id => context_id + ); + insert into survey_sections + (section_id, survey_id, name, description, description_html_p) + values + (v_section_id, new.survey_id, new.name, new.description, new.description_html_p); + + return v_section_id; + end new; + + procedure remove ( + section_id in survey_sections.section_id%TYPE + ) is + v_question_row survey_questions%ROWTYPE; + begin + for v_question_row in (select question_id + from survey_questions + where section_id=remove.section_id) loop + survey_question.remove(v_question_row.question_id); + end loop; + delete from survey_sections where section_id=remove.section_id; + acs_object.delete(remove.section_id); + end remove; +end survey_section; +/ +show errors + + +create or replace package body survey_question +as + function new ( + question_id in survey_questions.question_id%TYPE default null, + section_id in survey_questions.section_id%TYPE default null, + sort_order in survey_questions.sort_order%TYPE default null, + question_text in survey_questions.question_text%TYPE default null, + abstract_data_type in survey_questions.abstract_data_type%TYPE default null, + required_p in survey_questions.required_p%TYPE default 't', + active_p in survey_questions.active_p%TYPE default 't', + presentation_type in survey_questions.presentation_type%TYPE default null, + presentation_options in survey_questions.presentation_options%TYPE default null, + presentation_alignment in survey_questions.presentation_alignment%TYPE default 'below', + object_type in acs_objects.object_type%TYPE default 'survey_question', + creation_date in acs_objects.creation_date%TYPE default sysdate, + creation_user in acs_objects.creation_user%TYPE default null, + creation_ip in acs_objects.creation_ip%TYPE default null, + context_id in acs_objects.context_id%TYPE default null + ) return acs_objects.object_id%TYPE + is + v_question_id survey_questions.question_id%TYPE; + begin + v_question_id := acs_object.new ( + object_id => question_id, + object_type => object_type, + creation_date => creation_date, + creation_user => creation_user, + creation_ip => creation_ip, + context_id => section_id + ); + insert into survey_questions + (question_id, section_id, sort_order, question_text, abstract_data_type, + required_p, active_p, presentation_type, presentation_options, + presentation_alignment) + values + (v_question_id, new.section_id, new.sort_order, new.question_text, new.abstract_data_type, + new.required_p, new.active_p, new.presentation_type, new.presentation_options, + new.presentation_alignment); + return v_question_id; + end new; + + procedure remove ( + question_id in survey_questions.question_id%TYPE + ) + is + begin + + delete from survey_question_responses + where question_id=remove.question_id; + delete from survey_question_choices + where question_id=remove.question_id; + delete from survey_questions + where question_id = remove.question_id; + acs_object.delete(remove.question_id); + end remove; +end survey_question; +/ +show errors + + +create or replace package body survey_response +as + function new ( + response_id in survey_responses.response_id %TYPE default null, + survey_id in survey_responses.survey_id%TYPE default null, + title in survey_responses.title%TYPE default null, + notify_on_comment_p in survey_responses.notify_on_comment_p%TYPE default 'f', + object_type in acs_objects.object_type%TYPE default 'survey_response', + creation_date in acs_objects.creation_date%TYPE default sysdate, + creation_user in acs_objects.creation_user%TYPE default null, + creation_ip in acs_objects.creation_ip%TYPE default null, + context_id in acs_objects.context_id%TYPE default null, + initial_response_id in survey_responses.initial_response_id%TYPE default null + ) return acs_objects.object_id%TYPE + is + v_response_id survey_responses.response_id%TYPE; + begin + v_response_id := acs_object.new ( + object_id => response_id, + object_type => object_type, + creation_date => creation_date, + creation_user => creation_user, + creation_ip => creation_ip, + context_id => context_id + ); + insert into survey_responses (response_id, survey_id, title, notify_on_comment_p, initial_response_id) + values + (v_response_id, new.survey_id, new.title, new.notify_on_comment_p, new.initial_response_id); + return v_response_id; + end new; + + function initial_response_id ( + response_id in survey_responses.response_id%TYPE + ) return survey_responses.response_id%TYPE + is + v_initial_response_id survey_responses.response_id%TYPE; + begin + select initial_response_id into v_initial_response_id + from survey_responses where + response_id = initial_response_id.response_id; + if v_initial_response_id is NULL then + v_initial_response_id := initial_response_id.response_id; + end if; + return v_initial_response_id; + end initial_response_id; + + function initial_user_id ( + response_id in survey_responses.response_id%TYPE + ) return acs_objects.creation_user%TYPE + is + v_user_id acs_objects.creation_user%TYPE; + begin + select creation_user into v_user_id + from acs_objects + where object_id = survey_response.initial_response_id(initial_user_id.response_id); + return v_user_id; + end initial_user_id; + + procedure remove ( + response_id in survey_responses.response_id%TYPE + ) is + v_response_row survey_responses%ROWTYPE; + begin + for v_response_row in (select response_id from survey_responses + where initial_response_id=remove.response_id) loop + survey_response.del(v_response_row.response_id); + end loop; + + survey_response.del(remove.response_id); + end remove; + + procedure del ( + response_id in survey_responses.response_id%TYPE + ) + is + v_question_response_row survey_question_responses%ROWTYPE; + begin + for v_question_response_row in ( + select item_id + from survey_question_responses, cr_revisions + where response_id=del.response_id + and attachment_answer=revision_id) + loop + content_item.delete(v_question_response_row.item_id); + end loop; + + delete from survey_question_responses + where response_id=del.response_id; + delete from survey_responses + where response_id=del.response_id; + acs_object.delete(del.response_id); + end del; + + function boolean_answer ( + answer varchar, + question_id survey_questions.question_id%TYPE + ) return varchar + is + v_answer varchar(100); + v_presentation_options survey_questions.presentation_options%TYPE; + v_split_pos integer; + begin + + if answer is NOT NULL then + select presentation_options into v_presentation_options + from survey_questions where question_id=boolean_answer.question_id; + + v_split_pos:= instr(v_presentation_options, '/'); + + if answer = 't' then + v_answer:=substr(v_presentation_options, 1, v_split_pos -1 ); + end if; + if answer = 'f' then + v_answer:=substr(v_presentation_options, v_split_pos + 1 ); + end if; + + else + v_answer := ''; + end if; + return v_answer; + end boolean_answer; + +end survey_response; +/ +show errors + + +-- these views depend on functions in this file -DaveB +-- this view contains only the most recently edited version +-- of each survey response. + +create or replace view survey_responses_latest as +select sr.*, o.creation_date, + o.creation_user, + survey_response.initial_user_id(sr.response_id) as initial_user_id + from survey_responses sr, + acs_objects o, + (select max(response_id) as response_id + from survey_responses + group by survey_response.initial_response_id(response_id)) latest + where sr.response_id = o.object_id + and sr.response_id= latest.response_id; + +create or replace view survey_ques_responses_latest as +select qr.* + from survey_question_responses qr, survey_responses_latest r + where qr.response_id=r.response_id; Index: openacs.org-dev/packages/survey/sql/oracle/survey-package-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/sql/oracle/survey-package-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/sql/oracle/survey-package-drop.sql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,4 @@ +drop package survey_response; +drop package survey_question; +drop package survey_section; +drop package survey; Index: openacs.org-dev/packages/survey/sql/postgresql/survey-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/sql/postgresql/survey-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/sql/postgresql/survey-create.sql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,557 @@ +-- ported to OpenACS 4 by Gilbert Wong (gwong@orchardlabs.com) on 2001-05-20 +-- +-- based on student work from 6.916 in Fall 1999 +-- which was in turn based on problem set 4 +-- in http://photo.net/teaching/one-term-web.html +-- +-- by philg@mit.edu and raj@alum.mit.edu on February 9, 2000 +-- converted to ACS 4.0 by nstrug@arsdigita.com on 29th September 2000 +-- modified for dotLRN/OpenACS4.5 and renamed from "simple-survey" to "survey" +-- by dave@thedesignexperience.org on 13 July 2002 +-- +-- $Id: survey-create.sql,v 1.1 2002/10/08 15:47:41 rmello Exp $ + +create function inline_0 () +returns integer as ' +begin + PERFORM acs_privilege__create_privilege(''survey_create_survey'', null, null); + PERFORM acs_privilege__create_privilege(''survey_modify_survey'', null, null); + PERFORM acs_privilege__create_privilege(''survey_delete_survey'', null, null); + PERFORM acs_privilege__create_privilege(''survey_create_question'', null, null); + PERFORM acs_privilege__create_privilege(''survey_modify_question'', null, null); + PERFORM acs_privilege__create_privilege(''survey_delete_question'', null, null); + PERFORM acs_privilege__create_privilege(''survey_take_survey'', null, null); + PERFORM acs_privilege__create_privilege(''survey_admin_survey'', null, null); + + return 0; + +end;' language 'plpgsql'; + +select inline_0 (); +drop function inline_0 (); + + +begin; + -- temporarily drop this trigger to avoid a data-change violation + -- on acs_privilege_hierarchy_index while updating the child privileges. + drop trigger acs_priv_hier_ins_del_tr on acs_privilege_hierarchy; + + select acs_privilege__add_child('survey_admin_survey','survey_create_survey'); + select acs_privilege__add_child('survey_admin_survey','survey_modify_survey'); + select acs_privilege__add_child('survey_admin_survey','survey_delete_survey'); + select acs_privilege__add_child('survey_admin_survey','survey_create_question'); + select acs_privilege__add_child('survey_admin_survey','survey_modify_question'); + select acs_privilege__add_child('survey_admin_survey','survey_delete_question'); + + select acs_privilege__add_child('read','survey_take_survey'); + + -- re-enable the trigger before the last insert to force the + -- acs_privilege_hierarchy_index table to be updated. + + create trigger acs_priv_hier_ins_del_tr after insert or delete + on acs_privilege_hierarchy for each row + execute procedure acs_priv_hier_ins_del_tr (); + + select acs_privilege__add_child('admin','survey_admin_survey'); + +end; + + + +create function inline_1 () +returns integer as ' +begin + + PERFORM acs_object_type__create_type ( + ''survey'', + ''Survey'', + ''Surveys'', + ''acs_object'', + ''surveys'', + ''survey_id'', + null, + ''f'', + null, + null + ); + + PERFORM acs_object_type__create_type ( + ''survey_section'', + ''Survey Section'', + ''Survey Sections'', + ''acs_object'', + ''survey_sections'', + ''section_id'', + null, + ''f'', + null, + null + ); + + PERFORM acs_object_type__create_type ( + ''survey_question'', + ''Survey Question'', + ''Survey Questions'', + ''acs_object'', + ''survey_questions'', + ''question_id'', + null, + ''f'', + null, + null + ); + + PERFORM acs_object_type__create_type ( + ''survey_response'', + ''Survey Response'', + ''Survey Responses'', + ''acs_object'', + ''survey_responses'', + ''response_id'', + null, + ''f'', + null, + null + ); + + return 0; + +end;' language 'plpgsql'; + +select inline_1 (); +drop function inline_1 (); + +create table surveys ( + survey_id integer constraint surveys_survey_id_fk + references acs_objects (object_id) + on delete cascade + constraint surveys_pk + primary key, + name varchar(4000) + constraint surveys_name_nn + not null, + description text + constraint surveys_desc_nn + not null, + description_html_p boolean not null, + enabled_p boolean not null, + -- limit to one response per user + single_response_p boolean not null, + editable_p boolean not null, + single_section_p boolean not null, + type varchar(20), + display_type varchar(20), + package_id integer constraint surveys_package_id_nn + not null + constraint surveys_package_id_fk + references apm_packages (package_id) on delete cascade +); + + +create table survey_sections ( + section_id integer constraint survey_sections_section_id_fk + references acs_objects (object_id) + constraint survey_sections_pk + primary key, + survey_id integer + constraint survey_sections_survey_id_nn + not null + constraint survey_sections_survey_id_fk + references surveys, + name varchar(4000) + constraint survey_sections_name_nn + not null, + description text + constraint survey_sections_desc_nn + not null, + description_html_p boolean +); + +create index survey_sections_survey_id_fk on survey_sections(survey_id); +-- each question can be + +create table survey_questions ( + question_id integer constraint survey_q_question_id_fk + references acs_objects (object_id) + on delete cascade + constraint survey_q_question_id_pk + primary key, + section_id integer constraint survey_q_section_id_fk + references survey_sections + on delete cascade, + sort_order integer + constraint survey_q_sort_order_nn + not null, + question_text text + constraint survey_q_question_text_nn + not null, + abstract_data_type varchar(30) + constraint survey_q_abs_data_type_ck + check (abstract_data_type in ('text', 'shorttext', 'boolean', 'number', 'integer', 'choice','date')), + required_p boolean, + active_p boolean, + presentation_type varchar(20) + constraint survey_q_pres_type_nn + not null + constraint survey_q_pres_type_ck + check(presentation_type in ('textbox','textarea','select','radio', 'checkbox', 'date', 'upload_file')), + -- for text, "small", "medium", "large" sizes + -- for textarea, "rows=X cols=X" + presentation_options varchar(50), + presentation_alignment varchar(15) + constraint survey_q_pres_alignment_ck + check(presentation_alignment in ('below','beside')) +); + + +create index survey_q_sort_order on survey_questions(sort_order); +create index survey_q_active_p on survey_questions(active_p); + +-- for when a question has a fixed set of responses + +create sequence survey_choice_id_seq; +create view survey_choice_id_sequence as select nextval('survey_choice_id_seq') as nextval; + +create table survey_question_choices ( + choice_id integer constraint survey_qc_choice_id_nn + not null + constraint survey_qc_choice_id_pk + primary key, + question_id integer constraint survey_qc_question_id_nn + not null + constraint survey_qc_question_id_fk + references survey_questions + on delete cascade, + -- human readable + label varchar(500) constraint survey_qc_label_nn + not null, + -- might be useful for averaging or whatever, generally null + numeric_value numeric, + -- lower is earlier + sort_order integer +); + + +create index survey_q_c_question_id on survey_question_choices(question_id); +create index survey_q_c_sort_order on survey_question_choices(sort_order); + +-- this records a response by one user to one survey +-- (could also be a proposal in which case we'll do funny +-- things like let the user give it a title, send him or her +-- email if someone comments on it, etc.) +create table survey_responses ( + response_id integer constraint survey_resp_response_id_fk + references acs_objects (object_id) + on delete cascade + constraint survey_resp_response_id_pk + primary key, + initial_response_id integer constraint survey_resp_initial_fk + references survey_responses(response_id), + survey_id integer constraint survey_resp_survey_id_fk + references surveys + on delete cascade, + title varchar(100), + notify_on_comment_p boolean +); + + +-- this view contains only the most recently edited version +-- of each survey response. + + + +-- this table stores the answers to each question for a survey +-- we want to be able to hold different data types in one long skinny table +-- but we also may want to do averages, etc., so we can't just use CLOBs + +create table survey_question_responses ( + response_id integer constraint survey_qr_response_id_nn + not null + constraint survey_qr_response_id_fk + references survey_responses + on delete cascade, + question_id integer constraint survey_qr_question_id_nn + not null + constraint survey_qr_question_id_fk + references survey_questions + on delete cascade, + -- if the user picked a canned response + choice_id integer constraint survey_qr_choice_id_fk + references survey_question_choices + on delete cascade, + boolean_answer boolean, + clob_answer text, + number_answer numeric, + varchar_answer text, + date_answer timestamp, + attachment_answer integer + constraint survey_q_response_item_id_fk + references cr_items(item_id) + on delete cascade +); + +create index survey_q_r_choice_id on survey_question_responses(choice_id); +create index survey_q_r_attachment_answer on survey_question_responses(attachment_answer); +create index survey_response_index on survey_question_responses (response_id, question_id); + +-- We create a view that selects out only the last response from each +-- user to give us at most 1 response from all users. +-- create or replace view survey_question_responses_un as +-- select qr.* +-- from survey_question_responses qr, survey_responses_unique r +-- where qr.response_id=r.response_id; + + +-- API for survey objects + +create function survey__new (integer,varchar,text,boolean,boolean,boolean,boolean,boolean,varchar,varchar,integer,integer,integer) +returns integer as ' +declare + new__survey_id alias for $1; -- default null + new__name alias for $2; + new__description alias for $3; + new__description_html_p alias for $4; -- default f + new__single_response_p alias for $5; -- default f + new__editable_p alias for $6; -- default t + new__enabled_p alias for $7; -- default f + new__single_section_p alias for $8; -- default t + new__type alias for $9; -- default general + new__display_type alias for $10; + new__package_id alias for $11; + new__creation_user alias for $12; -- default null + new__context_id alias for $13; -- default null + v_survey_id integer; +begin + v_survey_id := acs_object__new ( + new__survey_id, + ''survey'', + now(), + new__creation_user, + null, + new__context_id + ); + + insert into surveys + (survey_id, name, description, + description_html_p, single_response_p, editable_p, + enabled_p, single_section_p, type, display_type, package_id) + values + (v_survey_id, new__name, new__description, + new__description_html_p, new__single_response_p, new__editable_p, + new__enabled_p, new__single_section_p, new__type, new__display_type, new__package_id); + + return v_survey_id; + +end;' language 'plpgsql'; + + +create function survey__delete (integer) +returns integer as ' +declare + delete__survey_id alias for $1; +begin + delete from surveys + where survey_id = delete__survey_id; + + PERFORM acs_object__delete(delete__survey_id); + + return 0; + +end;' language 'plpgsql'; + + +-- API for survey_section objects + +create function survey_section__new (integer,integer,varchar,text,boolean,integer,integer) +returns integer as ' +declare + new__section_id alias for $1; -- default null + new__survey_id alias for $2; -- default null + new__name alias for $3; -- default null + new__description alias for $4; -- default null + new__description_html_p alias for $5; -- default f + new__creation_user alias for $6; -- default null + new__context_id alias for $7; -- default null + v_section_id integer; +begin + v_section_id := acs_object__new ( + new__section_id, + ''survey_section'', + now(), + new__creation_user, + null, + new__context_id + ); + + insert into survey_sections + (section_id, survey_id, name, description, description_html_p) + values + (v_section_id, new__survey_id, new__name, new__description, new__description_html_p); + + return v_section_id; + +end;' language 'plpgsql'; + +create function survey_section__delete (integer) +returns integer as ' +declare + delete__section_id alias for $1; +begin + delete from survey_sections + where section_id = delete__section_id; + + PERFORM acs_object__delete(delete__section_id); + + return 0; + +end;' language 'plpgsql'; + +create function survey_question__new (integer,integer,integer,text,varchar,boolean,boolean,varchar,varchar,varchar,integer,integer) +returns integer as ' +declare + new__question_id alias for $1; -- default null + new__section_id alias for $2; -- default null + new__sort_order alias for $3; -- default null + new__question_text alias for $4; -- default null + new__abstract_data_type alias for $5; -- default null + new__required_p alias for $6; -- default t + new__active_p alias for $7; -- default + new__presentation_type alias for $8; -- default null + new__presentation_options alias for $9; -- default null + new__presentation_alignment alias for $10; -- default below + new__creation_user alias for $11; -- default null + new__context_id alias for $12; -- default null + v_question_id integer; +begin + v_question_id := acs_object__new ( + new__question_id, + ''survey_question'', + now(), + new__creation_user, + null, + new__context_id + ); + + insert into survey_questions + (question_id, section_id, sort_order, question_text, + abstract_data_type, required_p, active_p, + presentation_type, presentation_options, + presentation_alignment) + values + (v_question_id, new__section_id, new__sort_order, new__question_text, + new__abstract_data_type, new__required_p, new__active_p, + new__presentation_type, new__presentation_options, + new__presentation_alignment); + + return v_question_id; + +end;' language 'plpgsql'; + +-- procedure delete +create function survey_question__delete (integer) +returns integer as ' +declare + delete__question_id alias for $1; +begin + delete from survey_questions + where question_id = delete__question_id; + + PERFORM acs_object__delete(delete__question_id); + + return 0; + +end;' language 'plpgsql'; + + +-- create or replace package body survey_response +-- procedure new +create function survey_response__new(integer,integer,varchar,boolean,integer,varchar,integer,integer) +returns integer as ' +declare + new__response_id alias for $1; -- default null + new__survey_id alias for $2; -- default null + new__title alias for $3; -- default null + new__notify_on_comment_p alias for $4; -- default f + new__creation_user alias for $5; -- default null + new__creation_ip alias for $6; -- default null + new__context_id alias for $7; -- default null + new__initial_response_id alias for $8; -- default null + v_response_id integer; +begin + v_response_id := acs_object__new ( + new__response_id, + ''survey_response'', + now(), + new__creation_user, + new__creation_ip, + new__context_id + ); + + insert into survey_responses + (response_id, survey_id, title, notify_on_comment_p, initial_response_id) + values + (v_response_id, new__survey_id, new__title, new__notify_on_comment_p, new__initial_response_id); + + return v_response_id; + +end;' language 'plpgsql'; + +--function initial_response_id +create function survey_response__initial_response_id(integer) +returns integer as ' +declare + p_response_id alias for $1; + v_initial_response_id integer; +begin + select into v_initial_response_id initial_response_id from + survey_responses where response_id = p_response_id; + if v_initial_response_id is NULL then + v_initial_response_id := p_response_id; + end if; + return v_initial_response_id; +end;' language 'plpgsql'; + +create function survey_response__initial_user_id (integer) +returns integer as ' +declare +p_response_id alias for $1; +v_user_id integer; +begin + select into v_user_id creation_user + from acs_objects where + object_id = survey_response__initial_response_id(p_response_id); +return v_user_id; +end;' language 'plpgsql'; + +-- procedure delete +create function survey_response__delete(integer) +returns integer as ' +declare + delete__response_id alias for $1; +begin + delete from survey_responses + where response_id = delete__response_id; + + PERFORM acs_object__delete(delete__response_id); + + return 0; + +end;' language 'plpgsql'; + +create view survey_responses_latest as +select sr.*, o.creation_date, + o.creation_user, + survey_response__initial_user_id(sr.response_id) as initial_user_id + from survey_responses sr + join acs_objects o + on (sr.response_id = o.object_id) + join (select max(response_id) as response_id + from survey_responses + group by survey_response__initial_response_id(response_id)) latest + on (sr.response_id = latest.response_id); + +create view survey_ques_responses_latest as +select qr.* + from survey_question_responses qr, survey_responses_latest r + where qr.response_id=r.response_id; + Index: openacs.org-dev/packages/survey/sql/postgresql/survey-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/sql/postgresql/survey-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/sql/postgresql/survey-drop.sql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,76 @@ +-- +-- drop SQL for survey package +-- +-- by nstrug@arsdigita.com on 29th September 2000 +-- +-- $Id: survey-drop.sql,v 1.1 2002/10/08 15:47:41 rmello Exp $ + +select drop_package('survey_response'); +select drop_package('survey_question'); +select drop_package('survey_section'); +select drop_package('survey'); + +drop table survey_logic_surveys_map; +drop view survey_logic_id_sequence; +drop sequence survey_logic_id_seq; +drop table survey_logic; +drop table survey_choice_scores; +drop table survey_variables_surveys_map; +drop table survey_variables; +drop view survey_variable_id_sequence; +drop sequence survey_variable_id_seq; +drop view survey_responses_latest; +drop view survey_ques_responses_latest; +drop table survey_question_responses; +drop table survey_responses; +drop table survey_question_choices; +drop view survey_choice_id_sequence; +drop sequence survey_choice_id_seq; +drop table survey_questions; +drop table survey_sections; +drop table surveys; + +-- nuke all created objects +-- need to do this before nuking the types +delete from acs_objects where object_type = 'survey_response'; +delete from acs_objects where object_type = 'survey_question'; +delete from acs_objects where object_type = 'survey_section'; +delete from acs_objects where object_type = 'survey'; + +create function inline_0 () +returns integer as ' +begin + + PERFORM acs_object_type__drop_type (''survey_response'',''f''); + PERFORM acs_object_type__drop_type (''survey_question'',''f''); + PERFORM acs_object_type__drop_type (''survey_section'',''f''); + PERFORM acs_object_type__drop_type (''survey'',''f''); + + PERFORM acs_privilege__remove_child (''admin'',''survey_admin_survey''); + PERFORM acs_privilege__remove_child (''read'',''survey_take_survey''); + PERFORM acs_privilege__remove_child (''survey_admin_survey'',''survey_delete_question''); + PERFORM acs_privilege__remove_child (''survey_admin_survey'',''survey_modify_question''); + PERFORM acs_privilege__remove_child (''survey_admin_survey'',''survey_create_question''); + PERFORM acs_privilege__remove_child (''survey_admin_survey'',''survey_delete_survey''); + PERFORM acs_privilege__remove_child (''survey_admin_survey'',''survey_modify_survey''); + PERFORM acs_privilege__remove_child (''survey_admin_survey'',''survey_create_survey''); + + PERFORM acs_privilege__drop_privilege(''survey_admin_survey''); + PERFORM acs_privilege__drop_privilege(''survey_take_survey''); + PERFORM acs_privilege__drop_privilege(''survey_delete_question''); + PERFORM acs_privilege__drop_privilege(''survey_modify_question''); + PERFORM acs_privilege__drop_privilege(''survey_create_question''); + PERFORM acs_privilege__drop_privilege(''survey_delete_survey''); + PERFORM acs_privilege__drop_privilege(''survey_modify_survey''); + PERFORM acs_privilege__drop_privilege(''survey_create_survey''); + + return 0; +end;' language 'plpgsql'; + +select inline_0 (); +drop function inline_0 (); + +-- gilbertw - logical_negation is defined in utilities-create.sql in acs-kernel +-- drop function logical_negation(boolean); + + Index: openacs.org-dev/packages/survey/sql/postgresql/survey-notifications-init.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/sql/postgresql/survey-notifications-init.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/sql/postgresql/survey-notifications-init.sql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,62 @@ +-- daveb: not tested, this will probably break on postgresql +-- Survey +-- +-- -- @author dave@thedesignexperience.org, ben@openforce.biz +-- @creation-date 2002-08-03 +-- +-- integration with Notifications + +declare + impl_id integer; + v_foo integer; +begin + -- the notification type impl + impl_id := acs_sc_impl__new ( + 'NotificationType', + 'survey_response_notif_type', + 'survey' + ); + + v_foo := acs_sc_impl__new_alias ( + 'NotificationType', + 'survey_response_notif_type', + 'GetURL', + 'survey::notification::get_url', + 'TCL' + ); + + v_foo := acs_sc_impl__new_alias ( + 'NotificationType', + 'survey_response_notif_type', + 'ProcessReply', + 'survey::notification::process_reply', + 'TCL' + ); + + acs_sc_binding__new ( + contract_name => 'NotificationType', + impl_name => 'survey_response_notif_type' + ); + + v_foo:= notification_type__new ( + short_name => 'survey_response_notif', + sc_impl_id => impl_id, + pretty_name => 'Survey Response Notification', + description => 'Notifications for Survey', + creation_user => NULL, + creation_ip => NULL + ); + + -- enable the various intervals and delivery methods + insert into notification_types_intervals + (type_id, interval_id) + select v_foo, interval_id + from notification_intervals where name in ('instant','hourly','daily'); + + insert into notification_types_del_methods + (type_id, delivery_method_id) + select v_foo, delivery_method_id + from notification_delivery_methods where short_name in ('email'); + +end; + Index: openacs.org-dev/packages/survey/tcl/survey-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/tcl/survey-procs-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/tcl/survey-procs-oracle.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,83 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="survey_question_copy.create_question"> + <querytext> + + begin + :1 := survey_question.new ( + question_id => NULL, + section_id => :section_id, + sort_order => :new_sort_order, + question_text => empty_clob(), + abstract_data_type => :abstract_data_type, + presentation_type => :presentation_type, + presentation_alignment => :presentation_alignment, + presentation_options => :presentation_options, + active_p => :active_p, + required_p => :required_p, + context_id => :section_id, + creation_user => :user_id + ); + end; + + </querytext> +</fullquery> + +<fullquery name="survey_question_copy.get_choice_id"> +<querytext> +select survey_choice_id_sequence.nextval as choice_id from dual +</querytext> +</fullquery> + +<fullquery name="get_survey_info.n_completed"> +<querytext> + select count(distinct survey_response.initial_user_id(response_id)) + from + survey_responses + where survey_id=:survey_id +</querytext> +</fullquery> + + +<fullquery name="survey_copy.survey_create"> +<querytext> + begin + :1 := survey.new ( + survey_id => NULL, + name => :name, + description => :description, + description_html_p => :description_html_p, + editable_p => :editable_p, + single_response_p => :single_response_p, + enabled_p => :enabled_p, + single_section_p => :single_section_p, + type => :type, + display_type => :display_type, + package_id => :package_id, + context_id => :package_id, + creation_user => :user_id + ); + end; +</querytext> +</fullquery> + +<fullquery name="survey_copy.section_create"> +<querytext> + begin + :1 := survey_section.new ( + section_id=>NULL, + survey_id=>:new_survey_id, + name=>:name, + description=>empty_clob(), + description_html_p=>:description_html_p, + context_id =>:new_survey_id + ); + end; +</querytext> +</fullquery> + +</queryset> + Index: openacs.org-dev/packages/survey/tcl/survey-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/tcl/survey-procs-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/tcl/survey-procs-postgresql.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,48 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="survey_question_copy.create_question"> + <querytext> + begin + PERFORM survey_question__new ( + NULL, + :section_id, + :new_sort_order, + :question_text, + :abstract_data_type, + :required_p, + :active_p, + :presentation_type, + :presentation_options, + :presentation_alignment, + :user_id, + :section_id + ); + end; + </querytext> +</fullquery> + +<fullquery name="survey_question_copy.get_choice_id"> +<querytext> +select survey_choice_id_sequence.nextval as choice_id +</querytext> +</fullquery> + +<fullquery name="survey_do_notifications.get_response_info"> + <querytext> + select r.initial_response_id, r.responding_user_id, r.response_id, + u.first_names || ' ' || u.last_name as user_name, + edit_p, + o.creation_date as response_date + from (select survey_response__initial_user_id(response_id) as responding_user_id, + survey_response__initial_response_id(response_id) as initial_response_id, + response_id, (case when initial_response_id is NULL then 'f' else 't' end) as edit_p + from survey_responses) r, acs_objects o, + cc_users u where r.response_id=:response_id + and r.responding_user_id = u.user_id + and r.response_id = o.object_id + </querytext> +</fullquery> +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/tcl/survey-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/tcl/survey-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/tcl/survey-procs.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,512 @@ +# /tcl/survey-procs.tcl + +ad_library { + + Support procs for simple survey module, most important being + survey_question_display which generates a question widget based + on data retrieved from database. + + @author philg@mit.edu on + @author teadams@mit.edu + @author nstrug@arsdigita.com + @date February 9, 2000 + @cvs-id survey-simple-defs.tcl,v 1.29.2.5 2000/07/19 20:11:24 seb Exp + +} + +ad_proc -public get_survey_info { + {-survey_id ""} + {-section_id ""} +} { + creates a tcl array variable named "survey_info" in the caller's environment, + which contains key/value pairs for all properties of the requested survey. + + If survey_id is passed in, and it's a single-section survey, the + section_id will also be looked up and returned in the survey_info array. + + @author luke@museatech.net + @date 2002-07-24 +} { + upvar survey_info survey_info + + if {[empty_string_p $survey_id]} { + db_1row lookup_survey_id "" + } + + db_1row get_info_by_survey_id "" -column_array survey_info + + if {![info exists survey_info(survey_id)]} { + # survey doesn't exist, caller has to handle this in their + # own way + return + } + # If it's a single-section survey, look up the section_id + if {[empty_string_p $section_id] && $survey_info(single_section_p) == "t"} { + db_1row lookup_single_section_id "" + set survey_info(section_id) $section_id + } + + # some useful stats about the survey, dotLRN specific for sloanspace + if {[apm_package_installed_p dotlrn]} { + set community_id [dotlrn_community::get_community_id_from_url] + set survey_info(eligible) [db_string n_eligible {}] + set survey_info(completed) [db_string n_completed {}] + set survey_info(not_completed) [expr {$survey_info(eligible) - $survey_info(completed)}] + } +} + + +ad_proc -public survey_question_display { + question_id + {response_id ""} +} {Returns a string of HTML to display for a question, suitable for embedding in a form. The form variable is of the form \"response_to_question.\$question_id} { + + if {![empty_string_p $response_id]} { + set edit_previous_response_p "t" + } else { + set edit_previous_response_p "f" + } + + set element_name "response_to_question.$question_id" + + db_1row survey_question_properties "" + if {$required_p == "t"} { + set html "<span style=\"color: #f00;\">*</span>" + } else { + set html " " + } + + append html $question_text + if { $presentation_alignment == "below" } { + append html "<br />" + } else { + append html " " + } + + set user_value "" + + if {$edit_previous_response_p == "t"} { + set user_id [ad_get_user_id] + + set count 0 + db_foreach prev_response_query {} { + incr count + + if {$presentation_type == "checkbox"} { + set selected_choices($choice_id) "t" + } + } if_no_rows { + set choice_id 0 + set boolean_answer "" + set clob_answer "" + set number_answer "" + set varchar_answer "" + set date_answer "" + set attachment_answer "" + } + } + + switch -- $presentation_type { + "upload_file" { + if {$edit_previous_response_p == "t"} { + set user_value $attachment_answer + } + append html "<input type=file name=$element_name $presentation_options>" + } + "textbox" { + if {$edit_previous_response_p == "t"} { + if {$abstract_data_type == "number" || $abstract_data_type == "integer"} { + set user_value $number_answer + } else { + set user_value $varchar_answer + } + } + + append html "<input type=text name=$element_name value=\"[philg_quote_double_quotes $user_value]\" [ad_decode $presentation_options "large" "size=70" "medium" "size=40" "size=10"]>" + } + "textarea" { + if {$edit_previous_response_p == "t"} { + + set user_value $clob_answer + } + + set presentation_options [ad_decode $presentation_options "large" "rows=20 cols=65" "medium" "rows=15 cols=55" "rows=8 cols=35"] + append html "<textarea name=$element_name $presentation_options style=\"vertical-align: text-top\">$user_value</textarea>" + } + "date" { + if {$edit_previous_response_p == "t"} { + set user_value $date_answer + } + + append html "[ad_dateentrywidget $element_name $user_value]" + } + "select" { + if { $abstract_data_type == "boolean" } { + if {$edit_previous_response_p == "t"} { + set user_value $boolean_answer + } + + if {![empty_string_p $presentation_options]} { + set options_list [split $presentation_options "/"] + set choice_t [lindex $options_list 0] + set choice_f [lindex $options_list 1] + } else { + set choice_t "True" + set choice_f "False" + } + + append html "<select name=$element_name> + <option value=\"\">Select One</option> + <option value=\"t\" [ad_decode $user_value "t" "selected" ""]>$choice_t</option> + <option value=\"f\" [ad_decode $user_value "f" "selected" ""]>$choice_f</option> +</select> +" + } else { + if {$edit_previous_response_p == "t"} { + set user_value $choice_id + } + +# at some point, we may want to add a UI option for the admin +# to sepcify multiple or not for select + append html "<select name=$element_name> + <option value=\"\">Select One</option>\n" + db_foreach question_choices "" { + + if { $user_value == $choice_id } { + append html "<option value=$choice_id selected>$label</option>\n" + } else { + append html "<option value=$choice_id>$label</option>\n" + } + } + append html "</select>" + } + } + + "radio" { + if { $abstract_data_type == "boolean" } { + if {$edit_previous_response_p == "t"} { + set user_value $boolean_answer + } + if {![empty_string_p $presentation_options]} { + set options_list [split $presentation_options "/"] + set choice_t [lindex $options_list 0] + set choice_f [lindex $options_list 1] + } else { + set choice_t "True" + set choice_f "False" + } + + set choices [list "<input type=radio name=$element_name value=t [ad_decode $user_value "t" "checked" ""]> $choice_t" \ + "<input type=radio name=$element_name value=f [ad_decode $user_value "f" "checked" ""]> $choice_f"] + } else { + if {$edit_previous_response_p == "t"} { + set user_value $choice_id + } + + set choices [list] + db_foreach question_choices_2 "" { + if { $user_value == $choice_id } { + lappend choices "<input type=radio name=$element_name value=$choice_id checked> $label" + } else { + lappend choices "<input type=radio name=$element_name value=$choice_id> $label" + } + } + } + if { $presentation_alignment == "beside" } { + append html [join $choices " "] + } else { + append html "<blockquote>\n[join $choices "<br>\n"]\n</blockquote>" + } + } + + "checkbox" { + set choices [list] + db_foreach question_choices_3 "" { + if { [info exists selected_choices($choice_id)] } { + lappend choices "<input type=checkbox name=$element_name value=$choice_id checked> $label" + } else { + lappend choices "<input type=checkbox name=$element_name value=$choice_id> $label" + } + } + if { $presentation_alignment == "beside" } { + append html [join $choices " "] + } else { + append html "<blockquote>\n[join $choices "<br>\n"]\n</blockquote>" + } + } + } + + return $html +} + +ad_proc -public util_show_plain_text { text_to_display } "allows plain text (e.g. text entered through forms) to look good on screen without using tags; preserves newlines, angle brackets, etc." { + regsub -all "\\&" $text_to_display "\\&" good_text + regsub -all "\>" $good_text "\\>" good_text + regsub -all "\<" $good_text "\\<" good_text + regsub -all "\n" $good_text "<br>\n" good_text + # get rid of stupid ^M's + regsub -all "\r" $good_text "" good_text + return $good_text +} + +ad_proc -public survey_answer_summary_display {response_id {html_p 1}} "Returns a string with the questions and answers. If html_p =t, the format will be html. Otherwise, it will be text. If a list of category_ids is provided, the questions will be limited to that set of categories." { + + set return_string "" + set question_id_previous "" + + db_foreach summary "" { + + if {$question_id == $question_id_previous} { + continue + } + + if $html_p { + append return_string "<b># $sort_order: $question_text</b> + <blockquote>" + } else { + append return_string "# $sort_order: $question_text: " + } + append return_string [util_show_plain_text "$clob_answer $number_answer $varchar_answer $date_answer"] + + if {![empty_string_p $attachment_answer]} { + set package_id [ad_conn package_id] + set filename [db_string get_filename {}] + append return_string "Uploaded file: <a href=\"[site_node::get_url_from_object_id -object_id $package_id]/view-attachment?[export_url_vars response_id question_id]\">\"$filename\"</a>" + } + + if {$choice_id != 0 && ![empty_string_p $choice_id] && $question_id != $question_id_previous} { + set label_list [db_list survey_label_list ""] + append return_string "[join $label_list ", "]" + } + + if ![empty_string_p $boolean_answer] { + append return_string "[survey_decode_boolean_answer -response $boolean_answer -question_id $question_id]" + + } + + if $html_p { + append return_string "</blockquote> + <P>" + } else { + append return_string "\n\n" + } + + set question_id_previous $question_id + } + + return "$return_string" +} + + + +ad_proc -public survey_get_score {section_id user_id} "Returns the score of the user's most recent response to a survey" { + + set response_id [ survey_get_response_id $section_id $user_id ] + + if { $response_id != 0 } { + set score [db_string get_score "" -default 0] + } else { + set score {} + } + + return $score +} + + +ad_proc -public survey_display_types { +} { + return {list table paragraph} +} + + +ad_proc -public survey_question_copy { + {-new_section_id ""} + {-question_id:required} +} { copies a question within the same survey +} { + set user_id [ad_conn user_id] + db_1row get_question_details {} + if {![empty_string_p $new_section_id]} { + set section_id $new_section_id + } + + set old_question_id $question_id + if {[empty_string_p $new_section_id]} { + set after $sort_order + set new_sort_order [expr {$after + 1}] + db_dml renumber_sort_orders {} + } else { + set new_sort_order $sort_order + } + + set new_question_id [db_exec_plsql create_question {}] + db_dml insert_question_text {} + db_foreach get_survey_question_choices {} { + set new_choice_id [db_string get_choice_id {}] + db_dml insert_survey_question_choice {} + + } + + return $new_question_id +} + +ad_proc survey_copy { + {-survey_id:required} + {-package_id ""} + {-new_name ""} +} { + copies a survey, copying all questions, but not responses + is package_id is specific it copies they survey to another + survey package instance, otherwise it copies the survey to the + same package instance +} { + + if {[empty_string_p $package_id]} { + set package_id [ad_conn package_id] + } + + db_1row get_survey_info {} + if {![empty_string_p $new_name]} { + set name $new_name + } + set user_id [ad_conn user_id] + set new_survey_id [db_exec_plsql survey_create {} ] + set sections_list [db_list get_sections {}] + + + foreach section_id $sections_list { + + set new_section_id [db_exec_plsql section_create {}] + set new_section_ids($section_id) $new_section_id + if {![empty_string_p $description]} { + db_dml set_section_description {} + } + } + db_foreach get_questions {} { + + survey_question_copy -new_section_id $new_section_ids($section_id) -question_id $question_id + } +return $new_survey_id + +} + +ad_proc -public survey_do_notifications { + {-response_id ""} +} { process notifications when someone responds to a survey + or edits a response +} { + + set survey_id [db_string get_survey_id_from_response {}] + get_survey_info -survey_id $survey_id + set survey_name $survey_info(name) + set subject "Response to $survey_name" + + #dotlrn specific info + set dotlrn_installed_p [apm_package_installed_p dotlrn] + if {$dotlrn_installed_p} { + set package_id [ad_conn package_id] + set community_id [dotlrn_community::get_community_id] + set segment_id [dotlrn_community::get_rel_segment_id -community_id $community_id -rel_type "dotlrn_member_rel"] + set community_name [dotlrn_community::get_community_name $community_id] + set community_url "[ad_parameter -package_id [ad_acs_kernel_id] SystemURL][dotlrn_community::get_community_url $community_id]" + } + db_1row get_response_info {} + + set notif_text "" + if {$dotlrn_installed_p} { + append notif_text " +Group: $community_name" + } + append notif_text " +Survey: $survey_name +Respondent: $user_name + +Here is what $user_name <[acs_community_member_url -user_id $responding_user_id]> +had to say in response to $survey_name: + " + + if {$edit_p} { + append notif_text " +Edited " + } + append notif_text "Response on $response_date\n" + + append notif_text [survey_answer_summary_display $response_id 0] + +# add summary info for sloanspace + if {$dotlrn_installed_p} { + set n_responses [db_string n_responses {}] + if {$n_responses > 0} { + append notif_text " ----- +Already Responsed: $n_responses users + +View these users. <$community_url/survey/admin/respondents?response_type=responded> + +Spam these users. <$community_url/survey/admin/send-mail?survey_id=$survey_id&to=responded> + +" + } + set n_members [db_string n_members {}] + set n_awaiting [expr {$n_members - $n_responses}] + + append notif_text " +Awaiting a response: $n_awaiting users + +View these users. <$community_url/survey/admin/respondents?response_type=not_responded> + +Spam these users. <$community_url/survey/admin/send-mail?survey_id=$survey_id&to=not_responded> + +The whole group: $n_members + +View these users. <$community_url/survey/admin/respondents?response_type=all> + +Spam these users. <$community_url/survey/admin/send-mail?survey_id=$survey_id&to=all> + +Responses: +" + + db_foreach get_questions {} { + append notif_text "$sort_order. $question_text - View responses. <$community_url/survey/view-text-responses?question_id=$question_id> + " + } + } + notification::new \ + -type_id [notification::type::get_type_id \ + -short_name survey_response_notif] \ + -object_id $survey_id \ + -response_id $survey_id \ + -notif_subject $subject \ + -notif_text $notif_text + +} + + +ad_proc survey_decode_boolean_answer { + {-response:required} + {-question_id:required} +} { + takes t/f value from a boolean_answer column and + decodes it based on the presentation_options of the question + + @author Dave Bauer <dave@thedesignexperience.org> + + @param -response text value of response to be decoded + @param -question_id question_id of question response is from +} { + set presentation_options [db_string get_presentation_options {}] + if {[empty_string_p $presentation_options]} { + set presentation_options "True/False" + } + + + if {![empty_string_p $response]} { + set options_list [split $presentation_options "/"] + + if {$response=="t"} { + set response [lindex $options_list 0] + } else { + set response [lindex $options_list 1] + } + } + return $response +} \ No newline at end of file Index: openacs.org-dev/packages/survey/tcl/survey-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/tcl/survey-procs.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/tcl/survey-procs.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,295 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="get_survey_info.n_eligible"> +<querytext> + select count(*) from dotlrn_member_rels_full + where rel_type='dotlrn_member_rel' + and community_id=:community_id +</querytext> +</fullquery> + + +<fullquery name="get_survey_info.lookup_single_section_id"> +<querytext> + select min(section_id) as section_id + from survey_sections + where survey_id = :survey_id +</querytext> +</fullquery> + +<fullquery name="get_survey_info.lookup_survey_id"> +<querytext> + select survey_id + from survey_sections + where section_id = :section_id +</querytext> +</fullquery> + +<fullquery name="get_survey_info.get_info_by_survey_id"> +<querytext> + select s.*, + o.creation_user, o.creation_date, p.first_names || ' ' || p.last_name as creator_name, + (case when enabled_p = 't' then 'Enabled' else 'Disabled' end) as enabled_display, + (case when single_response_p = 't' then 'One response' else 'Multiple responses' end) as single_response_display, + (case when editable_p = 'f' then 'Non-Editable' else 'Editable' end) as editable_display, + (case when single_section_p = 'f' then 'Multiple sections' else 'Single section' end) as single_section_display + from surveys s, acs_objects o, persons p + where o.object_id = :survey_id + and s.survey_id = o.object_id + and p.person_id = o.creation_user +</querytext> +</fullquery> + + +<fullquery name="survey_question_display.prev_response_query"> +<querytext> +select + choice_id, + boolean_answer, + clob_answer, + number_answer, + varchar_answer, + date_answer, + attachment_answer + from survey_question_responses + where question_id = :question_id + and response_id = :response_id +</querytext> +</fullquery> + + +<fullquery name="survey_question_display.prev_response_query"> +<querytext> +select + choice_id, + boolean_answer, + clob_answer, + number_answer, + varchar_answer, + date_answer, + attachment_answer + from survey_question_responses + where question_id = :question_id + and response_id = :response_id +</querytext> +</fullquery> + + +<fullquery name="survey_question_display.survey_question_properties"> + <querytext> + +select + section_id, + sort_order, + question_text, + abstract_data_type, + required_p, + active_p, + presentation_type, + presentation_options, + presentation_alignment, + creation_user, + creation_date +from + survey_questions, acs_objects +where + object_id = question_id + and question_id = :question_id + </querytext> +</fullquery> + +<fullquery name="survey_question_display.question_choices"> + <querytext> + select choice_id, label +from survey_question_choices +where question_id = :question_id +order by sort_order + </querytext> +</fullquery> + + +<fullquery name="survey_question_display.question_choices_2"> + <querytext> + select choice_id, label +from survey_question_choices +where question_id = :question_id +order by sort_order + </querytext> +</fullquery> + + +<fullquery name="survey_question_display.question_choices_3"> + <querytext> + select * from survey_question_choices +where question_id = :question_id +order by sort_order + </querytext> +</fullquery> + + + +<fullquery name="survey_answer_summary_display.survey_label_list"> + <querytext> + select label + from survey_question_choices, survey_question_responses + where survey_question_responses.question_id = :question_id + and survey_question_responses.response_id = :response_id + and survey_question_choices.choice_id = survey_question_responses.choice_id + </querytext> +</fullquery> + + + + +<fullquery name="survey_question_copy.get_question_details"> +<querytext> +select * from survey_questions +where question_id=:question_id +</querytext> +</fullquery> + +<fullquery name="survey_question_copy.insert_question_text"> +<querytext> + update survey_questions + set question_text = :question_text + where question_id = :new_question_id +</querytext> +</fullquery> + +<fullquery name="survey_question_copy.renumber_sort_orders"> +<querytext> +update survey_questions + set sort_order = sort_order + 1 + where section_id = :section_id + and sort_order > :after +</querytext> +</fullquery> + +<fullquery name="survey_question_copy.get_survey_question_choices"> +<querytext> + select * from survey_question_choices + where question_id=:old_question_id +</querytext> +</fullquery> + +<fullquery name="survey_question_copy.insert_survey_question_choice"> +<querytext> +insert into survey_question_choices + (choice_id, question_id, label, numeric_value, sort_order) + values + (:new_choice_id, :new_question_id, :label, + :numeric_value, :sort_order) +</querytext> +</fullquery> + +<fullquery name="survey_do_notifications.get_survey_id_from_response"> +<querytext> + select survey_id from survey_responses + where response_id=:response_id +</querytext> +</fullquery> + +<fullquery name="survey_do_notifications.n_responses"> + <querytext> + select count(*) from survey_responses_latest + where survey_id=:survey_id + </querytext> +</fullquery> + +<fullquery name="survey_do_notifications.n_members"> + <querytext> + select count(*) from party_approved_member_map + where party_id=:segment_id + </querytext> +</fullquery> + +<fullquery name="survey_do_notifications.get_questions"> + <querytext> + select sort_order, question_text, question_id + from survey_questions + where section_id in + (select section_id + from survey_sections + where survey_id=:survey_id) + </querytext> +</fullquery> + +<fullquery name="survey_copy.get_survey_info"> +<querytext> +select * from surveys where survey_id=:survey_id +</querytext> +</fullquery> + +<fullquery name="survey_copy.set_section_description"> +<querytext> + update survey_sections set description=:description + where section_id=:new_section_id +</querytext> +</fullquery> + +<fullquery name="survey_copy.get_sections"> + <querytext> + select section_id from survey_sections where survey_id=:survey_id + </querytext> +</fullquery> + +<fullquery name="survey_copy.get_questions"> +<querytext> +select question_id from survey_questions + where section_id in (select section_id from survey_sections + where survey_id=:survey_id) +</querytext> +</fullquery> + +<fullquery name="survey_answer_summary_display.summary"> + <querytext> + +select + sq.question_id, + sq.section_id, + sq.sort_order, + sq.question_text, + sq.abstract_data_type, + sq.required_p, + sq.active_p, + sq.presentation_type, + sq.presentation_options, + sq.presentation_alignment, + sqr.response_id, + sqr.question_id, + sqr.choice_id, + sqr.boolean_answer, + sqr.clob_answer, + sqr.number_answer, + sqr.varchar_answer, + sqr.date_answer, + sqr.attachment_answer +from + survey_questions sq, + survey_question_responses sqr +where + sqr.response_id = :response_id + and sq.question_id = sqr.question_id + and sq.active_p = 't' +order by sort_order + + </querytext> +</fullquery> + +<fullquery name="survey_decode_boolean_answer.get_presentation_options"> + <querytext> + select presentation_options + from survey_questions + where question_id=:question_id + </querytext> +</fullquery> + +<fullquery name="survey_answer_summary_display.get_filename"> + <querytext> + select title from cr_revisions where + revision_id=:attachment_answer + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/index-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/index-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/index-oracle.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,21 @@ +<?xml version="1.0"?> + +<queryset> + +<fullquery name="survey_select"> + <querytext> + +select s.survey_id, s.name, s.editable_p, s.single_response_p, + sr.response_id, sr.creation_date + from surveys s ,(select survey_id, response_id, creation_date + from survey_responses_latest + where initial_user_id = :user_id) sr + where s.package_id=:package_id +and s.survey_id = sr.survey_id(+) +and s.enabled_p='t' + order by upper(s.name) + + </querytext> +</fullquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/index-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/index-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/index-postgresql.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,22 @@ +<?xml version="1.0"?> + +<queryset> + +<fullquery name="survey_select"> + <querytext> + +select s.survey_id, s.name, s.editable_p, s.single_response_p, + sr.response_id, sr.creation_date + from surveys s left outer join + (select survey_id, response_id, creation_date + from survey_responses_latest + where initial_user_id = :user_id) sr + on (s.survey_id = sr.survey_id) + where s.package_id=:package_id + and s.enabled_p='t' + order by upper(s.name) + + </querytext> +</fullquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/index.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/index.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,33 @@ +<master> +<property name="title">Surveys</property> +<property name="context_bar">@context_bar@</property> +<if @admin_p@ eq "1"><p style="text-align: right;"><a href="admin/"><img src="/graphics/admin.gif" border="0" alt="Administer Surveys"></a></if> + <ul> + + <multiple name="surveys"> + <li>@surveys.name@ + <if @surveys.single_response_p@ eq "t" and + @surveys.response_id@ nil> <a + href="respond?survey_id=@surveys.survey_id@"><img src="/graphics/answer.gif" border="0" alt="Answer Survey"></a></if> + <if @surveys.single_response_p@ eq "f"><a + href="respond?survey_id=@surveys.survey_id@"><img src="/graphics/answer.gif" border="0" alt="Answer Survey"></a></if> + </li> + <if @surveys.response_id@ not nil> + <ul> + <group column="survey_id"> + <li>Previous response on: @surveys.creation_date@ + <a href="one-respondent?survey_id=@surveys.survey_id@&#@surveys.response_id@"><img src="/graphics/view.gif" border="0" alt="View Response"></a> + <if @surveys.editable_p@ eq "t"> + <a href="respond?survey_id=@surveys.survey_id@&response_id=@surveys.response_id@"><img src="/graphics/edit.gif" border="0" alt="Edit Response"></a></if> + </li> + </group> + </ul> + </if> + </multiple> + + <if @surveys:rowcount@ eq 0> + <li>No surveys active + + </if> + </ul> + Index: openacs.org-dev/packages/survey/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/index.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/index.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,28 @@ +ad_page_contract { + + Lists all the enabled surveys + a user is eligable to complete. + + @author philg@mit.edu + @author nstrug@arsdigita.com + @date 28th September 2000 + @cvs-id $Id: index.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} { + +} -properties { + surveys:multirow +} + +set package_id [ad_conn package_id] + +set context_bar [ad_context_bar] + +set user_id [ad_maybe_redirect_for_registration] + +set admin_p [ad_permission_p $package_id admin] + +db_multirow surveys survey_select {} + + +ad_return_template + Index: openacs.org-dev/packages/survey/www/one-respondent.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/one-respondent.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/one-respondent.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,30 @@ +<master> +<property name="title">Answers to @survey_name@</property> +<property name="context_bar">@context_bar@</property> + + @description@ + <p> + <multiple name="responses"> + <if @responses.rownum@ ne @responses:rowcount@> + <a href="#@responses.response_id@">@responses.pretty_submission_date@</a> | + </if> + <else> + <a href="#@responses.response_id@">@responses.pretty_submission_date@</a> + </else> + </multiple> + <p> + <multiple name=responses> + <table width=100% cellpadding=2 cellspacing=2 border=0> + <tr class="table-header" bgcolor="#e6e6e6"> + <td><a name="@responses.response_id@">Your response + on @responses.pretty_submission_date@</a> + <if @editable_p@ eq "t">[<a + href="respond?survey_id=@survey_id@&response_id=@responses.response_id@">edit this response</a>]</if> + </td> + </tr> + <tr class="z_light" bgcolor="#f4f4f4"> + <td>@responses.answer_summary@</td> + </tr> + </table> + </multiple> + </html> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/one-respondent.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/one-respondent.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/one-respondent.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,45 @@ +ad_page_contract { + + Display the user's previous responses. + + @param section_id id of survey for which responses are displayed + @param return_url if provided, generate a 'return' link to that URL + @param group_id if specified, display all the responses for all + users of that group + + @author philg@mit.edu + @author nstrug@arsdigita.com + @date 28th September 2000 + @cvs-id $Id: one-respondent.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} { + + survey_id:integer + {return_url ""} + +} -validate { + survey_exists -requires {survey_id} { + if ![db_0or1row survey_exists {}] { + ad_complain "Survey $section_id does not exist" + } + } +} -properties { + survey_name:onerow + description:onerow + responses:multirow +} + +# If group_id is specified, we return all the responses for that group by any user + +set user_id [ad_verify_and_get_user_id] + +get_survey_info -survey_id $survey_id + +set survey_name $survey_info(name) +set description $survey_info(description) +set editable_p $survey_info(editable_p) +set context_bar [ad_context_bar "Responses"] +db_multirow -extend {answer_summary} responses responses_select {} { + set answer_summary [survey_answer_summary_display $response_id 1] +} + +ad_return_template Index: openacs.org-dev/packages/survey/www/one-respondent.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/one-respondent.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/one-respondent.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="survey_exists"> + <querytext> + + select 1 from surveys where survey_id = :survey_id + + </querytext> +</fullquery> + +<fullquery name="responses_select"> + <querytext> + + select response_id, creation_date, + to_char(creation_date, 'Month DD, YYYY') as pretty_submission_date + from survey_responses_latest + where survey_id=:survey_id + and initial_user_id = :user_id + order by creation_date desc + + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/one-survey-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/one-survey-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/one-survey-oracle.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,22 @@ +<?xml version="1.0"?> + +<queryset> + +<fullquery name="get_survey_details"> + <querytext> + +select s.survey_id, s.name, s.editable_p, s.single_response_p, + sr.response_id, sr.creation_date + from surveys s ,(select survey_id, response_id, creation_date + from survey_responses_latest + where initial_user_id = :user_id) sr + where s.survey_id=:survey_id +and s.package_id=:package_id +and s.survey_id = sr.survey_id(+) +and s.enabled_p='t' +order by sr.creation_date desc + + </querytext> +</fullquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/one-survey-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/one-survey-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/one-survey-postgresql.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,23 @@ +<?xml version="1.0"?> + +<queryset> + +<fullquery name="get_survey_details"> + <querytext> + +select s.survey_id, s.name, s.editable_p, s.single_response_p, + sr.response_id, sr.creation_date + from surveys s left outer join + (select survey_id, response_id, creation_date + from survey_responses_latest + where initial_user_id = :user_id) sr + on (s.survey_id = sr.survey_id) + where s.survey_id=:survey_id + and s.package_id=:package_id + and s.enabled_p='t' + order by upper(s.name) + + </querytext> +</fullquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/one-survey.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/one-survey.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/one-survey.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,31 @@ +<master> +<property name="title">Surveys</property> +<property name="context_bar">@context_bar@</property> +<if @admin_p@ eq "1"><p style="text-align: right;"><a href="admin/"><img src="/graphics/admin.gif" border="0" alt="Admin"></a></p></if> + <ul> + + <multiple name="survey_details"> + <li>@survey_details.name@ + <if @survey_details.single_response_p@ eq "t" and + @survey_details.response_id@ nil> <a + href="respond?survey_id=@survey_details.survey_id@"><img src="/graphics/answer.gif" border="0" alt="Answer Survey"></a></if> + <if @survey_details.single_response_p@ eq "f"><a + href="respond?survey_id=@survey_details.survey_id@"><img src="/graphics/answer.gif" border="0" alt="Answer Survey"></a></if> + </li> + <if @survey_details.response_id@ not nil> + + <group column="survey_id"> + <ul> + <li>Previous response on: @survey_details.creation_date@ + <a href="one-respondent?survey_id=@survey_details.survey_id@&#@survey_details.response_id@"><img src="/graphics/view.gif" border="0" alt="View Response"></a> + <if @survey_details.editable_p@ eq "t"> + <a href="respond?survey_id=@survey_details.survey_id@&response_id=@survey_details.response_id@"><img src="/graphics/edit.gif" border="0" alt="Edit Response"></a></if> + </li> + </ul> + + </group> + </if> + </multiple> + + </ul> + Index: openacs.org-dev/packages/survey/www/one-survey.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/one-survey.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/one-survey.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,29 @@ +ad_page_contract { + + Lists all the enabled surveys + a user is eligable to complete. + + @author philg@mit.edu + @author nstrug@arsdigita.com + @date 28th September 2000 + @cvs-id $Id: one-survey.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} { + survey_id:integer,notnull +} -properties { + survey_details:multirow +} + +set package_id [ad_conn package_id] + +set context_bar [ad_context_bar] + +set user_id [ad_maybe_redirect_for_registration] + +set take_survey_p [ad_permission_p $survey_id survey_take_survey] + +set admin_p [ad_permission_p $survey_id survey_admin_survey] + +db_multirow survey_details get_survey_details {} + +ad_return_template + Index: openacs.org-dev/packages/survey/www/one_list.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/one_list.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/one_list.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,5 @@ + <ol> + <list name="questions"> + <li><!--qis-->@questions:item@<!--qie--> + </list> + </ol> Index: openacs.org-dev/packages/survey/www/one_paragraph.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/one_paragraph.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/one_paragraph.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,4 @@ +<list name=questions> +@questions:item@<p> +</list> + Index: openacs.org-dev/packages/survey/www/one_table.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/one_table.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/one_table.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,5 @@ +<table border=1 cellpadding=4 width="80%"> +<list name=questions> +<tr><td>@questions:item@</td></tr> +</list> +</table> Index: openacs.org-dev/packages/survey/www/process-response-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/process-response-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/process-response-oracle.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,49 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="create_response"> + <querytext> + + begin + :1 := survey_response.new ( + response_id => :response_id, + survey_id => :survey_id, + context_id => :survey_id, + creation_user => :user_id, + initial_response_id => :initial_response_id + ); + end; + + </querytext> +</fullquery> + + +<fullquery name="survey_question_response_text_insert"> + <querytext> + + insert into survey_question_responses + (response_id, question_id, clob_answer) + values + (:response_id, :question_id, empty_clob()) + returning clob_answer into :1 + + </querytext> +</fullquery> + + +<fullquery name="create_item"> + <querytext> + + begin + :1 := content_item.new ( + name => :name, + creation_ip => :creation_ip + ); + end; + + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/process-response-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/process-response-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/process-response-postgresql.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,32 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="create_response"> + <querytext> + select survey_response__new ( + :response_id, + :survey_id, + null, + 'f', + :user_id, + :creation_ip, + :survey_id, + :initial_response_id + ) + </querytext> +</fullquery> + +<fullquery name="survey_question_response_text_insert"> + <querytext> + + insert into survey_question_responses + (response_id, question_id, clob_answer) + values + (:response_id, :question_id, :clob_answer) + + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/process-response.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/process-response.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/process-response.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,8 @@ +<master> +<property name=title>Response Submitted</property> +<property name=context_bar>@context_bar@</property> + <blockquote> + <p> Response submitted. Thank you.</p> + <p><a href=".">Return</a> to the survey index page.</p> + + </blockquote> Index: openacs.org-dev/packages/survey/www/process-response.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/process-response.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/process-response.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,326 @@ +ad_page_contract { + + Insert user response into database. + This page receives an input for each question named + response_to_question.$question_id + + @param section_id survey user is responding to + @param return_url optional redirect address + @param group_id + @param response_to_question since form variables are now named as response_to_question.$question_id, this is actually array holding user responses to all survey questions. + + @author jsc@arsdigita.com + @author nstrug@arsdigita.com + @date 28th September 2000 + @cvs-id $Id: process-response.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} { + survey_id:integer + section_id:integer + {initial_response_id:integer 0} + return_url:optional + response_to_question:array,optional,multiple,html + +} -validate { + + section_exists -requires { section_id } { + if ![db_0or1row section_exists {}] { + ad_complain "Section $section_id does not exist" + } + } + + check_questions -requires { section_id:integer } { + + set question_info_list [db_list_of_lists survey_question_info_list { + select question_id, question_text, abstract_data_type, presentation_type, required_p + from survey_questions + where section_id = :section_id + and active_p = 't' + order by sort_order + }] + + ## Validate input. + + set questions_with_missing_responses [list] + + foreach question $question_info_list { + set question_id [lindex $question 0] + set question_text [lindex $question 1] + set abstract_data_type [lindex $question 2] + set required_p [lindex $question 4] + + # Need to clean-up after mess with :array,multiple flags + # in ad_page_contract. Because :multiple flag will sorround empty + # strings and all multiword values with one level of curly braces {} + # we need to get rid of them for almost any abstract_data_type + # except 'choice', where this is intended behaviour. Why bother + # with :multiple flag at all? Because otherwise we would lost all + # but first value for 'choice' abstract_data_type - see ad_page_contract + # doc and code for more info. + # + if { [exists_and_not_null response_to_question($question_id)] } { + if {$abstract_data_type != "choice"} { + set response_to_question($question_id) [join $response_to_question($question_id)] + } + } + + + if { $abstract_data_type == "date" } { + if [catch { set response_to_question($question_id) [validate_ad_dateentrywidget "" response_to_question.$question_id [ns_getform]]} errmsg] { + ad_complain "$errmsg: Please make sure your dates are valid." + } + } + + if { [exists_and_not_null response_to_question($question_id)] } { + set response_value [string trim $response_to_question($question_id)] + } elseif {$required_p == "t"} { + lappend questions_with_missing_responses $question_text + continue + } else { + set response_to_question($question_id) "" + set response_value "" + } + + if {![empty_string_p $response_value]} { + if { $abstract_data_type == "number" } { + if { ![regexp {^(-?[0-9]+\.)?[0-9]+$} $response_value] } { + + ad_complain "The response to \"$question_text\" must be a number. Your answer was \"$response_value\"." + continue + } + } elseif { $abstract_data_type == "integer" } { + if { ![regexp {^[0-9]+$} $response_value] } { + + ad_complain "The response to \"$question_text\" must be an integer. Your answer was \"$response_value\"." + continue + } + } + } + + if { $abstract_data_type == "blob" } { + set tmp_filename $response_to_question($question_id.tmpfile) + set n_bytes [file size $tmp_filename] + if { $n_bytes == 0 && $required_p == "t" } { + + ad_complain "Your file is zero-length. Either you attempted to upload a zero length file, a file which does not exist, or something went wrong during the transfer." + } + } + + } + + if { [llength $questions_with_missing_responses] > 0 } { + ad_complain "You didn't respond to all required sections. You skipped:" + foreach skipped_question $questions_with_missing_responses { + ad_complain $skipped_question + } + return 0 + } else { + return 1 + } + } +} -properties { + + survey_name:onerow +} + +ad_require_permission $survey_id survey_take_survey + +set user_id [ad_verify_and_get_user_id] + +# Do the inserts. +# here we need to decide if it is an edit or multiple response, and create +# a new response, possibly linked to a previous response. + +set response_id [db_nextval acs_object_id_seq] +set creation_ip [ad_conn peeraddr] +if {$initial_response_id==0} { + set initial_response_id "" +} +db_transaction { + + db_exec_plsql create_response {} + + set question_info_list [db_list_of_lists survey_question_info_list { + select question_id, question_text, abstract_data_type, presentation_type, required_p + from survey_questions + where section_id = :section_id + and active_p = 't' + order by sort_order }] + + + foreach question $question_info_list { + set question_id [lindex $question 0] + set question_text [lindex $question 1] + set abstract_data_type [lindex $question 2] + set presentation_type [lindex $question 3] + + set response_value [string trim $response_to_question($question_id)] + + switch -- $abstract_data_type { + "choice" { + if { $presentation_type == "checkbox" } { + # Deal with multiple responses. + set checked_responses $response_to_question($question_id) + foreach response_value $checked_responses { + if { [empty_string_p $response_value] } { + set response_value [db_null] + } + + db_dml survey_question_response_checkbox_insert "insert into survey_question_responses (response_id, question_id, choice_id) + values (:response_id, :question_id, :response_value)" + } + } else { + if { [empty_string_p $response_value] || [empty_string_p [lindex $response_value 0]] } { + set response_value [db_null] + } + + db_dml survey_question_response_choice_insert "insert into survey_question_responses (response_id, question_id, choice_id) + values (:response_id, :question_id, :response_value)" + } + } + "shorttext" { + db_dml survey_question_choice_shorttext_insert "insert into survey_question_responses (response_id, question_id, varchar_answer) + values (:response_id, :question_id, :response_value)" + } + "boolean" { + if { [empty_string_p $response_value] } { + set response_value [db_null] + } + + db_dml survey_question_response_boolean_insert "insert into survey_question_responses (response_id, question_id, boolean_answer) + values (:response_id, :question_id, :response_value)" + } + "integer" - + "number" { + if { [empty_string_p $response_value] } { + set response_value [db_null] + } + db_dml survey_question_response_integer_insert "insert into survey_question_responses (response_id, question_id, number_answer) + values (:response_id, :question_id, :response_value)" + } + "text" { + if { [empty_string_p $response_value] } { + set response_value [db_null] + } + + db_dml survey_question_response_text_insert " +insert into survey_question_responses +(response_id, question_id, clob_answer) +values (:response_id, :question_id, empty_clob()) + returning clob_answer into :1" -clobs [list $response_value] + } + "date" { + if { [empty_string_p $response_value] } { + set response_value [db_null] + } + + db_dml survey_question_response_date_insert "insert into survey_question_responses (response_id, question_id, date_answer) + values (:response_id, :question_id, :response_value)" + } + "blob" { + + if { ![empty_string_p $response_value] } { + # this stuff only makes sense to do if we know the file exists + set tmp_filename $response_to_question($question_id.tmpfile) + + set file_extension [string tolower [file extension $response_value]] + # remove the first . from the file extension + regsub {\.} $file_extension "" file_extension + set guessed_file_type [ns_guesstype $response_value] + + set n_bytes [file size $tmp_filename] + # strip off the C:\directories... crud and just get the file name + if ![regexp {([^/\\]+)$} $response_value match client_filename] { + # couldn't find a match + set client_filename $response_value + } + if { $n_bytes == 0 } { + error "This should have been checked earlier." + } else { + set unique_name "${response_value}_${response_id}" + set mime_type [ns_guesstype $client_filename] + set revision_id [cr_import_content -title $client_filename "" $tmp_filename $n_bytes $mime_type $unique_name ] +# we use cr_import_content now --DaveB +# this abstracts out for use the blob handling for oracle or postgresql +# we are linking the file item_id to the survey_question_response attachment_answer field now + db_dml survey_question_response_attachment_insert " + insert into survey_question_responses + (response_id, question_id, attachment_answer) + values + (:response_id, :question_id, :revision_id + )" + } + } + } + } + } + +} + +survey_do_notifications -response_id $response_id + +# +# Survey type-specific stuff +# +get_survey_info -survey_id $survey_id +set type $survey_info(type) +set survey_id $survey_info(survey_id) +set survey_name $survey_info(name) + +#set type [db_string get_type "select type from survey_sections where section_id = :section_id"] + +switch $type { + + "general" { + + #set survey_name [db_string survey_name_from_id "select name from survey_sections where section_id = :section_id" ] + + db_release_unused_handles + + if {[info exists return_url] && ![empty_string_p $return_url]} { + ad_returnredirect "$return_url" + ad_script_abort + } else { + set context_bar [ad_context_bar "Response Submitted for $survey_name"] + ad_return_template + } + } + + "scored" { + + db_foreach get_score "select variable_name, sum(score) as sum_of_scores + from survey_choice_scores, survey_question_responses, survey_variables + where survey_choice_scores.choice_id = survey_question_responses.choice_id + and survey_choice_scores.variable_id = survey_variables.variable_id + and survey_question_responses.response_id = :response_id + group by variable_name" { + set sum_score($variable_name) $sum_of_scores + } + + set logic [db_string get_logic "select logic from survey_logic, survey_logic_surveys_map + where survey_logic.logic_id = survey_logic_surveys_map.logic_id + and section_id = :section_id"] + + + if {[info exists return_url] && ![empty_string_p $return_url]} { + + ad_returnredirect $return_url + + } + + eval $logic + + } + + default { + if {[info exists return_url] && ![empty_string_p $return_url]} { + ad_returnredirect "$return_url" + ad_script_abort + } else { + set context_bar [ad_context_bar "Response Submitted for $survey_name"] + + ad_return_template + } + } +} + + Index: openacs.org-dev/packages/survey/www/process-response.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/process-response.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/process-response.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,111 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="section_exists"> + <querytext> + + select 1 from survey_sections where section_id = :section_id + + </querytext> +</fullquery> + + +<fullquery name="survey_question_info_list"> + <querytext> + + select question_id, question_text, abstract_data_type, presentation_type, required_p + from survey_questions + where section_id = :section_id + and active_p = 't' + order by sort_order + + </querytext> +</fullquery> + + +<fullquery name="survey_question_info_list"> + <querytext> + + select question_id, question_text, abstract_data_type, presentation_type, required_p + from survey_questions + where section_id = :section_id + and active_p = 't' + order by sort_order + + </querytext> +</fullquery> + + +<fullquery name="survey_question_response_checkbox_insert"> + <querytext> + insert into survey_question_responses (response_id, question_id, choice_id) + values (:response_id, :question_id, :response_value) + </querytext> +</fullquery> + + +<fullquery name="survey_question_response_choice_insert"> + <querytext> + insert into survey_question_responses (response_id, question_id, choice_id) + values (:response_id, :question_id, :response_value) + </querytext> +</fullquery> + + +<fullquery name="survey_question_choice_shorttext_insert"> + <querytext> + insert into survey_question_responses (response_id, question_id, varchar_answer) + values (:response_id, :question_id, :response_value) + </querytext> +</fullquery> + + +<fullquery name="survey_question_response_boolean_insert"> + <querytext> + insert into survey_question_responses (response_id, question_id, boolean_answer) + values (:response_id, :question_id, :response_value) + </querytext> +</fullquery> + + +<fullquery name="survey_question_response_integer_insert"> + <querytext> + insert into survey_question_responses (response_id, question_id, number_answer) + values (:response_id, :question_id, :response_value) + </querytext> +</fullquery> + + +<fullquery name="survey_question_response_date_insert"> + <querytext> + insert into survey_question_responses (response_id, question_id, date_answer) + values (:response_id, :question_id, :response_value) + </querytext> +</fullquery> + + +<fullquery name="get_type"> + <querytext> + select type from survey_sections where section_id = :section_id + </querytext> +</fullquery> + + +<fullquery name="survey_name_from_id"> + <querytext> + select name from survey_sections where section_id = :section_id + </querytext> +</fullquery> + + + +<fullquery name="survey_question_response_file_attachment_insert"> + <querytext> + insert into survey_question_responses + (response_id, question_id, attachment_file) + values + (:response_id, :question_id, :revision_id) + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/respond-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/respond-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/respond-oracle.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,24 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="get_initial_response"> + <querytext> + + select survey_response.initial_response_id(:response_id) as initial_response_id from dual + + </querytext> +</fullquery> + +<fullquery name="count_responses"> + <querytext> + select count(*) from survey_responses + where survey_id=:survey_id + and survey_response.initial_user_id(response_id)=:user_id + and initial_response_id is null + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/respond-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/respond-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/respond-postgresql.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,24 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="get_initial_response"> + <querytext> + + select survey_response__initial_response_id(:response_id) as initial_response_id from dual + + </querytext> +</fullquery> + +<fullquery name="count_responses"> + <querytext> + select count(*) from survey_responses + where survey_id=:survey_id + and survey_response__initial_user_id(response_id)=:user_id + and initial_response_id is null + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/respond.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/respond.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/respond.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,28 @@ +<master> +<property name=title>One Survey: @name@</property> +<property name=context_bar>@context_bar@</property> + <table border="0" cellpadding="0" cellspacing="0" width="100%"> + <form enctype=multipart/form-data method="post" action="process-response"> + <if @initial_response_id@ not nil><input type="hidden" + name="initial_response_id" value="@initial_response_id@"></if> + <tr> + <td class="tabledata">@description@</td> + </tr> + <tr> + <td class="tabledata"><span style="color: #f00;">*</span> denotes a required question</td> + </tr> + <tr> + <td class="tabledata"><hr noshade size="1" color="#dddddd"></td> + </tr> + + <tr> + <td class="tabledata"> + @form_vars@ + <include src="one_@display_type@" questions=@questions@> + <hr noshade size="1" color="#dddddd"> + <input type="submit" value="@button_label@"> + </td> + </tr> + + </form> + </table> Index: openacs.org-dev/packages/survey/www/respond.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/respond.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/respond.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,86 @@ +ad_page_contract { + + Display a questionnaire for one survey. + + @param section_id id of displayed survey + + @author philg@mit.edu + @author nstrug@arsdigita.com + @date 28th September 2000 + @cvs-id $Id: respond.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ + +} { + + survey_id:integer,notnull + {section_id:integer 0} + {response_id:integer 0} + return_url:optional + +} -validate { + survey_exists -requires {survey_id} { + if ![db_0or1row survey_exists {}] { + ad_complain "Survey $survey_id does not exist" + } + set user_id [ad_maybe_redirect_for_registration] + set number_of_responses [db_string count_responses {}] + get_survey_info -survey_id $survey_id + set single_section_p $survey_info(single_section_p) + if {$section_id==0 && $single_section_p=="t"} { + set section_id $survey_info(section_id) + } + set name $survey_info(name) + set description $survey_info(description) + set single_response_p $survey_info(single_response_p) + set editable_p $survey_info(editable_p) + set display_type $survey_info(display_type) + if {($single_response_p=="t" && $editable_p=="f" && $number_of_responses>0) || ($single_response_p=="t" && $editable_p=="t" && $number_of_responses>0 && $response_id==0)} { + ad_complain "You have already completed this survey" + } elseif {$response_id>0 && $editable_p=="f"} { + ad_complain "This survey is not editable" + } + } +} -properties { + + name:onerow + section_id:onerow + button_label:onerow + questions:onerow + description:onerow + modification_allowed_p:onerow + return_url:onerow +} + +ad_require_permission $survey_id survey_take_survey + +set context_bar [ad_context_bar "$name"] +set button_label "Submit response" +if {$editable_p == "t"} { + if {$response_id > 0} { + set button_label "Modify previous response" + db_1row get_initial_response "" + } +} + +# build a list containing the HTML (generated with survey_question_display) for each question +set rownum 0 + +set questions [list] + +db_foreach survey_sections {} { + + db_foreach question_ids_select {} { + lappend questions [survey_question_display $question_id $response_id] + } + + # return_url is used for infoshare - if it is set + # the survey will return to it rather than + # executing the survey associated with the logic + # after the survey is completed + # + if ![info exists return_url] { + set return_url {} + } +} +set form_vars [export_form_vars section_id survey_id] +ad_return_template + Index: openacs.org-dev/packages/survey/www/respond.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/respond.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/respond.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="survey_exists"> + <querytext> + + select 1 from surveys where survey_id = :survey_id + + </querytext> +</fullquery> + +<fullquery name="question_ids_select"> + <querytext> + + select question_id + from survey_questions + where section_id = :section_id + and active_p = 't' + order by sort_order + + </querytext> +</fullquery> + +<fullquery name="survey_sections"> +<querytext> +select section_id from survey_sections +where survey_id=:survey_id +</querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/response-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/response-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/response-postgresql.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,20 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="get_initial_response"> + <querytext> + select survey_response__initial_response_id(:response_id) as initial_response_id + </querytext> +</fullquery> + +<fullquery name="count_responses"> + <querytext> + select count(*) from survey_responses + where survey_id=:survey_id + and survey_response__initial_user_id(response_id)=:user_id + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/view-attachment.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/view-attachment.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/view-attachment.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,33 @@ +ad_page_contract { + + View the attachment contents of a given response. + This page has been modified to use the CR for attachment storage dave@thedesignexperience.org + + @param response_id id of complete survey response submitted by user + @param question_id id of question for which this file was submitted as an answer + + + @author jbank@arsdigita.com + @author nstrug@arsdigita.com + @date 28th September 2000 + @cvs-id $Id: view-attachment.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} { + + response_id:integer,notnull + question_id:integer,notnull + +} -validate { + attachment_exists -requires {response_id question_id} { + db_1row get_file_info {} + + if { [empty_string_p $file_type] } { + ad_complain "Couldn't find attachment. Couldn't find an attachment matching the response_id $response_id, question_id $question_id given." + } + } +} + +ReturnHeaders $file_type + +cr_write_content -revision_id $revision_id + + Index: openacs.org-dev/packages/survey/www/view-attachment.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/view-attachment.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/view-attachment.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,17 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="get_file_info"> + <querytext> + select r.revision_id, r.mime_type as file_type + from cr_revisions r + where revision_id=( + select attachment_answer from survey_question_responses + where question_id=:question_id + and response_id=:response_id + ) + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/description-edit.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/description-edit.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/description-edit.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,7 @@ +<master src="master"> +<property name="survey_id">@survey_id@</property> + +<property name=title>@survey_name@: Edit Description</property> +<property name=context_bar>@context_bar@</property> + +<formtemplate id="edit-survey"></formtemplate> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/description-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/description-edit.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/description-edit.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,56 @@ +ad_page_contract { + + Form to allow user to the description of a survey. + + @param section_id integer denoting survey whose description we're changing + + @author Jin Choi (jsc@arsdigita.com) + @author nstrug@arsdigita.com + @date February 16, 2000 + @cvs-id $Id: description-edit.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} { + + survey_id:integer + +} + +ad_require_permission $survey_id survey_modify_survey +ad_form -name edit-survey -form { + survey_id:key + {description:text(textarea) {label "Survey Description"} {html {rows 10 cols 65}}} + {desc_html:text(radio) {label "The Above Description is"} + {options {{"Preformatted Text" "pre"} + {"HTML" "html"} {"Plain Text" "plain"}}}} +} -edit_request { + get_survey_info -survey_id $survey_id + set survey_name $survey_info(name) + set description $survey_info(description) + set description_html_p $survey_info(description_html_p) + set desc_html "" + if {$description_html_p=="t"} { + set desc_html "html" + } else { + set desc_html "plain" + } + ad_set_form_values desc_html description + +} -validate { + {description {[string length $description] <= 4000} + "Description must be less than 4000 characters" + } +} +} -edit_data { + if {$desc_html=="pre" || $desc_html=="html"} { + set description_html_p t + } else { + set description_html_p f + } + db_dml survey_update_description "" + + ad_returnredirect "one?[export_url_vars survey_id]" + ad_script_abort +} + +set context_bar [ad_context_bar [list "one?[export_url_vars survey_id]" $survey_info(name)] "Edit Description"] + +ad_return_template Index: openacs.org-dev/packages/survey/www/admin/description-edit.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/description-edit.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/description-edit.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="survey_properties"> + <querytext> + select name as survey_name, description, description_html_p as desc_html +from surveys +where survey_id = :survey_id + </querytext> +</fullquery> + + +<fullquery name="survey_update_description"> + <querytext> + update surveys + set description = :description, + description_html_p = :description_html_p + where survey_id = :survey_id + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/index.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/index.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,15 @@ +<master> + +<property name=title>Survey Administration</property> +<property name=context_bar>@context_bar@</property> +<property name="link_all">1</property> +<ul> +<multiple name=surveys> +<group column="enabled_p"> +<li> <a href=one?survey_id=@surveys.survey_id@>@surveys.name@</a> +<if @surveys.enabled_p@ eq "f"><span style="color: #f00">(disabled)</span></if> +</group> +</multiple> +<p> +<li> <a href=survey-create>New Survey</a> +</ul> Index: openacs.org-dev/packages/survey/www/admin/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/index.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/index.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,24 @@ +# /www/survsimp/admin/index.tcl +ad_page_contract { + This page is the main table of contents for navigation page + for simple survey module administrator + + @author philg@mit.edu + @author nstrug@arsdigita.com + @date 3rd October, 2000 + @cvs-id $Id: index.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} { + +} + +set context_bar [ad_context_bar] + +set package_id [ad_conn package_id] + +# bounce the user if they don't have permission to admin surveys +ad_require_permission $package_id survey_admin_survey + +set disabled_header_written_p 0 + +db_multirow surveys select_surveys {} +ad_return_template Index: openacs.org-dev/packages/survey/www/admin/index.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/index.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/index.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="select_surveys"> + <querytext> + select survey_id, name, enabled_p +from surveys +where package_id= :package_id +order by enabled_p desc, upper(name) + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/master.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/master.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/master.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,10 @@ +<master> +<if @context_bar@ not nil> +<property name="context_bar">@context_bar@</property> +</if> +<if @title@ not nil> +<property name="title">@title@</property> +</if> +<a href=".">Main Survey Administration</a> | <a href="one?survey_id=@survey_id@">Admin This Survey</a> +<p> +<slave> Index: openacs.org-dev/packages/survey/www/admin/modify-responses-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/modify-responses-2.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/modify-responses-2.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,51 @@ +ad_page_contract { + Modify question responses + + @param section_id integer denoting which survey we're adding question to + @param question_id id of new question + @param responses list of possible responses + @param scores list of variable scores + + @author Nick Strugnell (nstrug@arsdigita.com) + @date September 15, 2000 + @cvs-id $Id: modify-responses-2.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} { + section_id:integer,notnull + question_id:integer,notnull + {responses:multiple ""} + {scores:multiple,array,integer ""} + {variable_id_list ""} + {choice_id_list ""} +} + +ad_require_permission $section_id survey_modify_question + +db_transaction { + + set i 0 + foreach choice_id $choice_id_list { + set trimmed_response [string trim [lindex $responses $i]] + db_dml update_survey_question_choice "update survey_question_choices + set label = :trimmed_response + where choice_id = :choice_id" + + foreach variable_id $variable_id_list { + set score_list $scores($variable_id) + set score [lindex $score_list $i] + db_dml update_survey_scores "update survey_choice_scores + set score = :score + where choice_id = :choice_id + and variable_id = :variable_id" + } + + incr i + } +} + +db_release_unused_handles + +get_survey_info -section_id $section_id +set survey_id $survey_info(survey_id) +ad_returnredirect "one?[export_url_vars survey_id]" + + Index: openacs.org-dev/packages/survey/www/admin/modify-responses-2.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/modify-responses-2.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/modify-responses-2.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="update_survey_question_choice"> + <querytext> + update survey_question_choices + set label = :trimmed_response + where choice_id = :choice_id + </querytext> +</fullquery> + + +<fullquery name="update_survey_scores"> + <querytext> + update survey_choice_scores + set score = :score + where choice_id = :choice_id + and variable_id = :variable_id + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/modify-responses.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/modify-responses.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/modify-responses.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,88 @@ +ad_page_contract { + + Modify question responses and scores + + @param question_id which question we'll be changing responses of + @param section_id survey providing this question + + @author Nick Strugnell (nstrug@arsdigita.com) + @date September 15, 2000 + @cvs-id $Id: modify-responses.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} { + + question_id:integer + section_id:integer + +} + +ad_require_permission $section_id survey_modify_question + +get_survey_info -section_id $section_id +set survey_id $survey_info(survey_id) + +set survey_name [db_string survey_name_from_id "select name from survey_sections where section_id=:section_id" ] + +set question_text [db_string survey_question_text_from_id "select question_text +from survey_questions +where question_id = :question_id" ] + +set table_html "<table border=0> +<tr><th>Response</th>" + +set variable_id_list [list] + +db_foreach get_variable_names "select variable_name, survey_variables.variable_id as variable_id + from survey_variables, survey_variables_surveys_map + where survey_variables.variable_id = survey_variables_surveys_map.variable_id + and section_id = :section_id + order by variable_name" { + + lappend variable_id_list $variable_id + append table_html "<th>$variable_name</th>" + } + +append table_html "</tr>\n" + +set choice_id_list [list] + +db_foreach get_choices "select choice_id, label from survey_question_choices where question_id = :question_id order by choice_id" { + lappend choice_id_list $choice_id + append table_html "<tr><td align=center><input name=\"responses\" value=\"$label\" size=80></td>" + + db_foreach get_scores "select score, survey_variables.variable_id as variable_id + from survey_choice_scores, survey_variables + where survey_choice_scores.choice_id = :choice_id + and survey_choice_scores.variable_id = survey_variables.variable_id + order by variable_name" { + + append table_html "<td align=center><input name=\"scores.$variable_id\" value=\"$score\" size=2></td>" + } + + append table_html "</tr>\n" +} + +append table_html "</table>\n" + +db_release_unused_handles + +doc_return 200 text/html "[ad_header "Modify Responses"] +<h2>$survey_name</h2> + +[ad_context_bar [list "one?[export_url_vars survey_id]" $survey_info(name)] "Modify Question Responses"] + +<hr> + +Question: $question_text +<p> +<form action=\"modify-responses-2\" method=get> +[export_form_vars section_id question_id choice_id_list variable_id_list] +$table_html +<p> +<center> +<input type=submit value=\"Submit\"> +</center> + +</form> + +[ad_footer] +" Index: openacs.org-dev/packages/survey/www/admin/modify-responses.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/modify-responses.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/modify-responses.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,49 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="survey_name_from_id"> + <querytext> + select name from survey_sections where section_id=:section_id + </querytext> +</fullquery> + + +<fullquery name="survey_question_text_from_id"> + <querytext> + select question_text +from survey_questions +where question_id = :question_id + </querytext> +</fullquery> + + +<fullquery name="get_variable_names"> + <querytext> + select variable_name, survey_variables.variable_id as variable_id + from survey_variables, survey_variables_surveys_map + where survey_variables.variable_id = survey_variables_surveys_map.variable_id + and section_id = :section_id + order by variable_name + </querytext> +</fullquery> + + +<fullquery name="get_choices"> + <querytext> + select choice_id, label from survey_question_choices where question_id = :question_id order by choice_id + </querytext> +</fullquery> + + +<fullquery name="get_scores"> + <querytext> + select score, survey_variables.variable_id as variable_id + from survey_choice_scores, survey_variables + where survey_choice_scores.choice_id = :choice_id + and survey_choice_scores.variable_id = survey_variables.variable_id + order by variable_name + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/name-edit.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/name-edit.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/name-edit.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,8 @@ +<master src="master"> +<property name="survey_id">@survey_id@</property> + +<property name=title>@survey_name@: Edit Name</property> +<property name=context_bar>@context_bar@</property> + +Edit and submit to change the name for this survey: +<formtemplate id="edit-name"></formtemplate> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/name-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/name-edit.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/name-edit.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,46 @@ +ad_page_contract { + + Edit the name of the survey + + @param section_id integer denoting survey whose description we're changing + + @author Jin Choi (jsc@arsdigita.com) + @author nstrug@arsdigita.com + @date February 16, 2000 + @cvs-id $Id: name-edit.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} { + + survey_id:integer + {name ""} +} + +get_survey_info -survey_id $survey_id +set survey_name $survey_info(name) +set survey_description $survey_info(description) + +ad_require_permission $survey_id survey_modify_survey + +ad_form -name edit-name -form { + survey_id:key + {name:text(text) {label "Survey Name"} {html {size 80}} + {value $survey_name}} + {description:text(textarea) {label "Description"} + {html {rows 10 cols 65}} + {value $survey_description}} +} -validate { + {name {[string length $name] <= 4000} + "Survey Name must be less than 4000 characters" + } +} -edit_request { + set name $survey_name +} -edit_data { + db_dml survey_update "" + ad_returnredirect "one?[export_vars survey_id]" + ad_script_abort +} + +set context_bar [ad_context_bar "Edit Name"] + +ad_return_template + + Index: openacs.org-dev/packages/survey/www/admin/name-edit.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/name-edit.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/name-edit.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<queryset> +<fullquery name="survey_update"> +<querytext> +update surveys +set name= :name, + description= :description +where survey_id = :survey_id +</querytext> +</fullquery> +</queryset> Index: openacs.org-dev/packages/survey/www/admin/one-respondent-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/one-respondent-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/one-respondent-oracle.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,18 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + + +<fullquery name="get_responses"> + <querytext> + select response_id, case when initial_response_id is NULL then 'T' else 'F' end as original_p, survey_response.initial_response_id(response_id) as initial_response, creation_date +from survey_responses, acs_objects +where response_id = object_id +and creation_user = :user_id +and survey_id=:survey_id +order by creation_date desc + </querytext> +</fullquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/one-respondent-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/one-respondent-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/one-respondent-postgresql.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,16 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> +<fullquery name="get_responses"> + <querytext> + select response_id, case when initial_response_id is NULL then 'T' else 'F' end as original_p, survey_response__initial_response_id(response_id) as initial_response, creation_date +from survey_responses, acs_objects +where response_id = object_id +and creation_user = :user_id +and survey_id=:survey_id +order by creation_date desc + </querytext> +</fullquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/one-respondent.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/one-respondent.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/one-respondent.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,36 @@ +<master src="master"> + +<property name="survey_id">@survey_id@</property> + +<property name="survey_id">@survey_id@</property> +<property name="survey_name@">@survey_info.name@</property> +<property name="title">One Respondent: @first_names@ @last_name@</property> +<property name="context_bar">@context_bar@</property> +<table class=table-display cellspacing=0 cellpadding=5> +<tr class="table-header"><td> + Here is what <a href="/shared/community-member?user_id=@user_id@">@first_names@ @last_name@</a> had to say in response to @survey_name@: +</td> + + +<multiple name="responses"> + + <tr class="z_light"><td> +<group column="initial_response"> + +<if @responses.original_p@><a href="response-delete?response_id=@response_id@"> +<img valign="top" align="right" src="/graphics/delete.gif" border="0" alt="Delete"></a> +</if> + <strong>[<if + @responses.original_p@>Original</if><else>Edited</a></else> + Response on @responses.creation_date@]</strong> + <br /> +@responses.response_display@ + + +</group> +</td> +</tr> +<tr class="z_light"><td><hr class="main_color"></td></tr> +</multiple> +</table> + Index: openacs.org-dev/packages/survey/www/admin/one-respondent.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/one-respondent.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/one-respondent.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,41 @@ +ad_page_contract { + + Display the filled-out survey for a single user. + + @param user_id user whose response we're viewing + @param section_id survey we're viewing + @author jsc@arsdigita.com + @author nstrug@arsdigita.com + @date February 11, 2000 + @cvs-id $Id: one-respondent.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} { + + user_id:integer + survey_id:integer + +} + +ad_require_permission $survey_id survey_admin_survey + +get_survey_info -survey_id $survey_id +set survey_name $survey_info(name) +set description $survey_info(description) +set type $survey_info(type) + +# survey_name and description are now set + +set user_exists_p [db_0or1row user_name_from_id "select first_names, last_name from persons where person_id = :user_id" ] + +if { !$user_exists_p } { + ad_return_error "Not Found" "Could not find user #$user_id" + return +} + +set context_bar [ad_context_bar "One Respondent"] + + +db_multirow -extend {response_display} responses get_responses {} { +set response_display [survey_answer_summary_display $response_id 1 ] +} + +ad_return_template \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/one-respondent.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/one-respondent.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/one-respondent.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,12 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="user_name_from_id"> + <querytext> + select first_names, last_name from persons where person_id = :user_id + </querytext> +</fullquery> + + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/one.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/one.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/one.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,100 @@ +<master> +<property name="survey_id">@survey_id@</property> + +<property name="title">One Survey: @survey_info.name@</property> +<property name="context_bar">@context_bar@</property> +<p><a href=".">Main Survey Administration</a></p> +<font size=+1><b>@survey_info.name@</b></font> - Created by </td><td> <a href="@user_link@">@survey_info.creator_name@</a>, on @creation_date@</h2> +<table class="table-display" cellpadding=2 cellspacing=0> + <tr class="z_dark"><td> </td><td> This survey is <if @survey_info.enabled_p@ eq t>@survey_info.enabled_display@</if><else><span style="color: #f00;">@survey_info.enabled_display@</span></else>. - <a href="@toggle_enabled_url@">@toggle_enabled_text@</a></td></tr> + + <tr class="z_light"> +<td valign="top">Survey Name:<p> +Description: </td> + <td > +<a href="survey-preview?survey_id=@survey_id@"><img align=right src=/graphics/preview.gif border=0 alt="Preview"></a> + + <a href="name-edit?survey_id=@survey_id@"><img align=right src=/graphics/edit.gif border=0 alt="Edit"></a> +@survey_info.name@<p> +@survey_info.description@</td> +</tr> + <tr class="z_dark"><td>View Responses: </td><td > + <a + href="respondents?survey_id=@survey_id@">By user</a> | <a + href="responses?survey_id=@survey_id@">Summary</a> | + <a href="responses-export?survey_id=@survey_id@"> CSV file</a></td> + </tr> + <tr class="z_light"><td valign="top" rowspan="2"><nobr>Response Options: </nobr></td><td> @survey_info.single_response_display@ - [ + <a href="response-limit-toggle?survey_id=@survey_id@">@response_limit_toggle@</a> + ]</td></tr> + + + <tr class="z_light"><td><if @survey_info.editable_p@> Users may edit their responses</if><else>Users may not edit their responses</else> - [ <a + href="response-editable-toggle?survey_id=@survey_id@">make <if + @survey_info.editable_p@>non-</if>editable</a> ]</td></tr> + + <tr class="z_light"><td>Display Opinions: </td><td> @survey_info.display_type@ - <list name="survey_display_types"><if @survey_info.display_type@ ne @survey_display_types:item@>[<a href="survey-display-type-edit?display_type=@survey_display_types:item@&survey_id=@survey_id@">@survey_display_types:item@</a>]</if></list></td></tr> + + +<tr class="z_light"><td valign="top" rowspan="2">Email Options:</td><td >@notification_chunk@</td></tr> + + <tr class="z_light"><td ><a href="send-mail?survey_id=@survey_id@">Send bulk + mail</a> regarding this survey </td></tr> + + + <tr><td></td><td > + + <tr class="z_dark"> + <td>Extreme Actions: </td><td > + <a href="survey-delete?survey_id=@survey_id@">Delete this survey</a> - Removes all questions and responses<br> + <a href="survey-copy?survey_id=@survey_id@">Copy this survey</a> - Lets you use this survey as a template to create a new survey. + </td></tr> +</table> +<br /> + +<h3>Questions</h3> +<table cellspacing=0> +<if @questions:rowcount@ eq 0> + <tr class="z_light"> + </else> +<td></td><td><a href="question-add?section_id=@survey_info.section_id@">add new question</a></tr></tr> +</if> +<multiple name="questions"> + + <if @questions.rownum@ odd> + <tr class="z_light"> + </if> + <else> + <tr class="z_dark"> + </else> + +<td valign="top">@questions.rownum@. <a name="@questions.sort_order@"></a></td> + +<td><a href="question-modify?question_id=@questions.question_id@§ion_id=@section_id@&survey_id=@survey_id@"><img src=/graphics/edit.gif border=0 alt="Edit"></a> +<if @questions.active_p@ eq "f"><span style="color: #f00;">[inactive]</span></if> +<a href="question-copy?question_id=@questions.question_id@&sort_order=@questions.sort_order@"><img src="/graphics/copy.gif" border="0" alt="Copy"></a> +<a href="question-add?section_id=@section_id@&after=@questions.sort_order@"><img src="/graphics/new.gif" border="0" alt="Add New"></a><img src="/graphics/spacer.gif" border="0" alt="" width="10"> +<if @questions.rownum@ lt @questions:rowcount@ ><a + href="question-swap?section_id=@section_id@&survey_id=@survey_id@&sort_order=@questions.sort_order@&direction=down"><img src="/graphics/down" border="0" alt="Move Down"></a></if><if @questions.rownum@ gt 1><a + href="question-swap?section_id=@section_id@&survey_id=@survey_id@&sort_order=@questions.sort_order@&direction=up"><img src="/graphics/up.gif" border="0" alt="Move Up"></a></if><a href="question-delete?question_id=@questions.question_id@&survey_id=@survey_id@"><img src="/graphics/delete.gif" border="0" alt="Delete"></a></td></tr> + + <if @questions.rownum@ odd> + <tr class="z_light"> + </if> + <else> + <tr class="z_dark"> + </else> +<td colspan="3"> + <blockquote>@questions.question_display@</blockquote> +</td></tr> +<if @questions.rownum@ eq @questions:rowcount@> + <if @questions.rownum@ odd> + <tr class="z_dark"> + </if> + <else> + <tr class="z_light"> + </else> +<td></td><td><a href="question-add?section_id=@survey_info.section_id@">add new question</a></tr></tr> +</if> +</multiple> +</table> Index: openacs.org-dev/packages/survey/www/admin/one.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/one.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/one.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,78 @@ +ad_page_contract { + + This page allows the admin to administer a single survey. + + @param section_id integer denoting survey we're administering + + @author jsc@arsdigita.com + @author nstrug@arsdigita.com + @author dave@thedesignexperience.org + @date February 9, 2000 + @cvs-id $Id: one.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} { + + survey_id:integer + {section_id:integer ""} +} + +set package_id [ad_conn package_id] + +ad_require_permission $package_id survey_admin_survey + +# Get the survey information. +get_survey_info -survey_id $survey_id +if {![info exists survey_info(survey_id)]} { + ad_return_complaint 1 "Requested survey does not exist" + ad_script_abort +} +# get users and # who responded etc... +if {[apm_package_installed_p dotlrn]} { + set community_id [dotlrn_community::get_community_id_from_url] + set n_eligible [db_string n_eligible { + select count(*) from dotlrn_member_rels_full + where rel_type='dotlrn_member_rel' + and community_id=:community_id}] +} +set return_html "" + +set creation_date [util_AnsiDatetoPrettyDate $survey_info(creation_date)] +set user_link [acs_community_member_url -user_id $survey_info(creation_user)] +if {$survey_info(single_response_p) == "t"} { + set response_limit_toggle "allow multiple" +} else { + set response_limit_toggle "limit to one" +} + + +# allow site-wide admins to enable/disable surveys directly from here +set target "one?[export_url_vars survey_id]" +set enabled_p $survey_info(enabled_p) +set toggle_enabled_url "survey-toggle?[export_vars {survey_id enabled_p target}]" +if {$enabled_p == "t"} { + append toggle_enabled_text "disable" +} else { + append toggle_enabled_text "enable" +} + + +# Display Type (ben) +# provide list survey_display_types to adp process with <list> +set survey_display_types [survey_display_types] + + +# Questions summary. +# We need to get the questions for ALL sections. + +set context_bar [ad_context_bar $survey_info(name)] + +db_multirow -extend { question_display } questions survey_questions "" {set question_display [survey_question_display $question_id]} + + +set notification_chunk [notification::display::request_widget \ + -type survey_response_notif \ + -object_id $survey_id \ + -pretty_name $survey_info(name) \ + -url [ad_conn url]?survey_id=$survey_id \ +] + +ad_return_template Index: openacs.org-dev/packages/survey/www/admin/one.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/one.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/one.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="survey_questions"> + <querytext> +select question_id, sort_order, active_p, required_p, section_id + from survey_questions + where section_id in ( select section_id from survey_sections where survey_id=:survey_id) + order by section_id, sort_order + </querytext> +</fullquery> + +<fullquery name="survey_sections"> + <querytext> +select section_id from survey_sections +where survey_id=:survey_id + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/question-active-toggle-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-active-toggle-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-active-toggle-oracle.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="survey_question_required_toggle"> + <querytext> + update survey_questions set active_p = util.logical_negation(active_p) +where section_id = :section_id +and question_id = :question_id + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/question-active-toggle-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-active-toggle-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-active-toggle-postgresql.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="survey_question_required_toggle"> + <querytext> + update survey_questions set active_p = util__logical_negation(active_p) +where section_id = :section_id +and question_id = :question_id + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/question-active-toggle.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-active-toggle.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-active-toggle.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,27 @@ +# /www/survsimp/admin/question-active-toggle.tcl +ad_page_contract { + + Toggles if a response to required for a given question. + + @param section_id survey we're operating with + @param question_id denotes which question in survey we're updating + + @cvs-id question-active-toggle.tcl,v 1.5.2.4 2000/07/21 04:04:11 ron Exp +} { + + section_id:integer + question_id:integer + +} + +ad_require_permission $section_id survey_admin_survey + +db_dml survey_question_required_toggle "update survey_questions set active_p = util.logical_negation(active_p) +where section_id = :section_id +and question_id = :question_id" + +db_release_unused_handles +get_survey_info -section_id $section_id +set survey_id $survey_info(survey_id) +ad_returnredirect "one?[export_url_vars survey_id]" + Index: openacs.org-dev/packages/survey/www/admin/question-add-2.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-add-2.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-add-2.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,8 @@ +<master src="master"> +<property name="survey_id">@survey_id@</property> + +<property name=title>Survey Administration: Add a Question (cont.)</property> +<property name=context_bar>@context_bar@</property> + + + <formtemplate id="create-question-2"></formtemplate> Index: openacs.org-dev/packages/survey/www/admin/question-add-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-add-2.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-add-2.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,183 @@ +# /www/survsimp/admin/question-add-2.tcl +ad_page_contract { + + Based on the presentation type selected in previous form, + gives the user various options on how to lay out the question. + + @param section_id integer determining survey we're dealing with + @param after optional integer determining placement of question + @param question_text text comprising this question + @param presentation_type string denoting widget used to provide answer + @param required_p flag indicating whether this question is mandatory + @param active_p flag indicating whether this question is active + @param category_id optional integer describing category of this question (within survey) + + @author Jin Choi (jsc@arsdigita.com) + @author nstrug@arsdigita.com + @date February 9, 2000 + @cvs-id $Id: question-add-2.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} { + + section_id:integer + question_text:html,notnull + presentation_type + {after:integer ""} + {required_p t} + {active_p t} + {n_responses ""} + +} + +set package_id [ad_conn package_id] +set user_id [ad_get_user_id] +ad_require_permission $package_id survey_create_question + +set question_id [db_nextval acs_object_id_seq] +get_survey_info -section_id $section_id + +if {![info exists survey_info(survey_id)]} { + ad_return_complaint 1 "Requested survey does not exist" + ad_script_abort +} + +set survey_id $survey_info(survey_id) +set type $survey_info(type) + +# create a blank form, we fill it based on the question type +# maybe put question_id:key in there if we move the processing from quesion-add-3 to this form. + +ad_form -name create-question-2 -action question-add-3 -form { + {question:text(inform) {label "Question Text"} {value $question_text}} + {survey_id:text(hidden) {value $survey_id}} + {section_id:text(hidden) {value $section_id}} + {question_id:text(hidden) {value $question_id}} + {question_text:text(hidden) {value $question_text}} + {presentation_type:text(hidden) {value $presentation_type}} + {after:text(hidden) {value $after}} + {required_p:text(hidden) {value $required_p}} + {active_p:text(hidden) {value $active_p}} + {type:text(hidden) {value $type}} +} + + +# set exception_count 0 +# set exception_text "" + +# if { $type != "general" && $type != "scored" } { +# incr exception_count +# append exception_text "<li>Surveys of type $type are not currently available\n" +# } + +# if { $presentation_type == "upload_file" } { +# # incr exception_count +# # append exception_text "<li>The presentation type: upload file is not supported at this time." + +# } + +# if { $exception_count > 0 } { +# ad_return_complaint $exception_count $exception_text +# return +# } + +# Survey-type specific question settings + +if { $type == "scored" } { + + db_1row count_variable_names "" + + set response_fields "<table border=0> +<tr><th>Answer Text</th><th colspan=$n_variables>Score</th></tr> +<tr><td></td>" + + set variable_id_list [list] + db_foreach select_variable_names "" { + lappend variable_id_list $variable_id + append response_fields "<th>$variable_name</th>" + } + + append response_fields "</tr>\n" + + for {set response 0} {$response < $n_responses} {incr response} { + append response_fields "<tr><td align=center><input type=text name=\"responses\" size=80></td>" + for {set variable 0} {$variable < $n_variables} {incr variable} { + append response_fields "<td align=center><input type=text name=\"scores.$variable\" size=2></td>" + } + append response_fields "</tr>\n" + } + + append response_fields "</table>\n" + set response_type_html "<input type=hidden name=abstract_data_type value=\"choice\">" + set presentation_options_html "" + set form_var_list [export_form_vars section_id question_id question_text presentation_type after required_p active_p type n_variables variable_id_list] + +} elseif { $type == "general" } { + +# Display presentation options for sizing text input fields and textareas. + + switch -- $presentation_type { + "textbox" { + + ad_form -extend -name create-question-2 -form { + {textbox_size:text(select) {options {{Small small} {Medium medium} {Large large}}} {label "Size"}} + {abstract_data_type:text(select) {label "Type of Response"} + {options {{"Short Text" shorttext} {Text text} {Boolean boolean} {Number number} {Integer integer}}} + } + + } + } + "textarea" { + ad_form -extend -name create-question-2 -form { + {textarea_size:text(select) {options {{Small small} {Medium medium} {Large large}}} {label "Size"}} + {abstract_data_type:text(hidden) {value "text"}} + + } + } + } +} +# Let user enter valid responses for selections, radio buttons, and check boxes. + + set response_fields "" + + switch -- $presentation_type { + "radio" - + "select" { + + ad_form -extend -name create-question-2 -form { + {abstract_data_type:text(radio) + {label "Type of Response"} {value "choice"} + {options {{"True or False" boolean} {"Yes or No" yn} {"Multiple Choice" choice}}}} + {valid_responses:text(textarea) + {label "For Multiple Choice<br />Enter a List of Valid Responses<br /> (enter one choice per line)"} + {html {rows 10 cols 50}}} + } + } + + "checkbox" { + ad_form -extend -name create-question-2 -form { + {valid_responses:text(textarea) {label "Valid Resposnes (enter one choice per line)"} {html {rows 10 cols 50}}} + {abstract_data_type:text(hidden) {value "choice"}} + } + } + + + + "date" { + + ad_form -extend -name create-question-2 -form { + {abstract_data_type:text(hidden) {value date}} + } + + } + "upload_file" { + ad_form -extend -name create-question-2 -form { + {abstract_data_type:text(hidden) {value blob}} + } + } + } + +ad_form -extend -name create-question-2 -form { + {presentation_alignment:text(radio) {options {{"Beside the question" beside} {"Below the question" below}}} {value below} {label "Presentation Alignment"}} +} +set context_bar [ad_context_bar [list "one?[export_url_vars survey_id]" $survey_info(name)] "Add A Question"] + +ad_return_template Index: openacs.org-dev/packages/survey/www/admin/question-add-2.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-add-2.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-add-2.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<queryset> + + +<fullquery name="count_variable_names"> + <querytext> + select count(variable_name) as n_variables + from survey_variables, survey_variables_surveys_map + where survey_variables.variable_id = survey_variables_surveys_map.variable_id + and section_id = :section_id + </querytext> +</fullquery> + +<fullquery name="select_variable_names"> + <querytext> + select variable_name, survey_variables.variable_id as variable_id + from survey_variables, survey_variables_surveys_map + where survey_variables.variable_id = survey_variables_surveys_map.variable_id + and section_id = :section_id order by survey_variables.variable_id + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/question-add-3-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-add-3-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-add-3-oracle.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,41 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="create_question"> + <querytext> + + begin + :1 := survey_question.new ( + question_id => :question_id, + section_id => :section_id, + sort_order => :sort_order, + question_text => empty_clob(), + abstract_data_type => :abstract_data_type, + presentation_type => :presentation_type, + presentation_alignment => :presentation_alignment, + presentation_options => :presentation_options, + active_p => :active_p, + required_p => :required_p, + context_id => :section_id, + creation_user => :user_id + ); + end; + + </querytext> +</fullquery> + + +<fullquery name="get_choice_id"> + <querytext> + select survey_choice_id_sequence.nextval as choice_id from dual + </querytext> +</fullquery> + +<fullquery name="already_inserted_p"> + <querytext> + select decode(count(*),0,0,1) from survey_questions where question_id = :question_id + </querytext> +</fullquery> +</queryset> Index: openacs.org-dev/packages/survey/www/admin/question-add-3-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-add-3-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-add-3-postgresql.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,40 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="create_question"> + <querytext> + + select survey_question__new ( + :question_id, + :section_id, + :sort_order, + :question_text, + :abstract_data_type, + :required_p, + :active_p, + :presentation_type, + :presentation_options, + :presentation_alignment, + :user_id, + :section_id + ) + + </querytext> +</fullquery> + + +<fullquery name="get_choice_id"> + <querytext> + select survey_choice_id_sequence.nextval as choice_id + </querytext> +</fullquery> + +<fullquery name="already_inserted_p"> + <querytext> + select case when count(*) = 0 then 0 else 1 end from survey_questions where question_id = :question_id + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/question-add-3.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-add-3.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-add-3.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,153 @@ +# /www/survsimp/admin/question-add-3.tcl +ad_page_contract { + Inserts a new question into the database. + + @param section_id integer denoting which survey we're adding question to + @param question_id id of new question + @param after optional integer determining position of this question + @param question_text text of question + @param abstract_data_type string describing datatype we expect as answer + @param presentation_type string describing widget for providing answer + @param presentation_alignment string determining placement of answer widget relative to question text + @param valid_responses string containing possible choices, one per line + @param textbox_size width of textbox answer widget + @param textarea_size size of textarea answer widget + @param required_p flag telling us whether an answer to this question is mandatory + @param active_p flag telling us whether this question will show up at all + + @author Jin Choi (jsc@arsdigita.com) February 9, 2000 + @author nstrug@arsdigita.com + @cvs-id $Id: question-add-3.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} { + section_id:integer,notnull + question_id:integer,notnull + after:integer,optional + question_text:html + {abstract_data_type ""} + presentation_type + presentation_alignment + type:notnull + {valid_responses ""} + {textbox_size ""} + {textarea_size: "medium"} + {required_p t} + {active_p t} + {responses:multiple ""} + {scores:multiple,array,integer ""} + {n_variables:integer ""} + {variable_id_list ""} +} + +set package_id [ad_conn package_id] +set user_id [ad_get_user_id] +ad_require_permission $package_id survey_create_question +get_survey_info -section_id $section_id + +if {![info exists survey_info(survey_id)]} { + ad_return_complaint 1 "Requested survey does not exist" + ad_script_abort +} + +set survey_id $survey_info(survey_id) +set exception_count 0 +set exception_text "" + +if { [empty_string_p $question_text] } { + incr exception_count + append exception_text "<li>You did not enter a question.\n" +} + +if { $type != "scored" && $type != "general" } { + incr exception_count + append exception_text "<li>Surveys of type $type are not currently available.\n" +} + +if { $type == "general" && $abstract_data_type == "choice" && [empty_string_p $valid_responses] } { + incr exception_count + append exception_text "<li>You did not enter a list of valid responses/choices.\n" +} + + +if { $exception_count > 0 } { + ad_return_complaint $exception_count $exception_text + ad_script_abort +} + +set already_inserted_p [db_string already_inserted_p {}] + +if { $already_inserted_p } { + ad_returnredirect "one?[export_vars survey_id]" + ad_script_abort +} +# Generate presentation_options. + set presentation_options "" + if { $presentation_type == "textbox" } { + if { [exists_and_not_null textbox_size] } { + # Will be "small", "medium", or "large". + set presentation_options $textbox_size + } + } elseif { $presentation_type == "textarea" } { + if { [exists_and_not_null textarea_size] } { + # Will be "small", "medium", or "large". + set presentation_options $textarea_size + } + } elseif { $abstract_data_type == "yn" } { + set abstract_data_type "boolean" + set presentation_options "Yes/No" + } elseif { $abstract_data_type == "boolean" } { + set presentation_options "True/False" + } + + db_transaction { + if { [exists_and_not_null after] } { + # We're inserting between existing questions; move everybody down. + set sort_order [expr { $after + 1 }] + db_dml renumber_sort_orders {} + } else { + set sort_order [expr [db_string max_question {}] + 1] + } + + db_exec_plsql create_question {} + + db_dml add_question_text {} + + + # For questions where the user is selecting a canned response, insert + # the canned responses into survey_question_choices by parsing the valid_responses + # field. + if { $presentation_type == "checkbox" || $presentation_type == "radio" || $presentation_type == "select" } { + if { $abstract_data_type == "choice" } { + set responses [split $valid_responses "\n"] + set count 0 + foreach response $responses { + set trimmed_response [string trim $response] + if { [empty_string_p $trimmed_response] } { + # skip empty lines + continue + } + ### added this next line to + set choice_id [db_string get_choice_id "select survey_choice_id_sequence.nextval as choice_id from dual"] + db_dml insert_survey_question_choice "insert into survey_question_choices (choice_id, question_id, label, sort_order) +values (survey_choice_id_sequence.nextval, :question_id, :trimmed_response, :count)" + incr count + } + } + } + } on_error { + + db_release_unused_handles + ad_return_error "Database Error" "<pre>$errmsg</pre>" + ad_script_abort + + } + + +db_release_unused_handles +ad_returnredirect "one?survey_id=$survey_id&#${sort_order}" + + + + + + + Index: openacs.org-dev/packages/survey/www/admin/question-add-3.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-add-3.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-add-3.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,59 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="renumber_sort_orders"> + <querytext> + update survey_questions + set sort_order = sort_order + 1 + where section_id = :section_id + and sort_order > :after + </querytext> +</fullquery> + + +<fullquery name="add_question_text"> + <querytext> + + update survey_questions + set question_text = :question_text + where question_id = :question_id + + </querytext> +</fullquery> + + +<fullquery name="insert_survey_question_choice"> + <querytext> + insert into survey_question_choices + (choice_id, question_id, label, sort_order) + values + (:choice_id, :question_id, :trimmed_response, :count) + </querytext> +</fullquery> + + +<fullquery name="insert_survey_scores"> + <querytext> + insert into survey_choice_scores + (choice_id, variable_id, score) + values + (:choice_id, :variable_id, :score) + </querytext> +</fullquery> + +<fullquery name="already_inserted_p"> + <querytext> + + select case when count(*) = 0 then 0 else 1 end from survey_questions where question_id = :question_id + + </querytext> +</fullquery> + +<fullquery name="max_question"> + <querytext> + select max(sort_order) from survey_questions + where section_id=:section_id + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/question-add.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-add.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-add.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,9 @@ +<master src="master"> +<property name="survey_id">@survey_id@</property> + +<property name=title>@survey_info.name@: New Question</property> +<property name=context_bar>@context_bar@</property> + + <formtemplate id="create_question"></formtemplate> + +</form> Index: openacs.org-dev/packages/survey/www/admin/question-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-add.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-add.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,65 @@ +ad_page_contract { + Present form to begin adding a question to a survey. + Lets user enter the question and select a presentation type. + + @param section_id integer designating survey we're adding question to + @param after optinal integer denoting position of question within survey + + @author jsc@arsdigita.com + @author nstrug@arsdigita.com + @date February 9, 2000 + @cvs-id $Id: question-add.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} { + section_id:integer + {after:integer ""} + +} + +set package_id [ad_conn package_id] +set user_id [ad_get_user_id] +ad_require_permission $package_id survey_create_question + +get_survey_info -section_id $section_id + +ad_form -name create_question -action question-add-2 -export { after } -form { + question_id:key + {section_id:text(hidden) {value $section_id}} + {question_text:text(textarea) {label "Question"} {html {rows 5 cols 70}}} +} + +ad_form -extend -name create_question -form { + {presentation_type:text(select) + {label "Presentation Type"} + {options {{ "One Line Answer (Text Field)" "textbox" } + { "Essay Answer (Text Area)" "textarea" } + { "Multiple Choice (Drop Down, single answer allowed)" "select" } + { "Multiple Choice (Radio Buttons, single answer allowed)" "radio" } + { "Multiple Choice (Checkbox, multiple answers allowed)" "checkbox" } + { "Date" "date" } + { "File Attachment" "upload_file" } } } } +} + + + +get_survey_info -section_id $section_id +set survey_id $survey_info(survey_id) +set context_bar [ad_context_bar [list "one?[export_url_vars survey_id]" $survey_info(name)] "Add A Question"] + +if {[ad_parameter allow_question_deactivation_p] == 1} { + ad_form -extend -name create_question -form { + {active:text(radio) {label "Active?"} {options {{Yes t} {No f}}} {value t}} + } +} else { + ad_form -extend -name create_question -form { + {active:text(hidden) {value t}} + } +} +ad_form -extend -name create_question -form { + {required:text(radio) {label "Required?"} {options {{Yes t} {No f}}} {value t}} +} + +ad_return_template + + + + Index: openacs.org-dev/packages/survey/www/admin/question-copy-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-copy-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-copy-postgresql.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,33 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="create_question"> + <querytext> + begin + PERFORM survey_question__new ( + NULL, + :section_id, + :new_sort_order, + :question_text, + :abstract_data_type, + :required_p, + :active_p, + :presentation_type, + :presentation_options, + :presentation_alignment, + :user_id, + :section_id + ); + end; + </querytext> +</fullquery> + +<fullquery name="get_choice_id"> +<querytext> +select survey_choice_id_sequence.nextval as choice_id +</querytext> +</fullquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/question-copy.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-copy.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-copy.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,21 @@ +ad_page_contract { + Copy a question to the same survey + @author dave@thedesignexperience.org + @date July 29, 2002 + @cvs-id $Id: +} { + question_id:integer,notnull + {sort_order 0} +} + +set package_id [ad_conn package_id] +set user_id [ad_get_user_id] + +ad_require_permission $package_id survey_create_question +set section_id [db_string get_section_id_from_question {}] +get_survey_info -section_id $section_id +set survey_id $survey_info(survey_id) +set new_question_id [survey_question_copy -question_id $question_id] +incr sort_order +ad_returnredirect "one?[export_vars survey_id]&#${sort_order}" + Index: openacs.org-dev/packages/survey/www/admin/question-copy.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-copy.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-copy.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,10 @@ +<?xml version="1.0"?> + +<queryset> +<fullquery name="get_section_id_from_question"> +<querytext> +select section_id from survey_questions + where question_id=:question_id +</querytext> +</fullquery> +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/question-delete-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-delete-2.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-delete-2.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,44 @@ +# /www/survsimp/admin/question-delete.tcl +ad_page_contract { + + Delete a question from a survey, along with all responses. + + @param question_id question we're deleting + @author jsc@arsdigita.com + @date March 13, 2000 + @cvs-id question-delete-2.tcl,v 1.6.2.4 2000/07/21 20:22:35 seb Exp +} { + + question_id:integer + +} + +ad_require_permission $question_id survey_delete_question + +set user_id [ad_get_user_id] + +db_1row section_id_from_question_id "" + +db_transaction { + db_dml survey_question_responses_delete "delete from survey_question_responses where question_id = :question_id" + +db_dml survey_question_choices_score_delete "delete from survey_choice_scores where choice_id in (select choice_id from survey_question_choices + where question_id = :question_id)" + + db_dml survey_question_choices_delete "delete from survey_question_choices where question_id = :question_id" + + db_dml survey_questions_delete "delete from survey_questions where question_id = :question_id" + +} on_error { + ad_return_error "Database Error" "There was an error while trying to delete the question: + <pre> + $errmsg + </pre> + <p> Please go back to the <a href=\"one?section_id=$section_id\">survey</a>. + " + ad_script_abort +} + +db_release_unused_handles +ad_returnredirect "one?[export_url_vars survey_id]" + Index: openacs.org-dev/packages/survey/www/admin/question-delete-2.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-delete-2.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-delete-2.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,46 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="section_id_from_question_id"> + <querytext> + select sq.section_id, sec.survey_id + from survey_questions sq, survey_sections sec + where sq.question_id = :question_id + and sq.section_id = sec.section_id + </querytext> +</fullquery> + + +<fullquery name="survey_question_responses_delete"> + <querytext> + delete from survey_question_responses where question_id = :question_id + </querytext> +</fullquery> + + +<fullquery name="survey_question_choices_score_delete"> + <querytext> + + delete from survey_choice_scores + where choice_id in (select choice_id from survey_question_choices + where question_id = :question_id) + + </querytext> +</fullquery> + + +<fullquery name="survey_question_choices_delete"> + <querytext> + delete from survey_question_choices where question_id = :question_id + </querytext> +</fullquery> + + +<fullquery name="survey_questions_delete"> + <querytext> + delete from survey_questions where question_id = :question_id + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/question-delete-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-delete-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-delete-oracle.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,14 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="survey_delete_question"> +<querytext> + begin + survey_question.remove (:question_id); + end; +</querytext> +</fullquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/question-delete-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-delete-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-delete-postgresql.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,15 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="survey_delete_question"> + <querytext> + + select survey_question__delete (:question_id); + + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/question-delete.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-delete.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-delete.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,8 @@ +<master src="master"> + +<property name="survey_id">@survey_id@</property> + +<property name="title">DELETE: Question</property> +<property name="context_bar">@context_bar@</property> + +<formtemplate id="confirm_delete"></formtemplate> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/question-delete.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-delete.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-delete.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,84 @@ +# /www/survsimp/admin/question-delete.tcl +ad_page_contract { + + Delete a question from a survey + (or ask for confirmation if there are responses). + + @param question_id question we're about to delete + + @author jsc@arsdigita.com + @date March 13, 2000 + @cvs-id question-delete.tcl,v 1.5.2.4 2000/07/21 04:04:15 ron Exp +} { + + question_id:integer + {sort_order ""} +} + +ad_require_permission $question_id survey_delete_question + +db_1row section_id_from_question_id "" + +get_survey_info -section_id $section_id +set survey_id $survey_info(survey_id) + +set n_responses [db_string survey_number_responses {} ] + +ad_form -name confirm_delete -export {sort_order} -form { + question_id:key + {question_text:text(inform) {label "Delete:"}} + {from:text(inform) {label "From:"} {value $survey_info(name)}} +} + +if {$n_responses > 0} { + if {$n_responses >1} { + set response_text "responses" + } else { + set response_text "response" + } + ad_form -extend -name confirm_delete -form { + {warning:text(inform) {value "This question has $n_responses $response_text that will be deleted if you continue. (Note: This can not be undone.)"} + {label "Warning!"}} + } + +} + +ad_form -extend -name confirm_delete -form { + {confirmation:text(radio) {label " "} + {options + {{"Continue with Delete" t } + {"Cancel and return to survey responses" f }} } + {value f}} + } -select_query_name {get_question_details} -on_submit { + if {$confirmation} { + db_transaction { + + db_dml survey_question_responses_delete {} + + db_dml survey_question_choices_delete {} + + db_exec_plsql survey_delete_question {} + if {![empty_string_p $sort_order]} { + db_exec_plsql survey_renumber_questions {} + } + } on_error { + + ad_return_error "Database Error" "There was an error while trying to delete the question: + <pre> + $errmsg + </pre> + <p> Please go back using your browser. + " + ad_script_abort + } + + db_release_unused_handles + set sort_order [expr {$sort_order -1}] + } + ad_returnredirect "one?[export_url_vars survey_id]&#${sort_order}" + ad_script_abort + } + +set context_bar [ad_context_bar "Delete Question"] +ad_return_template + Index: openacs.org-dev/packages/survey/www/admin/question-delete.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-delete.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-delete.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,52 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="section_id_from_question_id"> + <querytext> + select section_id + from survey_questions + where question_id = :question_id + </querytext> +</fullquery> + + +<fullquery name="survey_number_responses"> + <querytext> + select count(*) +from survey_question_responses +where question_id = :question_id + </querytext> +</fullquery> + + +<fullquery name="survey_question_responses_delete"> +<querytext> + delete from survey_question_responses + where question_id=:question_id +</querytext> +</fullquery> + +<fullquery name="survey_question_choices_delete"> + <querytext> + delete from survey_question_choices where + question_id = :question_id + </querytext> +</fullquery> + +<fullquery name="get_question_details"> +<querytext> + select * from survey_questions where question_id=:question_id +</querytext> +</fullquery> + +<fullquery name="survey_renumber_questions"> +<querytext> +update survey_questions set sort_order=sort_order -1 +where section_id in ( + select section_id from surveys where + survey_id=:survey_id) +and sort_order > :sort_order +</querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/question-modify-text.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-modify-text.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-modify-text.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,8 @@ +<master src="master"> +<property name="survey_id">@survey_id@</property> + +<property name=title>@survey_name@: Modify Question Text</property> +<property name=context_bar>@context_bar@</property> + +<formtemplate id="modify_question"></formtemplate> + Index: openacs.org-dev/packages/survey/www/admin/question-modify-text.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-modify-text.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-modify-text.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,40 @@ +ad_page_contract { + + Allow the user to modify the text of a question. + + @param section_id survey this question belongs to + @param question_id question which text we're changing + + @author cmceniry@arsdigita.com + @author nstrug@arsdigita.com + @date Jun 16, 2000 + @cvs-id $Id: question-modify-text.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} { + + question_id:integer + section_id:integer + +} + +ad_require_permission $section_id survey_modify_question + +get_survey_info -section_id $section_id +set survey_name $survey_info(name) +set survey_id $survey_info(survey_id) + +ad_form -name modify_question -form { + question_id:key + {question_text:text(textarea) {label Question} {html {rows 5 cols 70}}} + {section_id:text(hidden) {value $section_id}} + {survey_id:text(hidden) {value $survey_id}} +} -select_query_name {survey_question_text_from_id} -edit_data { + + db_dml survey_question_text_update "update survey_questions set question_text=:question_text where question_id=:question_id" + ad_returnredirect "one?survey_id=$survey_id" + ad_script_abort + +} + +set context_bar [ad_context_bar [list "one?[export_url_vars survey_id]" $survey_info(name)] "Modify a Question's Text"] + +ad_return_template Index: openacs.org-dev/packages/survey/www/admin/question-modify-text.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-modify-text.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-modify-text.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="survey_name_from_id"> + <querytext> + select name from survey_sections where section_id=:section_id + </querytext> +</fullquery> + + +<fullquery name="survey_question_text_from_id"> + <querytext> +select question_text +from survey_questions +where question_id = :question_id + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/question-modify.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-modify.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-modify.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,8 @@ +<master src="master"> +<property name="survey_id">@survey_id@</property> + +<property name=title>@survey_name@: Modify Question Text</property> +<property name=context_bar>@context_bar@</property> + +<formtemplate id="modify_question"></formtemplate> + Index: openacs.org-dev/packages/survey/www/admin/question-modify.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-modify.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-modify.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,146 @@ +ad_page_contract { + + Allow the user to modify a question. + + @param section_id survey this question belongs to + @param question_id question which text we're changing + + @author cmceniry@arsdigita.com + @author nstrug@arsdigita.com + @date Jun 16, 2000 + @cvs-id $Id: question-modify.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} { + + question_id:integer + section_id:integer + {valid_responses ""} + {presentation_options ""} + {sort_order ""} +} + +get_survey_info -section_id $section_id +set survey_name $survey_info(name) +set survey_id $survey_info(survey_id) +ad_require_permission $survey_id survey_modify_question +set allow_question_deactivation [ad_parameter "allow_question_deactivation_p"] +set n_responses [db_string survey_number_responses {} ] + +ad_form -name modify_question -form { + question_id:key +} + +if {$n_responses > 0} { + if {$n_responses >1} { + set isare "are" + set resp "responses" + } else { + set isare "is" + set resp "response" + } + ad_form -extend -name modify_question -form { + {warning:text(inform) {label "Warning!"} {value "<span style=\"color: #f00;\">There $isare $n_responses $resp to this question. Editing a question with responses is not recommnded. No record of the original question will remain. Proceed with caution."}} + } +} +ad_form -extend -name modify_question -export {sort_order} -form { + {question_number:text(inform) {label "Modify Question #"}} + {survey_name:text(inform) {label "From"} {value $survey_name}} + {question_text:text(textarea) {label Question} {html {rows 5 cols 70}}} +} + +if {$allow_question_deactivation == 1} { + ad_form -extend -name modify_question -form { + {active_p:text(radio) {label "Active?"} {options {{Yes t} {No f}}}} + } +} else { + ad_form -extend -name modify_question -form { + {active_p:text(hidden) {value t}} + } +} +ad_form -extend -name modify_question -form { + {required_p:text(radio) {label "Required?"} {options {{Yes t} {No f}}}} + {section_id:text(hidden) {value $section_id}} + {survey_id:text(hidden) {value $survey_id}} +} + + +db_1row presentation {} + +if {($presentation_type=="checkbox" || $presentation_type=="select" || $presentation_type=="radio") && $abstract_data_type != "boolean"} { + set valid_responses_list [db_list survey_question_valid_responses {}] + set response_list "" + foreach response $valid_responses_list { + append valid_responses "$response\n" + } + ad_form -extend -name modify_question -form { + {valid_responses:text(textarea) + {label "For Multiple Choice<br />Enter a List of Valid Responses<br /> (enter one choice per line)"} + {html {rows 10 cols 50}} + {value $valid_responses}} + } +} + +if {$presentation_type == "textarea" || $presentation_type == "textbox"} { + ad_form -extend -name modify_question -form { + {presentation_options:text(select) {options {{Small small} {Medium medium} {Large large}}} {value $presentation_options} {label "[string totitle $presentation_type] Size"}} + + } +} + + +ad_form -extend -name modify_question -select_query_name {survey_question_details} -edit_data { + + db_dml survey_question_update {} + + # add new responses is choice type question + + + if {[info exists valid_responses]} { + + set responses [split $valid_responses "\n"] + set count 0 + set response_list "" + foreach response $responses { + set trimmed_response [string trim $response] + if { [empty_string_p $trimmed_response] } { + # skip empty lines + continue + } + + lappend response_list [list "$trimmed_response" "$count"] + incr count + } + + set choice_id_to_update_list [db_list get_choice_id {}] + set choice_count 0 + foreach one_response $response_list { + set choice_name [lindex $one_response 0] + set choice_value [lindex $one_response 1] + set choice_id_to_update [lindex $choice_id_to_update_list $choice_count] + if {[empty_string_p $choice_id_to_update]} { + db_dml insert_new_choice {} + } else { + + db_dml update_new_choice {} + } + incr choice_count + } + while {[llength $choice_id_to_update_list] >= $choice_count} { + set choice_id_to_delete [lindex $choice_id_to_update_list $choice_count] + db_dml delete_old_choice {} + incr choice_count + } + + } + + + + + + ad_returnredirect "one?survey_id=$survey_id&#${sort_order}" + ad_script_abort +} + + +set context_bar [ad_context_bar "Modify Question"] + +ad_return_template Index: openacs.org-dev/packages/survey/www/admin/question-modify.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-modify.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-modify.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,92 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="survey_number_responses"> +<querytext> + select count(*) + from survey_question_responses + where question_id=:question_id +</querytext> +</fullquery> + +<fullquery name="survey_name_from_id"> + <querytext> + select name from survey_sections where section_id=:section_id + </querytext> +</fullquery> + + +<fullquery name="survey_question_details"> + <querytext> +select + question_id, + question_text, + abstract_data_type, + presentation_alignment, + presentation_options, + sort_order as question_number, + required_p, + sort_order +from survey_questions +where question_id = :question_id + </querytext> +</fullquery> + +<fullquery name="survey_question_valid_responses"> +<querytext> +select label from survey_question_choices +where question_id=:question_id +order by sort_order +</querytext> +</fullquery> + +<fullquery name="presentation"> +<querytext> +select presentation_type, presentation_options, abstract_data_type, +sort_order as anchor +from survey_questions +where question_id=:question_id +</querytext> +</fullquery> + +<fullquery name="survey_question_update"> +<querytext> +update survey_questions + set question_text=:question_text, + active_p=:active_p, + required_p=:required_p, + presentation_options=:presentation_options + where question_id=:question_id +</querytext> +</fullquery> + +<fullquery name="insert_new_choice"> +<querytext> +insert into survey_question_choices +(choice_id, question_id, label, sort_order) +values (survey_choice_id_sequence.nextval, :question_id, :choice_name, :choice_value) +</querytext> +</fullquery> + +<fullquery name="update_new_choice"> +<querytext> +update survey_question_choices + set label=:choice_name where choice_id=:choice_id_to_update +</querytext> +</fullquery> + +<fullquery name="delete_old_choice"> +<querytext> +delete from survey_question_choices where choice_id = :choice_id_to_delete +</querytext> +</fullquery> + +<fullquery name="get_choice_id"> +<querytext> + select choice_id from survey_question_choices + where question_id=:question_id + order by sort_order +</querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/question-required-toggle-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-required-toggle-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-required-toggle-oracle.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="survey_question_required_toggle"> + <querytext> + update survey_questions set required_p = util.logical_negation(required_p) +where section_id = :section_id +and question_id = :question_id + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/question-required-toggle-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-required-toggle-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-required-toggle-postgresql.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + + +<fullquery name="survey_question_required_toggle"> + <querytext> + update survey_questions set required_p = util__logical_negation(required_p) +where section_id = :section_id +and question_id = :question_id + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/question-required-toggle.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-required-toggle.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-required-toggle.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,32 @@ +# /www/survsimp/admin/question-required-toggle.tcl +ad_page_contract { + + Toggle required field for a question. + + @param required_p flag indicating original status of this question + @param section_id survey this question belongs to + @param question_id question we're dealing with + + @author jsc@arsdigita.com + @date February 9, 2000 + @cvs-id question-required-toggle.tcl,v 1.5.2.5 2000/07/23 16:53:34 seb Exp + +} { + + required_p:notnull + section_id:integer + question_id:integer + +} + +ad_require_permission $section_id survey_modify_question + +db_dml survey_question_required_toggle "update survey_questions set required_p = util.logical_negation(required_p) +where section_id = :section_id +and question_id = :question_id" + +db_release_unused_handles +get_survey_info -section_id $section_id +set survey_id $survey_info(survey_id) +ad_returnredirect "one?[export_url_vars survey_id]" + Index: openacs.org-dev/packages/survey/www/admin/question-swap.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-swap.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-swap.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,44 @@ +ad_page_contract { + + Swaps two sort keys for a survey, sort_order and sort_order - 1. + + @param section_id survey we're acting upon + @param sort_order integer determining position of question which is + about to be replaced with previous one + + @author nstrug@arsdigita.com + + @cvs-id $Id: question-swap.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ + +} { + survey_id:integer,notnull + section_id:integer,notnull + sort_order:integer,notnull + direction:notnull +} + +ad_require_permission $section_id survey_modify_survey + +if { $direction=="up" } { + set next_sort_order [expr { $sort_order - 1 }] +} else { + set next_sort_order [expr { $sort_order + 1 }] +} +db_transaction { + db_dml swap_sort_orders "update survey_questions +set sort_order = decode(sort_order, :sort_order, :next_sort_order, :next_sort_order, :sort_order) +where section_id = :section_id +and sort_order in (:sort_order, :next_sort_order)" + +} on_error { + + ad_return_error "Database error" "A database error occured while trying +to swap your questions. Here's the error: +<pre> +$errmsg +</pre> +" + ad_script_abort +} +ad_returnredirect "one?survey_id=$survey_id&#${sort_order}" + Index: openacs.org-dev/packages/survey/www/admin/question-swap.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/question-swap.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/question-swap.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="swap_sort_orders"> + <querytext> +update survey_questions +set sort_order = (case when sort_order = :sort_order then :next_sort_order when sort_order = :next_sort_order then :sort_order end) +where section_id = :section_id +and sort_order in (:sort_order, :next_sort_order) + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/respondents.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/respondents.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/respondents.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,7 @@ +<master src="master"> +<property name="survey_id">@survey_id@</property> + +<property name="title">@survey_name@: Respondents</property> +<property name="context_bar">@context_bar@</property> + +@respondents_table@ Index: openacs.org-dev/packages/survey/www/admin/respondents.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/respondents.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/respondents.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,40 @@ +ad_page_contract { + List respondents to this survey. + + @param section_id which survey we're displaying respondents to + + @author jsc@arsdigita.com + @author nstrug@arsdigita.com + @creation-date February 11, 2000 + @version $Id: respondents.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} -query { + survey_id:integer + {orderby "email"} + {response_type "responded"} +} -properties { + survey_name:onevalue + respondents:multirow +} + +ad_require_permission $survey_id survey_admin_survey + +# for sloanspace, we can also list users who have NOT responded or +# the entire group. + + +get_survey_info -survey_id $survey_id +set survey_name $survey_info(name) + +set context_bar [ad_context_bar [list "one?[export_url_vars survey_id]" $survey_info(name)] "Respondents"] + +set table_def { + {first_names "First Name" {upper(first_names) $order} {<td><a href="one-respondent?[export_vars {user_id survey_id}]">$first_names</a></td>}} + {last_name "Last Name" "" {<td><a href="one-respondent?[export_vars {user_id survey_id}]">$last_name</a></td>}} + {email "Email Address" "" {<td><a href="one-respondent?[export_vars {user_id survey_id}]">$email</a></td>}} + {actions "Actions" no_sort {<td><a href="one-respondent?[export_vars {user_id survey_id}]"><img src="/graphics/view.gif" border="0" alt="View"></a></td>}} +} + +set respondents_table [ad_table -Torderby $orderby -Textra_vars {survey_id} select_respondents {} $table_def] + +ad_return_template + Index: openacs.org-dev/packages/survey/www/admin/respondents.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/respondents.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/respondents.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<queryset> + + <fullquery name="select_respondents"> + <querytext> + select persons.first_names, persons.last_name, + acs_objects.creation_user as user_id, + parties.email + from survey_responses_latest s, + persons, + parties, + acs_objects + where s.survey_id=:survey_id + and s.response_id = acs_objects.object_id + and acs_objects.creation_user = persons.person_id + and persons.person_id = parties.party_id + group by acs_objects.creation_user, + parties.email, + persons.first_names, + persons.last_name + [ad_order_by_from_sort_spec $orderby $table_def] + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/response-delete-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/response-delete-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/response-delete-oracle.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,25 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> +<fullquery name="delete_response"> +<querytext> +begin + survey_response.remove(:response_id); +end; +</querytext> +</fullquery> + +<fullquery name="get_response_info"> +<querytext> +select survey_id, survey_response.initial_user_id(response_id) as user_id, + u.first_names || ' ' || last_name as user_name, + o.creation_date as response_date +from survey_responses, cc_users u, acs_objects o +where response_id=:response_id +and o.object_id = response_id +and u.user_id = survey_response.initial_user_id(response_id) +</querytext> +</fullquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/response-delete-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/response-delete-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/response-delete-postgresql.xql 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,21 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> +<fullquery name="delete_response"> +<querytext> +begin + survey_response__remove(:response_id); +end; +</querytext> +</fullquery> + +<fullquery name="get_response_info"> +<querytext> +select survey_id, survey_response__initial_user_id(response_id) as user_id +from survey_responses +where response_id=:response_id +</querytext> +</fullquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/response-delete.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/response-delete.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/response-delete.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,8 @@ +<master src="master"> + +<property name="survey_id">@survey_id@</property> + +<property name="title">DELETE: Survey Response</property> +<property name="context_bar">@context_bar@</property> + +<formtemplate id="confirm_delete"></formtemplate> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/response-delete.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/response-delete.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/response-delete.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,39 @@ +ad_page_contract { + + This page allows the admin to delete survey and all responses. + + @param survey_id + + @author dave@thedesignexperience.org + @date August 7, 2002 + @cvs-id $Id: response-delete.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ +} { + response_id:integer,optional +} + +set package_id [ad_conn package_id] +ad_require_permission $package_id survey_admin_survey + +db_1row get_response_info {} + +ad_form -name confirm_delete -form { + {response_id:text(hidden) {value $response_id}} + {survey_id:text(hidden) {value $survey_id}} + {user_id:text(hidden) {value $user_id}} + {warning:text(inform) {value "Completely delete ${user_name}'s response from $response_date? (Note: This can not be undone.)"} + {label "Warning!"}} + {confirmation:text(radio) {label " "} + {options + {{"Continue with Delete" t } + {"Cancel and return to survey responses" f }} } + {value f} + } + +} -on_submit { + if {$confirmation} { + db_exec_plsql delete_response {} + } + ad_returnredirect "one-respondent?[export_vars {survey_id user_id}]" +} + +set context_bar [ad_context_bar "Delete Response"] \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/response-drill-down.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/response-drill-down.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/response-drill-down.adp 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,15 @@ +<master src="master"> +<property name="survey_id">@survey_id@</property> + +<property name=title>People who answered @response_text@</property> +<property name=context_bar>@context_bar@</property> + +@survey_name@ responders who answered @response_text@ +when asked @question_text@: + +<ul> +<multiple name="user_responses"> +<li><a href="one-respondent?user_id=@user_responses.user_id@&survey_id=@survey_id@">@user_responses.responder_name@</a></li> + +</multiple> +</ul> Index: openacs.org-dev/packages/survey/www/admin/response-drill-down.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/response-drill-down.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/response-drill-down.tcl 8 Oct 2002 15:47:41 -0000 1.1 @@ -0,0 +1,57 @@ +ad_page_contract { + + Display the list of users who gave a particular answer to a + particular question. + + @param question_id question for which we're drilling down responses + @param choice_id we're seeking respondents who selected this choice + as an answer to question + + @author philg@mit.edu + @author jsc@arsdigita.com + @author nstrug@arsdigita.com + @date February 16, 2000 + @cvs-id $Id: response-drill-down.tcl,v 1.1 2002/10/08 15:47:41 rmello Exp $ + +} { + + question_id:integer,notnull + choice_id:integer,notnull + +} + +ad_require_permission $question_id survey_admin_survey + +# get the prompt text for the question and the ID for survey of +# which it is part + +set question_exists_p [db_0or1row get_question_text ""] +get_survey_info -section_id $section_id +set survey_name $survey_info(name) +set survey_id $survey_info(survey_id) + +if { !$question_exists_p } { + db_release_unused_handles + ad_return_error "Survey Question Not Found" "Could not find a survey question #$question_id" + return +} + +set response_exists_p [db_0or1row get_response_text ""] + +if { !$response_exists_p } { + db_release_unused_handles + ad_return_error "Response Not Found" "Could not find the response #$choice_id" + return +} + +# Get information of users who responded in particular manner to +# choice question. + +db_multirow user_responses all_users_for_response {} + +set context_bar [ad_context_bar \ + [list "one?[export_url_vars survey_id]" $survey_info(name)] \ + [list "responses?[export_url_vars survey_id]" "Responses"] \ + "One Response"] + +ad_return_template Index: openacs.org-dev/packages/survey/www/admin/response-drill-down.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/response-drill-down.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/response-drill-down.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,46 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="get_question_text"> + <querytext> + +select section_id, question_text, section_id +from survey_questions +where question_id = :question_id + + </querytext> +</fullquery> + + +<fullquery name="get_response_text"> + <querytext> + +select label as response_text +from survey_question_choices +where choice_id = :choice_id + </querytext> +</fullquery> + +<fullquery name="all_users_for_response"> + <querytext> + +select + first_names || ' ' || last_name as responder_name, + person_id as user_id, + creation_date +from + acs_objects, + survey_responses sr, + persons u, + survey_question_responses qr +where + qr.response_id = sr.response_id + and qr.response_id = object_id + and creation_user = person_id + and qr.question_id = :question_id + and qr.choice_id = :choice_id + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/response-editable-toggle-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/response-editable-toggle-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/response-editable-toggle-oracle.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,13 @@ +<?xml version="1.0"?> +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="survey_response_editable_toggle"> + <querytext> + update surveys set editable_p = util.logical_negation(editable_p) +where survey_id = :survey_id + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/response-editable-toggle-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/response-editable-toggle-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/response-editable-toggle-postgresql.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,13 @@ +<?xml version="1.0"?> +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="survey_response_editable_toggle"> + <querytext> + update surveys set editable_p = util__logical_negation(editable_p) +where survey_id = :survey_id + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/response-editable-toggle.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/response-editable-toggle.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/response-editable-toggle.tcl 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,22 @@ +ad_page_contract { + + Toggles a survey between allowing a user to + edit to or not. + + @param section_id survey we're dealing with + + @author Jin Choi (jsc@arsdigita.com) + @author nstrug@arsdigita.com + @cvs-id $Id: response-editable-toggle.tcl,v 1.1 2002/10/08 15:47:42 rmello Exp $ +} { + + survey_id:integer + +} + +ad_require_permission $survey_id survey_admin_survey + +db_dml survey_response_editable_toggle "" + +db_release_unused_handles +ad_returnredirect "one?[export_url_vars survey_id]" Index: openacs.org-dev/packages/survey/www/admin/response-limit-toggle-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/response-limit-toggle-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/response-limit-toggle-oracle.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="survey_reponse_toggle"> + <querytext> + update surveys +set single_response_p = util.logical_negation(single_response_p) +where survey_id = :survey_id + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/response-limit-toggle-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/response-limit-toggle-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/response-limit-toggle-postgresql.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="survey_reponse_toggle"> + <querytext> + update surveys +set single_response_p = util__logical_negation(single_response_p) +where survey_id = :survey_id + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/response-limit-toggle.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/response-limit-toggle.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/response-limit-toggle.tcl 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,21 @@ +# /www/survsimp/admin/response-limit-toggle.tcl +ad_page_contract { + + Toggles a survey between allowing multiple responses or one response per user. + + @param section_id survey whose properties we're changing + + @cvs-id response-limit-toggle.tcl,v 1.2.2.6 2000/07/21 04:04:21 ron Exp + +} { + + survey_id:integer + +} + +ad_require_permission $survey_id survey_admin_survey + +db_dml survey_reponse_toggle "" + +db_release_unused_handles +ad_returnredirect "one?[export_url_vars survey_id]" Index: openacs.org-dev/packages/survey/www/admin/responses-export-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/responses-export-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/responses-export-oracle.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,77 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="get_question_data_types"> +<querytext> + select question_id, abstract_data_type, q.sort_order, + question_text + from survey_questions q, survey_sections s + where s.survey_id = :survey_id + and s.section_id=q.section_id + order by q.sort_order,q.question_id +</querytext> +</fullquery> + +<fullquery name="get_all_survey_question_responses"> +<querytext> +select + sq.response_id, + sq.question_id, + sq.email, + sq.first_names, + sq.last_name, + sq.user_id, + sq.creation_date, + resp.boolean_answer, + resp.number_answer, + resp.date_answer, + resp.varchar_answer, + resp.clob_answer, + resp.attachment_answer, + resp.label + from + (select + sqr.response_id, + sqr.question_id, + sqr.boolean_answer, + sqr.number_answer, + sqr.date_answer, + sqr.varchar_answer, + sqr.clob_answer, + sqr.attachment_answer, + sqc.label, + sqc.sort_order + from + survey_responses sr, + survey_question_responses sqr, + survey_question_choices sqc + where + sr.survey_id=:survey_id + and sr.response_id = sqr.response_id + and sqr.question_id = sqc.question_id (+) + and sqr.choice_id = sqc.choice_id (+)) resp, + (select r.response_id, + q.question_id, + u.email, + u.first_names, + u.last_name, + r.user_id, + r.creation_date, + q.abstract_data_type, + q.sort_order + from survey_questions q, (select creation_user as user_id, creation_date, response_id from (select rownum as r_num, rt.* from survey_responses_latest rt where survey_id=:survey_id) where r_num >= $start and r_num <= $end) r, cc_users u, survey_sections ss + where ss.survey_id=:survey_id + and q.section_id=ss.section_id + and r.user_id = u.user_id) sq + where sq.response_id = resp.response_id (+) + and sq.question_id = resp.question_id (+) + order by + sq.response_id, + sq.sort_order, + sq.question_id, + resp.sort_order +</querytext> +</fullquery> +</queryset> Index: openacs.org-dev/packages/survey/www/admin/responses-export.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/responses-export.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/responses-export.tcl 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,136 @@ +# /www/survey/admin/responses-export.tcl +ad_page_contract { + + CSV export of responses to particular survey. + + @author sebastian@arsdigita.com + @date July 2000 + @cvs-id $Id: responses-export.tcl,v 1.1 2002/10/08 15:47:42 rmello Exp $ + +} { + + survey_id:integer,notnull + {unique_users_p f} + on_what_id:optional,integer + {start:naturalnum 1} + {end:naturalnum 10000} +} +set csv_export "" +set package_id [ad_conn package_id] +ad_require_permission $package_id survey_admin_survey + +set question_id_list [list] +set responses_table survey_responses + +set headline "email,first_names,last_name,user_id,submission_date,ip_address,response_id" + +db_foreach get_question_data_types {} { + lappend question_id_list $question_id + regsub -all {"} $question_text {""} question_text + append headline ",\"$question_text" + append headline "\"" + set question_data_type($question_id) $abstract_data_type + switch -- $abstract_data_type { + "date" { + set question_column($question_id) "date_answer" + } + "text" { + set question_column($question_id) "clob_answer" + } + "shorttext" { + set question_column($question_id) "varchar_answer" + } + "boolean" { + set question_column($question_id) "boolean_answer" + } + "integer" - + "number" { + set question_column($question_id) "number_answer" + } + "choice" { + set question_column($question_id) "label" + } + "blob" { + set question_column($question_id) "attachment_answer" + } + default { + set question_column($question_id) "varchar_answer" + } + } + +} + +# We're looping over all question responses in survey_question_responses + +set current_response_id "" +set current_response "" +set current_question_id "" +set current_question_list [list] +set csv_export "" +set r 0 +ReturnHeaders "application/text" +ns_write "$headline \r\n" + +db_foreach get_all_survey_question_responses "" { + + if { $response_id != $current_response_id } { + if { ![empty_string_p $current_question_id] } { + append current_response ",\"[join $current_question_list ","]\"" + } + + if { ![empty_string_p $current_response_id] } { + append csv_export "$current_response \r\n" + } + set current_response_id $response_id + set one_response [list $email $first_names $last_name $user_id $creation_date $response_id] + regsub -all {"} $one_response {""} one_response + set current_response "\"[join $one_response {","}]\"" + + set current_question_id "" + set current_question_list [list] + } + + set response_value [set $question_column($question_id)] + # Properly escape double quotes to make Excel & co happy + regsub -all {"} $response_value {""} response_value + + # Remove any CR or LF characters that may be present in text fields + regsub -all {[\r\n]} $response_value {} response_value + + if { $question_id != $current_question_id } { + if { ![empty_string_p $current_question_id] } { + append current_response ",\"[join $current_question_list ","]\"" + } + set current_question_id $question_id + set current_question_list [list] + } +# decode boolean answers + if {$question_data_type($question_id)=="boolean"} { + set response_value [survey_decode_boolean_answer -response $response_value -question_id $question_id] + } + if {$question_data_type($question_id)=="blob"} { + set response_value [db_string get_filename {} -default ""] + } + lappend current_question_list $response_value + + incr r + if {$r>99} { + ns_write "${csv_export} " + set csv_export "" + set rows 0 + } + + } + + if { ![empty_string_p $current_question_id] } { + append current_response ",\"[join $current_question_list ","]\"" + } + if { ![empty_string_p $current_response_id] } { + append csv_export "$current_response\r\n" + } + if {[empty_string_p $csv_export]} { + set csv_export "\r\n" + } + ns_write $csv_export + +ns_conn close \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/responses-export.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/responses-export.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/responses-export.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<queryset> + <fullquery name="get_filename"> + <querytext> + select title from cr_revisions where + revision_id=:attachment_answer + </querytext> + </fullquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/responses.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/responses.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/responses.adp 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,13 @@ +<master src="master"> +<property name="survey_id">@survey_id@</property> + +<property name=title>@survey_name@: Responses</property> +<property name=context_bar>@context_bar@</property> + +@return_html@ +<p> +@response_sentence@ + +<ul> +@results@ +</ul> Index: openacs.org-dev/packages/survey/www/admin/responses.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/responses.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/responses.tcl 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,92 @@ +ad_page_contract { + + View summary of all responses to one survey. + + @param section_id survey for which we're building list of responses + @param unique_users_p whether we will display only latest response for each user + + @author jsc@arsdigita.com + @author nstrug@arsdigita.com + @date February 11, 2000 + @cvs-id $Id: responses.tcl,v 1.1 2002/10/08 15:47:42 rmello Exp $ +} { + + survey_id:integer + +} + +ad_require_permission $survey_id survey_admin_survey + +set user_id [ad_get_user_id] + +# nstrug - 12/9/2000 +# Summarise scored responses for all users + +get_survey_info -survey_id $survey_id +set survey_name $survey_info(name) +set type $survey_info(type) + +set return_html "" + +# mbryzek - 3/27/2000 +# We need a way to limit the summary page to 1 response from +# each user. We use views to select out only the latest response +# from any given user + + +set results "" + +db_foreach survey_question_list {} { + append results "<li>#$sort_order $question_text +<blockquote> +" + switch -- $abstract_data_type { + "date" - + "text" - + "shorttext" { + append results "<a href=\"view-text-responses?question_id=$question_id\">View responses</a>\n" + } + + "boolean" { + + db_foreach survey_boolean_summary "" { + append results "[survey_decode_boolean_answer -response $boolean_answer -question_id $question_id]: $n_responses<br>\n" + } + } + "integer" - + "number" { + db_foreach survey_number_summary "" { + append results "$number_answer: $n_responses<br>\n" + } + db_1row survey_number_average "" + append results "<p>Mean: $mean<br>Standard Dev: $standard_deviation<br>\ +\n" + + } + "choice" { + db_foreach survey_section_question_choices "" { + append results "$label: <a href=\"response-drill-down?[export_url_vars question_id choice_id]\">$n_responses</a><br>\n" + } + } + "blob" { + db_foreach survey_attachment_summary {} { + append results "<a href=\"../view-attachment?response_id=$response_id&question_id=$question_id\">$title</a><br />" + } + } + } + append results "</blockquote>\n" +} + + + +set n_responses [db_string survey_number_responses {} ] + +if { $n_responses == 1 } { + set response_sentence "There has been 1 response." +} else { + set response_sentence "There have been $n_responses responses." +} + +set context_bar [ad_context_bar [list "one?[export_url_vars survey_id]" $survey_info(name)] "Responses"] + +ad_return_template Index: openacs.org-dev/packages/survey/www/admin/responses.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/responses.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/responses.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,76 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="survey_question_list"> + <querytext> + select question_id, question_text, abstract_data_type, sort_order +from survey_questions +where section_id in (select section_id from survey_sections + where survey_id=:survey_id) +order by sort_order + </querytext> +</fullquery> + + +<fullquery name="survey_boolean_summary"> + <querytext> +select count(*) as n_responses, (case when boolean_answer = 't' then 'True' when boolean_answer = 'f' then 'False' end) as boolean_answer +from survey_ques_responses_latest +where question_id = :question_id +group by boolean_answer +order by boolean_answer desc + </querytext> +</fullquery> + + +<fullquery name="survey_number_summary"> + <querytext> + select count(*) as n_responses, number_answer +from survey_ques_responses_latest +where question_id = :question_id +group by number_answer +order by number_answer + </querytext> +</fullquery> + + +<fullquery name="survey_number_average"> + <querytext> + select avg(number_answer) as mean, stddev(number_answer) as standard_deviation +from survey_ques_responses_latest +where question_id = :question_id + </querytext> +</fullquery> + + +<fullquery name="survey_section_question_choices"> + <querytext> + select count(*) as n_responses, label, qc.choice_id +from survey_ques_responses_latest qr, survey_question_choices qc +where qr.choice_id = qc.choice_id + and qr.question_id = :question_id +group by label, sort_order, qc.choice_id +order by sort_order + </querytext> +</fullquery> + +<fullquery name="survey_attachment_summary"> + <querytext> + select cr.title, qr.question_id, qr.response_id + from cr_revisions cr, survey_ques_responses_latest qr + where + revision_id=attachment_answer + and qr.question_id=question_id + </querytext> +</fullquery> + +<fullquery name="survey_number_responses"> + <querytext> + select count(*) +from survey_responses_latest +where survey_id=:survey_id +</querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/send-mail-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/send-mail-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/send-mail-oracle.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,139 @@ +<?xml version="1.0"?> +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + + <partialquery name="dotlrn_all"> + <querytext> + select '$sender_email' as from_addr, + '$sender_first_names' as sender_first_names, + '$sender_last_name' as sender_last_name, + parties.email, + decode(acs_objects.object_type, + 'user', + (select first_names + from persons + where person_id = parties.party_id), + 'group', + (select group_name + from groups + where group_id = parties.party_id), + 'rel_segment', + (select segment_name + from rel_segments + where segment_id = parties.party_id), + '') as first_names, + decode(acs_objects.object_type, + 'user', + (select last_name + from persons + where person_id = parties.party_id), + '') as last_name, + '$community_name' as community_name, + '$community_url' as community_url + from party_approved_member_map, + parties, + acs_objects + where party_approved_member_map.party_id = $segment_id + and party_approved_member_map.member_id <> $segment_id + and party_approved_member_map.member_id = parties.party_id + and parties.party_id = acs_objects.object_id + </querytext> + </partialquery> + + <partialquery name="dotlrn_responded"> + <querytext> + select '$sender_email' as from_addr, + '$sender_first_names' as sender_first_names, + '$sender_last_name' as sender_last_name, + parties.email, + decode(acs_objects.object_type, + 'user', + (select first_names + from persons + where person_id = parties.party_id), + 'group', + (select group_name + from groups + where group_id = parties.party_id), + 'rel_segment', + (select segment_name + from rel_segments + where segment_id = parties.party_id), + '') as first_names, + decode(acs_objects.object_type, + 'user', + (select last_name + from persons + where person_id = parties.party_id), + '') as last_name, + '$community_name' as community_name, + '$community_url' as community_url + from party_approved_member_map, + parties, + acs_objects + where party_approved_member_map.party_id = $segment_id + and party_approved_member_map.member_id <> $segment_id + and party_approved_member_map.member_id = parties.party_id + and parties.party_id = acs_objects.object_id + and parties.party_id in ( + select survey_response.initial_user_id(response_id) + from survey_responses_latest where survey_id=$survey_id) + </querytext> + </partialquery> + + <partialquery name="dotlrn_not_responded"> + <querytext> + select '$sender_email' as from_addr, + '$sender_first_names' as sender_first_names, + '$sender_last_name' as sender_last_name, + parties.email, + decode(acs_objects.object_type, + 'user', + (select first_names + from persons + where person_id = parties.party_id), + 'group', + (select group_name + from groups + where group_id = parties.party_id), + 'rel_segment', + (select segment_name + from rel_segments + where segment_id = parties.party_id), + '') as first_names, + decode(acs_objects.object_type, + 'user', + (select last_name + from persons + where person_id = parties.party_id), + '') as last_name, + '$community_name' as community_name, + '$community_url' as community_url + from party_approved_member_map, + parties, + acs_objects + where party_approved_member_map.party_id = $segment_id + and party_approved_member_map.member_id <> $segment_id + and party_approved_member_map.member_id = parties.party_id + and parties.party_id = acs_objects.object_id + and parties.party_id not in ( + select survey_response.initial_user_id(response_id) + from survey_responses_latest where survey_id=$survey_id) + </querytext> + </partialquery> + + <partialquery name="responded"> + <querytext> + select '$sender_email' as from_addr, + '$sender_first_names' as sender_first_names, + '$sender_last_name' as sender_last_name, + parties.email, + from parties + where parties.party_id = acs_objects.object_id + and parties.party_id in ( + select survey_response.initial_user_id(response_id) + from survey_responses_latest where survey_id=$survey_id) + </querytext> + </partialquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/send-mail-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/send-mail-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/send-mail-postgresql.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,140 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + + <partialquery name="dotlrn_all"> + <querytext> + select '$sender_email' as from_addr, + '$sender_first_names' as sender_first_names, + '$sender_last_name' as sender_last_name, + parties.email, + coalesce(acs_objects.object_type, + 'user', + (select first_names + from persons + where person_id = parties.party_id), + 'group', + (select group_name + from groups + where group_id = parties.party_id), + 'rel_segment', + (select segment_name + from rel_segments + where segment_id = parties.party_id), + '') as first_names, + coalesce(acs_objects.object_type, + 'user', + (select last_name + from persons + where person_id = parties.party_id), + '') as last_name, + '$community_name' as community_name, + '$community_url' as community_url + from party_approved_member_map, + parties, + acs_objects + where party_approved_member_map.party_id = $segment_id + and party_approved_member_map.member_id <> $segment_id + and party_approved_member_map.member_id = parties.party_id + and parties.party_id = acs_objects.object_id + </querytext> + </partialquery> + + <partialquery name="dotlrn_responded"> + <querytext> + select '$sender_email' as from_addr, + '$sender_first_names' as sender_first_names, + '$sender_last_name' as sender_last_name, + parties.email, + coalesce(acs_objects.object_type, + 'user', + (select first_names + from persons + where person_id = parties.party_id), + 'group', + (select group_name + from groups + where group_id = parties.party_id), + 'rel_segment', + (select segment_name + from rel_segments + where segment_id = parties.party_id), + '') as first_names, + coalesce(acs_objects.object_type, + 'user', + (select last_name + from persons + where person_id = parties.party_id), + '') as last_name, + '$community_name' as community_name, + '$community_url' as community_url + from party_approved_member_map, + parties, + acs_objects + where party_approved_member_map.party_id = $segment_id + and party_approved_member_map.member_id <> $segment_id + and party_approved_member_map.member_id = parties.party_id + and parties.party_id = acs_objects.object_id + and parties.party_id in ( + select survey_response__initial_user_id(response_id) + from survey_responses_latest where survey_id=$survey_id) + </querytext> + </partialquery> + + <partialquery name="dotlrn_not_responded"> + <querytext> + select '$sender_email' as from_addr, + '$sender_first_names' as sender_first_names, + '$sender_last_name' as sender_last_name, + parties.email, + coalesce(acs_objects.object_type, + 'user', + (select first_names + from persons + where person_id = parties.party_id), + 'group', + (select group_name + from groups + where group_id = parties.party_id), + 'rel_segment', + (select segment_name + from rel_segments + where segment_id = parties.party_id), + '') as first_names, + coalesce(acs_objects.object_type, + 'user', + (select last_name + from persons + where person_id = parties.party_id), + '') as last_name, + '$community_name' as community_name, + '$community_url' as community_url + from party_approved_member_map, + parties, + acs_objects + where party_approved_member_map.party_id = $segment_id + and party_approved_member_map.member_id <> $segment_id + and party_approved_member_map.member_id = parties.party_id + and parties.party_id = acs_objects.object_id + and parties.party_id not in ( + select survey_response__initial_user_id(response_id) + from survey_responses_latest where survey_id=$survey_id) + </querytext> + <partialquery> + + <partialquery name="responded"> + <querytext> + select '$sender_email' as from_addr, + '$sender_first_names' as sender_first_names, + '$sender_last_name' as sender_last_name, + parties.email, + from parties + where parties.party_id = acs_objects.object_id + and parties.party_id in ( + select survey_response__initial_user_id(response_id) + from survey_responses_latest where survey_id=$survey_id) + </querytext> + <partialquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/send-mail.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/send-mail.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/send-mail.adp 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,9 @@ +<master src="master"> + +<property name="survey_id">@survey_id@</property> + +<property name="title">Send Mail Re: @survey_name@</property> +<property name="context_bar">@context_bar@</property> + + <formtemplate id="send-mail"></formtemplate> + \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/send-mail.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/send-mail.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/send-mail.tcl 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,105 @@ +ad_page_contract { + + this page offers options for sending email regarding + a survey to various groups + + @param survey_id + + @author dave@thedesignexperience.org + @date July 29, 2002 + @cvs-id $Id: +} { + survey_id:integer,notnull + {package_id:integer 0} + {to "all"} +} + +set package_id [ad_conn package_id] +set user_id [ad_conn user_id] +set sender_id [ad_conn user_id] +set rel_type "dotlrn_member_rel" + +ad_require_permission $survey_id survey_admin_survey + +get_survey_info -survey_id $survey_id +set survey_name $survey_info(name) +db_1row select_sender_info {} +set dotlrn_installed_p [apm_package_installed_p dotlrn] +if {$dotlrn_installed_p} { + set community_id [dotlrn_community::get_community_id] + set segment_id [db_string select_rel_segment_id {}] + set community_name [dotlrn_community::get_community_name $community_id] + set community_url "[ad_parameter -package_id [ad_acs_kernel_id] SystemURL][dotlrn_community::get_community_url $community_id]" + + set n_responses [db_string n_responses {}] + if {$n_responses > 0} { + ad_form -name send-mail -form { + {to:text(radio) {options { + {"Everyone eligible to take this survey" "all"} + {"Everyone who has already taken this survey" "responded"} + {"Everyone who has not yet taken this survey" "not_responded"}}} + {label "Send mail to"} + {value $to} + } + } + } else { + ad_form -name send-mail -form { + {to:text(radio) {options { + {"Everyone eligible to take this survey" "all"} + {"Everyone who has not yet taken this survey" "not_responded"}}} + {label "Send mail to"} + {value $to} + } + } + } +} else { + ad_form -name send-mail -form { + {to:text(radio) {options { + {"Everyone who has already taken this survey" "all"}}} + {value "all"} + {label "Send mail to"} + } + } +} + +ad_form -extend -name send-mail -form { + {subject:text(text) {value $survey_name} {label "Message Subject"} {html {size 50}}} + {message:text(textarea) {label "Enter Message"} {html {rows 15 cols 60}}} + {survey_id:text(hidden) {value $survey_id}} + {package_id:text(hidden) {value $package_id}} +} -on_submit { + +set query "" + switch $to { + all { + if {$dotlrn_installed_p} { + set query [db_map dotlrn_all {}] + } + } + responded { + if {$dotlrn_installed_p} { + set query [db_map dotlrn_responded {}] + } else { + set query [db_map responded {}] + } + } + not_responded { + if {$dotlrn_installed_p} { + set query [db_map dotlrn_not_responded {}] + } + } + } + + bulk_mail::new \ + -package_id $package_id \ + -from_addr $sender_email \ + -subject $subject \ + -message $message \ + -query $query + ad_returnredirect "one?survey_id=$survey_id" + ad_script_abort +} + +set context_bar [ad_context_bar "Send Mail"] +ad_return_template + Index: openacs.org-dev/packages/survey/www/admin/send-mail.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/send-mail.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/send-mail.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,33 @@ +<?xml version="1.0"?> + +<queryset> + + <fullquery name="select_sender_info"> + <querytext> + select parties.email as sender_email, + persons.first_names as sender_first_names, + persons.last_name as sender_last_name + from parties, + persons + where parties.party_id = :sender_id + and persons.person_id = :sender_id + </querytext> + </fullquery> + + <fullquery name="select_rel_segment_id"> + <querytext> + select rel_segments.segment_id + from rel_segments + where rel_segments.group_id = :community_id + and rel_segments.rel_type = :rel_type + </querytext> + </fullquery> + + <fullquery name="n_responses"> + <querytext> + select count(*) from survey_responses_latest + where survey_id=:survey_id + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/site-wide-survey-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/site-wide-survey-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/site-wide-survey-oracle.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,21 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="select surveys"> + <querytext> + select s.survey_id, s.name, s.editable_p, s.single_response_p, + s.package_id, + acs_object.name(apm_package.parent_id(s.package_id)) as parent_name, + (select site_node.url(site_nodes.node_id) + from site_nodes + where site_nodes.object_id = s.package_id) as url + from surveys s + where enabled_p='t' + order by +parent_name, +upper(s.name) + </querytext> +</fullquery> +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/site-wide-survey.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/site-wide-survey.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/site-wide-survey.adp 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,16 @@ +<master> + +<if @surveys:rowcount@ gt 0> + <multiple name="surveys"> +@surveys.parent_name@ +<ul> +<group column="package_id"> + + <li> + <a href="@surveys.url@admin/one?survey_id=@surveys.survey_id@">@surveys.name@</a> + + </li> + +</group> +</ul> </multiple> +</if> Index: openacs.org-dev/packages/survey/www/admin/site-wide-survey.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/site-wide-survey.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/site-wide-survey.tcl 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,25 @@ +ad_page_contract { + Shows list of all surveys + in all mounted survey packages +} { + +} + +set user_id [ad_conn user_id] +permission::require_permission -party_id $user_id -object_id 0 -privilege admin + +db_multirow surveys get_surveys { + select s.survey_id, s.name, s.editable_p, s.single_response_p, + s.package_id, + acs_object.name(apm_package.parent_id(s.package_id)) as parent_name, + (select site_node.url(site_nodes.node_id) + from site_nodes + where site_nodes.object_id = s.package_id) as url + from surveys s + where enabled_p='t' + order by +parent_name, +upper(s.name) +} + +ad_return_template \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/survey-category-add-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-category-add-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-category-add-oracle.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,25 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="category_id_next_sequence"> + <querytext> + select + category_id_sequence.nextval from dual + </querytext> +</fullquery> + + +<fullquery name="category_map_insert"> + <querytext> + insert into site_wide_category_map + (map_id, category_id, + on_which_table, on_what_id, mapping_date, one_line_item_desc) + values (site_wide_cat_map_id_seq.nextval, :category_id, 'survey_sections', + :section_id, sysdate, :one_line_item_desc) + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/survey-category-add-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-category-add-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-category-add-postgresql.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,25 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="category_id_next_sequence"> + <querytext> + select + category_id_sequence.nextval + </querytext> +</fullquery> + + +<fullquery name="category_map_insert"> + <querytext> + insert into site_wide_category_map + (map_id, category_id, + on_which_table, on_what_id, mapping_date, one_line_item_desc) + values (site_wide_cat_map_id_seq.nextval, :category_id, 'survey_sections', + :section_id, current_timestamp, :one_line_item_desc) + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/survey-category-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-category-add.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-category-add.tcl 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,44 @@ +# /www/survsimp/admin/one-respondent.tcl +ad_page_contract { + + Inserts a category into the central categories table + and maps it to this survey. + + @param section_id which survey we'll assign category to + @param category name of a category to be created and assigned to survey + + @cvs-id survey-category-add.tcl,v 1.4.2.4 2000/07/21 04:04:22 ron Exp +} { + + section_id:integer,notnull + category:notnull + +} + + + + +db_transaction { + + set category_id [db_string category_id_next_sequence "select + category_id_sequence.nextval from dual"] + + db_dml category_insert "insert into categories + (category_id, category,category_type) + values (:category_id, :category, 'survsimp')" + + set one_line_item_desc "Survey: [db_string survey_name " + select name from survey_sections where section_id = :section_id" ]" + + db_dml category_map_insert "insert into site_wide_category_map + (map_id, category_id, + on_which_table, on_what_id, mapping_date, one_line_item_desc) + values (site_wide_cat_map_id_seq.nextval, :category_id, 'survey_sections', + :section_id, sysdate, :one_line_item_desc)" + +} + +get_survey_info -section_id $section_id +set survey_id $survey_info(survey_id) +ad_returnredirect "one?[export_url_vars survey_id]" + Index: openacs.org-dev/packages/survey/www/admin/survey-category-add.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-category-add.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-category-add.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="category_insert"> + <querytext> + insert into categories + (category_id, category,category_type) + values (:category_id, :category, 'survsimp') + </querytext> +</fullquery> + + +<fullquery name="survey_name"> + <querytext> + + select name from survey_sections where section_id = :section_id + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/survey-copy-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-copy-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-copy-postgresql.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,40 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="survey_create"> +<querytext> + :1 := survey__new ( + NULL, + :name, + :description, + :description_html_p, + :single_response_p, + :editable_p, + :enabled_p, + :single_section_p, + :type, + :display_type, + :package_id, + :user_id, + :package_id, + ); +</querytext> +</fullquery> + +<fullquery name="section_create"> +<querytext> + :1 := survey_section__new ( + NULL, + :new_survey_id, + :name, + :description, + :description_html_p, + :user_id, + :package_id + ); +</querytext> +</fullquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/survey-copy.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-copy.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-copy.adp 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,6 @@ +<master> +<property name="survey_id">@survey_id@</property> +<property name="title">Copy: @title_name@</property> +<property name="context_bar">@context_bar@</property> + +<formtemplate id="copy_survey"></formtemplate> Index: openacs.org-dev/packages/survey/www/admin/survey-copy.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-copy.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-copy.tcl 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,38 @@ +ad_page_contract { + Copy a survey + @author dave@thedesignexperience.org + @date August 3, 2002 + @cvs-id $Id: +} { + survey_id:integer,notnull + name:optional + new_survey_id:optional +} + +set package_id [ad_conn package_id] +set user_id [ad_get_user_id] + +ad_require_permission $package_id survey_create_question + +db_1row get_survey_info {} +set title_name $name +set name "Copy of $name" + +ad_form -name copy_survey -form { + new_survey_id:key + {message:text(inform) {value "Copying a survey will create a new survey with copies of all the questions.<br /> None of the response data will be duplicated."}} + {name:text(text) {label Name} {html {size 60}} {value $name}} + {survey_id:text(hidden) {value $survey_id}} + +} -on_submit { + set new_survey_id [survey_copy -survey_id $survey_id -new_name $name] + + set survey_id $new_survey_id + + ad_returnredirect "one?[export_vars survey_id]" + ad_script_abort +} + + +set context_bar [ad_context_bar "Copy $title_name"] +ad_return_template Index: openacs.org-dev/packages/survey/www/admin/survey-copy.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-copy.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-copy.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="get_survey_info"> +<querytext> +select * from surveys where survey_id=:survey_id +</querytext> +</fullquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/survey-create-choice.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-create-choice.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-create-choice.tcl 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,44 @@ +# /www/survsimp/admin/survey-create-choice.tcl +ad_page_contract { + + Ask the user what kind of survey they wish to create. + + @author nstrug@arsdigita.com + @date September 13, 2000 + @cvs-id $Id: survey-create-choice.tcl,v 1.1 2002/10/08 15:47:42 rmello Exp $ + +} { + + + +} + +set package_id [ad_conn package_id] +ad_require_permission $package_id survey_create_survey + +set whole_page "[ad_header "Choose Survey Type"] + +<h2>Choose a Survey Type</h2> + +[ad_context_bar "Choose Type"] + +<hr> + +<dl> +<dt><a href=\"survey-create?type=scored\">Scored Survey</a> +<dd>This is a multiple choice survey where each answer can be scored on one +or more variables. This survey also allows you to execute arbitrary +code (e.g. for redirects) conditional on the user's score at the end +of the survey.</dd> +<dt><a href=\"survey-create?type=general\">General Survey</a> +<dd>This survey allows you to specify the type of response +required. Use this survey if you want to allow users to enter their +own answers rather than choose from a list. You should also use this +survey if you wish to mix question types, e.g. have multiple choice +and free text answer questions in the same survey.</dd> +</dl> + +[ad_footer] +" + +doc_return 200 text/html $whole_page Index: openacs.org-dev/packages/survey/www/admin/survey-create-confirm.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-create-confirm.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-create-confirm.adp 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,11 @@ +<master> +<property name="title">Confirm Survey Details</property> + Survey Name: @name@ +<p> +Here is how your survey description will appear: +<blockquote> +@description@ +</blockquote> +</p> +<include src="/packages/acs-templating/resources/forms/confirm-button"> + Index: openacs.org-dev/packages/survey/www/admin/survey-create-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-create-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-create-oracle.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,49 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="create_survey"> + <querytext> + begin + :1 := survey.new ( + survey_id => :survey_id, + name => :name, + description => :description, + description_html_p => :description_html_p, + type => :type, + display_type => :display_type, + package_id => :package_id, + context_id => :package_id, + creation_user => :user_id, + enabled_p => :enabled_p + ); + end; + </querytext> +</fullquery> + +<fullquery name="create_section"> + <querytext> + begin + :1 := survey_section.new ( + section_id=>:section_id, + survey_id=>:survey_id, + name=>:name, + description=>empty_clob(), + description_html_p=>:description_html_p, + context_id=>:survey_id + ); + end; + </querytext> +</fullquery> + +<fullquery name="add_logic"> + <querytext> + insert into survey_logic + (logic_id, logic) + values + (:logic_id, empty_clob()) returning logic into :1 + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/survey-create-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-create-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-create-postgresql.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,49 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + +<fullquery name="create_survey"> + <querytext> + select survey__new ( + :survey_id, + :name, + :description, + :description_html_p, + 'f', + 't', + 'f', + 't', + :type, + :display_type, + :package_id, + :user_id, + :package_id + ) + </querytext> +</fullquery> + +<fullquery name="create_section"> + <querytext> + select survey_section__new ( + :section_id, + :survey_id, + :name, + :description, + :description_html_p, + :user_id, + :package_id + ) + </querytext> +</fullquery> + +<fullquery name="add_logic"> + <querytext> + insert into survey_logic + (logic_id, logic) + values + (:logic_id, :logic) + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/survey-create.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-create.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-create.adp 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,7 @@ +<master> + +<property name=title>Survey Administration: Create New Survey</property> +<property name=context_bar>@context_bar@</property> +<formtemplate id="create_survey"> +</formtemplate> + Index: openacs.org-dev/packages/survey/www/admin/survey-create.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-create.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-create.tcl 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,89 @@ +# /www/survsimp/admin/survey-create.tcl +ad_page_contract { + + Form for creating a survey. + + @param name title for new survey + @param description description for new survey + + @author raj@alum.mit.edu + @author nstrug@arsdigita.com + @date February 9, 2000 + @cvs-id $Id: survey-create.tcl,v 1.1 2002/10/08 15:47:42 rmello Exp $ + +} { + survey_id:optional + {name ""} + {description:html ""} + {variable_names ""} + {type "general"} +} + +set package_id [ad_conn package_id] + +# bounce the user if they don't have permission to admin surveys +ad_require_permission $package_id survey_create_survey +set user_id [ad_conn user_id] + +# use ad_form --DaveB +set display_type "list" + +ad_form -name create_survey -confirm_template survey-create-confirm -form { + survey_id:key + {display_type:text(hidden) {value $display_type}} + {name:text(text) {label "Survey Name"} {html {size 55}}} + {description:text(textarea) {label "Description"} {html {rows 10 cols 40}}} + {desc_html:text(radio) {label "The Above Description is"} + {options {{"Preformatted Text" "pre"} + {"HTML" "html"} {"Plain Text" "plain"}}} + {value "plain"} + } + +} -validate { + {name {[string length $name] <= 4000} + "Survey Name must be 4000 characters or less" +} {description {[string length $description] <= 4000} + "Survey Name must be 4000 characters or less" +} + {survey_id {[db_string count_surveys "select count(survey_id) from surveys where survey_id=:survey_id"] < 1} "oops" + } + +} -new_data { + + if {[string compare $desc_html "plain"] == 0} { + set description_html_p "f" + } else { + set description_html_p "t" + } + + if {[parameter::get -package_id $package_id -parameter survey_enabled_default_p -default 0]} { + set enabled_p "t" + } else { + set enabled_p "f" + } + db_transaction { + db_exec_plsql create_survey "" + + # survey type-specific inserts + + + # create new section here. the questions go in the section + # section_id is null to create a new section + # we might want to specify a section_id later for + # multiple section surveys + set section_id "" + set section_id [db_exec_plsql create_section ""] + } + ad_returnredirect "question-add?section_id=$section_id" + ad_script_abort +} + + + + +# function to insert survey type-specific form html + +set context_bar [ad_context_bar "Create Survey"] + +ad_return_template + Index: openacs.org-dev/packages/survey/www/admin/survey-create.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-create.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-create.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,36 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> + + +<fullquery name="add_variable_name"> + <querytext> + insert into survey_variables + (variable_id, variable_name) + values + (:variable_id, :variable_name) + </querytext> +</fullquery> + + +<fullquery name="map_variable_name"> + <querytext> + insert into survey_variables_surveys_map + (variable_id, section_id) + values + (:variable_id, :section_id) + </querytext> +</fullquery> + + +<fullquery name="map_logic"> + <querytext> + insert into survey_logic_surveys_map + (logic_id, section_id) + values + (:logic_id, :section_id) + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/survey-delete-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-delete-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-delete-oracle.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,13 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> +<fullquery name="delete_survey"> +<querytext> +begin + survey.remove(:survey_id); +end; +</querytext> +</fullquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/survey-delete-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-delete-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-delete-postgresql.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,13 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>postgresql</type><version>7.1</version></rdbms> +<fullquery name="delete_survey"> +<querytext> +begin + survey__remove(:survey_id); +end; +</querytext> +</fullquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/survey-delete.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-delete.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-delete.adp 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,9 @@ +<master src="master"> +<property name="survey_id">@survey_id@</property> + +<property name="survey_id">@survey_id@</property> + +<property name="title">DELETE: @survey_info.name@</property> +<property name="context_bar">@context_bar@</property> + +<formtemplate id="confirm_delete"></formtemplate> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/survey-delete.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-delete.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-delete.tcl 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,45 @@ +ad_page_contract { + + This page allows the admin to delete survey and all responses. + + @param survey_id + + @author dave@thedesignexperience.org + @date August 7, 2002 + @cvs-id $Id: survey-delete.tcl,v 1.1 2002/10/08 15:47:42 rmello Exp $ +} { + + survey_id:integer + +} + +set package_id [ad_conn package_id] +ad_require_permission $package_id survey_admin_survey + +get_survey_info -survey_id $survey_id + +set questions_count "" +set responses_count "" + +ad_form -name confirm_delete -form { + {survey_id:text(hidden) {value $survey_id}} + {warning:text(inform) {label "Warning:"} {value "Deleting this survey will delete all $questions_count questions and all $responses_count responses associated with this survey!"}} + {confirmation:text(radio) {label " "} + {options + {{"Continue with Delete" t } + {"Cancel and return to survey administration" f }} } + {value f} + } + +} -on_submit { + if {$confirmation} { + db_exec_plsql delete_survey {} + ad_returnredirect "." + ad_script_abort + } else { + ad_returnredirect "one?[export_vars survey_id]" + ad_script_abort + } +} + +set context_bar [ad_context_bar "Delete Survey"] \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/survey-display-type-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-display-type-edit.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-display-type-edit.tcl 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,20 @@ +ad_page_contract { + + Set the display type + + @param section_id survey whose properties we're changing + @cvs-id response-limit-toggle.tcl,v 1.2.2.6 2000/07/21 04:04:21 ron Exp + +} { + survey_id:integer + display_type:notnull +} + +ad_require_permission $survey_id survey_admin_survey + +if {[lsearch [survey_display_types] $display_type] > -1} { + db_dml survey_display_type_edit "" +} + +db_release_unused_handles +ad_returnredirect "one?[export_url_vars survey_id]" Index: openacs.org-dev/packages/survey/www/admin/survey-display-type-edit.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-display-type-edit.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-display-type-edit.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<queryset> +<fullquery name="survey_display_type_edit"> +<querytext> +update surveys + set display_type= :display_type + where survey_id = :survey_id +</querytext> +</fullquery> +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/survey-preview.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-preview.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-preview.adp 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,28 @@ +<master src="master"> +<property name="survey_id">@survey_id@</property> + +<property name=title>Preview One Survey: @name@</property> +<property name=context_bar>@context_bar@</property> +<a href="@return_url@">Return</a> + <table border="0" cellpadding="0" cellspacing="0" width="100%"> + <form enctype="multipart/form-data" > + <tr> + <td class="tabledata">@description@</td> + </tr> + <tr> + <td class="tabledata"><span style="color: #f00;">*</span> denotes a required question</td> + </tr> + <tr> + <td class="tabledata"><hr noshade size="1" color="#dddddd"></td> + </tr> + + <tr> + <td class="tabledata"> + @form_vars@ + <include src="../one_@display_type@" questions=@questions@> + <hr noshapde size="1" color="#dddddd"> + </td> + </tr> + + </form> + </table> Index: openacs.org-dev/packages/survey/www/admin/survey-preview.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-preview.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-preview.tcl 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,63 @@ +ad_page_contract { + + Display a questionnaire for one survey. + + @param section_id id of displayed survey + + @author philg@mit.edu + @author nstrug@arsdigita.com + @date 28th September 2000 + @cvs-id $Id: survey-preview.tcl,v 1.1 2002/10/08 15:47:42 rmello Exp $ + +} { + + survey_id:integer,notnull + {section_id:integer ""} + return_url:optional + +} -validate { + survey_exists -requires {survey_id} { + if ![db_0or1row survey_exists {}] { + ad_complain "Survey $survey_id does not exist" + } + } +} -properties { + + name:onerow + section_id:onerow + button_label:onerow + questions:onerow + description:onerow + modification_allowed_p:onerow + return_url:onerow +} + +ad_require_permission $survey_id survey_take_survey + + get_survey_info -survey_id $survey_id + set name $survey_info(name) + set description $survey_info(description) + set single_response_p $survey_info(single_response_p) + set editable_p $survey_info(editable_p) + set display_type $survey_info(display_type) + +set context_bar [ad_context_bar "Preview $name"] + +# build a list containing the HTML (generated with survey_question_display) for each question +set rownum 0 + +set questions [list] + +db_foreach survey_sections {} { + + db_foreach question_ids_select {} { + lappend questions [survey_question_display $question_id] + } + + + } + +set return_url "one?[export_vars survey_id]" +set form_vars [export_form_vars section_id survey_id] +ad_return_template + Index: openacs.org-dev/packages/survey/www/admin/survey-preview.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-preview.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-preview.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="survey_exists"> + <querytext> + select 1 from surveys where survey_id = :survey_id + </querytext> +</fullquery> + +<fullquery name="question_ids_select"> + <querytext> + select question_id + from survey_questions + where section_id = :section_id + and active_p = 't' + order by sort_order + </querytext> +</fullquery> + +<fullquery name="survey_sections"> + <querytext> + select section_id from survey_sections + where survey_id=:survey_id + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/survey-toggle.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-toggle.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-toggle.tcl 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,29 @@ +ad_page_contract { + Survey,-toggle.tcl will toggle (ie - enable or disable) a single survey. + + @param section_id survey we're toggling + @param enabled_p flag describing original state of survey + @param target URL where we will be redirected to after toggling + + @author raj@alum.mit.edu + @author nstrug@arsdigita.com + @date February 9, 2000 + @cvs-id $Id: survey-toggle.tcl,v 1.1 2002/10/08 15:47:42 rmello Exp $ +} { + survey_id:integer + enabled_p + {target "./"} +} + +ad_require_permission $survey_id survey_admin_survey + +if {$enabled_p == "f"} { + set enabled_p "t" +} else { + set enabled_p "f" +} + +db_dml survey_active_toggle "" + +ad_returnredirect "$target" + Index: openacs.org-dev/packages/survey/www/admin/survey-toggle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/survey-toggle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/survey-toggle.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,13 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="survey_active_toggle"> + <querytext> + update surveys + set enabled_p = :enabled_p + where survey_id = :survey_id + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/user-responses-delete-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/user-responses-delete-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/user-responses-delete-oracle.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,24 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="delete_response"> + <querytext> + begin + survey_response.remove(:response_id); + end; + </querytext> +</fullquery> + + +<fullquery name="get_response_info"> + <querytext> + select survey_id, survey_response.initial_user_id(response_id) as user_id, response_id, initial_response_id + from survey_responses + where survey_id=:survey_id + and survey_response.initial_user_id(response_id)=:user_id + </querytext> +</fullquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/user-responses-delete-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/user-responses-delete-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/user-responses-delete-postgresql.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,24 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms><type>oracle</type><version>8.1.6</version></rdbms> + +<fullquery name="delete_response"> + <querytext> + begin + survey_response__remove(:response_id); + end; + </querytext> +</fullquery> + + +<fullquery name="get_response_info"> + <querytext> + select survey_id, survey_response__initial_user_id(response_id) as user_id, response_id, initial_response_id + from survey_responses + where survey_id=:survey_id + and survey_response__initial_user_id(response_id)=:user_id + </querytext> +</fullquery> + +</queryset> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/user-responses-delete.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/user-responses-delete.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/user-responses-delete.adp 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,9 @@ +<master src="master"> +<property name="survey_id">@survey_id@</property> + +<property name="survey_id">@survey_id@</property> + +<property name="title">DELETE: Survey Response</property> +<property name="context_bar">@context_bar@</property> + +<formtemplate id="confirm_delete"></formtemplate> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/user-responses-delete.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/user-responses-delete.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/user-responses-delete.tcl 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,44 @@ +ad_page_contract { + + This page allows the admin to delete survey and all responses. + + @param survey_id + + @author dave@thedesignexperience.org + @date August 7, 2002 + @cvs-id $Id: user-responses-delete.tcl,v 1.1 2002/10/08 15:47:42 rmello Exp $ +} { + survey_id:integer + user_id:integer +} + +set package_id [ad_conn package_id] +ad_require_permission $package_id survey_admin_survey + +db_multirow responses get_response_info {} + +set response_count [template::multirow size responses] +ad_form -name confirm_delete -form { + {survey_id:text(hidden) {value $survey_id}} + {user_id:text(hidden) {value $user_id}} + {warning:text(inform) {label "Warning:"} {value "This will remove $response_count responses"}} + {confirmation:text(radio) {label " "} + {options + {{"Continue with Delete" t } + {"Cancel and return to survey responses" f }} } + {value f} + } + +} -on_submit { + if {$confirmation} { + template::multirow foreach responses { + if {[empty_string_p $initial_response_id]} { + db_exec_plsql delete_response {} + } + } + } + ad_returnredirect "one-respondent?[export_vars {survey_id user_id}]" + ad_script_abort +} + +set context_bar [ad_context_bar "Delete Response"] \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/view-text-responses-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/view-text-responses-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/view-text-responses-oracle.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="all_responses_to_question"> + <querytext> + select + $column_name as response, + person.name(o.creation_user) as respondent_name, + o.creation_date as submission_date, + o.creation_user, + o.creation_ip as ip_address + from + survey_responses r, + survey_question_responses qr, + acs_objects o + where + qr.response_id = r.response_id + and qr.question_id = :question_id + and o.object_id = qr.response_id + order by submission_date + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/view-text-responses-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/view-text-responses-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/view-text-responses-postgresql.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="all_responses_to_question"> + <querytext> + + select + $column_name as response, + person__name(acs_object__get_attribute(r.response_id,'creation_user')::text::integer) as respondent_name, + acs_object__get_attribute(r.response_id,'creation_date') as submission_date, + acs_object__get_attribute(r.response_id,'creation_user') as creation_user, + acs_object__get_attribute(r.response_id,'creation_ip') as ip_address + from + survey_responses r, + survey_question_responses qr + where + qr.response_id = r.response_id + and qr.question_id = :question_id + order by submission_date + </querytext> +</fullquery> + + +</queryset> Index: openacs.org-dev/packages/survey/www/admin/view-text-responses.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/view-text-responses.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/view-text-responses.adp 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,17 @@ +<master src="master"> + +<property name="survey_id">@survey_id@</property> + +<property name="title">@survey_name@: Responses to Question</property> +<property name="context_bar">@context_bar@</property> +@question_text@ +<hr /> +<if @responses:rowcount@ eq 0> + <em>No Responses</em> + </if> + <multiple name="responses"> +<a + href="one-respondent?user_id=@responses.creation_user@&survey_id=@survey_id@">@responses.respondent_name@</a> + on @responses.submission_date@ | @responses.response@ +<br /> +</multiple> \ No newline at end of file Index: openacs.org-dev/packages/survey/www/admin/view-text-responses.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/view-text-responses.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/view-text-responses.tcl 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,43 @@ +# /www/survsimp/admin/view-text-responses.tcl +ad_page_contract { + + View all the typed-in text responses for one question. + + @param question_id which question we want to list answers to + + @author jsc@arsdigita.com + @date February 11, 2000 + @cvs-id view-text-responses.tcl,v 1.5.2.3 2000/07/21 04:04:25 ron Exp + +} { + + question_id:integer,notnull + +} + +db_1row one_question "" + +get_survey_info -section_id $section_id +set survey_name $survey_info(name) +set survey_id $survey_info(survey_id) + +ad_require_permission $survey_id survey_admin_survey + +set abstract_data_type [db_string abstract_data_type "select abstract_data_type +from survey_questions q +where question_id = :question_id"] + +if { $abstract_data_type == "text" } { + set column_name "clob_answer" +} elseif { $abstract_data_type == "shorttext" } { + set column_name "varchar_answer" +} elseif { $abstract_data_type == "date" } { + set column_name "date_answer" +} + +set results "" + + +db_multirow responses all_responses_to_question {} + +set context_bar [ad_context_bar [list "one?[export_url_vars survey_id]" $survey_info(name)] "Responses to Question"] Index: openacs.org-dev/packages/survey/www/admin/view-text-responses.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/admin/view-text-responses.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/admin/view-text-responses.xql 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="one_question"> + <querytext> + select sq.question_text, sq.section_id + from survey_questions sq, survey_sections sec + where sq.question_id = :question_id + and sq.section_id = sec.section_id + </querytext> +</fullquery> + + +<fullquery name="abstract_data_type"> + <querytext> + select abstract_data_type + from survey_questions q + where question_id = :question_id + </querytext> +</fullquery> + +</queryset> Index: openacs.org-dev/packages/survey/www/doc/index.html =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/survey/www/doc/index.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/survey/www/doc/index.html 8 Oct 2002 15:47:42 -0000 1.1 @@ -0,0 +1,109 @@ +<html> +<!--AD_DND--> +<head> +<title>Survey</title> +</head> + +<body bgcolor=#ffffff text=#000000> +<h2>Survey</h2> + +A package for <a href="index">OpenACS 4.6</a> + +<hr> + +<h3>The Big Idea</h3> + +We want to be able to survey users. We want a non-technical person to +be able to design surveys from HTML forms. We want someone who is not +a site-admin to be able to review answers (we just give them admin + over the survey package.) + +<h3>Survey Question Possibilities</h3> + +Each survey question specifies an abstract data type for responses: + +<ul> + +<li>boolean +<li>number +<li>integer +<li>shorttext (less than 4000 characters) +<li>text +<li>choice + +</ul> + +Each survey also specifies a presentation type: + +<ul> +<li>textbox +<li>textarea (size can be specified in +<code>presentation_options</code>) +<li>select (from a fixed set of options in <code>survsimp_question_choices</code>) +<li>radio (from a fixed set of options in <code>survsimp_question_choices</code>) +<li>checkbox (from a fixed set of options in <code>survsimp_question_choices</code>) + +</ul> + +<h3>The data model</h3> + +We use the following tables: + +<ul> +<li><code>survey_questions</code> -- questions for each survey +<li><code>surveys</code> -- specs for one survey form (except the + questions) +<li><code>survey-sections</code> allows for future development of + branched or multi-part surveys +<li><code>survey_responses</code> -- user responses to surveys +<li><code>survey_question_responses</code> -- user responses to +individual questions within a survey + +</ul> + +The philosophy about storing the users responses is to use one single table to store all responses, i.e., we do not create a new table +when we create a new survey. In order to make it possible to store all +kinds of data in one table, we give the +<code>survey_question_responses</code> table five columns. + +<blockquote> +<pre><code> + -- if the user picked a canned response + choice_id references survey_question_choices, + boolean_answer char(1) check(boolean_answer in ('t','f')), + clob_answer clob, + number_answer number, + attachment_answer integer references cr_revisions(revision_id) + varchar_answer varchar(4000), +</code></pre> +</blockquote> + +Only one of the columns will be not-null. + +<p> + +Why the CLOB in addition to the varchar? The CLOB is necessary when +people are using this system for proposal solicitation (people might +type more than 4000 characters).</p> +<p>NOTE: Postgresql uses a text column in place of CLOB.</p> + <p>Attachment_answer allows for uploaded files to be stored in + the content-repository</p>. +<h3>User Interface</h3> + +The user interface for creating a survey is as follows: +<ol> +<li>User creates a survey, giving it a name and a description. +<li>User adds questions one by one, and is given the opportunity to reorder questions. + +<li>To add a question, user first types in the question and selects +its presentation type (radio buttons, checkbox, text field, etc.). +<li>Then the user is given the opportunity to specify further +attributes for the question depending upon the presentation type that +was chosen. For instance, any "choice" presentation (radio buttons, +checkboxes, and select lists) require a list of choices. A text field +requires the user to specify an abstract data type and the size of the +input field. +</ol> + + + \ No newline at end of file Index: openacs.org-dev/packages/ticket-tracker-lite/www/admin/master.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ticket-tracker-lite/www/admin/master.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ticket-tracker-lite/www/admin/master.adp 8 Oct 2002 15:47:43 -0000 1.1 @@ -0,0 +1,23 @@ +<master> +<property name="title">@title@</property> +<property name="context">@context@</property> +<property name="header_stuff">@header_stuff@</property> + +<table class="full" cellspacing=0> + <tr> + <td class="contextbar"><%= [eval ad_context_bar @context@] %></td> + <td class="contextbar" align=right> + <if @admin_url@ not nil><a class=tiny href=@admin_url@>Admin view</a></if> + </td> + </tr> + <tr> + <td></td> + <td align=right> + <if @right_header_html@ not nil>@right_header_html@</if> + </td> + </tr> +</table> + +<slave> + + Index: openacs.org-dev/packages/ticket-tracker-lite/www/admin/master.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/ticket-tracker-lite/www/admin/master.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/ticket-tracker-lite/www/admin/master.tcl 8 Oct 2002 15:47:43 -0000 1.1 @@ -0,0 +1,2 @@ +set header_stuff "<link rel=\"stylesheet\" type=\"text/css\" href=\"main.css\">" + Index: openacs.org-dev/packages/value-based-shipping/sql/oracle/value-based-shipping-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/value-based-shipping/sql/oracle/value-based-shipping-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/value-based-shipping/sql/oracle/value-based-shipping-create.sql 8 Oct 2002 15:47:44 -0000 1.1 @@ -0,0 +1,47 @@ +create table vbs_service_levels ( + service_level_id number not null primary key, + service_level_code varchar2(20), + service_level_description + varchar2(80) +); + +create sequence vbs_service_level_id_seq increment by 1 start with 1; +create function vbs_sequence return number is +ret number; +begin + select vbs_service_level_id_seq.nextval into ret from dual; + return ret; + end; +/ +show errors; +create view vbs_service_level_id_sequence as select vbs_sequence from dual; + +alter table vbs_service_levels add(constraint vbs_service_levels_uk unique(service_level_code)); + +create table vbs_rates( + shipping_rate_id number not null, + service_level_id number not null, + country_iso char(2), + from_value number not null, + to_value number, + from_zip_code varchar2(10), + to_zip_code varchar2(10), + shipping_rate number, + primary key(shipping_rate_id), + foreign key(service_level_id) references vbs_service_levels(service_level_id), + foreign key(country_iso) references countries(iso)); + +create sequence vbs_shipping_rate_id_seq increment by 1 start with 1; +create function vbs_ship_sequence return number is +ret number; +begin + select vbs_shipping_rate_id_seq.nextval into ret from dual; + return ret; + end; +/ +show errors; +create view vbs_shipping_rate_id_sequence as select vbs_ship_sequence from dual; + +alter table vbs_rates add(constraint vbs_rates_uk unique(service_level_id, country_iso, from_value, to_value, from_zip_code, to_zip_code)); + +@value-based-shipping-sc-create.sql Index: openacs.org-dev/packages/value-based-shipping/sql/oracle/value-based-shipping-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/value-based-shipping/sql/oracle/value-based-shipping-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/value-based-shipping/sql/oracle/value-based-shipping-drop.sql 8 Oct 2002 15:47:44 -0000 1.1 @@ -0,0 +1,12 @@ +drop table vbs_rates; +drop sequence vbs_shipping_rate_id_seq; +drop view vbs_shipping_rate_id_sequence; + +drop table vbs_service_levels; +drop sequence vbs_service_level_id_seq; +drop view vbs_service_level_id_sequence; + +drop function vbs_ship_sequence; +drop function vbs_sequence; + +@value-based-shipping-sc-drop.sql Index: openacs.org-dev/packages/value-based-shipping/sql/oracle/value-based-shipping-sc-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/value-based-shipping/sql/oracle/value-based-shipping-sc-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/value-based-shipping/sql/oracle/value-based-shipping-sc-create.sql 8 Oct 2002 15:47:44 -0000 1.1 @@ -0,0 +1,44 @@ +-- This is an implementation of the ShippingGateway service contract + +declare + foo integer; +begin + foo := acs_sc_impl.new( + 'ShippingGateway', -- impl_contract_name + 'value-based-shipping', -- impl_name + 'value-based-shipping' -- impl_owner_name + ); + + foo := acs_sc_impl.new_alias( + 'ShippingGateway', -- impl_contract_name + 'value-based-shipping', -- impl_name + 'RatesAndServicesSelection', -- impl_operation_name + 'value-based-shipping.rates_and_services_selection', + -- impl_alias + 'TCL' -- impl_pl + ); + + foo := acs_sc_impl.new_alias( + 'ShippingGateway', -- impl_contract_name + 'value-based-shipping', -- impl_name + 'ServiceDescription', -- impl_operation_name + 'value-based-shipping.service_description', + -- impl_alias + 'TCL' -- impl_pl + ); +end; +/ +show errors + +declare + foo integer; +begin + + -- Add the binding + acs_sc_binding.new ( + contract_name => 'ShippingGateway', + impl_name => 'value-based-shipping' + ); +end; +/ +show errors Index: openacs.org-dev/packages/value-based-shipping/sql/oracle/value-based-shipping-sc-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/value-based-shipping/sql/oracle/value-based-shipping-sc-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/value-based-shipping/sql/oracle/value-based-shipping-sc-drop.sql 8 Oct 2002 15:47:44 -0000 1.1 @@ -0,0 +1,28 @@ +declare + foo integer; +begin + foo := acs_sc_impl.delete_alias( + 'ShippingGateway', + 'value-based-shipping', + 'RatesAndServicesSelection' + ); + + foo := acs_sc_impl.delete_alias( + 'ShippingGateway', + 'value-based-shipping', + 'ServiceDescription' + ); + + acs_sc_binding.delete( + contract_name => 'ShippingGateway', + impl_name => 'value-based-shipping' + ); + + acs_sc_impl.delete( + 'ShippingGateway', + 'value-based-shipping' + ); +end; +/ +show errors + Index: openacs.org-dev/packages/value-based-shipping/www/admin/rate-delete-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/value-based-shipping/www/admin/rate-delete-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/value-based-shipping/www/admin/rate-delete-oracle.xql 8 Oct 2002 15:47:44 -0000 1.1 @@ -0,0 +1,19 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms> + <type>oracle</type> + <version>8.1.6</version> + </rdbms> + + <fullquery name="get_shipping_rate"> + <querytext> + select l.service_level_description, c.default_name as country, round(r.from_value, 2) as from_value, round(r.to_value, 2) as to_value, + r.from_zip_code, r.to_zip_code, round(r.shipping_rate, 2) as shipping_rate + from vbs_rates r, countries c, vbs_service_levels l + where r.country_iso = c.iso(+) and r.shipping_rate_id = :shipping_rate_id + and r.service_level_id = l.service_level_id + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/value-based-shipping/www/admin/rate-delete-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/value-based-shipping/www/admin/rate-delete-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/value-based-shipping/www/admin/rate-delete-postgresql.xql 8 Oct 2002 15:47:44 -0000 1.1 @@ -0,0 +1,19 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms> + <type>postgresql</type> + <version>7.1</version> + </rdbms> + + <fullquery name="get_shipping_rate"> + <querytext> + select l.service_level_description, c.default_name as country, round(r.from_value, 2) as from_value, round(r.to_value, 2) as to_value, + r.from_zip_code, r.to_zip_code, round(r.shipping_rate, 2) as shipping_rate + from vbs_rates r left join countries c on (r.country_iso = c.iso), vbs_service_levels l + where r.shipping_rate_id = :shipping_rate_id + and r.service_level_id = l.service_level_id + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/value-based-shipping/www/admin/rates-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/value-based-shipping/www/admin/rates-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/value-based-shipping/www/admin/rates-oracle.xql 8 Oct 2002 15:47:44 -0000 1.1 @@ -0,0 +1,19 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms> + <type>oracle</type> + <version>8.1.6</version> + </rdbms> + + <fullquery name="get_shipping_rates"> + <querytext> + select r.shipping_rate_id, l.service_level_description, c.default_name as country, round(r.from_value, 2) as from_value, round(r.to_value, 2) as to_value, + r.from_zip_code, r.to_zip_code, round(r.shipping_rate, 2) as shipping_rate + from vbs_rates r, countries c, vbs_service_levels l + where r.country_iso = c.iso(+) and r.service_level_id = l.service_level_id + order by l.service_level_description, c.default_name, r.from_value, nvl(r.to_value, 0), nvl(r.from_zip_code, '0') + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/value-based-shipping/www/admin/rates-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/value-based-shipping/www/admin/rates-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/value-based-shipping/www/admin/rates-postgresql.xql 8 Oct 2002 15:47:44 -0000 1.1 @@ -0,0 +1,19 @@ +<?xml version="1.0"?> + +<queryset> + <rdbms> + <type>postgresql</type> + <version>7.1</version> + </rdbms> + + <fullquery name="get_shipping_rates"> + <querytext> + select r.shipping_rate_id, l.service_level_description, c.default_name as country, round(r.from_value, 2) as from_value, round(r.to_value, 2) as to_value, + r.from_zip_code, r.to_zip_code, round(r.shipping_rate, 2) as shipping_rate + from vbs_rates r left join countries c on (r.country_iso = c.iso), vbs_service_levels l + where r.service_level_id = l.service_level_id + order by l.service_level_description, c.default_name, r.from_value, coalesce(r.to_value, 0), coalesce(r.from_zip_code, '0') + </querytext> + </fullquery> + +</queryset> Index: openacs.org-dev/packages/wap/www/doc/index.html =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/wap/www/doc/index.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/wap/www/doc/index.html 8 Oct 2002 15:47:44 -0000 1.1 @@ -0,0 +1,24 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> + <head> + <title>OpenACS WAP package</title> + </head> + + <body bgcolor=white> + <h2>OpenACS WAP package</h2> + <a href="../">OpenACS documentation</a> + <hr> + Pieces: + <ul> + <li><a href="wap-requirements.html">Original Requirements Document</a> </li> + <li><a href="wap-design.html">Original Design Document</a> </li> + </ul> + + <hr> + <address><a href="mailto:vkurup@massmed.org">Vinod Kurup</a></address> +<!-- Created: Mon Aug 13 14:17:34 EDT 2001 --> +<!-- hhmts start --> +Last modified: Fri Sep 13 08:42:43 EDT 2002 +<!-- hhmts end --> + </body> +</html> Index: openacs.org-dev/packages/wp-slim/www/presentation-print-view.adp =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/wp-slim/www/presentation-print-view.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/wp-slim/www/presentation-print-view.adp 8 Oct 2002 15:47:46 -0000 1.1 @@ -0,0 +1,96 @@ +<master> +<property name="title">@pres_title@</property> + +<h2>@pres_title@</h2> +a Wimpy Point Presentation owned by <a href="/shared/community-member?user_id=@owner_id@">@owner_name@</a> +@copyright_notice@ + +<multiple name="slides"> + <hr> + <h1> @slides.title@ </h1> + + <% get_attach_list @slides.slide_id@ %> + + <multiple name="attach_list"> + <if @attach_list.display@ eq "top"> + <img src="@subsite_name@attach/@attach_list.attach_id@/@attach_list.file_name@" alt="@attach_list.file_name@"> + </if> + </multiple> + + <table width="100%"> + <tr> + <td> + <p>@slides.preamble@ + </td> + <td align="right"> + <multiple name="attach_list"> + <if @attach_list.display@ eq "preamble"> + <img src="@subsite_name@/attach/@attach_list.attach_id@/@attach_list.file_name@" alt="@attach_list.file_name@"> + </if> + </multiple> + </td> + </tr> + </table> + + <multiple name="attach_list"> + <if @attach_list.display@ eq "after_preamble"> + <img src="@subsite_name@/attach/@attach_list.attach_id@/@attach_list.file_name@" alt="@attach_list.file_name@"> + </if> + </multiple> + + + <table width="100%"> + <tr> + <td> + <% + set rownum @slides.rownum@ + set bullet_list [ multirow get slides $rownum bullet_list ] + %> + <list name="bullet_list"> + <ul> + <li> @bullet_list:item@ </li> + </ul> + </list> + </td> + + <td align=right> + <multiple name="attach_list"> + <if @attach_list.display@ eq "bullets"> + <img src="@subsite_name@/attach/@attach_list.attach_id@/@attach_list.file_name@" alt="@attach_list.file_name@"> + </if> + </multiple> + </td> + + </tr> + </table> + + <multiple name="attach_list"> + <if @attach_list.display@ eq "after_bullets"> + <img src="@subsite_name@/attach/@attach_list.attach_id@/@attach_list.file_name@" alt="@attach_list.file_name@"> + </if> + </multiple> + + <table width="100%"> + <tr> + <td> + <p>@slides.postamble@ + </td> + + <td align=right> + <multiple name="attach_list"> + <if @attach_list.display@ eq "postamble"> + <img src="@subsite_name@/attach/@attach_list.attach_id@/@attach_list.file_name@" alt="@attach_list.file_name@"> + </if> + </multiple> + </td> + + </tr> + </table> + <multiple name="attach_list"> + <if @attach_list.display@ eq "bottom"> + <img src="../../attach/@attach_list.attach_id@/@attach_list.file_name@" alt="@attach_list.file_name@"> + </if> + </multiple> +</multiple> +<hr> +@page_signature@ Index: openacs.org-dev/packages/wp-slim/www/presentation-print-view.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/wp-slim/www/presentation-print-view.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/wp-slim/www/presentation-print-view.tcl 8 Oct 2002 15:47:46 -0000 1.1 @@ -0,0 +1,50 @@ +# /packages/wimpy-point/www/presentation-print-view.tcl +ad_page_contract { +This generates a printer friendly view of a presentation, suitable for print-out thru' a browser. + @author Samir Joshi(samir@symphinity.com) + @creation-date Thu 8 Aug 2002 + +} { + item_id:naturalnum,notnull +} -properties { + pres_title:onevalue + page_signature:onevalue + copyright_notice:onevalue + public_p:onevalue + show_modified_p :onevalue + audience:onevalue + background:onevalue + slides:multirow + owner_name:onevalue + owner_id : onevalue +} +set user_id [ad_verify_and_get_user_id] + +set subsite_name [ad_conn package_url] +regexp {^(.+)/$} $subsite_name match subsite_name + +set package_id [ad_conn package_id] +set pres_item_id $item_id +set url [ad_conn url] + +db_1row get_owner_name { +} + +db_1row get_presentation_data { +} + +db_1row get_aud_data { +} + +db_1row get_back_data { +} + +db_multirow slides get_slide_info { +} + +ad_return_template + + + + + Index: openacs.org-dev/packages/wp-slim/www/presentation-print-view.xql =================================================================== RCS file: /usr/local/cvsroot/openacs.org-dev/packages/wp-slim/www/presentation-print-view.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs.org-dev/packages/wp-slim/www/presentation-print-view.xql 8 Oct 2002 15:47:46 -0000 1.1 @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<queryset> + +<fullquery name="get_first_slide_item_id"> + <querytext> + + select item_id as first_slide_item_id + from cr_items + where content_type = 'cr_wp_slide' + and parent_id = :pres_item_id + and exists (select 1 from cr_wp_slides s where s.slide_id=cr_items.live_revision and s.sort_key=1) + + </querytext> +</fullquery> + +<fullquery name="get_owner_name"> + <querytext> + select first_names || ' ' || last_name as owner_name, person_id as owner_id + from persons, acs_objects + where persons.person_id = acs_objects.creation_user + and acs_objects.object_id = :pres_item_id + </querytext> +</fullquery> + +<fullquery name="get_presentation_data"> + <querytext> + select p.pres_title, p.page_signature, p.style, p.copyright_notice, p.public_p, p.show_modified_p + from cr_wp_presentations p, cr_items i + where i.item_id = :pres_item_id + and i.live_revision = p.presentation_id + </querytext> +</fullquery> + +<fullquery name="get_aud_data"> + <querytext> + select name as audience + from cr_revisions, cr_items + where cr_items.content_type = 'cr_wp_presentation_aud' + and cr_items.parent_id = :pres_item_id + and cr_revisions.revision_id = cr_items.live_revision + </querytext> +</fullquery> + +<fullquery name="get_back_data"> + <querytext> + select name as background + from cr_revisions r, cr_items i + where i.content_type = 'cr_wp_presentation_back' + and i.parent_id = :pres_item_id + and r.revision_id = i.live_revision + </querytext> +</fullquery> + +<fullquery name="get_slide_info"> + <querytext> + select s.slide_title as title , + i.item_id as slide_id , + s.sort_key,wp_slide__get_preamble(i.item_id) as preamble, + wp_slide__get_postamble(i.item_id) as postamble, + wp_slide__get_bullet_items(i.item_id) as bullet_list + from cr_wp_slides s, cr_items i + where i.parent_id = :pres_item_id + and i.live_revision = s.slide_id + order by s.sort_key + </querytext> +</fullquery> + +</queryset>