Simple Machines Community Forum

General Community => Scripting Help => Topic started by: shinglis on January 07, 2022, 02:27:07 PM

Title: Different domain - display latest posts.
Post by: shinglis on January 07, 2022, 02:27:07 PM
Ok for background I have some basic html knowledge but very limited when it comes to pho and databases.

I would like to create a holding page ( advertising page) on a different domain, showing the latest posts from the forum.

Maybe try to make it clear, what I'm looking to do;
Domain A - single simple page showing forum latest posts which is on domain B.

So would like to know, is it easy to do? Any security issues? I have full control over both domains under the same hosting account and know all the relevant database security info. (Server up, username, password etc)

Thanks in advance for any assistance.
Title: Re: Different domain - display latest posts.
Post by: Chen Zhen on January 07, 2022, 04:56:14 PM

Yes you can make use of SSI.php to display a basic table containing latest posts.
This table can be displayed on the other forum/page as is or you can develop your own DOM parser to gather the data & display it as you wish.

example:
https://www.simplemachines.org/community/SSI.php?ssi_function=recentPosts;
Title: Re: Different domain - display latest posts.
Post by: Kindred on January 07, 2022, 04:58:53 PM
The issue is doing it on a different domain.
Title: Re: Different domain - display latest posts.
Post by: shinglis on January 07, 2022, 05:03:07 PM
Thanks, due to the different domain, would display RSS be easier or just use iframe ?
Title: Re: Different domain - display latest posts.
Post by: Kindred on January 07, 2022, 05:13:01 PM
Iframes are poor design,these days,  and potentially insecure
Title: Re: Different domain - display latest posts.
Post by: Chen Zhen on January 07, 2022, 07:44:25 PM
There is no issue using the DOM parser for a page scrape of a SMF forum from a different domain.
The output from SSI.php is very basic so there's not much to parse.

Example:
$html = file_get_contents('https://www.simplemachines.org/community/SSI.php?ssi_function=recentPosts;xml;');
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($html);
$tables = $dom->getElementsByTagName('table');
$rows = $tables->item(0)->getElementsByTagName('tr');
echo '
        <div style="width: 100%;overflow: hidden;">
            <div style="width: 100%;text-align: center;margin: 0 auto;color: blue;font-size: 1.5em;text-decoration: underline;padding: 1em;">SIMPLE MACHINES FORUM - LATEST POSTS</div>';
foreach ($rows as $row) {
    $cols = $row->getElementsByTagName('td');
    list($topicLinks, $num) = array($cols->item(1)->getElementsByTagName('a'), 0);
    foreach($topicLinks as $topicLink) {
        $topicAtt[$num] = array($topicLink->nodeValue, '<a href="' . $topicLink->getAttribute('href') . '">' . $topicLink->nodeValue . '</a>');
        $num++;
    }

    $topic = $cols->item(1)->nodeValue;
    $topic = str_replace($topicAtt[0][0], $topicAtt[0][1], $topic);
    $topic = str_replace($topicAtt[1][0], $topicAtt[1][1], $topic);
    echo '
            <div>Board: <a href="' . $cols->item(0)->getElementsByTagName('a')->item(0)->getAttribute('href') . '">'.$cols->item(0)->nodeValue.'</a></div>
            <div>Topic: '.$topic.'</div>
            <div>Date: '.$cols->item(2)->nodeValue . '</div>
            <hr />';
}
echo '
        </div>';
Title: Re: Different domain - display latest posts.
Post by: Arantor on January 08, 2022, 04:46:45 AM
But why would you do that when you can literally just call SSI.php directly with a function name in the URL (because this is how the SHTML version works)?
Title: Re: Different domain - display latest posts.
Post by: Chen Zhen on January 09, 2022, 02:24:20 PM
I'm not sure if you were referring to my post but that's exactly what the code I wrote will do. It just allows the admin/user to display it as they wish.
Title: Re: Different domain - display latest posts.
Post by: Arantor on January 09, 2022, 03:35:44 PM
Yes, I see what you're doing, you're calling it the really really roundabout way and building/parsing a DOM tree off the back of it.

Instead of, say, just calling it and including it directly, as it comes by default in an HTML fragment such as https://www.simplemachines.org/community/SSI.php?ssi_function=recentTopics and *just using it* as is.
Title: Re: Different domain - display latest posts.
Post by: Chen Zhen on January 09, 2022, 03:47:28 PM
Yes the default display of that HTML table is fine as it is if someone wants it like that. I figure people will likely want to have it display as they wish so using the DOM parser allows that.
Title: Re: Different domain - display latest posts.
Post by: shinglis on January 10, 2022, 05:10:27 PM
Thanks for the comments and feedback the ssi code is exactly what I'm looking for.
Title: Re: Different domain - display latest posts.
Post by: Chen Zhen on January 10, 2022, 09:39:07 PM

Great, glad to hear that works for you.

Below is another example but also changing the time format (just for kicks):

$changeTimeFormat = true;
$timeFormat = array('search' => 'F d, Y', 'old' => 'F d, Y, h:i:s A', 'new' => 'Y-m-d');
$html = file_get_contents('https://www.simplemachines.org/community/SSI.php?ssi_function=recentPosts');
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($html);
$tables = $dom->getElementsByTagName('table');
$rows = $tables->item(0)->getElementsByTagName('tr');
echo '
<div style="width: 100%;overflow: hidden;">
<div style="width: 100%;text-align: center;margin: 0 auto;color: blue;font-size: 1.5em;text-decoration: underline;padding: 1em;">SIMPLE MACHINES FORUM - LATEST POSTS</div>';
foreach ($rows as $row) {
$cols = $row->getElementsByTagName('td');
$topic = $cols->item(1)->nodeValue;
$topicLinks = $cols->item(1)->getElementsByTagName('a');
// %B %d, %Y, %I:%M:%S %p
$date = trim($cols->item(2)->nodeValue);
$date = preg_replace("/[^A-Za-z0-9,:\s]/", '', $date);
if (!empty($changeTimeFormat)) {
if (stripos($date, 'today') !== FALSE) {
$timestamp = strtotime('today');
$today = date($timeFormat['search'], $timestamp);
$date = str_ireplace('today at', $today . ',', $date);
}
elseif (stripos($date, 'yesterday') !== FALSE) {
$timestamp = strtotime('yesterday');
$today = date($timeFormat['search'], $timestamp);
$date = str_ireplace('yesterday at', $today . ',', $date);
}

$myDateTime = date_create_from_format($timeFormat['old'], $date);
$date = date_format($myDateTime, $timeFormat['new']);
}

foreach($topicLinks as $topicLink) {
$topic = str_replace($topicLink->nodeValue, '<a href="' . $topicLink->getAttribute('href') . '">' . $topicLink->nodeValue . '</a>', $topic);
}

echo '
<div>Board: <a href="' . $cols->item(0)->getElementsByTagName('a')->item(0)->getAttribute('href') . '">'.$cols->item(0)->nodeValue . '</a></div>
<div>Topic: ' . $topic . '</div>
<div>Date: ' . $date . '</div>
<hr />';
}
echo '
</div>';

The time format parameters for the output of the above are here:
PHP.net: date_create_from_format() (https://www.php.net/manual/en/datetime.createfromformat.php)



You can also do the whole thing in JavaScript using setInterval() which would allow an auto-refresh.