Membership application test

Membership Application Form EOL; } @include GITROOT.'/sharedlib/includes/debug-head.php'; require_once('NomadDB.php5'); //require_once('handle_person_data.php5'); @ include_once('library/bpDebug.php5'); @ include_once('library/bpTextFileLogger.php5'); require_once('library/bpResultSet.php5'); require_once('library/bpDate.php5'); require_once('library/bpForm.php5'); require_once('library/bpTextFormElement.php5'); require_once('library/bpCalendarEdit.php5'); require_once('library/bpStaticFormElement.php5'); require_once('library/bpFormElementStaticManipulator.php5'); require_once('library/bpHLineFormElement.php5'); require_once('library/bpHiddenFormElement.php5'); require_once('library/bpFormElementHGroup.php5'); require_once('library/bpDialogue.php5'); require_once('library/bpSQLFunctions.php5'); require_once('library/bpStringFunctions.php5'); if(defined('MEMBERSHIP_LOGFILE') && '' != constant('MEMBERSHIP_LOGFILE') && class_exists('bpDebug') && class_exists('bpTextFileLogger')) { bpDebug::setDefaultMessageLog(new bpTextFileLogger(constant('MEMBERSHIP_LOGFILE'))); } $interestsFields = array(); if(defined('MEMBERSHIP_INTERESTSFIELDSUSED') && constant('MEMBERSHIP_INTERESTSFIELDSUSED') != '') { $interestsFields = explode(',', constant('MEMBERSHIP_INTERESTSFIELDSUSED')); } /* deal with annoying magic quotes */ disableMagicQuotesGPC(); function & initialiseSession() { if(!array_key_exists('membershipform', $_SESSION) || !is_array($_SESSION['membershipform'])) { $_SESSION['membershipform'] = array(); } $orgKey = 'o' . constant('ORGANISATIONID'); if(!array_key_exists($orgKey, $_SESSION['membershipform']) || !is_array($_SESSION['membershipform'][$orgKey])) { $_SESSION['membershipform'][$orgKey] = array(); } if(!array_key_exists('developer_data', $_SESSION['membershipform']) || !is_array($_SESSION['membershipform']['developer_data'])) { $_SESSION['membershipform']['developer_data'] = array(); } if(!array_key_exists($orgKey, $_SESSION['membershipform']['developer_data']) || !is_array($_SESSION['membershipform']['developer_data'][$orgKey])) { $_SESSION['membershipform']['developer_data'][$orgKey] = array(); } return $_SESSION['membershipform'][$orgKey]; } function & sessionData() { $orgKey = 'o' . constant('ORGANISATIONID'); initialiseSession(); return $_SESSION['membershipform'][$orgKey]; } function & devSessionData() { initialiseSession(); return $_SESSION['membershipform']['developer_data']['o' . constant('ORGANISATIONID')]; } function membershipLogoff() { // disable this function for newlogin global $newLoginSystem; if($newLoginSystem) return; /* destroy all session variables, crucially including the ID of the logged-on person */ $sessionData = & sessionData(); $sessionData = array(); } /* in order to get references to return values must request assign-by-reference * as well as fn providing return-by-reference */ $sessionData = & initialiseSession(); $developerSessionData = & devSessionData(); /* gracefully handles fatal errors that occur mid-script */ function membershipFatalError( $logMsg, $userMsg = null) { bpDebug::logError($logMsg); if(!is_string($userMsg)) { $userMsg = constant('MEMBERSHIP_GENERICERRORMESSAGE'); } message($userMsg); @include GITROOT.'/sharedlib/includes/debug-foot.php'; if(defined('MEMBERSHIP_TAIL')) { readfile(constant('MEMBERSHIP_TAIL')); } else { // a basic, default page tail echo ''; } exit(0); } /* ** includes js content directly in the source in a cross-browser, ** standards-compliant manner. ** ** if $required is true (default), failure to include the file ** will result in a graceful fatal error; if it's false, failure will ** just return false and the script will continue */ function membershipIncludeJavascriptFile( $file, $required = true ) { $success = false; if(is_string($file) && file_exists($file)) { echo '' . LF; } if(!$success && $required) membershipFatalError('javascript file \'' . $file . '\' could not be included in the html source.'); return $success; } function membershipCountJointCategories() { global $db; $sql = 'SELECT `OrganisationMembershipCategory`.`OrganisationMembershipCategoryID` FROM `OrganisationMembershipCategory` WHERE `OrganisationMembershipCategory`.`OrganisationID`=\'' . $db->escapeText(constant('ORGANISATIONID')) . '\' AND `OrganisationMembershipCategory`.`Joint` != \'0\''; $qJointCategoryCount = $db->query($sql); $jointCategoryCount = -1; if($qJointCategoryCount instanceof bpResultSet) { $jointCategoryCount = $qJointCategoryCount->rowCount(); $qJointCategoryCount->free(); } unset($qJointCategoryCount); return $jointCategoryCount; } function inDeveloperMode() { return defined('MEMBERSHIP_DEVELOPER_MODE') && true == constant('MEMBERSHIP_DEVELOPER_MODE'); } if(inDeveloperMode()) { echo '

Developer Mode

'; } // javascript support functions: mostly validation on form submission membershipIncludeJavascriptFile('js/common_validation.js'); if(array_key_exists('MembershipFormErrorMessage', $sessionData)) { if('' != trim($sessionData['MembershipFormErrorMessage'])) { errorMessage($sessionData['MembershipFormErrorMessage']); } unset($sessionData['MembershipFormErrorMessage']); } if(defined('MEMBERSHIP_NOTNOWMESSAGE') && constant('MEMBERSHIP_NOTNOWMESSAGE') != '') { echo '

' . constant('MEMBERSHIP_NOTNOWMESSAGE') . '

