09 Announcement System

Started by Mindless, July 20, 2012, 08:12:37 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

DragonCoder

Quote from: whocares on March 14, 2016, 08:38:16 PM
I just tested this on a clean install of tbdev09 and it is working properly

same here too

whocares

I just tested this on a clean install of tbdev09 and it is working properly
Unless stated otherwise code is untested

DragonCoder

Quote from: whocares on March 11, 2016, 08:29:58 PM
This is showing just a white page or does it give any kind of error?

theres no error logs for it not any showing this is the first thing i do look at to fix errors and none shows

whocares

This is showing just a white page or does it give any kind of error?
Unless stated otherwise code is untested

DragonCoder

still same mate car`nt under stand this lol every else working even bittorrant lol

Quote from: whocares on March 11, 2016, 05:23:51 PM
maybe
<?php
require_once("include/bittorrent.php");
require_once 
"include/user_functions.php";

dbconn(false);
loggedinorreturn();
$HTMLOUT ="";
$lang array_mergeload_language('global') );

if (
$CURUSER['class'] < UC_ADMINISTRATOR)
stderr('Error','Your not authorised');

if (
$_SERVER['REQUEST_METHOD'] == 'POST')
{
        
// The expiry days.
        
$days = array(
         array(
7,'7 Days'),
        array(
14,'14 Days'),
        array(
21,'21 Days'),
        array(
28,'28 Days'),
        array(
56,'2 Months'));

 
// usersearch POST data...
        
$n_pms = (isset($_POST['n_pms']) ? $_POST['n_pms'] : 0);
        
$ann_query = (isset($_POST['ann_query']) ? trim($_POST['ann_query']) : '');
        
$ann_hash = (isset($_POST['ann_hash']) ? trim($_POST['ann_hash']) : '');

        if (
hashit($ann_query,$n_pms) != $ann_hashstderr('Error','Invalid Hash'); // Validate POST...

        
if (!preg_match('/\\ASELECT.+?FROM.+?WHERE.+?\\z/'$ann_query)) stderr('Error','Misformed Query');
        if (!
$n_pmsstderr('Error','No recipients');

        
// Preview POST data ...
        
$body trim((isset($_POST['msg']) ? $_POST['msg'] : ''));
        
$subject trim((isset($_POST['subject']) ? $_POST['subject'] : ''));
        
$expiry + (isset($_POST['expiry']) ? $_POST['expiry'] : 0);

        if ((isset(
$_POST['buttonval']) AND $_POST['buttonval'] == 'Submit'))
 {
        
// Check values before inserting into row...
        
if (empty($body)) stderr('Error','No body to announcement');
        if (empty(
$subject)) stderr('Error','No subject to announcement');

        unset(
$flag);
        
reset($days);
        foreach(
$days as $x)
                 {if (
$expiry == $x[0]) $flag 1;}

        if (!isset(
$flag)) stderr('Error','Invalid expiry selection');

        
$expires time() + (86400 $expiry); // 86400 seconds in one day.
        
$created time();



        
$query sprintf('INSERT INTO announcement_main '.
                 
'(owner_id, created, expires, sql_query, subject, body) '.
        
'VALUES (%s, %s, %s, %s, %s, %s)',
        
sqlesc($CURUSER['id']),
        
sqlesc($created),
                 
sqlesc($expires),
                 
sqlesc($ann_query),
                 
sqlesc($subject),
        
sqlesc($body));

        
mysql_query($query);

        if (
mysql_affected_rows())
                
stderr('Success','Announcement was successfully created');

        
stderr('Error','Contact an administrator');
 }

  print 
stdhead("Create Announcement"false);

        
$HTMLOUT.="<table class='main' width='750' border='0' cellspacing='0' cellpadding='0'>
        <tr><td class='embedded'><div align='center'>"
;
  
?>

  <h1>Create Announcement for <?php print($n_pms);?> user<?php print(($n_pms>'s'''));?>!</h1>
        <?php
        $HTMLOUT
.="<form name='compose' method='post' action='{$TBDEV['baseurl']}/new_announcement.php'>
        <table border='1' cellspacing='0' cellpadding='5'>
        <tr>
        <td colspan='2'><b>Subject: </b>
        <input name='subject' type='text' size='76' value='"
.htmlspecialchars_decode($subject)."' /></td>
        </tr>
        <tr><td colspan='2'><div align='center'>
  <textarea name='msg' cols='80' rows='15'>"
.htmlspecialchars_decode($body)."</textarea>
  </div></td></tr>"
;
        
$HTMLOUT .="<tr><td colspan='2' align='center'>";

        
$HTMLOUT .="<select name='expiry'>";

  
reset($days);
        foreach(
$days as $x)
  {
$HTMLOUT.='<option value="'.$x[0].'"'.(($expiry == $x[0] ? '' '')).'>'.$x[1].'</option>';}

        
$HTMLOUT .="</select>

        <input type='submit' name='buttonval' value='Preview' class='btn' />
        <input type='submit' name='buttonval' value='Submit' class='btn' />
        </td></tr></table>
        <input type='hidden' name='n_pms' value='"
.$n_pms."' />
        <input type='hidden' name='ann_query' value='"
.$ann_query."' />
        <input type='hidden' name='ann_hash' value='"
.$ann_hash."' />
        </form><br /><br />
        </div></td></tr></table>"
;

        if (
$body)
        {
        
$newtime time() + (86400 $expiry);
        
$HTMLOUT .="<table width='700' class='main' border='0' cellspacing='1' cellpadding='1'>
        <tr><td bgcolor='#663366' align='center' valign='baseline'><h2><font color='white'>Announcement:
        "
.htmlspecialchars_decode($subject)."</font></h2></td></tr>
        <tr><td class='text'>
        "
.format_comment($body)."<br /><hr />Expires: ".get_date($newtime'DATE')."";
        
$HTMLOUT .="</td></tr></table>";
}
} else { 
// Shouldn't be here
header("HTTP/1.0 404 Not Found");
$HTMLOUT .="<html><h1>Not Found</h1><p>The requested URL {$_SERVER['PHP_SELF']} was not found on this server.</p><hr /><address>Apache/1.1.11 (xxxxx) Server at ".$_SERVER['SERVER_NAME']." Port 80</address></body></html>\n";
die(
$HTMLOUT);
}
print 
$HTMLOUT stdfoot();
?>


whocares

maybe
<?php
require_once("include/bittorrent.php");
require_once 
"include/user_functions.php";

dbconn(false);
loggedinorreturn();
$HTMLOUT ="";
$lang array_mergeload_language('global') );

if (
$CURUSER['class'] < UC_ADMINISTRATOR)
stderr('Error','Your not authorised');

if (
$_SERVER['REQUEST_METHOD'] == 'POST')
{
        
// The expiry days.
        
$days = array(
         array(
7,'7 Days'),
        array(
14,'14 Days'),
        array(
21,'21 Days'),
        array(
28,'28 Days'),
        array(
56,'2 Months'));

 
// usersearch POST data...
        
$n_pms = (isset($_POST['n_pms']) ? $_POST['n_pms'] : 0);
        
$ann_query = (isset($_POST['ann_query']) ? trim($_POST['ann_query']) : '');
        
$ann_hash = (isset($_POST['ann_hash']) ? trim($_POST['ann_hash']) : '');

        if (
hashit($ann_query,$n_pms) != $ann_hashstderr('Error','Invalid Hash'); // Validate POST...

        
if (!preg_match('/\\ASELECT.+?FROM.+?WHERE.+?\\z/'$ann_query)) stderr('Error','Misformed Query');
        if (!
$n_pmsstderr('Error','No recipients');

        
// Preview POST data ...
        
$body trim((isset($_POST['msg']) ? $_POST['msg'] : ''));
        
$subject trim((isset($_POST['subject']) ? $_POST['subject'] : ''));
        
$expiry + (isset($_POST['expiry']) ? $_POST['expiry'] : 0);

        if ((isset(
$_POST['buttonval']) AND $_POST['buttonval'] == 'Submit'))
 {
        
// Check values before inserting into row...
        
if (empty($body)) stderr('Error','No body to announcement');
        if (empty(
$subject)) stderr('Error','No subject to announcement');

        unset(
$flag);
        
reset($days);
        foreach(
$days as $x)
                 {if (
$expiry == $x[0]) $flag 1;}

        if (!isset(
$flag)) stderr('Error','Invalid expiry selection');

        
$expires time() + (86400 $expiry); // 86400 seconds in one day.
        
$created time();



        
$query sprintf('INSERT INTO announcement_main '.
                 
'(owner_id, created, expires, sql_query, subject, body) '.
        
'VALUES (%s, %s, %s, %s, %s, %s)',
        
sqlesc($CURUSER['id']),
        
sqlesc($created),
                 
sqlesc($expires),
                 
sqlesc($ann_query),
                 
sqlesc($subject),
        
sqlesc($body));

        
mysql_query($query);

        if (
mysql_affected_rows())
                
stderr('Success','Announcement was successfully created');

        
stderr('Error','Contact an administrator');
 }

  print 
stdhead("Create Announcement"false);

        
$HTMLOUT.="<table class='main' width='750' border='0' cellspacing='0' cellpadding='0'>
        <tr><td class='embedded'><div align='center'>"
;
  
?>

  <h1>Create Announcement for <?php print($n_pms);?> user<?php print(($n_pms>'s'''));?>!</h1>
        <?php
        $HTMLOUT
.="<form name='compose' method='post' action='{$TBDEV['baseurl']}/new_announcement.php'>
        <table border='1' cellspacing='0' cellpadding='5'>
        <tr>
        <td colspan='2'><b>Subject: </b>
        <input name='subject' type='text' size='76' value='"
.htmlspecialchars_decode($subject)."' /></td>
        </tr>
        <tr><td colspan='2'><div align='center'>
  <textarea name='msg' cols='80' rows='15'>"
.htmlspecialchars_decode($body)."</textarea>
  </div></td></tr>"
;
        
$HTMLOUT .="<tr><td colspan='2' align='center'>";

        
$HTMLOUT .="<select name='expiry'>";

  
reset($days);
        foreach(
$days as $x)
  {
$HTMLOUT.='<option value="'.$x[0].'"'.(($expiry == $x[0] ? '' '')).'>'.$x[1].'</option>';}

        
$HTMLOUT .="</select>

        <input type='submit' name='buttonval' value='Preview' class='btn' />
        <input type='submit' name='buttonval' value='Submit' class='btn' />
        </td></tr></table>
        <input type='hidden' name='n_pms' value='"
.$n_pms."' />
        <input type='hidden' name='ann_query' value='"
.$ann_query."' />
        <input type='hidden' name='ann_hash' value='"
.$ann_hash."' />
        </form><br /><br />
        </div></td></tr></table>"
;

        if (
$body)
        {
        
$newtime time() + (86400 $expiry);
        
$HTMLOUT .="<table width='700' class='main' border='0' cellspacing='1' cellpadding='1'>
        <tr><td bgcolor='#663366' align='center' valign='baseline'><h2><font color='white'>Announcement:
        "
.htmlspecialchars_decode($subject)."</font></h2></td></tr>
        <tr><td class='text'>
        "
.format_comment($body)."<br /><hr />Expires: ".get_date($newtime'DATE')."";
        
$HTMLOUT .="</td></tr></table>";
}
} else { 
// Shouldn't be here
header("HTTP/1.0 404 Not Found");
$HTMLOUT .="<html><h1>Not Found</h1><p>The requested URL {$_SERVER['PHP_SELF']} was not found on this server.</p><hr /><address>Apache/1.1.11 (xxxxx) Server at ".$_SERVER['SERVER_NAME']." Port 80</address></body></html>\n";
die(
$HTMLOUT);
}
print 
$HTMLOUT stdfoot();
?>
Unless stated otherwise code is untested

DragonCoder

Morpheus
   whocares

tryed both still same no change

whocares

One thing to double check is that it looks like you have spaces before the <?php at the start of the file which could at least cause it to not read correctly
Unless stated otherwise code is untested

Morpheus

#3
try this :)

replace <textarea name='msg' cols='80' rows='15'>".htmlspecialchars_decode($body)."</textarea>

with <textarea name='body' type='text' cols='80' rows='15'>".htmlspecialchars_decode($body)."</textarea>
"Simplicity is the ultimate sophistication." ~ Leonardo da Vinci

DragonCoder

#2
this file is white paging error the rest of this mod is working but this one to set up ive looked in the error logs and there is no error file telling what it is any help to fix this would be nice many thax


    <?php
    
require "include/bittorrent.php";
    require_once 
ROOT_PATH.'/include/user_functions.php';
    require_once 
ROOT_PATH.'/include/bbcode_functions.php';
    
dbconn(false);
    
loggedinorreturn();
    
$HTMLOUT ="";
    
$lang array_mergeload_language('global') );
     
    if (
$CURUSER['class'] < UC_ADMINISTRATOR
    
stderr('Error','Your not authorised');
     
    if (
$_SERVER['REQUEST_METHOD'] == 'POST')
    {
            
// The expiry days.
            
$days = array(
             array(
7,'7 Days'),
            array(
14,'14 Days'),
            array(
21,'21 Days'),
            array(
28,'28 Days'),
            array(
56,'2 Months'));
     
     
// usersearch POST data...
            
$n_pms = (isset($_POST['n_pms']) ? $_POST['n_pms'] : 0);
            
$ann_query = (isset($_POST['ann_query']) ? trim($_POST['ann_query']) : '');
            
$ann_hash = (isset($_POST['ann_hash']) ? trim($_POST['ann_hash']) : '');
     
            if (
hashit($ann_query,$n_pms) != $ann_hash) die(); // Validate POST...
     
            
if (!preg_match('/\\ASELECT.+?FROM.+?WHERE.+?\\z/'$ann_query)) stderr('Error','Misformed Query');
            if (!
$n_pmsstderr('Error','No recipients');
     
            
// Preview POST data ...
            
$body trim((isset($_POST['msg']) ? $_POST['msg'] : ''));
            
$subject trim((isset($_POST['subject']) ? $_POST['subject'] : ''));
            
$expiry + (isset($_POST['expiry']) ? $_POST['expiry'] : 0);
     
            if ((isset(
$_POST['buttonval']) AND $_POST['buttonval'] == 'Submit'))
     {
            
// Check values before inserting into row...
            
if (empty($body)) stderr('Error','No body to announcement');
            if (empty(
$subject)) stderr('Error','No subject to announcement');
     
            unset(
$flag);
            
reset($days);
            foreach(
$days as $x)
                     if (
$expiry == $x[0]) $flag 1;
     
            if (!isset(
$flag)) stderr('Error','Invalid expiry selection');
     
            
$expires time() + (86400 $expiry); // 86400 seconds in one day.
            
$created time();
     
     
     
            
$query sprintf('INSERT INTO announcement_main '.
                     
'(owner_id, created, expires, sql_query, subject, body) '.
            
'VALUES (%s, %s, %s, %s, %s, %s)',
            
sqlesc($CURUSER['id']),
            
sqlesc($created),
                     
sqlesc($expires),
                     
sqlesc($ann_query),
                     
sqlesc($subject),
            
sqlesc($body));
     
            
mysql_query($query);
     
            if (
mysql_affected_rows())
                    
stderr('Success','Announcement was successfully created');
     
            
stderr('Error','Contact an administrator');
     }
     
      print 
stdhead("Create Announcement"false);
      
            
$HTMLOUT.="<table class='main' width='750' border='0' cellspacing='0' cellpadding='0'>
            <tr><td class='embedded'><div align='center'>"
;
      
?>

      <h1>Create Announcement for <?php print($n_pms);?> user<?php print(($n_pms>'s'''));?>!</h1>
            <?php
            $HTMLOUT
.="<form name='compose' method='post' action='{$TBDEV['baseurl']}/new_announcement.php'>
            <table border='1' cellspacing='0' cellpadding='5'>
            <tr>
            <td colspan='2'><b>Subject: </b>
            <input name='subject' type='text' size='76' value='"
.htmlspecialchars_decode($subject)."' /></td>
            </tr>
            <tr><td colspan='2'><div align='center'>
      "
.textbbcode("compose","msg",$body)."
      </div></td></tr>"
;
            
$HTMLOUT .="<tr><td colspan='2' align='center'>";
     
            
$HTMLOUT .="<select name='expiry'>";
     
      
reset($days);
            foreach(
$days as $x)
      
$HTMLOUT.='<option value="'.$x[0].'"'.(($expiry == $x[0] ? '' '')).'>'.$x[1].'</option>';
     
            
$HTMLOUT .="</select>
     
            <input type='submit' name='buttonval' value='Preview' class='btn' />
            <input type='submit' name='buttonval' value='Submit' class='btn' />
            </td></tr></table>
            <input type='hidden' name='n_pms' value='"
.$n_pms."' />
            <input type='hidden' name='ann_query' value='"
.$ann_query."' />
            <input type='hidden' name='ann_hash' value='"
.$ann_hash."' />
            </form><br /><br />
            </div></td></tr></table>"
;
     
            if (
$body)
            {
            
$newtime time() + (86400 $expiry);
            
$HTMLOUT .="<table width='700' class='main' border='0' cellspacing='1' cellpadding='1'>
            <tr><td bgcolor='#663366' align='center' valign='baseline'><h2><font color='white'>Announcement: 
            "
.htmlspecialchars_decode($subject)."</font></h2></td></tr>
            <tr><td class='text'>
            "
.format_comment($body)."<br /><hr />Expires: ".get_date($newtime'DATE')."";
            
$HTMLOUT .="</td></tr></table>";
    }
    } else { 
// Shouldn't be here
    
header("HTTP/1.0 404 Not Found");
    
$HTMLOUT .="<html><h1>Not Found</h1><p>The requested URL {$_SERVER['PHP_SELF']} was not found on this server.</p><hr /><address>Apache/1.1.11 (xxxxx) Server at ".$_SERVER['SERVER_NAME']." Port 80</address></body></html>\n";
    die();
    }
    print 
$HTMLOUT stdfoot();
    
?>


i replaced with this one as i do not want bbcode

    <?php
    
require_once("include/bittorrent.php");
    require_once 
"include/user_functions.php";
    require_once 
"include/user_functions.php";

    
dbconn(false);
    
loggedinorreturn();
    
$HTMLOUT ="";
    
$lang array_mergeload_language('global') );

    if (
$CURUSER['class'] < UC_ADMINISTRATOR)
    
stderr('Error','Your not authorised');

    if (
$_SERVER['REQUEST_METHOD'] == 'POST')
    {
            
// The expiry days.
            
$days = array(
             array(
7,'7 Days'),
            array(
14,'14 Days'),
            array(
21,'21 Days'),
            array(
28,'28 Days'),
            array(
56,'2 Months'));

     
// usersearch POST data...
            
$n_pms = (isset($_POST['n_pms']) ? $_POST['n_pms'] : 0);
            
$ann_query = (isset($_POST['ann_query']) ? trim($_POST['ann_query']) : '');
            
$ann_hash = (isset($_POST['ann_hash']) ? trim($_POST['ann_hash']) : '');

            if (
hashit($ann_query,$n_pms) != $ann_hash) die(); // Validate POST...

            
if (!preg_match('/\\ASELECT.+?FROM.+?WHERE.+?\\z/'$ann_query)) stderr('Error','Misformed Query');
            if (!
$n_pmsstderr('Error','No recipients');

            
// Preview POST data ...
            
$body trim((isset($_POST['msg']) ? $_POST['msg'] : ''));
            
$subject trim((isset($_POST['subject']) ? $_POST['subject'] : ''));
            
$expiry + (isset($_POST['expiry']) ? $_POST['expiry'] : 0);

            if ((isset(
$_POST['buttonval']) AND $_POST['buttonval'] == 'Submit'))
     {
            
// Check values before inserting into row...
            
if (empty($body)) stderr('Error','No body to announcement');
            if (empty(
$subject)) stderr('Error','No subject to announcement');

            unset(
$flag);
            
reset($days);
            foreach(
$days as $x)
                     if (
$expiry == $x[0]) $flag 1;

            if (!isset(
$flag)) stderr('Error','Invalid expiry selection');

            
$expires time() + (86400 $expiry); // 86400 seconds in one day.
            
$created time();



            
$query sprintf('INSERT INTO announcement_main '.
                     
'(owner_id, created, expires, sql_query, subject, body) '.
            
'VALUES (%s, %s, %s, %s, %s, %s)',
            
sqlesc($CURUSER['id']),
            
sqlesc($created),
                     
sqlesc($expires),
                     
sqlesc($ann_query),
                     
sqlesc($subject),
            
sqlesc($body));

            
mysql_query($query);

            if (
mysql_affected_rows())
                    
stderr('Success','Announcement was successfully created');

            
stderr('Error','Contact an administrator');
     }

      print 
stdhead("Create Announcement"false);

            
$HTMLOUT.="<table class='main' width='750' border='0' cellspacing='0' cellpadding='0'>
            <tr><td class='embedded'><div align='center'>"
;
      
?>

      <h1>Create Announcement for <?php print($n_pms);?> user<?php print(($n_pms>'s'''));?>!</h1>
            <?php
            $HTMLOUT
.="<form name='compose' method='post' action='{$TBDEV['baseurl']}/new_announcement.php'>
            <table border='1' cellspacing='0' cellpadding='5'>
            <tr>
            <td colspan='2'><b>Subject: </b>
            <input name='subject' type='text' size='76' value='"
.htmlspecialchars_decode($subject)."' /></td>
            </tr>
            <tr><td colspan='2'><div align='center'>
      <textarea name='msg' cols='80' rows='15'>"
.htmlspecialchars_decode($body)."</textarea>
      </div></td></tr>"
;
            
$HTMLOUT .="<tr><td colspan='2' align='center'>";

            
$HTMLOUT .="<select name='expiry'>";

      
reset($days);
            foreach(
$days as $x)
      
$HTMLOUT.='<option value="'.$x[0].'"'.(($expiry == $x[0] ? '' '')).'>'.$x[1].'</option>';

            
$HTMLOUT .="</select>

            <input type='submit' name='buttonval' value='Preview' class='btn' />
            <input type='submit' name='buttonval' value='Submit' class='btn' />
            </td></tr></table>
            <input type='hidden' name='n_pms' value='"
.$n_pms."' />
            <input type='hidden' name='ann_query' value='"
.$ann_query."' />
            <input type='hidden' name='ann_hash' value='"
.$ann_hash."' />
            </form><br /><br />
            </div></td></tr></table>"
;

            if (
$body)
            {
            
$newtime time() + (86400 $expiry);
            
$HTMLOUT .="<table width='700' class='main' border='0' cellspacing='1' cellpadding='1'>
            <tr><td bgcolor='#663366' align='center' valign='baseline'><h2><font color='white'>Announcement:
            "
.htmlspecialchars_decode($subject)."</font></h2></td></tr>
            <tr><td class='text'>
            "
.format_comment($body)."<br /><hr />Expires: ".get_date($newtime'DATE')."";
            
$HTMLOUT .="</td></tr></table>";
    }
    } else { 
// Shouldn't be here
    
header("HTTP/1.0 404 Not Found");
    
$HTMLOUT .="<html><h1>Not Found</h1><p>The requested URL {$_SERVER['PHP_SELF']} was not found on this server.</p><hr /><address>Apache/1.1.11 (xxxxx) Server at ".$_SERVER['SERVER_NAME']." Port 80</address></body></html>\n";
    die();
    }
    print 
$HTMLOUT stdfoot();
    
?>

Mindless

#1
QuoteRetro
Why are Mass PMs bad?

When you mass PM members, you create a message for each individual you mass PM. If you mass PM 3,000 members, then you generate 3,000 PMs.

What a waste...

The following code will generate one single message, then intelligently select the recipients of this message. I say intelligently, because you can target ALL power users, and any member who gets promoted or demoted into that target group after the message has been sent, will also receive that message.

The announcement also has one other feature. It will expire, so you can select an expiry, knowing that when the message dies, so will all the table entries associated with it.

I still have one final script to code, which is an administration script, but what follows is the complete implementation of the announcement code.

[Update ChangeLog]
Xhtml valid
Changed to 09 Timestamps and structure

Reworked for 09 :) - Not much to say but massive respect to Retro for this system as its superb

[ChangeLog]

Two new data tables


Code (sql) Select
CREATE TABLE IF NOT EXISTS `announcement_main` (
  `main_id` int(10) unsigned NOT NULL auto_increment,
  `owner_id` int(10) unsigned NOT NULL default '0',
  `created` int(11) NOT NULL default '0',
  `expires` int(11) NOT NULL default '0',
  `sql_query` text NOT NULL,
  `subject` text NOT NULL,
  `body` text NOT NULL,
  PRIMARY KEY  (`main_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;



