Jump to content

Simple php calendar plugin trying to add linkable dates


Go to solution Solved by OldGrim,

Recommended Posts

I have a simple php calendar script that works great however, I need to make the dates clickable referencing a db tables data. I tried changing the for loop to a while loop with no success so I am now trying to work with the for loop to make the dates (links); here is my complete script (using it as a calendar plugin) with comments to show my re-coding attempt.

<?php
$time = time();
$numDay = date('d', $time);
$numMonth = date('m', $time);
$strMonth = date('F', $time);
$numYear = date('Y', $time);
$firstDay = mktime(0,0,0,$numMonth,1,$numYear);
$daysInMonth = cal_days_in_month(0, $numMonth, $numYear);
$dayOfWeek = date('w', $firstDay);
echo "<div class='row'>\n";
echo "<table width='100%' border='0'><tr>\n";
echo "<td align='center'><span style='font-size:16px; color:#FCF9B6;'><b>Calendar</b></span><p>\n";
echo "<table width='63%' border='1' cellpadding='5'><tr>\n";
echo "<td bgcolor='#AFAFAF'><table width='100%' cellpadding='4' border='1'>\n";
echo "<caption style='text-align:center; font-size:16px; background:#B83C32; color:#fff;'><b>$strMonth $numYear</b></caption>\n";
echo "<thead><tr>\n";
echo "<th style='text-align:center; font-size:12px;' bgcolor='#005500' abbr='Sunday' scope='col' title='Sunday'>S</th>\n";
echo "<th style='text-align:center; font-size:12px;' bgcolor='#005500' abbr='Monday' scope='col' title='Monday'>M</th>\n";
echo "<th style='text-align:center; font-size:12px;' bgcolor='#005500' abbr='Tuesday' scope='col' title='Tuesday'>T</th>\n";
echo "<th style='text-align:center; font-size:12px;' bgcolor='#005500' abbr='Wednesday' scope='col' title='Wednesday'>W</th>\n";
echo "<th style='text-align:center; font-size:12px;' bgcolor='#005500' abbr='Thursday' scope='col' title='Thursday'>T</th>\n";
echo "<th style='text-align:center; font-size:12px;' bgcolor='#005500' abbr='Friday' scope='col' title='Friday'>F</th>\n";
echo "<th style='text-align:center; font-size:12px;' bgcolor='#005500' abbr='Saturday' scope='col' title='Saturday'>S</th>\n";
echo "</tr></thead><tbody><tr>\n";
if($dayOfWeek !=0) {
echo "<td style='text-align:center; font-size:12px; color:#000; background:#ddd;' colspan='".$dayOfWeek."'></td>\n";
}
for($i=1;$i<=$daysInMonth;$i++) {

/* my inserted coding for db query */

$moz = date('n', $time);
$result = dbquery("SELECT * From ".DB_GRIMS_BLOG_POST_TOPIC." WHERE art_mon='$moz'");
if (dbrows($result)) {
		while($data = dbarray($result)) {
		$dah = $data['art_day'];
		$pst = $data['post_id'];
	}
if($i == $dah) { "<a href='../grims_blog/filtered.php?post_id=$pst'>$i</a>"; }

/* normal script continues */

if($i == $numDay) { 
echo "<td style='text-align:center; font-size:12px; color:#fff; background:#890000;'><b>\n";
} else {
echo "<td style='text-align:center; font-size:12px; color:#000; background:#ddd'><b>\n";
}
$padding = $i;
$padding = str_pad($padding, 2, '0', STR_PAD_LEFT);
echo $padding;
echo "</b></td>\n";

/* closing of db query inserted here */
}
/* ends here */

if(date('w', mktime(0,0,0,$numMonth, $i, $numYear)) == 6) {
echo "</tr>\n";
        }
}
echo "</tbody>\n";
echo "</table></td></tr></table>\n";
echo "</td></tr></table><br /><br /></div>\n";
?>

It doesn't throw an error but it doesn't work either. Any help would be appreciated.

the simplest and most efficient way of doing this would be to query the database to get all the data matching the date range you are trying to display, fetch all the data into a php array variable, using the date value as the main array index. if there can be more than one piece of data per day, when you are fetching the data store it as an array of rows of data. then, as you are looping to produce the output for the calendar, for each day, form a date value in exactly the same format as was used for the array index values, test if an element isset() in the array of data, and if so, reference it when you are producing the output for that calendar's day.

4 hours ago, OldGrim said:

It doesn't throw an error but it doesn't work either

Can you define "doesn't work" for us.

  • What should it do that it isn't doing?
  • What is it doing that it shouldn't do?

What I mean is the calendar display is the same as if the code weren't there. The code does nothing. It is supposed to make the day of an article a link which when clicked pulls up that article. Here's a link to see my calendar.

https://whisperwillow.net/infusions/grims_blog/index.php

The highlighted day is today's date. In my db table the month is 'art_mon' for article month 'tinyint(2)'. The day is 'art_day' for article day 'tinyint(2)' and of course 'post_id' is the article id (int(10). All of these values are inserted into the db table when a new article is posted. The calendar script is not mine and was not written to have linked events(articles) in my case and I am trying to add that capability. The month of December so far has 2 articles posted on the 1st and the 3rd so those 2 days in the calendar should link to those 2 articles. Using this coding in a test file:

$time = time();
$moz = date('n', $time);
$main = '$days = array(';
$endmain = ');';
$result = dbquery("SELECT * From ".DB_GRIMS_BLOG_POST_TOPIC." WHERE art_mon='11'");
if (dbrows($result)) {
	$na = array();
		while($data = dbarray($result)) {
	$mdata = array();
		$dah = $data['art_day'];
		$pst = $data['post_id'];
	$mdata = "&lt;a href='https://whisperwillow.net/infusions/grims_blog/filtered.php?post_id=$pst'&gt;$dah&lt;/a&gt;";
	$na[] = $mdata;
	}
}
echo $main.'<br>';foreach($na as $x => $value) {echo $value.'<br>';}echo $endmain;

