diff --git a/calls/call_email.class.php b/calls/call_email.class.php
index e856d3cc..1f7606ed 100644
--- a/calls/call_email.class.php
+++ b/calls/call_email.class.php
@@ -21,8 +21,11 @@ function run()
$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']);
+ $recips = Array();
+ foreach ((array)$_REQUEST['roster_view'] as $viewid) {
+ $view = $GLOBALS['system']->getDBObject('roster_view', (int)$viewid);
+ $recips += $view->getAssignees($_REQUEST['start_date'], $_REQUEST['end_date']);
+ }
} else {
if (empty($_REQUEST['personid'])) {
$recips = $emails = $blanks = $archived = Array();
diff --git a/db_objects/abstract_note.class.php b/db_objects/abstract_note.class.php
index 4eee912a..c3dac209 100644
--- a/db_objects/abstract_note.class.php
+++ b/db_objects/abstract_note.class.php
@@ -76,6 +76,7 @@ protected static function _getFields()
'editable' => false,
'references' => 'person',
'visible' => false,
+ 'default' => 0,
),
'edited' => Array(
'type' => 'datetime',
diff --git a/db_objects/family.class.php b/db_objects/family.class.php
index 1de4aed9..99e376d4 100644
--- a/db_objects/family.class.php
+++ b/db_objects/family.class.php
@@ -188,7 +188,7 @@ function printMemberList($abbreviated=NULL)
$persons = $this->getMemberData();
$show_actions = !empty($this->id); // hide actions if this is a "draft" family
- if (isset($this->_tmp['show_member_callback'])) {
+ if (!empty($this->_tmp['show_member_callback'])) {
call_user_func($this->_tmp['show_member_callback'], $persons);
} else if (!$abbreviated) {
@@ -336,7 +336,6 @@ function printSummaryWithMembers($abbreviate_member_list=TRUE, $member_data=NULL
function printCustomSummary($showMembersCallback)
{
- // TODO: test this in the mmebers interface
$this->fields['members'] = Array('divider_before' => 1);
$this->_tmp['show_member_callback'] = $showMembersCallback;
parent::printSummary();
diff --git a/db_objects/roster_view.class.php b/db_objects/roster_view.class.php
index fab4c89d..e37e62b2 100644
--- a/db_objects/roster_view.class.php
+++ b/db_objects/roster_view.class.php
@@ -502,6 +502,8 @@ function printSingleViewFlexi($service, $includeServiceFields=FALSE)
?>
queryCol($SQL);
foreach ($ids as $id) {
- $res[] = $GLOBALS['system']->getDBObject('roster_view', $id);
+ $res[$id] = $GLOBALS['system']->getDBObject('roster_view', $id);
}
return $res;
}
diff --git a/db_objects/service.class.php b/db_objects/service.class.php
index d615041e..189dc517 100644
--- a/db_objects/service.class.php
+++ b/db_objects/service.class.php
@@ -732,14 +732,43 @@ public function printRunSheetPersonnelFlexi()
{
$rosterViews = Roster_View::getForRunSheet($this->getValue('congregationid'));
if ($rosterViews) {
+ ob_start();
+ $emails = $personids = Array();
+ foreach ($rosterViews as $view) {
+ $asns = $view->printSingleViewFlexi($this);
+ foreach ($asns as $role => $roleAsns) {
+ foreach ($roleAsns as $asn) {
+ if (!empty($asn['personid'])) $personids[] = $asn['personid'];
+ if (!empty($asn['email'])) $emails[] = $asn['email'];
+ }
+ }
+ }
+ $assignments_output = ob_get_clean();
+ $email_href = get_email_href($GLOBALS['user_system']->getCurrentUser('email'), NULL, array_unique($emails), $this->toString());
+ if ($GLOBALS['user_system']->havePerm('PERM_SENDSMS') && ifdef('SMS_HTTP_URL')) {
+ require_once 'include/sms_sender.class.php';
+ SMS_Sender::printModal();
+ }
+
?>
-
Personnel
+
+
+ @Email
+ havePerm('PERM_SENDSMS') && ifdef('SMS_HTTP_URL')) {
+ ?>
+
+ SMS
+
+
+ Personnel
+
printSingleViewFlexi($this);
- }
+ echo $assignments_output;
?>
diff --git a/include/db_object.class.php b/include/db_object.class.php
index d5a9d509..d88f9924 100644
--- a/include/db_object.class.php
+++ b/include/db_object.class.php
@@ -325,7 +325,8 @@ public function save()
$changes = $this->_getChanges();
if ($changes) {
$user = $GLOBALS['user_system']->getCurrentPerson();
- $this->values['history'][time()] = 'Updated by '.$user['first_name'].' '.$user['last_name'].' (#'.$user['id'].")\n".implode("\n", $changes);
+ $now = time();
+ $this->values['history'][$now] = 'Updated by '.$user['first_name'].' '.$user['last_name'].' (#'.$user['id'].")\n".implode("\n", $changes);
$this->_old_values['history'] = 1;
}
}
diff --git a/include/jethrodb.php.bak b/include/jethrodb.php.bak
new file mode 100644
index 00000000..d0fbb740
--- /dev/null
+++ b/include/jethrodb.php.bak
@@ -0,0 +1,262 @@
+execute();
+ $result = $stmnt->fetch();
+ $stmnt->closeCursor();
+ return $result;
+ }
+
+ /**
+ * Execute the specified query and fetch the value from a single column of
+ * each row of the result set into an array
+ *
+ * @param $sql Query to execute
+ * @param $colnum Column index OR column name to include in the result array
+ * @return array
+ */
+ public function queryCol($sql, $colnum = 0)
+ {
+ $stmnt = self::prepare($sql);
+ $stmnt->execute();
+ $result = $stmnt->fetchAll(PDO::FETCH_COLUMN, $colnum);
+ return $result;
+ }
+
+ /**
+ * Execute the specified query and
+ * fetch all the rows of the result set into a two dimensional array
+ *
+ * @param string $sql Query to execute
+ * @param array $types Legacy parameter, not used.
+ * @param int $fetchmode Legacy parameter, not used.
+ * @param boolean $rekey Whether to use the first col of the query result as the keys of the result array
+ * @param boolean $force_array Used only when the query returns exactly two columns.
+ * If true, the values of the returned array will be one-element arrays instead of scalars.
+ * @param boolean $group If true, the values of the returned array is wrapped in another array.
+ * If the same key value (in the first column) repeats itself, the values will be appended to this array instead of overwriting the existing values.
+ * @return array
+ */
+ public function queryAll($sql, $types = null, $fetchmode = null, $rekey = false, $force_array = false, $group = false)
+ {
+ $all = array();
+ $stmnt = self::prepare($sql);
+ $stmnt->execute();
+
+ if (!$rekey) {
+ $all = $stmnt->fetchAll();
+ } else {
+ $row = $stmnt->fetch();
+ if ($row === false) {
+ return $all;
+ } // return an empty array if there is nothing here
+ $shift_array = $rekey ? false : null;
+ if (null !== $shift_array) {
+ $colnum = count($row);
+ if ($colnum < 2) {
+ return new Exception('rekey feature requires at least 2 columns');
+ }
+ $shift_array = (!$force_array && $colnum == 2);
+ }
+ do {
+ $key = reset($row);
+ unset($row[key($row)]);
+ if ($shift_array) {
+ $row = array_shift($row);
+ }
+ if ($group) {
+ $all[$key][] = $row;
+ } else {
+ $all[$key] = $row;
+ }
+ } while (($row = $stmnt->fetch()));
+ }
+ return $all;
+ }
+
+ /**
+ * Execute the specified query,
+ * fetch the value from the first column of the first row of the result set
+ * and then frees the result set.
+ *
+ * @param string $query SQL query to run
+ * @param string $type
+ * @param mixed $colnum
+ * @return mixed field value
+ */
+ public function queryOne($query, $type = null, $colnum = 0)
+ {
+ $result = false;
+ $stmnt = self::prepare($query);
+ $stmnt->execute();
+ $row = $stmnt->fetch(PDO::FETCH_NUM);
+ if ($row) {
+ $result = $row[$colnum];
+ }
+ $stmnt->closeCursor();
+ return $result;
+ }
+
+ /**
+ * Return true if the database has any tables in it
+ * @return boolean
+ */
+ public function hasTables()
+ {
+ $stmnt = self::prepare('SHOW TABLES');
+ $stmnt->execute();
+ $result = $stmnt->fetchAll(PDO::FETCH_COLUMN, 0);
+ return !empty($result);
+ }
+
+ /**
+ * Return true if the database has the getCurrentUserID function in it
+ * @return boolean
+ */
+ public function hasFunctions()
+ {
+ try {
+ $result = true;
+ $stmnt = self::prepare('SHOW CREATE FUNCTION getCurrentUserID');
+ $stmnt->execute();
+ $res = $stmnt->fetchAll(PDO::FETCH_COLUMN, 0);
+ $stmnt->closeCursor();
+ } catch (PDOException $e) {
+ $result = false;
+ }
+ return $result;
+ }
+
+ /**
+ * Set the current User ID variable in the DB
+ * @param int $userid
+ */
+ public function setCurrentUserID($userid)
+ {
+ try {
+ $sql = 'SET @current_user_id = ' . $userid;
+ $result = parent::query($sql);
+ } catch (PDOException $e) {
+ trigger_error('Failed to set user id in database', E_USER_ERROR);
+ }
+ }
+
+}
diff --git a/include/photo_handler.class.php b/include/photo_handler.class.php
index 7782863e..52ef7e00 100644
--- a/include/photo_handler.class.php
+++ b/include/photo_handler.class.php
@@ -33,9 +33,26 @@ public static function getUploadedPhotoData($fieldName)
}
if (function_exists('imagepng')) {
$fn = 'imagecreatefrom'.$ext;
- list($orig_width, $orig_height) = getimagesize($_FILES[$fieldName]['tmp_name']);
$input_img = $fn($_FILES[$fieldName]['tmp_name']);
if (!$input_img) exit;
+ // Rotate the image as necessary - thanks http://php.net/manual/en/function.exif-read-data.php#110894
+ $exif = @exif_read_data($_FILES[$fieldName]['tmp_name']);
+ if (!empty($exif['Orientation'])) {
+ switch($exif['Orientation']) {
+ case 8:
+ $input_img = imagerotate($input_img,90,0);
+ break;
+ case 3:
+ $input_img = imagerotate($input_img,180,0);
+ break;
+ case 6:
+ $input_img = imagerotate($input_img,-90,0);
+ break;
+ }
+ }
+ $orig_width = imagesx($input_img);
+ $orig_height = imagesy($input_img);
+
$orig_ratio = $orig_width / $orig_height;
if (($orig_width > self::MAX_PHOTO_WIDTH) || ($orig_height > self::MAX_PHOTO_HEIGHT)) {
if (self::MAX_PHOTO_WIDTH > self::MAX_PHOTO_HEIGHT) {
diff --git a/include/sms_sender.class.php b/include/sms_sender.class.php
index 8de1f3ac..12835832 100644
--- a/include/sms_sender.class.php
+++ b/include/sms_sender.class.php
@@ -129,7 +129,7 @@ public static function sendMessage($message, $recips, $saveAsNote=FALSE)
$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_', ($message), $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);
if (ifdef('SMS_RECIPIENT_ARRAY_PARAMETER')) {
diff --git a/members/calls/call_photo.class.php b/members/calls/call_photo.class.php
index 55e5ad44..9950ea58 100644
--- a/members/calls/call_photo.class.php
+++ b/members/calls/call_photo.class.php
@@ -21,7 +21,6 @@ function run()
$db = $GLOBALS['db'];
if (!empty($_REQUEST['personid'])) {
$obj = $GLOBALS['system']->getDBObject('member', (int)$_REQUEST['personid']);
- $SQL = 'SELECT photodata FROM person_photo WHERE personid = '.(int)$obj->id;
} else if (!empty($_REQUEST['familyid'])) {
$obj = $GLOBALS['system']->getDBObject('family', (int)$_REQUEST['familyid']);
diff --git a/members/db_objects/member.class.php b/members/db_objects/member.class.php
index abcb246f..c74bd8c0 100644
--- a/members/db_objects/member.class.php
+++ b/members/db_objects/member.class.php
@@ -5,6 +5,10 @@
class Member extends DB_Object
{
+ function toString()
+ {
+ return $this->values['first_name'].' '.$this->values['last_name'];
+ }
protected static function _getFields()
{
diff --git a/members/templates/member_list.template.php b/members/templates/member_list.template.php
index 1bd3b89a..70eae216 100644
--- a/members/templates/member_list.template.php
+++ b/members/templates/member_list.template.php
@@ -1,6 +1,39 @@
includeDBClass('member');
+$dummy = new Member();
+foreach ($persons as $personid => $person) {
+ $dummy->populate($personid, $person);
+ ?>
+
+ featureEnabled('PHOTOS')) {
+ ?>
+
+
+
+ toString()); ?>
+
+ getFormattedValue('age_bracketid'));
+ echo ' • ';
+ echo ents($dummy->getFormattedValue('gender'));
+ echo '
';
+ $dummy->printFieldValue('mobile_tel');
+ if ($dummy->getValue('mobile_tel') && $dummy->getValue('email')) {
+ echo ' • ';
+ }
+ $dummy->printFieldValue('email');
+ ?>
+
+
+
+
\ No newline at end of file
+
+ *
\ No newline at end of file
diff --git a/members/views/view_1_home.class.php b/members/views/view_1_home.class.php
index 25577a60..a8f5a2d4 100644
--- a/members/views/view_1_home.class.php
+++ b/members/views/view_1_home.class.php
@@ -18,20 +18,33 @@ function printView()
Search people
getDBObject('family', $GLOBALS['user_system']->getCurrentMember('familyid'));
unset($family->fields['status']);
- $family->printCustomSummary(Array($this, 'printFamilyMembers'));
+
+ if ($GLOBALS['system']->featureEnabled('PHOTOS')) {
+ ?>
+
+ printSummary();
+ echo '
';
+ $persons = $family->getMemberData();
+ include 'templates/member_list.template.php';
+ echo '
';
?>
@@ -40,7 +53,7 @@ function printView()
?>
$member) {
- $dummy->populate($id, $member);
if ($member['familyid'] != $lastFamilyID) {
+ if (!empty($persons)) {
+ echo '
';
+ include 'templates/member_list.template.php';
+ echo '
';
+ echo '
'; // member-family-contents
+ }
+ $persons = Array();
+
+ $dummy->populate($id, $member);
$showAddress = defined('MEMBERS_SHARE_ADDRESS')
&& MEMBERS_SHARE_ADDRESS
&& !empty($member['address_suburb']);
+
?>
-
+
featureEnabled('PHOTOS')) {
+ ?>
+
+ ';
if ($showAddress || $member['home_tel']) {
?>
-
-
+
';
@@ -59,53 +70,17 @@ function printView()
$dummy->printFieldValue('home_tel');
}
?>
-
featureEnabled('PHOTOS')) {
- ?>
-
- ';
- echo ents($member['first_name'].' '.$member['last_name']);
- echo '
';
- if ($member['congregationid']) {
- $dummy->printFieldValue('congregationid');
- echo '
';
- }
- if ($member['mobile_tel']) {
- $dummy->printFieldValue('mobile_tel');
- echo '
';
- }
- $dummy->printFieldValue('email');
- ?>
-
-
-
-
-
-
-
- printFieldValue('congregationid'); ?>
-
-
- printFieldValue('mobile_tel'); ?>
-
-
- printFieldValue('email'); ?>
-
-
-
-
- ';
+ include 'templates/member_list.template.php';
+ echo '
';
+ echo '';
}
diff --git a/resources/less/jethro.less.php b/resources/less/jethro.less.php
index d62692d6..c88450c6 100644
--- a/resources/less/jethro.less.php
+++ b/resources/less/jethro.less.php
@@ -1094,10 +1094,27 @@
float: none !important;
}
}
+.member-homepage-box img.family-photo {
+ float: right !important;
+ width: 150px;
+ right: 5px;
+ margin-bottom: 5px;
+ border-radius: 5px;
+ border: 1px solid @jethroDarkest;
+}
+.member-homepage-box table {
+ width: auto !important;
+}
+@media (max-width: 440px) {
+ .member-homepage-box img.family-photo {
+ float: none;
+ width: 100%;
+ }
+}
/*************** PERSON LIST IN MEMBER INTERFACE *************/
#member-list {
- max-width: 90ex;
+ max-width: 110ex;
margin-left: 0px;
margin-top: 15px;
}
@@ -1114,27 +1131,44 @@
#member-list .family-row {
margin-bottom: 10px;
}
+#member-list img.family {
+ float: right;
+ width: 150px;
+ border-radius: 5px;
+ border: 1px solid @jethroDarkest;
+}
+#member-list div.member-family-details {
+ margin: 5px 0px;
+}
+#member-list div.member-family-contents {
+ margin-right: 152px;
+}
+.member-family-members {
+ overflow: auto; /* clearfix */
+}
+.member-family-members .family-member {
+ width: 49%;
+ margin: 0 1% 5px 0;
+}
#member-list h3 {
clear: both;
- margin-bottom: 0px;
-}
-#member-list div.member-card {
- float: left;
- padding-left: 60px;
- width: 230px;
- margin-bottom: 10px;
- height: 80px;
+ margin-bottom: 5px;
+ margin-top: 15px;
}
-#member-list div.member-card img {
- width: 50px;
- margin-left: -60px;
- float: left;
- margin-top: 3px;
+
+@media (max-width: 600px) {
+ .member-family-members .family-member {
+ width: 98%;
+ }
}
-@media (max-width: 400px) {
- #member-list div.person {
+@media (max-width: 440px) {
+ #member-list img.family {
+ float: none;
width: 100%;
}
+ #member-list div.member-family-contents {
+ margin-right: 0;
+ }
}
diff --git a/upgrades/2018-upgrade-to-2.23.sql b/upgrades/2018-upgrade-to-2.23.sql
index e69de29b..c686009a 100644
--- a/upgrades/2018-upgrade-to-2.23.sql
+++ b/upgrades/2018-upgrade-to-2.23.sql
@@ -0,0 +1,2 @@
+/* Issue #457 - clean up zero dates just for tidyness */
+UPDATE _person SET status_last_changed = NULL where CAST(status_last_changed AS CHAR(20)) = '0000-00-00 00:00:00' ;