Пример #1
0
 public function response()
 {
     $result = new XMLElement($this->_event_name);
     $post_values = new XMLElement('post-values');
     $fields = $_POST['fields'];
     if (!empty($fields)) {
         General::array_to_xml($post_values, $fields, true);
     }
     if (!empty($this->_error_array)) {
         $result->appendChild($post_values);
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('Entry encountered errors when saving.')));
         foreach ($this->_error_array as $field => $message) {
             $type = $fields[$field] == '' ? 'missing' : 'invalid';
             $field = new XMLElement($field);
             $field->setAttribute('type', $type);
             $field->setAttribute('message', $message);
             $result->appendChild($field);
         }
     } else {
         $result->setAttribute('result', 'success');
         $result->appendChild(new XMLElement('message', __('Entry created successfully.')));
     }
     return $result;
 }
 function action()
 {
     if ($this->_context[2] == 'saved') {
         $this->_context[2] = NULL;
     }
     $fields = new XMLElement('fields');
     General::array_to_xml($fields, (array) $_POST['fields']);
     $this->_XML->appendChild($fields);
     parent::action();
 }
 /**
  * This function does the bulk of processing the Event, from running the delegates
  * to validating the data and eventually saving the data into Symphony. The result
  * of the Event is returned via the `$result` parameter.
  *
  * @param array $fields
  *  An array of $_POST data, to process and add/edit an entry.
  * @param XMLElement $result
  *  The XMLElement contains the result of the Event, it is passed by
  *  reference.
  * @param integer $position
  *  When the Expect Multiple filter is added, this event should expect
  *  to deal with adding (or editing) multiple entries at once.
  * @param integer $entry_id
  *  If this Event is editing an existing entry, that Entry ID will
  *  be passed to this function.
  * @return XMLElement
  *  The result of the Event
  */
 public function __doit($fields, XMLElement &$result, $position = null, $entry_id = null)
 {
     $post_values = new XMLElement('post-values');
     if (!is_array($this->eParamFILTERS)) {
         $this->eParamFILTERS = array();
     }
     // Check to see if the Section of this Event is valid.
     if (!($section = SectionManager::fetch($this->getSource()))) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('The Section, %s, could not be found.', array($this->getSource()))));
         return false;
     }
     // Create the post data element
     if (is_array($fields) && !empty($fields)) {
         General::array_to_xml($post_values, $fields, true);
     }
     // If the EventPreSaveFilter fails, return early
     if ($this->processPreSaveFilters($result, $fields, $post_values, $entry_id) === false) {
         return false;
     }
     // If the `$entry_id` is provided, check to see if it exists.
     // @todo If this was moved above PreSaveFilters, we can pass the
     // Entry object to the delegate meaning extensions don't have to
     // do that step.
     if (isset($entry_id)) {
         $entry = EntryManager::fetch($entry_id);
         $entry = $entry[0];
         if (!is_object($entry)) {
             $result->setAttribute('result', 'error');
             $result->appendChild(new XMLElement('message', __('The Entry, %s, could not be found.', array($entry_id))));
             return false;
         }
     } else {
         $entry = EntryManager::create();
         $entry->set('section_id', $this->getSource());
     }
     // Validate the data. `$entry->checkPostData` loops over all fields calling
     // checkPostFieldData function. If the return of the function is `__ENTRY_FIELD_ERROR__`
     // then abort the event, adding the error messages to the `$result`.
     if (__ENTRY_FIELD_ERROR__ == $entry->checkPostData($fields, $errors, $entry->get('id') ? true : false)) {
         $result = self::appendErrors($result, $fields, $errors, $post_values);
         return false;
     } else {
         if (__ENTRY_OK__ != $entry->setDataFromPost($fields, $errors, false, $entry->get('id') ? true : false)) {
             $result = self::appendErrors($result, $fields, $errors, $post_values);
             return false;
         } else {
             if ($entry->commit() === false) {
                 $result->setAttribute('result', 'error');
                 $result->appendChild(new XMLElement('message', __('Unknown errors where encountered when saving.')));
                 if (isset($post_values) && is_object($post_values)) {
                     $result->appendChild($post_values);
                 }
                 return false;
             } else {
                 $result->setAttributeArray(array('result' => 'success', 'type' => isset($entry_id) ? 'edited' : 'created', 'id' => $entry->get('id')));
                 $result->appendChild(new XMLElement('message', isset($entry_id) ? __('Entry edited successfully.') : __('Entry created successfully.')));
             }
         }
     }
     // PASSIVE FILTERS ONLY AT THIS STAGE. ENTRY HAS ALREADY BEEN CREATED.
     if (in_array('send-email', $this->eParamFILTERS) && !in_array('expect-multiple', $this->eParamFILTERS)) {
         $result = $this->processSendMailFilter($result, $_POST['send-email'], $fields, $section, $entry);
     }
     $result = $this->processPostSaveFilters($result, $fields, $entry);
     $result = $this->processFinalSaveFilters($result, $fields, $entry);
     if (isset($post_values) && is_object($post_values)) {
         $result->appendChild($post_values);
     }
     return true;
 }
Пример #4
0
 public function appendLoginStatusToEventXML(array $context = null)
 {
     $result = new XMLElement('member-login-info');
     if ($this->isLoggedIn()) {
         $result->setAttributearray(array('logged-in' => 'yes', 'id' => $this->getMemberID(), 'result' => 'success'));
     } else {
         $result->setAttribute('logged-in', 'no');
         // Append error messages
         if (is_array(extension_Members::$_errors) && !empty(extension_Members::$_errors)) {
             foreach (extension_Members::$_errors as $type => $error) {
                 $result->appendChild(new XMLElement($type, null, array('type' => $error['type'], 'message' => $error['message'], 'label' => General::sanitize($error['label']))));
             }
         }
         // Append post values to simulate a real Symphony event
         if (extension_Members::$_failed_login_attempt) {
             $result->setAttribute('result', 'error');
             $post_values = new XMLElement('post-values');
             $post = General::getPostData();
             // Create the post data cookie element
             if (is_array($post['fields']) && !empty($post['fields'])) {
                 General::array_to_xml($post_values, $post['fields'], true);
                 $result->appendChild($post_values);
             }
         }
     }
     $context['wrapper']->appendChild($result);
 }