I can get this result:

$days = array(
<a href='https://whisperwillow.net/infusions/grims_blog/filtered.php?post_id=12'>23</a>
<a href='https://whisperwillow.net/infusions/grims_blog/filtered.php?post_id=13'>24</a>
<a href='https://whisperwillow.net/infusions/grims_blog/filtered.php?post_id=8'>1</a>
<a href='https://whisperwillow.net/infusions/grims_blog/filtered.php?post_id=9'>7</a>
);

This is for the month of November. However using this coding in another calendar script I've tried it doesn't work either because the above is actually one long string instead of an array. I thought about trying to use eval but I have no experience with it and am concerned about the warnings of using it.

I've rewritten the code for you,

  • cleaned up the structure
  • cleaned up the HTML using classes and CSS and removed deprecated markup
  • implemented mac_gyver's array suggestion
  • implemented the links
<?php
const HOST     = 'localhost';                                                              #####
const USERNAME = '????';                                                                       #
const PASSWORD = '????';                                                                       #
const DATABASE = '????';                                                                       #     These lines would
                                                                                               #
function pdoConnect($dbname=DATABASE)                                                          #     normally be in
{                                                                                              #
    $db = new PDO("mysql:host=".HOST.";dbname=$dbname;charset=utf8",USERNAME,PASSWORD);        #     an included file
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);                              #
    $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);                         #
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);                                      #
    return $db;                                                                                #
}                                                                                          #####

/*********************************      TEST DATA      *****************************************
            +---------+------------+--------+------------+
            | blog_id | date       | title  | content    |
            +---------+------------+--------+------------+
            |       1 | 2020-11-15 | Blog 1 | Blog one   |
            |       2 | 2020-12-07 | Blog 2 | Blog two   |
            |       3 | 2020-12-08 | Blog 3 | Blog three |
            |       4 | 2020-12-10 | Blog 4 | Blog four  |
            |       5 | 2020-12-21 | Blog 5 | Blog five  |
            |       6 | 2021-01-02 | Blog 6 | Blog six   |
            +---------+------------+--------+------------+
*************************************************************************************************/

$pdo = pdoConnect();

$today = new DateTime( $_GET['date'] ?? '' );
$prev = (clone $today)->modify('-1 month')->format('Y-m-d');
$next = (clone $today)->modify('+1 month')->format('Y-m-d');

$caption = $today->format('F Y');
$this_month =  $today->format('n');

$day1 = (clone $today)->modify("first day of this month");
$queryStart = $day1->format('Y-m-d');
if ($day1->format('w') != 0) {
    $day1->modify('last Sunday');
}
$dayN = $today->modify('last day of this month');
$queryEnd = $dayN->format('Y-m-d');
if ($dayN->format('w') != 6) {
    $dayN->modify('next sunday');
}
$period = new DatePeriod($day1, new DateInterval('P1D'), $dayN);                // calendar display dates

##
##  get this month's blogs
##
$blogs = [];
$res = $pdo->prepare("SELECT blog_id
                           , date as day
                           , title
                      FROM blog
                      WHERE date BETWEEN ? AND ?
                      ORDER BY date     
                     ");
$res->execute( [ $queryStart, $queryEnd ] );
foreach ($res as $r) {
    $blogs[$r['day']] = $r;
}

##
##  Functions
##

function calheads()
{
    $out = '<tr>';
    $days = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ];
    foreach ($days as $d) {
        $out .= "<th abbr='$d' title='$d'>{$d[0]}</th>";
    }
    return $out;
}

function caldata($per, $mth, &$blogs)
{
    $i = 0;
    $out = '';
    foreach ($per as $d) {
        if ($i%7 == 0) {
            if ($out != '') $out .= "</tr>\n";
            $out .= "<tr>";
        }
        ++$i;
        $dno = $d->format('d');
        $cls = $link = $title = '';
        if ($d->format('n') != $mth) {
            $cls .= 'blank ';
        } else {
            $cls .= 'daycell ';
            if (isset($blogs[$d->format('Y-m-d')])) {
                $cls .= 'active ';
                $title = $blogs[$d->format('Y-m-d')]['title'];
                $dno = "<a href='https://whisperwillow.net/infusions/grims_blog/filtered.php?post_id={$blogs[$d->format('Y-m-d')]['blog_id']}'>$dno</a>";
            }
            if ($d->format('Y-m-d') == date('Y-m-d')) $cls .= 'today ';
        }
        
        $out .= "<td class='$cls' title='$title'>$dno</td>";
    }
    $out .= "</tr>\n";
    return $out;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-language" content="en">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Examle calendar</title>
<meta name="creation-date" content="12/06/2020">
<style type='text/css'>
    body, table {
        font-family: verdana, sans-serif;
        font-size: 10pt;
    }
    table {
        border-collapse: collapse;
        width: 63%;
        margin: 50px auto;
    }
    caption {
        background-color: #A91723;
        color: #FFF;
        padding: 4px;
        text-align: center;
        font-size: 16pt; 
    }
    th {
        background-color: #5F8874;
        color: #FFF;
        padding: 4px;
    }
    td {
        background-color: #EEE;
        padding: 8px;
        text-align: center;
        font-weight: 600;
    }
    td.active {
        background-color: #CCC;
        color: #FFF;
    }
    td.blank {
        background-color: #FFF;
        color: #CCC;
    }
    td.today {
        border-color: #A91723;
        border-width: 5px;
        color: #666;
    }
    #navbtn1, #navbtn2 {
        font-weight: 600;
        color: #FFF;
        text-decoration: none;
    }
    #navbtn1 {
        float: left;
    }
    #navbtn2 {
        float: right;
    }
