function notifyUser($userid, $prizeid, $winEmailTemplate, $winNotTemplate)
{
    $claimURL = URL_CANVAS . "?p=redeem&id={$prizeid}";
    $claimLink = "<a href='" . $claimURL . "'>" . $claimURL . "</a>";
    $message .= "Prize {$prizeid} awarded to user {$userid}. ";
    $message .= "User needs to use following link to claim their prize: " . $claimLink;
    //////////////////////////
    // set up data to notify user
    require_once PATH_CORE . '/classes/user.class.php';
    $ut = new UserTable($db);
    $uit = new UserInfoTable($db);
    $user = $ut->getRowObject();
    $user->load($userid);
    require_once PATH_CORE . '/classes/prizes.class.php';
    $pt = new PrizeTable($db);
    $prize = $pt->getRowObject();
    $prize->load($prizeid);
    $nameWords = explode(" ", $user->name);
    require_once PATH_CORE . '/classes/template.class.php';
    $templateObj = new template($db);
    $columns['prizeTitle'] = $prize->title;
    $columns['claimURL'] = $claimURL;
    $columns['firstName'] = $nameWords[0];
    $callbacks = array();
    $winEmail = clone $winEmailTemplate;
    // i hate php
    $winNot = clone $winNotTemplate;
    // construct an email for this specific user
    $winEmail->email = $user->email;
    $winEmail->subject = $templateObj->processRow($columns, $winEmailTemplate->subject, $callbacks);
    $winEmail->body = $templateObj->processRow($columns, $winEmailTemplate->body, $callbacks);
    // construct notification info
    $winNot->body = $templateObj->processRow($columns, $winNotTemplate->body, $callbacks);
    $fbIds = $uit->getFbIdsForUsers(array($user->userid));
    $winNot->fbId = $fbIds[0];
    //$mailtoText = "mailto:$winEmail->email?subject=$winEmail->subject&body=$winEmail->body";
    // do send notifications
    echo "Mailing {$winEmail->email}...";
    sendEmail($winEmail);
    echo "Notifying {$winNot->fbId}...";
    sendNotification($winNot);
}
$action->action= 'completedChallenge';
$action->itemid = $completed_challenge['id'];
$userid = $completed_challenge['userid'];
$action->userid1 = $userid;
// could fill in fbId here if we werent lazy too
$fbId = 0; 

$actionFeed = new actionFeed();
$report = $actionFeed->fetchChallengeCompletedFeedItem( $action , $fbId, true); 
echo $report;
*/
///////////////////////////
// NEW
require_once PATH_CORE . '/classes/user.class.php';
$ut = new UserInfoTable();
$memberids = $ut->getFbIdsForUsers(array($completed_challenge['userid']));
$memberid = $memberids[0];
echo '<a href="' . URL_CANVAS . '?p=profile&memberid=' . $memberid . '&viewSubmitted">
	Click here to see profile with challenge submit records</a>';
