/** * The router is set to /action and this segment of the url is overloaded * so that /someRecipient is also valid. This __call method is invoked * whenever this segment of the url is not a defined action and in these * cases, the $actionMethod may be a valid recipient. These sre trapped * here and, if valid, the request is re-dispatched to the index action to * which we pass a recipient parameter. * If a valid recipient is not found then execution is passed to the parent * __call method. * * @param string $actionMethod Url segment. * @param array $args Request arguments. * * @return null */ public function __call($actionMethod, $args) { $logger = ESAPI::getAuditor('IndexController'); // I do not anticipate this happening often... if (!is_string($actionMethod)) { return parent::__call($actionMethod, $args); } // If there's less than two recipients defined, we don't need to trap // usernames. ignore them. if ($this->_recipientsConfig->count() < 2) { return parent::__call($actionMethod, $args); } // Strip the trailing 'Action' from the method name. $method = null; $detectedCharacterEncoding = mb_detect_encoding($actionMethod); $len = mb_strlen($actionMethod, $detectedCharacterEncoding); if (mb_substr($actionMethod, $len - 6, 6, $detectedCharacterEncoding) == 'Action') { $method = mb_substr($actionMethod, 0, $len - 6, $detectedCharacterEncoding); } else { $method = $actionMethod; } // Validate the possible recipient and, if valid, add a 'recipient' // request param and continue on to the indexAction of this controller. $recipientValidator = new Custom_Validate_ValidRecipient($this->_recipientsConfig); if ($recipientValidator->isValid($method)) { $this->_request->setActionName('index'); $this->_request->setParams(array('recipient' => $method, 'action' => 'index')); $this->_request->setDispatched(false); return; } return parent::__call($actionMethod, $args); }
/** * Generates an option in the recipient select element for each recipient * display name defined in the recpients Zend_Config object. * If there are less than two recipients the the select element will be * deleted from the form. * * @return null */ private function _setRecipientSelector() { // If the list of recipients contains less than two recipients then we // remove the unecessary select element from the form. if (sizeof($this->_recipients) < 2 && $this->recipientMap instanceof Zend_Form_Element) { $this->removeElement('recipientMap'); $this->_conditionallyUseCaptcha = false; return; } // If the url contained a valid recipient name then that name will be // the selected option in the form. The request parameter 'recipient' // will be set and it should exactly match a defined recipient. // Note that the user may have set the recipient parameter so validation // of that parameter must be done here. $fc = Zend_Controller_Front::getInstance(); $validRecipient = $fc->getRequest()->getParam('recipient', null); if ($validRecipient !== null) { $recipientValidator = new Custom_Validate_ValidRecipient($this->_recipients); if ($recipientValidator->isValid($validRecipient) === false) { $validRecipient = null; } } if ($validRecipient === null) { $this->_conditionallyUseCaptcha = false; } // Before we generate an option for each valid recipient, get any // existing options - these will be dummy options (there should ideally // be just one) that are not valid recipients but allow us to generate // a select element that does not have a pre-selected option and fails // to validate if one of the dummy values is selected so that the user // is reminded to select a recipient. $dummy = $this->recipientMap->getMultiOptions(); // Now add a multi option for each recipient. If validRecipient is set // then mark the corresponding element as the selected one (setValue()). $validRecipientLower = null; if ($validRecipient !== null) { $charEnc = mb_detect_encoding($validRecipient); $validRecipientLower = mb_strtolower($validRecipient, $charEnc); } // Get a whitespace removal filter $whitespace = new Zend_Filter_PregReplace(array('match' => '/ /', 'replace' => '')); foreach ($this->_recipients as $_ => $cfg) { foreach ($cfg as $key => $displayName) { if ($key !== 'display') { continue; } $this->recipientMap->addMultiOption($displayName, $displayName); if ($validRecipientLower !== null) { $charEnc = mb_detect_encoding($displayName); $displayNameL = mb_strtolower($displayName, $charEnc); $displayNameS = $whitespace->filter($displayNameL); if ($validRecipientLower === $displayNameL || $validRecipientLower === $displayNameS) { $this->recipientMap->setValue($displayName); } } } } $o = array('recipients' => $this->_recipients, 'dummy' => $dummy); $this->recipientMap->addValidator('validRecipient', false, $o); return; }