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'); + ?> +
+ +
+ @@ -29,4 +62,5 @@ -
\ 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

- +

- Edit + Edit My Family

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() ?>

- Subscribe + Subscribe My Roster Allocations  

$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' ;