/** * Where `$name` is one of the following values, `role`, `timezone`, * `email`, `activation`, `authentication` and `identity`, this function * will return the Field's `element_name`. `element_name` is a handle * of the Field's label, used most commonly by events in `$_POST` data. * If no `$name` is given, an array of all Member field handles will * be returned. * * @param string $type * @return string */ public function getFieldHandle($type = null) { if (is_null($type)) { return null; } $type = extension_Members::getFieldType($type); // Check to see if this name has been stored in our 'static' cache // If it hasn't, lets go find it (for better or worse) if (!isset($this->handles[$type])) { $this->initialiseField($type, $this->section_id); } // No field, return null if (!isset($this->handles[$type])) { return null; } // Return the handle return $this->handles[$type]; }
/** * 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); }
/** * 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 static 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); $role_fields = FieldManager::fetch(null, null, 'ASC', 'sortorder', extension_Members::getFieldType('role')); if ($purge_members) { $members = array(); foreach ($role_fields as $role_field) { $members_of_role = Symphony::Database()->fetchCol('entry_id', sprintf("SELECT `entry_id` FROM `tbl_entries_data_%d` WHERE `role_id` = %d", $role_field->get('id'), $role_id)); $members = array_merge($members, $members_of_role); } /** * Prior to deletion of entries. An array of Entry ID's is provided which * can be manipulated. This delegate was renamed from `Delete` to `EntryPreDelete` * in Symphony 2.3. * * @delegate EntryPreDelete * @param string $context * '/publish/' * @param array $entry_id * An array of Entry ID's passed by reference */ Symphony::ExtensionManager()->notifyMembers('EntryPreDelete', '/publish/', array('entry_id' => &$members)); EntryManager::delete($members); /** * After the deletion of entries, this delegate provides an array of Entry ID's * that were deleted. * * @since Symphony 2.3 * @delegate EntryPostDelete * @param string $context * '/publish/' * @param array $entry_id * An array of Entry ID's that were deleted. */ Symphony::ExtensionManager()->notifyMembers('EntryPostDelete', '/publish/', array('entry_id' => $members)); } return true; }
public function __actionIndex() { $checked = is_array($_POST['items']) ? array_keys($_POST['items']) : null; if (is_array($checked) && !empty($checked)) { if (preg_match('/move::(\\d+)/i', $_POST['with-selected'], $match)) { $roleFields = FieldManager::fetch(null, null, 'ASC', 'sortorder', extension_Members::getFieldType('role')); $target_role = $match[1]; if (!($replacement = RoleManager::fetch($target_role))) { return false; } foreach ($checked as $role_id) { if ($role_id == $target_role) { continue; } foreach ($roleFields as $roleField) { Symphony::Database()->query(sprintf("\n\t\t\t\t\t\t\t\t\tUPDATE `tbl_entries_data_%d` SET `role_id` = %d WHERE `role_id` = %d\n\t\t\t\t\t\t\t\t", $roleField->get('id'), $target_role, $role_id)); } } return true; } switch ($_POST['with-selected']) { case 'delete': foreach ($checked as $role_id) { RoleManager::delete($role_id); } redirect(extension_Members::baseURL() . '/roles/'); break; case 'delete-members': foreach ($checked as $role_id) { RoleManager::delete($role_id, null, true); } redirect(extension_Members::baseURL() . '/roles/'); break; } } }
/** * Returns an Entry object given an array of credentials * * @param array $credentials * @param boolean $isHashed * Defaults to false * @return integer */ public function findMemberIDFromCredentials(array $credentials, $isHashed = false) { if ((!isset($credentials['username']) || is_null($credentials['username'])) && (!isset($credentials['email']) || is_null($credentials['email']))) { return null; } $identity = $this->setIdentityField($credentials); if (!$identity instanceof Field) { return null; } // Member from Identity $member_id = $identity->fetchMemberIDBy($credentials); // Validate against Password $auth = $this->section->getField('authentication'); if (!is_null($auth)) { $member_id = $auth->fetchMemberIDBy($credentials, $member_id, $isHashed); } // No Member found, can't even begin to check Activation // Return null if (is_null($member_id)) { return null; } // Check that if there's activiation, that this Member is activated. if (!is_null($this->section->getFieldHandle('activation'))) { $entry = EntryManager::fetch($member_id, NULL, NULL, NULL, NULL, NULL, false, true, array($this->section->getFieldHandle('activation'))); $isActivated = $entry[0]->getData($this->section->getField('activation')->get('id'), true)->activated == "yes"; // If we are denying login for non activated members, lets do so now if ($this->section->getField('activation')->get('deny_login') == 'yes' && !$isActivated) { extension_Members::$_errors[$this->section->getFieldHandle('activation')] = array('message' => __('Member is not activated.'), 'type' => 'invalid', 'label' => $this->section->getField('activation')->get('label')); return null; } // If the member isn't activated and a Role field doesn't exist // just return false. if (!$isActivated && !FieldManager::isFieldUsed(extension_Members::getFieldType('role'))) { extension_Members::$_errors[$this->section->getFieldHandle('activation')] = array('message' => __('Member is not activated.'), 'type' => 'invalid', 'label' => $this->section->getField('activation')->get('label')); return false; } } return $member_id; }