Пример #1
0
 public function __viewIndex()
 {
     $this->setPageType('table');
     $this->setTitle(__('%1$s – %2$s', array(__('Symphony'), __('Member Roles'))));
     if (is_null(extension_Members::getFieldHandle('role')) && !is_null(extension_Members::getMembersSection())) {
         $this->pageAlert(__('There is no Member: Role field in the active Members section. <a href="%s%d/">Add Member: Role field?</a>', array(SYMPHONY_URL . '/blueprints/sections/edit/', extension_Members::getMembersSection())), Alert::NOTICE);
     }
     $this->appendSubheading(__('Member Roles'), Widget::Anchor(__('Create New'), Administration::instance()->getCurrentPageURL() . 'new/', __('Create a Role'), 'create button', NULL, array('accesskey' => 'c')));
     $roles = RoleManager::fetch();
     $aTableHead = array(array(__('Name'), 'col'), array(__('Members'), 'col'));
     $aTableBody = array();
     if (!is_array($roles) || empty($roles)) {
         $aTableBody = array(Widget::TableRow(array(Widget::TableData(__('None found.'), 'inactive', NULL, count($aTableHead)))));
     } else {
         if (is_null(extension_Members::getMembersSection())) {
             $aTableBody = array(Widget::TableRow(array(Widget::TableData(__('No Member section has been specified in <a href="%s">Preferences</a>. Please do this first.', array(SYMPHONY_URL . '/system/preferences/')), 'inactive', NULL, count($aTableHead)))));
         } else {
             $sectionManager = new SectionManager(Administration::instance());
             $section = $sectionManager->fetch(extension_Members::getMembersSection());
             $with_selected_roles = array();
             $hasRoles = !is_null(extension_Members::getFieldHandle('role'));
             foreach ($roles as $role) {
                 // Setup each cell
                 $td1 = Widget::TableData(Widget::Anchor($role->get('name'), Administration::instance()->getCurrentPageURL() . 'edit/' . $role->get('id') . '/', null, 'content'));
                 if ($role->get('id') != Role::PUBLIC_ROLE) {
                     $td1->appendChild(Widget::Input("items[{$role->get('id')}]", null, 'checkbox'));
                 }
                 // Get the number of members for this role, as long as it's not the Public Role.
                 if ($hasRoles && $role->get('id') != Role::PUBLIC_ROLE) {
                     $member_count = Symphony::Database()->fetchVar('count', 0, sprintf("SELECT COUNT(*) AS `count` FROM `tbl_entries_data_%d` WHERE `role_id` = %d", extension_Members::getField('role')->get('id'), $role->get('id')));
                     $td2 = Widget::TableData(Widget::Anchor("{$member_count}", SYMPHONY_URL . '/publish/' . $section->get('handle') . '/?filter=' . extension_Members::getFieldHandle('role') . ':' . $role->get('id')));
                 } else {
                     if ($role->get('id') == Role::PUBLIC_ROLE) {
                         $td2 = Widget::TableData(__('This is the role assumed by the general public.'));
                     } else {
                         $td2 = Widget::TableData(__('None'), 'inactive');
                     }
                 }
                 // Add cells to a row
                 $aTableBody[] = Widget::TableRow(array($td1, $td2));
                 if ($hasRoles && $role->get('id') != Role::PUBLIC_ROLE) {
                     $with_selected_roles[] = array("move::" . $role->get('id'), false, $role->get('name'));
                 }
             }
         }
     }
     $table = Widget::Table(Widget::TableHead($aTableHead), NULL, Widget::TableBody($aTableBody), 'selectable');
     $this->Form->appendChild($table);
     $tableActions = new XMLElement('div');
     $tableActions->setAttribute('class', 'actions');
     $options = array(0 => array(null, false, __('With Selected...')), 2 => array('delete', false, __('Delete'), 'confirm'), 3 => array('delete-members', false, __('Delete Members'), 'confirm'));
     if (count($with_selected_roles) > 0) {
         $options[1] = array('label' => __('Move Members To'), 'options' => $with_selected_roles);
     }
     $tableActions->appendChild(Widget::Select('with-selected', $options));
     $tableActions->appendChild(Widget::Input('action[apply]', __('Apply'), 'submit'));
     $this->Form->appendChild($tableActions);
 }
 public function __construct($factory, $res)
 {
     parent::__construct($factory, $res);
     $field_ids = array();
     if (!is_null(extension_Members::getFieldHandle('identity'))) {
         $field_ids[] = extension_Members::getField('identity')->get('id');
     }
     if (!is_null(extension_Members::getFieldHandle('email'))) {
         $field_ids[] = extension_Members::getField('email')->get('id');
     }
     // Get data about linking fields that point to the members
     // section AND to one of the linking fields (Username/Email)
     $sql_result = Symphony::Database()->fetch(sprintf("\n\t\t\t\t\tSELECT `child_section_id`, `child_section_field_id`\n\t\t\t\t\tFROM `tbl_sections_association`\n\t\t\t\t\tWHERE `parent_section_id` = %d\n\t\t\t\t\tAND `parent_section_field_id` IN ('%s')\n\t\t\t\t", extension_Members::getMembersSection(), implode("','", $field_ids)));
     $result = array();
     if (is_array($sql_result)) {
         foreach ($sql_result as $data) {
             $result[$data['child_section_id']] = array('id' => $data['child_section_field_id']);
         }
     }
     $this->member_fields = $result;
 }
