diff --git a/doc/basics.html b/doc/basics.html index df65b45..6ce6b98 100644 --- a/doc/basics.html +++ b/doc/basics.html @@ -36,22 +36,22 @@ for your installation:

Every piece of information in an XML file (elements, text, numbers) is stored in memory in "nodes". Nodes are defined by the mxml_node_t +href='#mxml_node_t'>mxml_node_t structure. The type member +href='#mxml_type_t'>type member defines the node type (element, integer, opaque, real, or text) which determines which value you want to look at in the value union.

+href='#mxml_value_t'>value union.

New nodes can be created using the mxmlNewElement(), +href='#mxmlNewElement'>mxmlNewElement(), mxmlNewInteger(), +href='#mxmlNewInteger'>mxmlNewInteger(), mxmlNewOpaque(), -mxmlNewReal(), +href='#mxmlNewOpaque'>mxmlNewOpaque(), +mxmlNewReal(), and mxmlNewText() +href='#mxmlNewText'>mxmlNewText() functions. Only elements can have child nodes, and the top node must be an element, usually "?xml".

@@ -98,7 +98,7 @@ like the following in memory:

to the first child node.

Once you are done with the XML data, use the mxmlDelete() +href='#mxmlDelete'>mxmlDelete() function to recursively free the memory that is used for a particular node or the entire tree:

@@ -109,15 +109,15 @@ particular node or the entire tree:

Loading and Saving XML Files

You load an XML file using the mxmlLoadFile() +href='#mxmlLoadFile'>mxmlLoadFile() function:

     FILE *fp;
-    mxml_node_t *tree;
+    mxml_node_t *tree;
 
     fp = fopen("filename.xml", "r");
-    tree = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
+    tree = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
     fclose(fp);
 
@@ -131,15 +131,15 @@ attribute values to determine the proper value type to return. The default value type is MXML_TEXT if no callback is used.

Similarly, you save an XML file using the mxmlSaveFile() +href='#mxmlSaveFile'>mxmlSaveFile() function:

     FILE *fp;
-    mxml_node_t *tree;
+    mxml_node_t *tree;
 
     fp = fopen("filename.xml", "w");
-    mxmlSaveFile(tree, fp, MXML_NO_CALLBACK);
+    mxmlSaveFile(tree, fp, MXML_NO_CALLBACK);
     fclose(fp);
 
@@ -154,49 +154,49 @@ whitespace should be added and the string to insert (spaces, tabs, carriage returns, and newlines) otherwise.

The mxmlLoadString(), +href='#mxmlLoadString'>mxmlLoadString(), mxmlSaveAllocString(), +href='#mxmlSaveAllocString'>mxmlSaveAllocString(), and mxmlSaveString() +href='#mxmlSaveString'>mxmlSaveString() functions load XML node trees from and save XML node trees to strings:

     char buffer[8192];
     char *ptr;
-    mxml_node_t *tree;
+    mxml_node_t *tree;
 
     ...
-    tree = mxmlLoadString(NULL, buffer, MXML_NO_CALLBACK);
+    tree = mxmlLoadString(NULL, buffer, MXML_NO_CALLBACK);
 
     ...
-    mxmlSaveString(tree, buffer, sizeof(buffer), MXML_NO_CALLBACK);
+    mxmlSaveString(tree, buffer, sizeof(buffer), MXML_NO_CALLBACK);
 
     ...
-    ptr = mxmlSaveAllocString(tree, MXML_NO_CALLBACK);
+    ptr = mxmlSaveAllocString(tree, MXML_NO_CALLBACK);
 

Finding and Iterating Nodes

The mxmlWalkPrev() +href='#mxmlWalkPrev'>mxmlWalkPrev() and mxmlWalkNext()functions +href='#mxmlWalkNext'>mxmlWalkNext()functions can be used to iterate through the XML node tree:

-    mxml_node_t *node = mxmlWalkPrev(current, tree, MXML_DESCEND);
+    mxml_node_t *node = mxmlWalkPrev(current, tree, MXML_DESCEND);
 
-    mxml_node_t *node = mxmlWalkNext(current, tree, MXML_DESCEND);
+    mxml_node_t *node = mxmlWalkNext(current, tree, MXML_DESCEND);
 

In addition, you can find a named element/node using the mxmlFindElement() +href='#mxmlFindElement'>mxmlFindElement() function:

