function run()
 {
     $fp = fopen('php://output', 'w');
     header('Content-type: application/force-download');
     header("Content-Type: application/download");
     header('Content-type: text/csv');
     header('Content-Disposition: attachment; filename="jethro_' . date('Y-m-d_h:i') . '.csv"');
     $GLOBALS['system']->includeDBClass('family');
     $GLOBALS['system']->includeDBClass('person');
     switch (array_get($_REQUEST, 'merge_type')) {
         case 'family':
             $merge_data = Family::getFamilyDataByMemberIDs($_POST['personid']);
             $dummy = new Family();
             $dummy_family = NULL;
             break;
         case 'person':
         default:
             $merge_data = $GLOBALS['system']->getDBObjectData('person', array('id' => (array) $_POST['personid']));
             $dummy = new Person();
             $dummy_family = new Family();
             break;
     }
     $headerrow = array('ID');
     foreach (array_keys(reset($merge_data)) as $header) {
         if ($header == 'familyid') {
             continue;
         }
         $headerrow[] = strtoupper($dummy->getFieldLabel($header));
     }
     fputcsv($fp, $headerrow);
     foreach ($merge_data as $id => $row) {
         @$dummy->populate($id, $row);
         $outputrow = array($id);
         foreach ($row as $k => $v) {
             if ($k == 'history') {
                 continue;
             }
             if ($k == 'familyid') {
                 continue;
             }
             if ($dummy->hasField($k)) {
                 $outputrow[] = $dummy->getFormattedValue($k, $v);
                 // pass value to work around read-only fields
             } else {
                 if ($dummy_family && $dummy_family->hasField($k)) {
                     $outputrow[] = $dummy_family->getFormattedValue($k, $v);
                 } else {
                     $outputrow[] = $v;
                 }
             }
         }
         fputcsv($fp, $outputrow);
     }
     fclose($fp);
 }
 private function getRecipients()
 {
     $recips = $archived = $blanks = array();
     if (!empty($_REQUEST['queryid'])) {
         $query = $GLOBALS['system']->getDBObject('person_query', (int) $_REQUEST['queryid']);
         $personids = $query->getResultPersonIDs();
         $recips = $GLOBALS['system']->getDBObjectData('person', array('(id' => $personids, '!mobile_tel' => '', '!status' => 'archived'), 'AND');
         $blanks = $GLOBALS['system']->getDBObjectData('person', array('(id' => $personids, 'mobile_tel' => '', '!status' => 'archived'), 'AND');
         $archived = $GLOBALS['system']->getDBObjectData('person', array('(id' => $personids, 'status' => 'archived'), 'AND');
     } else {
         if (!empty($_REQUEST['groupid'])) {
             $group = $GLOBALS['system']->getDBObject('person_group', (int) $_REQUEST['groupid']);
             $personids = array_keys($group->getMembers());
             $recips = $GLOBALS['system']->getDBObjectData('person', array('(id' => $personids, '!mobile_tel' => '', '!status' => 'archived'), 'AND');
             $blanks = $GLOBALS['system']->getDBObjectData('person', array('(id' => $personids, 'mobile_tel' => '', '!status' => 'archived'), 'AND');
             $archived = $GLOBALS['system']->getDBObjectData('person', array('(id' => $personids, 'status' => 'archived'), 'AND');
         } else {
             if (!empty($_REQUEST['roster_view'])) {
                 $view = $GLOBALS['system']->getDBObject('roster_view', (int) $_REQUEST['roster_view']);
                 $recips = $view->getAssignees($_REQUEST['start_date'], $_REQUEST['end_date']);
                 foreach ($recips as $i => $details) {
                     if ($details['status'] == 'archived') {
                         $archived[$i] = $details;
                         unset($recips[$i]);
                     } else {
                         if (empty($details['mobile_tel'])) {
                             $blanks[$i] = $details;
                             unset($recips[$i]);
                         }
                     }
                 }
             } else {
                 switch (array_get($_REQUEST, 'sms_type')) {
                     case 'family':
                         $GLOBALS['system']->includeDBClass('family');
                         $families = Family::getFamilyDataByMemberIDs($_POST['personid']);
                         $recips = $GLOBALS['system']->getDBObjectData('person', array('age_bracket' => '0', '(familyid' => array_keys($families), '!mobile_tel' => '', '!status' => 'archived'), 'AND');
                         $blanks = $GLOBALS['system']->getDBObjectData('person', array('age_bracket' => '0', '(familyid' => array_keys($families), 'mobile_tel' => '', '!status' => 'archived'), 'AND');
                         $archived = $GLOBALS['system']->getDBObjectData('person', array('age_bracket' => '0', '(familyid' => array_keys($families), 'status' => 'archived'), 'AND');
                         break;
                     case 'person':
                     default:
                         if (!empty($_POST['personid'])) {
                             $recips = $GLOBALS['system']->getDBObjectData('person', array('id' => $_POST['personid'], '!mobile_tel' => '', '!status' => 'archived'), 'AND');
                             $blanks = $GLOBALS['system']->getDBObjectData('person', array('id' => $_POST['personid'], 'mobile_tel' => '', '!status' => 'archived'), 'AND');
                             $archived = $GLOBALS['system']->getDBObjectData('person', array('id' => $_POST['personid'], 'status' => 'archived'), 'AND');
                             $GLOBALS['system']->includeDBClass('person');
                         }
                         break;
                 }
             }
         }
     }
     return array($recips, $blanks, $archived);
 }
    function run()
    {
        if (!empty($_REQUEST['print_popup'])) {
            $GLOBALS['system']->initErrorHandler();
        }
        $blanks = $archived = array();
        if (!empty($_REQUEST['queryid'])) {
            $query = $GLOBALS['system']->getDBObject('person_query', (int) $_REQUEST['queryid']);
            $personids = $query->getResultPersonIDs();
            $recips = $GLOBALS['system']->getDBObjectData('person', array('(id' => $personids, '!email' => '', '!status' => 'archived'), 'AND');
            $blanks = $GLOBALS['system']->getDBObjectData('person', array('(id' => $personids, 'email' => '', '!status' => 'archived'), 'AND');
            $archived = $GLOBALS['system']->getDBObjectData('person', array('(id' => $personids, 'status' => 'archived'), 'AND');
        } else {
            if (!empty($_REQUEST['groupid'])) {
                $group = $GLOBALS['system']->getDBObject('person_group', (int) $_REQUEST['groupid']);
                $personids = array_keys($group->getMembers());
                $recips = $GLOBALS['system']->getDBObjectData('person', array('(id' => $personids, '!email' => '', '!status' => 'archived'), 'AND');
                $blanks = $GLOBALS['system']->getDBObjectData('person', array('(id' => $personids, 'email' => '', '!status' => 'archived'), 'AND');
                $archived = $GLOBALS['system']->getDBObjectData('person', array('(id' => $personids, 'status' => 'archived'), 'AND');
            } else {
                if (!empty($_REQUEST['roster_view'])) {
                    $view = $GLOBALS['system']->getDBObject('roster_view', (int) $_REQUEST['roster_view']);
                    $recips = $view->getAssignees($_REQUEST['start_date'], $_REQUEST['end_date']);
                    // TODO: find email-less people here?
                } else {
                    switch (array_get($_REQUEST, 'email_type')) {
                        case 'family':
                            $GLOBALS['system']->includeDBClass('family');
                            $families = Family::getFamilyDataByMemberIDs($_POST['personid']);
                            $recips = $GLOBALS['system']->getDBObjectData('person', array('age_bracket' => '0', '(familyid' => array_keys($families), '!email' => '', '!status' => 'archived'), 'AND');
                            $blanks = $GLOBALS['system']->getDBObjectData('person', array('age_bracket' => '0', '(familyid' => array_keys($families), 'email' => '', '!status' => 'archived'), 'AND');
                            $archived = $GLOBALS['system']->getDBObjectData('person', array('age_bracket' => '0', '(familyid' => array_keys($families), 'status' => 'archived'), 'AND');
                            break;
                        case 'person':
                        default:
                            $recips = $GLOBALS['system']->getDBObjectData('person', array('id' => $_POST['personid'], '!email' => '', '!status' => 'archived'), 'AND');
                            $blanks = $GLOBALS['system']->getDBObjectData('person', array('id' => $_POST['personid'], 'email' => '', '!status' => 'archived'), 'AND');
                            $archived = $GLOBALS['system']->getDBObjectData('person', array('id' => $_POST['personid'], 'status' => 'archived'), 'AND');
                            $GLOBALS['system']->includeDBClass('person');
                            break;
                    }
                }
            }
        }
        $emails = array();
        foreach ($recips as $recip) {
            $emails[$recip['email']] = 1;
        }
        $emails = array_keys($emails);
        if (!empty($_REQUEST['show_modal'])) {
            $this->printModal($emails, $archived, $blanks);
        } else {
            if (!empty($_REQUEST['print_popup'])) {
                $this->printPopup($emails, $archived, $blanks);
            } else {
                if (count($emails) > EMAIL_CHUNK_SIZE || !empty($blanks)) {
                    $this->launchPopupFromHiddenIframe($blanks);
                } else {
                    if (count($emails) > 0) {
                        $public = array_get($_REQUEST, 'method') == 'public';
                        ?>
			<a id="mailto" href="<?php 
                        echo $this->getHref($emails, $public);
                        ?>
" target="_parent" <?php 
                        echo email_link_extras();
                        ?>
>Send email</a>
			<script>document.getElementById('mailto').click();</script>
			<?php 
                    } else {
                        ?>
			<script>alert('None of the selected persons have email addresses in the system');</script>
			<?php 
                    }
                }
            }
        }
    }
    function printView()
    {
        $recips = $successes = $failures = $archived = $blanks = array();
        if (!empty($_REQUEST['queryid'])) {
            $query = $GLOBALS['system']->getDBObject('person_query', (int) $_REQUEST['queryid']);
            $personids = $query->getResultPersonIDs();
            $recips = $GLOBALS['system']->getDBObjectData('person', array('(id' => $personids, '!mobile_tel' => '', '!status' => 'archived'), 'AND');
            $blanks = $GLOBALS['system']->getDBObjectData('person', array('(id' => $personids, 'mobile_tel' => '', '!status' => 'archived'), 'AND');
            $archived = $GLOBALS['system']->getDBObjectData('person', array('(id' => $personids, 'status' => 'archived'), 'AND');
        } else {
            if (!empty($_REQUEST['groupid'])) {
                $group = $GLOBALS['system']->getDBObject('person_group', (int) $_REQUEST['groupid']);
                $personids = array_keys($group->getMembers());
                $recips = $GLOBALS['system']->getDBObjectData('person', array('(id' => $personids, '!mobile_tel' => '', '!status' => 'archived'), 'AND');
                $blanks = $GLOBALS['system']->getDBObjectData('person', array('(id' => $personids, 'mobile_tel' => '', '!status' => 'archived'), 'AND');
                $archived = $GLOBALS['system']->getDBObjectData('person', array('(id' => $personids, 'status' => 'archived'), 'AND');
            } else {
                if (!empty($_REQUEST['roster_view'])) {
                    $view = $GLOBALS['system']->getDBObject('roster_view', (int) $_REQUEST['roster_view']);
                    $recips = $view->getAssignees($_REQUEST['start_date'], $_REQUEST['end_date']);
                    foreach ($recips as $i => $details) {
                        if ($details['status'] == 'archived') {
                            $archived[$i] = $details;
                            unset($recips[$i]);
                        } else {
                            if (empty($details['mobile_tel'])) {
                                $blanks[$i] = $details;
                                unset($recips[$i]);
                            }
                        }
                    }
                } else {
                    switch (array_get($_REQUEST, 'sms_type')) {
                        case 'family':
                            $GLOBALS['system']->includeDBClass('family');
                            $families = Family::getFamilyDataByMemberIDs($_POST['personid']);
                            $recips = $GLOBALS['system']->getDBObjectData('person', array('age_bracket' => '0', '(familyid' => array_keys($families), '!mobile_tel' => '', '!status' => 'archived'), 'AND');
                            $blanks = $GLOBALS['system']->getDBObjectData('person', array('age_bracket' => '0', '(familyid' => array_keys($families), 'mobile_tel' => '', '!status' => 'archived'), 'AND');
                            $archived = $GLOBALS['system']->getDBObjectData('person', array('age_bracket' => '0', '(familyid' => array_keys($families), 'status' => 'archived'), 'AND');
                            break;
                        case 'person':
                        default:
                            if (!empty($_POST['personid'])) {
                                $recips = $GLOBALS['system']->getDBObjectData('person', array('id' => $_POST['personid'], '!mobile_tel' => '', '!status' => 'archived'), 'AND');
                                $blanks = $GLOBALS['system']->getDBObjectData('person', array('id' => $_POST['personid'], 'mobile_tel' => '', '!status' => 'archived'), 'AND');
                                $archived = $GLOBALS['system']->getDBObjectData('person', array('id' => $_POST['personid'], 'status' => 'archived'), 'AND');
                                $GLOBALS['system']->includeDBClass('person');
                            }
                            break;
                    }
                }
            }
        }
        if (empty($recips)) {
            print_message("Did not find any recipients with mobile numbers.  Message not sent.", 'error');
        } else {
            $mobile_tels = array();
            foreach ($recips as $recip) {
                $mobile_tels[$recip['mobile_tel']] = 1;
            }
            $mobile_tels = array_keys($mobile_tels);
            $message = $_POST['message'];
            if (empty($message) || strlen($message) > SMS_MAX_LENGTH) {
                print_message("Your message is empty or too long", "error");
                return;
            }
            $content = SMS_HTTP_POST_TEMPLATE;
            $content = str_replace('_USER_MOBILE_', urlencode($GLOBALS['user_system']->getCurrentUser('mobile_tel')), $content);
            $content = str_replace('_USER_EMAIL_', urlencode($GLOBALS['user_system']->getCurrentUser('email')), $content);
            $content = str_replace('_MESSAGE_', urlencode($message), $content);
            $content = str_replace('_RECIPIENTS_COMMAS_', urlencode(implode(',', $mobile_tels)), $content);
            $content = str_replace('_RECIPIENTS_NEWLINES_', urlencode(implode("\n", $mobile_tels)), $content);
            $opts = array('http' => array('method' => 'POST', 'content' => $content, 'header' => "Content-Length: " . strlen($content) . "\r\n" . "Content-Type: application/x-www-form-urlencoded\r\n"));
            $response = '';
            $fp = fopen(SMS_HTTP_URL, 'r', false, stream_context_create($opts));
            if ($fp) {
                $response = stream_get_contents($fp);
                fclose($fp);
            }
            if (empty($response)) {
                add_message('Failed communicating with SMS server - please check your config', 'failure');
                return;
            }
            $response = str_replace("\r", '', $response);
            if (SMS_HTTP_RESPONSE_OK_REGEX) {
                foreach ($recips as $id => $recip) {
                    $pattern = '/' . str_replace('_RECIPIENT_', preg_quote($recip['mobile_tel']), SMS_HTTP_RESPONSE_OK_REGEX) . '/m';
                    if (preg_match($pattern, $response)) {
                        $successes[$id] = $recip;
                    } else {
                        $failures[$id] = $recip;
                    }
                }
                if (!empty($successes)) {
                    print_message('SMS sent successfully to ' . count($successes) . ' recipients');
                    $this->logSuccess(count($successes), $message);
                }
                if (!empty($failures)) {
                    print_message('SMS sending failed for ' . count($failures) . ' recipients', 'failure');
                    ?>
					<p><b>Sending an SMS to the following recipients failed.  <span class="clickable" onclick="$('#response').toggle()">Show server response</span></b></p>
					<div class="hidden standard" id="response"><?php 
                    bam($response);
                    ?>
</div>
					<?php 
                    $persons = $failures;
                    require 'templates/person_list.template.php';
                }
            } else {
                // No check of the response - give a less confident success message
                print_message('SMS sent to ' . count($recips) . ' recipients');
                $this->logSuccess(count($recips), $message);
                ?>
				<span class="clickable" onclick="$('#response').toggle()">Show SMS server response</span></b></p>
				<div class="hidden standard" id="response"><?php 
                bam($response);
                ?>
</div>
				<?php 
            }
        }
        if (!empty($archived)) {
            ?>
			<h4>Archived Recipients</h4>
			<p style="clear: both"><?php 
            echo count($archived);
            ?>
 of the intended recipients were not sent the message because they are archived.</p>
			<?php 
        }
        if (!empty($blanks)) {
            ?>
			<h4>Recipients with blank mobile number</h4>
			<p style="clear:both">The following persons were not sent the message because they don't have a mobile number recorded:</b>
			<?php 
            $persons = $blanks;
            $include_special_fields = FALSE;
            require 'templates/person_list.template.php';
        }
        if (empty($archived) && empty($blanks)) {
            ?>
			<a href="javascript:window.history.back()" class="btn"><i class="icon-chevron-left"></i> Back</a>
			<?php 
        }
    }
    function run()
    {
        //Handle special IE contype request
        if (isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT'] == 'contype') {
            header('Content-Type: application/pdf');
            exit;
        }
        $env = new Envelope_List();
        $GLOBALS['system']->includeDBClass('family');
        if (!empty($_REQUEST['familyid'])) {
            $family =& $GLOBALS['system']->getDBObject('family', (int) $_REQUEST['familyid']);
            $env->addAddress($family->getAdultMemberNames() . "\n" . $family->getPostalAddress());
        }
        if (!empty($_REQUEST['personid'])) {
            if (is_array($_REQUEST['personid'])) {
                $families = Family::getFamilyDataByMemberIDs($_REQUEST['personid']);
                $addressee = array_get($_REQUEST, 'addressee', 'persons');
                $dummy = new Family();
                foreach ($families as $id => $family) {
                    if (empty($family['address_street'])) {
                        continue;
                    }
                    $dummy->populate($id, $family);
                    if ($addressee == 'family') {
                        $to = $family['family_name'] . " Family";
                    } else {
                        if ($addressee == 'adults') {
                            $to = $dummy->getAdultMemberNames();
                        } else {
                            if (count(explode(',', $family['selected_lastnames'])) == 1) {
                                $to = $family['selected_firstnames'] . ' ' . $family['selected_lastnames'];
                            } else {
                                $firstnames = explode(',', $family['selected_firstnames']);
                                $lastnames = explode(',', $family['selected_lastnames']);
                                $common_name = TRUE;
                                foreach ($lastnames as $lastname) {
                                    if ($lastname != reset($lastnames)) {
                                        $common_name = FALSE;
                                    }
                                }
                                if ($common_name) {
                                    $final = array_pop($firstnames);
                                    $to = implode(', ', $firstnames) . ' and ' . $final . ' ' . reset($lastnames);
                                } else {
                                    $tos = array();
                                    foreach ($firstnames as $i => $firstname) {
                                        $tos[] = $firstname . ' ' . $lastnames[$i];
                                    }
                                    $final = array_pop($tos);
                                    $to = implode(', ', $tos) . ' and ' . $final;
                                }
                            }
                        }
                    }
                    $env->addAddress($to . "\n" . $dummy->getPostalAddress());
                }
            } else {
                $person =& $GLOBALS['system']->getDBObject('person', (int) $_REQUEST['personid']);
                $family =& $GLOBALS['system']->getDBObject('family', $person->getValue('familyid'));
                $env->addAddress($person->toString() . "\n" . $family->getPostalAddress());
            }
        }
        if (empty($env->pages)) {
            ?>
			<script>
			alert("No addresses were found for the specified families");
			window.close();
			</script>
			<?php 
        } else {
            $env->output();
        }
    }
 protected function getMergeData()
 {
     $merge_type = array_get($_REQUEST, 'merge_type', 'person');
     switch ($merge_type) {
         case 'family':
             $GLOBALS['system']->includeDBClass('family');
             $merge_data = Family::getFamilyDataByMemberIDs($_POST['personid']);
             $dummy = new Family();
             break;
         case 'person':
         default:
             $temp_merge_data = $GLOBALS['system']->getDBObjectData('person', array('id' => $_POST['personid']));
             $merge_data = array();
             foreach ($_REQUEST['personid'] as $id) {
                 $merge_data[$id] = $temp_merge_data[$id];
             }
             $GLOBALS['system']->includeDBClass('person');
             $dummy = new Person();
             break;
     }
     foreach ($merge_data as $id => $row) {
         @$dummy->populate($id, $row);
         foreach ($row as $k => $v) {
             if ($k == 'history') {
                 unset($merge_data[$id][$k]);
             }
             if ($dummy->hasField($k)) {
                 $merge_data[$id][$k] = $dummy->getFormattedValue($k);
             }
             if ($k == 'selected_firstnames') {
                 $merge_data[$id]['selected_members'] = $v;
             }
         }
     }
     return $merge_data;
 }