Jump to content

Barand

Moderators
  • Posts

    24,420
  • Joined

  • Last visited

  • Days Won

    805

Posts posted by Barand

  1. It looks like your output is a single string ...

    $output = '["1.Question text 1 blah blah","2.Question text 2 blah blah","3.Question text 3 blah blah","4.Question text 4 blah blah"]';

    … (a json-encoded array) which is why you get a single <li> item.

    However, you should get the required result if you ...

    $questions = json_decode($output, true);
    
    echo "<ul>";
    foreach ($questions as $q) {
        echo "<li>$q</li>";
    }
    echo "</ul>";
    

    image.png.15bc8a44563869ad26b8f270f6e4b837.png

  2. I'll second that - use PDO.

    I originally switched from MySQL_ functions to mysqli_ ones . Some time later I decided to give PDO a go and wished I'd done it years earlier. 

    EDIT:

    mysqli looks tempting because looks as though all you have to do is add the letter "I" to the function calls - you can't.

    With mysqli, if you use the query() function you get a "result" object. If you use prepare() you get a "statement" object. The functions you use to process the query results from these two object types are different ( Confusing, you get the impression it was developed by two separate teams who didn't speak to one another).

    With PDO you get the same object type with both methods and therefore only one set of processing functions to worry about. What's more, they are easier to use than the equivalent mysqli versions.

  3. 9 hours ago, maxxd said:

    I think that exact code is one of the main reasons jQuery blew up as big as it did as quickly as it did.

    +1. I can't understand why anyone would not use jQuery for AJAX requests.

    As you are just fetching data to display on the page you should be using GET method and not POST.

    Change to $_GET and test your  "urlpost.php" page on its own in your browser, passing the "url=www.facebook.com" in the query string. Any errors should the become evident.

  4. I changed to function below so it returns "false" if the keyword is not found. 

    If the matched item is the first in the array its index will be "0" so your test for 

    if ($index)

    will fail as 0 evaluates to false. You need to explicitly test for a Boolean false as below

    function array_search_partial($arr, $keyword) {
        foreach ($arr as $index => $string) {
                $userBase = basename($string);
                $test = substr_count($userBase, '-');
                if($test === 2) {
                    if(preg_split("/[-]+/", $userBase)[2] == $keyword) {
                        return $index;
                    } 
                }
        }
        // if we get here it hasn't found the keyword
        return false;    
    }
    
    $index = array_search_partial($profilePaths, $userName);
    if($index !== false){                                           // check it isn't (boolean) false
        $profileLink = "/".$profilePaths[$index].".html";
    } 

     

  5. Do you test your code? Aside from the logic being wrong it is also missing a "}"

    In the code below using your function, a search for "dinosaur64"" should return "1"

    $filepaths = array();
    $filepaths[] = "/path/to/file/bob-villa-bvilla35";
    $filepaths[] = "/path/to/file/jim-bob-dinosaur64";
    $filepaths[] = "/path/to/file/abe-lincoln-alinkler";
    $filepaths[] = "/path/to/file/michael-jordan-ncairman";
    $filepaths[] = "/path/to/file/bart-simpson-eatmyshorts";
    
    function array_search_partial($arr, $keyword) {
        foreach ($arr as $index => $string) {
                $userBase = basename($string);
                $test = substr_count($userBase, '-');
                if($test === 2) {
                    if(preg_split("/[-]+/", $userBase)[2] == $keyword) {
                        return $index;
                    } else {
                        return false;
                    }
                }
        }    
    }
    
    $index = array_search_partial($filepaths, 'dinosaur64');
    var_dump($index);                                               //-->   bool(false)           (Should be "1")

     

    27 minutes ago, nephesh said:

    It will always find something.

    You can guarantee that no-one will search for a keyword that isn't there?

    (At the moment it will only ever find the first item.)

  6. 10 minutes ago, kilnakorr said:

    using a while loop will just output '10 12 15'

    It will if you only out put the total column - but the animal type is there too...

    mysql> CREATE TABLE myanimal (animal varchar(10) );
    Query OK, 0 rows affected (0.55 sec)
    
    mysql> INSERT INTO myanimal VALUES ('cat'),('dog'),('cat'),('dog'),('horse'),('horse'),('duck'),('dog'),('cat');
    Query OK, 9 rows affected (0.06 sec)
    Records: 9  Duplicates: 0  Warnings: 0
    
    mysql> select * from myanimal;
    +--------+
    | animal |
    +--------+
    | cat    |
    | dog    |
    | cat    |
    | dog    |
    | horse  |
    | horse  |
    | duck   |
    | dog    |
    | cat    |
    +--------+
    9 rows in set (0.00 sec)
    
    mysql> select animal
        ->      , count(*) as total
        -> FROM myanimal
        -> GROUP BY animal;
    +--------+-------+
    | animal | total |
    +--------+-------+
    | cat    |     3 |
    | dog    |     3 |
    | duck   |     1 |
    | horse  |     2 |
    +--------+-------+

    In PHP...

    $res = $db->query("SELECT animal
                            , COUNT(*) as total
                       FROM myanimal
                       GROUP BY animal
                      ");
    $totals = [];
    foreach ($res as $row) {
        $totals[ $row['animal'] ]  = $row['total'];
    }
    
    // now you can access each animal's total
    
    echo $totals['horse'];          //--> 2 
    echo $totals['dog'];            //--> 3 

     

  7. Alternatively you can do it in the query by defining the condition for each column and setting it 0 or 1 then SUMMING the columns grouped by class

    I have only done the first five columns but you should get the idea

    SELECT classroomname as Classroom
         , COUNT(*) as Enrolled
         , SUM(cconly) as `CC Only`
         , SUM(ehspi) as `EHS/PI`
         , SUM(ccpi) as `CC/PI`
         , SUM(ehsccpi) as `EHS/CC/PI`
    FROM classrooms
            JOIN
         (
    		SELECT classroomID
                 , CASE WHEN childcaretype IS NOT NULL
                             AND hstype IS NULL
                             AND cpsstatus IS NULL
                        THEN 1
                        ELSE 0
                    END as cconly
                  , CASE WHEN hstype = 'EHS'
                              AND (cpsstatus = 'PI PEN' OR cpsstatus = 'PI APP')
                         THEN 1 
                         ELSE 0
                     END as ehspi
                  , CASE WHEN childcaretype IS NOT NULL
                              AND (cpsstatus = 'PI PEN' OR cpsstatus = 'PI APP')
                         THEN 1
                         ELSE 0
                     END as ccpi
                   , CASE WHEN childcaretype IS NOT NULL
                               AND hstype = 'EHS'
                               AND (cpsstatus = 'PI PEN' OR cpsstatus = 'PI APP')
    					  THEN 1
                          ELSE 0
                      END as ehsccpi
    		 FROM children	
         ) as childs USING (classroomid)
    GROUP BY classroomname;
    +-----------+----------+---------+--------+-------+-----------+
    | classroom | Enrolled | CC Only | EHS/PI | CC/PI | EHS/CC/PI |
    +-----------+----------+---------+--------+-------+-----------+
    | Room 1    |       13 |       5 |      1 |     3 |         1 |
    | Room 2    |       12 |       3 |      1 |     3 |         1 |
    | Room 3    |       16 |       2 |      2 |     5 |         2 |
    | Room 4    |       18 |       5 |      0 |     4 |         0 |
    | Room 5    |       10 |       4 |      0 |     0 |         0 |
    | Room 6    |       12 |       2 |      1 |     2 |         1 |
    | Room 7    |       12 |       4 |      1 |     2 |         1 |
    +-----------+----------+---------+--------+-------+-----------+

    It would better if the cpsstatus were two columns

    1. PI or PFA
    2. AP or PEN
  8. I ran

    if(isset($_POST['datestop'])){
    
    $today = date("Y-m-d");                                
    $datestop=$_POST['datestop'];                     // assuming $datestop now contains '2019-10-15'
    echo "$today<br /><br />$datestop<br /><br />";
    
    $begin = new DateTime($today);
    $end = new DateTime($datestop);
    
    }

     - no errors!

    then added

    $period = new DatePeriod($begin, new DateInterval('P1D'), $end);
    
    foreach ($period as $d) {
        echo $d->format('jS F Y') . "<br>\n";
    }

    giving

    Quote

    8th October 2019
    9th October 2019
    10th October 2019
    11th October 2019
    12th October 2019
    13th October 2019
    14th October 2019

     

  9. Shame on me for missing that!

    @techker To save having to test if every mysqli function call worked or not, tell it to throw an exception automatically. It keeps your code a lot cleaner. Call mysqli_report() before you connect to the db.

     mysqli_report(MYSQLI_REPORT_ERROR|MYSQLI_REPORT_STRICT);
    
     $mydb = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);

     

  10. Are you saying that when you select "1" from the dropdown then $_GET['cr'] contains "2"

    You don't show your <select> tag - can you confirm the name = 'cr' ?

    It looks OK but check the source code of your form page to make sure the menu is built correctly.

    Some general points …

    1. As you are updating data your form method should be POST and not GET
    2. strip_tags hasn't been required since magic_quotes were deprecated decades ago
    3. mysqli_real_escape_string is not used with prepared queries,
  11. So I guess you'd have a front-end form for the user so they can select various options ( varying depending on the survey) and then submission of the form would generate the above query and execute it.

    The challenge then becomes the program which, given a specific survey, will generate that front-end form.

  12. You don't show the query so I'm going to guess the results are from using a join.

    If you have

    tableA                                   tableB
    +-----------+--------------+             +------+-----------+-------+
    |  a_id     |   name       |             | b_id |   cola    | a_id  |
    +-----------+--------------+             +------+-----------+-------+
    |    1      |   Curly      |             |   1  |   aaa     |   1   |
    |    2      |   Larry      |             |   2  |   bbb     |   2   |
    +-----------+--------------+             |   3  |   ccc     |   1   |
                                             |   4  |   ddd     |   1   |
                                             |   5  |   eee     |   1   |
                                             |   5  |   fff     |   2   |
                                             |   5  |   ggg     |   2   |
                                             |   5  |   hhh     |   2   |
                                             +------+-----------+-------+
                                             
    SELECT a.name
         , b_id
         , cola
    FROM tablea a 
           INNER JOIN
         tableb b ON a.a_id = b.a_id
    WHERE a.a_id = 1

    then the results will be

    +---------+--------+--------+
    | name    |  b_id  |  cola  |
    +---------+--------+--------+
    | Curly   |    1   |   aaa  |
    | Curly   |    3   |   ccc  |
    | Curly   |    4   |   ddd  |
    | Curly   |    5   |   eee  |
    +---------+--------+--------+

    where "Curly" is repeated 4 times because for the record in tablea there are 4 matching records in tableb with matching values in column a_id.

    That's the nature of joins. Live with it.

    A common way is to rearrange the data thus

    data['Curly'] = [ 
                      1 => aaa,
                      3 => ccc,
                      4 => ddd,
                      5 => eee
                    ]

     

  13. The simple part is creating an application to create different surveys. The hard part is an app for analyzing the results of any survey that is thrown at it.

    You are going to have infinite combinations of different types of answer

    • simple Boolean (Y/N)
    • single value number/date/text(avoid)
    • single choice list
    • multiple choice list
    • value ranges (crap, poor, OK, good, excellent)

    with 

    • cross-tabulations/pivot tables between any two responses (eg average/count/total of X for each Y)
    • Frequency charts to analyze responses

    I suppose it's a bit like printers (sell it cheap and make your money selling the ink cartridges). In this case you sell the ability to create surveys then monetize it by selling customised analysis services.

    Something like this should work

    image.png.31b48c84e27962325c5f7605a416ad4e.png

  14. This is my test version (with a couple of extra displays to confirm the processing)

    <?php
    
    ## connect to your DB here ##
                                    
    $userid = '0';
    $subid  = '0';
    $cr     = 0;
    $max    = 0;
    $confirm = '';
    $before = $after = '';
    //
    // was data posted?
    //
    if ($_SERVER['REQUEST_METHOD']=='POST') {
    
        $userid = $_POST['userid'] ?? 0;
        $subid  = $_POST['subid'] ?? 0;
        $cr     = $_POST['credits'] ?? 0;
        
        $before = "<h3>Before</h3>" . query2HTML($db, "select * from codes where userid in ($userid, $subid)");
    
    
        $stmt = $db->prepare("UPDATE codes
                                SET UserId = ?
                                WHERE UserId = ?
                                  AND status != 'Used'    
                                LIMIT ?     
                          ");
        $stmt->bind_param('iii', $subid, $userid, $cr);
        $stmt->execute();
        $howmany = $db->affected_rows;
        
        if ($cr==$howmany)  {
            $confirm = "<div style='display:inline-block; padding: 16px; background-color: #EEE; color: #000'>$howmany rows transferred</div><br>";
        } else {
            $confirm = "<div style='display:inline-block; padding: 16px; background-color: #F00; color: #FFF'>$howmany rows transferred</div><br>";
        }
    
        $after  = "<h3>After</h3>" . query2HTML($db, "select * from codes where userid in ($userid, $subid)");
    }
    //
    // respond to ajax request
    //
    if (isset($_GET['ajax'])) {
        exit(cr_options($db, $_GET['userid'], 0));
    }
    
    /**
    * create list of credit quantity options
    * 
    * @param mysqli $db
    * @param int $user
    * @param int $current     - current quantity
    */
            function cr_options(mysqli $db, $user, $current)
            {
                $stmt = $db->prepare("SELECT COUNT(*) as tot
                                      FROM codes
                                      WHERE status != 'Used'
                                      AND UserId = ?
                                     ");
                $stmt->bind_param('i', $user);
                $stmt->execute();
                $stmt->bind_result($tot);
                $stmt->fetch();
                if ($tot == 0) {
                    $opts = "<option value=''>No unused codes</option>";
                }
                else {
                    for($i=1; $i<=$tot; $i++) {
                        $sel = $i==$current ? 'selected' : '';
                        $opts .= "<option $sel>$i</option>";
                    }
                }
                return $opts;
            }
    /**
    * general purpose debugging utility function to output query results
    * 
    * @param mysqli connection $db
    * @param string $sql
    * @return string         - html table
    */
            function query2HTML($db, $sql)
            {
                $output = "<table border='1' cellpadding='2' style='border-collapse:collapse'>\n";
                  // Query the database
                $result = $db->query($sql);
                  // check for errors
                if (!$result) return ("$db->error <pre>$sql</pre>");
                if ($result->num_rows == 0) return "No matching records";
                  // get the first row and display the headings
                $row = $result->fetch_assoc();
                $output .= "<tr><th>" . join('</th><th>', array_keys($row)) . "</th></tr>\n";
                
                  // display the data
                do {
                   $output .= "<tr><td>" . join('</td><td>', $row) . "</td></tr>\n"; 
                } while ($row = $result->fetch_assoc());
                $output .= "</table>\n";
                return $output;
            }
    ?>
    <html>
    <head>
    <meta http-equiv="content-language" content="en">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Sample Code Transfer</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script type="text/javascript">
        $().ready(function() {
            $("#userid").change( function() {
                var user = $(this).val()
                $.get(
                    "",
                    {"ajax":1, "userid":user },
                    function(resp) {
                        $("#credits").html(resp)
                    },
                    "TEXT"
                )
            })
        })
    </script>
    <style type="text/css">
        label {display:inline-block; width: 160px; font-weight: 600;}
    </style>
    </head>
    <body>
    <form method='post'>
        <fieldset>
        <legend>Codes Transfer</legend>
            <label>From user</label><input type="text" name="userid" id="userid" value="<?=$userid?>" size="5"><br>
            <label>Credits to transfer</label><select name="credits" id="credits"><?=cr_options($db, $userid, $cr)?></select><br><br>
            <label>To user</label><input type="text" name="subid" id="subid" value="<?=$subid?>" size="5"><br>
            <label>&nbsp;</label><input type="submit" name="btnSub" value="Transfer">
        </fieldset>
    </form>
    <br>
    <br>
    <?=$before?>
    <?=$confirm?>
    <?=$after?>
    </body>
    </html>

     

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.