</style>
</head>
<body>
    <input type='hidden' id='caldata' value=''>
    <table border='1'>
        <caption>
            <a id='navbtn1' href='?date=<?=$prev?>'>&lt;</a>
            <?=$caption?>
            <a id='navbtn2' href='?date=<?=$next?>'>&gt;</a>
        </caption>
        <thead>
            <?=calheads()?>
        </thead>
        <tbody>
            <?=caldata($period, $this_month, $blogs)?>
        </tbody>
    </table>
</body>
</html>

output:

image.png.985c2651a9d521daf14a0012746dceed.png

You know I really really appreciate all your hard work on this. The CMS I'm running is PHP-Fusion and all though our system is PDO based I have never never used pdo prepared statements even though I know about it. I don't see how I can suddenly completely redo all my calendar code as you suggest. I tried using some of the ideas from your code but so far no luck. I suppose I'm just going to have to abandon my idea of making my calendar clickable.

On second thought I really do need to learn PHP PDO. Considering your post above how would I change it to reflect my actual data which follows:

/*********************************      MY TABLE DATA      *****************************************
                        +--------------------+-----------+-------------+-------------+-----------+
                        | post_topic_id | post_id | topic_id | art_mon | art_day |
                        |          1	                1	   1	  9	    4         |-------------------------
                        |          2	                2	   2	  9	    9         | 3 articles in Sep 4, 9 & 27
                        |          3	                3	   5	  9	    27      |--------------------------
                        |          4	                4	   4	  10	    11      |--------2 articles----- both on
                        |          5	                6	   3	  10	    11      |-----------in Oct-------  the 11th
                        |          6	                12	   2	  11	    23      |--------------------------
                        |          7	                13	   6	  11	    24      |      4 articles
                        |          8	                8	   3	  11	    1        |         in Nov 1, 7, 23 & 24
                        |          9	                9	   4	  11	    7        |--------------------------
                        |          10	                14	   4	  12	    1        |--------2 articles-----
                        |          11	                15	   4	  12	    3        |---------in Dec-------- 1 & 3
                        +--------------------+-----------+-------------+-------------+-----------+
******************************************************************************************************/
All I need from this table is the following:
current month(art_mon) 1 or 2 digits depending on month
day(art_day) 1 or 2 digits depending on day
and the (post_id) 1 or 2 digits depending on article post
+----------------------------------------------------------------------------------------------------+
As I said before this data is inserted in this table at post creation time
The post_id is gleaned from the last inserted article post_id. Code follows:
+----------------------------------------------------------------------------------------------------+
	$posted = time();
$result = dbquery("INSERT INTO ".DB_GRIMS_BLOG_POST." (post_id, topic_id, post_title, post_body, post_img, post_thb, posted, active) VALUES ('', '$topic_id', '$post_title', '$post_body', '$post_img', '$post_thb', '$posted.', '$active')");
$last_id = db_lastid();
$mymon = date("n", $posted);
$myday = date("j", $posted);
$result = dbquery("INSERT INTO ".DB_GRIMS_BLOG_POST_TOPIC." (post_topic_id, post_id, topic_id, art_mon, art_day) VALUES ('', '$last_id', '$topic_id', '$mymon', '$myday')");

I know this is a long shot but if you could help me one more time I would be SO GRATEFUL!

Why do you insert the data into two tables
The POST_TOPIC table merely duplicates data that is in the the POST table (art_mon and art_day are derived from posted value)

  +-------------+
  |  POST       |
  +-------------+
  |  post_id    |-------+
  |  topic_id   |----+  |        +----------------+
  |  post_title |    |  |        | POST_TOPIC     |
  |  post_body  |    |  |        +----------------+
  |  post_img   |    |  |        |  post_topic_id |
  |  post_thb   |    |  +--------|  post_id       |
  |  posted     |-+  +-----------|  topic_id      |
  |  active     | +--------------|  art_mon       |
  +-------------+ +--------------|  art_day       |
                                 +----------------+

You aren't doing yourself any favours by storing unix time value and separate month/day fields - just use a DATE type for posted (yyyy-mm-dd).

Substitute this query into my code to use your table structure

SELECT post_id
     , date(from_unixtime(posted)) as day   
     , post_title
FROM DB_GRIMS_BLOG_POST
WHERE posted BETWEEN unix_timestamp(?) AND unix_timestamp(?)
ORDER BY posted

 

Edited by Barand

Message Reply: Yes we liked it very much after figuring out how to implement it in our CMS. It took some tweaking but the end result is much better than I had hoped for. Thank you very very much. I used Freaks many years ago and was always impressed by the quality and knowledge of the people here. Only showing one link per day is fine. Again thanks !!!

Case closed.

Hello; good morning Barand. I have one more question, the answer to which I fear will be no but will ask anyway. When viewing my blog; if the Prev arrow is clicked which gives the month of November the articles for Nov. are shown on the calendar. If a linked day is then clicked it pulls up that article in the center column as it should however; the calendar display defaults back to the current month so only one link can be clicked in Prev mode. Question: Is there anyway to make the calendar stay on the Prev month? If the answer is yes then I realize it probably entails using jQuery somehow. but I would have no idea how to implement that coding.

try this version

<?php
const HOST     = 'localhost';                                                              #####
const USERNAME = '????';                                                                       #
const PASSWORD = '????';                                                                       #
const DATABASE = '????';                                                                       #     These lines would
                                                                                               #