-    mxml_node_t *node = mxmlFindElement(tree, tree, "name", "attr",
+    mxml_node_t *node = mxmlFindElement(tree, tree, "name", "attr",
                                 	"value", MXML_DESCEND);
 
@@ -206,30 +206,30 @@ e.g.:

     /* Find the first "a" element */
-    node = mxmlFindElement(tree, tree, "a", NULL, NULL, MXML_DESCEND);
+    node = mxmlFindElement(tree, tree, "a", NULL, NULL, MXML_DESCEND);
 
     /* Find the first "a" element with "href" attribute */
-    node = mxmlFindElement(tree, tree, "a", "href", NULL, MXML_DESCEND);
+    node = mxmlFindElement(tree, tree, "a", "href", NULL, MXML_DESCEND);
 
     /* Find the first "a" element with "href" to a URL */
-    node = mxmlFindElement(tree, tree, "a", "href",
+    node = mxmlFindElement(tree, tree, "a", "href",
                 	   "http://www.easysw.com/~mike/mxml/", MXML_DESCEND);
 
     /* Find the first element with a "src" attribute*/
-    node = mxmlFindElement(tree, tree, NULL, "src", NULL, MXML_DESCEND);
+    node = mxmlFindElement(tree, tree, NULL, "src", NULL, MXML_DESCEND);
 
     /* Find the first element with a "src" = "foo.jpg" */
-    node = mxmlFindElement(tree, tree, NULL, "src", "foo.jpg", MXML_DESCEND);
+    node = mxmlFindElement(tree, tree, NULL, "src", "foo.jpg", MXML_DESCEND);
 

You can also iterate with the same function:

-    mxml_node_t *node;
+    mxml_node_t *node;
 
-    for (node = mxmlFindElement(tree, tree, "name", NULL, NULL, MXML_DESCEND);
+    for (node = mxmlFindElement(tree, tree, "name", NULL, NULL, MXML_DESCEND);
          node != NULL;
-         node = mxmlFindElement(node, tree, "name", NULL, NULL, MXML_DESCEND))
+         node = mxmlFindElement(node, tree, "name", NULL, NULL, MXML_DESCEND))
     {
       ... do something ...
     }
diff --git a/doc/mxml.html b/doc/mxml.html
index b57f856..d9dce2f 100644
--- a/doc/mxml.html
+++ b/doc/mxml.html
@@ -23,7 +23,7 @@ PRE { font-family: monospace }
 Michael Sweet
Copyright 2003-2004
-
+

Table of Contents



Introduction @@ -101,9 +101,16 @@ Copyright 2003-2004
  • mxmlDelete()
  • mxmlElementGetAttr()
  • mxmlElementSetAttr()
  • +
  • mxmlEntityAddCallback()
  • mxmlEntityGetName()
  • mxmlEntityGetValue()
  • +
  • mxmlEntityRemoveCallback()
  • mxmlFindElement()
  • +
  • mxmlIndexDelete()
  • +
  • mxmlIndexEnum()
  • +
  • mxmlIndexFind()
  • +
  • mxmlIndexNew()
  • +
  • mxmlIndexReset()
  • mxmlLoadFile()
  • mxmlLoadString()
  • mxmlNewElement()
  • @@ -129,6 +136,7 @@ Copyright 2003-2004
  • Structures
  • -
    +

    3 - More Mini-XML Programming Techniques

    This chapter shows additional ways to use the Mini-XML library in @@ -602,7 +615,7 @@ mxmlSaveString() functions load XML node trees from and save

    Changing Node Values

    Formatted Text

    Indexing

    -
    +

    4 - Using the mxmldoc Utility

    This chapter describes how to use the mxmldoc(1) utility that comes with Mini-XML to automatically generate documentation for @@ -957,7 +970,7 @@ align="bottom"> Listing 4-1, XML Schema File "mxmldoc.xsd" (con't)< -


    +

    A - GNU Library General Public License

    Version 2, June 1991 @@ -1333,11 +1346,22 @@ align="bottom"> Listing 4-1, XML Schema File "mxmldoc.xsd" (con't)< SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

    END OF TERMS AND CONDITIONS

    -
    +

    B - Release Notes

    Changes in Mini-XML 2.0

    • New programmers manual.
    • +
    • Added UTF-16 support (input only; all output is UTF-8)
    • +
    • Added index functions to build a searchable index of XML nodes.
    • +
    • Added character entity callback interface to support additional + character entities beyond those defined in the XHTML specification.
    • +
    • Added support for XHTML character entities.
    • +
    • The mxmldoc utility now produces XML output which conforms to an + updated XML schema, described in the file "doc/mxmldoc.xsd".
    • +
    • Changed the whitespace callback interface to return strings instead + of a single character, allowing for greater control over the formatting + of XML files written using Mini-XML. THIS CHANGE WILL REQUIRE CHANGES + TO YOUR 1.x CODE IF YOU USE WHITESPACE CALLBACKS.
    • The mxmldoc utility now produces XML output which conforms to an updated XML schema, described in the file "doc/mxmldoc.xsd".
    • Changed the whitespace callback interface to return strings instead @@ -1456,7 +1480,7 @@ align="bottom"> Listing 4-1, XML Schema File "mxmldoc.xsd" (con't)<
      • Initial public release.
      -
      +

      C - Library Reference

      Contents

      @@ -1498,9 +1523,18 @@ align="bottom"> Listing 4-1, XML Schema File "mxmldoc.xsd" (con't)<
    • mxmlDelete()
    • mxmlElementGetAttr()
    • mxmlElementSetAttr()
    • +
    • mxmlEntityAddCallback() +
    • mxmlEntityGetName()
    • mxmlEntityGetValue()
    • +
    • mxmlEntityRemoveCallback() +
    • mxmlFindElement()
    • +
    • mxmlIndexDelete()
    • +
    • mxmlIndexEnum()
    • +
    • mxmlIndexFind()
    • +
    • mxmlIndexNew()
    • +
    • mxmlIndexReset()
    • mxmlLoadFile()
    • mxmlLoadString()
    • mxmlNewElement()
    • @@ -1638,6 +1672,29 @@ mxmlElementSetAttr(

      Returns

      Nothing.

      + +

      mxmlEntityAddCallback()

      +
      +

      Description

      +

      Add a callback to convert entities to Unicode.

      +

      Syntax

      +
      +void
      +mxmlEntityAddCallback(
      +    int (*cb)(const char *name));
      +
      +

      Arguments

      +

      + + + + + +
      NameDescription
      (*cb)(const char *name)Callback function to + add
      +

      Returns

      +

      Nothing.

      +

      mxmlEntityGetName()


      @@ -1685,6 +1742,29 @@ mxmlEntityGetValue(

      Returns

      Character value or -1 on error

      + +

      mxmlEntityRemoveCallback()

      +
      +

      Description

      +

      Remove a callback.

      +

      Syntax

      +
      +void
      +mxmlEntityRemoveCallback(
      +    int (*cb)(const char *name));
      +
      +

      Arguments

      +

      + + + + + +
      NameDescription
      (*cb)(const char *name)Callback function to + remove
      +

      Returns

      +

      Nothing.

      +

      mxmlFindElement()


      @@ -1726,6 +1806,134 @@ mxmlFindElement(

      Returns

      Element node or NULL

      + +

      mxmlIndexDelete()

      +
      +

      Description

      +

      Delete an index.

      +

      Syntax

      +
      +void
      +mxmlIndexDelete(
      +    mxml_index_t * ind);
      +
      +

      Arguments

      +

      + + + + + +
      NameDescription
      indIndex to delete
      +

      Returns

      +

      Nothing.

      + + +

      mxmlIndexEnum()

      +
      +

      Description

      +

      Return the next node in the index. Nodes are returned in the sorted + order of the index.

      +

      Syntax

      +
      +mxml_node_t *
      +mxmlIndexEnum(
      +    mxml_index_t * ind);
      +
      +

      Arguments

      +

      + + + + + +
      NameDescription
      indIndex to enumerate
      +

      Returns

      +

      Next node or NULL if there is none

      + + +

      mxmlIndexFind()

      +
      +

      Description

      +

      Find the next matching node. You should call mxmlIndexReset() prior + to using this function for the first time with a particular set of + "element" and "value" strings. Passing NULL for both "element" and + "value" is equivalent to calling mxmlIndexEnum().

      +

      Syntax

      +
      +mxml_node_t *
      +mxmlIndexFind(
      +    mxml_index_t * ind,
      +    const char * element,
      +    const char * value);
      +
      +

      Arguments

      +

      + + + + + + + +
      NameDescription
      indIndex to search
      elementElement name to find, if any
      valueAttribute value, if any
      +

      Returns

      +

      Node or NULL if none found

      + + +

      mxmlIndexNew()

      +
      +

      Description

      +

      Create a new index. The index will contain all nodes that contain the + named element and/or attribute. If both "element" and "attr" are NULL, + then the index will contain a sorted list of the elements in the node + tree. Nodes are sorted by element name and optionally by attribute + value if the "attr" argument is not NULL.

      +

      Syntax

      +
      +mxml_index_t *
      +mxmlIndexNew(
      +    mxml_node_t * node,
      +    const char * element,
      +    const char * attr);
      +
      +

      Arguments

      +

      + + + + + + + +
      NameDescription
      nodeXML node tree
      elementElement to index or NULL for all
      attrAttribute to index or NULL for none
      +

      Returns

      +

      New index

      + + +

      mxmlIndexReset()

      +
      +

      Description

      +

      Reset the enumeration/find pointer in the index and return the first + node in the index. This function should be called prior to using + mxmlIndexEnum() or mxmlIndexFind() for the first time.

      +

      Syntax

      +
      +mxml_node_t *
      +mxmlIndexReset(
      +    mxml_index_t * ind);
      +
      +

      Arguments

      +

      + + + + + +
      NameDescription
      indIndex to reset
      +

      Returns

      +

      First node or NULL if there is none

      +

      mxmlLoadFile()


      @@ -2327,6 +2535,7 @@ mxmlWalkPrev(

      Structures

    + +

    mxml_index_t

    +
    +

    Description

    +

    An XML node index.

    +

    Definition

    +
    +typedef struct mxml_index_s mxml_index_t;
    +
    +

    mxml_node_t


    @@ -2541,5 +2790,19 @@ union mxml_value_u realReal number textText fragment + + +

    Variables

    + + + +

    num_callbacks

    +
    +

    Definition

    +
    +static int num_callbacks = 1;
    +
    diff --git a/doc/mxml.pdf b/doc/mxml.pdf index a3bb527..04fe796 100644 Binary files a/doc/mxml.pdf and b/doc/mxml.pdf differ diff --git a/www/data/mxml.sql b/www/data/mxml.sql index d7f0c91..3c45544 100644 --- a/www/data/mxml.sql +++ b/www/data/mxml.sql @@ -1,5 +1,5 @@ -- --- "$Id: mxml.sql,v 1.3 2004/05/17 21:00:42 mike Exp $" +-- "$Id: mxml.sql,v 1.4 2004/05/20 03:38:42 mike Exp $" -- -- Database schema for the Mini-XML web pages. -- @@ -10,6 +10,7 @@ -- Revision History: -- -- M. Sweet 05/17/2004 Initial revision. +-- M. Sweet 05/19/2004 Added link, poll, and vote tables. -- @@ -69,6 +70,80 @@ CREATE TABLE comment ( ); +-- +-- Table structure for table 'link' +-- +-- This table lists links to external applications, web pages, etc. +-- Basically, we end up providing a hierachical, searchable link list, +-- complete with comments from users... +-- + +CREATE TABLE link ( + id INTEGER PRIMARY KEY, -- Link ID number + parent_id INTEGER, -- Parent link ID or 0 for top-level + is_category INTEGER, -- 0 = listing, 1 = category + is_published INTEGER, -- 0 = private, 1 = public + name VARCHAR(255), -- Link name + version VARCHAR(255), -- Current version number string + license VARCHAR(255), -- Current license + author VARCHAR(255), -- Current author + email VARCHAR(255), -- Public email address + homepage_url VARCHAR(255), -- Home page + download_url VARCHAR(255), -- Download page + description TEXT, -- HTML description of link + rating_total INTEGER, -- Total of all ratings + rating_count INTEGER, -- Number of ratings + homepage_visits INTEGER, -- Number of clicks to the home page + download_visits INTEGER, -- Number of clicks to the download page + create_date INTEGER, -- Creation time/date + create_user VARCHAR(255), -- User that created the link + modify_date INTEGER, -- Last time/date changed + modify_user VARCHAR(255) -- User that made the last change +); + + +-- +-- Table structure for table 'poll' +-- +-- This table provides a very simple single question, multiple choice poll +-- interface for the main page. Used successfully for a couple years now +-- on the CUPS and FLTK sites, the main twist is the new poll_type field +-- to control whether it is pick-one or pick-many poll. +-- + +CREATE TABLE poll ( + id INTEGER PRIMARY KEY, -- Poll ID number + is_published INTEGER, -- 0 = private, 1 = public + poll_type INTEGER, -- 0 = pick one, 1 = pick many + question VARCHAR(255), -- Question plain text + answer0 VARCHAR(255), -- Answer #1 plain text + count0 INTEGER, -- Number of votes for #1 + answer1 VARCHAR(255), -- Answer #2 plain text + count1 INTEGER, -- Number of votes for #2 + answer2 VARCHAR(255), -- Answer #3 plain text + count2 INTEGER, -- Number of votes for #3 + answer3 VARCHAR(255), -- Answer #4 plain text + count3 INTEGER, -- Number of votes for #4 + answer4 VARCHAR(255), -- Answer #5 plain text + count4 INTEGER, -- Number of votes for #5 + answer5 VARCHAR(255), -- Answer #6 plain text + count5 INTEGER, -- Number of votes for #6 + answer6 VARCHAR(255), -- Answer #7 plain text + count6 INTEGER, -- Number of votes for #7 + answer7 VARCHAR(255), -- Answer #8 plain text + count7 INTEGER, -- Number of votes for #8 + answer8 VARCHAR(255), -- Answer #9 plain text + count8 INTEGER, -- Number of votes for #9 + answer9 VARCHAR(255), -- Answer #10 plain text + count9 INTEGER, -- Number of votes for #10 + votes INTEGER, -- Total votes + create_date INTEGER, -- Time/date of creation + create_user VARCHAR(255), -- User that created the poll + modify_date INTEGER, -- Time/date of last change + modify_user VARCHAR(255) -- User that made the last change +); + + -- -- Schema for table 'str' -- @@ -154,6 +229,18 @@ INSERT INTO users VALUES(NULL, 1, 'mike', 'Michael Sweet ', '195c416888c3151df53ae9f38c67afcc', 100, 1084823565, 'mike', 1084823565, 'mike'); + -- --- End of "$Id: mxml.sql,v 1.3 2004/05/17 21:00:42 mike Exp $". +-- Table structure for table 'vote' +-- +-- This table is used to track ratings, poll votes, etc. that are made on +-- the links and poll pages. +-- + +CREATE TABLE vote ( + type_id_ip VARCHAR(255) PRIMARY KEY -- type_id_ip +); + +-- +-- End of "$Id: mxml.sql,v 1.4 2004/05/20 03:38:42 mike Exp $". -- diff --git a/www/images/graph.gif b/www/images/graph.gif new file mode 100644 index 0000000..de9568b Binary files /dev/null and b/www/images/graph.gif differ diff --git a/www/index.php b/www/index.php index b6eb8ab..6e8cabc 100644 --- a/www/index.php +++ b/www/index.php @@ -1,12 +1,13 @@ Mini-XML Home Page"); print("

    \n" - .""); +html_end_row(); +html_end_table(); html_start_table(array("Quick Info"), "100%", "100%"); html_start_row(); print(""); html_end_row(); html_end_table(); print("" - ."\n" html_footer(); // -// End of "$Id: index.php,v 1.4 2004/05/19 21:17:47 mike Exp $". +// End of "$Id: index.php,v 1.5 2004/05/20 03:38:42 mike Exp $". // ?> diff --git a/www/phplib/common.php b/www/phplib/common.php index b390193..87f3d81 100644 --- a/www/phplib/common.php +++ b/www/phplib/common.php @@ -1,6 +1,6 @@ \n"; } + else + $ftext .= "\n"; $col = 0; break; @@ -671,6 +673,6 @@ validate_email($email) // I - Email address // -// End of "$Id: common.php,v 1.10 2004/05/20 02:04:45 mike Exp $". +// End of "$Id: common.php,v 1.11 2004/05/20 03:38:42 mike Exp $". // ?> diff --git a/www/phplib/globals.php b/www/phplib/globals.php index fa4d293..33311ce 100644 --- a/www/phplib/globals.php +++ b/www/phplib/globals.php @@ -1,6 +1,6 @@ diff --git a/www/phplib/html.php b/www/phplib/html.php index 38cd535..07c41ad 100644 --- a/www/phplib/html.php +++ b/www/phplib/html.php @@ -1,6 +1,6 @@ "); - $add_html_cols = 0; // Add to html_cols after display if colspan is used. $html_row = 0; - $html_cols = sizeof($headings); + $html_cols = count($headings); reset($headings); - for ($i = 0; $i < $html_cols; $i ++) + for ($i = 0; $i < count($headings); $i ++) { // // Headings can be in the following forms: @@ -262,58 +262,45 @@ html_start_table($headings, // I - Array of heading strings // "xxxxxxxx:aa" -- Heading with align. // "xxxxxxxx::cc" -- Heading with a colspan. // "xxxxxxxx:::ww" -- Heading with a width. - // "xxxxxxxx:cc:ww" -- Heading with colspan and width. + // "xxxxxxxx::cc:ww" -- Heading with colspan and width. // "xxxxxxxx:aa:cc:ww" -- Heading with align, colspan and width. // // etc, etc. // - $s_header = ""; + $s_header = ""; $s_colspan = ""; - $s_width = ""; - $s_align = ""; + $s_width = ""; + $s_align = ""; - if (strstr( $headings[$i], ":" )) + if (strstr($headings[$i], ":")) { - $data = explode( ":", $headings[$i] ); - + $data = explode(":", $headings[$i]); $s_header = $data[0]; - if (ISSET($data[1])) - { - $align = $data[1]; - $s_align = "align=$align"; - } + if ($data[1] != "") + $s_align = "align=$data[1]"; - if ($data[2] > 0) + if ($data[2] > 1) { - $colspan = $data[2]; - $s_colspan = "colspan=$colspan"; - if ($colspan > 1) - $add_html_cols += ($colspan - 1); + $s_colspan = "colspan=$data[2]"; + + if ($data[2] > 1) + $html_cols += $data[2] - 1; } if ($data[3] > 0) - { - $width = $data[3]; - $s_width = "width=$width%"; - } + $s_width = "width=$data[3]%"; } else $s_header = $headings[$i]; if (strlen($s_header)) - { print(""); - } else - { print(""); - } } - $html_cols += $add_html_cols; - print("\n"); diff --git a/www/phplib/poll.php b/www/phplib/poll.php new file mode 100644 index 0000000..e2cedb7 --- /dev/null +++ b/www/phplib/poll.php @@ -0,0 +1,114 @@ +" + ."$question\n"); + + if ($row['poll_type'] == $POLL_TYPE_PICKONE) + print("(please pick one)\n"); + else + print("(pick all that apply)\n"); + + for ($i = 0; $i < 10; $i ++) + { + $answer = htmlspecialchars($row["answer$i"]); + + if ($answer != "") + { + if ($row['poll_type'] == $POLL_TYPE_PICKONE) + print("
    $answer\n"); + } + } + + $votes = $row['votes']; + if ($votes == 1) + $votes .= " vote"; + else + $votes .= " votes"; + + $ccount = count_comments("poll.php_r$id"); + if ($ccount == 1) + $ccount .= " comment"; + else + $ccount .= " comments"; + + print("
    \n" + ."[ Results ]\n"); + print("
    ($votes, $ccount)

    \n"); + } + + db_free($result); +} + + +// +// End of "$Id: poll.php,v 1.1 2004/05/20 03:38:42 mike Exp $". +// +?> diff --git a/www/poll.php b/www/poll.php new file mode 100644 index 0000000..f001055 --- /dev/null +++ b/www/poll.php @@ -0,0 +1,388 @@ + 0) +{ + $op = $argv[0][0]; + $argv[0][0] = ' '; + $poll = (int)$argv[0]; +} +else if ($LOGIN_LEVEL >= AUTH_DEVEL) + $op = 'l'; +else + $op = 'c'; + +if ($poll == 0 && $op != 'u' && $op != 'n') + $poll = get_recent_poll(); + +// Do it! +switch ($op) +{ + case 'c' : // Show a poll + html_header("Poll #$poll"); + print("

    Poll #$poll

    \n"); + show_poll($poll); + html_footer(); + break; + + case 'l' : // List all polls + html_header("Polls"); + + if ($LOGIN_LEVEL > AUTH_USER) + { + // Show all polls and allow poll creation... + $result = db_query("SELECT * FROM poll ORDER BY id DESC"); + + html_start_links(1); + html_link("Add New Poll", "$PHP_SELF?n"); + html_end_links(1); + } + else + { + // Only show published polls... + $result = db_query("SELECT * FROM poll WHERE is_published = 1 " + ."ORDER BY id DESC"); + } + + print("

    Polls

    \n"); + + html_start_table(array("ID", "Question::2")); + + while ($row = db_next($result)) + { + $id = $row['id']; + $votes = $row['votes']; + $question = htmlspecialchars($row['question']); + $ccount = count_comments("poll.php_r$id"); + + if ($ccount == 1) + $ccount .= " comment"; + else + $ccount .= " comments"; + + html_start_row(); + print("" + .""); + html_end_row(); + } + + html_end_table(); + + db_free($result); + + html_footer(); + break; + + case 'r' : // Show results + html_header("Poll #$poll"); + + html_start_links(1); + html_link("Show All Polls", "$PHP_SELF?l"); + html_link("Show Comments", "#_USER_COMMENTS"); + html_link("Submit Comment", "comment.php?r0+ppoll.php_r$poll"); + html_end_links(1); + + print("

    Poll #$poll

    \n"); + + $result = db_query("SELECT * FROM poll WHERE id = $poll"); + $row = db_next($result); + + $votes = $row['votes']; + + for ($max_count = 0, $i = 0; $i < 10; $i ++) + { + if ($row["count$i"] > $max_count) + $max_count = $row["count$i"]; + } + + if ($votes == 0) + print("

    No votes for this poll yet...

    \n"); + else + { + $question = htmlspecialchars($row['question']); + + print("
    "); + ."
    "); + +html_start_table(array("Current Poll [ " + ."Show All ]")); +html_start_row(); +print(""); +show_poll(get_recent_poll()); +print("" - ."

    Stable Release: v1.3, " - ."December 21, 2003
    " - ."Developer Release: v2.0rc1, " - ."May 20, 2004

    \n" + ."

    " + ."Stable Release: v1.3
    " + ."Developer Release: v2.0rc1

    \n" ."

    Mini-XML is a small XML parsing library that you can use to " ."read XML and XML-like data files in your application without " ."requiring large non-standard libraries. Mini-XML only requires " ."an ANSI C compatible compiler (GCC works, as do most vendors' " ."ANSI C compilers) and a 'make' program.

    \n" - ."

    Mini-XML provides the following functionality:

    \n" + ."
    \n" ."
        " - ."

    Recent Articles [ View All" + ."

    " + ."

    Recent Articles [ Show All" ." ]

    \n"); $result = db_query("SELECT * FROM article WHERE is_published = 1 " @@ -88,6 +97,6 @@ print("
    $s_header " ."
    #$row[id]$question"); + if (!$row['is_published']) + print(" private"); + print("Vote | " + ."Results"); + + if ($LOGIN_LEVEL > AUTH_USER) + print(" | Edit"); + + print(" ($votes total votes, $ccount)
    \n"); + print("\n"); + + for ($i = 0; $i < 10; $i ++) + { + if ($row["answer$i"] != "") + { + $percent = (int)(100 * $row["count$i"] / $votes); + $size = (int)(300 * $row["count$i"] / $max_count); + $answer = htmlspecialchars($row["answer$i"]); + $count = $row["count$i"]; + + print("\n"); + } + } + + print("\n"); + print("
    $question
    $answer" + ." $count / $percent%
    $votes total votes.
    \n"); + } + + print("


    \n" + ."

    User Comments

    \n"); + html_start_links(); + html_link("Submit Comment", "comment.php?r0+ppoll.php_r$poll"); + html_end_links(); + + show_comments("poll.php_r$poll"); + + db_free($result); + + html_footer(); + break; + + case 'v' : // Vote on a poll + $answers = ""; + + if ($REQUEST_METHOD == "POST") + { + if (array_key_exists("ANSWER", $_POST)) + { + $answer = (int)$_POST["ANSWER"]; + $answers = ",count$answer=count$answer+1"; + } + else + { + for ($i = 0; $i < 10; $i ++) + { + if (array_key_exists("ANSWER$i", $_POST)) + $answers .= ",count$i=count$i+1"; + } + } + } + + if ($answers != "") + { + if (!db_query("INSERT INTO vote VALUES('poll_${poll}_${REMOTE_ADDR}')") + && $LOGIN_LEVEL < AUTH_DEVEL) + { + html_header("Poll Error"); + print("

    Poll Error

    \n"); + print("

    Sorry, it appears that you or someone else using your IP " + ."address has already voted for " + ."poll #$poll.\n"); + html_footer(); + } + else + { + db_query("UPDATE poll SET votes=votes+1$answers WHERE id = $poll"); + + header("Location: $PHP_SELF?r$poll"); + } + } + else + { + header("Location: $PHP_SELF?c$poll"); + } + break; + + case 'n' : // New poll + case 'e' : // Edit poll + if (!$LOGIN_USER) + { + header("Location:$PHP_SELF?r$poll"); + break; + } + + if ($poll) + { + html_header("Poll #$poll"); + + print("

    Poll #$poll

    \n"); + + $result = db_query("SELECT * FROM poll WHERE id = $poll"); + $row = db_next($result); + + $question = htmlspecialchars($row['question']); + $poll_type = $row['poll_type']; + + for ($i = 0; $i < 10; $i ++) + { + if ($row["answer$i"]) + $answer[$i] = htmlspecialchars($row["answer$i"], ENT_QUOTES); + else + $answer[$i] = ""; + } + + $is_published = $row['is_published']; + + db_free($result); + } + else + { + html_header("New Poll"); + + print("

    New Poll

    \n"); + + $question = ""; + $poll_type = $POLL_TYPE_PICKONE; + $answer[0] = ""; + $answer[1] = ""; + $answer[2] = ""; + $answer[3] = ""; + $answer[4] = ""; + $answer[5] = ""; + $answer[6] = ""; + $answer[7] = ""; + $answer[8] = ""; + $answer[9] = ""; + $is_published = 0; + } + + print("
    \n"); + print("
    \n" + ."\n"); + + print("\n"); + + print("\n"); + + for ($i = 0; $i < 10; $i ++) + { + $number = $i + 1; + + print("\n"); + } + + if ($poll) + print("\n"); + else + print("\n"); + + print("
    Question:" + ."
    Type:" + ."
    Published:"); + select_is_published($is_published); + print("
    Answer #$number" + ."
    \n"); + print("
    \n"); + + html_footer(); + break; + + case 'u' : // Update poll + header("Location:$PHP_SELF?l"); + + if ($LOGIN_LEVEL < AUTH_DEVEL) + break; + + $is_published = (int)$_POST["IS_PUBLISHED"]; + $question = db_escape($_POST["QUESTION"]); + $poll_type = (int)$_POST["POLLTYPE"]; + $answer0 = db_escape($_POST["ANSWER0"]); + $answer1 = db_escape($_POST["ANSWER1"]); + $answer2 = db_escape($_POST["ANSWER2"]); + $answer3 = db_escape($_POST["ANSWER3"]); + $answer4 = db_escape($_POST["ANSWER4"]); + $answer5 = db_escape($_POST["ANSWER5"]); + $answer6 = db_escape($_POST["ANSWER6"]); + $answer7 = db_escape($_POST["ANSWER7"]); + $answer8 = db_escape($_POST["ANSWER8"]); + $answer9 = db_escape($_POST["ANSWER9"]); + $date = time(); + + if ($poll) + { + // Update an existing poll... + db_query("UPDATE poll SET " + ."question='$question'," + ."is_published=$is_published," + ."poll_type=$poll_type," + ."answer0='$answer0'," + ."answer1='$answer1'," + ."answer2='$answer2'," + ."answer3='$answer3'," + ."answer4='$answer4'," + ."answer5='$answer5'," + ."answer6='$answer6'," + ."answer7='$answer7'," + ."answer8='$answer8'," + ."answer9='$answer9'," + ."modify_date=$date," + ."modify_user='$LOGIN_USER' " + ."WHERE id = $poll"); + } + else + { + // Create a new poll... + db_query("INSERT INTO poll VALUES(NULL," + ."$is_published," + ."$poll_type," + ."'$question'," + ."'$answer0',0," + ."'$answer1',0," + ."'$answer2',0," + ."'$answer3',0," + ."'$answer4',0," + ."'$answer5',0," + ."'$answer6',0," + ."'$answer7',0," + ."'$answer8',0," + ."'$answer9',0," + ."0," + ."$date,'$LOGIN_USER'," + ."$date,'$LOGIN_USER')"); + } + break; +} + +db_close(); + +// +// End of "$Id: poll.php,v 1.1 2004/05/20 03:38:42 mike Exp $". +// +?>