Пример #3
0
 /**
  * Part 2 - Update Password, logs the user in
  * If the user changed their password, we need to login them back into the
  * system with their new password.
  */
 public function filter_UpdatePasswordLogin(array $context)
 {
     // If the user didn't update their password, or no Identity field exists return
     if (empty($context['fields'][extension_Members::getFieldHandle('authentication')]['password'])) {
         return;
     }
     // Handle which is the Identity field, either the Member: Username or Member: Email field
     $identity = is_null(extension_Members::getFieldHandle('identity')) ? 'email' : 'identity';
     $this->login(array(extension_Members::getFieldHandle($identity) => $context['entry']->getData(extension_Members::getField($identity)->get('id'), true)->value, extension_Members::getFieldHandle('authentication') => $context['fields'][extension_Members::getFieldHandle('authentication')]['password']), false);
     if (isset($_REQUEST['redirect'])) {
         redirect($_REQUEST['redirect']);
     }
 }
Пример #4
0
 public function addMemberDetailsToPageParams(array $context = null)
 {
     if (!$this->isLoggedIn()) {
         return;
     }
     $this->initialiseMemberObject();
     $context['params']['member-id'] = $this->getMemberID();
     if (!is_null(extension_Members::getFieldHandle('role'))) {
         $role_data = $this->getMember()->getData(extension_Members::getField('role')->get('id'));
         $role = RoleManager::fetch($role_data['role_id']);
         if ($role instanceof Role) {
             $context['params']['member-role'] = $role->get('name');
         }
     }
     if (!is_null(extension_Members::getFieldHandle('activation'))) {
         if ($this->getMember()->getData(extension_Members::getField('activation')->get('id'), true)->activated != "yes") {
             $context['params']['member-activated'] = 'no';
         }
     }
 }