function pdoConnect($dbname=DATABASE)                                                          #     normally be in
{                                                                                              #
    $db = new PDO("mysql:host=".HOST.";dbname=$dbname;charset=utf8",USERNAME,PASSWORD);        #     an included file
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);                              #
    $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);                         #
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);                                      #
    return $db;                                                                                #
}                                                                                          #####

/*********************************      TEST DATA      *****************************************
+---------+----------+------------+------------+----------+----------+------------+--------+
| post_id | topic_id | post_title | post_body  | post_img | post_thb | posted     | active |
+---------+----------+------------+------------+----------+----------+------------+--------+
|       1 |     NULL | Blog 1     | Blog one   | NULL     |     NULL | 1605398400 |   NULL |
|       2 |     NULL | Blog 2     | Blog two   | NULL     |     NULL | 1607299200 |   NULL |
|       3 |     NULL | Blog 3     | Blog three | NULL     |     NULL | 1607385600 |   NULL |
|       4 |     NULL | Blog 4     | Blog four  | NULL     |     NULL | 1608508800 |   NULL |
|       5 |     NULL | Blog 5     | Blog five  | NULL     |     NULL | 1608508800 |   NULL |
|       6 |     NULL | Blog 6     | Blog six   | NULL     |     NULL | 1609545600 |   NULL |
+---------+----------+------------+------------+----------+----------+------------+--------+
*************************************************************************************************/

$pdo = pdoConnect();

$today = new DateTime( $_GET['date'] ?? '' );
$prev = (clone $today)->modify('-1 month')->format('Y-m-d');
$next = (clone $today)->modify('+1 month')->format('Y-m-d');

$caption = $today->format('F Y');
$this_month =  $today->format('n');

$day1 = (clone $today)->modify("first day of this month");
$queryStart = $day1->format('Y-m-d');
if ($day1->format('w') != 0) {
    $day1->modify('last Sunday');
}
$dayN = (clone $today)->modify('last day of this month');
$queryEnd = $dayN->format('Y-m-d');
if ($dayN->format('w') != 6) {
    $dayN->modify('next sunday');
}
$period = new DatePeriod($day1, new DateInterval('P1D'), $dayN);                // calendar display dates

##
##  get this month's blogs
##
$blogs = [];
$res = $pdo->prepare("SELECT post_id
                             , date(from_unixtime(posted)) as day   
                             , post_title
                        FROM DB_GRIMS_BLOG_POST
                        WHERE date(from_unixtime(posted)) BETWEEN ? AND ?
                        ORDER BY posted 
                        ");
$res->execute( [ $queryStart, $queryEnd ] );
foreach ($res as $r) {
    if (!isset($blogs[$r['day']])) {
    $blogs[$r['day']] = [];
    }
    $blogs[$r['day']][] = $r;
}

##
##  Functions
##

function calheads()
{
    $out = '<tr>';
    $days = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ];
    foreach ($days as $d) {
        $out .= "<th abbr='$d' title='$d'>{$d[0]}</th>";
    }
    return $out;
}

function caldata($per, $mth, &$blogs, $date)
{
    $i = 0;
    $out = '';
    foreach ($per as $d) {
        if ($i%7 == 0) {
            if ($out != '') $out .= "</tr>\n";
            $out .= "<tr>";
        }
        ++$i;
        $dno = $d->format('d');
        $cls = $link = $title = $datablog = '';
        $dbArr = [];
        if ($d->format('n') != $mth) {
            $cls .= 'blank ';
        } else {
            $cls .= 'daycell ';
            if ($d->format('Y-m-d') == date('Y-m-d')) $cls .= 'today ';
            if (isset($blogs[$d->format('Y-m-d')])) {
                $dayblogs = $blogs[$d->format('Y-m-d')];
                $cls .= 'active ';
                if (count($dayblogs)==1) {
                    $title = $blogs[$d->format('Y-m-d')][0]['post_title'];
                    $dno = "<a href='https://whisperwillow.net/infusions/grims_blog/filtered.php?post_id={$blogs[$d->format('Y-m-d')][0]['post_id']}&date=$date'>$dno</a>";
                }
                else {
                    $title = join("\n", array_column($dayblogs,'post_title'));
                    $cls .= 'multiblog ';
                    foreach ($dayblogs as $dba) {
                        $dbArr[$dba['post_id']] = $dba['post_title'];
                    }
                    $datablog = json_encode($dbArr);
                }
            }
        }
        
        $out .= "<td class='$cls' title='$title' data-blogs='$datablog'>$dno</td>\n";
    }
    $out .= "</tr>\n";
    return $out;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-language" content="en">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Examle calendar</title>
<meta name="creation-date" content="12/06/2020">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type='text/javascript'>

    $().ready( function() {
        
        $(".multiblog").click( function() {
            var blogs =  $(this).data('blogs')
            var date = $("#cal-date").val()
            $("#blogmenu").hide()
            $("#blogmenu").position({"Top":0, "Left":0})
            $("#blogmenu").html("<b>Select blog:</b><br>")
            $.each(blogs, function(k,v) {
                $("#blogmenu").append("<p><a href='https://whisperwillow.net/infusions/grims_blog/filtered.php?post_id="+k+"&date="+date+"'>"+v+"</a></p>")
            })
            var pos = $(this).position()
            
            $("#blogmenu").css("display","inline-block")
            $("#blogmenu").offset( {"top": pos.top+25, "left": pos.left} )
        })
        
        $("#blogmenu").click( function() {
            $("#blogmenu").html("<b>Select blog:</b><br>")
            $("#blogmenu").hide()
            $("#blogmenu").position({"Top":0, "Left":0})
        })
    })
    
</script>
<style type='text/css'>
    body, table {
        font-family: arial, sans-serif;
        font-size: 14px;
    }
    table {
        border-collapse: collapse;
        width: 63%;
        margin: 50px auto;
    }
    caption {
        background-color: #A91723;
        color: #FFF;
        padding: 5px;
        text-align: center;
        font-size: 16px; 
    }
    th {
        background-color: #5F8874;
        color: #FFF;
        padding: 2px;
    }
    td {
        background-color: #000;
        color: #FFF;
        padding: 2px;
        text-align: center;
        font-weight: 600;
        height: 22px;
    }
    td.active {
        background-color: #e3e3e3;
        color: #0000FC;
    }
    td.blank {
        background-color: #CCC;
        color: #FFF;
    }
    td.today {
        background-color: #07ABF6;
    }
    a {
        text-decoration: none;;
    }
    a:hover {
        text-decoration: underline;;
    }
    #navbtn1, #navbtn2 {
        font-weight: 600;
        color: #FFF;
        text-decoration: none;
    }
    #navbtn1 {
        float: left;
    }
    #navbtn2 {
        float: right;
    }
    #blogmenu {
        display: none;
        font-size: 14px;
        position: absolute;
        top: 0;
        left: 0;
        max-width: 200px;
        background-color: #FCF8E8;
        color: #000;
        padding: 4px;
        border: 2px solid #006EFC;
    }
    .multiblog {
        cursor: pointer;
    }
