Ejemplo n.º 1
0
    function printView()
    {
        if ($this->_group) {
            ?>
			<h3>Group Details</h3>
			<table class="table-full-width">
				<tr>
					<th class="narrow" style="padding-bottom: 10px">Category</th>
					<td><?php 
            $this->_group->printFieldValue('categoryid');
            ?>
&nbsp;&nbsp;</td>
					<th class="narrow hidden-phone">Record Attendance?</th>
					<td class="hidden-phone"><?php 
            $this->_group->printFieldValue('attendance_recording_days');
            ?>
</td>
					<td class="align-right">
						<a class="link-collapse" href="?view=_edit_group&groupid=<?php 
            echo $this->_group->id;
            ?>
"><i class="icon-wrench"></i>Edit group details</a>
					</td>
				</tr>
				<tr>
					<th class="narrow">Status</th>
					<td><?php 
            $this->_group->printFieldValue('is_archived');
            ?>
</td>
					<th class="narrow hidden-phone">Share Member Details?</th>
					<td class="hidden-phone"><?php 
            $this->_group->printFieldValue('share_member_details');
            ?>
</td>
					<td class="align-right">
						<form class="min" method="post" action="?view=_edit_group&groupid=<?php 
            echo $this->_group->id;
            ?>
">
							<input type="hidden" name="action" value="delete" />
							<button class="btn-link double-confirm-title link-collapse" type="submit" title="Delete this group">
								<i class="icon-trash"></i>Delete group
							</button>
						</form>
					</td>
				</tr>
			</table>

			<div class="modal hide fade" id="action-plan-modal" role="dialog" aria-hidden="true">
				<form method="post" action="?view=_edit_group&action=add_member&groupid=<?php 
            echo $this->_group->id;
            ?>
">
					<div class="modal-header">
						<h4>Add Members by Name Search</h4>
					</div>
					<div class="modal-body">
						<table>
							<tr>
								<td>Select persons:</td>
								<td>
									<?php 
            $GLOBALS['system']->includeDBClass('person');
            Person::printMultipleFinder('personid');
            ?>
								</td>
							</tr>
							<tr>
								<td>Membership status:</td>
								<td>
									<?php 
            $GLOBALS['system']->includeDBClass('person_group');
            Person_Group::printMembershipStatusChooser('membership_status');
            ?>
								</td>
							</tr>
						</table>
					</div>
					<div class="modal-footer">
						<input class="btn" type="submit" value="Add Members" id="add-member-button" />
						<input class="btn" type="button" value="Cancel" data-dismiss="modal" aria-hidden="true" />
					</div>
				</form>
			</div>

			<div class="modal hide fade autosize" id="email-modal" role="dialog" aria-hidden="true">
				<div class="modal-header">
					<h4>Email members of <?php 
            echo ents($this->_group->getValue('name'));
            ?>
</h4>
				</div>
				<div class="modal-body">
					<!-- to be populated with ajax -->
				</div>
				<div class="modal-footer">
					<input class="btn" type="button" value="Cancel" data-dismiss="modal" aria-hidden="true" />
				</div>
			</div>


			<?php 
            $persons = $this->_group->getMembers(!empty($_SESSION['show_archived_group_members']));
            list($status_options, $default_status) = Person_Group::getMembershipStatusOptionsAndDefault();
            ?>
			<h3>Group Members (<?php 
            echo count($persons);
            ?>
)</h3>

			<?php 
            if (empty($_REQUEST['edit_statuses'])) {
                ?>
				<div class="group-members-links">
					<div class="archived-link">
						<?php 
                if (empty($_SESSION['show_archived_group_members'])) {
                    ?>
							<a class="hidden-phone" href="<?php 
                    echo build_url(array('show_archived' => 1));
                    ?>
"><i class="icon-eye-open"></i>Show archived members</a>
							<?php 
                } else {
                    ?>
							<a class="hidden-phone" href="<?php 
                    echo build_url(array('show_archived' => 0));
                    ?>
"><i class="icon-eye-close"></i>Hide archived members</a>
							<?php 
                }
                ?>
					</div>
				<?php 
                if (!empty($persons)) {
                    ?>
					<div class="email-link">
						<a href="<?php 
                    echo build_url(array('view' => NULL, 'call' => 'email', 'groupid' => $this->_group->id, 'show_modal' => 1));
                    ?>
" data-target="#email-modal" data-toggle="modal"><i class="icon-email">@</i>Email members</a>
					</div>
					<?php 
                }
                if (!empty($persons) && $GLOBALS['user_system']->havePerm(PERM_EDITPERSON)) {
                    if (count($status_options) > 1) {
                        ?>
						<div class="edit-status-link">
							<a href="<?php 
                        echo build_url(array('edit_statuses' => 1));
                        ?>
"><i class="icon-wrench"></i>Edit membership statuses</a>
						</div>
						<?php 
                    }
                }
                ?>
					<div class="add-link">
						<a href="#action-plan-modal" data-toggle="modal"><i class="icon-plus-sign"></i>Add members</a>
					</div>
				</div>
				<?php 
            }
            if (!empty($persons)) {
                $special_fields = array('joined_group', 'congregation');
                if (count($status_options) > 1) {
                    array_unshift($special_fields, 'membership_status');
                }
                if (!empty($_REQUEST['edit_statuses'])) {
                    ?>
					<form method="post" action="<?php 
                    echo build_url(array('edit_statuses' => NULL));
                    ?>
">
					<?php 
                    $callbacks = array('membership_status' => array($this, 'printMembershipStatusChooser'));
                    $show_actions = FALSE;
                    // This is a bit ugly, but the 'membership status' column needs to show the membership status chooser,
                    // which needs the ID rather than the label
                    foreach ($persons as &$person) {
                        $person['membership_status'] = $person['membership_status_id'];
                    }
                }
                include_once 'templates/person_list.template.php';
                if (!empty($_REQUEST['edit_statuses'])) {
                    ?>
					<div class="align-right">
						<input type="submit" class="btn" value="Save membership statuses" />
						<a class="btn" href="<?php 
                    echo build_url(array('edit_statuses' => NULL));
                    ?>
">Cancel</a>
					</div>
					</form>
					<?php 
                }
            } else {
                ?>
				<p><em>This group does not currently have any members</em></p>
				<?php 
            }
        }
    }
 /**
  * Get the options for filtering people by (person or group-membership) status
  * @return array
  */
 public static function getStatusOptions()
 {
     $statusOptions = array();
     foreach (Person::getStatusOptions() as $id => $val) {
         $statusOptions['p-' . $id] = $val;
     }
     list($gOptions, $default) = Person_Group::getMembershipStatusOptionsAndDefault();
     foreach ($gOptions as $id => $val) {
         $statusOptions['g-' . $id] = $val;
     }
     return $statusOptions;
 }
    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>';
        ?>
			</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>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>



		</table>
		<?php 
    }
    private function printSet($cohortid, $cohortname)
    {
        $stats = Attendance_Record_Set::getStatsForPeriod($this->_start_date, $this->_end_date, $cohortid);
        if (empty($stats) || $stats[NULL]['rate'] == 0) {
            return FALSE;
        }
        ?>
		<div class="span4">
		<table class="table table-bordered attendance-stats">
			<thead>
				<tr>
					<th colspan="4"><?php 
        echo ents($cohortname);
        ?>
</th>
				</tr>
				<tr>
					<th><?php 
        echo _('Segment');
        ?>
</th>
					<th title=<?php 
        echo _('"Percentage of dates marked present rather than absent"');
        ?>
><?php 
        echo _('Rate');
        ?>
</th>
					<th class="present" title=<?php 
        echo _('"Average number marked present per date"');
        ?>
><?php 
        echo _('Avg&nbsp;P');
        ?>
</th>
					<th class="absent" title="<?php 
        echo _('Average number marked absent per date"');
        ?>
><?php 
        echo _('Avg&nbsp;A');
        ?>
</th>
			</thead>
			<tbody>
		<?php 
        $map['age_bracket'] = explode(',', AGE_BRACKET_OPTIONS);
        if ($cohortid[0] == 'g') {
            list($map['status'], $default) = Person_Group::getMembershipStatusOptionsAndDefault();
        } else {
            $map['status'] = $this->status_map;
        }
        foreach (array('status', 'age_bracket') as $grouping) {
            foreach ($map[$grouping] as $k => $v) {
                if (!isset($stats[$grouping][$k])) {
                    continue;
                }
                ?>
				<tr <?php 
                if ($k == 0 && $grouping == 'age_bracket') {
                    echo 'class="thick-top-border"';
                }
                ?>
>
					<th><?php 
                echo ents($v);
                ?>
</th>
				<?php 
                if (isset($stats[$grouping][$k])) {
                    ?>
					<td><?php 
                    echo $stats[$grouping][$k]['rate'];
                    ?>
%</td>
					<td><?php 
                    echo number_format($stats[$grouping][$k]['avg_present'], 1);
                    ?>
</td>
					<td><?php 
                    echo number_format($stats[$grouping][$k]['avg_absent'], 1);
                    ?>
</td>
					<?php 
                } else {
                    ?>
					<td>-</td>
					<td>-</td>
					<td>-</td>
					<?php 
                }
                ?>
				</tr>
				<?php 
            }
        }
        ?>
				<tr class="thick-top-border">
					<th><?php 
        echo _('Overall');
        ?>
</th>
					<td><?php 
        echo $stats[NULL]['rate'];
        ?>
%</td>
					<td><?php 
        echo number_format($stats[NULL]['avg_present'], 1);
        ?>
</td>
					<td><?php 
        echo number_format($stats[NULL]['avg_absent'], 1);
        ?>
</td>
				</tr>
				<tr class="headcount">
					<th colspan="2">
						<?php 
        echo _('Avg&nbsp;Headcount');
        ?>
					</th>
					<td class="right">
						<?php 
        $bits = explode('-', $cohortid);
        $hc = Headcount::fetchAverage($bits[0], $bits[1], $this->_start_date, $this->_end_date);
        if ($hc) {
            echo number_format($hc, 1);
        } else {
            echo 'N/A';
        }
        ?>
					</td>
					<td colspan="2"></td>
				</tr>
			</tbody>
		</table>
		</div>
		<?php 
        return TRUE;
    }