'; } else { $calendarDay = date('j'); $calendarMonth = date('n'); $calendarYear = date('Y'); $noOrgEmail = false; $noApplicantEmail = false; $noSysadminEmail = false; $noSqlUpdate = false; $displaySql = false; if(inDeveloperMode()) { if(array_key_exists('ForceCalendarDate', $_GET)) { $myDate = bpDate::newDateFromString($_GET['ForceCalendarDate'], bpDate::FORMAT_MYSQL); if(!($myDate instanceof bpDate)) { message('Developer mode: provided calendar date is not valid ("' . $_GET['ForceCalendarDate'] . '")'); } else { $developerSessionData['calendarDay'] = $myDate->day(); $developerSessionData['calendarMonth'] = $myDate->month(); $developerSessionData['calendarYear'] = $myDate->year(); } unset($myDate); } if(array_key_exists('calendarDay', $developerSessionData)) { $calendarDay = $developerSessionData['calendarDay']; } if(array_key_exists('calendarMonth', $developerSessionData)) { $calendarMonth = $developerSessionData['calendarMonth']; } if(array_key_exists('calendarYear', $developerSessionData)) { $calendarYear = $developerSessionData['calendarYear']; } message('Calendar date set to: ' . sprintf('%02d', $calendarDay) . '/' . sprintf('%02d', $calendarMonth) . '/' . sprintf('%04d', $calendarYear)); if(array_key_exists('NoOrgEmail', $_GET)) { $developerSessionData['noOrgEmail'] = true; } if(array_key_exists('noOrgEmail', $developerSessionData)) { $noOrgEmail = $developerSessionData['noOrgEmail']; } if(array_key_exists('NoApplicantEmail', $_GET)) { $developerSessionData['noApplicantEmail'] = true; } if(array_key_exists('noApplicantEmail', $developerSessionData)) { $noApplicantEmail = $developerSessionData['noApplicantEmail']; } if(array_key_exists('NoSysadminEmail', $_GET)) { $developerSessionData['noSysadminEmail'] = true; } if(array_key_exists('noSysadminEmail', $developerSessionData)) { $noSysadminEmail = $developerSessionData['noSysadminEmail']; } if(array_key_exists('NoSQLUpdate', $_GET)) { $developerSessionData['noSqlUpdate'] = true; } if(array_key_exists('noSqlUpdate', $developerSessionData)) { $noSqlUpdate = $developerSessionData['noSqlUpdate']; } if(array_key_exists('DisplaySQL', $_GET)) { $developerSessionData['displaySql'] = true; } if(array_key_exists('displaySql', $developerSessionData)) { $displaySql = $developerSessionData['displaySql']; } } $calendarDate = new bpDate($calendarDay, $calendarMonth, $calendarYear); $calendarDateSql = $calendarDate->toString(bpDate::FORMAT_MYSQL); switch(MECON_SERVER_TYPE) { case 'TEST': $dbUserName = constant('MEMBERSHIP_TEST_SERVER_DBUSER'); $dbPass = constant('MEMBERSHIP_TEST_SERVER_DBPASS'); break; case 'LIVE': $dbUserName = constant('MEMBERSHIP_LIVE_SERVER_DBUSER'); $dbPass = constant('MEMBERSHIP_LIVE_SERVER_DBPASS'); break; default: membershipFatalError('missing or invalid mecon server type in configuration'); } if(!defined('MEMBERSHIP_LOGON_REQUIRES_DOB')) { define('MEMBERSHIP_LOGON_REQUIRES_DOB', true); } $db = new NomadDB($dbUserName, $dbPass); unset($dbUserName, $dbPass); if(!$db->connect()) { membershipFatalError('failed to connect to database. check credentials and server details.'); } else if(!$db->isValidOrganisationID(constant('ORGANISATIONID'))) { membershipFatalError('configured organisationid for paper proposal is not valid.'); } else { // optional initial statement sets session timezone global $gconfig; if(@$gconfig['db_init_stmt']) $db->query(@$gconfig['db_init_stmt']); $organisationName = $db->organisationSummary(constant('ORGANISATIONID')); $backToStartOption = null; $stage=isset($_GET['Stage'])?$_GET['Stage']:'Login'; // newlogin - redirect straight to Apply stage if logged in if($newLoginSystem && $newLoginAuthenticated && !isset($_GET['Stage'])){ header('Location: membershipform.php5?Stage=Apply'); exit(0); } switch($stage) { /* ** Stage 1 - Logon ** ** - log off any existing user ** - present a logon form, based on name & DoB */ default: case 'Logon': case '1': membershipLogoff(); // helps ensure going back to "logon" from "update" forces logon check to // be done again: not set to false until AFTER Update stage passed $sessionData['LogOnNewUser'] = true; echo '

lock For Privacy information click here.

' . LF; if($newLoginSystem){ // instead of the form, output a button styled hyperlink to new login system $loginUrl = '/account/contact/login?destination='.urlencode($_SERVER['PHP_SELF'].'?Stage=Apply'); $loginButton = sprintf('Login', $loginUrl); $loginButton = sprintf('
  • %s
', $loginButton); // leverages current css styling $loginButton = sprintf('%s
', $loginButton); // stop other stuff echo '
Please login to continue this membership application:

'.$loginButton; } else { $f = new bpForm('membershipform.php5?Stage=Update', 'startform'); $f->addElement(new bpTextFormElement('LogonFirstName', 'First Name', '', 'f')); $f->addElement(new bpTextFormElement('LogonLastName', 'Last Name', '', 'l')); if (constant('MEMBERSHIP_LOGON_REQUIRES_DOB')) { $f->addElement($e = new bpCalendarEdit('LogonDateOfBirth', 'Date of Birth', 'd')); } $f->setSubmitCaption('Continue'); $f->setSubmitAction('javascript:startform_submit();'); $f->setResetCaption('Clear'); $f->hideStatusArea(); // js validation functions for this stage membershipIncludeJavascriptFile('js/logon_validation.js'); echo '

Enter your full name and date of birth to continue. Please note that throughout the application process, dates must be entered in UK format (DD/MM/YYYY)

'; /* this is REQUIRED to be valid HTML */ if (defined('MEMBERSHIP_LOGON_INTRODUCTION_TEXT') && '' != constant('MEMBERSHIP_LOGON_INTRODUCTION_TEXT')) { echo constant('MEMBERSHIP_LOGON_INTRODUCTION_TEXT'); } $f->output(); } break; /* ** stage 2 - Update ** ** - Log on the user using the provided logon details ** OR use the current PersonID session variable if we're ** returning after the user entered invalid data ** - show a form containing the user's current contact ** details, OR a form containing new details for folk ** we've not come across before. */ case 'Update': case '2': if($newLoginSystem) $_POST = array(); // newlogin integration - disable login backdoor by forcing app failure of this stage // attempt to log on the user if((array_key_exists('LogonLastName', $_POST) && array_key_exists('LogonFirstName', $_POST) && (constant('MEMBERSHIP_LOGON_REQUIRES_DOB') === false || array_key_exists('LogonDateOfBirth', $_POST))) || array_key_exists('PersonID', $sessionData)) { $d = bpDate::newDateFromString($_POST['LogonDateOfBirth'], bpCalendarEdit::RESULT_FORMAT); if($d instanceof bpDate) { $_POST['LogonDateOfBirth'] = $d->toString(bpDate::FORMAT_MYSQL); } else { $_POST['LogonDateOfBirth'] = ''; } $logonQuery = null; if(array_key_exists('PersonID', $sessionData) && true != $sessionData['LogOnNewUser']) { $logonQuery = $db->query('SELECT * FROM `Person` WHERE `Person`.`PersonID`=\'' . $db->escapeText($sessionData['PersonID']) . '\''); } else { /* MySQL has a quirk of text-matching where trailing whitespace in * string operands to the = operator is ignored, so: * "Smith" = "Smith "; to workaround this, use the LIKE operator * and escape any wildcards (% and _) in the provided credentials * bizarre, I know, but true - the fuzzy-search LIKE operator must * be used in preference to the equality operator to enforce * strict equality matching... */ /* $_POST['LogonDateOfBirth'] has already been validated so no need * to escape it */ $sqlLogon = 'SELECT * FROM `Person` WHERE `Person`.`LastName` LIKE \'' . $db->escapeWildcards($db->escapeText($_POST['LogonLastName'])) . '\' AND `Person`.`FirstName` LIKE \'' . $db->escapeWildcards($db->escapeText($_POST['LogonFirstName'])) . '\' ' . (constant('MEMBERSHIP_LOGON_REQUIRES_DOB') === false ? '' : ' AND `Person`.`DateOfBirth` = \'' . $_POST['LogonDateOfBirth'] . '\''); $logonQuery = $db->query($sqlLogon); unset($sqlLogon); } if($logonQuery instanceof bpResultSet) { $rowCount = $logonQuery->rowCount(); if(2 > $rowCount) { $details = array(); if(1 == $rowCount) { $details = $logonQuery->firstRow(); $sessionData['PersonID'] = $details['Person.PersonID']; } else if(0 == $rowCount) { $details = array( 'Person.PersonID' => '0', 'Person.FirstName' => $_POST['LogonFirstName'], 'Person.LastName' => $_POST['LogonLastName'], 'Person.Title' => '', 'Person.OtherTitle' => '', 'Person.DateOfBirth' => $_POST['LogonDateOfBirth'], 'Person.Nationality' => '', 'Person.Gender' => '', 'Person.JobTitle' => '', 'Person.Department' => '', 'Person.Institution' => '', 'Person.Address1' => '', 'Person.Address2' => '', 'Person.Address3' => '', 'Person.Address4' => '', 'Person.City' => '', 'Person.PostCode' => '', 'Person.Country' => '', 'Person.Phone1' => '', 'Person.MobilePhone' => '', 'Person.EMail' => '', 'Person.Twitter' => '', 'Person.Facebook' => ''); $sessionData['PersonID'] = '0'; } else { message('The membership database found more than one set of contact details that matched your name and date of birth. Please contact the administrator to have this resolved.'); if(!$noSysadminEmail) { NomadMailer::mail(MECON_SYSADMIN_EMAIL, 'Multiple Matches During Membership Application Logon', 'GET data (as PHP):' . LF . var_export($_GET, true) . LFLF . 'POST data:' . LF . var_export($_POST, true) . LFLF . 'Configuration follows:' . LF . file_get_contents('config.php')); } } /* set up the form */ $f = new bpForm('membershipform.php5?Stage=Apply', 'editperson', 'Contact Details'); $f->addElement(new bpHiddenFormElement('PersonID', $sessionData['PersonID'])); $spacingBefore = array(); $spacingAfter = array('Person.Country', 'Person.Gender'); $ignoredFields = array('Person.PersonID', 'Person.BadEmail', 'Person.LastUpdateTime', 'Person.Phone1', 'Person.Notes', // _ns newlogin cols 'Person.Pronoun', 'Person.PronounSuggestion', 'Person.DetailsUpdateTime', 'Person.EmailVerified', 'Person.PasswordHash', ); $requiredFields = array('Person.FirstName', 'Person.LastName', 'Person.Title', 'Person.DateOfBirth', 'Person.Gender', 'Person.Address1', 'Person.City', 'Person.PostCode', 'Person.Country', 'Person.MobilePhone', 'Person.EMail'); $newColumn = array('Person.Address1'/*, 'Phone1'*/); foreach($details as $column => $value) { if(in_array($column, $ignoredFields)) { continue; } $element = $db->getDefaultFormElement($column, $value); $element->setHelpTopic(''); switch($column) { case 'Person.Address2': case 'Person.Address3': case 'Person.Address4': $element->setCaption(''); break; case 'Person.MobilePhone': $element->setCaption('Mobile Phone'); break; /* * *** FORK *** * * EASST does not want to ask for nationality * */ case 'Person.Nationality': $element = new bpHiddenFormElement($element->name(), ''); break; /* * *** END FORK *** */ } if(in_array($column, $newColumn)) { $element->setNewColumn(true); } if(in_array($column, $requiredFields)) { $element->setRequired(true); } if(in_array($column, $spacingBefore)) { $f->addElement(new bpHLineFormElement('spacer')); } $f->addElement($element); if(in_array($column, $spacingAfter)) { $f->addElement(new bpHLineFormElement('spacer')); } } membershipIncludeJavascriptFile('js/person_validation.js'); if('0' == $sessionData['PersonID']) { echo '