Пример #5
0
 function __doit($source, $fields, &$result, &$obj, &$event, $filters, $position = NULL, $entry_id = NULL)
 {
     $post_values = new XMLElement('post-values');
     $post = General::getPostData();
     $filter_results = array();
     ## Create the post data cookie element
     if (is_array($post) && !empty($post)) {
         General::array_to_xml($post_values, $fields, true);
     }
     ###
     # Delegate: EventPreSaveFilter
     # Description: Prior to saving entry from the front-end. This delegate will force the Event to terminate if it populates the error
     #              array reference. Provided with references to this object, the POST data and also the error array
     $obj->ExtensionManager->notifyMembers('EventPreSaveFilter', '/frontend/', array('fields' => $fields, 'event' => &$event, 'messages' => &$filter_results, 'post_values' => &$post_values));
     if (is_array($filter_results) && !empty($filter_results)) {
         foreach ($filter_results as $fr) {
             list($type, $status, $message) = $fr;
             $result->appendChild(buildFilterElement($type, $status ? 'passed' : 'failed', $message));
             if (!$status) {
                 $result->appendChild($post_values);
                 $result->setAttribute('result', 'error');
                 $result->appendChild(new XMLElement('message', __('Entry encountered errors when saving.')));
                 return false;
             }
         }
     }
     include_once TOOLKIT . '/class.sectionmanager.php';
     include_once TOOLKIT . '/class.entrymanager.php';
     $sectionManager = new SectionManager($obj);
     if (!($section = $sectionManager->fetch($source))) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('Section is invalid')));
         return false;
     }
     $entryManager = new EntryManager($obj);
     if (isset($entry_id) && $entry_id != NULL) {
         $entry =& $entryManager->fetch($entry_id);
         $entry = $entry[0];
         if (!is_object($entry)) {
             $result->setAttribute('result', 'error');
             $result->appendChild(new XMLElement('message', __('Invalid Entry ID specified. Could not create Entry object.')));
             return false;
         }
     } else {
         $entry =& $entryManager->create();
         $entry->set('section_id', $source);
     }
     $filter_errors = array();
     if (__ENTRY_FIELD_ERROR__ == $entry->checkPostData($fields, $errors, $entry->get('id') ? true : false)) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('Entry encountered errors when saving.')));
         foreach ($errors as $field_id => $message) {
             $field = $entryManager->fieldManager->fetch($field_id);
             $result->appendChild(new XMLElement($field->get('element_name'), NULL, array('type' => $fields[$field->get('element_name')] == '' ? 'missing' : 'invalid', 'message' => General::sanitize($message))));
         }
         if (isset($post_values) && is_object($post_values)) {
             $result->appendChild($post_values);
         }
         return false;
     } elseif (__ENTRY_OK__ != $entry->setDataFromPost($fields, $errors, false, $entry->get('id') ? true : false)) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('Entry encountered errors when saving.')));
         if (isset($errors['field_id'])) {
             $errors = array($errors);
         }
         foreach ($errors as $err) {
             $field = $entryManager->fieldManager->fetch($err['field_id']);
             $result->appendChild(new XMLElement($field->get('element_name'), NULL, array('type' => 'invalid')));
         }
         if (isset($post_values) && is_object($post_values)) {
             $result->appendChild($post_values);
         }
         return false;
     } else {
         if (!$entry->commit()) {
             $result->setAttribute('result', 'error');
             $result->appendChild(new XMLElement('message', __('Unknown errors where encountered when saving.')));
             if (isset($post_values) && is_object($post_values)) {
                 $result->appendChild($post_values);
             }
             return false;
         }
         $result->setAttribute('id', $entry->get('id'));
     }
     ## PASSIVE FILTERS ONLY AT THIS STAGE. ENTRY HAS ALREADY BEEN CREATED.
     if (@in_array('send-email', $filters) && !@in_array('expect-multiple', $filters)) {
         if (!function_exists('__sendEmailFindFormValue')) {
             function __sendEmailFindFormValue($needle, $haystack, $discard_field_name = true, $default = NULL, $collapse = true)
             {
                 if (preg_match('/^(fields\\[[^\\]]+\\],?)+$/i', $needle)) {
                     $parts = preg_split('/\\,/i', $needle, -1, PREG_SPLIT_NO_EMPTY);
                     $parts = array_map('trim', $parts);
                     $stack = array();
                     foreach ($parts as $p) {
                         $field = str_replace(array('fields[', ']'), '', $p);
                         $discard_field_name ? $stack[] = $haystack[$field] : ($stack[$field] = $haystack[$field]);
                     }
                     if (is_array($stack) && !empty($stack)) {
                         return $collapse ? implode(' ', $stack) : $stack;
                     } else {
                         $needle = NULL;
                     }
                 }
                 $needle = trim($needle);
                 if (empty($needle)) {
                     return $default;
                 }
                 return $needle;
             }
         }
         $fields = $_POST['send-email'];
         $fields['recipient'] = __sendEmailFindFormValue($fields['recipient'], $_POST['fields'], true);
         $fields['recipient'] = preg_split('/\\,/i', $fields['recipient'], -1, PREG_SPLIT_NO_EMPTY);
         $fields['recipient'] = array_map('trim', $fields['recipient']);
         $fields['recipient'] = $obj->Database->fetch("SELECT `email`, `first_name` FROM `tbl_authors` WHERE `username` IN ('" . @implode("', '", $fields['recipient']) . "') ");
         $fields['subject'] = __sendEmailFindFormValue($fields['subject'], $_POST['fields'], true, __('[Symphony] A new entry was created on %s', array($obj->Configuration->get('sitename', 'general'))));
         $fields['body'] = __sendEmailFindFormValue($fields['body'], $_POST['fields'], false, NULL, false);
         $fields['sender-email'] = __sendEmailFindFormValue($fields['sender-email'], $_POST['fields'], true, 'noreply@' . parse_url(URL, PHP_URL_HOST));
         $fields['sender-name'] = __sendEmailFindFormValue($fields['sender-name'], $_POST['fields'], true, 'Symphony');
         $edit_link = URL . '/symphony/publish/' . $section->get('handle') . '/edit/' . $entry->get('id') . '/';
         $body = __('Dear <!-- RECIPIENT NAME -->,') . General::CRLF . __('This is a courtesy email to notify you that an entry was created on the %1$s section. You can edit the entry by going to: %2$s', array($section->get('name'), $edit_link)) . General::CRLF . General::CRLF;
         if (is_array($fields['body'])) {
             foreach ($fields['body'] as $field_handle => $value) {
                 $body .= "// {$field_handle}" . General::CRLF . $value . General::CRLF . General::CRLF;
             }
         } else {
             $body .= $fields['body'];
         }
         $errors = array();
         if (!is_array($fields['recipient']) || empty($fields['recipient'])) {
             $result->appendChild(buildFilterElement('send-email', 'failed', __('No valid recipients found. Check send-email[recipient] field.')));
         } else {
             foreach ($fields['recipient'] as $r) {
                 list($email, $name) = array_values($r);
                 if (!General::sendEmail($email, $fields['sender-email'], $fields['sender-name'], $fields['subject'], str_replace('<!-- RECIPIENT NAME -->', $name, $body))) {
                     $errors[] = $email;
                 }
             }
             if (!empty($errors)) {
                 $xml = buildFilterElement('send-email', 'failed');
                 foreach ($errors as $address) {
                     $xml->appendChild(new XMLElement('recipient', $address));
                 }
                 $result->appendChild($xml);
             } else {
                 $result->appendChild(buildFilterElement('send-email', 'passed'));
             }
         }
     }
     $filter_results = array();
     ###
     # Delegate: EventPostSaveFilter
     # Description: After saving entry from the front-end. This delegate will not force the Events to terminate if it populates the error
     #              array reference. Provided with references to this object, the POST data and also the error array
     $obj->ExtensionManager->notifyMembers('EventPostSaveFilter', '/frontend/', array('entry_id' => $entry->get('id'), 'fields' => $fields, 'entry' => $entry, 'event' => &$event, 'messages' => &$filter_results));
     if (is_array($filter_results) && !empty($filter_results)) {
         foreach ($filter_results as $fr) {
             list($type, $status, $message) = $fr;
             $result->appendChild(buildFilterElement($type, $status ? 'passed' : 'failed', $message));
         }
     }
     ###
     # Delegate: EventFinalSaveFilter
     $obj->ExtensionManager->notifyMembers('EventFinalSaveFilter', '/frontend/', array('fields' => $fields, 'event' => &$event, 'errors' => &$filter_errors, 'entry' => $entry));
     $result->setAttributeArray(array('result' => 'success', 'type' => isset($entry_id) ? 'edited' : 'created'));
     $result->appendChild(new XMLElement('message', isset($entry_id) ? __('Entry edited successfully.') : __('Entry created successfully.')));
     if (isset($post_values) && is_object($post_values)) {
         $result->appendChild($post_values);
     }
     return true;
     ## End Function
 }
 protected function __trigger()
 {
     $result = new XMLElement(self::ROOTELEMENT);
     $fields = $_REQUEST['fields'];
     $this->driver = Symphony::ExtensionManager()->create('members');
     $requested_identity = $fields[extension_Members::getFieldHandle('identity')];
     // 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);
     }
     // Set the section ID
     $result = $this->setMembersSection($result, $_REQUEST['members-section-id']);
     if ($result->getAttribute('result') === 'error') {
         // We are not calling notifyMembersPasswordResetFailure here,
         // because this is not an authentication error
         $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') {
         // We are not calling notifyMembersPasswordResetFailure here,
         // because this is not an authentication 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 = $this->driver->getMemberDriver()->section->getField('authentication');
     if (!$auth instanceof fieldMemberPassword) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('No Authentication field found.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
         $this->notifyMembersPasswordResetFailure($requested_identity);
         $result->appendChild($post_values);
         return $result;
     }
     // Check that either a Member: Username or Member: Email field
     // has been detected
     $identity = $this->driver->getMemberDriver()->setIdentityField($fields, false);
     if (!$identity instanceof Identity) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('No Identity field found.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
         $this->notifyMembersPasswordResetFailure($requested_identity);
         $result->appendChild($post_values);
         return $result;
     }
     if (!isset($fields[$this->driver->getMemberDriver()->section->getFieldHandle('authentication')]['recovery-code']) or empty($fields[$this->driver->getMemberDriver()->section->getFieldHandle('authentication')]['recovery-code'])) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('Member event encountered errors when processing.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
         $result->appendChild(new XMLElement($auth->get('element_name'), null, array('label' => $auth->get('label'), 'type' => 'missing', 'message-id' => EventMessages::FIELD_MISSING, 'message' => __('Recovery code is a required field.'))));
         $this->notifyMembersPasswordResetFailure($requested_identity);
         $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[$this->driver->getMemberDriver()->section->getFieldHandle('authentication')]['recovery-code'])));
     if (empty($row)) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('Member encountered errors.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
         $result->appendChild(new XMLElement($auth->get('element_name'), null, array('label' => $auth->get('label'), 'type' => 'invalid', 'message-id' => EventMessages::FIELD_INVALID, 'message' => __('No recovery code found.'))));
         $this->notifyMembersPasswordResetFailure($requested_identity);
     } else {
         // Retrieve Member Entry record
         $entry = $this->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('message', __('Member event encountered errors when processing.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
             $result->appendChild(new XMLElement($identity->get('element_name'), null, extension_Members::$_errors[$identity->get('element_name')]));
             $this->notifyMembersPasswordResetFailure($requested_identity);
             $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('message', __('Member event encountered errors when processing.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
             $result->appendChild(new XMLElement($auth->get('element_name'), null, array('label' => $auth->get('label'), 'type' => 'invalid', 'message-id' => MemberEventMessages::RECOVERY_CODE_INVALID, 'message' => __('Recovery code has expired.'))));
             $this->notifyMembersPasswordResetFailure($requested_identity);
             $result->appendChild($post_values);
             return $result;
         }
         // Create new password using the auth field so simulate the checkPostFieldData
         // and processRawFieldData functions.
         $message = '';
         // For the purposes of this event, the auth field should ALWAYS be required
         // as we have to set a password (ie. handle the case where this field is
         // actually optional) RE: #193
         $auth->set('required', 'yes');
         $status = $auth->checkPostFieldData($fields[$auth->get('element_name')], $message, $member_id);
         if (Field::__OK__ != $status) {
             $result->setAttribute('result', 'error');
             $result->appendChild(new XMLElement('message', __('Member event encountered errors when processing.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
             $result->appendChild(new XMLElement($auth->get('element_name'), null, array('type' => $status == Field::__MISSING_FIELDS__ ? 'missing' : 'invalid', 'message' => $message, 'message-id' => $status == Field::__MISSING_FIELDS__ ? EventMessages::FIELD_MISSING : EventMessages::FIELD_INVALID, 'label' => $auth->get('label'))));
             $this->notifyMembersPasswordResetFailure($requested_identity);
             $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);
         /**
          * Fired just after a Member has reset their password.
          *
          * @delegate MembersPostResetPassword
          * @param string $context
          *  '/frontend/'
          * @param integer $member_id
          *  The Member ID of the member who just reset their password
          */
         Symphony::ExtensionManager()->notifyMembers('MembersPostResetPassword', '/frontend/', array('member_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.
             $this->driver->getMemberDriver()->filter_UpdatePasswordLogin(array('entry' => $entry, 'fields' => array($this->driver->getMemberDriver()->section->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;
 }
 private function getXML($position = 0, $entry_id = NULL)
 {
     // Cache stuff that can be reused between filter fields and entries
     static $post;
     static $postValues;
     // Remember if $post contains multiple entries or not
     static $expectMultiple;
     $xml = new XMLElement('data');
     // Get post values
     if (empty($postValues) || $position > 0) {
         // TODO: handle post of multiple entries at the same time
         if (empty($post)) {
             $post = General::getPostData();
             // Check if post contains multiple entries or not
             // TODO: make some hidden field required for post, so we can check for sure
             //       if $post['fields'][0]['conditionalizer'] exists?
             $expectMultiple = is_array($post['fields']) && is_array($post['fields'][0]) ? true : false;
         }
         if (!empty($post['fields']) && is_array($post['fields'])) {
             $postValues = new XMLElement('post');
             if ($expectMultiple == true) {
                 if (!empty($entry_id) && isset($post['id'])) {
                     // $entry_id overrides $position
                     foreach ($post['id'] as $pos => $id) {
                         if ($id == $entry_id) {
                             $position = $pos;
                             break;
                         }
                     }
                 } else {
                     if (isset($post['id'][$position]) && is_numeric($post['id'][$position])) {
                         $entry_id = $post['id'][$position];
                     }
                 }
                 $postValues->setAttribute('position', $position);
                 General::array_to_xml($postValues, $post['fields'][$position], false);
             } else {
                 if ($position < 1) {
                     if (empty($entry_id) && isset($post['id']) && is_numeric($post['id'])) {
                         $entry_id = $post['id'];
                     }
                     General::array_to_xml($postValues, $post['fields'], false);
                 } else {
                     // TODO: add error element?
                 }
             }
         }
     }
     if (!empty($postValues)) {
         $xml->appendChild($postValues);
     }
     // Get old entry
     $entry = NULL;
     if (!class_exists('EntryManager')) {
         include_once TOOLKIT . '/class.entrymanager.php';
     }
     if (!empty($entry_id)) {
         $entry = EntryManager::fetch($entry_id);
         $entry = $entry[0];
         if (is_object($entry)) {
             $entry_xml = new XMLElement('old-entry');
             $entry_xml->setAttribute('position', $position);
             $this->appendEntryXML($entry_xml, $entry);
             $xml->appendChild($entry_xml);
         } else {
             $entry = NULL;
         }
     } else {
         $entry = EntryManager::create();
         $entry->set('section_id', $this->get('parent_section'));
     }
     // Set new entry data. Code found in event.section.php:
     // https://github.com/symphonycms/symphony-2/blob/29244318e4de294df780513ee027edda767dd75a/symphony/lib/toolkit/events/event.section.php#L99
     if (is_object($entry)) {
         self::$recursion = true;
         if (__ENTRY_FIELD_ERROR__ == $entry->checkPostData($expectMultiple ? $post['fields'][$position] : $post['fields'], $errors, $entry->get('id') ? true : false)) {
             // Return early - other fields will mark their errors
             self::$recursion = false;
             return self::__OK__;
         } else {
             if (__ENTRY_OK__ != $entry->setDataFromPost($expectMultiple ? $post['fields'][$position] : $post['fields'], $errors, true, $entry->get('id') ? true : false)) {
                 // Return early - other fields will mark their errors.
                 self::$recursion = false;
                 return self::__OK__;
             }
         }
         self::$recursion = false;
         $entry_xml = new XMLElement('entry');
         $entry_xml->setAttribute('position', $position);
         $this->appendEntryXML($entry_xml, $entry);
         $xml->appendChild($entry_xml);
     }
     // Get author
     if ($temp = Symphony::Engine()->Author) {
         $author = new XMLElement('author');
         $author->setAttribute('id', $temp->get('id'));
         $author->setAttribute('user_type', $temp->get('user_type'));
         $author->setAttribute('primary', $temp->get('primary'));
         $author->setAttribute('username', $temp->get('username'));
         $author->setAttribute('first_name', $temp->get('first_name'));
         $author->setAttribute('last_name', $temp->get('last_name'));
         $xml->appendChild($author);
     }
     return $xml;
 }
 protected function __trigger()
 {
     $result = new XMLElement(self::ROOTELEMENT);
     $fields = $_POST['fields'];
     $this->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);
     }
     // Set the section ID
     $result = $this->setMembersSection($result, $_REQUEST['members-section-id']);
     if ($result->getAttribute('result') === 'error') {
         $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('regenerate-activation-code-template');
     $activation = $this->driver->getMemberDriver()->section->getField('activation');
     if (!$activation instanceof fieldMemberActivation) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('No Activation field found.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
         $result->appendChild($post_values);
         return $result;
     }
     // Check that either a Member: Username or Member: Password field
     // has been detected
     $identity = $this->driver->getMemberDriver()->setIdentityField($fields, false);
     if (!$identity instanceof Identity) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('No Identity field found.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
         $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('message', __('Member event encountered errors when processing.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
         $result->appendChild(new XMLElement($identity->get('element_name'), null, array('label' => $identity->get('label'), 'type' => 'missing', 'message-id' => EventMessages::FIELD_MISSING, 'message' => __('%s is a required field.', array($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('message', __('Member event encountered errors when processing.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
         $result->appendChild(new XMLElement($identity->get('element_name'), null, extension_Members::$_errors[$identity->get('element_name')]));
         $result->appendChild($post_values);
         return $result;
     }
     // Check that the current member isn't already activated. If they
     // are, no point in regenerating the code.
     $entry = $this->driver->getMemberDriver()->fetchMemberFromID($member_id);
     if ($entry->getData($activation->get('id'), true)->activated == 'yes') {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('Member event encountered errors when processing.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
         $result->appendChild(new XMLElement($activation->get('element_name'), null, array('label' => $activation->get('label'), 'type' => 'invalid', 'message-id' => MemberEventMessages::ACTIVATION_PRE_COMPLETED, 'message' => __('Member is already activated.'))));
         $result->appendChild($post_values);
         return $result;
     }
     // Regenerate the code
     $status = Field::__OK__;
     $data = $activation->processRawFieldData(array('activated' => 'no'), $status);
     // If the Member has entry data for the Activation field, update it to yes
     if (array_key_exists((int) $activation->get('id'), $entry->getData())) {
         Symphony::Database()->update($data, 'tbl_entries_data_' . $activation->get('id'), ' `entry_id` = ' . $member_id);
     } else {
         $data['entry_id'] = $member_id;
         Symphony::Database()->insert($data, 'tbl_entries_data_' . $activation->get('id'));
     }
     /**
      * Fired just after a Member has regenerated their activation code
      * for their account.
      *
      * @delegate MembersPostRegenerateActivationCode
      * @param string $context
      *  '/frontend/'
      * @param integer $member_id
      *  The Member ID of the member who just requested a new activation code
      * @param string $activation_code
      *  The new activation code for this Member
      */
     Symphony::ExtensionManager()->notifyMembers('MembersPostRegenerateActivationCode', '/frontend/', array('member_id' => $member_id, 'activation_code' => $data['code']));
     // 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;
 }
Пример #9
0
 protected function __trigger()
 {
     $api = new MailChimp($this->_driver->getKey());
     $result = new XMLElement("mailchimp");
     $email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
     $list = isset($_POST['list']) ? $_POST['list'] : $this->_driver->getList();
     // For post values
     $fields = $_POST;
     unset($fields['action']);
     // Valid email?
     if (!$email) {
         $error = new XMLElement('error', 'E-mail is invalid.');
         $error->setAttribute("handle", 'email');
         $result->appendChild($error);
         $result->setAttribute("result", "error");
         return $result;
     }
     // Default subscribe parameters
     $params = array('email' => array('email' => $email), 'id' => $list, 'merge_vars' => array(), 'email_type' => $fields['email_type'] ? $fields['email_type'] : 'html', 'double_optin' => $fields['double_optin'] ? $fields['double_optin'] == 'yes' : true, 'update_existing' => $fields['update_existing'] ? $fields['update_existing'] == 'yes' : false, 'replace_interests' => $fields['replace_interests'] ? $fields['replace_interests'] == 'yes' : true, 'send_welcome' => $fields['send_welcome'] ? $fields['send_welcome'] == 'yes' : false);
     // Are we merging?
     try {
         $mergeVars = $api->call('lists/merge-vars', array('id' => array($list)));
         $mergeVars = $mergeVars['success_count'] ? $mergeVars['data'][0]['merge_vars'] : array();
         if (count($mergeVars) > 1 && isset($fields['merge'])) {
             $merge = $fields['merge'];
             foreach ($merge as $key => $val) {
                 if (!empty($val)) {
                     $params['merge_vars'][$key] = $val;
                 } else {
                     unset($fields['merge'][$key]);
                 }
             }
         }
         // Subscribe the user
         $api_result = $api->call('lists/subscribe', $params);
         if ($api_result['status'] == 'error') {
             $result->setAttribute("result", "error");
             // try to match mergeVars with error
             if (count($mergeVars) > 1) {
                 // replace
                 foreach ($mergeVars as $var) {
                     $errorMessage = str_replace($var['tag'], $var['name'], $api_result['error'], $count);
                     if ($count == 1) {
                         $error = new XMLElement("message", $errorMessage);
                         break;
                     }
                 }
             }
             // no error message found with merge vars in it
             if ($error == null) {
                 $msg = General::sanitize($api_result['error']);
                 $error = new XMLElement("message", strlen($msg) > 0 ? $msg : 'Unknown error', array('code' => $api_result['code'], 'name' => $api_result['name']));
             }
             $result->appendChild($error);
         } else {
             if (isset($_REQUEST['redirect'])) {
                 redirect($_REQUEST['redirect']);
             } else {
                 $result->setAttribute("result", "success");
                 $result->appendChild(new XMLElement('message', __('Subscriber added to list successfully')));
             }
         }
         // Set the post values
         $post_values = new XMLElement("post-values");
         General::array_to_xml($post_values, $fields);
         $result->appendChild($post_values);
     } catch (Exception $ex) {
         $error = new XMLElement('error', General::wrapInCDATA($ex->getMessage()));
         $result->appendChild($error);
     }
     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;
 }
 protected function __trigger()
 {
     $result = new XMLElement(self::ROOTELEMENT);
     $fields = $_POST['fields'];
     $this->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);
     }
     // Set the section ID
     $result = $this->setMembersSection($result, $_REQUEST['members-section-id']);
     if ($result->getAttribute('result') === 'error') {
         $result->appendChild($post_values);
         return $result;
     }
     // If a member is logged in, return early with an error
     if ($this->driver->getMemberDriver()->isLoggedIn()) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('You cannot generate a recovery code while being logged in.'), array('message-id' => MemberEventMessages::ALREADY_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 = $this->driver->getMemberDriver()->setIdentityField($fields, false);
     if (!$identity instanceof Identity) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('No Identity field found.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
         $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('message', __('Member event encountered errors when processing.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
         $result->appendChild(new XMLElement($identity->get('element_name'), null, array('label' => $identity->get('label'), 'type' => 'missing', 'message-id' => EventMessages::FIELD_MISSING, 'message' => __('%s is a required field.', array($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('message', __('Member event encountered errors when processing.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS)));
         $result->appendChild(new XMLElement($identity->get('element_name'), null, extension_Members::$_errors[$identity->get('element_name')]));
         $result->appendChild($post_values);
         return $result;
     }
     // Find the Authentication fiedl
     $auth = $this->driver->getMemberDriver()->section->getField('authentication');
     $status = Field::__OK__;
     // Generate new password
     $newPassword = $auth->generatePassword();
     $entry = $this->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' => $auth->encodePassword($newPassword . $member_id)), $status);
     // Set the Entry password to be reset and the current timestamp
     $data['recovery-code'] = SHA1::hash($newPassword . $member_id);
     $data['reset'] = 'yes';
     $data['expires'] = DateTimeObj::get('Y-m-d H:i:s', time());
     // If the Member has entry data for the Authentication field, update it
     if (array_key_exists((int) $auth->get('id'), $entry_data)) {
         // 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);
     } else {
         $data['entry_id'] = $member_id;
         Symphony::Database()->insert($data, 'tbl_entries_data_' . $auth->get('id'));
     }
     /**
      * Fired just after a Member has requested a recovery code so they
      * can reset their password.
      *
      * @delegate MembersPostForgotPassword
      * @param string $context
      *  '/frontend/'
      * @param integer $member_id
      *  The Member ID of the member who just requested a recovery
      *  code.
      * @param string $recovery_code
      *  The recovery code that was generated for this Member
      */
     Symphony::ExtensionManager()->notifyMembers('MembersPostForgotPassword', '/frontend/', array('member_id' => $member_id, 'recovery_code' => $data['recovery-code']));
     // 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;
 }
Пример #12
0
    public function appendEventXML(array $context = null)
    {
        $result = new XMLElement('paypal');
        $cookie = new Cookie('paypal', TWO_WEEKS, __SYM_COOKIE_PATH__, null, true);
        $accessToken = $cookie->get('token');
        //$accessToken->getRefreshToken()
        // var_dump($accessToken);die;
        if (!empty($accessToken)) {
            $user = $cookie->get('user');
            $result->appendChild(General::array_to_xml($result, $user));
        } else {
            $baseUrl = SYMPHONY_URL . '/extension/paypal/consent';
            // ### Get User Consent URL
            // The clientId is stored in the bootstrap file
            //Get Authorization URL returns the redirect URL that could be used to get user's consent
            $redirectUrl = OpenIdSession::getAuthorizationUrl($baseUrl, array('openid', 'profile', 'address', 'email', 'phone', 'https://uri.paypal.com/services/paypalattributes', 'https://uri.paypal.com/services/expresscheckout'), null, null, null, $this->apiContext);
            $authend = $this->mode == 'sandbox' ? '"authend": "sandbox",' : '';
            $scriptInclude = '<span id="lippButton"></span>
					<script src="https://www.paypalobjects.com/js/external/api.js"></script>
					<script>
					paypal.use( ["login"], function(login) {
					  login.render ({
						"appid": "' . $this->clientId . '",' . $authend . '"scopes": "openid profile email address phone https://uri.paypal.com/services/paypalattributes https://uri.paypal.com/services/expresscheckout",
						"containerid": "lippButton",
						"locale": "en-us",
						"returnurl": "' . $baseUrl . '"
					  });
					});
					</script>';
            $result->appendChild(new XMLElement('authorize', $this->repairEntities($scriptInclude), array('url' => $this->repairEntities($redirectUrl))));
            // var_dump($redirectUrl);die;
        }
        $context['wrapper']->appendChild($result);
    }
Пример #13
0
 public function eventPreSaveFilter($context)
 {
     if ($context['fields'] === null && (RestEngine::getHTTPMethod() === 'put' || 'post')) {
         $parsedData = RestEngine::parseBodyContent();
         if ($context['entry_id'] === null && RestEngine::getHTTPMethod() === 'put') {
             $pageID = RestEngine::getPageID();
             $urlParams = $this::getPageURLParams();
             //use the page ID to look up the format and uid param settings
             $settings = RestResourceManager::getByPageID($pageID);
             if (array_key_exists($settings['uid_parameter'], $urlParams)) {
                 $entryIDValue = $urlParams[$settings['uid_parameter']];
                 if ($settings['field_id'] == 0) {
                     // 0 stands for using the Entry ID number directly so just
                     // check to see if that entry number exists in the correct section
                     $entrySection = EntryManager::fetchEntrySectionID($entryIDValue);
                     if ($entrySection == $settings['section_id']) {
                         //good to go
                         $entryID = $entryIDValue;
                     }
                 } else {
                     $fieldType = FieldManager::fetchFieldTypeFromID($settings['field_id']);
                     //TODO: Eventually add in a more robust field type management to distinguish between value and handle based fields if necessary, or do it by array searching?
                     if ($fieldType != 'memberemail') {
                         $query = "SELECT `entry_id` FROM `tbl_entries_data_" . $settings['field_id'] . "` WHERE `handle` = '" . $entryIDValue . "' LIMIT 1";
                     } else {
                         $query = "SELECT `entry_id` FROM `tbl_entries_data_" . $settings['field_id'] . "` WHERE `value` = '" . $entryIDValue . "' LIMIT 1";
                     }
                     $entryID = Symphony::Database()->fetchVar('entry_id', 0, $query);
                 }
                 if (is_null($entryID)) {
                     //no matching entry
                     $context['messages'][] = array('restengine:invalid-id', FALSE, __('The specified resource "%1$s" does not exist.', array($entryIDValue)));
                 } else {
                     //good to go
                     $context['entry_id'] = $entryID;
                 }
             } else {
                 $context['messages'][] = array('restengine:settings-error', FALSE, __('Invalid Rest Resource unique ID URL parameter: %1$s.', array($settings['uid_parameter'])));
                 //probably some kind of error needs returning here
             }
         }
         if (is_array($parsedData) && !empty($parsedData['data']) && $parsedData['errors'] === null) {
             //Create the post data cookie element.
             General::array_to_xml($context['post_values'], $parsedData, true);
             //TODO: check for field mapping
             //TODO: Do we need to error when message body contains properties that we don't have fields for in the assigned section?
             $context['fields'] = $parsedData['data'];
         }
     }
 }
Пример #14
0
 /**
  * Dumps sections to XMLElement.
  *
  * @param $sections
  *
  * @return XMLElement
  */
 private function buildOutput($sections)
 {
     $result = new XMLElement('sections');
     foreach ($sections as $handle => $section) {
         foreach ($section['entries'] as $entry) {
             $post_values = new XMLElement('post-values');
             General::array_to_xml($post_values, $entry['orig_fields'], true);
             $rep_post_values = new XMLElement('rep-post-values');
             General::array_to_xml($rep_post_values, $entry['fields'], true);
             $entry['result']->appendChild($post_values);
             $entry['result']->appendChild($rep_post_values);
             $entry['result']->appendChild($entry['res_entry']);
             $entry['result']->appendChild($entry['res_fields']);
             $entry['result']->appendChild($entry['res_filters']);
             $section['result']->appendChild($entry['result']);
         }
         $result->appendChild($section['result']);
     }
     return $result;
 }
 /**
  * Append element to datasource output
  */
 public function appendFormattedElement(&$wrapper, $data, $encode = false)
 {
     $node = new XMLElement($this->get('element_name'));
     $newsletter = EmailNewsletterManager::create($data['newsletter_id']);
     $properties = $newsletter->getStats();
     $node->setAttribute('newsletter-id', $data['newsletter_id']);
     $node->setAttribute('started-on', $properties['started_on']);
     $node->setAttribute('started-by', $properties['started_by']);
     $node->setAttribute('completed-on', $properties['completed_on']);
     $node->setAttribute('status', $properties['status']);
     $node->setAttribute('total', $properties['total']);
     $node->setAttribute('sent', $properties['sent']);
     $node->setAttribute('failed', $properties['failed']);
     $node->appendChild(new XMLElement('subject', $newsletter->getTemplate()->subject));
     // load configuration;
     // use saved (entry) config XML if available (i.e.: if the email newsletter has been sent);
     // fallback: the field's configuration XML
     // sender
     $sender = new XMLElement('sender');
     $about = is_object($newsletter->getSender()) ? $newsletter->getSender()->about() : array();
     General::array_to_xml($sender, $about);
     $sender_name = $about['name'];
     $sender_handle = is_object($newsletter->getSender()) ? $newsletter->getSender()->getHandle() : NULL;
     $el = new XMLElement('name');
     $el->setAttribute('id', $sender_handle);
     $el->setValue($sender_name);
     $sender->replaceChildAt(0, $el);
     $node->appendChild($sender);
     // recipients
     $recipients = new XMLElement('recipient-groups');
     foreach ($newsletter->getRecipientGroups() as $group) {
         $rgroup = new XMLElement('group');
         $about = (array) $group->about();
         General::array_to_xml($rgroup, $about);
         $rgroup_name = $about['name'];
         $rgroup_handle = $group->getHandle();
         $el = new XMLElement('name');
         $el->setAttribute('id', $rgroup_handle);
         $el->setValue($rgroup_name);
         $rgroup->replaceChildAt(0, $el);
         $rgroup_count = RecipientgroupManager::create($rgroup_handle)->getCount();
         $rgroup->setAttribute('count', $rgroup_count);
         $recipients->appendChild($rgroup);
     }
     $node->appendChild($recipients);
     // template
     $template = new XMLElement('template');
     $about = (array) $newsletter->getTemplate()->about;
     General::array_to_xml($template, $about);
     $template_name = $about['name'];
     $template_handle = EmailTemplateManager::getHandleFromName($template_name);
     $el = new XMLElement('name');
     $el->setAttribute('id', $template_handle);
     $el->setValue($template_name);
     $template->replaceChildAt(0, $el);
     $node->appendChild($template);
     $wrapper->appendChild($node);
 }
 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;
 }
 public function __viewPreview()
 {
     $this->setPageType('index');
     $this->setTitle(__("Symphony - Newsletter Recipient Groups Preview"));
     $sectionManager = new SectionManager($this);
     try {
         $source = RecipientgroupManager::create($this->_context[1]);
     } catch (Exception $e) {
         Administration::instance()->errorPageNotFound();
     }
     if ($_GET['pg']) {
         $source->dsParamSTARTPAGE = (int) $_GET['pg'];
     }
     $source->dsParamLIMIT = 17;
     $elements = $source->getSlice();
     $recipients = new XMLElement('recipients');
     General::array_to_xml($recipients, $source->about());
     General::array_to_xml($recipients, array('source' => is_numeric($section = $source->getSource()) ? $sectionManager->fetch($source->getSource())->get('handle') : 'system:' . $source->getSource()));
     General::array_to_xml($recipients, $elements);
     $context = new XMLElement('context');
     General::array_to_xml($context, $this->_context);
     $this->_XML->appendChild($context);
     $this->_XML->appendChild($recipients);
     $this->insertBreadcrumbs(array(Widget::Anchor(__('Email Newsletter Recipients'), SYMPHONY_URL . '/extension/email_newsletter_manager/recipientgroups/')));
     $about = $source->about();
     $this->appendSubheading($about['name'] . ' ' . __('preview'), array(Widget::Anchor(__('Edit %s group', array($layout)), SYMPHONY_URL . '/extension/email_newsletter_manager/recipientgroups/edit/' . $source->getHandle() . '/' . $layout, __('Edit %s group', array($layout)), 'button')));
 }
Пример #18
0
 /**
  * This function does the bulk of processing the Event, from running the delegates
  * to validating the data and eventually saving the data into Symphony. The result
  * of the Event is returned via the `$result` parameter.
  *
  * @param array $fields
  *  An array of $_POST data, to process and add/edit an entry.
  * @param XMLElement $result
  *  The XMLElement contains the result of the Event, it is passed by
  *  reference.
  * @param integer $position
  *  When the Expect Multiple filter is added, this event should expect
  *  to deal with adding (or editing) multiple entries at once.
  * @param integer $entry_id
  *  If this Event is editing an existing entry, that Entry ID will
  *  be passed to this function.
  * @throws Exception
  * @return XMLElement
  *  The result of the Event
  */
 public function __doit(array $fields = array(), XMLElement &$result, $position = null, $entry_id = null)
 {
     $post_values = new XMLElement('post-values');
     if (!is_array($this->eParamFILTERS)) {
         $this->eParamFILTERS = array();
     }
     // Check to see if the Section of this Event is valid.
     if (!($section = SectionManager::fetch($this->getSource()))) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('The Section, %s, could not be found.', array($this->getSource())), array('message-id' => EventMessages::SECTION_MISSING)));
         return false;
     }
     // Create the post data element
     if (!empty($fields)) {
         General::array_to_xml($post_values, $fields, true);
     }
     // If the EventPreSaveFilter fails, return early
     if ($this->processPreSaveFilters($result, $fields, $post_values, $entry_id) === false) {
         return false;
     }
     // If the `$entry_id` is provided, check to see if it exists.
     // @todo If this was moved above PreSaveFilters, we can pass the
     // Entry object to the delegate meaning extensions don't have to
     // do that step.
     if (isset($entry_id)) {
         $entry = EntryManager::fetch($entry_id);
         $entry = $entry[0];
         if (!is_object($entry)) {
             $result->setAttribute('result', 'error');
             $result->appendChild(new XMLElement('message', __('The Entry, %s, could not be found.', array($entry_id)), array('message-id' => EventMessages::ENTRY_MISSING)));
             return false;
         }
         // `$entry_id` wasn't provided, create a new Entry object.
     } else {
         $entry = EntryManager::create();
         $entry->set('section_id', $this->getSource());
     }
     // Validate the data. `$entry->checkPostData` loops over all fields calling
     // their `checkPostFieldData` function. If the return of the function is
     // `Entry::__ENTRY_FIELD_ERROR__` then abort the event and add the error
     // messages to the `$result`.
     if (Entry::__ENTRY_FIELD_ERROR__ == $entry->checkPostData($fields, $errors, $entry->get('id') ? true : false)) {
         $result = self::appendErrors($result, $fields, $errors, $post_values);
         return false;
         // If the data is good, process the data, almost ready to save it to the
         // Database. If processing fails, abort the event and display the errors
     } elseif (Entry::__ENTRY_OK__ != $entry->setDataFromPost($fields, $errors, false, $entry->get('id') ? true : false)) {
         $result = self::appendErrors($result, $fields, $errors, $post_values);
         return false;
         // Data is checked, data has been processed, by trying to save the
         // Entry caused an error to occur, so abort and return.
     } elseif ($entry->commit() === false) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('Unknown errors where encountered when saving.'), array('message-id' => EventMessages::ENTRY_UNKNOWN)));
         if (isset($post_values) && is_object($post_values)) {
             $result->appendChild($post_values);
         }
         return false;
         // Entry was created, add the good news to the return `$result`
     } else {
         $result->setAttributeArray(array('result' => 'success', 'type' => isset($entry_id) ? 'edited' : 'created', 'id' => $entry->get('id')));
         if (isset($entry_id)) {
             $result->appendChild(new XMLElement('message', __('Entry edited successfully.'), array('message-id' => EventMessages::ENTRY_EDITED_SUCCESS)));
         } else {
             $result->appendChild(new XMLElement('message', __('Entry created successfully.'), array('message-id' => EventMessages::ENTRY_CREATED_SUCCESS)));
         }
     }
     // PASSIVE FILTERS ONLY AT THIS STAGE. ENTRY HAS ALREADY BEEN CREATED.
     if (in_array('send-email', $this->eParamFILTERS) && !in_array('expect-multiple', $this->eParamFILTERS)) {
         $result = $this->processSendMailFilter($result, $_POST['send-email'], $fields, $section, $entry);
     }
     $result = $this->processPostSaveFilters($result, $fields, $entry);
     $result = $this->processFinalSaveFilters($result, $fields, $entry);
     if (isset($post_values) && is_object($post_values)) {
         $result->appendChild($post_values);
     }
     return true;
 }
Пример #19
0
 public function __doit($fields, &$result, $position = null, $entry_id = null)
 {
     $post_values = new XMLElement('post-values');
     $filter_results = array();
     if (!is_array($this->eParamFILTERS)) {
         $this->eParamFILTERS = array();
     }
     // Create the post data cookie element
     if (is_array($fields) && !empty($fields)) {
         General::array_to_xml($post_values, $fields, true);
     }
     /**
      * Prior to saving entry from the front-end. This delegate will
      * force the Event to terminate if it populates the `$filter_results`
      * array. All parameters are passed by reference.
      *
      * @delegate EventPreSaveFilter
      * @param string $context
      * '/frontend/'
      * @param array $fields
      * @param Event $this
      * @param array $messages
      *  An associative array of array's which contain 4 values,
      *  the name of the filter (string), the status (boolean),
      *  the message (string) an optionally an associative array
      *  of additional attributes to add to the filter element.
      * @param XMLElement $post_values
      * @param integer $entry_id
      *  If editing an entry, this parameter will be an integer,
      *  otherwise null.
      */
     Symphony::ExtensionManager()->notifyMembers('EventPreSaveFilter', '/frontend/', array('fields' => &$fields, 'event' => &$this, 'messages' => &$filter_results, 'post_values' => &$post_values, 'entry_id' => &$entry_id));
     if (is_array($filter_results) && !empty($filter_results)) {
         $can_proceed = true;
         foreach ($filter_results as $fr) {
             list($name, $status, $message, $attributes) = $fr;
             $result->appendChild($this->buildFilterElement($name, $status ? 'passed' : 'failed', $message, $attributes));
             if ($status === false) {
                 $can_proceed = false;
             }
         }
         if ($can_proceed !== true) {
             $result->appendChild($post_values);
             $result->setAttribute('result', 'error');
             $result->appendChild(new XMLElement('message', __('Entry encountered errors when saving.')));
             return false;
         }
     }
     include_once TOOLKIT . '/class.sectionmanager.php';
     include_once TOOLKIT . '/class.entrymanager.php';
     if (!($section = SectionManager::fetch($this->getSource()))) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('The Section, %s, could not be found.', array($this->getSource()))));
         return false;
     }
     if (isset($entry_id)) {
         $entry =& EntryManager::fetch($entry_id);
         $entry = $entry[0];
         if (!is_object($entry)) {
             $result->setAttribute('result', 'error');
             $result->appendChild(new XMLElement('message', __('The Entry, %s, could not be found.', array($entry_id))));
             return false;
         }
     } else {
         $entry =& EntryManager::create();
         $entry->set('section_id', $this->getSource());
     }
     if (__ENTRY_FIELD_ERROR__ == $entry->checkPostData($fields, $errors, $entry->get('id') ? true : false)) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('Entry encountered errors when saving.')));
         foreach ($errors as $field_id => $message) {
             $field = FieldManager::fetch($field_id);
             if (is_array($fields[$field->get('element_name')])) {
                 $type = array_reduce($fields[$field->get('element_name')], array('SectionEvent', '__reduceType'));
             } else {
                 $type = $fields[$field->get('element_name')] == '' ? 'missing' : 'invalid';
             }
             $result->appendChild(new XMLElement($field->get('element_name'), null, array('label' => General::sanitize($field->get('label')), 'type' => $type, 'message' => General::sanitize($message))));
         }
         if (isset($post_values) && is_object($post_values)) {
             $result->appendChild($post_values);
         }
         return false;
     } elseif (__ENTRY_OK__ != $entry->setDataFromPost($fields, $errors, false, $entry->get('id') ? true : false)) {
         $result->setAttribute('result', 'error');
         $result->appendChild(new XMLElement('message', __('Entry encountered errors when saving.')));
         foreach ($errors as $field_id => $message) {
             $field = FieldManager::fetch($field_id);
             $result->appendChild(new XMLElement($field->get('element_name'), null, array('label' => General::sanitize($field->get('label')), 'type' => 'invalid', 'message' => General::sanitize($message))));
         }
         if (isset($post_values) && is_object($post_values)) {
             $result->appendChild($post_values);
         }
         return false;
     } else {
         if (!$entry->commit()) {
             $result->setAttribute('result', 'error');
             $result->appendChild(new XMLElement('message', __('Unknown errors where encountered when saving.')));
             if (isset($post_values) && is_object($post_values)) {
                 $result->appendChild($post_values);
             }
             return false;
         }
         $result->setAttribute('id', $entry->get('id'));
     }
     // PASSIVE FILTERS ONLY AT THIS STAGE. ENTRY HAS ALREADY BEEN CREATED.
     if (in_array('send-email', $this->eParamFILTERS) && !in_array('expect-multiple', $this->eParamFILTERS)) {
         if (!function_exists('__sendEmailFindFormValue')) {
             function __sendEmailFindFormValue($needle, $haystack, $discard_field_name = true, $default = null, $collapse = true)
             {
                 if (preg_match('/^(fields\\[[^\\]]+\\],?)+$/i', $needle)) {
                     $parts = preg_split('/\\,/i', $needle, -1, PREG_SPLIT_NO_EMPTY);
                     $parts = array_map('trim', $parts);
                     $stack = array();
                     foreach ($parts as $p) {
                         $field = str_replace(array('fields[', ']'), '', $p);
                         $discard_field_name ? $stack[] = $haystack[$field] : ($stack[$field] = $haystack[$field]);
                     }
                     if (is_array($stack) && !empty($stack)) {
                         return $collapse ? implode(' ', $stack) : $stack;
                     } else {
                         $needle = null;
                     }
                 }
                 $needle = trim($needle);
                 if (empty($needle)) {
                     return $default;
                 }
                 return $needle;
             }
         }
         $fields = $_POST['send-email'];
         $db = Symphony::Database();
         $fields['recipient'] = __sendEmailFindFormValue($fields['recipient'], $_POST['fields'], true);
         $fields['recipient'] = preg_split('/\\,/i', $fields['recipient'], -1, PREG_SPLIT_NO_EMPTY);
         $fields['recipient'] = array_map('trim', $fields['recipient']);
         $fields['subject'] = __sendEmailFindFormValue($fields['subject'], $_POST['fields'], true, __('[Symphony] A new entry was created on %s', array(Symphony::Configuration()->get('sitename', 'general'))));
         $fields['body'] = __sendEmailFindFormValue($fields['body'], $_POST['fields'], false, null, false);
         $fields['sender-email'] = __sendEmailFindFormValue($fields['sender-email'], $_POST['fields'], true, null);
         $fields['sender-name'] = __sendEmailFindFormValue($fields['sender-name'], $_POST['fields'], true, null);
         $fields['reply-to-name'] = __sendEmailFindFormValue($fields['reply-to-name'], $_POST['fields'], true, null);
         $fields['reply-to-email'] = __sendEmailFindFormValue($fields['reply-to-email'], $_POST['fields'], true, null);
         $edit_link = SYMPHONY_URL . '/publish/' . $section->get('handle') . '/edit/' . $entry->get('id') . '/';
         $language = Symphony::Configuration()->get('lang', 'symphony');
         $template_path = Event::getNotificationTemplate($language);
         $body = sprintf(file_get_contents($template_path), $section->get('name'), $edit_link);
         if (is_array($fields['body'])) {
             foreach ($fields['body'] as $field_handle => $value) {
                 $body .= "// {$field_handle}" . PHP_EOL . $value . PHP_EOL . PHP_EOL;
             }
         } else {
             $body .= $fields['body'];
         }
         // Loop over all the recipients and attempt to send them an email
         // Errors will be appended to the Event XML
         $errors = array();
         foreach ($fields['recipient'] as $recipient) {
             $author = AuthorManager::fetchByUsername($recipient);
             if (empty($author)) {
                 $errors['recipient'][$recipient] = __('Recipient not found');
                 continue;
             }
             $email = Email::create();
             // Huib: Exceptions are also thrown in the settings functions, not only in the send function.
             // Those Exceptions should be caught too.
             try {
                 $email->recipients = array($author->get('first_name') => $author->get('email'));
                 if ($fields['sender-name'] != null) {
                     $email->sender_name = $fields['sender-name'];
                 }
                 if ($fields['sender-email'] != null) {
                     $email->sender_email_address = $fields['sender-email'];
                 }
                 if ($fields['reply-to-name'] != null) {
                     $email->reply_to_name = $fields['reply-to-name'];
                 }
                 if ($fields['reply-to-email'] != null) {
                     $email->reply_to_email_address = $fields['reply-to-email'];
                 }
                 $email->text_plain = str_replace('<!-- RECIPIENT NAME -->', $author->get('first_name'), $body);
                 $email->subject = $fields['subject'];
                 $email->send();
             } catch (EmailValidationException $e) {
                 $errors['address'][$author->get('email')] = $e->getMessage();
             } catch (EmailGatewayException $e) {
                 // The current error array does not permit custom tags.
                 // Therefore, it is impossible to set a "proper" error message.
                 // Will return the failed email address instead.
                 $errors['gateway'][$author->get('email')] = $e->getMessage();
             } catch (EmailException $e) {
                 // Because we don't want symphony to break because it can not send emails,
                 // all exceptions are logged silently.
                 // Any custom event can change this behaviour.
                 $errors['email'][$author->get('email')] = $e->getMessage();
             }
         }
         // If there were errors, output them to the event
         if (!empty($errors)) {
             $xml = $this->buildFilterElement('send-email', 'failed');
             foreach ($errors as $type => $messages) {
                 $xType = new XMLElement('error');
                 $xType->setAttribute('error-type', $type);
                 foreach ($messages as $recipient => $message) {
                     $xType->appendChild(new XMLElement('message', $message, array('recipient' => $recipient)));
                 }
                 $xml->appendChild($xType);
             }
             $result->appendChild($xml);
         } else {
             $result->appendChild($this->buildFilterElement('send-email', 'passed'));
         }
     }
     $filter_results = array();
     /**
      * After saving entry from the front-end. This delegate will not force
      * the Events to terminate if it populates the `$filter_results` array.
      * Provided with references to this object, the `$_POST` data and also
      * the error array
      *
      * @delegate EventPostSaveFilter
      * @param string $context
      * '/frontend/'
      * @param integer $entry_id
      * @param array $fields
      * @param Entry $entry
      * @param Event $this
      * @param array $messages
      *  An associative array of array's which contain 4 values,
      *  the name of the filter (string), the status (boolean),
      *  the message (string) an optionally an associative array
      *  of additional attributes to add to the filter element.
      */
     Symphony::ExtensionManager()->notifyMembers('EventPostSaveFilter', '/frontend/', array('entry_id' => $entry->get('id'), 'fields' => $fields, 'entry' => $entry, 'event' => &$this, 'messages' => &$filter_results));
     if (is_array($filter_results) && !empty($filter_results)) {
         foreach ($filter_results as $fr) {
             list($name, $status, $message, $attributes) = $fr;
             $result->appendChild($this->buildFilterElement($name, $status ? 'passed' : 'failed', $message, $attributes));
         }
     }
     $filter_errors = array();
     /**
      * This delegate that lets extensions know the final status of the
      * current Event. It is triggered when everything has processed correctly.
      * The `$messages` array contains the results of the previous filters that
      * have executed, and the `$errors` array contains any errors that have
      * occurred as a result of this delegate. These errors cannot stop the
      * processing of the Event, as that has already been done.
      *
      *
      * @delegate EventFinalSaveFilter
      * @param string $context
      * '/frontend/'
      * @param array $fields
      * @param Event $this
      * @param array $messages
      *  An associative array of array's which contain 4 values,
      *  the name of the filter (string), the status (boolean),
      *  the message (string) an optionally an associative array
      *  of additional attributes to add to the filter element.
      * @param array $errors
      *  An associative array of array's which contain 4 values,
      *  the name of the filter (string), the status (boolean),
      *  the message (string) an optionally an associative array
      *  of additional attributes to add to the filter element.
      * @param Entry $entry
      */
     Symphony::ExtensionManager()->notifyMembers('EventFinalSaveFilter', '/frontend/', array('fields' => $fields, 'event' => $this, 'messages' => $filter_results, 'errors' => &$filter_errors, 'entry' => $entry));
     if (is_array($filter_errors) && !empty($filter_errors)) {
         foreach ($filter_errors as $fr) {
             list($name, $status, $message, $attributes) = $fr;
             $result->appendChild($this->buildFilterElement($name, $status ? 'passed' : 'failed', $message, $attributes));
         }
     }
     $result->setAttributeArray(array('result' => 'success', 'type' => isset($entry_id) ? 'edited' : 'created'));
     $result->appendChild(new XMLElement('message', isset($entry_id) ? __('Entry edited successfully.') : __('Entry created successfully.')));
     if (isset($post_values) && is_object($post_values)) {
         $result->appendChild($post_values);
     }
     return true;
 }
 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;
 }