Ejemplo n.º 5
0
 function _processObjectEditing()
 {
     $mod_count = 0;
     $processed = FALSE;
     switch (array_get($_REQUEST, 'action')) {
         case 'add_member':
         case 'add_members':
             $personids = array_get($_POST, 'personid', array());
             list($status_options, $default_status) = Person_Group::getMembershipStatusOptionsAndDefault();
             $mstatus = array_get($_POST, 'membership_status', $default_status);
             // When moving from an old group to this one, the magic membership status _PRESERVE_
             // means we should look up their status in the old group and use that status in the new group.
             if (!empty($_POST['remove_from_groupid'])) {
                 $old_group = $GLOBALS['system']->getDBObject('person_group', (int) $_POST['remove_from_groupid']);
                 if ($mstatus == '_PRESERVE_') {
                     $old_memberships = $old_group->getMembers();
                 }
             }
             // overwrite_membership means if they are already in the group with a different status,
             // their membership status will be updated.  Used for single-person actions but not bulk.
             $overwrite = array_get($_POST, 'overwrite_membership');
             if (!empty($personids)) {
                 if (!is_array($personids)) {
                     $personids = array($personids);
                 }
                 foreach ($personids as $personid) {
                     $new_member =& $GLOBALS['system']->getDBObject('person', (int) $personid);
                     $newstatus = $mstatus == '_PRESERVE_' ? $old_memberships[$personid]['membership_status_id'] : $mstatus;
                     if ($new_member->id) {
                         if ($this->_edited_object->addMember((int) $personid, $newstatus, $overwrite)) {
                             $mod_count++;
                         }
                     }
                 }
                 $verb = !empty($_POST['remove_from_groupid']) ? 'moved' : 'added';
                 if (count($personids) > 1) {
                     add_message($mod_count . ' persons ' . $verb . ' to group');
                 } else {
                     add_message('Person ' . $verb . ' to group');
                 }
             }
             if (!empty($_POST['remove_from_groupid']) && !empty($old_group)) {
                 $old_group->removeMembers($_POST['personid']);
             }
             $processed = TRUE;
             break;
         case 'remove_member':
         case 'remove_members':
             $personids = $_POST['personid'];
             if (!empty($personids)) {
                 if (!is_array($personids)) {
                     $personids = array($personids);
                 }
                 foreach ($personids as $personid) {
                     if ($this->_edited_object->removeMember((int) $personid)) {
                         $mod_count++;
                     }
                 }
                 if (count($personids) > 1) {
                     add_message($mod_count . ' persons removed from group');
                 } else {
                     add_message('Person removed from group');
                 }
             }
             $processed = TRUE;
             break;
         case 'delete':
             if ($_POST['action'] == 'delete') {
                 // must be POSTed
                 $GLOBALS['user_system']->checkPerm(PERM_EDITGROUP);
                 $name = $this->_edited_object->toString();
                 $this->_edited_object->delete();
                 add_message('Group "' . $name . '" deleted');
                 redirect('groups__list_all', array('groupid' => NULL, 'action' => NULL));
                 // exits
             }
             break;
     }
     if (!$processed) {
         // normal group edit
         $GLOBALS['user_system']->checkPerm(PERM_EDITGROUP);
         $processed = parent::_processObjectEditing();
     }
     if ($processed) {
         switch (array_get($_REQUEST, 'back_to')) {
             case 'persons':
                 redirect('persons', array('personid' => (int) reset($personids)), 'groups');
             case 'groups__list_all':
                 redirect('groups__list_all', array('groupid' => NULL, 'action' => NULL));
                 // exits
             // exits
             case 'groups':
             default:
                 redirect('groups', array('groupid' => $this->_edited_object->id));
                 // exits
         }
     }
 }
    private function printSet($cohortid, $cohortname)
    {
        $stats = Attendance_Record_Set::getStatsForPeriod($this->_start_date, $this->_end_date, $cohortid);
        if (empty($stats)) {
            return FALSE;
        }
        ?>
		<div class="span4">
		<table class="table table-bordered attendance-stats">
			<thead>
				<tr>
					<th colspan="4"><?php 
        echo ents($cohortname);
        ?>
</th>
				</tr>
				<tr>
					<th>Status</th>
					<th title="Percentage of dates marked present rather than absent">Rate</th>
					<th class="present" title="Average number marked present per date">Avg&nbsp;P</th>
					<th class="absent" title="Average number marked absent per date">Avg&nbsp;A</th>
			</thead>
			<tbody>
		<?php 
        if ($cohortid[0] == 'g') {
            list($map, $default) = Person_Group::getMembershipStatusOptionsAndDefault();
        } else {
            $map = $this->status_map;
        }
        foreach ($map as $k => $v) {
            if (isset($stats[$k])) {
                ?>
				<tr>
					<th><?php 
                echo ents($v);
                ?>
</th>
					<td style="width: 6ex; text-align: right"><?php 
                echo $stats[$k]['rate'];
                ?>
%</td>
					<td style="width: 6ex; text-align: right"><?php 
                echo number_format($stats[$k]['avg_present'], 1);
                ?>
</td>
					<td style="width: 6ex; text-align: right"><?php 
                echo number_format($stats[$k]['avg_absent'], 1);
                ?>
</td>
				</tr>
				<?php 
            }
        }
        ?>
				<tr class="thick-top-border">
					<th>Overall</th>
					<td style="width: 6ex; text-align: right"><?php 
        echo $stats[NULL]['rate'];
        ?>
%</td>
					<td style="width: 6ex; text-align: right"><?php 
        echo number_format($stats[NULL]['avg_present'], 1);
        ?>
</td>
					<td style="width: 6ex; text-align: right"><?php 
        echo number_format($stats[NULL]['avg_absent'], 1);
        ?>
</td>
				</tr>
				<tr class="headcount">
					<th colspan="2">
						Avg&nbsp;Headcount
					</th>
					<td class="right">
						<?php 
        $bits = explode('-', $cohortid);
        $hc = Headcount::fetchAverage($bits[0], $bits[1], $this->_start_date, $this->_end_date);
        if ($hc) {
            echo number_format($hc, 1);
        } else {
            echo 'N/A';
        }
        ?>
					</td>
					<td colspan="2"></td>
				</tr>
			</tbody>
		</table>
		</div>
		<?php 
        return TRUE;
    }