Пример #5
0
 /**
  * This function will ensure that the user who has submitted the form (and
  * hence is requesting that an event be triggered) is actually allowed to
  * do this request.
  * There are 2 action types, creation and editing. Creation is a simple yes/no
  * affair, whereas editing has three levels of permission, None, Own Entries
  * or All Entries:
  * - None: This user can't do process this event
  * - Own Entries: If the entry the user is trying to update is their own
  *   determined by if the `entry_id` or, in the case of a SBL or
  *   similar field, the `entry_id` of the linked entry matches the logged in
  *   user's id, process the event.
  * - All Entries: The user can update any entry in Symphony.
  * If there are no Roles in this system, or the event is set to ignore permissions
  * (by including a function, `ignoreRolePermissions` that returns `true`, it will
  * immediately proceed to processing any of the Filters attached to the event
  * before returning.
  *
  * @uses EventPreSaveFilter
  *
  * @param array $context
  * @return null
  */
 public function checkEventPermissions(array &$context)
 {
     // If this system has no Roles, or the event is set to ignore role permissions
     // continue straight to processing the Filters
     if (!FieldManager::isFieldUsed(extension_Members::getFieldType('role')) || method_exists($context['event'], 'ignoreRolePermissions') && $context['event']->ignoreRolePermissions() == true) {
         $this->__processEventFilters($context);
         return null;
     }
     // Prior to Symphony 2.2.2, the EventPreSaveFilter delegate doesn't
     // pass the `$entry_id`. This can cause an issue when an Event has the
     // `allow_multiple` filter set as we can't determine the correct `$entry_id`
     // This will check to see if the `$entry_id` is set, otherwise fallback
     // to the previous logic. This will mean that using `allow_multiple` will
     // not be compatible without Symphony 2.2.2 and Members 1.1
     // @see https://github.com/symphonycms/members/issues/167
     if (isset($context['entry_id']) && is_numeric($context['entry_id'])) {
         $entry_id = (int) $context['entry_id'];
         $action = 'edit';
     } else {
         if (isset($_POST['id']) && !empty($_POST['id'])) {
             $entry_id = (int) $_POST['id'];
             $action = 'edit';
         } else {
             $action = 'create';
             $entry_id = 0;
         }
     }
     $required_level = $action == 'create' ? EventPermissions::CREATE : EventPermissions::ALL_ENTRIES;
     $role_id = Role::PUBLIC_ROLE;
     $isLoggedIn = $this->getMemberDriver()->isLoggedIn();
     if ($isLoggedIn && $this->getMemberDriver()->initialiseMemberObject()) {
         if ($this->getMemberDriver()->getMember() instanceof Entry) {
             $required_level = EventPermissions::OWN_ENTRIES;
             $role_data = $this->getMemberDriver()->getMember()->getData(extension_Members::getField('role')->get('id'));
             $role_id = $role_data['role_id'];
             if ($action == 'edit' && method_exists($context['event'], 'getSource')) {
                 $section_id = $context['event']->getSource();
                 $isOwner = false;
                 // If the event is the same section as the Members section, then for `$isOwner`
                 // to be true, the `$entry_id` must match the currently logged in user.
                 if ($section_id == $this->getMemberDriver()->getMember()->get('section_id')) {
                     // Check the logged in member is the same as the `entry_id` that is about to
                     // be updated. If so the user is the Owner and can modify EventPermissions::OWN_ENTRIES
                     $isOwner = $this->getMemberDriver()->getMemberID() == $entry_id;
                 } else {
                     $field_ids = array();
                     // Get the ID's of the fields that may be used for Linking (Username/Email)
                     if (!is_null(extension_Members::getFieldHandle('identity'))) {
                         $field_ids[] = extension_Members::getField('identity')->get('id');
                     }
                     if (!is_null(extension_Members::getFieldHandle('email'))) {
                         $field_ids[] = extension_Members::getField('email')->get('id');
                     }
                     // Query for the `field_id` of any linking fields that link to the members
                     // section AND to one of the linking fields (Username/Email)
                     $fields = Symphony::Database()->fetchCol('child_section_field_id', sprintf("\n\t\t\t\t\t\t\t\t\tSELECT `child_section_field_id`\n\t\t\t\t\t\t\t\t\tFROM `tbl_sections_association`\n\t\t\t\t\t\t\t\t\tWHERE `parent_section_id` = %d\n\t\t\t\t\t\t\t\t\tAND `child_section_id` = %d\n\t\t\t\t\t\t\t\t\tAND `parent_section_field_id` IN ('%s')\n\t\t\t\t\t\t\t\t", $this->getMemberDriver()->getMember()->get('section_id'), $section_id, implode("','", $field_ids)));
                     // If there was a link found, get the `relation_id`, which is the `member_id` of
                     // an entry in the active Members section.
                     if (!empty($fields)) {
                         foreach ($fields as $field_id) {
                             if ($isOwner === true) {
                                 break;
                             }
                             $field = FieldManager::fetch($field_id);
                             if ($field instanceof Field) {
                                 // So we are trying to find all entries that have selected the Member entry
                                 // to determine ownership. This check will use the `fetchAssociatedEntryIDs`
                                 // function, which typically works backwards, by accepting the `entry_id` (in
                                 // this case, our logged in Member ID). This will return an array of all the
                                 // linked entries, so we then just check that the current entry that is going to
                                 // be updated is in that array
                                 $member_id = $field->fetchAssociatedEntryIDs($this->getMemberDriver()->getMemberID());
                                 $isOwner = in_array($entry_id, $member_id);
                             }
                         }
                     }
                 }
                 // User is not the owner, so they can edit EventPermissions::ALL_ENTRIES
                 if ($isOwner === false) {
                     $required_level = EventPermissions::ALL_ENTRIES;
                 }
             }
         }
     }
     $role = RoleManager::fetch($role_id);
     $event_handle = strtolower(preg_replace('/^event/i', NULL, get_class($context['event'])));
     $success = false;
     if ($role) {
         $success = $role->canProcessEvent($event_handle, $action, $required_level) ? true : false;
     }
     $context['messages'][] = array('permission', $success, $success === false ? __('You are not authorised to perform this action.') : null);
     // Process the Filters for this event.
     $this->__processEventFilters($context);
 }
