Jump to content

Leaderboard

  1. Barand

    Barand

    Moderators


    • Points

      222

    • Content Count

      20,913


  2. requinix

    requinix

    Administrators


    • Points

      123

    • Content Count

      12,415


  3. kicken

    kicken

    Gurus


    • Points

      48

    • Content Count

      3,764


  4. gizmola

    gizmola

    Administrators


    • Points

      37

    • Content Count

      5,138



Popular Content

Showing content with the highest reputation since 07/14/2019 in Posts

  1. 3 points
    I enjoy the challenge when someone posts a problem I can get my teeth into.
  2. 3 points
    People still use StackOverflow? That's only half a joke. Their community has always been toxic to newcomers and there's so much emphasis on correctness that anything less than perfect is unacceptable. And there's the hostility towards any form of discussion about what is right that I always mention when this subject comes up. SO is good when you're looking for a precise answer to a specific question, but it's terrible for actually asking the questions, or trying to weigh in as a new person with different answers. But I am glad they dethroned Expert Sex Change in search results. edit: If Your Common Sense/shrapnelcol came across this thread and decided they wanted to join our forum...
  3. 3 points
    A few notes about text bounding boxes which, I hope, will help in precise placement of your text. Suppose I have the text string "The lazy fox" which I want to display using 150pt Vivaldi . My image is 4896 x 3672 and I want the text placed at the bottom right but 250 pixels from the edges of the image. $box = imagettfbbox(150,0,'c:/windows/fonts/vivaldii.ttf','The lazy fox'); gives this array of coordinates of the four corners $box = Array ( [0] => 23 [1] => 55 [2] => 871 [3] => 55 [4] => 871 [5] => -140 [6] => 23 [7] => -140 ) You may wonder why it can't just give a rectangle from (0,0) to (width, height) to make sizing simple, but there is extra information to be extracted from the array Text width = (871 - 23) = 848 Text height = 55 - (-140) = 195 The baseline will be 140px from the top The text is offset 23 px to the right. My text, therefore, will be in a rectangle 848 x 195 positioned 250 px from right and bottom edges. The top left x coord of the rectangle will be (4896 - 250 - 848) = 3798 and top left y coord will be (3672 - 250 - 195) = 3227. However, to land the text precisely into this area we position it on the baseline and at the required x offset, ie (3798 - 23 , 3227 + 140) = (3775, 3367). I use a simple custom function to assist with this process function metrics($font, $fsize, $str) { $box = imagettfbbox($fsize, 0, $font, $str); $ht = abs($box[5] - $box[1]); $wd = abs($box[4] - $box[0]); $base = -$box[5]; $tx = -$box[0]; return [ 'width' => $wd, 'height' => $ht, 'ascent' => $base, 'offsetx' => $tx ]; } $box = metrics ('c:/windows/fonts/vivaldii.ttf', 150, 'The lazy fox'); $box = Array ( [width] => 848 [height] => 195 [ascent] => 140 [offsetx] => -23 )
  4. 3 points
    Don't use $GLOBALS. Forget it exists. There is never a good reason to use it. Pretend you never saw it.
  5. 3 points
    +----------------+ +----------------+ | Make sure to |---+ +------->| (e.g. Courier) | +----------------+ | | +----------------+ | | | | +----------+ | | +->| use a |---+ | | +----------------+ +----------+ | | +------->| and use spaces | | | +----------------+ | +----------------+ | | +--->| monospace font |-----+ | +----------------+ | +----------+ | | not tabs |<----------+ +----------+ | +--------------------------------------------------------------------------+ | V +---------------+ | It also helps | +---------------+ | | | +-------------------+ +-------------------+ +------------------------>| if you sometimes |---------------------->| switch between | +-------------------+ +-------------------+ | | +-----------------+-----------------+ | | | | +-------------------+ +-------------------+ | overtype | | insert | +-------------------+ +-------------------+ | | | | | +----------+ | +----------=>| modes |<----------+ +----------+
  6. 2 points
    I created an extra table to define which category the values were in mysql> select * from catval; +-----+------+ | val | cat | +-----+------+ | 1 | 4 | | 2 | 4 | | 3 | 4 | | 4 | 4 | | 5 | 3 | | 6 | 3 | | 7 | 2 | | 8 | 2 | | 9 | 1 | | 10 | 1 | +-----+------+ then $sql = "SELECT a.cat as cata , b.cat as catb FROM datatb d JOIN catval a ON d.grpa = a.val JOIN catval b ON d.grpb = b.val "; $result = $db->query($sql); //categories $cat = [ 4 => ['name'=>'1:4', 'recs'=>[]], 3 => ['name'=>'5:6', 'recs'=>[]], 2 => ['name'=>'7:8', 'recs'=>[]], 1 => ['name'=>'9:10','recs'=>[]] ]; $n = 0; while ($row = $result->fetch_assoc()) { $cat[$row['cata']]['recs'][$n][] = $row['cata']; $cat[$row['catb']]['recs'][$n][] = $row['catb']; $n++; } // the output echo "<table border='1' style='width:500px; border-collapse:collapse;'>"; foreach ($cat as $c) { echo "<tr><th>{$c['name']}</th>"; for ($i=0; $i<$n; $i++) { echo '<td style="text-align:center;">' . (isset($c['recs'][$i]) ? join(',', $c['recs'][$i]) : '&ndash;') . "</td>"; } echo "</tr>\n"; } echo "</table>\n";
  7. 2 points
    $q = 'SELECT ID FROM table'; That is a SQL query. You have to run that query through your database, receive the results, and then look for each single matching image in the directory for every returned record. You can probably skip looking in the directory, though. It will only tell you if the file exists. So if you already know (or assume) the file exists then you don't need to bother looking.
  8. 2 points
    Don't worry about the IBD file. MySQL knows how to manage itself, you don't need to go second guessing it because of what you think you saw in Notepad. The question you think you're asking is whether to use an UPDATE or a DELETE+INSERT, but the question you're actually asking is how you should manage uploaded files that can be replaced. The answer to that is... well, it depends. There are two basic options: 1. Forget the previously uploaded file. You don't care about it. Take the new file and stick it wherever you want, update the database, and delete the old file. Gotta delete. Because if you forget about the old file then there's not much of a point to keeping the file itself around too. 2. Keep track of the previous file. You'd probably want a table that holds all the information for past and future uploads, and that's where you track them. For using those files, instead of storing the file information in whatever place, you reference the file in your upload information table. New image, new information row, and you update whatever place was affected. This lets you keep a history of everything, which probably isn't important for stuff like user avatars but is frighteningly important for stuff like monetary transactions. "Okay, I've decided that I want to do <whichever option>. But what about my literal question? Should I update or delete and insert?" Time to learn about an important concept in computing that disappointingly few programmers ever end up learning: atomicity. That's the noun version of "atomic", which means (in this case) that whatever operation you need to do can't be interrupted or broken in half or appear to anyone else as being anything less than one single action. Atomicity is important for stuff like files and databases because you basically never want to look at a file or data in the middle of some important operation. Imagine your site is popular. Really popular. Facebook or Twitter popular. Constant traffic to your servers. Now imagine a user uploads a new image. When the code is ready, it needs to go off into the database to make whatever changes it needs to make so the user has the new image. Say you go with DELETE and INSERT. Your code runs one query that DELETEs whatever, then another query that INSERTs. Sounds fine. Except remember how your site is always busy? It's quite possible someone was looking at your site at the moment in between those two queries. Since the DELETE has happened but not yet the INSERT, your code isn't going to find whatever data it needed to find and the user is going to get a bad experience. If that user was a CEO for a huge company that wanted to buy you out for lots of money, they might not do that now. A DELETE and INSERT is not atomic because there was that point in between the two queries. It was not "one single action". Instead you go with UPDATE. The database does whatever it does, but the clever people who wrote the software for it already knew about stuff like atomicity. And they made their system guarantee that UPDATEs are atomic. One single action. If you do an UPDATE when that rich CEO looks at your site, the database has guaranteed to you that either (a) the CEO will see the old data because the update hasn't happened yet, or (b) they'll see the new data because the update has happened. There is no moment in between old and new for stuff to be broken.
  9. 2 points
    Unlikely Quotes need removing... $query = "UPDATE `greencard` SET `comments`= '$comments', 'sent' = '$sent' WHERE `hospitalnumber`= '$hospitalnumber' and `PIN`= '$PIN'"; ^ ^ and it's easier just to use ... sent = NOW() WHERE ...
  10. 2 points
    Defining a value in the parameter list makes that parameter optional. If it's not provided when the function is called, the it takes on the value assigned to it. Your specific example doesn't really make use of the feature effectively. Take something like this for example though: function findFiles($directory, $includeHidden = false){ $iter = new DirectoryIterator($directory); $list = []; foreach ($iter as $item){ if ($item->isFile()){ $isHidden = $item->getFilename()[0] === '.'; if ($includeHidden || !$isHidden){ $list[] = $item->getPathname(); } } } return $list; } That function requires at least one parameter when it's called, the directory to search. So you end up with the following options for calling it $files = findFiles('/home/kicken'); /* executes with $directory = '/home/kicken', $includeHidden = false */ $files = findFiles('/home/aoeex', true); /* executes with $directory = '/home/aoeex', $includeHidden = true */
  11. 2 points
    I just didn't see the table - the end of that first line was somewhere in my neighbour's living room.
  12. 2 points
    Your randomNr array contains 10 elements so foreach($randomNr as $number) will give 10 columns. You need to pick a random 6 numbers out of the 10. Separate the php code from the html. Use CSS for styling the output. Example <?php $randomNr = range(0,9); $bingokaart = display($randomNr); function display ($arr) { $result = ""; for ($row = 1; $row < 7; ++$row) { $rand6 = array_rand($arr, 6); $result .= '<tr>'; foreach ($rand6 as $n) { $result .= "<td>$row$arr[$n]</td>"; } $result .= "</tr>\n"; } return $result; } ?> <!DOCTYPE html> <html> <head> <title>Sample</title> <style type="text/css"> table { border-collapse: collapse; } td { padding: 2px; } </style> </head> <body> <table border='1'> <?= $bingokaart ?> </table> </body> </html>
  13. 2 points
    Why are you even attempting to store that duration. You can get it any time you need it with a query. Rule of DB design - don't store derived data. If you really insist on storing it, why do need two queries? UPDATE attendance_records SET duration = timediff(...) WHERE ... - a single update would do the job
  14. 2 points
    They aren't the same width because you don't have any sort of CSS in there that says anything about a width. It's not like the browser can read your mind about how you want it to appear... Have you tried giving the buttons a width?
  15. 2 points
    An alternative to the 2-table option is to treat costs as transactions, just like payments (cost amounts +ve, payment amounts -ve in this example)... DATA TABLE: payment +------+------+------------+--------------+---------+ | uid | name | trans_date | payment_type | payment | +------+------+------------+--------------+---------+ | 1 | kim | 2020-03-01 | cost | 100 | | 1 | kim | 2020-03-02 | card | -100 | | 2 | lee | 2020-03-01 | cost | 95 | | 2 | lee | 2020-03-02 | cash | -95 | | 3 | kent | 2020-03-01 | cost | 100 | | 3 | kent | 2020-03-03 | cash | -50 | | 3 | kent | 2020-03-04 | card | -50 | | 4 | iya | 2020-03-01 | cost | 80 | | 4 | iya | 2020-03-05 | cash | -40 | | 4 | iya | 2020-03-06 | card | -20 | +------+------+------------+--------------+---------+ then SELECT uid , name , date , cost , cash , card , total as balance FROM ( SELECT name , DATE_FORMAT(trans_date, '%b %D') as date , CASE payment_type WHEN 'cash' THEN -payment ELSE '-' END as cash , CASE payment_type WHEN 'card' THEN -payment ELSE '-' END as card , CASE payment_type WHEN 'cost' THEN payment ELSE '-' END as cost , @tot := CASE @previd WHEN uid THEN @tot+payment ELSE payment END as total , @previd := uid as uid FROM ( SELECT * FROM payment ORDER BY uid, trans_date ) sorted JOIN (SELECT @previd:=0, @tot:=0) initialize ) recs; +------+------+---------+------+------+------+---------+ | uid | name | date | cost | cash | card | balance | +------+------+---------+------+------+------+---------+ | 1 | kim | Mar 1st | 100 | - | - | 100 | | 1 | kim | Mar 2nd | - | - | 100 | 0 | | 2 | lee | Mar 1st | 95 | - | - | 95 | | 2 | lee | Mar 2nd | - | 95 | - | 0 | | 3 | kent | Mar 1st | 100 | - | - | 100 | | 3 | kent | Mar 3rd | - | 50 | - | 50 | | 3 | kent | Mar 4th | - | - | 50 | 0 | | 4 | iya | Mar 1st | 80 | - | - | 80 | | 4 | iya | Mar 5th | - | 40 | - | 40 | | 4 | iya | Mar 6th | - | - | 20 | 20 | +------+------+---------+------+------+------+---------+
  16. 2 points
    I totally agree with @requinix regarding the two tables. However, if you are willing to compromise over the output, you could do something like this SELECT uid , name , SUM(CASE payment_type WHEN 'cash' THEN payment ELSE 0 END) as cash , SUM(CASE payment_type WHEN 'card' THEN payment ELSE 0 END) as card , cost , cost-SUM(payment) as balance FROM payment GROUP BY uid +------+------+------+------+------+---------+ | uid | name | cash | card | cost | balance | +------+------+------+------+------+---------+ | 1 | kim | 0 | 100 | 100 | 0 | | 2 | lee | 95 | 0 | 95 | 0 | | 3 | kent | 50 | 50 | 100 | 0 | | 4 | iya | 40 | 20 | 80 | 20 | +------+------+------+------+------+---------+ If you really need every transaction listed, the SQL becomes quite complex involving user variables and subqueries. It would be much easier to do in the PHP as you output each row. [EDIT] ... For the sake of completeness SELECT uid , name , cash , card , cost , cost-total as balance FROM ( SELECT name , CASE payment_type WHEN 'cash' THEN payment ELSE 0 END as cash , CASE payment_type WHEN 'card' THEN payment ELSE 0 END as card , cost , @tot := CASE @previd WHEN uid THEN @tot + payment ELSE payment END as total , @previd := uid as uid FROM ( SELECT * FROM payment ORDER BY uid ) sorted JOIN (SELECT @previd:=0, @tot:=0) initialize ) recs; +------+------+------+------+------+---------+ | uid | name | cash | card | cost | balance | +------+------+------+------+------+---------+ | 1 | kim | 0 | 100 | 100 | 0 | | 2 | lee | 95 | 0 | 95 | 0 | | 3 | kent | 50 | 0 | 100 | 50 | | 3 | kent | 0 | 50 | 100 | 0 | | 4 | iya | 40 | 0 | 80 | 40 | | 4 | iya | 0 | 20 | 80 | 20 | +------+------+------+------+------+---------+
  17. 2 points
    Not sure I would call a registration and login system less complex than threads and posts, but I guess it depends... I suggest you take a look at MariaDB's knowledge base section on database theory.
  18. 2 points
    Don't do that. Not in the actual table at least. Some people recommend this stupidity to try and avoid name collisions in their queries (such as two tables have a Label column) but such issues can be easily handled using the table.column syntax in your query rather than cluttering up column names in the table. SELECT o.Label as o_label, s.Label as s_label FROM order o INNER JOIN status s ON s.Id=o.Status One of the applications I work on was original designed using a scheme like that where every column has a table specific prefix to it and it's super annoying (long names, broken autocomplete) for no real benefit. I've been slowly undoing that when I can and just giving the columns nice simple names. I'd also suggest just using the full table name in your constraint names rather than some alias. It makes things very clear when someone 6 months later needs to decipher things.
  19. 2 points
    the convention around here is "New question, new thread". That allows for short, direct answer to short, direct questions instead of long, rambling threads where all the "Goodness" gets lost. Some comments on the above: the use of "global" breaks encapsulation, requiring the environment "outside" the function to provide the variable. It is better to pass the data as an argument to the function. What value does admin['gender'] have? Any value passed that resolves to true will cause the ternary operator to return "Mr" and everything else will return "Mrs". The code makes no attempt to ensure that the array indexes used actually exist; this may or may not be an issue. What if the individual is female and not married? They might object to being called "Mrs". What if the individual is not gender-identifying? They would object most strongly to be referred to by either of the terms used here. Marital status and/or gender are both Personal Data and should be stored in the User's "record" (whatever form that takes) so that it can be managed by/on behalf of the User and changed over time. Regards, Phill W.
  20. 2 points
    Alternative model which allows multiple siblings jdev_nroll; jdev_sibling; +----+--------+---------+-------+-----------+------------+ +------------+----------+ | id | sname | ctclass | shift | ctstudent | dob | | sibling_id | elder_id | +----+--------+---------+-------+-----------+------------+ +------------+----------+ | 1 | Curly | 1 | 0 | N | 2007-01-20 | | 2 | 1 | | 2 | Larry | 1 | 0 | Y | 2010-12-21 | | 3 | 1 | | 3 | Mo | 1 | 0 | Y | 2011-02-22 | | 3 | 2 | | 4 | Peter | 1 | 0 | N | 2009-01-03 | | 4 | 5 | | 5 | Paul | 1 | 0 | N | 2006-12-21 | | 9 | 8 | | 6 | Mary | 1 | 0 | Y | 2010-09-20 | | 9 | 10 | | 7 | Jane | 1 | 0 | N | 2008-03-08 | | 10 | 8 | | 8 | John | 1 | 0 | N | 2006-10-04 | +------------+----------+ | 9 | George | 1 | 0 | Y | 2010-10-26 | | 10 | Ringo | 1 | 0 | Y | 2009-11-15 | +----+--------+---------+-------+-----------+------------+ SELECT a.id as sibling_id , a.sname as sibling_name , TIMESTAMPDIFF(YEAR,a.dob,curdate()) as sibling_age , a.ctclass as class , b.id as elder_id , b.sname as elder_name , TIMESTAMPDIFF(YEAR,b.dob,curdate()) as elder_age , b.ctstudent as elder_ctstudent FROM jdev_nroll a JOIN jdev_sibling s ON a.id = s.sibling_id JOIN jdev_nroll b ON s.elder_id = b.id WHERE a.ctstudent = 'Y' ORDER BY a.id +------------+--------------+-------------+-------+----------+------------+-----------+-----------------+ | sibling_id | sibling_name | sibling_age | class | elder_id | elder_name | elder_age | elder_ctstudent | +------------+--------------+-------------+-------+----------+------------+-----------+-----------------+ | 2 | Larry | 9 | 1 | 1 | Curly | 13 | N | | 3 | Mo | 8 | 1 | 1 | Curly | 13 | N | | 3 | Mo | 8 | 1 | 2 | Larry | 9 | Y | | 9 | George | 9 | 1 | 8 | John | 13 | N | | 9 | George | 9 | 1 | 10 | Ringo | 10 | Y | | 10 | Ringo | 10 | 1 | 8 | John | 13 | N | +------------+--------------+-------------+-------+----------+------------+-----------+-----------------+
  21. 2 points
    For example, https://www.php.net/manual/en/datetime.createfromformat.php https://www.php.net/manual/en/datetime.format.php
  22. 2 points
    Christmas has come early! <?php const IMGDIR = 'images/'; const THUMBDIR = 'thumbs/'; const THUMBSIZE = 150; // max thumbnail dimension const NUM = 100; // number of images to be processed on each run $images = glob(IMGDIR.'{*.png,*.jpg}', GLOB_BRACE); $thumbs = glob(THUMBDIR.'{*.png,*.jpg}', GLOB_BRACE); // reduce to basenames only $images = array_map('basename', $images); $thumbs = array_map('basename', $thumbs); // copy the next NUM images to $todo list where thumbnails do not yet exist $todo = array_slice(array_diff($images, $thumbs), 0, NUM); $output = ''; foreach ($todo as $fn) { $sz = getimagesize(IMGDIR.$fn); if ($sz[0] == 0) continue; // not an image $ok = 0; $out = null; switch ($sz['mime']) { // check the mime types case 'image/jpeg': $im = imagecreatefromjpeg(IMGDIR.$fn); $ok = $im; $out = 'imagejpeg'; break; case 'image/png': $im = imagecreatefrompng(IMGDIR.$fn); $ok = $im; $out = 'imagepng'; break; default: $ok = 0; } if (!$ok) continue; // not png or jpg // calculate thumbnail dimensions if ($sz[0] >= $sz[1]) { // landscape $w = THUMBSIZE; $h = THUMBSIZE * $sz[1]/$sz[0]; } else { // portrait $h = THUMBSIZE; $w = THUMBSIZE * $sz[0]/$sz[1]; } // copy and resize the image $tim = imagecreatetruecolor(THUMBSIZE, THUMBSIZE); $bg = imagecolorallocatealpha($tim,0xFF,0xFF,0xFF,127); imagefill($tim, 0, 0, $bg); imagecolortransparent($tim, $bg); // centre the image in the 150 pixel square $dx = (THUMBSIZE - $w) / 2; $dy = (THUMBSIZE - $h) / 2; imagecopyresized($tim, $im, $dx, $dy, 0, 0, $w, $h, $sz[0], $sz[1]); imagesavealpha($tim, true); $out($tim, THUMBDIR.$fn); imagedestroy($im); imagedestroy($tim); $output .= "<img src='".THUMBDIR."$fn' alt='$fn'>\n"; } ?> <!DOCTYPE html> <html> <head> <meta http-equiv="content-language" content="en"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Create Thumbnails</title> <meta name="author" content="Barry Andrew"> <meta name="creation-date" content="10/09/2019"> <style type="text/css"> body { font-family: verdana, sans-serif; font-size: 11pt; } header { background-color: black; color: white; padding: 15px 10px;} img { margin: 5px; } </style> </head> <body> <header> <h1>New Thumbnail Images</h1> </header> <?=$output?> </body> </html>
  23. 2 points
    This example uses glob() to get all .png and .jpg in a folder. By default, the folder is assumed to be named "images" and is a subdirectory of the folder containing the script. Images are displayed as thumbnails, 5 in each row with 25 per page. <?php session_start(); const IMGDIR = 'images/'; const PERPAGE = 25; $page = $_GET['page'] ?? 1; $imgdir = $_GET['dir'] ?? IMGDIR; if (!isset($_SESSION['imgdir']) || $_SESSION['imgdir'] != $imgdir) { unset($_SESSION['images']); $_SESSION['imgdir'] = $imgdir; $page = 1; } if (!isset($_SESSION['images'])) { $_SESSION['images'] = glob($imgdir.'{*.png,*.jpg}', GLOB_BRACE); // get .jpg and .png images } $total = count($_SESSION['images']); /** ************************************************************************************** * display paginated images from SESSION['images] * * @param int $page * @param int $perpage */ function displayImages($page, $perpage) { $start = ($page - 1) * $perpage; $ilist = array_slice($_SESSION['images'], $start, $perpage); foreach ($ilist as $i) { $n = trim(basename($i)); list($iw, $ih,, $sz) = getimagesize($i); if ($iw >= $ih) { // landscape $w = 150; $h = 150 * $ih/$iw; } else { // portrait $h = 150; $w = 150 * $iw/$ih; } $alt = substr($n, 0, 15); echo " <div class='image'> <img src='$i' height='$h' width = '$w' alt='$alt'> </div> "; } echo "<div style='clear:both'></div>"; } /** ************************************************************************************ * function to output page selection buttons * * @param int $total total records * @param int $page current page number * @return string selection buttons html */ function page_selector($total, $page) { if ($total==0) { return ''; } $kPages = ceil($total/PERPAGE); $filler = '&nbsp;&middot;&nbsp;&middot;&nbsp;&middot;&nbsp;'; $lim1 = max(1, $page-2); $lim2 = min($kPages, $page+3); $p = $page==1 ? 1 : $page - 1; $n = $page== $kPages ? $kPages : $page + 1;; $out = "$kPages page" . ($kPages==1 ? '' : 's') . " &emsp;"; if ($kPages==1) { return $out; } $out .= ($page > 1) ? "<div class='pagipage' data-pn='$p'>Prev</div>&ensp;" : "<div class='pagipage x' data-pn='$p' disabled>Prev</div>&ensp;"; if ($page > 4) { $out .= "<div class='pagipage' data-pn='1'>1</div> $filler"; } elseif ($page==4) { $out .= "<div class='pagipage' data-pn='1'>1</div>"; } for ($i=$lim1; $i<=$lim2; $i++) { if ($page==$i) $out .= "<div class='pagicurrent'>$i</div>"; else $out .= "<div class='pagipage' data-pn='$i'>$i</div>"; } if ($page < $kPages-3) { $out .= "$filler <div class='pagipage' data-pn='$kPages'>$kPages</div>"; } $out .= $page < $kPages ? "&ensp;<div class='pagipage' data-pn='$n'>Next</div>" : "&ensp;<div class='pagipage x' data-pn='$n' disabled>Next</div>"; return $out; } ?> <!DOCTYPE html> <html> <head> <meta http-equiv="content-language" content="en"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="author" content="B A Andrew"> <meta name="creation-date" content="11/29/2019"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <title>Example</title> <script type="text/javascript"> $().ready( function() { $(".pagipage").click( function() { $("#page").val( $(this).data("pn") ) $("#form1").submit() }) }) </script> <style type="text/css"> body { font-family: verdana, sans-serif; font-size: 11pt; } label { display: inline-block; width: 150px; font-weight: 600; } #image_wrapper { margin: 30px; } .image { width: 18%; min-height: 200px; margin: 10px; float: left; text-align: center; padding: auto;} /* pagination styles */ .pagipage { display: inline; width: 25px; height: 15px; padding: 3px 5px; text-align: center; font-size: 9pt; border: 1px solid #BB9A21 ; color: #BB9A21; background-color: #FFF; cursor: pointer; margin-left: -1px; } .pagipage.x { background-color: #CCC;} .pagipage:hover { background-color: #BB9A21; border-color: #F0F; color: white; } .pagicurrent { display: inline; width: 25px; height: 15px; text-align: center; font-size: 9pt; font-weight: 600; border: 1px solid #BB9A21; background-color: #BB9A21; color: white; padding: 3px 5px; } .paginate_panel { text-align: center; margin: 20px 0; width: 100%; color: #BB9A21; } </style> </head> <body> <header> <h1>Example Image List</h1> </header> <form id="form1"> <fieldset> <label>Image Folder</label> <input type="text" name="dir" value="<?=$imgdir?>" size="80"> <input type="hidden" name="page" id="page" value="<?=$page?>"> <br> <label>&nbsp;</label> <input type="submit" name="btnSubmit" value="Submit"> </fieldset> </form> <div class='paginate_panel'> <?=page_selector($total, $page, PERPAGE)?> </div> <div id="image_wrapper"> <?=displayImages($page, PERPAGE)?> </div> <div class='paginate_panel'> <?=page_selector($total, $page, PERPAGE)?> </div> </body> </html>
  24. 2 points
    Yes but you don't want to run both at the same time. If you really wanted to, you would need to change the Apache port on one of them as they both use port 80
  25. 2 points
    Hi, This is a probably a wrong way of inserting new email into the DB and can result in race conditions. You should be inserting the new email directly into the DB and your column for ermail ids should be unique so that it throws an exception for duplicate entries.
  26. 2 points
    It depends on the collation setting for the column.
  27. 2 points
    Not even close. This code... $product_details = "SELECT * FROM product WHERE product_id=".$_GET['product_id']; $prepare = $connect->prepare($product_details); $prepare->execute(); ...would embed any SQL injection code contained in the GET into the query which would then be executed. (Just as an unprepared query would) In the correct version the injection code would only be treated as data and not part of the SQL code.
  28. 2 points
    This is my take on it. I copy/pasted a couple of extra jobs to give... CODE <?php $required = ['Feasibility', 'Measure Up', 'Model Drawing', 'Concept Design', 'Developed Design', 'Resource Consent', 'Construction Documentation' ]; $colors = array_combine($required, ['w3-red', 'w3-green', 'w3-orange', 'w3-deep-orange', 'w3-teal', 'w3-yellow', 'w3-purple'] ); $staff_arr = [ 'Staff1' => 'SP', 'Staff2' => 'MB', 'Staff3' => 'BF', 'Staff4' => 'MCP', 'Staff5' => 'DG' ]; function state_dropdown($staff, $color) { return "<form action='' method='POST'>" . "<select class='w3-input w3-round $color' name ='StaffName' onchange='this.form.submit()'>" . // why is a menu of states called "StaffName" ? "<option value =''>$staff</option>" . "<option class='form-control col-sm-3 bg-white text-dark'>Feasibility </option> " . "<option class='form-control col-sm-3 bg-white text-dark'>Measure Up </option> " . "<option class='form-control col-sm-3 bg-white text-dark'>Model Drawing </option> " . "<option class='form-control col-sm-3 bg-white text-dark'>Concept Design </option> " . "<option class='form-control col-sm-3 bg-white text-dark'>Developed Design </option> " . "<option class='form-control col-sm-3 bg-white text-dark'>Resource Consent </option> " . "<option class='form-control col-sm-3 bg-white text-dark'>Construction Docs </option> " . "</select>" . "</form>"; } $xml = simplexml_load_file('plugnz.xml'); $data = []; // // collect the jobs and current task data into an array // foreach ($xml->Jobs->Job as $job) { $id = (string)$job->ID; $state = (string)$job->State; if (!in_array($state, $required)) continue; $data[$id] = [ 'name' => (string)$job->Name, 'state' => $state ]; $tasks = $job->xpath("Tasks/Task[Name='$state']"); $clr = $colors[$state]; $due = (string)$tasks[0]->DueDate; $data[$id]['due'] = date('Y-m-d', strtotime($due)); $data[$id]['display_date'] = date('M d Y', strtotime($due)); $assigned = []; foreach ($tasks[0]->Assigned->Staff as $s) { $assigned[] = $staff_arr[(string)$s->Name]; } $staff_str = join(' ', $assigned); $data[$id]['task'] = [ 'staff' => $staff_str, 'clr' => $clr ]; } // // sort the data array on the task due date DESC // uasort($data, function($a,$b) { return $b['due'] <=> $a['due']; } ); // // output the array as a table // $tdata = ''; foreach ($data as $jid => $jdata) { $tdata .= "<tr><td class='jobno'>$jid</td><td>{$jdata['name']}</td>"; foreach ($required as $stat) { if ($jdata['state']==$stat) { $tdata .= "<td>" . state_dropdown($jdata['task']['staff'], $jdata['task']['clr']) . "</td>"; } else { $tdata .= "<td>&nbsp;</td>"; } } $tdata .= "<td>&nbsp;</td>"; $tdata .= "<td>{$jdata['display_date']}</td></tr>"; } ?> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="creation-date" content="05/10/2019"> <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <title>Job Status Table</title> <style type="text/css"> body { font-family: verdana,sans-serif; font-size: 10pt; padding: 20px 50px; } table {border-collapse: collapse;} .th-sm-1 { font-size: 8pt; text-align: left; } .jobno { font-weight: 600; color: #2196f3; } select { width: 120px; } </style> </head> <body> <table border=1> <thead> <tr> <th class="th-sm-1">Project Number</th> <th class="th-sm-1">Project Name</th> <th class="th-sm-1">Feasibility</th> <th class="th-sm-1">Measure Up</th> <th class="th-sm-1">Model Drawing</th> <th class="th-sm-1">Concept Design</th> <th class="th-sm-1">Developed Design</th> <th class="th-sm-1">Resource Consent</th> <th class="th-sm-1">Construction Docs</th> <th class="th-sm-1">Milestone</th> <th class="th-sm-1">Due Date</th> </tr> </thead> <tbody> <?=$tdata?> </tbody> </table> </body> </html>
  29. 2 points
    Protecting a form field from what? htmlspecialchars() is for use when outputting user-supplied data data to a web page. mysql_real_escape string() is was used to protect input values to queries from SQL injection. This is now obsolete, replaced by mysqli_real_escape_string() or (better still) the use of prepared statements to completely separate the query code from the user-supplied data.
  30. 2 points
    the path being used in the opendir() statement either has a hard-coded '/home/sites/' in it or is using a variable that has that incorrect value in it. based on the path where the code is actually at, that part of the path should be - /home/customer/www/
  31. 2 points
    Store the info that the user put in the original QR code. User retrieves and edits the data, then generates new QR code.
  32. 2 points
    I have been playing around with a possible database solution to your problem Given that a postcode such as "EH12 3AB" breaks down into four parts viz +------+----------+--------+------+ | area | district | sector | unit | +------+----------+--------+------+ | EH | 12 | 3 | AB | +------+----------+--------+------+ ... I was toying with this table structure CREATE TABLE `postcode` ( `pc_id` int(11) NOT NULL AUTO_INCREMENT, `seller` int(11) DEFAULT NULL, `area` varchar(2) DEFAULT NULL, `district` varchar(2) DEFAULT NULL, `sector_min` char(1) DEFAULT NULL, `sector_max` char(1) DEFAULT NULL, `unit_min` char(2) DEFAULT NULL, `unit_max` char(2) DEFAULT NULL, `deliverable` tinyint(4) DEFAULT NULL, `price` decimal(8,2) DEFAULT NULL, PRIMARY KEY (`pc_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +-------+--------+------+----------+------------+------------+----------+----------+-------------+-------+ | pc_id | seller | area | district | sector_min | sector_max | unit_min | unit_max | deliverable | price | +-------+--------+------+----------+------------+------------+----------+----------+-------------+-------+ | 1 | 1 | EH | 1 | 1 | 4 | AA | ZZ | 1 | 1.50 | | 2 | 1 | EH | 1 | 5 | 5 | AA | BZ | 1 | 1.80 | | 3 | 1 | EH | 1 | 5 | 5 | CA | ZZ | 0 | 2.00 | | 4 | 1 | EH | 2 | 1 | 9 | AA | ZZ | 1 | 2.25 | | 5 | 1 | EH | 3 | 1 | 9 | AA | PZ | 1 | 2.50 | +-------+--------+------+----------+------------+------------+----------+----------+-------------+-------+ My code was $postcodes = [ 'EH1 2DB', 'eh15bg' , 'eh1 5ba', 'eh15dg', 'EH2 7HJ', 'EH3 2PT', 'EH3 8SX', 'EH146DE' ]; echo '<pre>'; foreach ($postcodes as $pc) { vprintf('%s%s %s%s : %s<br>', deliveryPrice($db, $pc)); } echo '</pre>'; function deliveryPrice($db, $pcode) { $pcode = strtoupper(str_replace(' ', '', $pcode)); $area = $district = ''; $sector = substr($pcode,-3, 1); $unit = substr($pcode, -2); $l = strlen($pcode); $first = str_split(substr($pcode, 0, $l-3)); foreach ($first as $c) { if (ctype_digit($c)) { $district .= $c; } else { $area .= $c; } } $res = $db->prepare("SELECT price FROM postcode WHERE area = ? AND district = ? AND ? between sector_min AND sector_max AND ? BETWEEN unit_min AND unit_max AND deliverable "); $res->execute( [ $area, $district, $sector, $unit ] ); $p = $res->fetchColumn(); $price = $p ? number_format($p, 2) : 'N/A'; return [$area, $district, $sector, $unit, $price ]; } RESULTS: EH1 2DB : 1.50 EH1 5BG : 1.80 EH1 5BA : 1.80 EH1 5DG : N/A EH2 7HJ : 2.25 EH3 2PT : 2.50 EH3 8SX : N/A EH14 6DE : N/A
  33. 1 point
    Alternatively, configure your web server to show a particular page on error. For apache you might do for example ErrorDocument 500 /500.html Exact configuration will depend on your server version and setup.
  34. 1 point
    I downloaded the class and gave it a try. This creates a pdf doc with a separate page (image and name) for each person. <?php require '../tcpdf/tcpdf.php'; $names = [ "ماشوت محمد علي علام" , "منى طه أبو العلا شعلان" , "وليد عبد العزيز السيد الشيخ" , "ابراهيم عبد السلام خلف" , "احمد حمدى نوار" ]; $pdf = new tcpdf(); $pdf->SetFont('aefurat', '', 30); $pdf->SetTextColor(255); foreach ($names as $name) { $pdf->AddPage(); $pdf->Image('images/snowman.png',15,15,180,180); $pdf->setY(40); $pdf->cell(0,15,$name,0,1,'C'); } $pdf->output('Sample.pdf', 'I'); ?> Output (greatly reduced)
  35. 1 point
    Plan C - Embed the png image in the svg image and overlay with the name <?php $name = 'لقمان ابراهيم عباس عجلان'; $im = "<svg width='500' height='500'> <image x='0' y='0' width='500' height='500' xlink:href='images/snowman.png' /> <text x='250' y='110' text-anchor='middle' style='font-family:calibri; font-size:30pt; fill:#FFF;'>$name</text> </svg> "; echo $im; ?>
  36. 1 point
    $teamnaam = $lidnummer = ''; That's the only time you ever assign values to those variables.
  37. 1 point
    Leave it in benanamen's format in your database. Change the query result to whatever format you need when you do the compare.
  38. 1 point
    Reminder: these forums use Let's Encrypt certs. They last for 3+ months and we have a cronjob that automatically renews when needed. A free cert that I never have to worry about expiring and renewing by myself is amazing.
  39. 1 point
    That is not the way to handle it. Set a unique constraint on the DB column(s) Attempt the insert and catch the duplicate error if any.
  40. 1 point
    HTML knows nothing about php variables. If it's in the HTML section (as this is) it needs embedding inside php tags Either <a href='test.php?id=<?php echo $uri; ?>'>link to page2</a> or use short tags <a href='test.php?id=<?=$uri?>'>link to page2</a>
  41. 1 point
    don't execute SELECT queries inside of loops. with today's server hardware, the time it takes for php to send the sql query statement to the database server is several times longer than the time it takes the database server to execute a query. you want to limit the number of queries you execute. postgreSQL has a LIMIT n OFFSET m statement that you should use for pagination. if for some reason you are not supposed to use that for this assignment, use php's array_slice() on the $listings array to get an array of the desired ids. then use an IN() operator to get the desired rows of data using one query. btw - the header() redirect needs an exit/die statement to stop program execution. without an exit/die, all the rest of that code is still executed. since you haven't shown us what the build_listing_card() code is or what output it produces, cannot help you with what or why your view listing links should be or don't work. don't write code like this either. every pg_fetch_result() call performs a data-seek, followed by a fetch. this takes twice as long a just fetching the data, and you have a couple of dozen pg_fetch_result() statements. the query in this code will match at most one row of data. just fetch that row into a php variable, then access elements of that fetched array. this will run measurably faster and take a lot less typing to produce the code needed for the page. if your initial long list of echo statements are for debugging purposes, just use print_r() or var_dump(), surrounded by html <pre>...</pre> tags to format the output. if this output is instead a desired part of the page output, don't spend your time typing out line after line of code for each possible field/column. use a loop and let php do the work for you.
  42. 1 point
    Also, escaping in and out of HTML like this is kinda old fashioned. These days you may want to keep your HTML separate from PHP. Personally I limit myself to placing only variables in my HTML. So, no conditional logic in the HTML itself, which makes it very clean and easy to maintain. If using heredoc, you can use curly brackets around variables. I.e.: $tpl_content = array('title' => 'test', 'article_body' => 'hallo world'); $template = <<<_TEMPLATE_ <!doctype html> <html> <head> <title>{$tpl_content['title']}</title> </head> <body> <article> <header> <h1>{$tpl_content['title']}</h1> </header> {$tpl_content['article_body']} </article> </body> </html> _TEMPLATE_; // End of Template I wish I had learned this early on myself, as it could have saved me many hours of spaghetti hell.
  43. 1 point
    I assume you've had a go at it yourself by now. Here's my effort... <?php $data = []; for ($r=0; $r<4; $r++) { for ($c=0; $c<4; $c++) { $data[$r][$c] = rand(0,1); } } $rowcounts = $colcounts = []; for ($r=0; $r<4; $r++) { $rowcounts[$r] = count(array_keys($data[$r], 1)); } for ($c=0; $c<4; $c++) { $colcounts[$c] = count(array_keys(array_column($data,$c), 1)); } $rmax = max($rowcounts); $cmax = max($colcounts); $rcmax = max($rmax, $cmax); $hirows = array_keys($rowcounts, $rcmax); $hicols = array_keys($colcounts, $rcmax); echo "<table border='1' style='border-collapse:collapse'>\n"; for ($r=0; $r<4; $r++) { echo "<tr>"; for ($c=0; $c<4; $c++) { $hilite = (in_array($r, $hirows) || in_array($c, $hicols)) ? 'class="max"' : ''; echo "<td $hilite>&nbsp;{$data[$r][$c]}&nbsp;</td>"; } echo "</tr>\n"; } echo "</table>\n"; ?>
  44. 1 point
    if you use the simple session cart definition that has been given on a different forum, using the item id as the array index, and storing the quantity as the array value under the index, doing what you are asking only takes a couple of lines of code.
  45. 1 point
    It means you posted this in multiple forums and someone already took the time in another forum to answer you so we are not going to waste more experts time answering something that has already been answered.
  46. 1 point
    Either that or the OP is should not be programming.
  47. 1 point
    Use glob() function which returns an array of the files. E.G. $folder = 'C:/Users/... /chartSamples/' ; foreach (glob("{$folder}*.png") as $fn) { echo basename($fn) . '<br>'; } giving column.png doughnut.png line.png radar.png rosechart.png stacked.png
  48. 1 point
    ... or you could have used <?=$tdata?> as I did. FYI, my PDO connection code is... $dsn = "mysql:dbname=$database; host=$host; charset=utf8"; $db = new pdo($dsn, $username, $password, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); so that any errors are reported
  49. 1 point
    It sounds like it would be more efficient to make [#][0] the key of sets of subarrays . Then you can go straight ot the ones you want instead of repeatedly searching the whole array. array ( [string] => array ( array (int, int, string, string), array (int, int, string, string), array (int, int, string, string), array (int, int, string, string) ), ... [string] => array ( array (int, int, string, string), array (int, int, string, string), array (int, int, string, string), array (int, int, string, string) ) );
  50. 1 point
    It's not. Here. Yes. Here. Admittedly, I'm asking you to think a little when it comes to some of it, but ... really? Beyond that, Barand has been his typical self and gone above and beyond the call of duty to answer your questions in no uncertain terms and with concrete code examples; yet there are more requests to simply do it for you.
This leaderboard is set to New York/GMT-04:00
  • Newsletter

    Want to keep up to date with all our latest news and information?
    Sign Up
×
×
  • 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.