/** * Prints out a piece of a template * * @param string $template The name of the template to print * @param string $piece The piece of the template to print * @param array $data The data to replace the variables with * @return void */ private static function printPiece($template, $name, $data) { if (!isset(self::$templates[$template]['pieces'][$name])) { throw new fProgrammerException('The template piece, %s, was not specified when defining the %s template', $name, $template); } $piece = self::$templates[$template]['pieces'][$name]; preg_match_all('#\\{\\{ (\\w+)((?:\\|\\w+)+)? \\}\\}#', $piece, $matches, PREG_SET_ORDER); foreach ($matches as $match) { $variable = $match[1]; $value = !isset($data[$variable]) ? NULL : $data[$variable]; if (isset($match[2])) { $filters = array_slice(explode('|', $match[2]), 1); foreach ($filters as $filter) { if (!in_array($filter, self::$filters)) { throw new fProgrammerException('The filter specified, %1$s, is invalid. Must be one of: %2$s.', $filter, join(', ', self::$filters)); } if (!strlen($value)) { continue; } if ($filter == 'inflect') { $value = fGrammar::inflectOnQuantity($data['total_records'], $value); } elseif ($filter == 'lower') { $value = fUTF8::lower($value); } elseif ($filter == 'url_encode') { $value = urlencode($value); } elseif ($filter == 'humanize') { $value = fGrammar::humanize($value); } } } $piece = preg_replace('#' . preg_quote($match[0], '#') . '#', fHTML::encode($value), $piece, 1); } echo $piece; }
/** * Validates values against unique constraints * * @param fSchema $schema The schema object for the object * @param fActiveRecord $object The instance of the class to check * @param array &$values The values to check * @param array &$old_values The old values for the record * @return array An aray of error messages for the unique constraints */ private static function checkUniqueConstraints($schema, $object, &$values, &$old_values) { $class = get_class($object); $table = fORM::tablize($class); $db = fORMDatabase::retrieve($class, 'read'); $key_info = $schema->getKeys($table); $pk_columns = $key_info['primary']; $unique_keys = $key_info['unique']; $messages = array(); foreach ($unique_keys as $unique_columns) { settype($unique_columns, 'array'); // NULL values are unique $found_not_null = FALSE; foreach ($unique_columns as $unique_column) { if ($values[$unique_column] !== NULL) { $found_not_null = TRUE; } } if (!$found_not_null) { continue; } $params = array("SELECT %r FROM %r WHERE ", $key_info['primary'], $table); $column_info = $schema->getColumnInfo($table); $conditions = array(); foreach ($unique_columns as $unique_column) { $value = $values[$unique_column]; // This makes sure the query performs the way an insert will if ($value === NULL && $column_info[$unique_column]['not_null'] && $column_info[$unique_column]['default'] !== NULL) { $value = $column_info[$unique_column]['default']; } if (self::isCaseInsensitive($class, $unique_column) && self::stringlike($value)) { $condition = fORMDatabase::makeCondition($schema, $table, $unique_column, '=', $value); $conditions[] = str_replace('%r', 'LOWER(%r)', $condition); $params[] = $table . '.' . $unique_column; $params[] = fUTF8::lower($value); } else { $conditions[] = fORMDatabase::makeCondition($schema, $table, $unique_column, '=', $value); $params[] = $table . '.' . $unique_column; $params[] = $value; } } $params[0] .= join(' AND ', $conditions); if ($object->exists()) { foreach ($pk_columns as $pk_column) { $value = fActiveRecord::retrieveOld($old_values, $pk_column, $values[$pk_column]); $params[0] .= ' AND ' . fORMDatabase::makeCondition($schema, $table, $pk_column, '<>', $value); $params[] = $table . '.' . $pk_column; $params[] = $value; } } try { $result = call_user_func_array($db->translatedQuery, $params); $result->tossIfNoRows(); // If an exception was not throw, we have existing values $column_names = array(); foreach ($unique_columns as $unique_column) { $column_names[] = fORM::getColumnName($class, $unique_column); } if (sizeof($column_names) == 1) { $messages[join('', $unique_columns)] = self::compose('%sThe value specified must be unique, however it already exists', fValidationException::formatField(join('', $column_names))); } else { $messages[join(',', $unique_columns)] = self::compose('%sThe values specified must be a unique combination, however the specified combination already exists', fValidationException::formatField(join(', ', $column_names))); } } catch (fNoRowsException $e) { } } return $messages; }
/** * Allows adding a custom header to the email * * If the method is called multiple times with the same name, the last * value will be used. * * Please note that this class will properly format the header, including * adding the `:` between the name and value and wrapping values that are * too long for a single line. * * @param string $name The name of the header * @param string $value The value of the header * @param array :$headers An associative array of `{name} => {value}` * @return fEmail The email object, to allow for method chaining */ public function addCustomHeader($name, $value = NULL) { if ($value === NULL && is_array($name)) { foreach ($name as $key => $value) { $this->addCustomHeader($key, $value); } return; } $lower_name = fUTF8::lower($name); $this->custom_headers[$lower_name] = array($name, $value); return $this; }
/** * Validates values against unique constraints * * @param fActiveRecord $object The instance of the class to check * @param array &$values The values to check * @param array &$old_values The old values for the record * @return string An error message for the unique constraints */ private static function checkUniqueConstraints($object, &$values, &$old_values) { $class = get_class($object); $table = fORM::tablize($class); $key_info = fORMSchema::retrieve()->getKeys($table); $primary_keys = $key_info['primary']; $unique_keys = $key_info['unique']; foreach ($unique_keys as $unique_columns) { settype($unique_columns, 'array'); // NULL values are unique $found_not_null = FALSE; foreach ($unique_columns as $unique_column) { if ($values[$unique_column] !== NULL) { $found_not_null = TRUE; } } if (!$found_not_null) { continue; } $sql = "SELECT " . join(', ', $key_info['primary']) . " FROM " . $table . " WHERE "; $first = TRUE; foreach ($unique_columns as $unique_column) { if ($first) { $first = FALSE; } else { $sql .= " AND "; } $value = $values[$unique_column]; if (self::isCaseInsensitive($class, $unique_column) && self::stringlike($value)) { $sql .= 'LOWER(' . $unique_column . ')' . fORMDatabase::escapeBySchema($table, $unique_column, fUTF8::lower($value), '='); } else { $sql .= $unique_column . fORMDatabase::escapeBySchema($table, $unique_column, $value, '='); } } if ($object->exists()) { foreach ($primary_keys as $primary_key) { $value = fActiveRecord::retrieveOld($old_values, $primary_key, $values[$primary_key]); $sql .= ' AND ' . $primary_key . fORMDatabase::escapeBySchema($table, $primary_key, $value, '<>'); } } try { $result = fORMDatabase::retrieve()->translatedQuery($sql); $result->tossIfNoRows(); // If an exception was not throw, we have existing values $column_names = array(); foreach ($unique_columns as $unique_column) { $column_names[] = fORM::getColumnName($class, $unique_column); } if (sizeof($column_names) == 1) { return self::compose('%sThe value specified must be unique, however it already exists', fValidationException::formatField(join('', $column_names))); } else { return self::compose('%sThe values specified must be a unique combination, however the specified combination already exists', fValidationException::formatField(join(', ', $column_names))); } } catch (fNoRowsException $e) { } } }