</style>
</head>
<body>
    <input type='hidden' id='cal-date' value='<?=$today->format('Y-m-d')?>'>
    <table border='1'>
        <caption>
            <a id='navbtn1' href='?date=<?=$prev?>'>&lt;</a>
            <?=$caption?>
            <a id='navbtn2' href='?date=<?=$next?>'>&gt;</a>
        </caption>
        <thead>
            <?=calheads()?>
        </thead>
        <tbody>
            <?=caldata($period, $this_month, $blogs, $today->format('Y-m-d'))?>
        </tbody>
    </table>
    <div id='blogmenu'></div>
</body>
</html>

 

Doesn't quite work yet. Error code:

[10-Dec-2020 16:28:41 Europe/London] PHP Parse error:  syntax error, unexpected '").click( function() {
 (T_CONSTANT_ENCAPSED_STRING), expecting ',' or ';' in /home/whisperw/public_html/infusions/grims_blog/index.php on line 42

This is my new index.php file:

<?php
/*-------------------------------------------------------+
| PHP-Fusion Content Management System
| Copyright © 2002 - 2014 Nick Jones
| http://www.php-fusion.co.uk/
+--------------------------------------------------------+
| Filename: index.php
| Copyright © 2020 Grimloch
| https://www.whisperwillow.com
+--------------------------------------------------------+
| This program is released as free software under the
| Affero GPL license. You can redistribute it and/or
| modify it under the terms of this license which you
| can read by viewing the included agpl.txt or online
| at www.gnu.org/licenses/agpl.html. Removal of this
| copyright header is strictly prohibited without
| written permission from the original author(s).
+--------------------------------------------------------*/
require_once "../../maincore.php";
include INFUSIONS."grims_blog/infusion_db.php";
if (file_exists(INFUSIONS."grims_blog/locale/".$settings['locale'].".php")) {
	include INFUSIONS."grims_blog/locale/".$settings['locale'].".php";
} else {
	include INFUSIONS."grims_blog/locale/English.php";
}
echo "<!DOCTYPE html>\n";
echo "<html>\n";
echo "<head>\n";
echo "<title>".$locale['gb_200']."</title>\n";
echo "<meta content='text/html'>\n";
echo "<meta charset='UTF-8' />\n";
echo "<meta name='viewport' content='width=device-width, initial-scale=1'>\n";
echo "<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css'>\n";
echo "<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>\n";
echo "<script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js'></script>\n";
echo "<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js'></script>\n";
echo "<link rel='stylesheet' href='".INFUSIONS."grims_blog/css/public_styles.css' type='text/css' />\n";
echo "<script type='text/javascript'>
    $().ready( function() {
        $(".multiblog").click( function() {
            var blogs =  $(this).data('blogs')
            var date = $("#cal-date").val()
            $("#blogmenu").hide()
            $("#blogmenu").position({"Top":0, "Left":0})
            $("#blogmenu").html("<b>Select blog:</b><br>")
            $.each(blogs, function(k,v) {
                $("#blogmenu").append("<p><a class='lnkc' href='../grims_blog/filtered.php?post_id="+k+"&date="+date+"'>"+v+"</a></p>")
            })
            var pos = $(this).position()
            $("#blogmenu").css("display","inline-block")
            $("#blogmenu").offset( {"top": pos.top+25, "left": pos.left} )
        })
        $("#blogmenu").click( function() {
            $("#blogmenu").html("<b>Select blog:</b><br>")
            $("#blogmenu").hide()
            $("#blogmenu").position({"Top":0, "Left":0})
        })
    })
</script>\n";
echo "</head>\n";
echo "<body>\n";
echo "<div id='wrapper'>\n";
echo "<div id='head'>\n";
	include INFUSIONS."grims_blog/include/header.php";
