how to make ssi_boardNews shows attachment?

Started by sinbad, November 23, 2004, 11:16:01 AM

Previous topic - Next topic

sinbad

as my board is already show attachment to guest (everyone)
how could I possibly get the attachment shown from 'ssi_boardNews'?
please help

[Unknown]

This would mean more than a little bit of modification, but it could be done....

Do you know any PHP?

-[Unknown]

sinbad

Yes, I know PHP quite well and I don't mind any modification
Can I steal some functions from somewhere?
e.g. require(anything); and run some functions() to show attachment?

thanks [Unknown] for your help/reply

[Unknown]

Well, the basic idea is simple.

// Find the posts.
$request = db_query("
SELECT
m.icon, m.subject, m.body, IFNULL(mem.realName, m.posterName) AS posterName, m.posterTime,
t.numReplies, t.ID_TOPIC, m.ID_MEMBER, m.smileysEnabled
FROM {$db_prefix}topics AS t, {$db_prefix}messages AS m
LEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = m.ID_MEMBER)
WHERE t.ID_BOARD = $board
AND m.ID_MSG = t.ID_FIRST_MSG
ORDER BY m.ID_MSG DESC
LIMIT $start, $limit", __FILE__, __LINE__);
$return = array();
while ($row = mysql_fetch_assoc($request))
{


The above query finds all messages that are first posts in the specified board, and adds them to an array.  We're going to want to add the attachment information to this array after this for, but first we need to get the ID_MSG information to even get the attachments.

So, first, this means adding m.ID_MSG to the first list of columns, after m.smileysEnabled.  Then, we need an array, so we should start an array off before the loop, like so:

// Find the posts.
$request = db_query("
SELECT
m.icon, m.subject, m.body, IFNULL(mem.realName, m.posterName) AS posterName, m.posterTime,
t.numReplies, t.ID_TOPIC, m.ID_MEMBER, m.smileysEnabled, m.ID_MSG
FROM {$db_prefix}topics AS t, {$db_prefix}messages AS m
LEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = m.ID_MEMBER)
WHERE t.ID_BOARD = $board
AND m.ID_MSG = t.ID_FIRST_MSG
ORDER BY m.ID_MSG DESC
LIMIT $start, $limit", __FILE__, __LINE__);
$return = array();
$message_ids = array();
while ($row = mysql_fetch_assoc($request))
{
$message_ids[] = $row['ID_MSG'];


Beautiful... now we have all the message ids.  The next step is to select the actual attachments, and add them to the $return array.  So, after this snippet:

if (empty($return))
return $return;


We want this:

// Find their attachments.
$request = db_query("
SELECT ID_ATTACH, ID_MSG, filename, size, downloads
FROM {$db_prefix}attachments
WHERE ID_MSG IN (" . implode(', ', $message_ids) . ")", __FILE__, __LINE__);
while ($row = mysql_fetch_assoc($request))
{
$return[$row['ID_MSG']]['attachments'][] = array(
'name' => $row['filename'],
'downloads' => $row['downloads'],
'size' => round($row['size'] / 1024, 2) . ' ' . $txt['smf211'],
'byte_size' => $row['size'],
'href' => $scripturl . '?action=dlattach;topic=' . $return[$row['ID_MSG']]['id'] . '.0;id=' . $row['ID_ATTACH'],
'link' => ''<a href="' . $scripturl . '?action=dlattach;topic=' . $return[$row['ID_MSG']]['id'] . '.0;id=' . $row['ID_ATTACH'] . '">' . $row['filename'] . '</a>'
);
}
mysql_free_result($request);


We also need the $return array indexed by ID_MSG, so we need to make this:

$return[] = array(

Read, instead:

$return[$row['ID_MSG']] = array(
'attachments' => array(),


(all of this is within that function, of course... there may be other occurances of the code snippets outside it too.)

That should work, in theory.  Of course, the next step is actually displaying the data in the array.  You'll see that, at the end of the function, all the data is echo'd.  All that has to be done is a foreach over $news['attachments'], each value of that array will hold all the important information for the attachment ;).

-[Unknown]

sinbad

yakk, it doesn't work ;(

do you mind paste the full function code?

thanks [Unknown], sorry to bother you many times

[Unknown]

I'm afraid it's hard on me to work "in the dark"; what errors did you get when you tried the above?

-[Unknown]

Reinier

#6
Sorry for bumping this topic up the topic list, but I think I found the error:

Quote'link' => ''<a href="'

should be:

Quote'link' => '<a href="'

So, delete one '

I got the code working now, except that the image is not displayed when I use:

<img src="' . $news[ 'attachments' ][ 0 ][ 'href' ] . '">

When I paste the href in my address bar the board tells me that I am not allowed to open attachments - even though I am logged in as an administrator and I can actually see and open the attachments in the actual message (in the forum, not on the page where the SSI functions are used. So that is my next problem to be solved :)

Edit: adding ;image to the href did the trick! Got it all working now.

Edit2: the modified ssi_boardNews returns an array with one element too many. $limit messages plus one empty element. How can I fix that?

Reinier

ssi)boardNews does not return exactly $limit anymore, with [Unknown]'s modification. Why is that?

loudog

Unknown........ Can you put all this code together in one # box, and some how mark where I would need to make changes to fit my specific board topic ID. I'm not to good with PHP. It would be most appreciated. I have a car of the day page on my regular site, and then on my board I have a guy who post the car of the day seperately. I'd like to just use his post for my regular site, but he uses attachments.  I just wish I had your knowledge on this stuff. I thought I was doing good with HTML back in 95, and then next thing you know we have PHP, CSS, FlASH, XML. It all seemed to happen faster then I could figure it out.

I will donate 5$ to the board for advice if you give me link. I know I'm always asking for help, but its truly appreciated.

Reinier

Okay, well, here we go :)
I changed the funciton ssi_boardNews (in SSI.php) into this: (note: output_method "echo" is not available anymore since I won't use it!)


function ssi_boardNews($board = null, $limit = null, $start = null, $length = null, $output_method = 'echo')
{
global $scripturl, $db_prefix, $txt;
global $settings, $modSettings, $context;

loadLanguage('Stats');

// Must be integers....
if ($limit === null)
$limit = isset($_GET['limit']) ? (int) $_GET['limit'] : 5;
else
$limit = (int) $limit;

if ($start === null)
$start = isset($_GET['start']) ? (int) $_GET['start'] : 0;
else
$start = (int) $start;

if ($board !== null)
$board = (int) $board;
elseif (isset($_GET['board']))
$board = (int) $_GET['board'];

if ($length === null)
$length = isset($_GET['length']) ? (int) $_GET['length'] : 0;
else
$length = (int) $length;

// Make sure guests can see this board.
$request = db_query("
SELECT ID_BOARD
FROM {$db_prefix}boards
WHERE " . ($board === null ? '' : "ID_BOARD = $board
AND ") . "FIND_IN_SET(-1, memberGroups)
LIMIT 1", __FILE__, __LINE__);
if (mysql_num_rows($request) == 0)
{
if ($output_method == 'echo')
die($txt['smf_news_error2']);
else
return array();
}
list ($board) = mysql_fetch_row($request);
mysql_free_result($request);

// Find the posts.
$request = db_query("
SELECT
m.icon, m.subject, m.body, IFNULL(mem.realName, m.posterName) AS posterName, m.posterTime,
t.numReplies, t.ID_TOPIC, m.ID_MEMBER, m.smileysEnabled, m.ID_MSG
FROM {$db_prefix}topics AS t, {$db_prefix}messages AS m
LEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = m.ID_MEMBER)
WHERE t.ID_BOARD = $board
AND m.ID_MSG = t.ID_FIRST_MSG
ORDER BY m.ID_MSG DESC
LIMIT $start, $limit", __FILE__, __LINE__);
$return = array();
$message_ids = array();
while ($row = mysql_fetch_assoc($request))
{
$message_ids[] = $row['ID_MSG'];
// If we want to limit the length of the post.
if (!empty($length) && strlen($row['body']) > $length)
{
$row['body'] = substr($row['body'], 0, $length);

// The first space or line break. (<br />, etc.)
$cutoff = max(strrpos($row['body'], ' '), strrpos($row['body'], '<'));

if ($cutoff !== false)
$row['body'] = substr($row['body'], 0, $cutoff);
$row['body'] .= '...';
}

$row['body'] = doUBBC($row['body'], $row['smileysEnabled']);

censorText($row['subject']);
censorText($row['body']);

  $return[$row['ID_MSG']] = array(
'attachments' => array(),
'id' => $row['ID_TOPIC'],
'icon' => '<img src="' . $settings['images_url'] . '/post/' . $row['icon'] . '.gif" align="middle" alt="' . $row['icon'] . '" />',
'subject' => $row['subject'],
'time' => timeformat($row['posterTime']),
'timestamp' => $row['posterTime'],
'body' => $row['body'],
'href' => $scripturl . '?topic=' . $row['ID_TOPIC'] . '.0',
'link' => '<a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '.0">' . $row['numReplies'] . ' ' . ($row['numReplies'] == 1 ? $txt['smf_news_1'] : $txt['smf_news_2']) . '</a>',
'replies' => $row['numReplies'],
'new_comment' => '<a href="' . $scripturl . '?action=post;topic=' . $row['ID_TOPIC'] . '.' . $row['numReplies'] . '">' . $txt['smf_news_3'] . '</a>',
'poster' => array(
'id' => $row['ID_MEMBER'],
'name' => $row['posterName'],
'href' => !empty($row['ID_MEMBER']) ? $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] : '',
'link' => !empty($row['ID_MEMBER']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] . '">' . $row['posterName'] . '</a>' : $row['posterName']
),
'is_last' => false
);
}
mysql_free_result($request);



if (empty($return))
return $return;

// Find their attachments.

$request = db_query("
SELECT ID_ATTACH, ID_MSG, filename, size, downloads
FROM {$db_prefix}attachments
WHERE ID_MSG IN (" . implode(', ', $message_ids) . ")", __FILE__, __LINE__);
while ($row = mysql_fetch_assoc($request))

{
$return[$row['ID_MSG']]['attachments'][] = array(
'name' => $row['filename'],
'downloads' => $row['downloads'],
'size' => round($row['size'] / 1024, 2) . ' ' . $txt['smf211'],
'byte_size' => $row['size'],
'href' => $scripturl . '?action=dlattach;topic=' . $return[$row['ID_MSG']]['id'] . '.0;id=' . $row['ID_ATTACH'],
'link' => '<a href="' . $scripturl . '?action=dlattach;topic=' . $return[$row['ID_MSG']]['id'] . '.0;id=' . $row['ID_ATTACH'] . '">' . $row['filename'] . '</a>'
);
}
mysql_free_result($request);
return $return;
}


I call the function like this:


$array_boardNews = ssi_boardNews(1.0, 3, null, 250 , 'array');


Which returns an array with the 3 most recent messages from board 1.0, limited to 250 characters each.
Followed by something like this:


foreach ($array_boardNews as $news)
{
$newsImage = '' ;
if( isset( $news[ 'attachments' ][ 0 ] ) )
{
$newsImage = '<img class="news" src="' . $news[ 'attachments' ][ 0 ][ 'href' ] . ';image" alt="' . $news[ 'attachments' ][ 0 ][ 'name' ] . '" title="' . $news[ 'attachments' ][ 0 ][ 'name' ] . '" width="120" height="90"/>' ;
}
echo '
<div class="teaser">
<div class="teasercontent">
<h1 class="news">' . $news['subject'] . '</h1>' . $newsImage . $news['body'] . '
</div>
<div class="teaserfooter">
<p>Posted b: ' . $news['poster']['link'] . ' on ' . $news['time'] . ' | ' . $news['link'] . ' | ' . $news['new_comment'] . '</p>
</div>
</div>
';
}


Note that this displays only 1 attachment (which is what I want). You can easily change the code to display e.g. 3 images.

Hope this helps.

There is still one bug which I have to fix: anonymous visitors can't see the images, even though I gave anonymous users the permission to read attachments.

Remember to include SSI.php in the first line of your script!

tutarm

This sounds great... ..Is it possible to bring the images to the front page of Mambo ?

rakuli

Sorry.
I'm trying to teach myself PHP understand some but not most ';rakuli sits in the corner muttering about functions
This however, gets a bit complicated.
[unknown], could you, or for that matter anyone else, advise how I should change this to make the attachment apear as a simple link to an mp3 file?
This script as seen above works for pics but it also tries to display mp3's as images and thus rendering them useless from the $board_news location.

[Unknown]

Instead of something like this:


if( isset( $news[ 'attachments' ][ 0 ] ) )
{
$newsImage = '<img class="news" src="' . $news[ 'attachments' ][ 0 ][ 'href' ] . ';image" alt="' . $news[ 'attachments' ][ 0 ][ 'name' ] . '" title="' . $news[ 'attachments' ][ 0 ][ 'name' ] . '" width="120" height="90"/>' ;
}


You'd use:


foreach ($news['attachments'] as $file)
$newsImage = '<a href="' . $file['href'] . '">', $file['name'], '</a>';


That should get you the link, at least.

-[Unknown]

rakuli

Quote from: [Unknown] on March 16, 2005, 06:34:37 PM
Instead of something like this:


if( isset( $news[ 'attachments' ][ 0 ] ) )
{
$newsImage = '<img class="news" src="' . $news[ 'attachments' ][ 0 ][ 'href' ] . ';image" alt="' . $news[ 'attachments' ][ 0 ][ 'name' ] . '" title="' . $news[ 'attachments' ][ 0 ][ 'name' ] . '" width="120" height="90"/>' ;
}


You'd use:


foreach ($news['attachments'] as $file)
$newsImage = '<a href="' . $file['href'] . '">', $file['name'], '</a>';


That should get you the link, at least.

-[Unknown]


I can see the idea, but I am not entirely sure where to put it. I tried a few places but got a pass error.
Do I replace
if( isset( $news[ 'attachments' ][ 0 ] ) )
{etc....

with the code below? or add it somewhere.
'Thanks again for your help :)

[Unknown]

Yes, you just replace the code I quoted from the above code with the new code I gave.

-[Unknown]

rakuli

#15
Sorry, I must have been (as usual) tired.  Please try:


$array_boardNews = ssi_boardNews(1.0, 3, null, 250 , 'array');
foreach ($array_boardNews as $news)
{
$newsImage = '' ;
foreach ($news['attachments'] as $file)
$newsImage = '<a href="' . $file['href'] . '">' . $file['name'] . '</a>';

echo '
<div class="teaser">
<div class="teasercontent">
<h1 class="news">' . $news['subject'] . '</h1>' . $newsImage . $news['body'] . '
</div>
<div class="teaserfooter">
<p>Posted b: ' . $news['poster']['link'] . ' on ' . $news['time'] . ' | ' . $news['link'] . ' | ' . $news['new_comment'] . '</p>
</div>
</div>';
}


-[Unknown]

rakuli

Fantastic, I can see there from yesterday how the code has changed and I understand now why it didn't work.

Thanks again for your support. :D :D.

;Rakuli leaps up from the corner in excitement at understanding something about PHP

carbonize

C a r b o n i z e

costanza

I got this working with Reinier's function edit, and I'm using RC1.  It would be so incredibly useful if the vanilla SSI did it though.  Oh yeah I can only get it to return the most recent attachment, it won't do more than 1 attachment per post.  Oh well, might be useful as is, for a while.

evulness

i so want to add this feature to my ssi.php, but i've already made so many changes to my ssi.php
(added alot of mods, and custom edits already...)

i'm not even sure where to begin to get the attachment display into my ssi_boardNews().... i guess i'll compare my function to the one stated to replace the default function... see whats different.
from what i can see so far (at a quick glance) theres alot different from mine, compared to the one Reinier supplied.

Heres MY ssi_boardNews:
function ssi_boardNews($board = null, $limit = null, $start = null, $length = null, $output_method = 'echo')
{
global $scripturl, $db_prefix, $txt, $settings, $modSettings, $context;
global $func;

loadLanguage('Stats');

// Must be integers....
if ($limit === null)
$limit = isset($_GET['limit']) ? (int) $_GET['limit'] : 5;
else
$limit = (int) $limit;

if ($start === null)
$start = isset($_GET['start']) ? (int) $_GET['start'] : 0;
else
$start = (int) $start;

// Was a board passed?
if ($board !== null)
{
// Are we using an array?
if (is_array($board))
{
// Make sure all values are numeric.
foreach ($board as $key => $board_id)
$board[$key] = (int) $board_id;
}
// Otherwise, it's probably a number.
else
{
$board = (int) $board;
}
}
// No board? Check GET variable.
elseif (isset($_REQUEST['board']))
{
// Could it be an array?
// You can pass a comma seperated list of boards, and they'll all be
// used (eg. ?board=1,2,3,4,5).
if (strpos($_REQUEST['board'], ',') !== false)
{
// Split up the string.
$board = explode(',', $_REQUEST['board']);
// Make sure all values are numeric.
foreach ($board as $key => $board_id)
$board[$key] = (int) $board_id;
}
// Probably a number (backwards-compatibility).
else
{
$board = (int) $_REQUEST['board'];
}
}

// WHERE clause in the queries.
$boardQuery = 'ID_BOARD ' . (is_array($board) ? ('IN (' . implode(',', $board) . ')') : ('= ' . $board));

if ($length === null)
$length = isset($_GET['length']) ? (int) $_GET['length'] : 0;
else
$length = (int) $length;

$limit = max(0, $limit);
$start = max(0, $start);

// If no boards were passed, get the first board guests can view
// Otherwise, check if all the passed boards are valid.
$request = db_query("
SELECT ID_BOARD, name
FROM {$db_prefix}boards
WHERE " . ($board === null ? '' : $boardQuery . '
AND ') . 'FIND_IN_SET(-1, memberGroups)
ORDER BY ID_BOARD ASC' . ($board === null ? '
LIMIT 1' : ''), __FILE__, __LINE__);

// No boards? That's bad.
if (mysql_num_rows($request) == 0)
{
if ($output_method == 'echo')
die($txt['smf_news_error2']);
else
return array();
}

$boardInfo = array();
// Empty the board ID array - We're grabbing the IDs from scratch.
unset($board);
$board = array();

// Loop through all returned boards.
while ($row = mysql_fetch_assoc($request))
{
// Add this board to the arrays.
// Board info - Used later on (in the stuff returned)
$boardInfo[$row['ID_BOARD']] = $row;
$board[] = $row['ID_BOARD'];
}
mysql_free_result($request);

// Let's get the new WHERE clause
// Note: The $board array does not need to be sanitised, its data has been
// returned from the database (and is safe).
$boardQuery = 'ID_BOARD IN (' . implode(',', $board) . ')';


// Load the message icons - the usual suspects.
$stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled', 'wireless');
$icon_sources = array();
foreach ($stable_icons as $icon)
$icon_sources[$icon] = 'images_url';

// Find the post ids.
$request = db_query("
SELECT ID_FIRST_MSG
FROM {$db_prefix}topics
WHERE $boardQuery
ORDER BY ID_FIRST_MSG DESC
LIMIT $start, $limit", __FILE__, __LINE__);
$posts = array();
while ($row = mysql_fetch_assoc($request))
$posts[] = $row['ID_FIRST_MSG'];
mysql_free_result($request);

if (empty($posts))
return array();

// Find the posts.
$request = db_query("
SELECT
m.icon, m.subject, m.body, IFNULL(mem.realName, m.posterName) AS posterName, m.posterTime,
t.numReplies, t.ID_TOPIC, m.ID_MEMBER, m.smileysEnabled, m.ID_MSG, t.locked, t.ID_BOARD
FROM ({$db_prefix}topics AS t, {$db_prefix}messages AS m)
LEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = m.ID_MEMBER)
WHERE t.ID_FIRST_MSG IN (" . implode(', ', $posts) . ")
AND m.ID_MSG = t.ID_FIRST_MSG
ORDER BY t.ID_FIRST_MSG DESC
LIMIT " . count($posts), __FILE__, __LINE__);
$return = array();
while ($row = mysql_fetch_assoc($request))
{
// If we want to limit the length of the post.
if (!empty($length) && $func['strlen']($row['body']) > $length)
{
$row['body'] = $func['substr']($row['body'], 0, $length);

// The first space or line break. (<br />, etc.)
$cutoff = max(strrpos($row['body'], ' '), strrpos($row['body'], '<'));

if ($cutoff !== false)
$row['body'] = $func['substr']($row['body'], 0, $cutoff);
$row['body'] .= '...';
}

$row['body'] = parse_bbc($row['body'], $row['smileysEnabled'], $row['ID_MSG']);

// Check that this message icon is there...
if (empty($modSettings['messageIconChecks_disable']) && !isset($icon_sources[$row['icon']]))
$icon_sources[$row['icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['icon'] . '.gif') ? 'images_url' : 'default_images_url';

censorText($row['subject']);
censorText($row['body']);

$return[] = array(
'id' => $row['ID_TOPIC'],
'message_id' => $row['ID_MSG'],
'icon' => '<img src="' . $settings[$icon_sources[$row['icon']]] . '/post/' . $row['icon'] . '.gif" align="middle" alt="' . $row['icon'] . '" border="0" />',
'subject' => $row['subject'],
'time' => timeformat($row['posterTime']),
'timestamp' => forum_time(true, $row['posterTime']),
'body' => $row['body'],
'href' => $scripturl . '?topic=' . $row['ID_TOPIC'] . '.0',
'link' => '<a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '.0">' . $row['numReplies'] . ' ' . ($row['numReplies'] == 1 ? $txt['smf_news_1'] : $txt['smf_news_2']) . '</a>',
'replies' => $row['numReplies'],
'comment_href' => !empty($row['locked']) ? '' : $scripturl . '?action=post;topic=' . $row['ID_TOPIC'] . '.' . $row['numReplies'] . ';num_replies=' . $row['numReplies'],
'comment_link' => !empty($row['locked']) ? '' : '<a href="' . $scripturl . '?action=post;topic=' . $row['ID_TOPIC'] . '.' . $row['numReplies'] . ';num_replies=' . $row['numReplies'] . '">' . $txt['smf_news_3'] . '</a>',
'new_comment' => !empty($row['locked']) ? '' : '<a href="' . $scripturl . '?action=post;topic=' . $row['ID_TOPIC'] . '.' . $row['numReplies'] . '">' . $txt['smf_news_3'] . '</a>',
'poster' => array(
'id' => $row['ID_MEMBER'],
'name' => $row['posterName'],
'href' => !empty($row['ID_MEMBER']) ? $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] : '',
'link' => !empty($row['ID_MEMBER']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] . '">' . $row['posterName'] . '</a>' : $row['posterName']
),
'locked' => !empty($row['locked']),

'board' => array(
'id' => $row['ID_BOARD'],
'name' => $boardInfo[$row['ID_BOARD']]['name'],
'href' => $scripturl . '?board=' . $row['ID_BOARD'],
'link' => '<a href="' . $scripturl . '?board=' . $row['ID_BOARD'] . '">' . $boardInfo[$row['ID_BOARD']]['name'] . '</a>'
),
'is_last' => false
);
}
mysql_free_result($request);

if (empty($return))
return $return;

$return[count($return) - 1]['is_last'] = true;

if ($output_method != 'echo')
return $return;

foreach ($return as $news)
{
echo '
<div>
<a href="', $news['href'], '">', $news['icon'], '</a> <b>', $news['subject'], '</b>
<div class="smaller">', $news['time'], ' ', $txt[525], ' ', $news['poster']['link'], '</div>

<div class="post" style="padding: 2ex 0;">', $news['body'], '</div>

', $news['link'], $news['locked'] ? '' : ' | ' . $news['comment_link'], '
</div>';

if (!$news['is_last'])
echo '
<hr style="margin: 2ex 0;" width="100%" />';
}
}



Advertisement: