static function printFormFields()
    {
        ?>
		<input type="hidden" id="size-detector-width" name="_sizeDetector[width]" value="" />
		<input type="hidden" id="size-detector-height" name="_sizeDetector[height]" value="" />
		<script>
		$(document).ready(function() {
			var w=window,d=document,e=d.documentElement,g=d.getElementsByTagName('body')[0],x=w.innerWidth||e.clientWidth||g.clientWidth,y=w.innerHeight||e.clientHeight||g.clientHeight;
			$('#size-detector-width').val(x);
			$('#size-detector-height').val(y);
			if (-1 != document.location.href.indexOf('showsize=1')) {
				document.write('<p>'+x+' x '+y+'</p>');
				document.write('<p>Jquery:'+$(document).width()+' x '+$(document).height()+'</p>');
			}
		});
		</script>
		<?php 
        if (!empty($_REQUEST['showsize'])) {
            bam($_SERVER['HTTP_USER_AGENT']);
        }
    }
}
//end if
$fbm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('funnelback_manager');
$collections = $fbm->getCollections();
foreach ($collections as $index => $collection) {
    $file_paths = array();
    $all_good = TRUE;
    printCollection($index, $collection['name']);
    $data_path = $fbm->getCollectionDataPath($index) . '/conf/';
    $file_paths['contextual_navigation.cfg'] = 'fluster.cfg';
    $file_paths['query_expansion.cfg'] = 'synonyms.cfg';
    $file_paths['best_bets.cfg'] = 'featured_pages.cfg';
    foreach ($file_paths as $new_path => $file_path) {
        if (file_exists($data_path . $file_path)) {
            if (!copy($data_path . $file_path, $data_path . $new_path)) {
                bam($data_path . $file_path);
                $all_good = FALSE;
            }
        }
    }
    if ($all_good) {
        printUpdateStatus('OK');
    } else {
        printUpdateStatus('FAILED');
    }
}
/**
* Prints the name of the collection as a padded string
*
* Pads name to 40 columns
*
    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 
        }
    }
}
$to_remove = array();
foreach ($list_members['data'] as $member) {
    if (!isset($report_members[strtolower($member['email'])])) {
        $to_remove[] = $member['email'];
    }
}
if ($DEBUG > 1) {
    bam("LIST MEMBERS:");
    bam($list_members);
    bam("==================");
}
if ($DEBUG && !empty($to_remove)) {
    bam("TO REMOVE:");
    bam($to_remove);
    bam("==================");
}
if (!empty($to_remove) && !$DRYRUN) {
    $api->listBatchUnsubscribe($list_id, $to_remove, true, false, false);
    // delete them completely; don't send goodbye; don't send notification to admin.
}
if (!empty($api->errorMessage)) {
    trigger_error("Mailchimp API Error calling listBatchUnsubscribe(): " . $api->errorMessage, E_USER_ERROR);
}
exit(0);
//// HELPER FUNCTION ////
function getMergeVars($person_data, $email)
{
    static $dummy_person = null;
    if (is_null($dummy_person)) {
        $GLOBALS['system']->includeDBClass('person');
    $result = $db->query($select);
    assert_valid_db_result($result);
    while (DB_OK === $result->fetchInto($row)) {
        $with_custom_attr_assets_id = array_merge($with_custom_attr_assets_id, array($row['assetid']));
    }
    $result->free();
}
if ($verbose) {
    bam('page_asset_listing ids of assets with custom attribute');
    bam($with_custom_attr_assets_id);
}
// find the assets that we need to create a custom attribute
$create_custom_attr_id = array_diff($assets_id, $with_custom_attr_assets_id);
if ($verbose) {
    bam('Assets that need to have a custom value');
    bam($create_custom_attr_id);
}
// USER MANUAL
echo "\n\n";
echo "***************************************************************\n";
echo "* WARNING: DOUBLE CHECK THE SQL QUERIES BEFORE EXECUTING THEM *\n";
echo "***************************************************************\n\n";
// USER MANUAL
echo "\n\n";
echo '*****************************************************************************' . "\n";
echo '* TO SET THE METADATA SORTING OPTION TO "RAW" RUN THE FOLLOWING SQL QUERIES *' . "\n";
echo '*****************************************************************************' . "\n\n";
// create a custom value for the assets
foreach ($create_custom_attr_id as $id) {
    echo 'INSERT INTO sq_ast_attr_val(assetid, attrid, custom_val) values (\'' . $id . '\', \'' . $attribute_id . '\', \'raw\');' . "\n";
}
Example #6
0
// Then, for all list members, check if they are in the report members list and if not add them to the "remove" list.
$list_members = $api->listMembers($list_id, 'subscribed', null, 0, 10000);
if (!empty($api->errorMessage)) {
    trigger_error("Mailchimp API Error calling listMembers(): " . $api->errorMessage, E_USER_ERROR);
}
$to_remove = array();
foreach ($list_members['data'] as $member) {
    if (!isset($report_members[$member['email']])) {
        $to_remove[] = $member['email'];
    }
}
if ($DEBUG) {
    bam("LIST MEMBERS:");
    bam($list_members);
    bam("TO REMOVE:");
    bam($to_remove);
}
if (!empty($to_remove)) {
    $api->listBatchUnsubscribe($list_id, $to_remove, true, false, false);
    // delete them completely; don't send goodbye; don't send notification to admin.
}
if (!empty($api->errorMessage)) {
    trigger_error("Mailchimp API Error calling listBatchUnsubscribe(): " . $api->errorMessage, E_USER_ERROR);
}
exit(0);
//// HELPER FUNCTION ////
function getMergeVars($person_data, $email)
{
    static $dummy_person = null;
    if (is_null($dummy_person)) {
        $GLOBALS['system']->includeDBClass('person');
/**
*
* @param string	$file	the file to run through
*
* @return boolean
* @access public
*/
function process_errors_file($path, $file)
{
    bam('ERRORS ' . $file);
    $xml_object = new XML_Tree($file);
    $root = $xml_object->getTreeFromFile();
    assert_equals($root->name, 'files');
    echo $locale = $root->attributes['locale'];
    for (reset($root->children); null !== ($file_index = key($root->children)); next($root->children)) {
        $file_tag =& $root->children[$file_index];
        $file_name = $path . '/' . $file_tag->attributes['source'] . '/' . $locale . '/lang_errors.xml';
        // now create the file (and directory if required)
        create_directory($path . '/' . $file_tag->attributes['source'] . '/' . $locale);
        string_to_file($file_tag->children[0]->get(), $file_name);
    }
    return true;
}
    public function printView()
    {
        ?>
		<p>Some of the following settings can be edited on this page.  Other settings are read only on this page, but can be adjusted by getting your 
		<?php 
        if (defined('SYSADMIN_HREF')) {
            echo '<a href="' . SYSADMIN_HREF . '">';
        }
        ?>
		system administrator
		<?php 
        if (defined('SYSADMIN_HREF')) {
            echo '</a>';
        }
        ?>
		to edit the Jethro configuration file.</p>
		<table class="table no-autofocus system-config">
			<tr>
				<td colspan="2"><h3>Overall system settings</h3></td>
			</tr>
			<tr>
				<th>System Name</th>
				<td><?php 
        echo SYSTEM_NAME;
        ?>
</td>
			</tr>
			<tr>
				<th>Base URL</th>
				<td><?php 
        echo BASE_URL;
        ?>
</td>
			</tr>
			<tr>
				<th>Require HTTPS</th>
				<td><?php 
        echo REQUIRE_HTTPS ? 'Yes' : 'No';
        ?>
</td>
			</tr>
			<tr>
				<td colspan="2"><h3>Jethro behaviour settings</h3></td>
			</tr>
			<tr>
				<th>Enabled Features</th>
				<td>
					<?php 
        $enabled = explode(',', ENABLED_FEATURES);
        foreach (explode(',', 'NOTES,PHOTOS,DATES,ATTENDANCE,ROSTERS&SERVICES,SERVICEDETAILS,DOCUMENTS,SERVICEDOCUMENTS') as $feature) {
            echo '<i class="icon-' . (in_array($feature, $enabled) ? 'ok-sign' : 'ban-circle') . '"></i>' . $feature . '<br />';
        }
        ?>
				</td>
			</tr>
			<tr>
				<th>Require note when adding new family?</th>
				<td><?php 
        echo REQUIRE_INITIAL_NOTE ? 'Yes' : 'No';
        ?>
</td>
			</tr>
			<tr>
				<th>Attendance list order</th>
				<td><?php 
        echo ATTENDANCE_LIST_ORDER;
        ?>
					<br /><small>When recording attendance, persons will be listed in this order</small>
				</td>
			</tr>
			<tr>
				<th>Chunk size for listings</th>
				<td>
					<?php 
        echo CHUNK_SIZE;
        ?>
					<br /><small>When listing all persons or families, Jethro will paginate the results and aim for this number per page (up to a maximum of 26 pages).</small>
				
				</td>
			</tr>			
			<tr>
				<th>Lock length for editing objects</th>
				<td><?php 
        echo LOCK_LENGTH;
        ?>
					<br /><small>When you open an object for editing, Jethro will prevent other users from editing the object for this long.  You will need to save your changes within this timeframe.</small>
				</td>
			</tr>

			<tr>
				<td colspan="2"><h3>Security settings</h3></td>
			</tr>
			<tr>
				<th>Default Permissions</th>
				<td>
				<?php 
        $GLOBALS['system']->includeDBClass('staff_member');
        $sm = new Staff_Member();
        $sm->printFieldValue('permissions', DEFAULT_PERMISSIONS);
        ?>
				</td>
			</tr>
			<tr>
				<th>Session Inactivity Timeout</th>
				<td>
					<?php 
        echo defined('SESSION_TIMEOUT_MINS') && SESSION_TIMEOUT_MINS > 0 ? SESSION_TIMEOUT_MINS : 90;
        ?>
mins
					<br /><small>Users will be asked to log in again if they haven't done anything for this length of time.  This is important for security, especially on mobile devices.</small>
				</td>
			</tr>
			<tr>
				<th>Maximum Session Length</th>
				<td>
					<?php 
        $val = defined('SESSION_MAXLENGTH_MINS') && SESSION_MAXLENGTH_MINS > 0 ? SESSION_MAXLENGTH_MINS : 8 * 60;
        if ($val % 60 == 0 && $val > 60) {
            echo $val / 60 . ' hours';
        } else {
            echo $val . ' mins';
        }
        ?>
					<br /><small>Active users will be asked to log in again after this length of time.  This is important for security, especially on mobile devices.</small>
				</td>
			</tr>			
			<tr>
				<td colspan="2"><h3>Jethro data structure settings</h3></td>
			</tr>
			<tr>
				<th>Person Status Options</th>
				<td><?php 
        echo PERSON_STATUS_OPTIONS;
        ?>
 (Default <?php 
        echo PERSON_STATUS_DEFAULT;
        ?>
)</td>
			</tr>
			<tr>
				<th>Age Bracket Options</th>
				<td>
					<?php 
        echo AGE_BRACKET_OPTIONS;
        ?>
					<br /><small>This list must always begin with 'adult'</small>
				</td>
			</tr>
			<tr>
				<th>Group Membership Status Options</th>
				<td>
					<form method="post">
					<input type="hidden" name="group_membership_statuses_submitted" value="1" />
					<table class="table-condensed expandable table-bordered table-auto-width">
						<thead>
							<tr>
								<th>ID</th>
								<th>Label</th>
								<th>Default?</th>
								<th>Re-order</th>
								<th>Delete?</th>
							</tr>
						</thead>
						<tbody>
					<?php 
        $GLOBALS['system']->includeDBClass('person_group');
        list($options, $default) = Person_Group::getMembershipStatusOptionsAndDefault();
        $options[null] = '';
        $i = 0;
        foreach ($options as $id => $label) {
            ?>
						<tr>
							<td>
								<?php 
            if ($id) {
                echo $id;
                echo '<input type="hidden" name="membership_status_' . $i . '_id" value="' . $id . '" />';
            }
            echo '<input type="hidden" name="membership_status_ranking[]" value="' . $i . '" />';
            ?>
							</td>
							<td><input type="text" name="membership_status_<?php 
            echo $i;
            ?>
_label" value="<?php 
            echo ents($label);
            ?>
" /></td>
							<td><input type="radio" name="membership_status_default_rank" value="<?php 
            echo $i;
            ?>
" <?php 
            if ($id == $default) {
                echo 'checked="checked"';
            }
            ?>
 /></td>
							<td>
								<img src="<?php 
            echo BASE_URL;
            ?>
/resources/img/arrow_up_thin_black.png" class="icon move-row-up" title="Move this role up" />
								<img src="<?php 
            echo BASE_URL;
            ?>
/resources/img/arrow_down_thin_black.png" class="icon move-row-down" title="Move this role down" />
							</td>
							<td>
								<?php 
            if ($id) {
                ?>
									<input type="checkbox" name="membership_status_delete[]" data-toggle="strikethrough" data-target="row" value="<?php 
                echo $id;
                ?>
" />
									<?php 
            }
            ?>
							</td>

						</tr>
						<?php 
            $i++;
        }
        ?>
					</table>
					<input type="submit" value="Save" class="btn" />
					</form>
				</td>
			</tr>
			<tr>
				<td colspan="2"><h3>Rosters and Services</h3></td>
			</tr>
			<tr>
				<th>Roster Weeks Default</th>
				<td>
					<?php 
        echo ROSTER_WEEKS_DEFAULT;
        ?>
					<br /><small>By default, rosters will display this number of weeks in the future.</small>
				</td>
			</tr>
			<tr>
				<th>Roster repeat date threshold</th>
				<td>
					<?php 
        echo REPEAT_DATE_THRESHOLD;
        ?>
					<br /><small>If a roster has more than this number of columns, the date column will be repeated on the right hand side</small>
				</td>
			</tr>
			<tr>
				<th>Service Documents: Folders to populate</th>
				<td>
					<?php 
        if (SERVICE_DOCS_TO_POPULATE_DIRS) {
            echo implode('<br />', explode('|', SERVICE_DOCS_TO_POPULATE_DIRS));
        }
        ?>
				</td>
			</tr>
			<tr>
				<th>Service Documents: Folders to expand</th>
				<td>
					<?php 
        if (SERVICE_DOCS_TO_EXPAND_DIRS) {
            echo implode('<br />', explode('|', SERVICE_DOCS_TO_POPULATE_DIRS));
        }
        ?>
				</td>
			</tr>

			<tr>
				<td colspan="2"><h3>External tools</h3></td>
			</tr>
			<tr>
				<th>Bible reference URL</th>
				<td>
					<?php 
        echo BIBLE_URL;
        ?>
					<br /><small>Bible references in rosters will be linked using this URL template</small>
				</td>
			</tr>
			<tr>
				<th>Maps URL</th>
				<td>
					<?php 
        echo MAP_LOOKUP_URL;
        ?>
					<br /><small>The "map" link displayed next to a family's address uses this URL template</small>
				</td>
			</tr>
			<tr>
				<th>Email chunk size</th>
				<td>
					<?php 
        echo EMAIL_CHUNK_SIZE;
        ?>
					<br /><small>Email servers can only handle a limited number of recipients per email.  When constructing email links to multiple persons, Jethro will divide the list into several links if there are more than this number of recipients.</small>
				</td>
			</tr>
			<tr>
				<th>SMS Gateway</th>
				<td>
					<?php 
        echo SMS_HTTP_URL;
        ?>
<br />
					<?php 
        echo SMS_HTTP_POST_TEMPLATE && SMS_HTTP_RESPONSE_OK_REGEX ? 'See details in config file' : '<b>Not fully configured.<b>';
        ?>
                    <?php 
        echo ifdef('SMS_HTTP_HEADER_TEMPLATE') ? '' : ' No additional headers configured.';
        ?>
			</tr>
			<tr>
				<th>Max length for SMS messages</th>
				<td>
					<?php 
        echo SMS_MAX_LENGTH;
        ?>
					<br /><small>160 characters is generally a one-part SMS. Longer messages will be sent in several parts and will cost more.</small>
				</td>
			</tr>
            <tr>
              <th>Default to saving sent SMS as note</th>
              <td>
                <?php 
        echo ifdef('SMS_SAVE_TO_NOTE_BY_DEFAULT', 0);
        ?>
                <br />
              </td>
            </tr>
            <tr>
              <th>Default Subject for SMS saved as a note</th>
              <td>
                <?php 
        echo ifdef('SMS_SAVE_TO_NOTE_SUBJECT', '');
        ?>
                <br />
              </td>
            </tr>
			<tr>
				<th>Logging of SMS sending</th>
				<td>
					<?php 
        echo SMS_SEND_LOGFILE ? 'Configured' : 'Not configured';
        ?>
					<br /><small>This allows you to track how many SMSes each user is sending via Jethro.</small>
				</td>
			</tr>
			<tr>
				<td colspan="2"><h3>Locale settings</h3></td>
			</tr>

			<tr>
				<th>Timezone</th>
				<td><?php 
        echo defined('TIMEZONE') ? TIMEZONE : '(Server default)';
        ?>
</td>
			</tr>
			<tr>
				<th>Label for the Address 'suburb' field</th>
				<td><?php 
        echo defined('ADDRESS_SUBURB_LABEL') ? ADDRESS_SUBURB_LABEL : 'Suburb';
        ?>
</td>
			</tr>
			<tr>
				<th>Label for the address 'state' field</th>
				<td>
					<?php 
        if (!defined('ADDRESS_STATE_LABEL')) {
            echo 'State';
        } else {
            if (ADDRESS_STATE_LABEL) {
                echo ADDRESS_STATE_LABEL;
            } else {
                echo '(State field disabled)';
            }
        }
        echo '<br /><small>The state field can be hidden altogether by setting this to blank</small>';
        ?>
				</td>
			</tr>
			<tr>
				<th>Options for the Address 'state' field</th>
				<td><?php 
        echo ADDRESS_STATE_OPTIONS;
        ?>
  (Default: <?php 
        echo ADDRESS_STATE_DEFAULT;
        ?>
)</td>
			</tr>
			<tr>
				<th>Label for the address 'postcode' field</th>
				<td><?php 
        echo defined('ADDRESS_POSTCODE_LABEL') ? ADDRESS_POSTCODE_LABEL : 'Postcode';
        ?>
</td>
			</tr>
			<tr>
				<th>Valid formats for the address 'postcode' field</th>
				<td><?php 
        echo ADDRESS_POSTCODE_WIDTH . ' characters matching the expression ' . ADDRESS_POSTCODE_REGEX;
        ?>
</td>
			</tr>
			<tr>
				<th>Postcode lookup URL</th>
				<td>
					<?php 
        echo POSTCODE_LOOKUP_URL;
        ?>
					<br /><small>When editing an address, the "look up <?php 
        echo defined('ADDRESS_POSTCODE_LABEL') ? ADDRESS_POSTCODE_LABEL : 'postcode';
        ?>
" link uses this URL</small>
				</td>
			</tr>
			<tr>
				<th>Envelope Size</th>
				<td><?php 
        echo ENVELOPE_WIDTH_MM . 'mm x ' . ENVELOPE_HEIGHT_MM . 'mm';
        ?>
</td>
			</tr>


			<tr>
				<th>Formats for the home phone field</th>
				<td>
					<?php 
        echo nl2br(HOME_TEL_FORMATS);
        ?>
					<br /><small>When a phone number is displayed, it is laid out using these formats. When a phone number is entered, Jethro makes sure it has the right number of digits to match one of these formats.</small>
				</td>
			</tr>
			<tr>
				<th>Formats for the work phone field</th>
				<td><?php 
        echo nl2br(HOME_TEL_FORMATS);
        ?>
</td>
			</tr>
			<tr>
				<th>Formats for the mobile phone field</th>
				<td><?php 
        echo nl2br(MOBILE_TEL_FORMATS);
        ?>
</td>
			</tr>

			<tr>
				<td colspan="2"><h3>Appearance Settings</h3></td>
			</tr>
			<tr>
				<th>Custom Colours</th>
				<td><?php 
        $customLessVars = defined('CUSTOM_LESS_VARS') ? constant('CUSTOM_LESS_VARS') : NULL;
        $customCSSFile = 'jethro-' . JETHRO_VERSION . '-custom.css';
        if (file_exists(JETHRO_ROOT . '/' . $customCSSFile)) {
            ?>
						Jethro is using the custom CSS file <?php 
            echo $customCSSFile;
            ?>
<br />
						<?php 
            if ($customLessVars) {
                ?>
							The following <a href="http://lesscss.org/">LESS</a> variables are set in the conf file:
							<?php 
                bam($customLessVars);
                ?>
							To adjust these colours, first delete <?php 
                echo $customCSSFile;
                ?>
 from your jethro directory.  Then edit your conf.php file, and when happy with the changes, come back to this page to re-save the custom CSS file.
							<?php 
            }
        } else {
            if ($customLessVars) {
                ?>
						The following <a href="http://lesscss.org/">LESS</a> variables are set in the conf file:
						<?php 
                bam($customLessVars);
                ?>
						<b>These changes have not been saved to a custom CSS file,
							so Jethro is building the CSS on every page load.</b>
						For production environments you should
						<span class="clickable" onclick="TBLib.downloadText($(document.head).find('style[id^=less]').get(0).innerHTML, '<?php 
                echo $customCSSFile;
                ?>
')">download the compiled CSS</span>
						and save it in your main Jethro folder.
						<?php 
            }
        }
        ?>
				</td>
			</tr>

		</table>
		<?php 
    }