We do not currently have any contact details for you. Please enter your contact details below and click the Continue button.

' . LF . '

If you know you have provided this information previously, it is possible you did so using slightly different details. Please contact the administrator to confirm your details.

' . LF; } else { echo '

These are the contact details we currently have for you. Please amend them if required and click the Continue button.

' . LF; } /* this is REQUIRED to be valid HTML */ if(defined('MEMBERSHIP_CONTACT_INTRODUCTION_TEXT') && '' != constant('MEMBERSHIP_CONTACT_INTRODUCTION_TEXT')) { echo constant('MEMBERSHIP_CONTACT_INTRODUCTION_TEXT'); } $f->addFormOption(new bpMenuItem('Restart Application', 'membershipform.php5')); $f->hideStatusArea(); $f->setSubmitCaption('Continue'); $f->setSubmitAction('javascript: editperson_submit();'); $f->output(); } else { // failed to log user on - more than one match for name and DOB membershipFatalError('failed to log on user: more than one match for name and DoB', 'The database matched your name and date of birth more than once. Please contact the membership administrator.'); } $logonQuery->free(); } else { // failed to log user on membershipFatalError('failed to logo on user: error querying database'); } } else { // no logon details membershipFatalError('no logon details provided', 'You need to supply some basic identification details in order to start the registration process.'); } break; /* ** Stage 3 - Apply ** ** - Update a contact's details in the db if POST data is provided ** - Check whether the person is already a member of the organisation ** - Present a form for the user to enter all required application details */ case 'Apply': case '3': { if(!array_key_exists('PersonID', $sessionData)) { // no-one is logged in if($newLoginSystem){ // redirect back to default stage header('Location: membershipform.php5'); exit(0); } membershipFatalError('There appears to be no-one logged on to the membership application form (' . $sessionData['PersonID'] . ')', 'You must first provide your contact details before you can apply for membership of ' . $organisationName . '.'); } else { // past the logon stage going back just presents the details for the logged-on user $sessionData['LogOnNewUser'] = false; // check the person being updated matches the logged-on person# if(array_key_exists('PersonID', $_POST) && ($_POST['PersonID'] == $sessionData['PersonID'])) { // store the first, last and dob of the person for "joint" checking. $sessionData['JointCheckFirstName'] = $_POST['Person___FirstName']; $sessionData['JointCheckLastName'] = $_POST['Person___LastName']; $sessionData['JointCheckDateOfBirth'] = $_POST['Person___DateOfBirth']; /* handle private fields */ $_POST['Person___LastUpdateTime'] = $calendarDateSql . date(' H:i:s'); if(array_key_exists('Person___Notes', $_POST)) { unset($_POST['Person___Notes']); } if('0' == $_POST['PersonID']) { $_POST['Person___BadEmail'] = '0'; } elseif(array_key_exists('Person___BadEmail', $_POST)) { unset($_POST['Person___BadEmail']); } /* any required transformations/fixed data */ $_POST['Person___DateOfBirth'] = bpSQL_UKToMySQLDate($_POST['Person___DateOfBirth']); /* * *** FORK *** * * EASST does not want to ask for nationality * */ if($db->isValidPersonID($_POST['PersonID'])) { $_POST['Person___Nationality'] = $db->getField($_POST['PersonID'], 'Person', 'Nationality'); } else { $_POST['Person___Nationality'] = ''; } /* * *** END FORK *** */ /* ** NOTE 08/03/2006: ** ALL validation has been migrated to client-side javascript on the ** submission form, so validation here is redundant. ** ** re-use the shared person table update code from the nomad internal app ** ** this function expects data for ALL columns in the table */ $sql = $db->personUpdateSQL($_POST); if($newLoginSystem) $sql = 'SELECT 0 AS `dummyQuery`'; // newlogin integration - close details update backdoor - prevent update query from runniing bpDebug::logMessage('SQL to update contact details follows:'); bpDebug::logMessage('... ' . $sql); bpDebug::logMessage('Character set is ' . $db->characterSet() . ' (check against charset constants in bpDb.php5, should be UTF-8)'); if(inDeveloperMode() && $displaySql) { message($sql); } if(!inDeveloperMode() || '0' == $_POST['PersonID'] || !$noSqlUpdate) { if(!$db->query($sql)) { message('The application form was unable to update your contact details.'); } else { if('0' == $_POST['PersonID']) { $sessionData['PersonID'] = $db->getLastInsertID(); } } } else { message('SQL updates disabled: contact details not updated.'); } } if($db->isValidPersonID($sessionData['PersonID'])) { // check whether person has already registered if($db->isOrganisationMember($sessionData['PersonID'], constant('ORGANISATIONID'))) { echo '

Our database shows that you are a former or current member of ' . $organisationName . '. If you need to alter your membership details, please contact the administrator.

'; } else { /* ** defaults for ordinary member */ $sessionData['ProposedJointMembershipID'] = 0; $sessionData['Years'] = '1'; $sessionData['CategoryID'] = ''; $sessionData['FinalSubscription'] = '0'; $sessionData['StartYear'] = $calendarYear; $effectiveMonth = $calendarMonth + (defined('MEMBERSHIP_YEAREND_ISSUE_NEXT_YEAR_SUBS_MONTHS') ? constant('MEMBERSHIP_YEAREND_ISSUE_NEXT_YEAR_SUBS_MONTHS') : 0); /* adjust the start year for the subs based on the configured * number of months before year-end during which to issue next * year's subs. * it is conceivable that the effective month will be > 12 in * cases where subs start very early in they year (e.g. subs * start in Jan with 2 months before that where the next year's * subs are issued would make an effective month of 13 when it * is Nov). While it is not conceivable that it will be more * than 24, this code will cope with such cases */ while(12 < $effectiveMonth) { $effectiveMonth -= 12; ++$sessionData['StartYear']; } /* finally, adjust according to the org's membership cycle start * month and year offset */ $sessionData['SubscriptionStartMonth'] = $db->organisationAnnualSubscriptionStartMonth(constant('ORGANISATIONID')); if($effectiveMonth >= $sessionData['SubscriptionStartMonth']) { $sessionData['StartYear'] += $db->organisationAnnualSubscriptionYearOffset(constant('ORGANISATIONID')); } else { $sessionData['StartYear'] += ($db->organisationAnnualSubscriptionYearOffset(constant('ORGANISATIONID')) - 1); } unset($effectiveMonth); if(inDeveloperMode()) { message('A subscription starting in ' . $sessionData['StartYear'] . ' will be created.'); } // check whether we're waiting for the person as a secondary joint member $sql = 'SELECT `ProposedJointMembership`.`ProposedJointMembershipID`, CONCAT(`Person`.`FirstName`, \' \', `Person`.`LastName`) AS `MemberName`, `ProposedJointMembership`.`SubscriptionID`, `Subscriptions`.`CategoryID`, `Subscriptions`.`StartYear`, `Subscriptions`.`FinalSubscription`, `Subscriptions`.`Years` FROM `ProposedJointMembership` LEFT JOIN `Subscriptions` ON `Subscriptions`.`SubscriptionID`=`ProposedJointMembership`.`SubscriptionID` INNER JOIN `Membership` ON `Membership`.`MembershipID`=`Subscriptions`.`MembershipID` LEFT JOIN `Person` ON `Person`.`PersonID`=`Membership`.`PersonID` WHERE `ProposedJointMembership`.`FirstName`=\'' . $db->escapeText($sessionData['JointCheckFirstName']) . '\' AND `ProposedJointMembership`.`LastName`=\'' . $db->escapeText($sessionData['JointCheckLastName']) . '\' AND `ProposedJointMembership`.`DateOfBirth`=\'' . bpSQL_UKToMySQLDate($sessionData['JointCheckDateOfBirth']) . '\' AND `Membership`.`OrganisationID`=\'' . $db->escapeText(constant('ORGANISATIONID')) . '\''; $qSecondary = $db->query($sql); if($qSecondary) { if($qSecondary->rowCount() == 1) { echo '

The application process is expecting your application as a joint member with the following existing member:

'; $s = $qSecondary->firstRow(); echo '

' . $s['MemberName'] . '

'; echo '

If this is not what you are expecting, please contact the administrator.

'; /* ** make sure the submit stage picks this up and acts accordingly */ $sessionData['ProposedJointMembershipID'] = $s['ProposedJointMembershipID']; $sessionData['CategoryID'] = $s['CategoryID']; $sessionData['Years'] = $s['Years']; $sessionData['StartYear'] = $s['StartYear']; $sessionData['FinalSubscription'] = $s['FinalSubscription']; } else if($qSecondary->rowCount() > 1) { echo '

The application process is expecting your applicaiton as a joint member with more than one existing member. Please contact the administrator.

'; } $qSecondary->free(); } else { /* email about failure to check for secondary membership */ /* warn the applicant */ echo '

The application process was unable to check whether we are expecting your application as a joint member with someone who has already applied. If you are applying for joint membership with someone who has already applied, please exit the membership application process and contact the administrator

'; } unset($qSecondary); $details = array('Membership.CategoryID' => $sessionData['CategoryID'], 'Membership.JointMemberFirstName' => '', 'Membership.JointMemberLastName' => '', 'Membership.JointMemberDateOfBirth' => '', 'Membership.JointMemberEmail' => '', 'Membership.Years' => $sessionData['Years']); $f = new bpForm('membershipform.php5?Stage=Submit', 'editmembership', (defined('MEMBERSHIP_FORM_TITLE') && '' != constant('MEMBERSHIP_FORM_TITLE') ? constant('MEMBERSHIP_FORM_TITLE') : 'Complete ALL the questions below')); $spacingBefore = array(); $spacingAfter = array('Membership.JointMemberEmail', 'Membership.Years', 'Membership.FieldworkInterests', 'Membership.CountryOfBirth'); $newColumn = array(); $ignoredFields = array('Membership.Years', 'Membership.JointMemberLastName', 'Membership.JointMemberDateOfBirth', 'Membership.ApplicationDate'); $hiddenFields = array('Membership.Years' => $sessionData['Years'], 'ignore_ProposedJointMembershipID' => $sessionData['ProposedJointMembershipID']); /* if there are no joint categories, hide the joint member boxes */ $jointCategoryCount = membershipCountJointCategories(); if(0 == $jointCategoryCount) { $hiddenFields['Membership.JointMemberFirstName'] = ''; $hiddenFields['Membership.JointMemberLastName'] = ''; $hiddenFields['Membership.JointMemberDateOfBirth'] = ''; $hiddenFields['Membership.JointMemberEmail'] = ''; $ignoredFields[] = 'Membership.JointMemberFirstName'; $ignoredFields[] = 'Membership.JointMemberLastName'; $ignoredFields[] = 'Membership.JointMemberDateOfBirth'; $ignoredFields[] = 'Membership.JointMemberEmail'; } $requiredFields = array('Membership.CategoryID', 'Membership.Years'); $spacingAfter = array('Years'); $qMembershipFields = $db->query('SELECT `MembershipFieldDefinition`.`Field`, `MembershipFieldDefinition`.`Constraints` FROM `MembershipFieldDefinition` WHERE `MembershipFieldDefinition`.`OrganisationID`=\'' . $db->escapeText(constant('ORGANISATIONID')) . '\' AND `MembershipFieldDefinition`.`Visibility` LIKE \'%Membership Form%\' ORDER BY `MembershipFieldDefinition`.`Field` ASC'); if($qMembershipFields) { $fieldDefinition = $qMembershipFields->firstRow(); while($fieldDefinition) { $details['Membership.' . $fieldDefinition['MembershipFieldDefinition.Field']] = ''; /* TODO put in the default */ if(strpos($fieldDefinition['MembershipFieldDefinition.Constraints'], 'NOT') > -1) $requiredFields[] = 'Membership.' . $fieldDefinition['MembershipFieldDefinition.Field']; $fieldDefinition = $qMembershipFields->nextRow(); } } if(defined('MEMBERSHIP_REQUIRED_FIELDS_MARKED') && is_string(constant('MEMBERSHIP_REQUIRED_FIELDS_MARKED'))) $requiredFields = array_unique(array_merge($requiredFields, explode(',', constant('MEMBERSHIP_REQUIRED_FIELDS_MARKED')))); if($sessionData['ProposedJointMembershipID'] > 0) { $f->addElement(new bpHiddenFormElement('Membership___CategoryID', $sessionData['CategoryID'])); //$f->addElement(new bpHiddenFormElement('Membership___Years', $sessionData['Years'])); $ignoredFields = array_merge($ignoredFileds, array(/*'CategoryID',*/ 'Membership.JointMemberFirstName', 'Membership.JointMemberLastName', 'Membership.JointMemberDateOfBirth', 'Membership.JointMemberEmail')); } foreach($hiddenFields as $column => $value) { $f->addElement(new bpHiddenFormElement(str_replace('.', '___', $column), $value)); } $doneInterestsPrompt = false; foreach($details as $column => $value) { if(in_array($column, $ignoredFields)) { continue; } /* third param is org id to get details for certain fields */ $element = $db->defaultFormElement($column, $value, constant('ORGANISATIONID')); $element->setHelpTopic(''); /* customisations */ switch($column) { case 'Membership.CategoryID': if($sessionData['ProposedJointMembershipID'] > 0) { $element->setName('disabled_' . $element->getName()); $element->disable(); } else { if(defined('MEMBERSHIP_CATEGORY_PROMPT_TEXT') && '' != constant('MEMBERSHIP_CATEGORY_PROMPT_TEXT')) { $f->addElement(new bpStaticFormElement('ignore_CategoryPromptText', '', constant('MEMBERSHIP_CATEGORY_PROMPT_TEXT'))); } } $element->setCaption('Type of membership applied for'); break; case 'Membership.Years': $element->setCaption('Number of years membership applied for'); break; case 'Membership.JointMemberFirstName': $realElement = new bpFormElementHGroup('ignore_jointMemberName', 'First Name'); $element->setCaption(''); $realElement->addElement($element); $element = $db->defaultFormElement('Membership.JointMemberLastName', $details['Membership.JointMemberLastName'], constant('ORGANISATIONID')); $element->setCaption('Last Name'); $realElement->addElement($element); $element = $db->defaultFormElement('Membership.JointMemberDateOfBirth', $details['Membership.JointMemberDateOfBirth'], constant('ORGANISATIONID')); $element->setCaption('Date of Birth'); $element->setSize(10); $realElement->addElement($element); $element = $realElement; unset($realElement); break; case 'Membership.JointMemberEmail': $element->setCaption('email'); $element->setSize(80); break; } /* check for custom field label */ $overrideConstName = 'MEMBERSHIP_MEMBERSHIP_' . strtoupper(substr($column, strpos($column, '.') + 1)) . '_FIELDLABEL'; if(defined($overrideConstName) && is_string(constant($overrideConstName))) { $element->setCaption(constant($overrideConstName)); } unset($overrideConstName); if(in_array($column, $requiredFields)) { $element->setRequired(true); } else { $element->setRequired(false); } if(in_array($column, $newColumn)) { $element->setNewColumn(true); } if(in_array($column, $spacingBefore)) { $f->addElement(new bpHLineFormElement('spacer')); } $promptConstantName = 'MEMBERSHIP_FIELDPROMPT_BEFORE_' . strtoupper(str_replace('.', '_', $column)); if(defined($promptConstantName)) { $promptText = constant($promptConstantName); if(is_string($promptText)) { $promptText = trim($promptText); if($promptText != '') { $f->addElement(new bpStaticFormElement('ignore_' . $promptConstantName, '', htmlentities($promptText))); } } } $f->addElement($element); $promptConstantName = 'MEMBERSHIP_FIELDPROMPT_AFTER_' . strtoupper(str_replace('.', '_', $column)); if(defined($promptConstantName)) { $promptText = constant($promptConstantName); if(is_string($promptText)) { $promptText = trim($promptText); if($promptText != '') { $f->addElement(new bpStaticFormElement('ignore_' . $promptConstantName, '', htmlentities($promptText))); } } } unset($promptConstantName); if(in_array($column, $spacingAfter)) { $f->addElement(new bpHLineFormElement('spacer')); } } if(defined('MEMBERSHIP_EMAILONLY_FIELDS') && '' != constant('MEMBERSHIP_EMAILONLY_FIELDS')) { $doneSeparatorLine = false; $validTypes = array('BOOL', 'YEAR', 'DATE', 'TEXT', 'AREA'); $emailOnlyFields = assoc_explode(',', ':', constant('MEMBERSHIP_EMAILONLY_FIELDS')); foreach($emailOnlyFields as $field => $type) { $type = strtoupper(trim($type)); if(in_array($type, $validTypes)) { $element = null; $caption = trim($field); $name = preg_replace('/[^a-zA-Z0-9]/', '_', $caption); bpDebug::logMessage('creating email-only field with name \'' . $name . '\''); switch($type) { case 'BOOL': $element = new bpComboBoxFormElement('emailonly_BOOL_' . $name, $caption); $element->addOption('yes', 'Yes'); $element->addOption('no', 'No'); break; case 'YEAR': $element = new bpTextFormElement('emailonly_YEAR_' . $name, $caption); $element->setValidCharacters('0123456789'); $element->setSize(4); break; case 'DATE': $element = new bpTextFormElement('emailonly_DATE_' . $name, $caption); $element->setValidCharacters('0123456789/'); $element->setSize(10); break; case 'TEXT': $element = new bpTextFormElement('emailonly_DATE_' . $name, $caption); $element->setSize(255); break; case 'AREA': $element = new bpTextAreaFormElement('emailonly_AREA_' . $name, $caption); $element->setRows(4); $element->setCols(40); break; } if($element instanceof bpFormElement) { if(!$doneSeparatorLine) { $f->addElement(new bpHLineFormElement('spacer')); $doneSeparatorLine = true; } $f->addElement($element); } else { bpDebug::logMessage('email only field \'' . $field . '\' did not give rise to valid form element (' . typeof($element) . ')'); } } else { bpDebug::logMessage('found invalid email-only field: ' . $field . ' (' . $type . ')'); } } } // elements for any configured tags if(defined('MEMBERSHIP_TAGS_USED') && '' != constant('MEMBERSHIP_TAGS_USED')) { $usedTags = explode(',', constant('MEMBERSHIP_TAGS_USED')); } $sqlTags = 'SELECT `AvailableMembershipTag`.`AvailableMembershipTagID`,`AvailableMembershipTag`.`Tag`, `AvailableMembershipTag`.`Description` FROM `AvailableMembershipTag` WHERE `AvailableMembershipTag`.`OrganisationID`=\'' . $db->escapeText(constant('ORGANISATIONID')) . '\' AND `AvailableMembershipTag`.`Active`!=0 AND `AvailableMembershipTag`.`Public`!=0'; if(isset($usedTags) && count($usedTags) > 0) { $sqlTags .= ' AND `AvailableMembershipTag`.`Tag` IN (\'' . implode('\',\'', $usedTags) . '\')'; } $qTags = $db->query($sqlTags); if($qTags) { $tagOption = $qTags->firstRow(); while($tagOption) { $element = new bpCheckBoxFormElement('TAG_' . intval($tagOption['AvailableMembershipTag.AvailableMembershipTagID']), $tagOption['AvailableMembershipTag.Tag']); if(defined('MEMBERSHIP_TAGS_NOFIELDTITLES') && true === constant('MEMBERSHIP_TAGS_NOFIELDTITLES')) { $element->setCaption(''); } if(trim($tagOption['AvailableMembershipTag.Description']) != '') { $element->addManipulator(new bpFormElementStaticManipulator($tagOption['AvailableMembershipTag.Description'])); } $f->addElement($element); $tagOption = $qTags->nextRow(); } } else { bpDebug::logMessage('failed to query the database for available tags. SQL follows:'); bpDebug::logMessage($sqlTags); } membershipIncludeJavascriptFile('js/membership_validation.js'); // output the form echo '

'; // this is required to be properly formatted HTML paragraph(s) if(defined('MEMBERSHIP_APPLICATION_INTRODUCTION_TEXT') && '' != constant('MEMBERSHIP_APPLICATION_INTRODUCTION_TEXT')) { echo constant('MEMBERSHIP_APPLICATION_INTRODUCTION_TEXT'); } /* present a message indicating impending/passed switchover date for next year's memberships * December is 0 because the effective month will be 0 if it's Dec */ $monthNames = array('December', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'); $effectiveStartMonth = ($sessionData['SubscriptionStartMonth'] - (defined('MEMBERSHIP_YEAREND_ISSUE_NEXT_YEAR_SUBS_MONTHS') ? constant('MEMBERSHIP_YEAREND_ISSUE_NEXT_YEAR_SUBS_MONTHS') : 0)) % 12; if($calendarMonth >= $effectiveStartMonth) { echo '

Please note that from 1st ' . $monthNames[$effectiveStartMonth] . ' all applications are for ' . sprintf('%04d', $sessionData['StartYear']) . ' membership. Before this date, all applications are for ' . sprintf('%04d', $sessionData['StartYear'] - 1) . ' membership.

'; } $f->addFormOption(new bpMenuItem('Restart Application', 'membershipform.php5')); $f->setSubmitCaption('Continue'); $f->output(); } } else { // invalid person id stored in session membershipFatalError('failed to identify the contact details of the logged-on person'); } } } break; case 'Submit': case '4': // _ns - because of the terrible architecture of this app (post request used as view rather than redirect), users can refresh this page and continually add new memberships.... // hack in a check to see if a membership exists, signifying this request is probably a page refresh, then redirect back to default stage if(getConfiguredAppContainer()->dal->getMembershipIdByOrganisationIdPersonId(ORGANISATIONID, @$_SESSION['PersonID'])){ header('Location: membershipform.php5'); exit(0); } if(!$db->isValidPersonID($sessionData['PersonID'])) { // no-one is logged in if($newLoginSystem){ // redirect back to default stage header('Location: membershipform.php5'); exit(0); } membershipFatalError('no-one logged in to submit application', 'You must first provide your contact details and membership application data before your application can be sumbitted.'); } else { if(inDeveloperMode()) { message('A subscription starting in ' . $sessionData['StartYear'] . ' will be created.'); } $tryAgainOption = new bpMenuItem('Try Again', 'membershipform.php5?Stage=Apply'); /* ** data validation is carried out by javascript on previous ** stage, so we don't do any here ** ** this leaves us open to 3rd part form sumbission attacks causing ** a failure of the update query by providing invalid data for the ** update, but the threat of this is minimal given that this will ** always be an INSERT query rather than an UPDATE query - there is ** no possibility of an attacker overwriting someone else's ** registration */ // set up the fixed new-member fields $_POST['Membership___Currency'] = $db->getField($_POST['Membership___CategoryID'], 'OrganisationMembershipCategory', 'Currency'); $_POST['Membership___YearElected'] = $sessionData['StartYear']; $_POST['Membership___LastUpdateTime'] = $calendarDateSql . date(' H:i:s'); /* convert date/time fields */ $_POST['Membership___JointMemberDateOfBirth'] = bpSQL_UKToMySQLDate($_POST['Membership___JointMemberDateOfBirth']); /* if no joint categories, protect against spoofing joint member details */ $jointCategoryCount = membershipCountJointCategories(); if(0 == $jointCategoryCount) { $_POST['Membership___JointMemberFirstName'] = ''; $_POST['Membership___JointMemberLastName'] = ''; $_POST['Membership___JointMemberDateOfBirth'] = ''; $_POST['Membership___JointMemberEmail'] = ''; } $unquotedFields = array(); $allowEmptyFields = array(); // empty is '' - i.e. not NULL $ignoredFields = array( 'Membership___CategoryID', 'Membership___Years', 'Membership___JointMemberFirstName', 'Membership___JointMemberLastName', 'Membership___JointMemberDateOfBirth', 'Membership___JointMemberEmail', 'disabled___CategoryID'); $sql = 'INSERT INTO `Membership` SET `Membership`.`OrganisationID` = \'' . $db->escapeText(constant('ORGANISATIONID')) . '\', `Membership`.`PersonID` = \'' . $db->escapeText($sessionData['PersonID']) . '\', `Membership`.`ApplicationDate` = \'' . $calendarDateSql . '\''; /// TODO auto-request references here /* NEW STRUCTURE Membership.ReferenceStatus */ if(defined('MEMBERSHIP_SET_REFS_RECEIVED') && (true === constant('MEMBERSHIP_SET_REFS_RECEIVED'))) { $sql .= ', `Membership`.`ReferenceStatus`=\'References Received\''; } elseif(defined('MEMBERSHIP_SET_REFS_REQUESTED') && (true === constant('MEMBERSHIP_SET_REFS_REQUESTED'))) { $sql .= ', `Membership`.`ReferenceStatus`=\'References Requested\''; } else { // default behaviour based on number of referees required if(!defined('MEMBERSHIP_REQUIRE_REFEREES') || !is_int(constant('MEMBERSHIP_REQUIRE_REFEREES')) || 0 > constant('MEMBERSHIP_REQUIRE_REFEREES') || 2 < constant('MEMBERSHIP_REQUIRE_REFEREES')) { $requiredReferees = 2; } else { $requiredReferees = constant('MEMBERSHIP_REQUIRE_REFEREES'); } $sql .= ', `Membership`.`ReferenceStatus`=\'' . ($requiredReferees == 0 ? 'References Not Required' : 'References Not Requested') . '\''; } $errorMessages = array(); /* NOTE this form is intended to be available short-term only and DOES NOT validate * binary fields because there are none for EASA; if this changes before the form * is replaced, this will be a security hole */ $acceptedFields = array('Membership___ReferenceStatus', 'Membership___Currency', 'Membership___LastUpdateTime', 'Membership___YearElected'); $unquotedFields = array(); $qMembershipFields = $db->query('SELECT `MembershipFieldDefinition`.`Field`, `MembershipFieldDefinition`.`MembershipFieldDefinitionID` FROM `MembershipFieldDefinition` WHERE `MembershipFieldDefinition`.`OrganisationID`=\'' . $db->escapeText(constant('ORGANISATIONID')) . '\' AND `MembershipFieldDefinition`.`Visibility` LIKE \'%Membership Form%\' ORDER BY `MembershipFieldDefinition`.`Field` ASC'); if(!is_numeric($_POST['Membership___Years']) || $_POST['Membership___Years'] < 1) { $errorMessages[] = 'You must apply for at least one year\'s membership.'; } if($qMembershipFields) { $fieldDefinition = $qMembershipFields->firstRow(); while($fieldDefinition) { $acceptedFields[] = 'Membership___' . $fieldDefinition['MembershipFieldDefinition.Field']; $myErrorMessage = null; switch($db->validateMembershipFieldData($fieldDefinition['MembershipFieldDefinition.MembershipFieldDefinitionID'], $_POST['Membership___' . $fieldDefinition['MembershipFieldDefinition.Field']], $myErrorMessage)) { case NomadDB::DATA_ERROR: $errorMessages[] = $myErrorMessage; break; } $myErrorMessage = null; $fieldDefinition = $qMembershipFields->nextRow(); } } if(count($errorMessages) > 0) { $sessionData['MembershipFormErrorMessage'] = 'The following errors were found in your application form:' . chr(10) . chr(10) . implode(chr(10), $errorMessages); header('Location: membershipform.php5?Stage=Apply'); exit(0); } // construct SET clause from posted data foreach($_POST as $field => $value) { if(is_array($acceptedFields)) { if(!in_array($field, $acceptedFields)) { continue; } } elseif(in_array($field, $ignoredFields) || substr($field, 0, 7) == 'ignore_' || substr($field, 0, 10) == 'emailonly_' || substr($field, 0, 4) == 'TAG_') { bpDebug::logMessage('field \'' . $field . '\' not being used in INSERT SQL statement'); continue; } $sql .= ', `' . str_replace('___', '`.`', $field) . '`='; $value = $db->escapeText($value); $sql .= ($value == '' ? 'NULL' : '\'' . $db->escapeText('' . $value) . '\''); } if(inDeveloperMode() && $displaySql) { message($sql); } if(!inDeveloperMode() || !$noSqlUpdate) { if($db->query($sql)) { $membershipID = $db->getLastInsertID(); $emailBody = 'PID: ' . $sessionData['PersonID'] . LF . 'MembershipNumber: M' . $membershipID . LF . 'Name: ' . $db->getFullName($sessionData['PersonID']) . LF . 'Email: ' . $db->getField($sessionData['PersonID'], 'Person', 'Email') . LF . 'Institution: ' . $db->getField($sessionData['PersonID'], 'Person', 'Institution') . LF . 'DoB: ' . bpSQL_MySQLToUKDate($db->getField($sessionData['PersonID'], 'Person', 'DateOfBirth')) . LFLF . 'MembershipCategoryID: ' . $_POST['Membership___CategoryID'] . ' (' . $db->getField($_POST['Membership___CategoryID'], 'OrganisationMembershipCategory', 'Title') . ')' . LF . 'Joint Member Name: ' . $_POST['Membership___JointMemberFirstName'] . ' ' . $_POST['Membership___JointMemberLastName'] . '(DoB: ' . $_POST['Membership___JointMemberDateOfBirth'] . '; email: ' . $_POST['Membership___JointMemberEmail'] . ')' . LF . 'Years Applied For: ' . $_POST['Membership___Years'] . LF . 'Payment Currency: ' . $_POST['Membership___Currency'] . LF; /* TODO add the configured fields */ /* add the "email only" fields to the email body */ foreach($_POST as $field => $content) { if(substr($field, 0, 10) == 'emailonly_') { // next 4 chars are TYPE followed by _ $field = substr($field, 15); $emailBody .= LF . trim(str_replace('_', ' ', $field)) . ':' . LF . $content . LF; } } // insert any tags if($db->isValidMembershipID($membershipID)) { foreach($_POST as $field => $content) { // -1 is the default "true" value for selected checkboxes if(substr($field, 0, 4) == 'TAG_' && $content == '-1') { $tagID = intval(substr($field, 4)); if($db->isPublicMembershipTag($tagID) && $db->getOrganisationFromAvailableMembershipTag($tagID) == constant('ORGANISATIONID')) { $emailBody .= 'Tag \'' . $db->getField($tagID, 'AvailableMembershipTag', 'Tag') . '\' selected'; if(!$db->query('INSERT INTO `MembershipTag` SET `MembershipTag`.`MembershipID`=' . $membershipID . ', `MembershipTag`.`AvailableMembershipTagID`=' . $tagID)) { $emailBody .= ' but not inserted into membership record.'; bpDebug::logMessage('failed to add tag (ID=' . $tagID . ') for member. Database error follows:'); bpDebug::logMessage($db->getLastError()); } $emailBody .= LF; } else { bpDebug::logMessage('Tag (ID=' . $tagID . ', Form Field: \'' . $field . '\') selected but either does not exist, does not belong to this organisation or is not a public tag.'); } } else { bpDebug::logMessage('field \'' . $field . '\' is not a tag'); } } /* * insert the reg option */ /* difficult to check for error: rate can be 0 * if joining member to existing joint member rate is '0.00' */ if(0 == $sessionData['ProposedJointMembershipID']) { $rate = $db->getField($_POST['Membership___CategoryID'], 'OrganisationMembershipCategory', 'AnnualRate'); } else { $rate = '0.00'; } if(defined('MEMBERSHIP_SUBSCRIPTION_INVOICE_STATUS') && $db->isValidSubscriptionInvoiceStatus(constant('MEMBERSHIP_SUBSCRIPTION_INVOICE_STATUS'))) { $invoiceStatus = constant('MEMBERSHIP_SUBSCRIPTION_INVOICE_STATUS'); } else { $invoiceStatus = 'Not Invoiced'; } if($db->query('INSERT INTO `Subscriptions` (`MembershipID`, `CategoryID`, `StartYear`, `Years`, `AnnualRate`, `FinalSubscription`, `InvoiceStatus`) VALUES (' . $membershipID . ', ' . $_POST['Membership___CategoryID'] . ', ' . $sessionData['StartYear'] . ', ' . $_POST['Membership___Years'] . ', ' . $rate . ', ' . $sessionData['FinalSubscription'] . ', \'' . $invoiceStatus . '\')')) { $subsID = $db->getLastInsertID(); //echo '' . LF; $db->query('UPDATE `Membership` SET `Membership`.`LatestSubscriptionID`=' . $subsID . ' WHERE `Membership`.`MembershipID`=' . $membershipID); // check is failing even when insertion is successful, so it has been disabled //if($db->isValidSubscriptionID($subsID)) //{ /* ** do the joint membership */ if($sessionData['ProposedJointMembershipID'] > 0) { // join new member to existing as secondary $primarySubsID = $db->getField($sessionData['ProposedJointMembershipID'], 'ProposedJointMembership', 'SubscriptionID'); if(!$db->query('INSERT INTO `JointMembership` SET `JointMembership`.`PrimarySubscriptionID`=' . $primarySubsID . ', `JointMembership`.`OtherSubscriptionID`=' . $subsID)) { // email to inform of failure to join member properly if(!$noSysadminEmail) { NomadMailer::mail(MECON_SYSADMIN_EMAIL, 'Membership Application Failure for ' . $organisationName . ' (OrganisationID: ' . constant('ORGANISATIONID') . ')', 'A secondary joint member applied but the application was unable to create the join to the primary member:' . LFLF . 'MembershipID: ' . $membershipID . LF . 'SubscriptionID: ' . $subsID . LF . 'CategoryID: ' . $_POST['Membership___CategoryID'] . LF . 'PrimarySubscriptionID: ' . $primarySubsID . LFLF . 'The membership record has not been deleted.' . LFLF . 'GET data (as PHP):' . LF . var_export($_GET, true) . LFLF . 'POST data (as PHP):' . LF . var_export($_POST, true) . LFLF .'Configuration follows:' . LFLF . file_get_contents('config.php')); } $emailBody .= LFLF . 'NOTE' . LF . 'The application process reported an error joining a secondary member to the appropriate primary member.'; } else { // delete the holding area record if(!$db->query('DELETE FROM `ProposedJointMembership` WHERE `ProposedJointMembership`.`ProposedJointMembershipID`=' . $sessionData['ProposedJointMembershipID'] . ' LIMIT 1')) { // email to inform of failure to take out holding area record if(!$noSysadminEmail) { NomadMailer::mail(MECON_SYSADMIN_EMAIL, 'Membership Application Failure for ' . $organisationName . ' (OrganisationID: ' . constant('ORGANISATIONID') . ')', 'A secondary joint member applied and was successfully joined to the primary, but the application was unable to remove the secondary\'s record in the holding area:' . LFLF . 'MembershipID: ' . $membershipID . LF . 'SubscriptionID: ' . $subsID . LF . 'CategoryID: ' . $_POST['Membership___CategoryID'] / LF . 'PrimarySubscriptionID: ' . $primarySubsID . LF .'ProposedJointMembershipID: ' . $sessionData['ProposedJointMembershipID'] . LFLF); } $emailBody .= LF . 'The application process reported an error removing the holding area record for a successfully joined secondary member.' . LF; } } } else if($db->isJointMembership($subsID)) { // bung secondary's details in holding area if(!$db->query('INSERT INTO `ProposedJointMembership` SET `ProposedJointMembership`.`SubscriptionID`=' . $subsID . ', `ProposedJointMembership`.`FirstName`=\'' . $db->escapeText($_POST['Membership___JointMemberFirstName']) . '\', `ProposedJointMembership`.`LastName`=\'' . $db->escapeText($_POST['Membership___JointMemberLastName']) . '\', `ProposedJointMembership`.`DateOfBirth`=\'' . $_POST['Membership___JointMemberDateOfBirth'] . '\', `ProposedJointMembership`.`EMail`=\'' . $db->escapeText($_POST['Membership___JointMemberEmail']) . '\'')) { // failed to create joint member if(!$noSysadminEmail) { NomadMailer::mail(MECON_SYSADMIN_EMAIL, 'Membership Application Failure for ' . $organisationName . ' (OrganisationID: ' . constant('ORGANISATIONID') . ')', 'A joint membership was requested but the link to the details for the second member could not be created:' . LFLF . 'MembershipID: ' . $membershipID . LF . 'SubscriptionID: ' . $subsID . LF . 'CategoryID: ' . $_POST['Membership___CategoryID'] . LFLF . 'The membership record has not been deleted.'); } $emailBody .= LF . 'The application process reported an error recording the new joint member\'s second member.' . LF; message('There was a problem with the database. Your application could not be submitted at this time. Please try again later, and if the problem persists contact the administrator.', array($tryAgainOption), 'Membership Application Error'); } } //} //else //{ // /* // ** added subscription but mysql_insert_id() returned invalid subsid // */ // if(!$noSysadminEmail) { // NomadMailer::mail(MECON_SYSADMIN_EMAIL, "Membership Application Warning for ' . $organisationName . ' (OrganisationID: " . constant('ORGANISATIONID') . ")", // "Membership table was updated, but failed to validate the SubscriptionID returned by mysql_insert_id():\n\nMembershipID: $membershipID\nSubscriptionID: $subsID\nCategoryID: {$_POST['Membership___CategoryID']}\n\nThe membership record has not been deleted."); // } // $emailBody .= "\nThe application process reported an error creating the new member's subscription: the subscription was almost certainly created successfully, but the subscription ID created could not be verified.\n"; // //message('There was a problem with the database. Your application could not be submitted at this time. Please try again later, and if the problem persists contact the administrator.', array($tryAgainOption), 'Membership Application Error'); //} if(!$noOrgEmail && defined('MEMBERSHIP_MAILAPPLICATION') && true == constant('MEMBERSHIP_MAILAPPLICATION') && '' != ($orgAdminEmail = $db->getField(constant('ORGANISATIONID'), 'Organisation', 'MembershipAdministratorEMail')) && !mail($orgAdminEmail, 'New Member for ' . $db->getOrganisationSummary(constant('ORGANISATIONID')), $emailBody)) { if(!$noSysadminEmail) { NomadMailer::mail(MECON_SYSADMIN_EMAIL, 'NOTIFICATION FAILURE: New Member for ' . $db->getOrganisationSummary(constant('ORGANISATIONID')), 'The notification to the membership administrator was not accepted for delivery.' . LFLF . 'Membership Number: M' . $membershipID . LF . 'Name: ' . $db->getFullName($sessionData['PersonID']) . LFLF . 'Membership Admin Email: ' . $orgAdminEmail); } bpDebug::logError('Failed to send notification email to membership admin ("' . $orgAdminEmail . '") for new member ' . $membershipID . ' (' . $db->getFullName($sessionData['PersonID']) . ')'); } if(!$noSysadminEmail) { NomadMailer::mail(MECON_SYSADMIN_EMAIL, 'New Member for ' . $db->getOrganisationSummary(constant('ORGANISATIONID')), $emailBody); } echo '

' . ((defined('MEMBERSHIP_SUCCESSMESSAGE') && '' != constant('MEMBERSHIP_SUCCESSMESSAGE')) ? constant('MEMBERSHIP_SUCCESSMESSAGE') : 'Your application has been logged and you will be emailed an invoice in due course. Please bear in mind that it may take a couple of weeks to gather references.') . '

' . LF; $links = array(); if(defined('MEMBERSHIP_SHOW_HOME_PAGE_LINK') && true === constant('MEMBERSHIP_SHOW_HOME_PAGE_LINK')) { $links['Return to Home Page'] = $db->getField(constant('ORGANISATIONID'), 'Organisation', 'WebsiteURL'); } if(defined('MEMBERSHIP_SHOW_PAYMENT_PAGE_LINK') && true === constant('MEMBERSHIP_SHOW_PAYMENT_PAGE_LINK')) { $links['Payments Page'] = $db->getMemberInvoiceURL($membershipID); } if(0 < count($links)) { echo '' . LF; } //echo '

Return to ' . $organisationName . ' Home Page

' . LF; membershipLogoff(); $developerSessionData = array(); } else { // added member but could not link subscription if(!$noSysadminEmail) { NomadMailer::mail(MECON_SYSADMIN_EMAIL, 'Membership Failure for ' . $organisationName . ' (OrganisationID: ' . constant('ORGANISATIONID') . ')', 'Membership table was updated, but failed to link a subscription:' . LFLF . 'MembershipID: ' . $membershipID . LF . 'CategoryID: ' . $_POST['Membership___CategoryID'] . LFLF . 'The membership record has not been deleted.'); } //$db->query('DELETE FROM `Membership` WHERE `Membership`.`MembershipID`=' . $membershipID); meconFatalError('failed to create subscription record for new member', 'There was a problem submitting your application to our database. The problem has been reported to the website administrator.'); } } else { // added member but $db->getLastInsertID() returned invalid membership id if(!$noSysadminEmail) { NomadMailer::mail(MECON_SYSADMIN_EMAIL, 'Membership Application Failure for ' . $organisationName . ' (OrganisationID: ' . constant('ORGANISATIONID') . ')', 'Membership table was updated, but failed to validate the MembershipID returned by $db->getLastInsertID():' . LFLF . 'MembershipID: ' . $membershipID . LF . 'CategoryID: ' . $_POST['Membership___CategoryID'] . LFLF . 'The membership record has not been deleted.'); } membershipFatalError('Membership insert query returned invalid MembershipID', 'There was a problem with the database. Your application could not be submitted at this time. Please try again later, and if the problem persists contact the administrator.'); } } else { // failed to update db with new membership membershipFatalError('failed to create membership record for new member', 'We were unable to add your application to our database. Please try again later, and if the problem persists, contact the administrator.'); } } else { message('SQL updates disabled: membership record not created.'); } } break; case 'Cancel': if($newLoginSystem){ // redirect back to default stage header('Location: membershipform.php5'); exit(0); } membershipLogoff(); $developerSessionData = array(); echo '

You are no longer logged in to the membership application form.

' . LF; break; } } } echo '

Valid XHTML 1.0 Transitional

'; echo '

This page has passed the W3C XHTML1.0 compliance test.
It has also been tested on and found to work correctly with recent versions of Firefox, Safari, Chrome, Konqueror, Opera and IE.

'; if(inDeveloperMode()) { echo '
'; } ob_end_flush(); @include GITROOT.'/sharedlib/includes/debug-foot.php'; if(!defined('MEMBERSHIP_TAIL') || !@ readfile(constant('MEMBERSHIP_TAIL'))) { // a basic, default page tail echo ''; }