Market Research sample code

This code generates a research survey, discussed here.

<?php 
    /* This file creates a survey. The URI does not change, and the state of the survey is 
     * determined by POST variables. This prevents users from jumping to a specific page. The 
     * purpose of this code is to demonstrate how the POST variables work; in a professional 
     * implementation, there would also be code for maintaining responses in a database, 
     * validating users, and so on. Also, this survey is simple in format with no randomization
     * or skips, and with only radio and check responses; a full implementation would require 
     * text boxes.
     * Survey author and programmer: Paul Hartzer 
     */

    // Standard template information (for all pages on this site).
    $head = "Grove Attitudes and Interest Survey";    // Title of page
    $uppath = "../../../";                            // Folder depth ("../", "../../", etc.)
    include("\${uppath}template/functions.php");
    doctype(); 
    // End standard template.

    $myname = "survey.php";                           // Current file's name
    $response = str_repeat("0",42);                   // Number of data columns 
    $screenno = 0;                                    // Current question for display
    $MAXSCREEN = 10;                                  // Number of screens (not questions)

    function addresps ($newval, $colnum) {
    // Change a single column response (radio button)

        // Reset the current value
        $GLOBALS['response'] = substr_replace($GLOBALS['response'], 0, $colnum, 1);
        
        // Update value if appropriate 
        if (isset($_POST[$newval])) { 
            $GLOBALS['response'] = substr_replace($GLOBALS['response'], 
            $_POST[$newval], $colnum, 1); 
        }
    }
    
    function addckresps ($newval, $colbeg, $colend) {
    // Change a multiple column response (check box)
        
        // Reset the current values
        for ($i = $colbeg; $i <= $colend; $i++) {    
            $GLOBALS['response'] = substr_replace($GLOBALS['response'], 0, $i, 1);
        }
        
        // Update values as appropriate
        if (isset($_POST[$newval])) { 
            foreach($_POST[$newval] as $value) {
                $GLOBALS['response'] = substr_replace($GLOBALS['response'], 1, $value, 1); 
            }    
        }
    }
    
    function qtext ($qlabel) {
    // Print out the question text
        echo "<p>${qlabel}</p>";
    }
    
    function top5 ($qlabel) {
    // Print out the top of a 5-point agreement scale
        echo "<tr><td class=\"srv_wl\"> </td><td colspan=\"3\" class=\"srv_l\">Disagree</td>
        <td colspan=\"2\" class=\"srv_r\">Agree</td><td class=\"srv_c\"> </td><td class=\"srv_c\">No</td>
        </tr>";
        echo "<tr><td class=\"srv_l\">${qlabel}</td><td class=\"srv_c\">1</td>
        <td class=\"srv_c\">2</td><td class=\"srv_c\">3</td><td class=\"srv_c\">4</td>
        <td class=\"srv_c\">5</td><td class=\"srv_c\"> </td><td class=\"srv_c\">opinion</td></tr>";
    }
    
    function radiocell ($radname, $colnum, $qval) {
    // Print out a radio button
        echo "<td class=\"srv_c\"><input type=\"radio\" name=\"${radname}\" value=\"${qval}\"";
        if (substr($GLOBALS['response'], $colnum, 1) == $qval) {
            echo " checked=\"checked\"";
        }
        echo "</td>";
    }
    
    function radio5 ($radname, $colnum, $qlabel) {
    // Print out a row of 5 radio buttons (as a six-cell table row)
        echo "<tr><td class=\"srv_in\">${qlabel}</td>";
        radiocell ($radname, $colnum, 1);
        radiocell ($radname, $colnum, 2);
        radiocell ($radname, $colnum, 3);
        radiocell ($radname, $colnum, 4);
        radiocell ($radname, $colnum, 5);
        echo "<td class=\"srv_c\"> </td>";
        radiocell ($radname, $colnum, 9);
        echo "</tr>";
    }
    
    function radio1 ($radname, $colnum, $qval, $qlabel) {
    // Print out a single radio button (as a stand-alone row)
        echo "<p class=\"indent\"><input type=\"radio\" name=\"${radname}\" value=\"${qval}\"";
        if (substr($GLOBALS['response'], $colnum, 1) == $qval) {
            echo " checked=\"checked\"";
        }
        echo "> ${qlabel}</p>";
    }

    function check1 ($chkname, $colnum, $qlabel) {
    // Print out a check box (as a stand-alone row)
        echo "<p class=\"indent\"><input type=\"checkbox\" name=\"${chkname}[]\" 
        value=\"${colnum}\"";
        if (substr($GLOBALS['response'], $colnum, 1) == 1) {
            echo " checked=\"checked\"";
        }
        echo "> ${qlabel}</p>";
    }
    
    // Load response set and question number (if any) 
    if (isset($_POST['response'])) {
        $response = $_POST['response'];
    }
    if (isset($_POST['screenno'])) {
        $screenno = $_POST['screenno'];
    }

    // Update response set based on incoming question number
    switch ($screenno) {
        case 1:
            addresps ('q1', 0);
            break;
        case 2:
            addresps ('q2a', 1);
            addresps ('q2b', 2);
            addresps ('q2c', 3);
            addresps ('q2d', 4);
            break;
        case 3:
            addresps ('q2e', 5);
            addresps ('q2f', 6);
            addresps ('q2g', 7);
            break;
        case 4:
            addresps ('q2h', 8);
            addresps ('q2i', 9);
            addresps ('q2j', 10);
            break;
        case 5:
            addresps ('q2k', 11);
            addresps ('q2l', 12);
            addresps ('q2m', 13);
            addresps ('q2n', 14);
            addresps ('q2o', 15);
            break;
        case 6:
            addresps ('q3a', 16);
            addresps ('q3b', 17);
            addresps ('q3c', 18);
            addresps ('q3d', 19);
            addresps ('q3e', 20);
            addresps ('q3f', 21);
            break;
        case 7:
            addresps ('q3g', 22);
            addresps ('q3h', 23);
            addresps ('q3i', 24);
            addresps ('q3j', 25);
            addresps ('q3k', 26);
            addresps ('q3l', 27);
            break;
        case 8:
            addckresps ('q4', 28, 34);
            break;
        case 9:
            addckresps ('q4', 35, 40);
            break;
        case 10:
            addresps ('q5', 41);
            break;
    }
    
    // Determine new question based on which button was pressed
    if (isset($_POST['next'])) {
        $screenno++;
    }
    if (isset($_POST['back'])) {
        $screenno--;
    }

    // Start HTML file (including standard header and navigation bar, and custom styles)
    echo "<html>\n<head>";
    head($head);
    echo <<<STYLES
    <style  TYPE="text/css">
    <!--
    table.survey {
        margin-left: 1in;
        width: 80%;
    }
    td.srv_c {
        text-align: center;
        width: 50px;
        padding: 0px;
    }
    td.srv_l {
        text-align: left;
        padding: 0px;
    }
    td.srv_r {
        text-align: right;
        padding: 0px;
    }
    td.srv_wl { 
        text-align: left; 
        width: 300px; 
        padding: 0px;
    }
    td.srv_wr {
        text-align: right; 
        width: 300px; 
        padding: 0px;
    }
    td.srv_in { 
        text-align: left; 
        padding-left: 0.3in; 
        width: 50px;
        padding: 0px;
    }
    div.title { 
        font-size: 20pt;
        margin-bottom: 0pt; 
    }
    -->
    </style>