$pages = file($import_file);
$GLOBALS['SQ_SYSTEM']->setRunLevel(SQ_RUN_LEVEL_FORCED);
$csv_fd = fopen($import_file, 'r');
$line_number = 1;
while (($data = fgetcsv($csv_fd, 1024, ',')) !== FALSE) {
    if (count($data) != 4) {
        echo "Wrong number of arguments passed on line #{$line_number} : " . implode(', ', $data) . "\n";
        $line_number++;
        continue;
    }
    $GLOBALS['SQ_SYSTEM']->am->includeAsset(trim($data[1]));
    $parent_asset = $GLOBALS['SQ_SYSTEM']->am->getAsset(trim($data[2]), '', TRUE);
    if (is_null($parent_asset)) {
        echo "New parent asset #{$data[2]} does not exist on line #{$line_number}\n";
        $line_number++;
        continue;
    }
    $import_link = array('asset' => &$parent_asset, 'link_type' => $data[3]);
    $new_asset_type = trim($data[1]);
    $new_page = new $new_asset_type();
    $new_page->setAttrValue('name', trim($data[0]));
    if (!$new_page->create($import_link)) {
        echo 'Failed to import ' . $new_asset_type . ' ' . trim($data[0]);
        $line_number++;
        continue;
    } else {
        bam('New ' . $new_page->type() . ' asset created for ' . trim($data[0]) . ' - asset ID #' . $new_page->id);
    }
    $line_number++;
}
$GLOBALS['SQ_SYSTEM']->restoreRunLevel();
    public function printView()
    {
        $recips = $successes = $failures = $archived = $blanks = array();
        list($recips, $blanks, $archived) = $this->getRecipients();
        if (empty($recips)) {
            print_message("Did not find any recipients with mobile numbers.  Message not sent.", 'error');
        } else {
            $message = $_POST['message'];
            if (empty($message) || strlen($message) > SMS_MAX_LENGTH) {
                print_message("Your message is empty or too long", "error");
                return;
            }
            $sendResponse = SMS_Sender::send($message, $recips);
            $success = $sendResponse['success'];
            $successes = $sendResponse['successes'];
            $failures = $sendResponse['failures'];
            if (!$success) {
                add_message('Failed communicating with SMS server - please check your config', 'failure');
                return;
            }
            if (!empty($successes) || !empty($failures)) {
                if (!empty($successes)) {
                    print_message('SMS sent successfully to ' . count($successes) . ' recipients');
                    $this->saveAsNote($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 technical details</span></b></p>
					<div style="display: none" class="well error" id="response"><?php 
                    bam($sendResponse['rawrequest']);
                    bam($sendResponse['rawresponse']);
                    ?>
</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 dispatched to ' . count($recips) . ' recipients');
                ?>
				<span class="clickable" onclick="$('#response').toggle()">Show SMS server response</span></b></p>
				<div class="hidden standard" id="response"><?php 
                $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 
        }
    }