Jump to content
#FlattenTheCurve ×

Leaderboard

  1. Barand

    Barand

    Moderators


    • Points

      206

    • Content Count

      20,608


  2. requinix

    requinix

    Administrators


    • Points

      107

    • Content Count

      12,018


  3. ginerjm

    ginerjm

    Members


    • Points

      41

    • Content Count

      5,154


  4. kicken

    kicken

    Gurus


    • Points

      37

    • Content Count

      3,669



Popular Content

Showing content with the highest reputation since 04/08/2019 in all areas

  1. 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 )
  2. 3 points
    Don't use $GLOBALS. Forget it exists. There is never a good reason to use it. Pretend you never saw it.
  3. 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 |<----------+ +----------+
  4. 3 points
    The code in each switch is identical so all it achieves is to ensure the calculation uses only the defined list of diameter options. Just use an array of the valid values to verify the values. You can use the same array to generate the option list <?php $diam_vals = [2,3,4,6,8,10,12,14,16,18,20,22,24,26]; $results = ''; if ($_SERVER['REQUEST_METHOD']=='POST') { $x = $_POST['x'] ?? 0; $y = $_POST['y'] ?? 0; $diametre = $_POST['diametre'] ?? 0; if ($x > 0 && $y > 0 && in_array($diametre, $diam_vals)) { $rayon = $diametre * 38.1; $dc = $x/2; $ad = ($y/2)-$rayon; $ac = sqrt(pow($ad,2) + pow($dc,2)); $ec = sqrt(pow($ac,2) - pow($rayon,2)); $LongueurBayonette = $ec*2; $alpha = asin($dc/$ac); $alpha = $alpha*180/M_PI; $beta = acos($rayon/$ac); $beta = $beta*180/M_PI; $angle = 180-$alpha-$beta; $results .= "X = " . $x . "mm" . "<br/>"; $results .= "Y = " . $y . "mm" . "<br/>"; $results .= "Longueur = " . number_format($LongueurBayonette,1) . " mm" . "<br/>"; $results .= "&beta; = " . number_format($angle,1) . "°" . "<br/>"; $results .= "Rayon = " . $rayon . " mm" . "<br/>"; $results .= "&phi; = " . $diametre . '"' . "<br/>"; } else { $results = 'Inputs are not valid'; } } ?> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Simplified Example</title> </head> <body> <form method="post" action=""> <fieldset> X: <input type="text" name="x" value="" /> <br/> Y: <input type="text" name="y" value="" /> <br/> Diametre: <select name="diametre"> <option value="0"> </option> <?php foreach ($diam_vals as $d) { echo "<option value='$d'>$d</option>\n" ; } ?> </select> <input type="submit" value = "Calculer" /> </fieldset> </form> <br> <?=$results?> Just curious - do you have a diagram of how those values relate to one another. It metions "rayon" and "bayonnette" so my guess is that it is some kind of laser rifle with attached bayonet (but I could be wrong) 😊
  5. 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
  6. 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?
  7. 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.
  8. 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.
  9. 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.
  10. 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 | +------------+--------------+-------------+-------+----------+------------+-----------+-----------------+
  11. 2 points
    For example, https://www.php.net/manual/en/datetime.createfromformat.php https://www.php.net/manual/en/datetime.format.php
  12. 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>
  13. 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>
  14. 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
  15. 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.
  16. 2 points
    It depends on the collation setting for the column.
  17. 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.
  18. 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>
  19. 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.
  20. 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/
  21. 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.
  22. 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
  23. 2 points
    $numbers = array(1,3,7,8,10,13); $max = max(array_filter($numbers, function($v) { return $v%2==0; })) ;
  24. 2 points
    You need to specify your units for the margin values. 161px, not just 161.
  25. 2 points
    Not as it is now - if you want to tell the user which is taken you'll have to update the query. Right now it just returns a count of records that match either the username or the email. You'll have to actually select both and then check in PHP which one matches, or rewrite the query to return the offending column. However, I'd recommend just letting people know that one of the two has been taken. That way you're not confirming to an outside party which of the two actually exists in the database - a hacker that knows for a fact a username exists has less work to do and can focus only on figuring out a correct password.
  26. 2 points
    Just use var_dump if you just need to see what the array contains.
  27. 1 point
    Because you should always work with yyyy-mm-dd format in your database (column type DATE) If you always want to insert the current date, use VALUES ('$oracleid','$name','$des',CURDATE(),'$username', '$pass','$isadmin') EDIT: and use prepared statements!
  28. 1 point
    I think that was ginerjm is trying to say is that this may not be the easiest thing in the world for you, but even though there are some people here who don't know stuff like jQuery very well, I know we can help you out in one way or another. I'm sure he wasn't trying to gate-keep the world of software development and say that you had to give up. Right, ginerjm? What I mean is that we don't know anything about your code short of what you can post here and tell us about. As people who have never seen it before, you automatically know more about it (as a whole) than we do. It's not exactly like we can just jump right into the middle of all this and tell you exactly what needs to happen. It's good to know it works somewhere, but if you need help getting it to work someplace it does not then it'd be more helpful if we knew more about that, right? The PHP code is simple enough so any problem is likely to be with the Javascript side. Any errors in the browser console? And the general troubleshooting questions apply: what is it supposed to be doing and what is it actually doing?
  29. 1 point
  30. 1 point
    My code example defaults to 0 for both of those if they aren't set.
  31. 1 point
    so why would you expect to find it by defining a path starting with "inc/"?
  32. 1 point
    It depends - can people have more than one occupation and/or title in your system? If so, create a couple junction tables for that data. Other than that I'd consider splitting name into first and last just to make searching easier, but the rest looks fine.
  33. 1 point
    most likely, either your actual database name contains some non-printing/white-space character(s) or the Config::get() method, which you haven't posted the code for, is adding some non-printing/white-space character(s) to the value (i'm betting either a new-line or a <br> tag.) this code is just adding an unnecessary, pointless layer. it has no useful error handling, is using emulated prepared queries (the default), cannot be used with a LIMIT x term in a query, and can't be used with more than one connection or a different database type. if you want to do something useful for a database class, extend the PDO class and add a general prepared/non-prepared query method that will use a prepared query if there are input parameters and will use a non-prepared query if there are not. when you make the database connection, you should set the character set to match your database tables, set the error mode to exceptions, set emulated prepared queries to false, and set the default fetch mode to assoc (assoc works best when dynamically processing fetched data.)
  34. 1 point
    IMHO it's easier just to do both inserts in the same loop as you always want one of each. ////////////////////////////////////// // menu item and connection insert // ////////////////////////////////////// $ins_i = $conn->prepare(' INSERT INTO ssm_menu_items (menu_item_name) VALUES (?); '); $ins_c = $conn->prepare(' INSERT INTO ssm_menu_connection (menu_id, menu_item_id) VALUES (?,?) '); $ins_i->bind_param('s',$nmItem); $ins_c->bind_param('ii', $menuInsId, $menuItmInsId); foreach ($_POST['newMenuItem'] as $nmItem) { $ins_i->execute(); $menuItmInsId = $stmt->insert_id; $ins_c->execute(); }
  35. 1 point
  36. 1 point
    Try using domDocument or simple_html_dom. EG include("/path/to/simple_html_dom.php"); $html = file_get_html('my_source.html'); $rows = $html->find('tr[bgcolor="#EEEEEE"]'); $csvFile = fopen('mydata.csv', 'w'); foreach ($rows as $row) { $data = []; foreach ($row->children() as $itm) { $data[] = $itm->plaintext; } fputcsv($csvFile, $data); } fclose($csvFile); The csv file can then be loaded into a sql table using a LOAD DATA INFILE statement.
  37. 1 point
    Tell me how to load those images into a test database and I'll continue to help.
  38. 1 point
    Stop supposing and actually find the answer. It's documented very clearly if you look for it. Yes, Bootstrap v3 and v4 define the sizes differently. Because apparently nobody over there has any idea what "backwards compatibility" is.
  39. 1 point
    You could've had a database set up in less time than you spent moaning about what a PITA it is. It takes about half a dozen statements to create an image table from your image directory. JFDI. const IMGDIR = 'images/'; $db->exec("CREATE TABLE IF NOT EXISTS `image_lib` ( `img_id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(100) DEFAULT NULL, `path` varchar(255) DEFAULT NULL, `width` int(11) DEFAULT NULL, `height` int(11) DEFAULT NULL, `mime_type` varchar(20) DEFAULT NULL, `description` varchar(255) DEFAULT NULL, `img_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`img_id`), FULLTEXT KEY `idx_image_lib_description` (`description`) ) "); $ins = $db->prepare("INSERT INTO image_lib (name, path, width, height, mime_type) VALUES (?,?,?,?,?)") ; $imgs = glob(IMGDIR.'{*.png,*.jpg}', GLOB_BRACE); foreach ($imgs as $i) { $s = getimagesize($i); $ins->execute( [ basename($i), IMGDIR, $s[0], $s[1], $s['mime'] ]); } Job done!
  40. 1 point
    Or you could take the view that the product is a timeslot. If they want part of one and part of the next then they buy both. Check which slots contain or over lap the required times as this example does (see line 40) ... <?php $business_hours = [ 1 => [ 'am_from' => '10:00', 'am_to' => '12:00', 'pm_from' => '13:00', 'pm_to' => '19:00' ], 2 => [ 'am_from' => '08:00', 'am_to' => '12:00', 'pm_from' => '13:00', 'pm_to' => '17:00' ], 3 => [ 'am_from' => '12:00', 'am_to' => '12:00', 'pm_from' => '13:00', 'pm_to' => '19:00' ], 4 => [ 'am_from' => '08:00', 'am_to' => '12:00', 'pm_from' => '13:00', 'pm_to' => '17:00' ], 5 => [ 'am_from' => '08:00', 'am_to' => '12:00', 'pm_from' => '13:00', 'pm_to' => '13:00' ], ]; //------------------------------------------------------------ // from above array, generate daily 30 minute slots // for the next 15 days // $slots = []; $dt1 = new DateTime(); $intwd = DateInterval::createFromDateString('next weekday'); $dp_days = new DatePeriod($dt1, $intwd, 14); foreach ($dp_days as $d) { $dno = $d->format('w'); $times = $business_hours[$dno]; $slots[$d->format('Y-m-d')] = generateSlots($times); } //------------------------------------------------------------ // place these bookings in their slots // $bookings = [ ['title' => 'Test 1', 'start' => '2019-11-26 10:15', 'end' => '2019-11-26 11:30'], ['title' => 'Test 2', 'start' => '2019-11-29 11:00', 'end' => '2019-11-29 12:00'], ['title' => 'Test 3', 'start' => '2019-12-02 15:30', 'end' => '2019-12-02 16:30'] ]; foreach ($bookings as $b) { $sd = new DateTime($b['start']); $ed = new DateTime($b['end']); $date = $sd->format('Y-m-d'); $st = $sd->format('H:i'); $et = $ed->format('H:i'); foreach ($slots[$date] as &$s) { if ($s['t'] != '') continue; // not available if ($et > $s['s'] && $st < $s['e']) { // if booking is in or overlaps slot ( LINE 40 ) $s['t'] = $b['title']; // place title into slot } } } //------------------------------------------------------------ // output the slots to the page // $tdata = ''; foreach ($slots as $d => $ddata) { if ((new DateTime($d))->format('w')==1) { $tdata .= "<tr><td colspan='12'> </td></tr>\n"; } $tdata .= "<tr><td>" . date('D d M', strtotime($d)) . '</td>'; foreach ($ddata as $slt) { switch ($slt['t']) { case 'closed': $cls = 'class="closed"'; $txt = ''; break; case '': $cls = ''; $txt = ''; break; default: $cls = 'class="booked"'; $txt = $slt['t']; } $tdata .= "<td $cls>$txt</td>"; } $tdata .= "</tr>\n"; } /** * generate daily timeslots * * @param array $times - array of business hours for the day */ function generateSlots($times) { $stime = ''; $dt1 = new DateTime('08:00:00'); $dt2 = new DateTime('19:00:00'); $di = new DateInterval('PT1H'); $dp = new DatePeriod($dt1, $di, $dt2); $slots = []; foreach ($dp as $t) { $k = $t->format('G'); $h1 = $t->format('H:i'); $h2 = $t->modify('+1 hour')->format('H:i'); $text = ($h1 >= $times['am_from']) && ($h1 < $times['am_to']) || ($h1 >= $times['pm_from']) && ($h1 < $times['pm_to']) ? '' : 'closed' ; $slots[$k] = [ 's'=>$h1, 'e'=>$h2, 't'=>$text]; } return $slots; } ?> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Example Bookings</title> <style type="text/css"> body, table { font-family: calibri, sans-serif; font-size: 11pt; } table { border-collapse: collapse; width: 90%; margin: 0 auto; } th { padding: 4px 2px; background-color: #006EFC; color: #FFF; border-color: #FFF;} td { background-color: #FFF; padding: 2px; } td.closed { background-color: #888; color: #FFF; } td.booked { background-color: #FFC0C0; } </style> </head> <body> <header> <h1>Example Bookings</h1> </header> <table border='1'> <tr><th rowspan='2'>Date</th><th colspan='4'>AM</th><th></th><th colspan='6'>PM</th></tr> <tr><th>8 – 9</th><th>9 – 10</th><th>10 – 11</th><th>11 – 12</th> <th>12 – 1</th><th>1 – 2</th><th>2 – 3</th><th>3 – 4</th><th>4 – 5</th><th>5 – 6</th><th>6 – 7</th></tr> <?=$tdata?> </table> </body> </html>
  41. 1 point
    Having run the above code, my phpinfo() in the same script shows However, the output from a second identical script was exactly the same - the default reverted to London time. So the "data.timezone" setting is the one used unless it is set in the script. Running phpinfo() in a separate script shows "London" for both. So, Yes. You would need it every script unless you set it at ini file level.
  42. 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"; ?>
  43. 1 point
    Cars contain a motor. Motors do not contain cars. Therefore, put a column for motor in the Cars table and link through the various motor ids.
  44. 1 point
    It's better to put your Apache configuration inside apache's main (or vhost) configuration file then disable .htaccess file processing. However that's the kind of optimization that you only really need to do if you're trying to run a high traffic site and need every bit of performance you can get. Making a change such as a new redirect or rewrite rule would then require editing the configuration and reloading apache. Not a terrible thing but more cumbersome than editing the site-specific .htaccess. Yes, if you want multiple versions of PHP then you need to have them all installed separately in a way that doesn't conflict. Hopefully your package management system takes care of that for you. For example, I use ubuntu and the ondrej/php PPA which installs the configurations into /etc/php with a sub-folder for the version and api type. I use FPM so my configuration is in /etc/php/7.3/fpm/ with pools defined in /etc/php/7.3/fpm/pools.d/ Yes. You could do a per-site setup, per user, or something different. That's pretty much up to you and what you find most convinent. What I prefer to do is create a separate pool for each system user that hosts sites. I configure that pool with settings appropriate for their site and also configure it to run using their user account so there's no need really to deal with permission problems when the site whats to manipulate the files. For example, a typical pool configuration might look something like: [kicken] prefix = /var/run/php7-fpm user = $pool group = www-data listen.owner = www-data listen.group = www-data listen.mode = 0600 listen = $pool.sock php_value[error_log] = /var/log/php7-fpm/$pool-error.log php_value[session.save_path] = /var/lib/php7/$pool/sessions php_flag[log_errors] = on php_value[memory_limit] = 32M php_value[upload_max_filesize] = 500M php_value[post_max_size] = 501M php_value[max_input_vars] = 5000 I made a copy of the default www pool when I first set things up and made some general changes (like error log, session path, using $pool instead of hard-coded names) and save that as a template. Each time I need to add a new pool I just copy that template, rename the pool and make tweaks if necessary. I prefer using unix sockets vs TCP sockets as /var/run/php7-fpm/kicken.sock is easier to remember than 127.0.0.1:9038 or whatever port you want to use for that pool. On the apache side of things, I have a separate configuration file for all the PHP stuff that looks like Define PHP7_POOL_DEFAULT "proxy:unix:/var/run/php7-fpm/www-data.sock|fcgi://localhost" Define PHP7_POOL_KICKEN "proxy:unix:/var/run/php7-fpm/kicken.sock|fcgi://localhost" Define PHP7_POOL_USERX "proxy:unix:/var/run/php7-fpm/userx.sock|fcgi://localhost" Define PHP7_POOL_USERY "proxy:unix:/var/run/php7-fpm/usery.sock|fcgi://localhost" Define PHP7_POOL_USERZ "proxy:unix:/var/run/php7-fpm/userz.sock|fcgi://localhost" ScriptAlias /phpsource.cgi /usr/lib/cgi-bin/php7-source Action php-source /phpsource.cgi virtual <FilesMatch "\.phps"> SetHandler php-source </FilesMatch> <Directory /usr/lib/cgi-bin> Require all granted </Directory> <FilesMatch ".+\.ph(ar|p|tml)$"> SetHandler ${PHP7_POOL_DEFAULT} </FilesMatch> The pool's are setup as variables that can be used in the vhost configurations, and it sets up a default configuration. I set mine up to support highlighted .phps extensions also using a traditional CGI setup, but that can be skipped/ignored. In each vhost I set it to the right pool by giving it it's own FilesMatch with the appropriate handler. <VirtualHost *:443> ServerName aoeex.com ServerAlias www.aoeex.com <FilesMatch ".+\.ph(ar|p|tml)$"> SetHandler ${PHP7_POOL_KICKEN} </FilesMatch> </VirtualHost> Setting up multiple versions is just a matter of installing each version's php-fpm package, configuring a pool for that version, and pointing apache to whatever socket you setup for that pool. Fairly simple. I used to have a 5.6 setup going as well due to some old third-party software but I was finally able to move to single 7.3 version recently. Ideally you'd want to only have a single version going, and only use multiple versions if you really need to for some specific reason.
  45. 1 point
    This looks totally mixed up right not really, this is just a guess from you what "banking website"? As you don't seem to be firm with the technology, i would think it's not YOUR website, more like the website of the bank you are customer at. and the website is accessed via URL - that has plain nothing to to with any "folder" as i think you mean from a filesystem - except that there's a common fallback. And the syntax for a URL is documented: https://en.wikipedia.org/wiki/URL#Syntax
  46. 1 point
    array_reduce is a great function for this. Quite rare to see it in the real world, which means bonus points for actually using it. $numbers = array(1, 3, 7, 8, 10, 13); // assuming there is at least one even number >= 0 $max = array_reduce($numbers, function($max, $n) { return ($n % 2) == 0 && $n > $max ? $n : $max; }, 0); Or with PHP 7.4's arrow functions, $max = array_reduce($numbers, fn($max, $n) => ($n % 2) == 0 && $n > $max ? $n : $max, 0);
  47. 1 point
    1. The now extinct mysql library and the mysqli library are two completely different animals. 2. Forget about mysqli and use PDO. +---------+-------------+ | mysql | dodo | | mysqli | donkey | | PDO | racehorse | +---------+-------------+
  48. 1 point
    An alternative approach is to create an array during your first pass of the data. This array would contain arrays of records for each rep. EG $salesdata = [ 'Sales_rep1' => [ 0 => [ 'Col1', 'Col2', 'Col3' ], 1 => [ 'Col1', 'Col2', 'Col3' ], 2 => [ 'Col1', 'Col2', 'Col3' ] ], 'Sales_rep2' => [ 0 => [ 'Col1', 'Col2', 'Col3' ], 1 => [ 'Col1', 'Col2', 'Col3' ], 2 => [ 'Col1', 'Col2', 'Col3' ], 3 => [ 'Col1', 'Col2', 'Col3' ] ], ]; You can then loop through the array creating your sheets for each rep. foreach ($salesdata as $rep => $sales) { create new sheet foreach ($sales as $recno => $recdata) { add new row foreach ($recdata as $col) { output column } } }
  49. 1 point
    If you had php error checking turned on (as one should during ALL DEVELOPMENT) you would have probably been told of an error. In your first attempt you had a 'NON null' phrase on one field when you probably meant to use 'NOT null'.
  50. 1 point
    The first thing you need to do is remove the deprecated mysql code and replace it with PDO or at least mysqli. That you can even use mysql implies that your version of PHP is long ago obsolete.
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.