/** * Validate the emptiness of a number */ protected function _validateNumber($value, $column) { // Not much to check, since 0 is falsy but also a valid integer value. if (is_null($value)) { throw new Garp_Model_Validator_Exception(sprintf(__('%s is a required field'), __(Garp_Util_String::underscoredToReadable($column)))); } }
protected function _getAuthorName() { $name = $this->_exec_cmd("git config user.name"); if (!$name) { return ''; } $name = trim($name); $name = explode(' ', $name); return strtolower(Garp_Util_String::toDashed($name[0])); }
/** * Validate wether the given columns are long enough * * @param array $data The data to validate * @param Garp_Model_Db $model * @param bool $onlyIfAvailable Wether to skip validation on fields that are not in the array * @return void * @throws Garp_Model_Validator_Exception */ public function validate(array $data, Garp_Model_Db $model, $onlyIfAvailable = true) { $theFields = $this->_fields; $applicableFields = array_keys(array_get_subset($data, array_keys($theFields))); $tooShortFields = array_filter($applicableFields, function ($field) use($theFields, $data) { return !is_null($data[$field]) && strlen($data[$field]) < $theFields[$field]; }); if (count($tooShortFields)) { $first = current($tooShortFields); throw new Garp_Model_Validator_Exception(Garp_Util_String::interpolate(__(self::ERROR_MESSAGE), array('value' => $first, 'min' => $theFields[$first]))); } }
public function testShouldSendEmail() { if (!$this->_testsEnabled) { return; } $pwless = new Garp_Auth_Adapter_Passwordless(); $pwless->requestToken(array('email' => self::TEST_EMAIL)); $userModel = new Model_User(); $theUser = $userModel->fetchRow(); $authModel = new Model_AuthPasswordless(); $authRecord = $authModel->fetchRow(); $tokenUrl = new Garp_Util_FullUrl(array(array('method' => 'passwordless'), 'auth_submit')) . '?uid=' . $theUser->id . '&token=' . $authRecord->token; $storedMessage = file_get_contents(GARP_APPLICATION_PATH . '/../tests/tmp/' . self::TEST_EMAIL . '.tmp'); $expectedMessage = Garp_Util_String::interpolate($this->_getMockEmailMessage(), array('LOGIN_URL' => $tokenUrl)); // Pass thru actual Mime part, otherwise the two wil never be the same $mp = new Zend_Mime_Part($expectedMessage); $mp->encoding = Zend_Mime::ENCODING_QUOTEDPRINTABLE; $mp->type = Zend_Mime::TYPE_TEXT; $mp->disposition = Zend_Mime::DISPOSITION_INLINE; $mp->charset = 'iso-8859-1'; // Just check for the token url. Message is encoded so checking for entire message to be // correct is overly complex (and not the responsibility of this unit test). $this->assertTrue(strpos($storedMessage, $mp->getContent("\r\n")) !== false); }
protected function _validateSyncArguments(array $args) { $valid = false; $argCount = count($args); if (!array_key_exists(0, $args)) { Garp_Cli::errorOut("No source environment provided."); } elseif (!array_key_exists(1, $args)) { Garp_Cli::errorOut("No target environment provided."); } elseif (!in_array($args[0], $this->_environments)) { Garp_Cli::errorOut("Source environment is invalid. Try: " . Garp_Util_String::humanList($this->_environments, null, 'or') . '.'); } elseif (!in_array($args[1], $this->_environments)) { Garp_Cli::errorOut("Target environment is invalid. Try: " . Garp_Util_String::humanList($this->_environments, null, 'or') . '.'); } else { $valid = true; } if (!$valid) { $this->help(); return false; } return true; }
protected function _interpolateEmailBody($body, $userId, $token) { return Garp_Util_String::interpolate($body, array('LOGIN_URL' => $this->_getLoginUrl($userId, $token))); }
public function testFuzzyMatcher() { // test match $this->assertTrue(Garp_Util_String::fuzzyMatch('munchkin', 'm19302390iu23983n2893ch28302jdk2399i2903910hfwen')); // test non match $this->assertFalse(Garp_Util_String::fuzzyMatch('munchkin', 'm19302390iu23983n2893ch28302jdk2399i2903910hfwe')); // another non match $this->assertFalse(Garp_Util_String::fuzzyMatch('rugmuncher', 'm19302390iu23983n2893ch28302jdk2399i2903910hfwe')); // check with funky string $this->assertTrue(Garp_Util_String::fuzzyMatch('(╯°□°)╯︵ ┻━┻', '(╯aejfekn°□°klewmwlkfm192)╯#(#)(#︵dsjkfwjkdn ┻━┻')); // don't match when case-sensitive $this->assertFalse(Garp_Util_String::fuzzyMatch('munchkin', 'm19302390iU23983n2893ch28302jdk2399i2903910hfwen', false)); }
/** * Send validation email to the user * @param Garp_Db_Table_Row $user The user * @param String $code The validation code * @param String $updateOrInsert Wether this was caused by an insert or an update * @return Boolean */ public function sendEmailValidationEmail(Garp_Db_Table_Row $user, $code, $updateOrInsert = 'insert') { $authVars = Garp_Auth::getInstance()->getConfigValues('validateemail'); // Render the email message $activationUrl = '/g/auth/validateemail/c/' . $code . '/e/' . md5($user->email) . '/'; if (!empty($authVars['email_partial'])) { $bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap'); $view = $bootstrap->getResource('View'); $emailMessage = $view->partial($authVars['email_partial'], 'default', array('user' => $user, 'activationUrl' => $activationUrl, 'updateOrInsert' => $updateOrInsert)); $messageParam = 'htmlMessage'; } else { $snippetId = 'validate email '; $snippetId .= $updateOrInsert == 'insert' ? 'new user' : 'existing user'; $snippetId .= ' email'; $emailMessage = __($snippetId); $emailMessage = Garp_Util_String::interpolate($emailMessage, array('USERNAME' => (string) new Garp_Util_FullName($user), 'ACTIVATION_URL' => (string) new Garp_Util_FullUrl($activationUrl))); $messageParam = 'message'; } $mailer = new Garp_Mailer(); return $mailer->send(array('to' => $user->email, 'subject' => __($authVars['email_subject']), $messageParam => $emailMessage)); }
protected function _extractPeopleProp(SimpleXmlElement $response, $propName, $propChildName) { if (property_exists($response, $propName) && property_exists($response->{$propName}, $propChildName) && count($response->{$propName}->{$propChildName})) { $people = array(); foreach ($response->{$propName}->{$propChildName} as $person) { if (property_exists($person, 'name') && !empty($person->name)) { $people[] = $person->name; } } if ($people) { return Garp_Util_String::humanList($people, null, 'en'); } } }
/** * Fetch results from a model * * @param array $options Various fetching options (e.g. limit, sorting, etc.) * @return array */ public function fetch(array $options = null) { try { $this->_checkAcl('fetch'); } catch (Garp_Auth_Exception $e) { $this->_checkAcl('fetch_own'); } if ($this->_model instanceof Garp_Model_Db) { $options = $options instanceof Garp_Util_Configuration ? $options : new Garp_Util_Configuration($options); $options->setDefault('sort', array())->setDefault('start', null)->setDefault('limit', null)->setDefault('fields', null)->setDefault('query', false)->setDefault('group', array())->setDefault('rule', null)->setDefault('bindingModel', null)->setDefault('bidirectional', false)->setDefault('filterForeignKeys', false); $options['sort'] = (array) $options['sort']; $options['fields'] = (array) $options['fields']; $tableName = $this->_getTableName($this->_model); $options = (array) $options; $modelInfo = $this->_model->info(); $referenceMap = $modelInfo['referenceMap']; // SELECT // ============================================================ $select = $this->_model->select(); $select->setIntegrityCheck(false); // FILTER WHERES AND JOINS // ============================================================ $related = array(); if ($options['query'] && !empty($options['query'])) { /** * Check for other model names in the conditions. * These are indicated by a dot (".") in the name. * If available, add these models as joins to the Select object. * The format is <related-model-name>.<primary-key> => <value>. */ foreach ($options['query'] as $column => $value) { if (strpos($column, '.') !== false) { $related[$column] = $value; unset($options['query'][$column]); } } } // FROM // ============================================================ if ($options['fields']) { $fields = $options['fields']; } elseif (count($related)) { // When using a join filter (used for the relationpanel), it's more performant to // specify only a model's list fields, otherwise the query can get pretty heavy for // tables with 100.000+ records. $primary = array_values($this->_model->info(Zend_Db_Table_Abstract::PRIMARY)); $fields = array_merge($this->_model->getListFields(), $primary); } else { $fields = Zend_Db_Table_Select::SQL_WILDCARD; } // If filterForeignKeys is true, filter out the foreign keys if ($options['filterForeignKeys']) { $fields = $this->_filterForeignKeyColumns($fields, $referenceMap); } $select->from($tableName, $fields); // JOIN // ============================================================ if (count($related)) { $this->_addJoinClause($select, $related, $options['rule'], $options['bindingModel'], $options['bidirectional']); } // WHERE // Add WHERE clause if there still remains something after // filtering. // ============================================================ if ($options['query']) { $select->where($this->_createWhereClause($options['query'])); } // GROUP // ============================================================ $select->group($options['group']); // ORDER // ============================================================ // Prefix native columns with the table name (e.g. "id" becomes // "Thing.id") // Note that we create a mock table object based on the joint view // to collect column info. // This should be more accurate than reading that info from the table. $mockTable = new Zend_Db_Table(array(Zend_Db_Table_Abstract::NAME => $tableName, Zend_Db_Table_Abstract::PRIMARY => $this->_model->info(Zend_Db_Table_Abstract::PRIMARY))); $nativeColumns = $mockTable->info(Zend_Db_Table_Abstract::COLS); $select->order(array_map(function ($s) use($tableName, $nativeColumns) { $nativeColTest = preg_replace('/(ASC|DESC)$/', '', $s); $nativeColTest = trim($nativeColTest); if (in_array($nativeColTest, $nativeColumns) && strpos($s, '.') === false) { $s = $tableName . '.' . $s; } return $s; }, $options['sort'])); // LIMIT // ============================================================ // Do not limit when a COUNT(*) is performed, this skews results. $isCountQuery = count($fields) == 1 && !empty($fields[0]) && strtolower($fields[0]) == 'count(*)'; if (!$isCountQuery) { $select->limit($options['limit'], $options['start']); } $results = $this->_model->fetchAll($select)->toArray(); } else { $results = $this->_model->fetchAll(); } foreach ($results as &$result) { foreach ($result as $column => $value) { if (strpos($column, '.') !== false) { $keyParts = explode('.', $column, 2); $newKey = $keyParts[1]; $relModelKey = Garp_Util_String::strReplaceOnce($this->_model->getNameWithoutNamespace(), '', $keyParts[0]); $result['relationMetadata'][$relModelKey][$newKey] = $value; unset($result[$column]); } } } return $results; }
protected function _getForgotPasswordSnippet($user, $activationUrl) { $authVars = $this->getConfigValues('forgotpassword'); $snippet_column = !empty($authVars['email_snippet_column']) ? $authVars['email_snippet_column'] : 'text'; $snippet_identifier = !empty($authVars['email_snippet_identifier']) ? $authVars['email_snippet_identifier'] : 'forgot password email'; $snippetModel = $this->_getSnippetModel(); $emailSnippet = $snippetModel->fetchByIdentifier($snippet_identifier); $emailMessage = $emailSnippet->{$snippet_column}; return Garp_Util_String::interpolate($emailMessage, array('USERNAME' => (string) new Garp_Util_FullName($user), 'ACTIVATION_URL' => (string) new Garp_Util_FullUrl($activationUrl))); }
/** * Store targetUrl in session. After login the user is redirected * back to this url. * @return Void */ protected function _storeTargetUrl() { $request = $this->getRequest(); // Only store targetUrl when method = GET. A redirect to a POST request is useless. if (!$request->isGet()) { return; } // Allow ?targetUrl=/path/to/elsewhere on any URL if (!($targetUrl = $request->getParam('targetUrl'))) { $targetUrl = $request->getRequestUri(); $baseUrl = $request->getBaseUrl(); /** * Remove the baseUrl from the targetUrl. This is neccessary * when Garp is installed in a subfolder. */ $targetUrl = Garp_Util_String::strReplaceOnce($baseUrl, '', $targetUrl); } if ($targetUrl !== '/favicon.ico' && !$request->isXmlHttpRequest()) { $store = Garp_Auth::getInstance()->getStore(); $store->targetUrl = $targetUrl; } }
protected function _renderJoinForLocale($locale) { $modelId = $this->getModel()->id; $tableName = $this->getTableName(); $translatedTable = $tableName . self::TRANSLATED_TABLE_POSTFIX; $aliasForLocale = $tableName . '_' . $locale; $parentColumn = Garp_Util_String::camelcasedToUnderscored($modelId) . '_id'; $sql = "LEFT OUTER JOIN `{$translatedTable}` `{$aliasForLocale}` ON " . "`{$aliasForLocale}`.`{$parentColumn}` = `{$tableName}`.id AND `{$aliasForLocale}`.lang = '{$locale}' "; return $sql; }
/** * Populate record with new data * * @param array $output * @param string $key * @param string $value * @return void */ protected function _populateOutput(array &$output, $key, $value) { if (strpos($key, '.') === false) { $output[$key] = $value; return; } $array = Garp_Util_String::toArray($key, '.', $value); $output += $array; }
/** * Process the login request. @see G_AuthController::loginAction as to * why this is separate. * * @return void */ public function processAction() { // allow callers to set a targetUrl via the request if ($targetUrl = $this->_getSubmittedTargetUrl()) { Garp_Auth::getInstance()->getStore()->targetUrl = $targetUrl; } // never cache the process request $this->_helper->cache->setNoCacheHeaders($this->getResponse()); // This action does not render a view, it only redirects elsewhere. $this->_helper->viewRenderer->setNoRender(true); $method = $this->getRequest()->getParam('method') ?: 'db'; $adapter = Garp_Auth_Factory::getAdapter($method); $authVars = Garp_Auth::getInstance()->getConfigValues(); $postData = $this->getRequest()->getPost(); // Before login hook. $this->_beforeLogin($authVars, $adapter, $postData); /** * Params can come from GET or POST. * The implementing adapter should decide which to use, * using the current request to fetch params. */ if (!($userData = $adapter->authenticate($this->getRequest(), $this->getResponse()))) { $this->_respondToFaultyProcess($adapter); return; } $this->_helper->viewRenderer->setNoRender(true); // Check if adapter issued a redirect (as is the case with oAuth for instance) if ($this->getResponse()->isRedirect()) { return; } if ($userData instanceof Garp_Db_Table_Row) { $userData = $userData->toArray(); } // Save user data in a store. Garp_Auth::getInstance()->store($userData, $method); // Store User role in a cookie, so that we can use it with Javascript. if (!Garp_Auth::getInstance()->getStore() instanceof Garp_Store_Cookie) { $this->_storeRoleInCookie(); } // Determine targetUrl. // This is the URL the user was trying to access before logging in, or a default URL. $router = Zend_Controller_Front::getInstance()->getRouter(); if (!empty($authVars['login']['successRoute'])) { $targetUrl = $router->assemble(array(), $authVars['login']['successRoute']); } elseif (!empty($authVars['login']['successUrl'])) { $targetUrl = $authVars['login']['successUrl']; } else { $targetUrl = '/'; } $store = Garp_Auth::getInstance()->getStore(); if ($store->targetUrl) { $targetUrl = $store->targetUrl; unset($store->targetUrl); } // After login hook. $this->_afterLogin($userData, $targetUrl); // Set a Flash message welcoming the user. $flashMessenger = $this->_helper->getHelper('FlashMessenger'); $fullName = new Garp_Util_FullName($userData); $successMsg = __($authVars['login']['successMessage']); if (strpos($successMsg, '%s') !== false) { $successMsg = sprintf($successMsg, $fullName); } elseif (strpos('%USERNAME%', $successMsg) !== false) { $successMsg = Garp_Util_String::interpolate($successMsg, array('USERNAME' => $fullName)); } $flashMessenger->addMessage($successMsg); $this->_redirect($targetUrl); }
/** * Generate a slug from a base string * @param String $base String to base the slug on. * @return String $slug The generated slug */ public function generateSlug($base) { return strtolower(Garp_Util_String::toDashed($base)); }
/** * Returns the database name for this environment, to be used as the index name for Elasticsearch. */ protected function _getDefaultIndex() { $config = Zend_Registry::get('config'); if (!isset($config->app->name)) { throw new Exception(self::ERROR_NO_APP_NAME_CONFIGURED); } $appName = str_replace(' ', '', $config->app->name); $appName = Garp_Util_String::camelcasedToDashed($appName); if (!$appName) { throw new Exception(self::ERROR_APP_NAME_EMPTY); } $indexName = $appName . '-' . APPLICATION_ENV; return $indexName; }
public function getName() { return Garp_Util_String::toDashed(Zend_Registry::get('config')->app->name) . '-' . $this->_version; }