echo "</div>\n";
echo "<div class='row'>\n";
echo "<div class='col-sm-9'>\n";
echo "<div id='card-left'>\n";
echo "<div align='center'><h4><span style='color:#B83C32;'><b><u>Current Month Blogs</u></b></span></h4></div>\n";
$result = dbquery("SELECT * FROM ".DB_GRIMS_BLOG_POST." WHERE active='1' AND MONTH(post_date) = MONTH(CURDATE()) ORDER BY post_date DESC");
if (dbrows($result)) {
$cnt = 0;
	while($data = dbarray($result)) {
	$post_id = $data['post_id'];
	$topic_id = $data['topic_id'];
	$title = $data['post_title'];
	$content = $data['post_body'];
	$image = $data['post_img'];
	$thumb = $data['post_thb'];
	$timestamp = strtotime($data['post_date']);
		$result1 = dbquery("SELECT * FROM ".DB_GRIMS_BLOG_TOPICS." WHERE topic_id='$topic_id'");
			list($topic_id, $topic_title) = dbarraynum($result1);
		$id = $topic_id;
		$name = $topic_title;
			$result2 = dbquery("SELECT * FROM ".DB_GRIMS_BLOG_COMMENTS." WHERE post_id='$post_id' AND topic_id='$topic_id'");
			$num_rows = mysql_num_rows($result2);
echo "<a class='cats' href='filtered.php?post_id=".$post_id."'>$title</a><br />\n";
if ($image) {
echo "<span><img src='".THBPATH."$thumb' style='max-width:100%;height:auto;'></span><br />\n";
}
echo "<span class='cmnt-lnk'>".$locale['gb_201']."<a class='tpic-lnk' href='topics_page.php?topic_id=".$id."'>$name</a> on ".date("F d, Y", $timestamp)."</span><br />\n";
echo "<table cellpadding='5'><tr><td bgcolor='#fff'><table width='100%' cellpadding='8' border='0'>\n";
echo "<tr><td style='padding:5px; font-size:16px;'>".html_entity_decode(stripslashes($content))."</td></tr>\n";
echo "<tr><td style='background:#fff; padding:5px; font-size:16px;'><span class='info'><b><a class='tpic-lnk' href='comments.php?post_id=".$post_id."'>".$locale['gb_215']."</a> ($num_rows)</b></span></td></tr>\n";
echo "</table></td></tr></table><p></p>\n";
	}
$cnt++;
}
echo "</div></div>\n";
echo "<div class='col-sm-3'>\n";
echo "<div id='card-rite'>\n";
	include INFUSIONS."grims_blog/include/calendar.php";
echo "</div>\n";
echo "<div id='card-rite'>\n";
	include INFUSIONS."grims_blog/include/topics.php";
echo "</div>\n";
echo "<div id='card-rite'>\n";
	include INFUSIONS."grims_blog/include/latest_blogs.php";
echo "</div>\n";
echo "<div id='card-rite'>\n";
	include INFUSIONS."grims_blog/include/latest_comments.php";
echo "</div>\n";
echo "</div></div>\n";
	include INFUSIONS."grims_blog/include/footer.php";
echo "</div>\n";
echo "</body>\n";
echo "</html>\n";
?>

And this is my new calendar.php file:

<?php
include"cal_config.php";

$pdo = pdoConnect();

$today = new DateTime( $_GET['date'] ?? '' );
$prev = (clone $today)->modify('-1 month')->format('Y-m-d');
$next = (clone $today)->modify('+1 month')->format('Y-m-d');

$caption = $today->format('F Y');
$this_month =  $today->format('n');

$day1 = (clone $today)->modify("first day of this month");
$queryStart = $day1->format('Y-m-d');
if ($day1->format('w') != 0) {
    $day1->modify('last Sunday');
}
$dayN = (clone $today)->modify('last day of this month');
$queryEnd = $dayN->format('Y-m-d');
if ($dayN->format('w') != 6) {
    $dayN->modify('next sunday');
}
$period = new DatePeriod($day1, new DateInterval('P1D'), $dayN);                // calendar display dates

##  get this month's blogs
$blogs = [];
$res = $pdo->prepare("SELECT post_id
                           , post_date as day
                           , post_title
                      FROM ".DB_GRIMS_BLOG_POST."
                      WHERE post_date BETWEEN ? AND ?
                      ORDER BY post_date     
                     ");
$res->execute( [ $queryStart, $queryEnd ] );
foreach ($res as $r) {
    if (!isset($blogs[$r['day']])) {
    $blogs[$r['day']] = [];
    }
    $blogs[$r['day']][] = $r;
}

##  Functions
function calheads()
{
    $out = '<tr>';
    $days = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ];
    foreach ($days as $d) {
        $out .= "
		<th style='text-align:center; color:yellow;' abbr='$d' title='$d'>{$d[0]}</th>";
    }
    return $out;
}
function caldata($per, $mth, &$blogs)
{
    $i = 0;
    $out = '';
    foreach ($per as $d) {
        if ($i%7 == 0) {
            if ($out != '') $out .= "</tr>\n";
            $out .= "<tr>";
        }
        ++$i;
        $dno = $d->format('d');
        $cls = $link = $title = $datablog = '';
        $dbArr = [];
        if ($d->format('n') != $mth) {
            $cls .= 'blank ';
        } else {
            $cls .= 'daycell ';
            if ($d->format('Y-m-d') == date('Y-m-d')) $cls .= 'today ';
            if (isset($blogs[$d->format('Y-m-d')])) {
                $dayblogs = $blogs[$d->format('Y-m-d')];
                $cls .= 'active ';
                if (count($dayblogs)==1) {
                    $title = $blogs[$d->format('Y-m-d')][0]['post_title'];
                    $dno = "<a class='lnkc' href='../grims_blog/filtered.php?post_id={$blogs[$d->format('Y-m-d')][0]['post_id']}&date=$date'>$dno</a>";
                }
                else {
                    $title = join("\n", array_column($dayblogs,'post_title'));
                    $cls .= 'multiblog ';
                    foreach ($dayblogs as $dba) {
                        $dbArr[$dba['post_id']] = $dba['post_title'];
                    }
                    $datablog = json_encode($dbArr);
                }
            }
        }
        
        $out .= "<td class='$cls' title='$title' data-blogs='$datablog'>$dno</td>\n";
    }
    $out .= "</tr>\n";
    return $out;
}
echo "<div class='row'>\n";
echo "<table width='100%' border='0'><tr>\n";
echo "<td align='center'><span style='font-size:16px; color:#FCF9B6;'><b>Calendar</b></span><p>\n";
echo "<table width='63%' border='1' cellpadding='5'><tr>\n";
echo "<td bgcolor='#AFAFAF'><table width='100%' cellpadding='4' border='1'><tr>\n";
echo "<td><input type='hidden' id='cal-date' value='$today->format('Y-m-d')'>\n";
echo "<caption style='text-align:center; font-size:16px; background:#B83C32; color:#fff;'><a id='navbtn1' href='?date=$prev'>&laquo;</a>".$caption."<a id='navbtn2' href='?date=$next'>&raquo;</a></caption>\n";
echo "<thead  bgcolor='#005500'>".calheads()."</thead>\n";
echo "<tbody align='center' bgcolor='#000'>".caldata($period, $this_month, $blogs, $today->format('Y-m-d'))."</tbody>\n";
echo "</table></td></tr></table>\n";
echo "</td></tr></table>\n";
echo "<div id='blogmenu'></div>\n";
echo "<br /><br /></div>\n";
?>