STYLES;
    echo "</head>\n<body>";
    navbar();

    // Standard header for survey (table form)
    // Note that the question number and response set are passed as hidden variables
    echo "<p><table class=\"survey\">
    <tr><td class=\"srv_wl\"><img src=\"ice.jpg\" alt=\"[ITG logo]\" /></td>
    <td class=\"srv_wr\"><div class=\"title\">Iced Tree Grove</div><br />
    Attitudes and Interest Survey</td></tr>
    </table></p><br />
    <form action=\"${myname}\" method=\"POST\">
    <input type=\"hidden\" name=\"screenno\" value=\"${screenno}\">
    <input type=\"hidden\" name=\"response\" value=\"${response}\">";
    
    // Determine which question is to be asked, and display the appropriate text
    switch ($screenno) {
        case 0:
            qtext ("The following voluntary, anonymous survey is intended to help us improve
            the offerings of Iced Tree Grove. Please answer honestly; responses are 
            confidential. Both members and non-members of ICG may complete the survey.</p>
            <p>To navigate between the screens, please use the Next and Back buttons at the 
            bottom of the screen. If you go back to previous screens, your answers will be 
            preserved.</p>
            <p class=\"srv_c\"><span class=\"bold\">Note:</span> Your responses will not be 
            submitted until you click <span class=\"bold\">Next</span> on the final screen.</p>
            <p class=\"srv_c\">Please, only complete this survey once.</p>
            <p class=\"srv_c\">Thank you for your cooperation and input!</p>");
            break;
        case 1:
            qtext ("1. Approximately how many ICG rituals have you attended in the last year? 
            (Please count multiple rituals on the same day, such as Samhain, as a single 
            ritual.)");
            echo "<p><table class=\"survey\">\n<tr>";
            for ($i = 0; $i < 8; $i++) {
                echo "<td class=\"srv_c\">${i}</td>";
            }
            echo "</tr><tr>";
            radiocell ('q1', 0, 9);
            radiocell ('q1', 0, 1);
            radiocell ('q1', 0, 2);
            radiocell ('q1', 0, 3);
            radiocell ('q1', 0, 4);
            radiocell ('q1', 0, 5);
            radiocell ('q1', 0, 6);
            radiocell ('q1', 0, 7);
            radiocell ('q1', 0, 8);
            echo "</tr></table></p>";
            break;
        case 2:
            qtext ("2a. Please indicate how much you agree with the following statements, using
            a scale of 1 to 5, where 1 means you <span class=\"bold\">strongly disagree</span> 
            and 5 means you <span class=\"bold\">strongly agree</span>.");
            echo "<p><table class=\"survey\">";
            top5 ("I attend ICG rituals...");
            radio5 ('q2a', 1, "a. For the spiritual experience");
            radio5 ('q2b', 2, "b. For the opportunity to socialize"); 
            radio5 ('q2c', 3, "c. For the \"show\"/entertainment");
            radio5 ('q2d', 4, "d. Because someone in my family does");
            echo "</table></p>";
            break;
        case 3: 
            qtext ("2b. Please indicate how much you agree with the following statements, using 
            a scale of 1 to 5, where 1 means you <span class=\"bold\">strongly disagree</span> 
            and 5 means you <span class=\"bold\">strongly agree</span>.");
            echo "<p><table class=\"survey\">";
            top5 ("ICG rituals are held...");
            radio5 ('q2e', 5, "e. At convenient times");
            radio5 ('q2f', 6, "f. At appropriate locations in summer");
            radio5 ('q2g', 7, "g. At appropriate locations in winter");
            echo "</table></p>";
            break;
        case 4:
            qtext ("2c. Please indicate how much you agree with the following statements, using
            a scale of 1 to 5, where 1 means you <span class=\"bold\">strongly disagree</span> 
            and 5 means you <span class=\"bold\">strongly agree</span>.");
            echo "<p><table class=\"survey\">";
            top5 ("In general, other ICG events are held...");
            radio5 ('q2h', 8, "h. At convenient times");
            radio5 ('q2i', 9, "i. On convenient days");
            radio5 ('q2j', 10, "j. At appropriate locations");
            echo "</table></p>";
            break;
        case 5:
            qtext ("2d. Please indicate how much you agree with the following statements, using 
            a scale of 1 to 5, where 1 means you <span class=\"bold\">strongly disagree</span> 
            and 5 means you <span class=\"bold\">strongly agree</span>.");
            echo "<p><table class=\"survey\">";
            top5 ("Statements:");
            radio5 ('q2k', 11, "k. I know ICG's values and purpose");
            radio5 ('q2l', 12, "l. I know how to get info when needed");
            radio5 ('q2m', 13, "m. I feel like a valued part of the Grove");
            radio5 ('q2n', 14, 
            "n. If I needed special services, like a naming or a wedding, I would ask ICG");
            radio5 ('q2o', 15, "o. I want to design and run an ICG ritual");
            echo "</table></p>";
            break;
        case 6:
            qtext ("3a. Please indicate what you think about ICG with regards to the following 
            characteristics, using a scale of -2 to 2, where -2 means ICG has <span 
            class=\"bold\">far too little</span> and 2 means ICG has <span class=\"bold\">far 
            too much.</span>");
            echo "<p><table class=\"survey\">";
            echo "<tr><td class=\"srv_wl\"> </td><td colspan=\"2\" class=\"srv_l\">Too 
            little</td><td class=\"srv_c\">Just</td><td colspan=\"2\" class=\"srv_r\">Too 
            much</td><td class=\"srv_c\"> </td><td class=\"srv_c\">No</td></tr>";
            echo "<tr><td class=\"srv_l\"> </td><td class=\"srv_c\">-2</td>
            <td class=\"srv_c\">-1</td><td class=\"srv_c\">right</td>
            <td class=\"srv_c\">1</td><td class=\"srv_c\">2</td><td class=\"srv_c\"> </td>
            <td class=\"srv_c\">opinion</td></tr>";
            radio5 ('q3a', 16, "a. Spirituality of ritual");
            radio5 ('q3b', 17, "b. Length of ritual");
            radio5 ('q3c', 18, "c. Fun in ritual");
            radio5 ('q3d', 19, "d. Changes from ritual to ritual");
            radio5 ('q3e', 20, "e. Time spent teaching chants beforehand");
            radio5 ('q3f', 21, "f. Socializing before/after ritual");
            echo "</table></p>";
            break;
        case 7:
            qtext ("3b. Please indicate what you think about ICG with regards to the following 
            characteristics, using a scale of -2 to 2, where -2 means ICG has <span 
            class=\"bold\">far too little</span> and 2 means ICG has <span class=\"bold\">far 
            too much.</span>");
            echo "<p><table class=\"survey\">";
            echo "<tr><td class=\"srv_wl\"> </td><td colspan=\"2\" class=\"srv_l\">Too 
            little</td><td class=\"srv_c\">Just</td><td colspan=\"2\" class=\"srv_r\">Too 
            much</td><td class=\"srv_c\"> </td><td class=\"srv_c\">No</td></tr>";
            echo "<tr><td class=\"srv_l\"> </td><td class=\"srv_c\">-2</td>
            <td class=\"srv_c\">-1</td><td class=\"srv_c\">right</td>
            <td class=\"srv_c\">1</td><td class=\"srv_c\">2</td><td class=\"srv_c\"> </td>
            <td class=\"srv_c\">opinion</td></tr>";
            radio5 ('q3g', 22, "g. Other spiritual events");
            radio5 ('q3h', 23, "h. Other community/socializing events");
            radio5 ('q3i', 24, "i. Information on website");
            radio5 ('q3j', 25, "j. Reminders about rituals and events");
            radio5 ('q3k', 26, "k. Publicity and community outreach");
            radio5 ('q3l', 27, "l. Events or activities for children");
            echo "</table></p>";
            break;
        case 8:
            qtext ("4a. Which of the following activities would you like to be involved with, 
            assuming any meeting dates were convenient for you? (Check all that apply)");
            check1 ('q4', 28, "Designing rituals");
            check1 ('q4', 29, 
            "Participating in a bardic night, where people share songs, poems, and stories");
            check1 ('q4', 30, "Writing chants, narratives, or theatrical works for rituals");
            check1 ('q4', 31, "Discussing theology and mythology as a directed event");
            check1 ('q4', 32, "Group meditation, separate from a ritual and limited to adults");
            check1 ('q4', 33, "Making handicrafts and sharing techniques");
            check1 ('q4', 34, "Making ritual props and altar pieces");
            break;
        case 9:
            qtext ("4b. Which of the following activities would you like to be involved with, 
            assuming any meeting dates were convenient for you? (Check all that apply)");
            check1 ('q4', 35, "Exploring the role of ritual guardians and warriors");
            check1 ('q4', 36, 
            "Going on extended hikes or camping to get in touch with the deities");
            check1 ('q4', 37, 
            "Going on guided nature walks to learn more about local flora and fauna");
            check1 ('q4', 38, 
            "Preparing creative submissions for a newsletter or another Grove publication");
            check1 ('q4', 39, "Participating in environmentally conscious events, like cleaning 
            up litter around the river");
            check1 ('q4', 40, 
            "Social events, such as getting together to play games or chat over coffee");
            break;
        case 10:
            qtext ("5. <span class=\"bold\">(Members: Please skip)</span> What is the 
            <span class=\"bolditalic\">primary reason</span> you're not a current member? 
            (Check one)");
            radio1 ('q5', 41, 1, 
            "I'm still new to the group and haven't yet decided whether to join");
            radio1 ('q5', 41, 2, "I don't know how to join, or didn't know I could join");
            radio1 ('q5', 41, 3, "My renewal lapsed and I wasn't reminded");
            radio1 ('q5', 41, 4, 
            "I don't feel like I (would) get enough benefit from paying a fee");
            radio1 ('q5', 41, 5, 
            "The annual fee is too high for my current financial situation");
            radio1 ('q5', 41, 6, "I feel like I donate enough in other ways");
            radio1 ('q5', 41, 7, "I'm a guest");
            echo "<br />";
            radio1 ('q5', 41, 0, "I am a member - or - I choose not to answer");
            break;
        // Final screens (not included in MAXSCREEN)
        case $MAXSCREEN + 1:
            qtext ("Thank you for your input. Click Back to review your responses or Next to 
            submit them.");
            break;
        case $MAXSCREEN + 2:
            qtext ("The responses were coded as: ".$response);
            break;
    }

    // Display "Back" and "Next" buttons as appropriate (until the last screen of the survey)
    if ($screenno < $MAXSCREEN + 2) {
        echo "<br />\n<p><table class=\"survey\"><tr>";
        if ($screenno > 0) {
        // Don't display "Back" or percentage complete on first screen
            echo "<td class=\"srv_c\"><input type=\"submit\" name=\"back\" value=\"<< Back\">
            </td>";
            $percdone = ($screenno - 1) * 100 / $MAXSCREEN;
            echo "<td class=\"srv_c\">${percdone}% complete.</td>";
        } else {
            echo "<td class=\"srv_c\"> </td><td class=\"srv_c\"> </td>";
        }
        echo "<td class=\"srv_c\"><input type=\"submit\" name=\"next\" value=\"Next >>\">
        </td>\n</tr></table>";
    }
    
    // Close everything up
    echo "</form>";
    foot();
    echo "</body>\n</html>";
?>