//echo 'this is where the report goes';
////////////////////////////////////////////////////////////////
// figure out how many points would normally be credited
require_once PATH_CORE . '/classes/challenges.class.php';
$ct = new ChallengeTable();
//$this->db->setDebug(true);
$completedTable = new ChallengeCompletedTable();
$completed = $completedTable->getRowObject();
if ($completed->load($completed_challenge['id'])) {
    $challenge = $ct->getRowObject();
    if ($challenge->load($completed->challengeid)) {
        $points = $challenge->pointValue;
    function buildActionItem($action)
    {
        require_once PATH_CORE . '/classes/user.class.php';
        require_once PATH_CORE . '/classes/template.class.php';
        $uit = new UserInfoTable($this->db);
        $fbIds = $uit->getFbIdsForUsers(array($action->userid1));
        $fbId = $fbIds[0];
        if ($action->userid2) {
            $fbIds2 = $uit->getFbIdsForUsers(array($action->userid2));
            $fbId2 = $fbIds2[0];
        }
        if (!$fbId) {
            // cant return anything or #&*$@! paging gets screwed
            //$code .= '<div class="hidden">No fbId found for userid '. $action->userid1 . '</div>';
            $this->db->log("Action Feed: No fbId found for userid {$action->userid1} performing {$action->action} on {$action->t}");
            return '';
            //$code;
        }
        $ago .= self::getElapsedString(strtotime($action->t));
        switch ($action->action) {
            case 'completedChallenge':
                $code .= $this->fetchChallengeCompletedFeedItem($action, $fbId, false);
                // hack for now so the console can access it also
                //$ct = new ChallengeTable($this->db);
                break;
            case 'signup':
                /*$code .= template::buildLinkedProfilePic($fbIds[0], 'size="square"') .' '. template::buildLinkedProfileName($fbIds[0])
                				.' joined the action team!';
                		*/
                $code .= '<div class="profilePicLarger">' . template::buildLinkedProfilePic($fbIds[0], 'size="square"') . ' ' . '</div>
			                <div class="storyBlockWrap">
			                    <h3><span class="bold">' . template::buildLinkedProfileName($fbIds[0]) . ' joined the ' . SITE_TEAM_TITLE . '!</span> ' . $ago . '</h3>
			      		</div><!__end "storyBlockWrap"__>';
                break;
            case 'friendSignup':
                $code .= '<div class="profilePicLarger">' . template::buildLinkedProfilePic($fbIds[0], 'size="square"') . ' ' . '</div>
			                <div class="storyBlockWrap">
			                    <h3><span class="bold">' . template::buildLinkedProfileName($fbIds[0]) . ' got credit for inviting ' . template::buildLinkedProfileName($fbId2) . '!</span> ' . $ago . '</h3>
			      		</div><!__end "storyBlockWrap"__>';
                break;
            case 'chatStory':
                require_once PATH_CORE . '/classes/content.class.php';
                $contentTable = new ContentTable($this->db);
                $content = $contentTable->getRowObject();
                $contentid = $action->itemid;
                // hack: since jeff put the fbId in itemid2 for chatStory
                $fbId2 = $action->userid2;
                if ($content->load($contentid)) {
                    $code .= ' <div class="thumb">' . template::buildLinkedStoryImage($content->imageid, $contentid) . '</div>
				                <div class="storyBlockWrap">
				                	<div class="feed_poster">' . '<div class="avatar">' . template::buildLinkedProfilePic($fbIds[0], 'size="square"  with="30" height="30"') . '</div>' . '<div class="avatar">' . template::buildLinkedProfilePic($fbId2, 'size="square"  with="30" height="30"') . '</div>' . '<h3><span class="bold">' . template::buildLinkedProfileName($fbIds[0]) . ' chatted with ' . template::buildLinkedProfileName($fbId2) . ' about the story ' . template::buildStoryLink($content->title, $contentid) . '</span> ' . $ago . '</h3>
				                    </div>				                            
				                </div><!__end "storyBlockWrap"__>';
                }
                break;
                //case 'acceptedInvite': // actually want to filter these?
                // yeah, dont show these
                //break;
            //case 'acceptedInvite': // actually want to filter these?
            // yeah, dont show these
            //break;
            case 'redeemed':
                require_once PATH_CORE . '/classes/prizes.class.php';
                $prizeTable = new PrizeTable($this->db);
                $prize = $prizeTable->getRowObject();
                if ($prize->load($action->itemid) && !$prize->isWeekly && !$prize->isGrand) {
                    /*
                    $indefarticle = template::getIndefiniteArticle($prize->title);
                    $code .= template::buildLinkedProfilePic($fbIds[0], 'size="square"') .' '. template::buildLinkedProfileName($fbIds[0])
                    		." used {$prize->pointCost} points to get $indefarticle "
                    		. template::buildRewardLink($prize->title, $prize->id) .""
                    		. template::buildLinkedRewardPic($prize->id, $prize->thumbnail, $width=70);
                    //$code .= ' '. self::getElapsedString(strtotime($action->t));
                    */
                    $code .= '<div class="thumb">' . template::buildLinkedRewardPic($prize->id, $prize->thumbnail, $width = 70) . '</div>				           
				                <div class="storyBlockWrap">
				                	<div class="feed_poster"><div class="avatar">' . template::buildLinkedProfilePic($fbIds[0], 'size="square" with="30" height="30"') . '</div>
				                    	<h3><span class="bold">' . template::buildLinkedProfileName($fbIds[0]) . ' redeemed <span class="pointValue">' . $prize->pointCost . '<span class="pts"> points</span></span>.</span> ' . $ago . '</h3>
			                    	</div>
				                    <p class="storyHead">' . template::buildRewardLink($prize->title, $prize->id) . ' </p>
				                    <p class="storyCaption"></p>                
				                </div><!__end "storyBlockWrap"__>';
                } else {
                    // debug:
                    //$code .= 'No prize found for id ' . $action->itemid;
                }
                break;
            case 'wonPrize':
                // implement
                require_once PATH_CORE . '/classes/prizes.class.php';
                $prizeTable = new PrizeTable($this->db);
                $prize = $prizeTable->getRowObject();
                if ($prize->load($action->itemid)) {
                    if ($prize->isWeekly) {
                        $winText = 'won a Weekly Prize!';
                    }
                    if ($prize->isGrand == 1) {
                        $winText = 'won the Grand Prize and made the planet green with envy!';
                    }
                    if ($prize->isGrand > 1) {
                        $winText = 'won a Runner-up Prize!';
                    }
                    $code .= '<div class="thumb">' . template::buildLinkedRewardPic($prize->id, $prize->thumbnail, $width = 70) . '</div>
		                <div class="storyBlockWrap">
		                <div class="feed_poster"><div class="avatar">' . template::buildLinkedProfilePic($fbIds[0], 'size="square"  with="30" height="30"') . '</div>
		                    <h3><span class="bold">' . template::buildLinkedProfileName($fbIds[0]) . ' ' . $winText . ' ' . $ago . '</h3>
		                    </div>
		                    <p class="storyHead">' . template::buildRewardLink($prize->title, $prize->id) . ' </p>
		                    <p class="storyCaption"></p>                
		                </div><!__end "storyBlockWrap"__>';
                } else {
                    // debug:
                    //$code .= 'No prize found for id ' . $action->itemid;
                }
                break;
                break;
            case 'publishStory':
                // TODO ?
                //return '';
                //break;
            // TODO ?
            //return '';
            //break;
            case 'postBlog':
            case 'postStory':
                require_once PATH_CORE . '/classes/content.class.php';
                $contentTable = new ContentTable($this->db);
                $content = $contentTable->getRowObject();
                $contentid = $action->itemid;
                if ($content->load($contentid)) {
                    /*$code .= template::buildLinkedStoryImage($content->imageid, $contentid);
                    		$code .= template::buildLinkedProfilePic($fbIds[0], 'size="square"') .' '. template::buildLinkedProfileName($fbIds[0])
                    				.' posted a story';
                    		$code .= '<p>' . template::buildStoryLink($content->title, $contentid)
                    					.'</p>';
                    			*/
                    $code .= ' <div class="thumb">' . template::buildLinkedStoryImage($content->imageid, $contentid) . '</div>
				                <div class="storyBlockWrap">
				                	<div class="feed_poster"><div class="avatar">' . template::buildLinkedProfilePic($fbIds[0], 'size="square"  with="30" height="30"') . '</div>
				                    	<h3><span class="bold">' . template::buildLinkedProfileName($fbIds[0]) . ' posted a story</span> ' . $ago . '</h3>
				                    </div>
				                    <p class="storyHead">' . template::buildStoryLink($content->title, $contentid) . ' </p>
				                    <p class="storyCaption">' . $this->templateObj->ellipsis(strip_tags($content->caption, 200)) . ' ' . template::buildStoryLink('...more', $contentid) . '</p>                
				                </div><!__end "storyBlockWrap"__>';
                    //'</li>'
                }
                break;
            case 'vote':
                // ignore
                require_once PATH_CORE . '/classes/content.class.php';
                $contentTable = new ContentTable($this->db);
                $content = $contentTable->getRowObject();
                $contentid = $action->itemid;
                // grrrr
                if ($content->load($contentid)) {
                    $code .= ' <div class="thumb">' . template::buildLinkedStoryImage($content->imageid, $contentid) . '</div>
				                <div class="storyBlockWrap">
			                	<div class="feed_poster">' . '<h3><span class="bold">' . template::buildLinkedProfileName($fbIds[0]) . ' voted on the story ' . template::buildStoryLink($content->title, $contentid) . '</span> ' . $ago . '</h3>
				                    </div>
				                </div><!__end "storyBlockWrap"__>
				            ';
                }
                break;
            case 'comment':
                /*
                * 
                *  <li class="panel_block">
                                <div class="thumb"><a href="http://www.msnbc.msn.com/id/28529073/"><img src="{URL_BASE}/index.php?p=scaleImg&id=34608&x=185&y=130&fixed=x&crop" /></a>
                                </div>
                                <div class="storyBlockWrap">
                                    <h3><span class="bold"><a href="'.URL_CANVAS.'?p=profile&memberid=1180126201" onclick="return switchPage('profile', '', 1180126201);"><fb:name ifcantsee="Anonymous" uid="1180126201" capitalize="true" firstnameonly="false" linked="false" /></a> commented on the story <a href="#">It's Time to Aim Low</a></span> on Feb 2, 2009</h3>
                				<blockquote>
                					<div class="quotes">
                						<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam dolor nunc, vehicula et, tristique sed, auctor et, massa.</p>
                						<p> Nam at purus vitae diam commodo venenatis. Ut leo enim, vestibulum eget, rhoncus in, suscipit laoreet, magna. Aliquam diam. Nunc tempor lorem eget nisl.</p>
                					</div>
                				</blockquote>
                                </div><!__end "storyBlockWrap"__>
                            </li>
                */
                // assume comment->siteContentId is what is stored...
                require_once PATH_CORE . '/classes/content.class.php';
                require_once PATH_CORE . '/classes/comments.class.php';
                require_once PATH_CORE . '/classes/video.class.php';
                $contentTable = new ContentTable($this->db);
                $commentTable = new CommentTable($this->db);
                $videoTable = new VideoTable($this->db);
                $content = $contentTable->getRowObject();
                $comment = $commentTable->getRowObject();
                $video = $videoTable->getRowObject();
                $commentid = $action->itemid;
                // grr
                $contentid = $action->itemid2;
                // grrrr
                if ($comment->load($commentid) && $content->load($contentid)) {
                    if ($comment->videoid && $video->load($comment->videoid)) {
                        $quoteContents = '<div style="text-align:center;">' . videos::buildPlayerFromLink($video->embedCode, 160, 100) . '</div>';
                    } else {
                        $quoteContents = '<p>' . $this->templateObj->ellipsis(strip_tags($comment->comments), 200) . ' ' . template::buildStoryLink('...more', $contentid) . '</p>';
                    }
                    $code .= ' <div class="thumb">' . template::buildLinkedStoryImage($content->imageid, $contentid) . '</div>
				                <div class="storyBlockWrap">
			                	<div class="feed_poster"><div class="avatar">' . template::buildLinkedProfilePic($fbIds[0], 'size="square" height="30" width="30"') . '</div>
				                    	<h3><span class="bold">' . template::buildLinkedProfileName($fbIds[0]) . ' commented on the story ' . template::buildStoryLink($content->title, $contentid) . '</span> ' . $ago . '</h3>
				                    </div>
				                    <blockquote>
				                    	<div class="quotes">' . $quoteContents . '</div>
									</blockquote>               
				                </div><!__end "storyBlockWrap"__>
				            ';
                }
                break;
        }
        return $code;
    }
 static function getMemberFriends($db, $userid)
 {
     if (is_null($db)) {
         require_once PATH_CORE . '/classes/db.class.php';
         $db = new cloudDatabase();
     }
     require_once PATH_CORE . '/classes/user.class.php';
     $userInfoTable = new UserInfoTable($db);
     $userinfo = $userInfoTable->getRowObject();
     if ($userinfo->load($userid)) {
         return $userInfoTable->getFbIdsForUsers(explode(',', $userinfo->memberFriends));
     }
     return null;
 }
 function buildInvitePage()
 {
     // not tested since dropped into invite.class.php
     // REQUIRES Facebook session
     // some code taken from http://wiki.developers.facebook.com/index.php/Fb:request-forms
     /*echo "<pre>";			
     		echo '$this->facebook:'; print_r($this->facebook);
     		echo '$_GET:'; print_r( $_GET);
     		echo "</pre>";
     			*/
     require_once PATH_CORE . '/classes/user.class.php';
     $userid = $this->session->userid;
     $fbId = $this->session->fbId;
     if (isset($_GET['submit'])) {
         // Process posted invitation ids
         if (count($_POST['ids']) > 0) {
             $result = $this->templateObj->buildFacebookUserList('', $_POST['ids']);
             $result .= '<h1>Nice work!</h1><h5>What do you want to do now?</h5><div class="bullet_list"><ul>' . '<li><a href="?p=home" onclick="switchPage(\'home\');return false;">Go to the home page</a>?</li>' . '<li><a href="?p=team" onclick="switchPage(\'team\');return false;">Visit the ' . SITE_TEAM_TITLE . '</a>?</li>' . '</ul></div><!--end "bullet_list"-->';
             $code .= $this->page->buildMessage('success', 'Your invitations have been sent', $result);
             // Insert Invitations into table
             $inviteTable = new UserInviteTable($this->db);
             $invite = $inviteTable->getRowObject();
             $invite->userid = $userid;
             $invite->dateInvited = date('Y-m-d H:i:s', time());
             foreach ($_POST['ids'] as $id) {
                 $invite->friendFbId = $id;
                 $inviteid = UserInviteTable::checkExists($userid, $id);
                 if ($inviteid === false) {
                     $invite->insert();
                 } else {
                     $invite->id = $inviteid;
                     // date will be updated
                     $invite->update();
                 }
                 //$this->session->ui->cachedFriendsInvited++; // now done through log
                 $log = $this->page->app->getActivityLog();
                 $log->update($log->serialize(0, $this->session->userid, 'invite', $invite->friendFbId, 0));
                 // using itemid since userid2 implies the type is a userid, which it isnt
             }
             //$this->session->ui->update();
         } else {
             $code .= $this->page->buildMessage('error', 'Problem sending invitations', 'We encountered a problem sending your invitations. <a href="?p=invite" onclick="switchPage(\'invite\');return false;">Please try again</a>.');
         }
     } else {
         // Exclude users who have added the application already
         // TODO: do i use the fbApp action db for invitations?
         // Exclude users invited in the last 14 days by this user
         $userid = $this->session->userid;
         $inviteInterval = 3600 * 24 * 14;
         // 2 weeks in seconds
         $debug = false;
         $userInfoTable = new UserInfoTable($this->db);
         require_once PATH_CORE . '/classes/user.class.php';
         if ($debug) {
             echo 'session userinfo: <pre>' . print_r($this->session->ui, true) . '</pre>';
         }
         $allFriends = explode(',', $this->session->ui->friends);
         if ($debug) {
             echo 'session memberFriends: <pre>' . print_r($this->session->ui->memberFriends, true) . '</pre>';
         }
         $memberFriends = explode(',', $this->session->ui->memberFriends);
         // now cached
         if ($debug) {
             echo 'memberFriends uids: <pre>' . print_r($memberFriends, true) . '</pre>';
         }
         $memberFriends = $userInfoTable->getFbIdsForUsers($memberFriends);
         if ($debug) {
             echo 'memberFriends: <pre>' . print_r($memberFriends, true) . '</pre>';
         }
         //$invitedFriends = array();
         $invitedFriends = UserInviteTable::getRecentlyInvitedFriends($this->db, $userid, $inviteInterval);
         if ($debug) {
             echo 'invitedFriends: <pre>' . print_r($invitedFriends, true) . '</pre>';
         }
         if (is_null($invitedFriends)) {
             $invitedFriends = array();
         }
         if (is_null($memberFriends)) {
             $memberFriends = array();
         }
         $excludedFriends = array_merge($invitedFriends, $memberFriends);
         $excludedFriends = array_unique($excludedFriends);
         if ($debug) {
             echo 'excludedFriends: <pre>' . print_r($excludedFriends, true) . '</pre>';
         }
         $cntExcludedFriends = count($encludedFriends);
         //$allFriends=$this->facebook->api_client->friends_get();
         if (count($allFriends) <= $cntExcludedFriends) {
             //all friends are signed up or invited already
             $code .= '<h2>All your friends currently have the  ' . SITE_TITLE . ' application added or have been invited within the past two weeks.</h2><p>Thank you for supporting the ' . SITE_TITLE . '.</p>';
             $code .= '<p><a href="?p=home">Continue to home page</a></p>';
         } else {
             //  Construct a next url for referrals
             $nextUrl = $this->facebook->get_add_url("referfbid=" . $fbId . "&referid=" . $userid . "&viaInvite");
             //$this->db->log($nextUrl);
             $inviteText = $this->templateObj->templates['inviteText'] . "<fb:req-choice url=\"" . $nextUrl . "\" label=\"Add " . SITE_TITLE . "!\" />";
             // need to have this local jeff!
             $actionStr = $this->templateObj->templates['actionStr'];
             $code .= '<fb:request-form action="?p=invite&c=skipped&submit" method="POST" invite="true" type="' . SITE_TITLE . '" content="' . htmlentities($inviteText) . '">';
             if (is_numeric($this->page->app->notifications_per_day)) {
                 $maxRequests = $this->page->app->notifications_per_day;
             } else {
                 $maxRequests = 20;
             }
             $code .= '<fb:multi-friend-selector rows="5" max="' . $maxRequests . '" exclude_ids="' . join(',', $excludedFriends) . '" showborder="false"  actiontext="' . $actionStr . '"> </fb:request-form>';
         }
     }
     return $code;
 }