Пример #6
0
 /**
  * Will delete the Role given a `$role_id`. Should `$purge_members`
  * be passed, this function will remove all Members associated with
  * this role as well
  *
  * @param integer $role_id
  * @param boolean $purge_members
  * @return boolean
  */
 public function delete($role_id, $purge_members = false)
 {
     Symphony::Database()->delete("`tbl_members_roles_forbidden_pages`", " `role_id` = " . $role_id);
     Symphony::Database()->delete("`tbl_members_roles_event_permissions`", " `role_id` = " . $role_id);
     Symphony::Database()->delete("`tbl_members_roles`", " `id` = " . $role_id);
     if ($purge_members) {
         $members = Symphony::Database()->fetchCol('entry_id', sprintf("SELECT `entry_id` FROM `tbl_entries_data_%d` WHERE `role_id` = %d", extension_Members::getField('role')->get('id'), $role_id));
         /**
          * Prior to deletion of entries. Array of Entry ID's is provided.
          * The array can be manipulated
          *
          * @delegate Delete
          * @param string $context
          * '/publish/'
          * @param array $checked
          *  An array of Entry ID's passed by reference
          */
         Symphony::ExtensionManager()->notifyMembers('Delete', '/publish/', array('entry_id' => &$checked));
         $entryManager = new EntryManager(Symphony::Engine());
         $entryManager->delete($members);
     }
     return true;
 }
 protected function __trigger()
 {
     $result = new XMLElement(self::ROOTELEMENT);
     $fields = $_REQUEST['fields'];
     // Add POST values to the Event XML
     $post_values = new XMLElement('post-values');
     // Create the post data cookie element
     if (is_array($fields) && !empty($fields)) {
         General::array_to_xml($post_values, $fields, true);
     }
     // Trigger the EventPreSaveFilter delegate. We are using this to make
     // use of the XSS Filter extension that will ensure our data is ok to use
     $this->notifyEventPreSaveFilter($result, $fields, $post_values);
     if ($result->getAttribute('result') == 'error') {
         return $result;
     }
     // Add any Email Templates for this event
     $this->addEmailTemplates('reset-password-template');
     // Check that there is a row with this recovery code and that they
     // request a password reset
     $auth = extension_Members::getField('authentication');
     if (!$auth instanceof fieldMemberPassword) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('error', null, array('type' => 'invalid', 'message' => __('No Authentication field found.'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Check that either a Member: Username or Member: Email field
     // has been detected
     $identity = SymphonyMember::setIdentityField($fields, false);
     if (!$identity instanceof Identity) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('error', null, array('type' => 'invalid', 'message' => __('No Identity field found.'))));
         $result->appendChild($post_values);
         return $result;
     }
     if (!isset($fields[extension_Members::getFieldHandle('authentication')]['recovery-code']) or empty($fields[extension_Members::getFieldHandle('authentication')]['recovery-code'])) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement($auth->get('element_name'), null, array('type' => 'missing', 'message' => __('Recovery code is a required field.'), 'label' => $auth->get('label'))));
         $result->appendChild($post_values);
         return $result;
     }
     $row = Symphony::Database()->fetchRow(0, sprintf("\n\t\t\t\t\tSELECT `entry_id`, `recovery-code`\n\t\t\t\t\tFROM tbl_entries_data_%d\n\t\t\t\t\tWHERE reset = 'yes'\n\t\t\t\t\tAND `recovery-code` = '%s'\n\t\t\t\t", $auth->get('id'), Symphony::Database()->cleanValue($fields[extension_Members::getFieldHandle('authentication')]['recovery-code'])));
     if (empty($row)) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement($auth->get('element_name'), null, array('type' => 'invalid', 'message' => __('No recovery code found.'), 'label' => $auth->get('label'))));
     } else {
         // Retrieve Member Entry record
         $driver = Symphony::ExtensionManager()->create('members');
         $entry = $driver->getMemberDriver()->fetchMemberFromID($row['entry_id']);
         // Check that the given Identity data matches the Member that the
         // recovery code is for
         $member_id = $identity->fetchMemberIDBy($fields[$identity->get('element_name')]);
         if (!$entry instanceof Entry || $member_id != $row['entry_id']) {
             $result->setAttribute('result', 'error');
             $result->appendChild(new XMLElement($identity->get('element_name'), null, array('type' => 'invalid', 'message' => __('Member not found.'), 'label' => $identity->get('label'))));
             $result->appendChild($post_values);
             return $result;
         }
         // Check that the recovery code is still valid and has not expired
         if (is_null(Symphony::Database()->fetchVar('entry_id', 0, sprintf("\n\t\t\t\t\t\tSELECT `entry_id`\n\t\t\t\t\t\tFROM `tbl_entries_data_%d`\n\t\t\t\t\t\tWHERE `entry_id` = %d\n\t\t\t\t\t\tAND DATE_FORMAT(expires, '%%Y-%%m-%%d %%H:%%i:%%s') > '%s'\n\t\t\t\t\t\tLIMIT 1\n\t\t\t\t\t", $auth->get('id'), $member_id, DateTimeObj::get('Y-m-d H:i:s', strtotime('now - ' . $auth->get('code_expiry'))))))) {
             $result->setAttribute('result', 'error');
             $result->appendChild(new XMLElement($auth->get('element_name'), null, array('type' => 'invalid', 'message' => __('Recovery code has expired.'), 'label' => $auth->get('label'))));
             $result->appendChild($post_values);
             return $result;
         }
         // Create new password using the auth field so simulate the checkPostFieldData
         // and processRawFieldData functions.
         $message = '';
         $status = $auth->checkPostFieldData($fields[$auth->get('element_name')], $message, $member_id);
         if (Field::__OK__ != $status) {
             $result->setAttribute('result', 'error');
             $result->appendChild(new XMLElement($auth->get('element_name'), null, array('type' => $status == Field::__MISSING_FIELDS__ ? 'missing' : 'invalid', 'message' => $message, 'label' => $auth->get('label'))));
             $result->appendChild($post_values);
             return $result;
         }
         // processRawFieldData will encode the user's new password with the current one
         $status = Field::__OK__;
         $data = $auth->processRawFieldData(array('password' => Symphony::Database()->cleanValue($fields[$auth->get('element_name')]['password'])), $status);
         $data['recovery-code'] = null;
         $data['reset'] = 'no';
         $data['expires'] = null;
         // Update the database with the new password, removing the recovery code and setting
         // reset to no.
         Symphony::Database()->update($data, 'tbl_entries_data_' . $auth->get('id'), ' `entry_id` = ' . $member_id);
         // Trigger the EventFinalSaveFilter delegate. The Email Template Filter
         // and Email Template Manager extensions use this delegate to send any
         // emails attached to this event
         $this->notifyEventFinalSaveFilter($result, $fields, $post_values, $entry);
         if (extension_Members::getSetting('reset-password-auto-login') == "yes") {
             // Instead of replicating the same logic, call the UpdatePasswordLogin which will
             // handle relogging in the user.
             $driver->getMemberDriver()->filter_UpdatePasswordLogin(array('entry' => $entry, 'fields' => array(extension_Members::getFieldHandle('authentication') => array('password' => Symphony::Database()->cleanValue($fields[$auth->get('element_name')]['password'])))));
         }
         if (isset($_REQUEST['redirect'])) {
             redirect($_REQUEST['redirect']);
         }
         $result->setAttribute('result', 'success');
     }
     $result->appendChild($post_values);
     return $result;
 }
