I created classes Rankings and DateFilter.
Each rankings class has a DateFilter class that should produce the cutoff date. I am trying to be able to create a filter so that everything created after that date will be displayed in a table.
However, the comparison does not work. Can you see a problem?
Here is my DateFilter class:
<?php
include ("Filter.php");
class DateFilter extends Filter
{
//#param daysOld: how many days can be passed to be included in filter
//Ex. If daysOld = 7, everything that is less than a week old is included
private $interval;
public function DateFilter($daysOld)
{
$this->interval = new DateInterval('P'.$daysOld.'D');
}
//#Return: Returns a DateTime that is the earliest possible date to be included in the filter
function createLimitDate()
{
$now = new DateTime();
return $now->sub($this->interval);
}
//generates SQL code for checking date
//Ex. WHERE limitDate > created... if > means before
function genSQL()
{
$limitDate = $this->createLimitDate();
return $limitDate->format('Y-m-d') . " < 'created'";
}
}
?>
And my Rankings Class:
<?php
class Rankings
{
private $filter;
//#params: $filty is the filter given to these rankings
public function Rankings($filty)
{
$this->filter = $filty;
}
//#return: returns the html code for the rankings
public function display()
{
echo '<table border="1" align="center">'.
'<tr align="center" style="font-weight:bold;">
<b><td>#</td><td>NAME</td><td>Date</td></b>
</tr>
';
//hardcoding DB
$where = $this->filter->genSQL();
$qry = mysql_query("SELECT * FROM `pix`
WHERE $where
");
if (!$qry)
die("FAIL: " . mysql_error());
$i = 1;
while($row = mysql_fetch_array($qry))
{
$name = $row['uniquename'];
$created = $row['created'];
echo ' <tr>
<td>'. $i . '</td>'.
'<td>' . $name . '</td>'.
'<td>'. $created . '</td>'.
'</tr>';
$i += 1;
}
echo '</table>';
echo $where;
}
}
?>
I'm calling it like this:
$test = new DateFilter(100);
$rankings = new Rankings($test);
$rankings->display();
In that example, nothing is displayed, even though I'm sure everything in my datebase was uploaded less than 100 days ago.
Throw in some quotes around the date you're passing to MySQL, and drop the quotes around your column name:
return "'" . $limitDate->format('Y-m-d') . "' < created";
Related
Dbfiddle: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=65b310b4b973a7577d4953e01c09a124
Currently I have a table that displays a total count of my data values for each source. I'm getting this value after comparing 2 tables 1 is crm_leads with all my product information and 1 is crm_sources with what sources are the products related to.
Now this is the output:
Now as you can see the total count is shown under each header next to its source. There are 8 cells for each source as seen in the picture. Now these count values are inside a tags which once clicked go to viewall page.
Now here basically I want to show the data of the item that I had clicked. So for example, if I clicked the 163 under Hot status, it takes me to the viewall page and shows me id, source, enquiry_date for all those under status Hot in a table.
So basically it should detect the data for which source and which status is clicked and then accordingly make a statement like this?
select * from crm_leads where lead_source = '.$source.' and lead_status = '.$status.';
Another thing I'm thinking I can do here is put my table inside a form and pass those values as post in my controller class leadstatus which will pass that value to viewall? Not really sure on how to proceed.
Model Class:
function get_statusreport($fdate='',$tdate='')
{
$this->db->select("l.lead_status,crm_sources.title,count(*) as leadnum,l.enquiry_date,l.sub_status");
$this->db->from($this->table_name." as l");
if($fdate !='')
$this->db->where("date(l.added_date) >=",date('Y-m-d',strtotime($fdate)));
if($tdate !='')
$this->db->where("date(l.added_date) <=",date('Y-m-d',strtotime($tdate)));
$this->db->where("lead_status <>",10);
$this->db->join("crm_sources ","crm_sources.id= l.lead_source","left");
$this->db->group_by("l.lead_status,crm_sources.title");
$this->db->order_by("leadnum DESC, crm_sources.title ASC,l.lead_status ASC");
$query = $this->db->get();
$results = $query->result_array();
return $results;
}
Controller Class(leadstatus holds the view for my current table):
public function leadstatus($slug='')
{
$content='';
$content['groupedleads'] = $this->leads_model->get_statusreport($fdate,$tdate);
$this->load->view('crm/main',$main);
$this->load->view('crm/reports/leadstatus',$content);
}
public function viewall($slug='')
{
$content='';
$this->load->view('crm/main',$main);
$this->load->view('crm/reports/viewall',$content);
}
View class:
<?php
$ls_arr = array(1=>'Open',8=>'Hot',2=>'Closed',3=>'Transacted',4=>'Dead');
foreach($groupedleads as $grplead){
$statuses[] = $status = $ls_arr[$grplead["lead_status"]];
if($grplead["title"] == NULL || $grplead["title"] == '')
$grplead["title"] = "Unknown";
if(isset($grplead["title"]))
$titles[] = $title = $grplead["title"];
$leaddata[$status][$title] = $grplead["leadnum"];
}
if(count($titles) > 0)
$titles = array_unique($titles);
if(count($statuses) > 0)
$statuses = array_unique($statuses);
?>
<table>
<tr">
<th id="status">Source</th>
<?php
if(count($statuses) > 0)
foreach($statuses as $status){
?><th id=<?php echo $status; ?>><?php echo $status; ?></th>
<?php
}
?>
<th>Total</th>
</tr>
<?php
if(is_array($titles))
foreach($titles as $title){
?>
<tr>
<?php
$total = 0;
echo "<td>".$title."</td>";
foreach ($statuses as $status) {
$num = $leaddata[$status][$title];
echo "<td><a target='_blank' href='".site_url('reports/viewall')."'>".$num."</a></td>";
$total += $num;
$sum[$status] += $num;
}
echo "<td>".$total."</td>";
$grandtotal += $total;
?>
</tr>
<?php } ?>
</table>
You can include the source and status in the URL like this:
foreach ($statuses as $status) {
$num = $leaddata[$status][$title];
echo "<td><a target='_blank' href='" . site_url('reports/viewall?source=' . $source . '&status=' . $status) . "'>" . $num . "</a></td>";
$total += $num;
$sum[$status] += $num;
}
Then in your controller:
public function viewall($slug = '')
{
$content = '';
$source = $this->input->get('source');
$status = $this->input->get('status');
// Do what you want with $source and $status
$this->load->view('crm/main', $main);
$this->load->view('crm/reports/viewall', $content);
}
I have this function:
function get_content($text_to_match) {
$query = "SELECT * ";
$query .= "FROM table_name ";
$query .= "WHERE one_column_name LIKE '%{$text_to_match}%' OR another_column_name LIKE '%{$text_to_match}%'";
$cont = mysqli_query($connection, $query);
if($content = mysqli_fetch_assoc($cont)) {
return $content;
} else {
return null;
}
}
But when I call it like:
<div>
<?php
for ($i = 1; $i < count(get_content("text_to_match")); $i++) {
echo '<article>' .
'<h3>' . get_content("text_to_match")["string1"] . '</h3>'.
'<p>' . get_content("text_to_match")["string2"] . '</p>' .
'</article>';
}
?>
</div>
I only get the first match in the DB repeated as many times as the number of found items.
Where have I gone wrong?
use this code then fetch data properly
while($content = mysql_fetch_array($cont))
{
return $content;
}
Your logic is at fault. You are calling get_content function to get all matches for the loop, as well as to get individual elements out of the list. This is:
bad logic - the 2nd use case doesn't make sense
excessive - you shouldn't need to run a database query just to output an already retrieved result
What you probably want to do is:
foreach (get_content('text_to_match') as $content) {
echo '<article>';
echo '<h3>' . $content['string1'] . '</h3>';
echo '<p>' . $content['string2'] . '</p>';
echo '</article>';
}
With a few modifications in combination with tips from #Anant and #Unix One's answer, I arrived at this working solution:
Function definition
function get_content($text_to_match, $multiple=false) {
$query = "SELECT * ";
$query .= "FROM table_name ";
$query .= "WHERE one_column_name LIKE '%{$text_to_match}%' OR another_column_name LIKE '%{$text_to_match}%'";
$cont = mysqli_query($connection, $query);
if ($multiple) {
$content_array = [];
while($content = mysqli_fetch_array($cont)) {
$content_array[] = $content;
}
return $content_array;
} else {
if($content = mysqli_fetch_assoc($cont)) {
return $content;
} else {
return null;
}
}
}
Function calls
<?php
/* multiple items */
foreach(get_content("text_to_match", true) as $content) {
echo '<article>' .
'<h3>' . $content["string1"] . '</h3>' .
'<p>' . $content["string2"] . '</p>' .
'</article>';
}
?>
<?php
/* one item */
echo get_content("text_to_match")["string"];
?>
I have a MySQL query that selects two random rows in a table.
$API = mysql_query("SELECT * FROM APIs ORDER BY RAND() LIMIT 2") or die(mysql_error());
while ($row = mysql_fetch_assoc($API)) {
echo "<div class=\"header\"><h1>" . $row['Name'] . "</h1></div>";
}
Is there anything I can put into the while loop that will make the first result have a class of "header apiOne" and the second have a class of "apiTwo"?
How about this?:
$flag = FALSE;
while ($row = mysql_fetch_assoc($API)) {
$class = "header";
if(!$flag) {
$class .= " apiOne";
$flag = TRUE;
} else {
$class .= " apiTwo";
}
echo "<div class=\"$class\"><h1>" . $row['Name'] . "</h1></div>";
}
Add a counter before your for loop.
Set it to 0. In the loop do this
"if counter == 0 then do A, else do B",
then increments the counter
(A and B being the two different
actions you want to do).
I'm new to OOP (and programming for that matter, started a few months ago) so classes and objects are still a bit of a foreign concept to me. Anyhow, I'm attempting to store a mix of strings and variables in an array for later processing. See method drawtable(). drawtable() prints the tableheaders just fine, but tableheaders is just an array of strings. The issue comes when I try to print the tablelink, and text properties, which I've attempted to include variables in. What am I doing wrong here? Note: the session variables output fine.
I would also appreciate any general critiques of the code below, as I'm new and attempting to nip any bad habits in the bud. Many thanks.
<?php
class table{
function __construct($type){
if($type == "submittals"){
$this->tableheaders = array('Specification Section', 'Submittal #', 'Description', 'Vendor or Manufacturer', 'Date Received By GC', 'File', 'Date Submitted', 'File', 'Date Requested for Review', 'Date Returned to GC', 'File', 'Status', 'Date Returned to Subcontractor or Vendor');
$this->query = "***SELECT Query***";
$this->tablelink = array("/pd/upload/" . $_SESSION['current_project'] . "/s/" . $row['file'], "edit_submittal.php?submittal_id=", "edit_submittal.php?submittal_id=" . $row['submittal_id']);
$this->text = array($row['number'] . " - " . $row['name'], $this->row['submittal_num']);
}
}
function drawtable() {
$this->numheaders = count($this->tableheaders);
$this->db = mysqli_connect(***db connection info***);
$this->results = mysqli_query($this->db, $this->query);
$this->num_results = mysqli_num_rows($this->results);
echo " <table border=\"1\">
<tr>";
for ($i = 0; $i < $this->numheaders; $i++) {
echo "<th>" . $this->tableheaders[$i] . "</td>";
}
echo " </tr>";
for ($j=0; $j < $this->num_results; $j++) {
$row = mysqli_fetch_assoc($this->results);
echo " <tr>";
for($k = 0; $k < $this->numheaders; $k++) {
echo " <td>" . $this->text[$k] . "xxx</td>";
}
}
echo " </tr>
</table>";
}
}
?>
Update:Okay well this works, but I'm sure it's still has an air of noob sloppiness. Suggestions? Thanks
<?php
class Table{
function __construct($type){
if($type == "submittals"){
$this->table_headers = array('Specification Section', 'Submittal #', 'Description', 'Vendor or Manufacturer', 'Date Received By GC', 'File', 'Date Submitted', 'File', 'Date Requested for Review', 'Date Returned to GC', 'File', 'Status', 'Date Returned to Subcontractor or Vendor');
$this->query = "***SELECT query***";
}
}
function draw_table($type) {
$this->num_headers = count($this->table_headers);
$this->db = mysqli_connect(***db connection***);
$this->results = mysqli_query($this->db, $this->query);
$this->num_results = mysqli_num_rows($this->results);
echo " <table border=\"1\">
<tr>";
for ($i = 0; $i < $this->num_headers; $i++) {
echo "<th>" . $this->table_headers[$i] . "</td>";
}
echo " </tr>";
for ($j=0; $j < $this->num_results; $j++) {
$row = mysqli_fetch_assoc($this->results);
if($type == "submittals") {
$this->table_link = array("/pd/upload/" . $_SESSION['current_project'] . "/s/" . $row['file'], "edit_submittal.php?submittal_id=", "edit_submittal.php?submittal_id=" . $row['submittal_id']);
$this->text = array($row['number'] . " - " . $row['name'], $row['submittal_num'], $row['description']);
}
echo " <tr>";
for($k = 0; $k < $this->num_headers; $k++) {
echo " <td>" . $this->text[$k] . "</td>";
}
}
echo " </tr>
</table>";
}
function get_table_headers() {
echo $this->table_headers;
}
function get_query() {
echo $this->query;
}
function get_table_link() {
echo $this->table_link;
}
function get_text() {
echo $this->text;
}
}
?>
It doesn't work like this. You can't access $row in the constructor as over there the variable is undefined. You expect PHP to realize that it should replace the content of $row['name'] etc. later when you actually use the string. However, why should it? Instead PHP can't find $row at all and everything goes wrong. Actually, you should get an error telling you that $row is undefined.
Overall there is quite a lot wrong with your code. Sorry to say so, but you do not yet grasp the general concept of OOP at all. And it would take way too long to explain this here. And apparently there are some thing not even related to OOP, which you don't know. Scopes for example and about when and where variables exist.
The site I'm working on wants data organized in a specific way. I need to split it into two columns if it's over 8 td's long. Here is my code right now. I've put it into an array as I had an idea about doing that and using the count to display data but I haven't figured out how to make that work.
$resultFound = false;
$prevWeek = -1;
$count = 0;
while($row = mysqli_fetch_array($result)) {
$adjustedWeek = dateToWeek($row['date']) - 35;
if($_GET['keywords'] != "") {
$id = search($row, $_GET['keywords']);
if($row['id'] == $id) {
if($validWeek) {
if($week == $adjustedWeek) {
include('test2.php');
}
}
else {
include('test2.php');
}
}
}
foreach($tableArray as $table) {
echo $table;
}
Here is my code for test2.php
$table = "";
if($prevWeek != $adjustedWeek) {
$table .= ('<th colspan=2>Week' . $adjustedWeek . '</th>');
$prevWeek = $adjustedWeek;
}
$table .= '<tr>';
$table .= ('<td colspan=12><a href="details.php?id=' . $row['id'] . '">'
. getGameTitleText($row) . '</a></td>');
$table .= '</tr>';
$resultFound = true;
$tableArray[] = $table;
$count++;
I need the code to do something like this:
If (all items of any week > 8)
write out 8 items to column one
then write the rest to column two
I've accounted for the total number of entries it's searching but not specific to a week, and I don't want to have to make lots of variables for that either to keep track.
How could I get the result like I want?
Warning!! the following code is to illustrate the idea only. Not tested on machine, but I think you can iron the possible error out.
pseudo code example:
$arr=array();
while($row = mysqli_fetch_array($result)) {
$arr[]['data']=$row['data'];
$arr[]['whatever']=$row['whatever'];
}
$columns=floor(count($arr)/8);
$output="<table>";
foreach ($arr as $i=>$a){
$output.="<tr>";
$output.="<td>{$arr[$i]['data']}</td>";
if ($columes>0){
for($j=0;$j<$columes;$j++){
$row_number=$i+($j+1)*8;
$output.="<td>{$arr[$row_number]['data']}</td>";
}
}
$output.="</tr>";
}
$output.="</table>";
This code will continue to add the third column if 2 is not enough.
You may still want to put a test for the end of array, so you don't get a bunch of warning when the $row_number is larger than count($arr)
This is how I ended up doing it. It's a bit "dirty" because it echo's out an extra /table and /tr at the beginning but it works for my purposes and is simpler than the code already posted. That was too complex for me
$table = "";
if($prevWeek != $adjustedWeek) {
$table .= '</tr></table><table class="vault_table">';
$table .= ('<tr><th>Week ' . $adjustedWeek . '</th></tr>');
$table .= '<table class="vault_table">';
$prevWeek = $adjustedWeek;
}
if($count % 2 == 0) {
$table .= '<tr>';
}
$table .= ('<td><a href="details.php?id=' . $row['id'] . '">'
. getGameTitleText($row) . '</a></td>');
$resultFound = true;
$tableArray[] = $table;
$count++;
The class is just for styling the table. Didn't have anything to do with how it's being layed out. other than each side of the table being 50% width of the container