So I'm a little confused at this point. All I get is a white screen.

OK got that done but still not working. When I click a date in Prev month the calendar still goes back to Dec. The url in the top is then:

https://whisperwillow.net/infusions/grims_blog/filtered.php?post_id=3&date=

It's not picking up the new date function.

OK... when I do view page source this is what I see:

<link rel='stylesheet' href='../../infusions/grims_blog/css/public_styles.css' type='text/css' />
0</head>
<body>

See the zero before </head> ? It's not loading the script for some reason.

I've made a skeleton mockup of your "filtered.php" which works with this version of my code  included in it.

blog_filtered.php

<?php
include 'db_inc.php';
$pdo = pdoConnect('test');

$post_id = $_GET['post_id'] ?? 0;

$res = $pdo->prepare("SELECT post_title
                           , post_body
                           , date_format(from_unixtime(posted), '%D %M %Y at %l:%i %p') as posted
                      FROM db_grims_blog_post
                      WHERE post_id = ?     
                     ");
$res->execute([$post_id]);
$blog = $res->fetch();

$title = $blog['post_title'] ?? '';
$posted = $blog['posted'] ?? '';
$content = $blog['post_body'] ?? '';
    
?>
<!DOCTYPE html>
<html lang="en">
<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>
</head>
<body>
<div class='w3-container w3-black'>
    <div class="w3-row-padding">
        <div class='w3-col m9'>
            <div class='w3panel w3-yellow w3-padding'>
                <h3><?=$title?></h3><br>
                <h6><?=$posted?></h6>
            </div>
            <div class='w3-container'>
                <p><?=$content?></p>
            </div>
        </div>
        <div class='w3-col m3'>
            <?php include 'blog_calendar.php' ?>
        </div>
    </div>
</div>
</body>
</html>

blog_calendar.php

<?php
// include 'db_inc.php';
$pdo = pdoConnect();

$today = new DateTime( $_GET['date'] ?? '' );
$prev = (clone $today)->modify('-1 month')->format('Y-m-d');
$next = (clone $today)->modify('+1 month')->format('Y-m-d');

$caption = $today->format('F Y');
$this_month =  $today->format('n');

$day1 = (clone $today)->modify("first day of this month");
$queryStart = $day1->format('Y-m-d');
if ($day1->format('w') != 0) {
    $day1->modify('last Sunday');
}
$dayN = (clone $today)->modify('last day of this month');
$queryEnd = $dayN->format('Y-m-d');
if ($dayN->format('w') != 6) {
    $dayN->modify('next sunday');
}
$period = new DatePeriod($day1, new DateInterval('P1D'), $dayN);                // calendar display dates

##
##  get this month's blogs
##
$blogs = [];
$res = $pdo->prepare("SELECT post_id
                             , date(from_unixtime(posted)) as day   
                             , post_title
                        FROM DB_GRIMS_BLOG_POST
                        WHERE date(from_unixtime(posted)) BETWEEN ? AND ?
                        ORDER BY posted 
                        ");
$res->execute( [ $queryStart, $queryEnd ] );
foreach ($res as $r) {
    if (!isset($blogs[$r['day']])) {
    $blogs[$r['day']] = [];
    }
    $blogs[$r['day']][] = $r;
}

##
##  Functions
##

function calheads()
{
    $out = '<tr>';
    $days = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ];
    foreach ($days as $d) {
        $out .= "<th abbr='$d' title='$d'>{$d[0]}</th>";
    }
    return $out;
}

function caldata($per, $mth, &$blogs, $date)
{
    $i = 0;
    $out = '';
    foreach ($per as $d) {
        if ($i%7 == 0) {
            if ($out != '') $out .= "</tr>\n";
            $out .= "<tr>";
        }
        ++$i;
        $dno = $d->format('d');
        $cls = $link = $title = $datablog = '';
        $dbArr = [];
        if ($d->format('n') != $mth) {
            $cls .= 'blank ';
        } else {
            $cls .= 'daycell ';
            if ($d->format('Y-m-d') == date('Y-m-d')) $cls .= 'today ';
            if (isset($blogs[$d->format('Y-m-d')])) {
                $dayblogs = $blogs[$d->format('Y-m-d')];
                $cls .= 'active ';
                if (count($dayblogs)==1) {
                    $title = $blogs[$d->format('Y-m-d')][0]['post_title'];
                    $dno = "<a href='blog_filtered.php?post_id={$blogs[$d->format('Y-m-d')][0]['post_id']}&date=$date'>$dno</a>";
                }
                else {
                    $title = join("\n", array_column($dayblogs,'post_title'));
                    $cls .= 'multiblog ';
                    foreach ($dayblogs as $dba) {
                        $dbArr[$dba['post_id']] = $dba['post_title'];
                    }
                    $datablog = json_encode($dbArr);
                }
            }
        }
        
        $out .= "<td class='$cls' title='$title' data-blogs='$datablog'>$dno</td>\n";
    }
    $out .= "</tr>\n";
    return $out;
}
?>
<!--
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-language" content="en">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Example calendar</title>
<meta name="creation-date" content="12/06/2020">
-->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type='text/javascript'>

    $().ready( function() {
        
        $(".multiblog").click( function() {
            var blogs =  $(this).data('blogs')
            var date = $("#cal-date").val()
            $("#blogmenu").hide()
            $("#blogmenu").position({"Top":0, "Left":0})
            $("#blogmenu").html("<b>Select blog:</b><br>")
            $.each(blogs, function(k,v) {
//                $("#blogmenu").append("<p><a href='https://whisperwillow.net/infusions/grims_blog/filtered.php?post_id="+k+"&date="+date+"'>"+v+"</a></p>")
                $("#blogmenu").append("<p><a href='blog_filtered.php?post_id="+k+"&date="+date+"'>"+v+"</a></p>")
            })
            var pos = $(this).position()
            
            $("#blogmenu").css("display","inline-block")
            $("#blogmenu").offset( {"top": pos.top+25, "left": pos.left} )
        })
        
        $("#blogmenu").click( function() {
            $("#blogmenu").html("<b>Select blog:</b><br>")
            $("#blogmenu").hide()
            $("#blogmenu").position({"Top":0, "Left":0})
        })
    })
    
</script>
<style type='text/css'>
    body, table {
        font-family: arial, sans-serif;
        font-size: 14px;
    }
    table {
        border-collapse: collapse;
        width: 63%;
        margin: 50px auto;
    }
    caption {
        background-color: #A91723;
        color: #FFF;
        padding: 5px;
        text-align: center;
        font-size: 16px; 
    }
    th {
        background-color: #5F8874;
        color: #FFF;
        padding: 2px;
    }
    td {
        background-color: #000;
        color: #FFF;
        padding: 2px;
        text-align: center;
        font-weight: 600;
        height: 22px;
    }
    td.active {
        background-color: #e3e3e3;
        color: #0000FC;
    }
    td.blank {
        background-color: #CCC;
        color: #FFF;
    }
    td.today {
        background-color: #07ABF6;
    }
    a {
        text-decoration: none;;
    }
    a:hover {
        text-decoration: underline;;
    }
    #navbtn1, #navbtn2 {
        font-weight: 600;
        color: #FFF;
        text-decoration: none;
    }
    #navbtn1 {
        float: left;
    }
    #navbtn2 {
        float: right;
    }
    #blogmenu {
        display: none;
        font-size: 14px;
        position: absolute;
        top: 0;
        left: 0;
        max-width: 200px;
        background-color: #FCF8E8;
        color: #000;
        padding: 4px;
        border: 2px solid #006EFC;
    }
    .multiblog {
        cursor: pointer;
    }