Пример #8
0
 /**
  * If the Members installation has a Activation field used, we need to make sure
  * that this field represents accurately what Role this Member actually has.
  * The Activation field allows developers to set a Activation Role, which is the role
  * assigned to Members who have registered, but not yet activated their account.
  * This Activation role masks the Role field's value, so the Member assumes the
  * Role of the Activation role.
  *
  * @param integer $entry_id
  *  The Entry ID of the Member
  * @param integer $role_id
  *  A given Role ID
  * @return integer
  *  The resulting Role ID, whether that is the Activation ID or the
  *  given `$role_id`.
  */
 public function getActivationRole($entry_id = null, $role_id = null)
 {
     if (is_null($entry_id)) {
         return null;
     }
     $activation_role_id = null;
     $activation = extension_Members::getField('activation', $this->get('parent_section'));
     if (!is_null($activation) && !is_null($entry_id)) {
         $entry = EntryManager::fetch($entry_id);
         $entry = $entry[0];
         if ($entry instanceof Entry && $entry->getData($activation->get('id'), true)->activated != 'yes') {
             $activation_role_id = $activation->get('activation_role_id');
         }
     }
     if (!is_null($role_id) && is_null($activation_role_id)) {
         return $role_id;
     } else {
         return $activation_role_id;
     }
 }
 protected function __trigger()
 {
     $result = new XMLElement(self::ROOTELEMENT);
     $fields = $_POST['fields'];
     // Add POST values to the Event XML
     $post_values = new XMLElement('post-values');
     // Create the post data cookie element
     if (is_array($fields) && !empty($fields)) {
         General::array_to_xml($post_values, $fields, true);
     }
     // Trigger the EventPreSaveFilter delegate. We are using this to make
     // use of the XSS Filter extension that will ensure our data is ok to use
     $this->notifyEventPreSaveFilter($result, $fields, $post_values);
     if ($result->getAttribute('result') == 'error') {
         return $result;
     }
     // Add any Email Templates for this event
     $this->addEmailTemplates('activate-account-template');
     // Do sanity checks on the incoming data
     $activation = extension_Members::getField('activation');
     if (!$activation instanceof fieldMemberActivation) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('error', null, array('type' => 'invalid', 'message' => __('No Activation field found.'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Check that either a Member: Username or Member: Email field has been detected
     $identity = SymphonyMember::setIdentityField($fields, false);
     if (!$identity instanceof Identity) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('error', null, array('type' => 'invalid', 'message' => __('No Identity field found.'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Ensure that the Member: Activation field has been provided
     if (!isset($fields[$activation->get('element_name')]) or empty($fields[$activation->get('element_name')])) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement($activation->get('element_name'), null, array('type' => 'missing', 'message' => __('%s is a required field.', array($activation->get('label'))), 'label' => $activation->get('label'))));
         $result->appendChild($post_values);
         return $result;
     } else {
         $fields[$activation->get('element_name')] = trim($fields[$activation->get('element_name')]);
     }
     // Check that a member exists first before proceeding.
     $member_id = $identity->fetchMemberIDBy($fields[$identity->get('element_name')]);
     if (is_null($member_id)) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement($identity->get('element_name'), null, array('type' => 'invalid', 'message' => __('Member not found.'), 'label' => $identity->get('label'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Retrieve Member's entry
     $driver = Symphony::ExtensionManager()->create('members');
     $entry = $driver->getMemberDriver()->fetchMemberFromID($member_id);
     if ($entry->getData($activation->get('id'), true)->activated == 'yes') {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement($activation->get('element_name'), null, array('type' => 'invalid', 'message' => __('Member is already activated.'), 'label' => $activation->get('label'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Make sure we dont accidently use an expired code
     $activation->purgeCodes();
     $code = $activation->isCodeActive($member_id);
     if ($code['code'] != $fields[$activation->get('element_name')]) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement($activation->get('element_name'), null, array('type' => 'invalid', 'message' => __('Activation error. Code was invalid or has expired.'), 'label' => $activation->get('label'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Got to here, then everything is awesome.
     $status = Field::__OK__;
     $data = $activation->processRawFieldData(array('activated' => 'yes', 'timestamp' => DateTimeObj::get('Y-m-d H:i:s', time()), 'code' => null), $status);
     // Update the database setting activation to yes.
     Symphony::Database()->update($data, 'tbl_entries_data_' . $activation->get('id'), ' `entry_id` = ' . $member_id);
     // Update our `$entry` object with the new activation data
     $entry->setData($activation->get('id'), $data);
     // Simulate an array to login with.
     $data_fields = array_merge($fields, array(extension_Members::getFieldHandle('authentication') => $entry->getData(extension_Members::getField('authentication')->get('id'), true)->password));
     // Only login if the Activation field allows auto login.
     if (extension_Members::getSetting('activate-account-auto-login') == 'no' || $driver->getMemberDriver()->login($data_fields, true)) {
         // Trigger the EventFinalSaveFilter delegate. The Email Template Filter
         // and Email Template Manager extensions use this delegate to send any
         // emails attached to this event
         $this->notifyEventFinalSaveFilter($result, $fields, $post_values, $entry);
         // If a redirect is set, redirect, the page won't be able to receive
         // the Event XML anyway
         if (isset($_REQUEST['redirect'])) {
             redirect($_REQUEST['redirect']);
         }
         $result->setAttribute('result', 'success');
     } else {
         if (extension_Members::getSetting('activate-account-auto-login') == 'yes') {
             if (isset($_REQUEST['redirect'])) {
                 redirect($_REQUEST['redirect']);
             }
             $result->setAttribute('result', 'error');
         }
     }
     $result->appendChild($post_values);
     return $result;
 }
 protected function __trigger()
 {
     $result = new XMLElement(self::ROOTELEMENT);
     $fields = $_POST['fields'];
     $driver = Symphony::ExtensionManager()->create('members');
     // Add POST values to the Event XML
     $post_values = new XMLElement('post-values');
     // Create the post data cookie element
     if (is_array($fields) && !empty($fields)) {
         General::array_to_xml($post_values, $fields, true);
     }
     // If a member is logged in, return early with an error
     if ($driver->getMemberDriver()->isLoggedIn()) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('error', null, array('type' => 'invalid', 'message' => __('You cannot generate a recovery code while being logged in.'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Trigger the EventPreSaveFilter delegate. We are using this to make
     // use of the XSS Filter extension that will ensure our data is ok to use
     $this->notifyEventPreSaveFilter($result, $fields, $post_values);
     if ($result->getAttribute('result') == 'error') {
         return $result;
     }
     // Add any Email Templates for this event
     $this->addEmailTemplates('generate-recovery-code-template');
     // Check that either a Member: Username or Member: Password field
     // has been detected
     $identity = SymphonyMember::setIdentityField($fields, false);
     if (!$identity instanceof Identity) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('error', null, array('type' => 'invalid', 'message' => __('No Identity field found.'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Check that a member exists first before proceeding.
     if (!isset($fields[$identity->get('element_name')]) or empty($fields[$identity->get('element_name')])) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement($identity->get('element_name'), null, array('type' => 'missing', 'message' => __('%s is a required field.', array($identity->get('label'))), 'label' => $identity->get('label'))));
         $result->appendChild($post_values);
         return $result;
     }
     $member_id = $identity->fetchMemberIDBy($fields[$identity->get('element_name')]);
     if (is_null($member_id)) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement($identity->get('element_name'), null, array('type' => 'invalid', 'message' => __('Member not found.'), 'label' => $identity->get('label'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Generate new password
     $newPassword = General::generatePassword();
     // Set the Entry password to be reset and the current timestamp
     $auth = extension_Members::getField('authentication');
     $status = Field::__OK__;
     $entry = $driver->getMemberDriver()->fetchMemberFromID($member_id);
     $entry_data = $entry->getData();
     // Generate a Recovery Code with the same logic as a normal password
     $data = $auth->processRawFieldData(array('password' => General::hash($newPassword . $member_id, 'sha1')), $status);
     $data['recovery-code'] = $data['password'];
     $data['reset'] = 'yes';
     $data['expires'] = DateTimeObj::get('Y-m-d H:i:s', time());
     // Overwrite the password with the old password data. This prevents
     // a users account from being locked out if it it just reset by a random
     // member of the public
     $data['password'] = $entry_data[$auth->get('id')]['password'];
     $data['length'] = $entry_data[$auth->get('id')]['length'];
     $data['strength'] = $entry_data[$auth->get('id')]['strength'];
     Symphony::Database()->update($data, 'tbl_entries_data_' . $auth->get('id'), ' `entry_id` = ' . $member_id);
     // Trigger the EventFinalSaveFilter delegate. The Email Template Filter
     // and Email Template Manager extensions use this delegate to send any
     // emails attached to this event
     $this->notifyEventFinalSaveFilter($result, $fields, $post_values, $entry);
     // If a redirect is set, redirect, the page won't be able to receive
     // the Event XML anyway
     if (isset($_REQUEST['redirect'])) {
         redirect($_REQUEST['redirect']);
     }
     $result->setAttribute('result', 'success');
     $result->appendChild(new XMLElement('recovery-code', $data['recovery-code']));
     $result->appendChild($post_values);
     return $result;
 }
 /**
  * Determine current member role ID.
  *
  * @return int
  */
 private final function memberDetermineRoleId()
 {
     $driver = $this->memberGetDriver();
     // not logged in?
     if (!$driver->isLoggedIn()) {
         return $this->memberGetDefaultRoleId();
     }
     /** @var $member Entry */
     $member = $driver->getMember();
     $role_data = $member->getData(extension_Members::getField('role')->get('id'));
     $role = RoleManager::fetch($role_data['role_id']);
     // role doesn't exist?
     if (!$role instanceof Role) {
         return $this->memberGetDefaultRoleId();
     }
     return (int) $role_data['role_id'];
 }
 protected function __trigger()
 {
     $result = new XMLElement(self::ROOTELEMENT);
     $fields = $_POST['fields'];
     // Add POST values to the Event XML
     $post_values = new XMLElement('post-values');
     // Create the post data cookie element
     if (is_array($fields) && !empty($fields)) {
         General::array_to_xml($post_values, $fields, true);
     }
     // Trigger the EventPreSaveFilter delegate. We are using this to make
     // use of the XSS Filter extension that will ensure our data is ok to use
     $this->notifyEventPreSaveFilter($result, $fields, $post_values);
     if ($result->getAttribute('result') == 'error') {
         return $result;
     }
     // Add any Email Templates for this event
     $this->addEmailTemplates('regenerate-activation-code-template');
     $activation = extension_Members::getField('activation');
     if (!$activation instanceof fieldMemberActivation) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('error', null, array('type' => 'invalid', 'message' => __('No Activation field found.'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Check that either a Member: Username or Member: Password field
     // has been detected
     $identity = SymphonyMember::setIdentityField($fields, false);
     if (!$identity instanceof Identity) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('error', null, array('type' => 'invalid', 'message' => __('No Identity field found.'))));
         $result->appendChild($post_values);
         return $result;
     }
     if (!isset($fields[$identity->get('element_name')]) or empty($fields[$identity->get('element_name')])) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement($identity->get('element_name'), null, array('type' => 'missing', 'message' => __('%s is a required field.', array($identity->get('label'))), 'label' => $identity->get('label'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Make sure we dont accidently use an expired code
     $activation->purgeCodes();
     // Check that a member exists first before proceeding.
     $member_id = $identity->fetchMemberIDBy($fields[$identity->get('element_name')]);
     if (is_null($member_id)) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement($identity->get('element_name'), null, array('type' => 'invalid', 'message' => __('Member not found.'), 'label' => $identity->get('label'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Check that the current member isn't already activated. If they
     // are, no point in regenerating the code.
     $driver = Symphony::ExtensionManager()->create('members');
     $entry = $driver->getMemberDriver()->fetchMemberFromID($member_id);
     if ($entry->getData($activation->get('id'), true)->activated == 'yes') {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement($activation->get('element_name'), null, array('type' => 'invalid', 'message' => __('Member is already activated.'), 'label' => $activation->get('label'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Regenerate the code
     $status = Field::__OK__;
     $data = $activation->processRawFieldData(array('activated' => 'no'), $status);
     // Update the database setting activation to yes.
     Symphony::Database()->update($data, 'tbl_entries_data_' . $activation->get('id'), ' `entry_id` = ' . $member_id);
     // Trigger the EventFinalSaveFilter delegate. The Email Template Filter
     // and Email Template Manager extensions use this delegate to send any
     // emails attached to this event
     $this->notifyEventFinalSaveFilter($result, $fields, $post_values, $entry);
     // If a redirect is set, redirect, the page won't be able to receive
     // the Event XML anyway
     if (isset($_REQUEST['redirect'])) {
         redirect($_REQUEST['redirect']);
     }
     $result->setAttribute('result', 'success');
     $result->appendChild(new XMLElement('activation-code', $data['code']));
     $result->appendChild($post_values);
     return $result;
 }