Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 08/02/2022 in all areas

  1. the first section of code is just indexing/pivoting the data, using the parent id, when fetching it. there's actually a PDO fetch mode that will do this for you if you select the parent_id as the first column in the SELECT list - PDO::FETCH_GROUP next, you need a recursive function to loop over the data and output it the way you want. see the following example (should be close to what your db naming is) - <?php // create/display nested comments // init require 'pdo_connection.php'; // fake some data $user_id = 1; $_GET['news_id'] = 1; $post = []; // array to hold a trimmed working copy of the form data $errors = []; // array to hold user/valdiation errors // post if($_SERVER['REQUEST_METHOD'] == 'POST') { // trim all the data at once $post = array_map('trim',$_POST); // if any input is an array, use a recursive trim call-back function here instead of php's trim // validate inputs here... // if no errors, use the form data if(empty($errors)) { $sql = "INSERT comment (news_id, parent_id, user_id, comment, datetime) VALUE (?,?,?,?,NOW())"; $stmt = $pdo->prepare($sql); $stmt->execute([ $_GET['news_id'], $post['parent_id'], $user_id, $post['comment'] ]); } // if no errors, success if(empty($errors)) { die(header("Refresh:0")); } } // get all the rows of data for the requested news id $sql = "SELECT parent_id, id, news_id, user_id, comment FROM comment WhERE news_id = ? ORDER BY datetime"; $stmt = $pdo->prepare($sql); $stmt->execute([ $_GET['news_id'] ]); $comment_data = $stmt->fetchAll(PDO::FETCH_GROUP); // recursive function to output parent/child data function list_comments($parent_id, $data, $level=0) { // this just supplies a visual part to the output so you can see what the code does $indent = str_repeat("---- ", $level); // loop over data for the current parent_id foreach($data[$parent_id] as $arr) { // output the comment and any other information echo "$indent{$arr['comment']}<br>"; // determine and output any child count $count = isset($data[$arr['id']]) ? count($data[$arr['id']]) : 0; $pl = $count == 0 || $count > 1 ? 'ies' : 'y'; echo "$indent$count Repl$pl<br>"; // allow a comment for the current parent // you would probably want to use a javascript 'show' operation for this ?> <form method="post"> <input type='hidden' name='parent_id' value='<?=$arr['id']?>'> <?=$indent?><label>Comment:<br> <?=$indent?><textarea name="comment" rows="4" cols="50" placeholder="remember to be polite!"></textarea></label> <input type="submit"> </form><br> <?php // recurse if there are children of the current parent if(isset($data[$arr['id']])) { list_comments($arr['id'], $data, $level+1); } } } // html ?> <?php // display any errors if(!empty($errors)) { echo implode('<br>',$errors); } ?> <?php // allow a comment on the main article ?> <form method="post"> <input type='hidden' name='parent_id' value='0'> <label>Comment:<br> <textarea name="comment" rows="4" cols="50" placeholder="remember to be polite!"><?=$post['comment']??''?></textarea></label> <input type="submit"> </form><br> <?php // list comments, starting with parent 0 list_comments(0, $comment_data, 0);
    1 point
  2. My older version of TCPDF just collapsed like a house of cards when I tried and example page with PHPv8 throwing out errors everywhere - so that goes in the bin. As far as I know the newer versions use composer for installation. I did manage a sample using TFPDF Code <?php const ROOT = 'c:/inetpub/wwwroot'; require(ROOT.'/tfpdf/tfpdf.php'); include('db_inc.php'); $db = pdoConnect('exams'); $res = $db->query("SELECT name_en as en , name_ar as ar FROM staff ORDER BY RAND() LIMIT 10 "); $rows = $res->fetchAll(); class testpdf extends TFPDF { public function makePage($rows) { $this->AddPage(); $this->setFont('', '', 10); foreach ($rows as $r) { $this->SetFont('arial','',10); $this->Cell(60, 10, $r['en'], 'TB', 0, 'L'); $this->SetFont('calibri','',10); $this->Cell(60, 10, rtl($r['ar']), 'TB', 1, 'R'); } } } $test = new testpdf(); $test->AddFont('calibri','','calibri.ttf',true); $test->makePage($rows); $test->output(); function rtl($str) { $k = mb_strlen($str); for ($i=0; $i<$k; $i++) $a[] = mb_substr($str, $i, 1); $a = array_reverse($a); return join('', $a); } ?>
    1 point
  3. That's a lot of queries to run. Start off with a single query that gets all the replies for that post or whatever it is. All of them. Then shove them into an array based on their parent ID. $comment_parents = []; $count = 0; /* get each $row from the query { */ if (!isset($comment_parents[$row['parent']])) { $comment_parents[$row['parent']] = []; } $comment_parents[$row['parent']][] = $row; $count++; /* } */ That also gets you a count of the number of comments, which it seems you want. Now you display them. What's the markup? I don't know. But you're pretty much guaranteed take a recursive approach: show one comment, then immediately show all the comments below it, and repeat. function showComments(array $comment_parents, array $comment, int $level = 0) { /* show the $comment */ foreach ($comment_parents[$comment['id']] ?? [] as $child) { showComments($comment_parents, $child, $level + 1); } } foreach ($comment_parents[0] as $comment) { showComments($comment_parents, $comment); }
    1 point
  4. Here you go... CREATE TABLE `category` ( `id` int(11) NOT NULL, `name` varchar(45) DEFAULT NULL, `parent` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -- Dumping data for table `category` -- INSERT INTO `category` VALUES (1,'happy',0), (2,'comet',1), (3,'grumpy',0), (4,'prancer',3), (5,'bashful',0), (6,'dancer',3), (7,'doc',0), (8,'blitzen',10), (9,'dasher',7), (10,'donner',5), (11,'vixen',1), (12,'cupid',2), (13,'rudolph',3); -- Dump completed on 2021-06-15 15:43:51 Make sure you you have error reporting turned on in your php.ini file. Also turn display_errors and display_startup_errors on.
    1 point
  5. Don't use "SELECT * ". Specify the columns you want. This makes it easier for others, like me, to understand what is in the table and what the query is doing. Indent your code to show the nested structure of loops etc. If you had done those I might have given this problem more than a cursory glance. So you'll have to settle for a generic example of using a recursive function to give an indented list of parent/child elements. Also, Don't run queries inside loops. Use JOINs to get all the data in a single query THE DATA TABLE: category +----+---------+--------+ | id | name | parent | +----+---------+--------+ | 1 | happy | 0 | | 2 | comet | 0 | | 3 | grumpy | 0 | | 4 | prancer | 1 | | 5 | bashful | 1 | | 6 | dancer | 2 | | 7 | doc | 2 | | 8 | blitzen | 2 | | 9 | dasher | 3 | | 10 | donner | 1 | | 11 | vixen | 1 | | 12 | cupid | 8 | +----+---------+--------+ THE OUTPUT THE CODE <?php $sql = "SELECT id, name, parent FROM category"; $res = $db->query($sql); // // store arrays of items for each parent in an array // while (list($id, $name, $parent) = $res->fetch(PDO::FETCH_NUM)) { $data[$parent][] = array('id'=>$id, 'name'=>$name); } /** * recursive function to print a category then its child categories * * @param array $arr category data * @param int $parent parent category * @param int $level hierarchy level */ function displayHierarchy(&$arr, $parent, $level=0) { if (isset($arr[$parent])) { echo "<ul>\n"; foreach($arr[$parent] as $rec) { echo "<li class='li$level'>{$rec['name']}\n"; if (isset($arr[$rec['id']])) displayHierarchy($arr, $rec['id'], $level+1); echo "</li>\n"; } echo "</ul>\n"; } } ?> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Example</title> <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> <script type="text/javascript"> </script> <style type="text/css"> body { font-family: verdana,sans-serif; font-size: 11pt; padding: 50px; } li { font-weight: 600;} .li0 { color: red; } .li1 { color: green; } .li2 { color: blue; } </style> </head> <body> <?php displayHierarchy($data, 0); ?> </body> </html>
    1 point
This leaderboard is set to New York/GMT-05:00
×
×
  • 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.