Skip to content

Commit

Permalink
Document merge for rosters
Browse files Browse the repository at this point in the history
Replaces PR tbar0970#865
Now copes with multiple congregations
I had to strip out the SizeDetector test on my system as it caused the option to be omitted.
tim-pearce committed Aug 8, 2023
1 parent d5b6ba2 commit a9d4a29
Showing 3 changed files with 234 additions and 62 deletions.
144 changes: 127 additions & 17 deletions calls/call_document_merge_rosters.class.php
Original file line number Diff line number Diff line change
@@ -1,20 +1,63 @@
<?php
class Call_Document_merge_rosters extends Call
class Call_Document_Merge_Rosters extends Call
{
public static function getSavedTemplatesDir()
{
return Documents_Manager::getRootPath().'/Templates/To_Merge/';
}

public static function NewLines($extension, $item)
{
if ($extension == 'ods') {
$s = str_replace("\n", '</text:p><text:p>', trim($item));
} elseif ($extension == 'odt'){
$s = str_replace("\n", '<text:line-break/>', trim($item));
} else {
$s = trim($item);
}
$s = str_replace('&','&amp;',$s);
return $s;

}

function run()
{
$roster_id = (int)array_get($_REQUEST, 'roster_view');
if (empty($roster_id)) return;
$file_info = array_get($_FILES, 'source_document');
$content = null;
if (empty($file_info['tmp_name'])) {
trigger_error('Template file does not seem to have been uploaded');
$template_filename = null;
if (array_get($_REQUEST, 'template_format') == 'dump') {
$extension = '@@@debug@@@';
} else if (!empty($file_info['tmp_name'])) {
if (!empty($_REQUEST['save_template'])) {
$ok = TRUE;
if (!is_dir(self::getSavedTemplatesDir())) {
$ok = mkdir(self::getSavedTemplatesDir(), 0770, TRUE);
}
if ($ok) $ok = copy($file_info['tmp_name'], self::getSavedTemplatesDir().basename($file_info['name']));
if (!$ok) trigger_error("Problem saving template", E_USER_ERROR);

}


$bits = explode('.', $file_info['name']);
$extension = strtolower(end($bits));
$template_filename = basename($file_info['name']);
$source_file = $file_info['tmp_name'];
rename ($source_file, $source_file.'.'.$extension);
$source_file = $source_file.'.'.$extension;

} else if (!empty($_REQUEST['source_doc_select'])) {
// NB basename for security to avoid path injections.
$source_file = $template_filename = self::getSavedTemplatesDir().basename($_REQUEST['source_doc_select']);
$bits = explode('.', $source_file);
$extension = strtolower(end($bits));
} else {
trigger_error('Template file does not seem to have been uploaded or selected');
return;
}
$extension = @strtolower(end(explode('.', $file_info['name'])));
$source_file = $file_info['tmp_name'];
rename ($source_file, $source_file.'.'.$extension);
$source_file = $source_file.'.'.$extension;

switch ($extension) {
case 'odt':
case 'odg':
@@ -25,13 +68,15 @@ function run()
case 'docx':
case 'xlsx':
case 'ppt':
case '@@@debug@@@':
$view = $GLOBALS['system']->getDBObject('roster_view', $roster_id);
$start_date = substr(array_get($_REQUEST, 'start_date', ''), 0, 10);
$end_date = substr(array_get($_REQUEST, 'end_date', ''), 0, 10);
$data = $view->printCSV($start_date, $end_date, TRUE);
$labels = array();
$roster = array();
$people = array();
$persons_unique = array();
$rowno = 0;
foreach ($data as $row) {
switch ($rowno) {
@@ -42,7 +87,7 @@ function run()
$rowno++;
$itemno = 0;
foreach ($row as $item) {
$labels['label'.$itemno] = $item;
$labels['label'.$itemno] = str_replace('&','&amp;',$item);
$itemno++;
}
for ($i = 0; $i > 20; $i++) {
@@ -52,21 +97,30 @@ function run()
break;
default:
$rowno++;
$itemno = 0;
$roleno = 1;
$roster_row = array();
$persons = array();
foreach ($row as $item) {
$roster_row['role'.$itemno] = str_replace("\n", ', ', $item);
if ($itemno == 0) {
foreach ($row as $key => $item) {
if ($key == 0) {
$roster_row['date'] = $item;
$date = $item;
} else {
} elseif (is_numeric($key)) {
$roster_row['role'.$roleno] = str_replace('&','&amp;',str_replace("\n", ', ', $item));
$roster_row['role_cr'.$roleno] = $this->NewLines($extension, $item);
$roster_row[str_replace(' ','_',$labels['label'.$roleno])] = $roster_row['role'.$roleno];
$roster_row[str_replace(' ','_',$labels['label'.$roleno]).'_cr'] = $roster_row['role_cr'.$roleno];
$hashes = explode("\n", $item);
foreach ($hashes as $hash) {
$persons[$hash] = 1;
}
$roleno++;
} else {
$roster_row[$key] = trim($item);
$roster_row[$key.'_cr'] = $this->NewLines($extension, trim($item));
if ($key == 'topic') {
$title = $roster_row['topic'];
}
}
$itemno++;
}
for ($i = 0; $i > 20; $i++) {
$labels['role'.$itemno] = '';
@@ -75,15 +129,66 @@ function run()
$roster[] = $roster_row;
$peoples = array();
foreach ($persons as $key => $value) {
$peoples[] = $key;
if (trim($key) <> '') {
$peoples[] = trim($key);
}
}
asort($peoples);
foreach ($peoples as $value) {
$people[] = array('date' => $date, 'name' => $value);
$people[] = array('date' => $date, 'name' => str_replace('&','&amp;',$value));
$persons_unique[trim(str_replace('&','&amp;',$value))] = $value;
}
break;
}
}
$person = array();
asort($persons_unique);
foreach ($persons_unique as $key => $value) {
$person[] = array('name' => $key);
}

if ($extension == '@@@debug@@@') {
echo '<a href="javascript:history.go(-1)">Return</a>'."\n\n";
echo "<pre>\n";
echo '[onshow.system_name] = '.ifdef('SYSTEM_NAME', '')."\n";
echo '[onshow.timezone] = '.ifdef('TIMEZONE', '')."\n";
echo '[onshow.username] = '.$_SESSION['user']['username']."\n";
echo '[onshow.first_name] = '.$_SESSION['user']['first_name']."\n";
echo '[onshow.last_name] = '.$_SESSION['user']['last_name']."\n";
echo '[onshow.email] = '.$_SESSION['user']['email']."\n";
echo '[onshow.roster_view_name] = '.$_REQUEST['roster_view_name']."\n";
echo '[onshow.date] = '.$date."\n";
echo '[onshow.title] = '.$title."\n";
echo "\n";
foreach ($person as $line) {
foreach ($line as $k => $v) {
echo '[person.'.$k.'] = '.$v;
}
echo "\n";
}
echo "\n";
foreach ($labels as $k => $v) {
echo '[labels.'.$k.'] = '.$v."\n";
}
echo "\n";
foreach ($roster as $line) {
foreach ($line as $k => $v) {
echo '[roster.'.$k.'] = '.$v."\n";
}
echo "\n";
}
foreach ($people as $line) {
foreach ($line as $k => $v) {
echo '[people.'.$k.'] = '.$v."\n";
}
echo "\n";
}

echo "</pre>\n";
echo "\n\n".'<a href="javascript:history.go(-1)">Return</a>';
return;
}

require_once 'include/tbs.class.php';
include_once 'include/tbs_plugin_opentbs.php';
if (ini_get('date.timezone')=='') {
@@ -102,10 +207,15 @@ function run()
$TBS->VarRef['email'] = $_SESSION['user']['email'];
$TBS->VarRef['roster_view_name'] = $_REQUEST['roster_view_name'];
$TBS->VarRef['date'] = $date;
$TBS->VarRef['title'] = $title;
$TBS->MergeBlock('labels', array($labels));
$TBS->MergeBlock('roster', $roster);
$TBS->MergeBlock('people', $people);
$filename = basename($file_info['name']);
$TBS->MergeBlock('person', $person);
$filename = basename($template_filename);
$bits = explode('.', $filename);
$ext = array_pop($bits);
$filename = implode('_', $bits).'_merged_'.date('Y-m-d').'.'.$ext;
$TBS->Show(OPENTBS_DOWNLOAD, $filename);
break;
default:
51 changes: 44 additions & 7 deletions db_objects/roster_view.class.php
Original file line number Diff line number Diff line change
@@ -422,14 +422,15 @@ public function printCSV($start_date=NULL, $end_date=NULL, $return=FALSE)

$to_print = Array();
foreach ($services as $id => $service_details) {
$to_print[$service_details['date']]['service'][$service_details['congregationid']] = $service_details;
$to_print[$service_details['date']]['service'][$service_details['congregationid']]['id'] = $id;
$to_print[$service_details['date']][$service_details['congregationid']]['service'] = $service_details;
$to_print[$service_details['date']][$service_details['congregationid']]['service']['id'] = $id;
$to_print[$service_details['date']]['assignments'] = Array();
}
foreach ($this->getAssignments($start_date, $end_date) as $date => $date_assignments) {
$to_print[$date]['assignments'] = $date_assignments;
}
ksort($to_print);

$role_objects = Array();

$csvData = Array();
@@ -458,20 +459,54 @@ public function printCSV($start_date=NULL, $end_date=NULL, $return=FALSE)
}
$csvData[] = $row;

foreach ($to_print as $date => $ddetail) {
foreach ($to_print as $date => $sdetail) {
$row = Array(format_date($date));
if ($return) {
foreach ($sdetail as $cong => $ddetail) {
if (isset($ddetail['service']['format_title'])) {
$row['format'] = $ddetail['service']['format_title'];
} else {
$row['format'] = '';
}
$row['format_'.$cong] = $row['format'];
if (isset($ddetail['service']['topic_title'])) {
$row['topic'] = $ddetail['service']['topic_title'];
} else {
$row['topic'] = '';
}
if (trim(strval($row['topic'])) == '<div class=') {
$row['topic'] = '';
}
$row['topic_'.$cong] = $row['topic'];
if (isset($ddetail['service']['notes'])) {
$row['notes'] = $ddetail['service']['notes'];
} else {
$row['notes'] = '';
}
if (strpos($row['notes'], 'htmlspecial') > 1) {
$row['notes'] = '';
}
$row['notes_'.$cong] = $row['notes'];
if (isset($ddetail['service']['comments'])) {
$row['comments'] = $ddetail['service']['comments'];
} else {
$row['comments'] = '';
}
$row['comments_'.$cong] = $row['comments'];
}
}
foreach ($this->_members as $id => $mdetail) {
if (empty($mdetail)) continue;

if (!empty($mdetail['role_id'])) {
$names = Array();
foreach (array_get($ddetail['assignments'], $mdetail['role_id'], Array()) as $rank => $vs) {
foreach (array_get($sdetail['assignments'], $mdetail['role_id'], Array()) as $rank => $vs) {
$names[] = $vs['name'];
}
$row[] = implode("\n", $names);;
} else {
if (!empty($ddetail['service'][$mdetail['congregationid']])) {
$dummy_service->populate($ddetail['service'][$mdetail['congregationid']]['id'], $ddetail['service'][$mdetail['congregationid']]);
if (!empty($sdetail[$mdetail['congregationid']]['service'])) {
$dummy_service->populate($sdetail[$mdetail['congregationid']]['service']['id'], $sdetail[$mdetail['congregationid']]['service']);
$row[] = $dummy_service->getFormattedValue($mdetail['service_field']);
} else {
$row[] = '';
@@ -760,7 +795,8 @@ function printView($start_date=NULL, $end_date=NULL, $editing=FALSE, $public=FAL
foreach ($assignees as $rank => $pdetails) {
$personids[] = $pdetails['personid'];
if (!empty($pdetails['email']) && $pdetails['email'] != $my_email) {
$emails[] = $pdetails['email'];
$emails['"'.str_replace('"',"'",$pdetails['name']).'" <'.$pdetails['email'].'>'] = 1;
// $emails[] = $pdetails['email'];
}
if (!empty($pdetails['mobile'])) {
$mobiles[] = $pdetails['mobile'];
@@ -771,6 +807,7 @@ function printView($start_date=NULL, $end_date=NULL, $editing=FALSE, $public=FAL
echo '<br />';
}
if (!empty($emails)) {
$emails = array_keys($emails);
?>
<div class="smallprint no-print soft">
<a class="soft" href="<?php echo get_email_href($my_email, NULL, $emails, date('jS F', strtotime($date))); ?>" <?php echo email_link_extras(); ?>>Email&nbsp;All</a>
101 changes: 63 additions & 38 deletions views/view_7_rosters__1_display_roster_assignments.class.php
Original file line number Diff line number Diff line change
@@ -117,48 +117,73 @@ function _printParams()
if (PUBLIC_ROSTER_SECRET) $url .= '&secret='.PUBLIC_ROSTER_SECRET;
echo '<a class="nowrap" target="_rosterview" href="'.$url.'"><i class="icon-share"></i>View in public site</a> &nbsp; ';
}

require_once 'size_detector.class.php';
if (!SizeDetector::isNarrow()) {
?>
<span class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#"><i class="icon-chevron-down"></i>Download...</a>
<ul class="dropdown-menu" role="menu">
<li><?php echo '<a href="?call=roster_csv&roster_view='.$viewid.'&start_date='.$this->_start_date.'&end_date='.$this->_end_date.'" ><i class="icon-download-alt"></i>Download CSV</a>'; ?></li>
<li><a href="#merge-modal" data-toggle="modal" data-target="#merge-modal" ><i class="icon-download-alt"></i>Merge a document...</a></li>
</ul>
</span>
<?php
}
echo '</div>';
echo '<a href="?call=roster_csv&roster_view='.$viewid.'&start_date='.$this->_start_date.'&end_date='.$this->_end_date.'" ><i class="icon-download-alt"></i>Download CSV</a> &nbsp; ';

?>
<a href="#merge-modal" data-toggle="modal" data-target="#merge-modal" ><i class="icon-download-alt"></i>Merge a document...</a>

if (!SizeDetector::isNarrow()) {
?>
<div id="merge-modal" class="modal sms-modal hide fade" role="dialog" aria-hidden="true">
<form onsubmit="$('#merge-modal').modal('hide')" action="?call=document_merge_rosters" method="post" enctype="multipart/form-data">
<div class="modal-header">
<h4>Mail merge a document from this roster</h4>
</div>
<div class="modal-body">
<?php
echo _('Source Document').':';
print_hidden_field('roster_view', $viewid);
print_hidden_field('roster_view_name', $this->_view->getValue('name'));
print_hidden_field('start_date', $this->_start_date);
print_hidden_field('end_date', $this->_end_date);
?>
<input class="compulsory" type="file" name="source_document" />
<span class="smallprint"><a target="roster-merge-help" class="med-newwin" href="<?php echo BASE_URL; ?>index.php?call=document_merge_help"><i class="icon-print"></i>Help and examples</a><br></span>
</div>
<div class="modal-footer">
<input type="submit" class="btn" value="Go" />
<input type="button" class="btn" data-dismiss="modal" value="Cancel" />
<div id="merge-modal" class="modal sms-modal hide fade" role="dialog" aria-hidden="true">
<form onsubmit="$('#merge-modal').modal('hide')" action="?call=document_merge_rosters" method="post" enctype="multipart/form-data">
<div class="modal-header">
<h4>Mail merge a document from this roster</h4>
</div>
<div class="modal-body">
<?php
include_once 'calls/call_document_merge_rosters.class.php';
$templates = @glob(Call_Document_Merge_Rosters::getSavedTemplatesDir().'/*.*');
?>
<div class="control-group">
<label class="control-label"><?php echo _('Template Document')?></label>
<div class="controls">
<?php
if (!empty($templates)) {
$tOptions = Array('' => '', '__NEW__' => 'Upload a new file...');
foreach ($templates as $t) $tOptions[basename($t)] = basename($t);
print_widget('source_doc_select', Array('type' => 'select', 'options' => $tOptions, 'class' => 'merge-template'), '');
?>
<div id="merge-template-upload" class="indent-left" style="display:none">
<input type="file" name="source_document" />
<label class="checkbox"><input type="checkbox" name="save_template" value="1" />Save template for next time</label>
</div>
</form>
<?php
} else {
?>
<input class="compulsory" type="file" name="source_document" />
<p class="help-inline">(docx/xlsx/pptx/odt/ods/odp)</p>
<label class="checkbox"><input type="checkbox" name="save_template" value="1" />Save template for next time</label>
<?php
}
?>
</div>
<?php
}
</div>
<div class="control-group">
<label class="control-label"><?php echo _('Type')?></label>
<div class="controls">
<label class="radio inline">
<input type="radio" name="template_format" value="tbs" checked="checked" />Template</label>
<label class="radio inline" style="color:#888">
<input type="radio" name="template_format" value="dump" />
Dump <small><i>(<a target="roster-merge-help" class="med-newwin" href="<?php echo BASE_URL; ?>index.php?call=document_merge_help#dump">help</a>)</i></small>
</label>
<label class="radio inline smallprint">
<a target="roster-merge-help" class="med-newwin" href="<?php echo BASE_URL; ?>index.php?call=document_merge_help"><i class="icon-help"></i>Help and examples</a>
</label>
</div>
</div>
<div class="modal-footer">
<input type="hidden" name="roster_view" value="<?php echo $viewid; ?>" />
<?php
print_hidden_field('roster_view_name', $this->_view->getValue('name'));
print_hidden_field('start_date', $this->_start_date);
print_hidden_field('end_date', $this->_end_date);
?>
<input type="submit" class="btn" value="Go" />
<input type="button" class="btn" data-dismiss="modal" value="Cancel" />
</div>
</form>
</div>
</div>
<?php
}
}
}

0 comments on commit a9d4a29

Please sign in to comment.