Code (sql) Select
CREATE TABLE IF NOT EXISTS `announcement_process` (
  `process_id` int(10) unsigned NOT NULL auto_increment,
  `main_id` int(10) unsigned NOT NULL default '0',
  `user_id` int(10) unsigned NOT NULL default '0',
  `status` tinyint(3) unsigned NOT NULL default '0',
  PRIMARY KEY  (`process_id`),
  KEY `user_id` (`user_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;



Code (sql) Select
ALTER TABLE `users` ADD `curr_ann_last_check` INT UNSIGNED DEFAULT '0' NOT NULL AFTER `last_access` ,
ADD `curr_ann_id` INT UNSIGNED DEFAULT '0' NOT NULL AFTER `curr_ann_last_check`;


The first table is the container for the announcement and the second table is the announcement processor.

The status field in the second table will have three states.

0 - Not Processed. This is used purely for status changes to accounts, and will not be set by the main announcement code.

1 - Ignore. This means that the CURUSER is not a recipient of this announcement.

2 - Read. The announcement has been processed and displayed.

When a status change happens to a user account, any processes that are set to 'ignore' will need to be changed to 'Not Processed' to validate whether the member is outside or in a capturing group. This status change can be set by system promotion, or by manual promotion. The situation may arise where Power Users are sent an announcement prior to auto-promotion of some more members to Power User. The new Power Users, as Users, would have the status set to 'Ignore', but would need it reset to 'Not Processed' to ensure that they are re-validated, ensuring that, as Power Users, they can now see the announcement.

[bittorrent.php]

The following function, which should be included in bittorrent.php, will allow other areas of code to reset the status to 'Not Processed'. Since this code has no external references, the $id value is not parsed for validity.

Code (php) Select
function status_change($id) {
mysql_query('UPDATE announcement_process SET status = 0 WHERE user_id = '.sqlesc($id).' AND status = 1');
}


The following function is designed to add some security to data POST'd between pages.

Code (php) Select
function hashit($var,$addtext="")
{
return md5("This Text ".$addtext.$var.$addtext." is added to muddy the water...");
}


I would suggest that you change the literal text to something that only you know (unique for each community installing this function).

[cleanup.php]

Within the cleanup.php code, the promotion and demotion code needs to access the status_change function to reset the status.

Example...

Code (php) Select
while ($arr = mysql_fetch_assoc($res))
{
@mysql_query("UPDATE users SET class = 1 WHERE id = {$arr['id']}") or sqlerr(__FILE__, __LINE__);
@mysql_query("INSERT INTO messages (sender, receiver, added, msg, poster) VALUES(0, {$arr['id']}, $dt, $msg, 0)") or sqlerr(__FILE__, __LINE__);
}


to

Code (php) Select
while ($arr = mysql_fetch_assoc($res))
{
@mysql_query("UPDATE users SET class = 1 WHERE id = {$arr['id']}") or sqlerr(__FILE__, __LINE__);
@mysql_query("INSERT INTO messages (sender, receiver, added, msg, poster) VALUES(0, {$arr['id']}, $dt, $msg, 0)") or sqlerr(__FILE__, __LINE__);
status_change($arr['id']);
}



(You will need to find all promotion code, and make the change)

And some code to remove any orphaned announcement_processors

// Delete Orphaned announcement_processors
Code (php) Select
mysql_query("DELETE announcement_process FROM announcement_process LEFT JOIN users ON announcement_process.user_id = users.id WHERE users.id IS NULL");

// Delete expired announcements and processors
mysql_query("DELETE FROM announcement_main WHERE expires < ".sqlesc(time()));
mysql_query("DELETE announcement_process FROM announcement_process LEFT JOIN announcement_main ON announcement_process.main_id = announcement_main.main_id WHERE announcement_main.main_id IS NULL");



[modtask.php]

In modtask.php, you will need to add this line after the mysql_query that UPDATES the user row at the bottom.

Code (php) Select
status_change($userid);

These changes will allow an account status change to re-validate announcements set to 'ignore'.

[admin/usersearch.php]

Changes to the usersearch.php script which will allow a capture group to be selected, then forwarded to the new_announcement.php script ready for insertion into the announcement_main table.

Find the lines :

Code (php) Select
$select_is = "u.id, u.username, u.email, u.status, u.added, u.last_access, u.ip,
u.class, u.uploaded, u.downloaded, u.donor, u.modcomment, u.enabled, u.warned";
$query = "SELECT ".$distinct." ".$select_is." ".$querypm;


and precede with...

Code (php) Select
$announcement_query = 'SELECT u.id FROM '.$from_is.
(($where_is == "")? " WHERE 1=1":" WHERE $where_is");


In the debug code that follows,

Code (php) Select
stdmsg($lang['usersearch_url'],$q);

Add this under it :

Code (php) Select
stdmsg("Announce Query",$announcement_query);
echo "<br /><br />";


so that debugging information is present should it be needed.

Near the end of the script should be some HTML used for transferring to the sendmessage.php script. This will need to be changed to refer to the new_announcement.php script.

Code (php) Select
<br /><br />
<form method='post' action='./new_announcement.php'>
<table border='1' cellpadding='5' cellspacing='0'>
<tr>
<td>
<div align='center'>
<input name='n_pms' type='hidden' value='<?php print($count);?>' />
<input name='ann_query' type='hidden' value='<?php print($announcement_query);?>' />
<input name='ann_hash' type='hidden' value ='<?php print(hashit($announcement_query$count));?>' />
<button type='submit'>Create New Announcement</button>
</div></td>
</tr>
</table>
</form>


Or you can keep the pm button as well but the purpose of this modification is to replace the masspm system.

Notes about this code. You will notice that it uses the button tag. The reason for this is that using the <INPUT TYPE=SUBMIT results in a button that is not wide enough to hold all the text in a firefox broswer (truncates the end). You may need to change the HTML to suit your browser. The hashit() function uses the $announcement_query and $count to generate a unique hash which should help towards someone who finds a way of going straight to the new_announcement.php script using a POST injector (especially sore staff).

[new_announcement.php]

The following is the complete script for new_announcement.php

Code (php) Select
<?php
require "include/bittorrent.php";
require_once 
ROOT_PATH.'/include/user_functions.php';
require_once 
ROOT_PATH.'/include/bbcode_functions.php';
dbconn(false);
loggedinorreturn();
$HTMLOUT ="";
$lang array_mergeload_language('global') );

if (
$CURUSER['class'] < UC_ADMINISTRATOR
stderr('Error','Your not authorised');

if (
$_SERVER['REQUEST_METHOD'] == 'POST')
{
// The expiry days.
$days = array(
 
 array(7,'7 Days'),
 
array(14,'14 Days'),
 
array(21,'21 Days'),
 
array(28,'28 Days'),
 
array(56,'2 Months'));

 
// usersearch POST data...
$n_pms = (isset($_POST['n_pms']) ? $_POST['n_pms'] : 0);
$ann_query = (isset($_POST['ann_query']) ? trim($_POST['ann_query']) : '');
$ann_hash = (isset($_POST['ann_hash']) ? trim($_POST['ann_hash']) : '');

if (hashit($ann_query,$n_pms) != $ann_hash) die(); // Validate POST...

if (!preg_match('/\\ASELECT.+?FROM.+?WHERE.+?\\z/'$ann_query)) stderr('Error','Misformed Query');
if (!$n_pmsstderr('Error','No recipients');

// Preview POST data ...
$body trim((isset($_POST['msg']) ? $_POST['msg'] : ''));
$subject trim((isset($_POST['subject']) ? $_POST['subject'] : ''));
$expiry + (isset($_POST['expiry']) ? $_POST['expiry'] : 0);

if ((isset($_POST['buttonval']) AND $_POST['buttonval'] == 'Submit'))
 {
 
// Check values before inserting into row...
 
if (empty($body)) stderr('Error','No body to announcement');
 
if (empty($subject)) stderr('Error','No subject to announcement');

 
unset($flag);
 
reset($days);
 
foreach($days as $x)
 
 if ($expiry == $x[0]) $flag 1;

 
if (!isset($flag)) stderr('Error','Invalid expiry selection');

 
$expires time() + (86400 $expiry); // 86400 seconds in one day.
 
$created time();



 
$query sprintf('INSERT INTO announcement_main '.
 
 '(owner_id, created, expires, sql_query, subject, body) '.
 
'VALUES (%s, %s, %s, %s, %s, %s)',
 
sqlesc($CURUSER['id']),
 
sqlesc($created),
 
 sqlesc($expires),
 
 sqlesc($ann_query),
 
 sqlesc($subject),
 
sqlesc($body));

 
mysql_query($query);

 
if (mysql_affected_rows())
 
  stderr('Success','Announcement was successfully created');

 
stderr('Error','Contact an administrator');
 }

  print 
stdhead("Create Announcement"false);
  
 
$HTMLOUT.="<table class='main' width='750' border='0' cellspacing='0' cellpadding='0'>
  <tr><td class='embedded'><div align='center'>"
;
  
?>

  <h1>Create Announcement for <?php print($n_pms);?> user<?php print(($n_pms>'s'''));?>!</h1>
<?php
 
$HTMLOUT.="<form name='compose' method='post' action='{$TBDEV['baseurl']}/new_announcement.php'>
  <table border='1' cellspacing='0' cellpadding='5'>
  <tr>
  <td colspan='2'><b>Subject: </b>
  <input name='subject' type='text' size='76' value='"
.htmlspecialchars_decode($subject)."' /></td>
  </tr>
  <tr><td colspan='2'><div align='center'>
  "
.textbbcode("compose","msg",$body)."
  </div></td></tr>"
;
 
$HTMLOUT .="<tr><td colspan='2' align='center'>";

 
$HTMLOUT .="<select name='expiry'>";

  
reset($days);
 
foreach($days as $x)
  
$HTMLOUT.='<option value="'.$x[0].'"'.(($expiry == $x[0] ? '' '')).'>'.$x[1].'</option>';

 
$HTMLOUT .="</select>

  <input type='submit' name='buttonval' value='Preview' class='btn' />
  <input type='submit' name='buttonval' value='Submit' class='btn' />
  </td></tr></table>
  <input type='hidden' name='n_pms' value='"
.$n_pms."' />
  <input type='hidden' name='ann_query' value='"
.$ann_query."' />
  <input type='hidden' name='ann_hash' value='"
.$ann_hash."' />
  </form><br /><br />
  </div></td></tr></table>"
;

        if (
$body)
{
 
$newtime time() + (86400 $expiry);
 
$HTMLOUT .="<table width='700' class='main' border='0' cellspacing='1' cellpadding='1'>
  <tr><td bgcolor='#663366' align='center' valign='baseline'><h2><font color='white'>Announcement: 
  "
.htmlspecialchars_decode($subject)."</font></h2></td></tr>
  <tr><td class='text'>
  "
.format_comment($body)."<br /><hr />Expires: ".get_date($newtime'DATE')."";
 
$HTMLOUT .="</td></tr></table>";
}
} else { 
// Shouldn't be here
header("HTTP/1.0 404 Not Found");
$HTMLOUT .="<html><h1>Not Found</h1><p>The requested URL {$_SERVER['PHP_SELF']} was not found on this server.</p><hr /><address>Apache/1.1.11 (xxxxx) Server at ".$_SERVER['SERVER_NAME']." Port 80</address></body></html>\n";
die();
}
print 
$HTMLOUT stdfoot();
?>


The following line is for backward compatability with scripts that dont
have the textbbcode() function installed in the include/bbcode_function.php script - simply replace in new_announcement.php the following :

Code (php) Select
".textbbcode("compose","msg",$body)."

with this

Code (php) Select
<textarea name='msg' cols='80' rows='15'>".htmlspecialchars_decode($body)."</textarea>

[bittorrent.php]

The next step is the changes to the userlogin() function found in bittorrent.php

Find this :

Code (php) Select
unset($GLOBALS["CURUSER"]);

Add this line under it ...

Code (php) Select
$dt = time();

which will hold the current date_time needed for the following code to work...

Change the line...

Code (php) Select
$res = mysql_query("SELECT * FROM users WHERE id = $id AND enabled='yes' AND status = 'confirmed'");// or die(mysql_error());

for

Code (php) Select
$res = mysql_query("SELECT u.*, ann_main.subject AS curr_ann_subject, ann_main.body AS curr_ann_body " . "FROM users AS u " . "LEFT JOIN announcement_main AS ann_main " . "ON ann_main.main_id = u.curr_ann_id " . "WHERE u.id = $id AND u.enabled='yes' AND u.status = 'confirmed'") or sqlerr(__FILE__, __LINE__);

Under this code :

Code (php) Select
if (get_mycookie('pass') !== $row["passhash"])
        return;

       
And insert the following code after it.

Code (php) Select
//If curr_ann_id > 0 but curr_ann_body IS NULL, then force a refresh
if (($row['curr_ann_id'] > 0) AND ($row['curr_ann_body'] == NULL)) {
$row['curr_ann_id'] = 0;
$row['curr_ann_last_check'] = '0';
}

// If elapsed > 10 minutes, force a announcement refresh.
if (($row['curr_ann_last_check'] != '0') AND ($row['curr_ann_last_check']) < (time($dt) - 600))
$row['curr_ann_last_check'] = '0';

if (($row['curr_ann_id'] == 0) AND ($row['curr_ann_last_check'] == '0'))
{ // Force an immediate check...
$query = sprintf('SELECT m.*,p.process_id FROM announcement_main AS m '.
'LEFT JOIN announcement_process AS p ON m.main_id = p.main_id '.
'AND p.user_id = %s '.
'WHERE p.process_id IS NULL '.
'OR p.status = 0 '.
'ORDER BY m.main_id ASC '.
'LIMIT 1',
sqlesc($row['id']));

$result = mysql_query($query);

if (mysql_num_rows($result))
{ // Main Result set exists
$ann_row = mysql_fetch_assoc($result);

$query = $ann_row['sql_query'];

// Ensure it only selects...
if (!preg_match('/\\ASELECT.+?FROM.+?WHERE.+?\\z/', $query)) die();

// The following line modifies the query to only return the current user
// row if the existing query matches any attributes.
$query .= ' AND u.id = '.sqlesc($row['id']).' LIMIT 1';

$result = mysql_query($query);

if (mysql_num_rows($result))
{ // Announcement valid for member
$row['curr_ann_id'] = $ann_row['main_id'];

// Create two row elements to hold announcement subject and body.
$row['curr_ann_subject'] = $ann_row['subject'];
$row['curr_ann_body'] = $ann_row['body'];

// Create additional set for main UPDATE query.
$add_set = ', curr_ann_id = '.sqlesc($ann_row['main_id']);
$status = 2;
}
else
{
// Announcement not valid for member...
$add_set = ', curr_ann_last_check = '.sqlesc($dt);
$status = 1;
}

// Create or set status of process
if ($ann_row['process_id'] === NULL)
{
// Insert Process result set status = 1 (Ignore)
$query = sprintf('INSERT INTO announcement_process (main_id, '.
'user_id, status) VALUES (%s, %s, %s)',
sqlesc($ann_row['main_id']),
sqlesc($row['id']),
sqlesc($status));
}
else
{
// Update Process result set status = 2 (Read)
$query = sprintf('UPDATE announcement_process SET status = %s '.
'WHERE process_id = %s',
sqlesc($status),
sqlesc($ann_row['process_id']));
}
mysql_query($query);
}
else
{
// No Main Result Set. Set last update to now...
$add_set = ', curr_ann_last_check = '.sqlesc($dt);
}
unset($result);
unset($ann_row);
}


Finally, a change to the UPDATE query...

Code (php) Select
mysql_query("UPDATE users SET last_access='" . TIME_NOW . "', ip=".sqlesc($ip)." WHERE id=" . $row["id"]);// or die(mysql_error());

To :

Code (php) Select
$add_set = (isset($add_set))?$add_set:'';
mysql_query("UPDATE users SET last_access=".sqlesc($dt).", ip=".sqlesc($ip).$add_set." WHERE id=".$row['id']);// or die(mysql_error());


which allows the additional add_set to be incorporated into the query.

Notes about the above code. The announcement will store an SQL query to define the capture group, as set by the usersearch function. When an announcement is read, any further announcement will be displayed immediately. Only one announcement is displayed at a time. When no announcement exists, a minimum of 10 minutes will elapse before the code will check for further announcements, to save hogging the SQL server with additional requests.

This is all the changes needed for bittorrent.php

I've changed the display box a little - i have mine on index.php but i guess it equally can be added to bittorrent.php in the stdhead function under the message notification code :

Code (php) Select
// Announcement Code...
   $ann_subject = trim($CURUSER['curr_ann_subject']);
   $ann_body = trim($CURUSER['curr_ann_body']);
   if ((!empty($ann_subject)) AND (!empty($ann_body)))
   {
   $HTMLOUT .= "<div style='text-align:left;width:80%;border:1px solid blue;padding:5px;'>
   <div style='background:lightgrey;height:25px;'><span style='font-weight:bold;font-size:12pt;'>{$lang['index_announce']}</span></div><br />
   <table width='100%' border='1' cellspacing='0' cellpadding='5'>
   <tr><td bgcolor='#466248'><b><font color='black'>Announcement:
   ".htmlspecialchars_decode($ann_subject)."</font></b></td></tr>
   <tr><td style='padding: 10px; background: #CDFEAF'>
   ".format_comment($ann_body)."
   <br /><hr /><br />
   Click <a href='{$TBDEV['baseurl']}/clear_announcement.php'>
   <i><b>here</b></i></a> to clear this announcement.</td></tr></table></div><br />\n";
   }


[lang/en/lang_index.php]

Add :

Code (php) Select
'index_announce' => "Announcement",

[clear_announcement.php]

Finally, a script to clear the announcement once read.

Code (php) Select
<?php
require "include/bittorrent.php";
dbconn(false);
loggedinorreturn();

$query sprintf('UPDATE users SET curr_ann_id = 0, curr_ann_last_check = \'0\' '.
 
 'WHERE id = %s AND curr_ann_id != 0',
 
 sqlesc($CURUSER['id']));

mysql_query($query);

header("Location: {$TBDEV['baseurl']}/index.php");
?>


This is the current code available.

Still to be written is the admin script that allows direct edit of all attributes of the announcement, except the SQL Query embedded into the announcement, and a member script that allows them to look at all previous announcements that haven't expired.

[ADDENDUM]

[view_announce_history.php]

The following code will allow the member to view all previous announcements which havent expired.

Code (php) Select
<?php
require "include/bittorrent.php";
require_once 
ROOT_PATH.'/include/user_functions.php';
require_once 
ROOT_PATH.'/include/bbcode_functions.php';
dbconn(false);
loggedinorreturn();
$lang array_mergeload_language('global'));
$action = (isset($_GET['action']) ? $_GET['action'] : '');

$HTMLOUT ="";
$HTMLOUT .="<table class='main' width='750' border='0' cellspacing='0' cellpadding='10'>
<tr>
<td class='embedded'>
<h2 align='center'><font size='6'>Announcement History</font></h2>"
;

$query sprintf('SELECT m.main_id, m.subject, m.body FROM announcement_main AS m '.
 
 'LEFT JOIN announcement_process AS p '.
 
'ON m.main_id = p.main_id AND p.user_id = %s '.
 
'WHERE p.status = 2',
 
sqlesc($CURUSER['id']));

$result mysql_query($query);

$ann_list = array();

while (
$x mysql_fetch_array($result)) $ann_list[] = $x ;
unset(
$x);
unset(
$result);
reset($ann_list);

if (
$action == 'read_announce')
{
 
$id + (isset($_GET['id']) ? $_GET['id'] : );

 
if (!is_int($id)) { stdmsg('Error','Invalid ID'); stdfoot(); die(); }

 
foreach($ann_list AS $x)
 
 if ($x[0] == $id)
 
 list(,$subject,$body) = $x;

 
if (empty($subject) OR empty($body)) { 
 
stdmsg('Error','ID does not exist'); 
 
stdfoot(); 
 
die(); 
 
}

 
$HTMLOUT.="<table width='100%' border='0' cellpadding='4' cellspacing='0'>
  <tr>
  <td width='50%' bgcolor='orange'>Subject: <b>"
.htmlspecialchars_decode($subject)."</b></td>
  </tr>
  <tr>
  <td colspan='2' bgcolor='white'>"
.format_comment($body)."</td>
  </tr>
  <tr>
  <td>
  <a href='"
.$_SERVER['PHP_SELF']."'>Back</a>
  </td>
  </tr>
  </table>"
;
}

$HTMLOUT.="<table align='center' width='30%' border='0' cellpadding='4' cellspacing='0'>
<tr>
<td align='center' bgcolor='orange'><b>Subject</b></td>
</tr>"
;

foreach(
$ann_list AS $x)
$HTMLOUT .="<tr><td align='center'><a href='?action=read_announce&amp;id=".$x[0]."'>".htmlspecialchars_decode($x[1])."</a></td></tr>\n";
$HTMLOUT.="</table>";
$HTMLOUT.="</td></tr></table>";
print 
stdhead('Announcement History') . $HTMLOUT stdfoot();
?>


[userdetails.php]

A small change to the userdetails.php script which will provide a hyperlink to the view_announce_history.php script.

Code (php) Select
if ($CURUSER['id'] == $user['id'])
   $HTMLOUT.="<h1><a href='./my.php'>Edit My Profile</a></h1>
<h1><a href='./view_announce_history.php'>View My Announcements</a></h1><br />";


which will probably sit nicely above...

Code (php) Select
$HTMLOUT .= begin_main_frame();
     
$HTMLOUT .= "<table width='100%' border='1' cellspacing='0' cellpadding='5'>
<tr><td class='rowhead' width='1%'>{$lang['userdetails_joined']}</td><td align='left' width='99%'>{$joindate}</td></tr>
<tr><td class='rowhead'>{$lang['userdetails_seen']}</td><td align='left'>{$lastseen}</td></tr>";


ADVICE:

I would suggest that you use the usersearch function to select all members, so that you can create your first announcement. This announcement can be the Welcome Message that a lot of communities send new members as a PM. Once you have created this message, you will need to use your database editor to change the expiry date to a much later one ('2020-01-01 00:00:00'). Once you have done this, and made sure that new members see this Welcome Announcement, you can disable the Welcome PM generated for each new member.

This system is also ideal for announcing changes to the site, for staff benefit, or drawing their attention to a specific staff thread.

In fact, anything you would use the Mass PM system for, this system will perform much better.

The code uses the textbbcode() function found in include/bbcode_functions.php for displaying the text entry, which includes clickable smilies and bbtag buttons. If you don't have this function installed, then you can comment out the textbbcode() lines in the above scripts, and uncomment the <textarea> code, which will give you a basic interface.

Remember, when testing this code, that you may have to wait up to ten minutes before a new announcement is displayed. Please be patient.

Finally. I will offer limited support for these scripts. I will answer any questions I feel are genuine, but I won't install the scripts for anyone, or walk them through it. If you feel that you are not competant to install these scripts, then don't.

Always remember to back up your database and existing code before making any changes to scripts, especially the bittorrent.php script.