</style>
<!--
</head>
<body>
-->
    <input type='hidden' id='cal-date' value='<?=$today->format('Y-m-d')?>'>
    <table border='1'>
        <caption>
            <a id='navbtn1' href='?date=<?=$prev?>'>&lt;</a>
            <?=$caption?>
            <a id='navbtn2' href='?date=<?=$next?>'>&gt;</a>
        </caption>
        <thead>
            <?=calheads()?>
        </thead>
        <tbody>
            <?=caldata($period, $this_month, $blogs, $today->format('Y-m-d'))?>
        </tbody>
    </table>
    <div id='blogmenu'></div>
<!--
</body>
</html>
-->

 

  • Solution

Check out my blog site when you get a chance Barand. Everything now works correctly. I have a friend that lives in California and we, together developed this blog and calendar. He has been working on it on his localhost setup on his computer. He took your calendar code as is and it works correctly on his computer so he sent me his calendar.php file to test on my live system and it works beautifully !!! I made the mistake of trying to split things up too much. (old habits die hard)... at any rate this project is now truly complete with all aims accomplished. Thank you so very much Barand. We really appreciate all your hard work. I wish my php skills were anywhere near your skill level.

I've been helping OldGrim with the calendar module for out blog and have come up with a problem. The calendar is working great except for this and I'm wondering if it is supposed to be like this or not.  When you click on the arrow to go to the previous month, and click on an active date, the article is displayed as it should be but if you then click the arrow to return to the next month (from whatever month you are in),  there is no display in the left hand panel.  If you check it out on OldGrim's site, you will see what I mean.  If it supposed to be like that, then so be it, but  I thought I would check.  Here is his url:  Blog Calendar

Thanks.

1 hour ago, metroman90210 said:

If it supposed to be like that, then so be it,

There was no specification of how it's supposed to be. I just threw in the ability to change the month as an extra. If you want it to behave differently, change it.

 

3 hours ago, OldGrim said:

this project is now truly complete with all aims accomplished.

 

Edited by Barand

One final note:

We did change it Barand, When any previous month is selected and then an active date in that month is clicked, instead of 'filtered.php' it now pulls up our 'archive_files.php' then from there the month archive desired is clicked. Our little problem is now solved and our calendar scripts, indeed the entire blog system is now ready for production.

Thanks once again for all your help.

😉

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.