1<?php
2
3require_once dirname(__FILE__).'/accesscheck.php';
4
5$subselect = $whereClause = '';
6$action_result = '';
7$access = accessLevel('messages');
8
9$messageSortOptions = array(
10    'subjectasc'  => array(
11        // caption for drop-down list
12        'label' => s('Subject').' - '.s('Ascending'),
13        // sql order by
14        'orderby' => 'subject asc'
15    ),
16    'subjectdesc'  => array(
17        'label' => s('Subject').' - '.s('Descending'),
18        'orderby' => 'subject desc'
19    ),
20    'enteredasc'  => array(
21        'label' => s('Entered').' - '.s('Ascending'),
22        'orderby' => 'entered asc'
23    ),
24    'entereddesc'  => array(
25        'label' => s('Entered').' - '.s('Descending'),
26        'orderby' => 'entered desc'
27    ),
28    'modifiedasc'  => array(
29        'label' => s('Modified').' - '.s('Ascending'),
30        'orderby' => 'modified asc'
31    ),
32    'modifieddesc'  => array(
33        'label' => s('Modified').' - '.s('Descending'),
34        'orderby' => 'modified desc'
35    ),
36    'embargoasc'  => array(
37        'label' => s('Embargo').' - '.s('Ascending'),
38        'orderby' => 'embargo asc'
39    ),
40    'embargodesc'  => array(
41        'label' => s('Embargo').' - '.s('Descending'),
42        'orderby' => 'embargo desc'
43    ),
44    'sentasc'  => array(
45        'label' => s('Sent').' - '.s('Ascending'),
46        'orderby' => 'sent asc'
47    ),
48    'sentdesc'  => array(
49        'label' => s('Sent').' - '.s('Descending'),
50        'orderby' => 'sent desc'
51    ),
52);
53$tabParameters = array(
54    'active' => array(
55        // status values to select messages
56        'status' => "'inprocess', 'submitted', 'suspended'",
57        // initial ordering of tab
58        'defaultSort' => 'embargoasc'
59    ),
60    'draft' => array(
61        'status' => "'draft'",
62        'defaultSort' => 'modifieddesc'
63    ),
64    'sent' => array(
65        'status' => "'sent'",
66        'defaultSort' => 'sentdesc'
67    ),
68    'static' => array(
69        'status' => "'prepared'",
70        'defaultSort' => 'embargoasc'
71    ),
72);
73
74if ($access == 'all') {
75    $ownerselect_and = '';
76    $ownerselect_where = '';
77} else {
78    $ownerselect_where = ' where owner = '.$_SESSION['logindetails']['id'];
79    $ownerselect_and = ' and owner = '.$_SESSION['logindetails']['id'];
80}
81if (isset($_GET['start'])) {
82    $start = sprintf('%d', $_GET['start']);
83} else {
84    unset($start);
85}
86
87if (!isset($_SESSION['messagefilter'])) {
88    $_SESSION['messagefilter'] = '';
89}
90if (!empty($_POST['clear'])) {
91    $_SESSION['messagefilter'] = '';
92    $_SESSION['messagesortby'] = array();
93    $_SESSION['messagenumpp'] = MAX_MSG_PP;
94    unset($_POST['filter']);
95    unset($_POST['numPP']);
96    unset($_POST['sortBy']);
97}
98if (isset($_POST['filter'])) {
99    $_SESSION['messagefilter'] = removeXSS($_POST['filter']);
100    if ($_SESSION['messagefilter'] == $filterSelectDefault) {
101        $_SESSION['messagefilter'] = '';
102    }
103}
104if (!isset($_SESSION['messagenumpp'])) {
105    $_SESSION['messagenumpp'] = MAX_MSG_PP;
106}
107if (isset($_POST['numPP'])) {
108    $_SESSION['messagenumpp'] = sprintf('%d', $_POST['numPP']);
109    if ($_SESSION['messagenumpp'] <= 0) {
110        $_SESSION['messagenumpp'] = MAX_MSG_PP;
111    }
112}
113
114if (isset($_GET['tab']) && isset($tabParameters[$_GET['tab']])) {
115    $currentTab = $_GET['tab'];
116} else {
117    if (isset($_SESSION['lastmessagetype'])) {
118        $currentTab = $_SESSION['lastmessagetype'];
119    } else {
120        $currentTab = 'sent';
121    }
122}
123$_SESSION['lastmessagetype'] = $currentTab;
124
125if (isset($_POST['sortBy'])) {
126    if (in_array($_POST['sortBy'], array_keys($messageSortOptions))) {
127        $_SESSION['messagesortby'][$currentTab] = $_POST['sortBy'];
128    }
129}
130
131if (!isset($_SESSION['messagesortby'][$currentTab])) {
132    $_SESSION['messagesortby'][$currentTab] = $tabParameters[$currentTab]['defaultSort'];
133}
134$currentSortBy = $_SESSION['messagesortby'][$currentTab];
135
136echo '<div class="actions"><div class="fright">';
137echo PageLinkActionButton('send&amp;new=1', $GLOBALS['I18N']->get('Start a new campaign'));
138echo '</div><div class="clear"></div></div>';
139
140//## Print tabs
141$tabs = new WebblerTabs();
142$tabs->addTab($GLOBALS['I18N']->get('sent'), PageUrl2('messages&amp;tab=sent'), 'sent');
143$tabs->addTab($GLOBALS['I18N']->get('active'), PageUrl2('messages&amp;tab=active'), 'active');
144$tabs->addTab($GLOBALS['I18N']->get('draft'), PageUrl2('messages&amp;tab=draft'), 'draft');
145//$tabs->addTab($GLOBALS['I18N']->get("queued"),PageUrl2("messages&amp;tab=queued"));#
146if (USE_PREPARE) {
147    $tabs->addTab($GLOBALS['I18N']->get('static'), PageUrl2('messages&amp;tab=static'), 'static');
148}
149//obsolete, moved to rssmanager plugin
150//if (ENABLE_RSS) {
151//  $tabs->addTab("rss",PageUrl2("messages&amp;tab=rss"));
152//}
153$tabs->setCurrent($currentTab);
154
155echo '<div class="minitabs">';
156echo $tabs->display();
157echo '</div>';
158
159$filterDisplay = $_SESSION['messagefilter'];
160
161echo '<div id="messagefilter" class="filterdiv fright">';
162echo formStart(' id="messagefilterform" ');
163echo '<div><input type="text" name="filter" placeholder="&#128269;'.s('Search campaigns').'" value="'.htmlspecialchars($filterDisplay).'" />';
164
165echo '<select name="numPP" class="numppOptions">';
166foreach (array(5, 10, 15, 20, 50, 100) as $numppOption) {
167    if ($numppOption == $_SESSION['messagenumpp']) {
168        echo '<option selected="selected">'.$numppOption.'</option>';
169    } else {
170        echo '<option>'.$numppOption.'</option>';
171    }
172}
173echo '</select>';
174echo '<select name="sortBy" class="sortby">';
175foreach ($messageSortOptions as $sortOption => $optionData) {
176    if ($sortOption == $currentSortBy) {
177        echo '<option selected="selected" value="'.$sortOption.'">'.$optionData['label'].'</option>';
178    } else {
179        echo '<option value="'.$sortOption.'">'.$optionData['label'].'</option>';
180    }
181}
182echo '</select>';
183echo '<button type="submit" name="go" id="filterbutton" >'.s('Go').'</button> <button type="submit" name="clear" id="filterclearbutton" value="1">'.s('Clear').'</button></div>';
184echo '</form></div>';
185
186//## Process 'Action' requests
187if (!empty($_GET['delete'])) {
188    verifyCsrfGetToken();
189    $todelete = array();
190    if ($_GET['delete'] == 'draft') {
191        $req = Sql_Query(sprintf('select id from %s where status = "draft" and (subject = "" or subject = "(no subject)") %s',
192            $GLOBALS['tables']['message'], $ownerselect_and));
193        while ($row = Sql_Fetch_Row($req)) {
194            array_push($todelete, $row[0]);
195        }
196    } else {
197        array_push($todelete, sprintf('%d', $_GET['delete']));
198    }
199    foreach ($todelete as $delete) {
200        $action_result .= $GLOBALS['I18N']->get('Deleting')." $delete ...";
201        $del = deleteMessage($delete);
202        if ($del) {
203            $action_result .= '... '.$GLOBALS['I18N']->get('Done');
204        } else {
205            $action_result .= '... '.$GLOBALS['I18N']->get('failed');
206        }
207        $action_result .= '<br/>';
208    }
209    $action_result .= "<hr /><br />\n";
210}
211
212if (isset($_GET['duplicate'])) {
213    verifyCsrfGetToken();
214
215    Sql_Query(sprintf('insert into %s (uuid, subject, fromfield, tofield, replyto, message, textmessage, footer, entered,
216        modified, embargo, repeatuntil, repeatinterval, requeueinterval, status, htmlformatted, sendformat, template, rsstemplate, owner)
217        select "%s", subject, fromfield, tofield, replyto, message, textmessage, footer, now(),
218        now(), now(), now(), repeatinterval, requeueinterval, "draft",  htmlformatted,
219        sendformat, template, rsstemplate, "%d" from %s
220        where id = %d',
221        $GLOBALS['tables']['message'], (string) Uuid::generate(4), $_SESSION['logindetails']['id'],$GLOBALS['tables']['message'],
222        intval($_GET['duplicate'])));
223    if ($newId = Sql_Insert_Id()) {  // if we don't have a newId then the copy failed
224        Sql_Query(sprintf('insert into %s (id,name,data) '.
225            'select %d,name,data from %s where name in ("sendmethod","sendurl","campaigntitle","excludelist","subject") and id = %d',
226            $GLOBALS['tables']['messagedata'],$newId,$GLOBALS['tables']['messagedata'],intval($_GET['duplicate'])));
227        Sql_Query(sprintf('insert into %s (messageid, listid, entered)  select %d, listid, now() from %s where messageid = %d',
228            $GLOBALS['tables']['listmessage'],$newId,$GLOBALS['tables']['listmessage'],intval($_GET['duplicate'])));
229    }
230
231}
232
233if (isset($_GET['resend'])) {
234    verifyCsrfGetToken();
235    $resend = sprintf('%d', $_GET['resend']);
236    // requeue the message in $resend
237    $action_result .= $GLOBALS['I18N']->get('Requeuing')." $resend ..";
238    $result = Sql_Query(sprintf('update %s set status = "submitted", sendstart = null where id = %d',
239        $tables['message'], $resend));
240    $suc6 = Sql_Affected_Rows();
241    // only send it again to users, if we are testing, otherwise only to new users
242    if (TEST) {
243        $result = Sql_query(sprintf('delete from %s where messageid = %d', $tables['usermessage'], $resend));
244    }
245    if ($suc6) {
246        $action_result .= '... '.$GLOBALS['I18N']->get('Done');
247        foreach ($GLOBALS['plugins'] as $pluginname => $plugin) {
248            $plugin->messageReQueued($resend);
249        }
250        Sql_Query(sprintf('delete from %s where id = %d and (name = "start_notified" or name = "end_notified")',
251            $tables['messagedata'], $resend));
252        $messagedata = loadMessageData($resend);
253        $finishSending = mktime($messagedata['finishsending']['hour'], $messagedata['finishsending']['minute'], 0,
254            $messagedata['finishsending']['month'], $messagedata['finishsending']['day'],
255            $messagedata['finishsending']['year']);
256        if ($finishSending < time()) {
257            $action_result .= '<br />'.s('This campaign is scheduled to stop sending in the past. No mails will be sent.');
258            $action_result .= '<br />'.PageLinkButton('send&amp;id='.$messagedata['id'].'&amp;tab=Scheduling',
259                    s('Review Scheduling'));
260        }
261        if (getConfig('pqchoice') == 'phplistdotcom') {
262            $action_result .= activateRemoteQueue();
263        }
264    } else {
265        $action_result .= '... '.$GLOBALS['I18N']->get('failed');
266    }
267    $action_result .= '<br />';
268}
269
270if (isset($_GET['suspend'])) {
271    verifyCsrfGetToken();
272    $suspend = sprintf('%d', $_GET['suspend']);
273    $action_result .= $GLOBALS['I18N']->get('Suspending')." $suspend ..";
274    $result = Sql_query(sprintf('update %s set status = "suspended" where id = %d and (status = "inprocess" or status = "submitted") %s',
275        $tables['message'], $suspend, $ownerselect_and));
276    $suc6 = Sql_Affected_Rows();
277    if ($suc6) {
278        $action_result .= '... '.$GLOBALS['I18N']->get('Done');
279    } else {
280        $action_result .= '... '.$GLOBALS['I18N']->get('failed');
281    }
282    $action_result .= '<br /><hr /><br />';
283}
284//0012081: Add new 'Mark as sent' button
285if (isset($_GET['markSent'])) {
286    verifyCsrfGetToken();
287    $markSent = sprintf('%d', $_GET['markSent']);
288    $action_result .= $GLOBALS['I18N']->get('Marking as sent ')." $markSent ..";
289    $result = Sql_query(sprintf('update %s set status = "sent", sent = now(), repeatinterval = 0,requeueinterval = 0 where id = %d and (status = "suspended") %s',
290        $tables['message'], $markSent, $ownerselect_and));
291    $suc6 = Sql_Affected_Rows();
292    if ($suc6) {
293        $action_result .= '... '.$GLOBALS['I18N']->get('Done');
294    } else {
295        $action_result .= '... '.$GLOBALS['I18N']->get('Failed');
296    }
297    $action_result .= '<br /><hr /><br />';
298}
299
300if (isset($_GET['action'])) {
301    verifyCsrfGetToken();
302    switch ($_GET['action']) {
303        case 'suspall':
304            $action_result .= $GLOBALS['I18N']->get('Suspending all').' ..';
305            $result = Sql_query(sprintf('update %s set status = "suspended" where (status = "inprocess" or status = "submitted") %s',
306                $tables['message'], $ownerselect_and));
307            $suc6 = Sql_Affected_Rows();
308            if ($suc6) {
309                $action_result .= "... $suc6 ".$GLOBALS['I18N']->get('Done');
310            } else {
311                $action_result .= '... '.$GLOBALS['I18N']->get('Failed');
312            }
313            $action_result .= '<br /><hr /><br />';
314            break;
315        case 'markallsent':
316            $action_result .= $GLOBALS['I18N']->get('Marking all as sent ').'  ..';
317            $result = Sql_query(sprintf('update %s set status = "sent", sent = now(), repeatinterval = 0,requeueinterval = 0 where (status = "suspended") %s',
318                $tables['message'], $markSent, $ownerselect_and));
319            $suc6 = Sql_Affected_Rows();
320            if ($suc6) {
321                $action_result .= "... $suc6 ".$GLOBALS['I18N']->get('Done');
322            } else {
323                $action_result .= '... '.$GLOBALS['I18N']->get('Failed');
324            }
325            $action_result .= '<br /><hr /><br />';
326            break;
327    }
328}
329
330if (!empty($action_result)) {
331    //print ActionResult($action_result);
332    $_SESSION['action_result'] = $action_result;
333    Redirect('messages');
334    exit;
335}
336
337$where = array();
338$where[] = sprintf('status in (%s)', $tabParameters[$currentTab]['status']);
339$url_keep = '&amp;tab='.$currentTab;
340
341if (!empty($_SESSION['messagefilter'])) {
342    $where[] = ' subject like "%'.sql_escape($_SESSION['messagefilter']).'%" ';
343}
344
345//## Query messages from db
346if ($access != 'all') {
347    $where[] = ' owner = '.$_SESSION['logindetails']['id'];
348}
349$whereClause = ' where '.implode(' and ', $where);
350$sortBySql = 'order by '.$messageSortOptions[$currentSortBy]['orderby'];
351$req = Sql_query('select count(*) from '.$tables['message'].$whereClause.' '.$sortBySql);
352$total_req = Sql_Fetch_Row($req);
353$total = $total_req[0];
354
355//# Browse buttons table
356$limit = $_SESSION['messagenumpp'];
357$offset = 0;
358if (isset($start) && $start > 0) {
359    $offset = $start;
360} else {
361    $start = 0;
362}
363
364$paging = '';
365if ($total > $_SESSION['messagenumpp']) {
366    $paging = simplePaging("messages$url_keep", $start, $total, $_SESSION['messagenumpp'],
367        $GLOBALS['I18N']->get('Campaigns'));
368}
369
370$ls = new WebblerListing(s('Campaigns'));
371$ls->setElementHeading('Campaign');
372$ls->usePanel($paging);
373
374//# messages table
375if ($total) {
376    $result = Sql_query('SELECT * FROM '.$tables['message']." $whereClause $sortBySql limit $limit offset $offset");
377    while ($msg = Sql_fetch_array($result)) {
378        $editlink = '';
379        $messagedata = loadMessageData($msg['id']);
380        if ($messagedata['subject'] != $messagedata['campaigntitle']) {
381            $listingelement = '<!--'.$msg['id'].'-->'.stripslashes($messagedata['campaigntitle']).'<br/><strong>'.stripslashes($messagedata['subject']).'</strong>';
382        } else {
383            $listingelement = '<!--'.$msg['id'].'-->'.stripslashes($messagedata['subject']);
384        }
385
386        //   $listingelement = '<!--'.$msg['id'].'-->'.stripslashes($messagedata["campaigntitle"]);
387        if ($msg['status'] == 'draft') {
388            $editlink = PageUrl2('send&id='.$msg['id']);
389        }
390
391        $ls->addElement($listingelement, $editlink);
392        $ls->setClass($listingelement, 'row1');
393        $uniqueviews = Sql_Fetch_Row_Query("select count(userid) from {$tables['usermessage']} where viewed is not null and status = 'sent' and messageid = ".$msg['id']);
394
395        $clicks = Sql_Fetch_Row_Query("select sum(clicked) from {$tables['linktrack_ml']} where messageid = ".$msg['id']);
396//    $clicks = array(0);
397
398        /*
399            foreach ($messagedata as $key => $val) {
400              $ls->addColumn($listingelement,$key,$val);
401            }
402
403        */
404        $ls->addColumn($listingelement, $GLOBALS['I18N']->get('Entered'), formatDateTime($msg['entered']));
405
406        $_GET['id'] = $msg['id'];
407        $statusdiv = '<div id="messagestatus'.$msg['id'].'">';
408        include 'actions/msgstatus.php';
409        $statusdiv .= $status;
410        $statusdiv .= '</div>';
411        $GLOBALS['pagefooter']['statusupdate'.$msg['id']] = '<script type="text/javascript">
412      updateMessages.push(' .$msg['id'].');</script>';
413        $GLOBALS['pagefooter']['statusupdate'] = '<script type="text/javascript">window.setInterval("messagesStatusUpdate()",5000);</script>';
414        if ($msg['status'] == 'sent') {
415            $statusdiv = $GLOBALS['I18N']->get('Sent').': '.formatDateTime($msg['sent']);
416        }
417        $ls->addColumn($listingelement, $GLOBALS['I18N']->get('Status'), $statusdiv);
418
419        /*
420         * Display the lists that have been selected for the campaign
421         */
422        $maxListsDisplayed = 3;
423        $namesQuery = <<<END
424    SELECT SQL_CALC_FOUND_ROWS l.name
425    FROM {$tables['list']} l
426    JOIN {$tables['listmessage']} lm  ON l.id = lm.listid
427    WHERE lm.messageid = {$msg['id']}
428    ORDER BY l.name
429    LIMIT $maxListsDisplayed
430END;
431        $namesResult = Sql_Query($namesQuery);
432        $row = Sql_Fetch_Row_Query('SELECT FOUND_ROWS()');
433        $numberOfLists = $row[0];
434
435        if ($numberOfLists > 0) {
436            $listNames = array();
437
438            while ($row = Sql_Fetch_Assoc($namesResult)) {
439                $listNames[] = htmlspecialchars($row['name']);
440            }
441
442            if ($numberOfLists > $maxListsDisplayed) {
443                array_pop($listNames);
444                $listNames[] = sprintf(
445                    '<a href="%s">%s</a>',
446                    PageURL2('message', '', "id={$msg['id']}").'#targetlists',
447                    htmlspecialchars(s('and %d more', $numberOfLists - ($maxListsDisplayed - 1)))
448                );
449            }
450            $ls->addRow($listingelement, s('Lists'), implode('<br/>', $listNames), '', 'left');
451        }
452
453        if ($msg['status'] != 'draft') {
454            //    $ls->addColumn($listingelement,$GLOBALS['I18N']->get("total"), $msg['astext'] + $msg['ashtml'] + $msg['astextandhtml'] + $msg['aspdf'] + $msg['astextandpdf']);
455//    $ls->addColumn($listingelement,$GLOBALS['I18N']->get("text"), $msg['astext']);
456//    $ls->addColumn($listingelement,$GLOBALS['I18N']->get("html"), $msg["ashtml"] + $msg["astextandhtml"]);
457//    if (!empty($msg['aspdf'])) {
458//      $ls->addColumn($listingelement,$GLOBALS['I18N']->get("PDF"), $msg['aspdf']);
459//    }
460//    if (!empty($msg["astextandpdf"])) {
461//      $ls->addColumn($listingelement,$GLOBALS['I18N']->get("both"), $msg["astextandpdf"]);
462//    }
463
464            // Prepare view & bounce statistics for printing
465            $viewStats = array(
466                'views' => $msg['viewed']
467                , 'uniqueViews' => $uniqueviews[0]
468                , 'clicks' => $clicks[0]
469                , 'bounces' => $msg['bouncecount']
470            );
471
472            $viewStatsFormatted = array();
473
474            // Make statistical integers human readable
475            foreach ($viewStats as $key => $value) {
476                $viewStatsFormatted[$key] = number_format($value);
477            }
478            $resultStats = '
479    <table class="messagesendstats">
480        <thead>
481            <tr>
482                <th colspan="2">Statistics</th>
483            </tr>
484        </thead>
485        <tbody>
486            <tr>
487                <td>' .s('Total views').'</td>
488                <td>'.(!empty($viewStats['views']) ? PageLink2('mviews&id='.$msg['id'], $viewStatsFormatted['views']) : '0').'</td>
489            </tr>
490            <tr>
491                <td>' .s('Unique Views').'</td>
492                <td>'.(!empty($viewStats['uniqueViews']) ? PageLink2('mviews&id='.$msg['id'], $viewStatsFormatted['uniqueViews']) : '0').'</td>
493            </tr>';
494            if ($clicks[0]) {
495                $resultStats .= '
496            <tr>
497                <td>'.s('Total clicks').'</td>
498                <td>'. (!empty($viewStats['clicks']) ? PageLink2('mclicks&id='.$msg['id'], $viewStatsFormatted['clicks']): '0').'</td>
499            </tr>';
500            }
501            $resultStats .= '
502            <tr>
503                <td>' .s('Bounced').'</td>
504                <td>'.(!empty($viewStats['bounces']) ? PageLink2('msgbounces&id='.$msg['id'],$viewStatsFormatted['bounces']): '0').'</td>
505            </tr>
506        </tbody>
507    </table>';
508
509//      $ls->addColumn($listingelement,s('Results'),$resultStats);
510
511            //$ls->addColumn($listingelement,$GLOBALS['I18N']->get("Viewed"), $msg["viewed"]);
512            //$ls->addColumn($listingelement,$GLOBALS['I18N']->get("Unique Views"), $uniqueviews[0]);
513            //if ($clicks[0]) {
514            //$ls->addColumn($listingelement,$GLOBALS['I18N']->get("Clicks"), $clicks[0]);
515            //}
516            //$ls->addColumn($listingelement,$GLOBALS['I18N']->get("Bounced"), $msg["bouncecount"]);
517        }
518
519        if ($msg['status'] == 'sent') {
520            $started = s('Started ').': '.formatDateTime($msg['sendstart']);
521            $timetosend = s('Time to send').': '.timeDiff($msg['sendstart'], $msg['sent']);
522        } else {
523            $timetosend = '';
524            $started = '';
525        }
526
527        $colspan = 3;
528        if (!empty($msg['aspdf'])) {
529            ++$colspan;
530        }
531        if (!empty($msg['astextandpdf'])) {
532            ++$colspan;
533        }
534        $clicksrow = $bouncedrow = '';
535
536        //if ($clicks[0]) {
537        //$clicksrow = sprintf('<tr><td colspan="%d">%s</td><td>%d</td></tr>',
538        //$colspan-1,$GLOBALS['I18N']->get("Clicks"),$clicks[0]);
539        //}
540        //if ($msg["bouncecount"]) {
541        //$bouncedrow = sprintf('<tr><td colspan="%d">%s</td><td>%d</td></tr>',
542        //$colspan-1,$GLOBALS['I18N']->get("Bounced"),$msg["bouncecount"]);
543        //}
544
545        // Calculcate sent statistics for printing
546        $sentStats = array(
547            'grandTotal' => $msg['astext'] + $msg['ashtml'] + $msg['astextandhtml'] + $msg['aspdf'] + $msg['astextandpdf']
548            , 'text' => $msg['astext']
549            , 'html' => $msg['ashtml'] + $msg['astextandhtml'] //bug 0009687
550            , 'pdf' => $msg['aspdf']
551            , 'textPlusPDF' => $msg['astextandpdf']
552        );
553
554        $sentStatsFormatted = array();
555
556        // Make statistical integers human readable
557        foreach ($sentStats as $key => $value) {
558            $sentStatsFormatted[$key] = number_format($value);
559        }
560
561        $sendstats =
562            sprintf('<table class="messagesendstats">
563          <thead>
564            <tr>
565              <th colspan="3">Processed</th>
566            </tr>
567          </thead>
568          <tbody>
569              %s %s
570              <tr><td>' .s('total').'</td><td>'.s('text').'</td><td>'.s('html').'</td>
571                %s%s
572              </tr>
573              <tr><td><b>%s</b></td><td><b>%s</b></td><td><b>%s</b></td>
574                %s %s %s %s
575              </tr>
576          </tbody>
577      </table>',
578                !empty($started) ? '<tr> <td colspan="'.$colspan.'">'.$started.'</td></tr>' : '',
579                !empty($timetosend) ? '<tr> <td colspan="'.$colspan.'">'.$timetosend.'</td></tr>' : '',
580                !empty($msg['aspdf']) ? '<td>'.$GLOBALS['I18N']->get('PDF').'</td>' : '',
581                !empty($msg['astextandpdf']) ? '<td>'.$GLOBALS['I18N']->get('both').'</td>' : '',
582                $sentStatsFormatted['grandTotal'],
583                $sentStatsFormatted['text'],
584                $sentStatsFormatted['html'],
585                !empty($msg['aspdf']) ? '<td><b>'.$sentStatsFormatted['pdf'].'</b></td>' : '',
586                !empty($msg['astextandpdf']) ? '<td><b>'.$sentStatsFormatted['textPlusPDF'].'</b></td>' : '',
587                $clicksrow,
588                $bouncedrow
589            );
590        if ($msg['status'] != 'draft') {
591            $ls->addRow($listingelement, '', $resultStats.$sendstats);
592        }
593
594        $actionbuttons = '';
595        if ($msg['status'] == 'inprocess' || $msg['status'] == 'submitted') {
596            $actionbuttons .= '<span class="suspend">'.PageLinkButton('messages&suspend='.$msg['id'],
597                    $GLOBALS['I18N']->get('Suspend'), '', '', s('Suspend')).'</span>';
598        } elseif ($msg['status'] != 'draft') {
599            $actionbuttons .= '<span class="resend">'.PageLinkButton('messages', $GLOBALS['I18N']->get('Requeue'),
600                    'resend='.$msg['id'], '', s('Requeue')).'</span>';
601        }
602        $actionbuttons .= '<span class="view">'.PageLinkButton('message', $GLOBALS['I18N']->get('View'),
603                'id='.$msg['id'], '', s('View')).'</span>';
604
605        if ($clicks[0] && CLICKTRACK) {
606            $actionbuttons .= '<span class="stats">'.PageLinkButton('statsoverview',
607                    $GLOBALS['I18N']->get('statistics'), 'id='.$msg['id'], '', s('Statistics')).'</span>';
608        }
609        //0012081: Add new 'Mark as sent' button
610        if ($msg['status'] == 'suspended') {
611            $actionbuttons .= '<span class="marksent">'.PageLinkButton('messages&amp;markSent='.$msg['id'],
612                    $GLOBALS['I18N']->get('Mark&nbsp;sent'), '', '', s('Mark sent')).'</span>';
613            $actionbuttons .= '<span class="edit">'.PageLinkButton('send', $GLOBALS['I18N']->get('Edit'),
614                    'id='.$msg['id'], '', s('Edit')).'</span>';
615        } elseif ($msg['status'] == 'draft' || !empty($messagedata['istestcampaign'])) {
616            //# only draft messages should be deletable, the rest isn't
617
618            $deletebutton = new ConfirmButton(
619                s('Are you sure you want to delete this campaign?'),
620                PageURL2("messages$url_keep&delete=".$msg['id']),
621                s('delete this campaign'), '', 'button');
622
623//      $actionbuttons .= sprintf('<span class="delete"><a href="javascript:deleteRec(\'%s\');" class="button" title="'.$GLOBALS['I18N']->get("delete").'">'.$GLOBALS['I18N']->get("delete").'</a></span>',PageURL2("messages$url_keep","","delete=".$msg["id"]));
624            $actionbuttons .= '<span class="edit">'.PageLinkButton('send', $GLOBALS['I18N']->get('Edit'),
625                    'id='.$msg['id'], '', s('Edit')).'</span>';
626            if (empty($clicks[0])  ||  !empty($messagedata['istestcampaign'])) { //# disallow deletion when there are stats except when is test campaign
627                $actionbuttons .= '<span class="delete">'.$deletebutton->show().'</span>';
628            }
629        }
630
631        if ($msg['status'] == 'sent') {
632            $actionbuttons .= '<span class="copy">'.PageLinkButton('messages', s('Copy to Draft'),
633                    'tab=draft&duplicate='.$msg['id'], '', s('Copy to Draft')).'</span>';
634        }
635
636        $ls->addColumn($listingelement, $GLOBALS['I18N']->get('Action'),
637            '<div class="messageactions">'.$actionbuttons.'</div>');
638    }
639}
640
641echo $ls->display();
642
643if ($total > 5 && $currentTab == 'active') {
644    echo PageLinkButton('messages', $GLOBALS['I18N']->get('Suspend All'), 'action=suspall');
645    echo PageLinkButton('messages', $GLOBALS['I18N']->get('Mark All Sent'), 'action=markallsent');
646}
647