From b8a713a02f5d524943c41c089ca755a2a51f0fff Mon Sep 17 00:00:00 2001 From: Maarten Winter Date: Mon, 18 Jun 2012 17:56:33 +0200 Subject: [PATCH] Fixing bug in MySQL migrate syntax Fixing bug in MySQL regexp support Fixing typo in generic view "Form" Adding support for JSON data post to Alloy\Request --- alloy/Plugin/Spot/lib/Spot/Adapter/Mysql.php | 22 +- .../Spot/lib/Spot/Adapter/PDO/Abstract.php | 230 +++++++++--------- alloy/lib/Alloy/Request.php | 184 ++++++++------ alloy/lib/Alloy/View/Generic/Form.php | 48 ++-- 4 files changed, 256 insertions(+), 228 deletions(-) diff --git a/alloy/Plugin/Spot/lib/Spot/Adapter/Mysql.php b/alloy/Plugin/Spot/lib/Spot/Adapter/Mysql.php index 309b4b2..8b937ea 100644 --- a/alloy/Plugin/Spot/lib/Spot/Adapter/Mysql.php +++ b/alloy/Plugin/Spot/lib/Spot/Adapter/Mysql.php @@ -128,10 +128,16 @@ public function migrateSyntaxFieldCreate($fieldName, array $fieldInfo) if(!isset($this->_fieldTypeMap[$fieldInfo['type']])) { throw new \Spot\Exception("Field type '" . $fieldInfo['type'] . "' not supported"); } + + //MOD 20120611 mwoc: only overwrite NULL values with defaults + foreach($fieldInfo as $key => $opt){ + if(is_null($opt)){ + $fieldInfo[$key] = isset($this->_fieldTypeMap[$fieldInfo['type']][$key]) ? $this->_fieldTypeMap[$fieldInfo['type']][$key] : NULL; + } + } + //Ensure this class will choose adapter type - unset($fieldInfo['adapter_type']); - - $fieldInfo = array_merge($this->_fieldTypeMap[$fieldInfo['type']],$fieldInfo); + $fieldInfo['adapter_type'] = $this->_fieldTypeMap[$fieldInfo['type']]['adapter_type']; $syntax = "`" . $fieldName . "` " . $fieldInfo['adapter_type']; // Column type and length @@ -139,7 +145,7 @@ public function migrateSyntaxFieldCreate($fieldName, array $fieldInfo) // Unsigned $syntax .= ($fieldInfo['unsigned']) ? ' unsigned' : ''; // Collate - $syntax .= ($fieldInfo['type'] == 'string' || $fieldInfo['type'] == 'text') ? ' COLLATE ' . $this->_collate : ''; + $syntax .= ($fieldInfo['type'] == 'email' || $fieldInfo['type'] == 'string' || $fieldInfo['type'] == 'text') ? ' CHARACTER SET '. $this->_charset .' COLLATE ' . $this->_collate : ''; // Nullable $isNullable = true; if($fieldInfo['required'] || !$fieldInfo['null']) { @@ -230,7 +236,7 @@ public function migrateSyntaxTableCreate($table, array $formattedFields, array $ // Ensure table type is MyISAM if FULLTEXT columns have been specified if('myisam' !== strtolower($options['engine'])) { $options['engine'] = 'MyISAM'; - } + } $syntax .= "\n, FULLTEXT(`" . implode('`, `', $fulltextFields) . "`)"; } @@ -292,7 +298,7 @@ public function migrateSyntaxTableUpdate($table, array $formattedFields, array $ // Columns $syntax .= implode(",\n", $columnsSyntax); - + // Keys... $ki = 0; $tableKeys = array( @@ -339,10 +345,10 @@ public function migrateSyntaxTableUpdate($table, array $formattedFields, array $ // Ensure table type is MyISAM if FULLTEXT columns have been specified if('myisam' !== strtolower($options['engine'])) { $options['engine'] = 'MyISAM'; - } + } $syntax .= "\n, FULLTEXT(`" . implode('`, `', $fulltextFields) . "`)"; } - + // PRIMARY if($tableKeys['primary']) { $syntax .= "\n, PRIMARY KEY(`" . implode('`, `', $tableKeys['primary']) . "`)"; diff --git a/alloy/Plugin/Spot/lib/Spot/Adapter/PDO/Abstract.php b/alloy/Plugin/Spot/lib/Spot/Adapter/PDO/Abstract.php index d1dc04a..acf4455 100644 --- a/alloy/Plugin/Spot/lib/Spot/Adapter/PDO/Abstract.php +++ b/alloy/Plugin/Spot/lib/Spot/Adapter/PDO/Abstract.php @@ -10,11 +10,11 @@ abstract class PDO_Abstract extends AdapterAbstract implements AdapterInterface { protected $_database; - - + + /** * Get database connection - * + * * @return object PDO */ public function connection() @@ -25,7 +25,7 @@ public function connection() } else { $dsnp = $this->parseDSN($this->_dsn); $this->_database = $dsnp['database']; - + // Establish connection try { $dsn = $dsnp['adapter'].':host='.$dsnp['host'].';dbname='.$dsnp['database']; @@ -39,8 +39,8 @@ public function connection() } return $this->_connection; } - - + + /** * Escape/quote direct user input * @@ -59,8 +59,8 @@ public function formatMigrateOptions(array $options) { return $options; } - - + + /** * Migrate table structure changes to database * @param String $table Table name @@ -79,7 +79,7 @@ public function migrate($table, array $fields, array $options = array()) // Get current fields for table $tableExists = false; $tableColumns = $this->getColumnsForTable($table, $this->_database); - + if($tableColumns) { $tableExists = true; } @@ -91,11 +91,11 @@ public function migrate($table, array $fields, array $options = array()) $this->migrateTableCreate($table, $fields, $options); } } - - + + /** * Execute a CREATE TABLE command - * + * * @param String $table Table name * @param Array $fields Fields and their attributes as defined in the mapper * @param Array $options Options that may affect migrations or how tables are setup @@ -108,27 +108,27 @@ public function migrateTableCreate($table, array $formattedFields, array $option * Use column syntax array to get table syntax * Run SQL */ - + // Prepare fields and get syntax for each $columnsSyntax = array(); foreach($formattedFields as $fieldName => $fieldInfo) { $columnsSyntax[$fieldName] = $this->migrateSyntaxFieldCreate($fieldName, $fieldInfo); } - + // Get syntax for table with fields/columns $sql = $this->migrateSyntaxTableCreate($table, $formattedFields, $columnsSyntax, $options); - + // Add query to log \Spot\Log::addQuery($this, $sql); - + $this->connection()->exec($sql); return true; } - - + + /** * Execute an ALTER/UPDATE TABLE command - * + * * @param String $table Table name * @param Array $fields Fields and their attributes as defined in the mapper * @param Array $options Options that may affect migrations or how tables are setup @@ -141,24 +141,24 @@ public function migrateTableUpdate($table, array $formattedFields, array $option * Use column syntax array to get table syntax * Run SQL */ - + // Prepare fields and get syntax for each $tableColumns = $this->getColumnsForTable($table, $this->_database); $updateFormattedFields = array(); foreach($tableColumns as $fieldName => $columnInfo) { if(isset($formattedFields[$fieldName])) { // TODO: Need to do a more exact comparison and make this non-mysql specific - if ( + if ( $this->_fieldTypeMap[$formattedFields[$fieldName]['type']] != $columnInfo['DATA_TYPE'] || $formattedFields[$fieldName]['default'] !== $columnInfo['COLUMN_DEFAULT'] ) { $updateFormattedFields[$fieldName] = $formattedFields[$fieldName]; } - + unset($formattedFields[$fieldName]); } } - + $columnsSyntax = array(); // Update fields whose options have changed foreach($updateFormattedFields as $fieldName => $fieldInfo) { @@ -168,14 +168,14 @@ public function migrateTableUpdate($table, array $formattedFields, array $option foreach($formattedFields as $fieldName => $fieldInfo) { $columnsSyntax[$fieldName] = $this->migrateSyntaxFieldUpdate($fieldName, $fieldInfo, true); } - + // Get syntax for table with fields/columns if ( !empty($columnsSyntax) ) { $sql = $this->migrateSyntaxTableUpdate($table, $formattedFields, $columnsSyntax, $options); - + // Add query to log \Spot\Log::addQuery($this, $sql); - + try { // Run SQL $this->connection()->exec($sql); @@ -191,17 +191,17 @@ public function migrateTableUpdate($table, array $formattedFields, array $option } return true; } - - + + /** - * Prepare an SQL statement + * Prepare an SQL statement */ public function prepare($sql) { return $this->connection()->prepare($sql); } - - + + /** * Find records with custom SQL query * @@ -213,7 +213,7 @@ public function query($sql, array $binds = array()) { // Add query to log \Spot\Log::addQuery($this, $sql, $binds); - + // Prepare and execute query if($stmt = $this->connection()->prepare($sql)) { $results = $stmt->execute($binds); @@ -227,8 +227,8 @@ public function query($sql, array $binds = array()) throw new \Spot\Exception(__METHOD__ . " Error: Unable to execute SQL query - failed to create prepared statement from given SQL"); } } - - + + /** * Create new row object with set properties */ @@ -239,14 +239,14 @@ public function create($datasource, array $data, array $options = array()) $sql = "INSERT INTO " . $datasource . " (" . implode(', ', array_keys($data)) . ")" . " VALUES(:" . implode(', :', array_keys($binds)) . ")"; - + // Add query to log \Spot\Log::addQuery($this, $sql, $binds); - + try { // Prepare update query $stmt = $this->connection()->prepare($sql); - + if($stmt) { // Execute if($stmt->execute($binds)) { @@ -264,11 +264,11 @@ public function create($datasource, array $data, array $options = array()) if($e->getCode() == "42S02") { throw new \Spot\Exception_Datasource_Missing("Table or datasource '" . $datasource . "' does not exist"); } - + // Re-throw exception throw $e; } - + return $result; } @@ -289,7 +289,7 @@ public function read(\Spot\Query $query, array $options = array()) $order[] = $oField . " " . $oSort; } } - + $sql = " SELECT " . $this->statementFields($query->fields) . " FROM " . $query->datasource . " @@ -298,7 +298,7 @@ public function read(\Spot\Query $query, array $options = array()) " . ($order ? 'ORDER BY ' . implode(', ', $order) : '') . " " . ($query->limit ? 'LIMIT ' . $query->limit : '') . " " . ($query->limit && $query->offset ? 'OFFSET ' . $query->offset: '') . " "; - + // Unset any NULL values in binds (compared as "IS NULL" and "IS NOT NULL" in SQL instead) if($binds && count($binds) > 0) { foreach($binds as $field => $value) { @@ -307,15 +307,15 @@ public function read(\Spot\Query $query, array $options = array()) } } } - + // Add query to log \Spot\Log::addQuery($this, $sql, $binds); - + $result = false; try { // Prepare update query $stmt = $this->connection()->prepare($sql); - + if($stmt) { // Execute if($stmt->execute($binds)) { @@ -331,14 +331,14 @@ public function read(\Spot\Query $query, array $options = array()) if($e->getCode() == "42S02") { throw new \Spot\Exception_Datasource_Missing("Table or datasource '" . $query->datasource . "' does not exist"); } - + // Re-throw exception throw $e; } - + return $result; } - + /* * Count number of rows in source based on conditions */ @@ -351,7 +351,7 @@ public function count(\Spot\Query $query, array $options = array()) FROM " . $query->datasource . " " . ($conditions ? 'WHERE ' . $conditions : '') . " " . ($query->group ? 'GROUP BY ' . implode(', ', $query->group) : ''); - + // Unset any NULL values in binds (compared as "IS NULL" and "IS NOT NULL" in SQL instead) if($binds && count($binds) > 0) { foreach($binds as $field => $value) { @@ -360,15 +360,15 @@ public function count(\Spot\Query $query, array $options = array()) } } } - + // Add query to log \Spot\Log::addQuery($this, $sql,$binds); - + $result = false; try { // Prepare count query $stmt = $this->connection()->prepare($sql); - + //if prepared, execute if($stmt && $stmt->execute($binds)) { //the count is returned in the first column @@ -381,14 +381,14 @@ public function count(\Spot\Query $query, array $options = array()) if($e->getCode() == "42S02") { throw new \Spot\Exception_Datasource_Missing("Table or datasource '" . $query->datasource . "' does not exist"); } - + // Re-throw exception throw $e; } - + return $result; } - + /** * Update entity */ @@ -397,30 +397,30 @@ public function update($datasource, array $data, array $where = array(), array $ $dataBinds = $this->statementBinds($data, 0); $whereBinds = $this->statementBinds($where, count($dataBinds)); $binds = array_merge($dataBinds, $whereBinds); - + $placeholders = array(); $dataFields = array_combine(array_keys($data), array_keys($dataBinds)); // Placeholders and passed data foreach($dataFields as $field => $bindField) { $placeholders[] = $field . " = :" . $bindField . ""; } - + $conditions = $this->statementConditions($where, count($dataBinds)); - + // Ensure there are actually updated values on THIS table if(count($binds) > 0) { // Build the query $sql = "UPDATE " . $datasource . " SET " . implode(', ', $placeholders) . " WHERE " . $conditions; - + // Add query to log \Spot\Log::addQuery($this, $sql, $binds); - + try { // Prepare update query $stmt = $this->connection()->prepare($sql); - + if($stmt) { // Execute if($stmt->execute($binds)) { @@ -436,18 +436,18 @@ public function update($datasource, array $data, array $where = array(), array $ if($e->getCode() == "42S02") { throw new \Spot\Exception_Datasource_Missing("Table or datasource '" . $datasource . "' does not exist"); } - + // Re-throw exception throw $e; } } else { $result = false; } - + return $result; } - - + + /** * Delete entities matching given conditions * @@ -458,10 +458,10 @@ public function delete($datasource, array $data, array $options = array()) { $binds = $this->statementBinds($data, 0); $conditions = $this->statementConditions($data); - + $sql = "DELETE FROM " . $datasource . ""; $sql .= ($conditions ? ' WHERE ' . $conditions : ''); - + // Add query to log \Spot\Log::addQuery($this, $sql, $binds); try { @@ -482,23 +482,23 @@ public function delete($datasource, array $data, array $options = array()) if($e->getCode() == "42S02") { throw new \Spot\Exception_Datasource_Missing("Table or datasource '" . $datasource . "' does not exist"); } - + // Re-throw exception throw $e; } } - - + + /** * Truncate a database table * Should delete all rows and reset serial/auto_increment keys to 0 */ public function truncateDatasource($datasource) { $sql = "TRUNCATE TABLE " . $datasource; - + // Add query to log \Spot\Log::addQuery($this, $sql); - + try { return $this->connection()->exec($sql); } catch(\PDOException $e) { @@ -506,23 +506,23 @@ public function truncateDatasource($datasource) { if($e->getCode() == "42S02") { throw new \Spot\Exception_Datasource_Missing("Table or datasource '" . $datasource . "' does not exist"); } - + // Re-throw exception throw $e; } } - - + + /** * Drop a database table * Destructive and dangerous - drops entire table and all data */ public function dropDatasource($datasource) { $sql = "DROP TABLE " . $datasource; - + // Add query to log \Spot\Log::addQuery($this, $sql); - + try { return $this->connection()->exec($sql); } catch(\PDOException $e) { @@ -530,27 +530,27 @@ public function dropDatasource($datasource) { if($e->getCode() == "42S02") { throw new \Spot\Exception_Datasource_Missing("Table or datasource '" . $datasource . "' does not exist"); } - + // Re-throw exception throw $e; } } - - + + /** * Create a database * Will throw errors if user does not have proper permissions */ public function createDatabase($database) { $sql = "CREATE DATABASE " . $database; - + // Add query to log \Spot\Log::addQuery($this, $sql); - + return $this->connection()->exec($sql); } - - + + /** * Drop a database table * Destructive and dangerous - drops entire table and all data @@ -558,14 +558,14 @@ public function createDatabase($database) { */ public function dropDatabase($database) { $sql = "DROP DATABASE " . $database; - + // Add query to log \Spot\Log::addQuery($this, $sql); - + return $this->connection()->exec($sql); } - - + + /** * Return fields as a string for a query statement */ @@ -573,15 +573,15 @@ public function statementFields(array $fields = array()) { return count($fields) > 0 ? implode(', ', $fields) : "*"; } - - + + /** * Builds an SQL string given conditions */ public function statementConditions(array $conditions = array(), $ci = 0) { if(count($conditions) == 0) { return; } - + $sqlStatement = "("; $defaultColOperators = array(0 => '', 1 => '='); $loopOnce = false; @@ -595,7 +595,7 @@ public function statementConditions(array $conditions = array(), $ci = 0) $sqlWhere = array(); foreach($subConditions as $column => $value) { $whereClause = ''; - + // Column name with comparison operator $colData = explode(' ', $column); $operator = isset($colData[1]) ? $colData[1] : '='; @@ -604,7 +604,7 @@ public function statementConditions(array $conditions = array(), $ci = 0) $colData = array( implode(' ', $colData), $operator); } $col = $colData[0]; - + // Determine which operator to use based on custom and standard syntax switch($operator) { case '<': @@ -627,7 +627,7 @@ public function statementConditions(array $conditions = array(), $ci = 0) case '~=': case '=~': case ':regex': - $operator = "REGEX"; + $operator = "REGEXP"; break; // LIKE case ':like': @@ -667,7 +667,7 @@ public function statementConditions(array $conditions = array(), $ci = 0) } break; } - + // If WHERE clause not already set by the code above... if(is_array($value)) { $valueIn = ""; @@ -679,7 +679,7 @@ public function statementConditions(array $conditions = array(), $ci = 0) } elseif(is_null($value)) { $whereClause = $col . " " . $operator; } - + if(empty($whereClause)) { // Add to binds array and add to WHERE clause $colParam = preg_replace('/\W+/', '_', $col) . $ci; @@ -687,7 +687,7 @@ public function statementConditions(array $conditions = array(), $ci = 0) } else { $sqlWhere[] = $whereClause; } - + // Increment ensures column name distinction $ci++; } @@ -698,23 +698,23 @@ public function statementConditions(array $conditions = array(), $ci = 0) $sqlStatement .= ")"; if($loopOnce) { break; } } - + // Ensure we actually had conditions if(0 == $ci) { $sqlStatement = ''; } - + return $sqlStatement; } - - + + /** * Returns array of binds to pass to query function */ public function statementBinds(array $conditions = array(), $ci = false) { if(count($conditions) == 0) { return; } - + $binds = array(); $loopOnce = false; foreach($conditions as $condition) { @@ -725,9 +725,9 @@ public function statementBinds(array $conditions = array(), $ci = false) $loopOnce = true; } foreach($subConditions as $column => $value) { - + $bindValue = false; - + // Handle binding depending on type if(is_object($value)) { if($value instanceof \DateTime) { @@ -741,7 +741,7 @@ public function statementBinds(array $conditions = array(), $ci = false) } elseif(!is_array($value)) { $bindValue = $value; } - + // Bind given value if(false !== $bindValue) { // Column name with comparison operator @@ -752,15 +752,15 @@ public function statementBinds(array $conditions = array(), $ci = false) $colData = array(implode(' ', $colData), $operator); } $col = $colData[0]; - + // Increment ensures column name distinction if(false !== $ci) { $col = $col . $ci; $ci++; } - + $colParam = preg_replace('/\W+/', '_', $col); - + // Add to binds array and add to WHERE clause $binds[$colParam] = $bindValue; } @@ -769,8 +769,8 @@ public function statementBinds(array $conditions = array(), $ci = false) } return $binds; } - - + + /** * Return result set for current query */ @@ -778,25 +778,25 @@ public function toCollection(\Spot\Query $query, $stmt) { $mapper = $query->mapper(); $entityClass = $query->entityName(); - + if($stmt instanceof \PDOStatement) { // Set PDO fetch mode $stmt->setFetchMode(\PDO::FETCH_ASSOC); - + $collection = $mapper->collection($entityClass, $stmt); - + // Ensure statement is closed $stmt->closeCursor(); return $collection; - + } else { $mapper->addError(__METHOD__ . " - Unable to execute query " . implode(' | ', $this->connection()->errorInfo())); return array(); } } - - + + /** * Bind array of field/value data to given statement * diff --git a/alloy/lib/Alloy/Request.php b/alloy/lib/Alloy/Request.php index afcce9f..0486866 100644 --- a/alloy/lib/Alloy/Request.php +++ b/alloy/lib/Alloy/Request.php @@ -37,8 +37,19 @@ public function __construct() } // Properly handle PUT and DELETE request params - if($this->isPut() || $this->isDelete()) { - parse_str(file_get_contents('php://input'), $params); + if($this->isPost() || $this->isPut() || $this->isDelete()) { + $input=file_get_contents('php://input'); + if($this->isJSON()){ + //try to decode as if json is sent + $params = json_decode($input,true); + + if(JSON_ERROR_NONE!==json_last_error()){ + //probably not json data, try default instead + parse_str($input, $params); + } + } else { + parse_str($input, $params); + } $this->params($params); } } @@ -48,7 +59,7 @@ public function __construct() * Return requested URL path * * Works for HTTP(S) requests and CLI requests using the -u flag for URL dispatch emulation - * + * * @return string Requested URL path segement */ public function url() @@ -57,20 +68,20 @@ public function url() if($this->isCli()) { // CLI request $cliArgs = getopt("u:"); - + $requestUrl = isset($cliArgs['u']) ? $cliArgs['u'] : '/'; $qs = parse_url($requestUrl, PHP_URL_QUERY); $cliRequestParams = array(); parse_str($qs, $cliRequestParams); - + // Set parsed query params back on request object $this->setParams($cliRequestParams); - + // Set requestUrl and remove query string if present so router can parse it as expected if($qsPos = strpos($requestUrl, '?')) { $requestUrl = substr($requestUrl, 0, $qsPos); } - + } else { // HTTP request $requestUrl = $this->get('u', '/'); @@ -80,8 +91,8 @@ public function url() return $this->_url; } - - + + /** * Access values contained in the superglobals as public members * Order of precedence: 1. GET, 2. POST, 3. COOKIE, 4. SERVER, 5. ENV @@ -96,27 +107,27 @@ public function get($key, $default = null) case isset($this->_params[$key]): $value = $this->_params[$key]; break; - + case isset($_GET[$key]): $value = $_GET[$key]; break; - + case isset($_POST[$key]): $value = $_POST[$key]; break; - + case isset($_COOKIE[$key]): $value = $_COOKIE[$key]; break; - + case isset($_SERVER[$key]): $value = $_SERVER[$key]; break; - + case isset($_ENV[$key]): $value = $_ENV[$key]; break; - + default: $value = $default; } @@ -141,12 +152,12 @@ public function get($key, $default = null) $value = $value[$keyPart]; } else { $value = $default; - } + } } } } } - + return $value; } // Automagic companion function @@ -154,8 +165,8 @@ public function __get($key) { return $this->get($key); } - - + + /** * Override request parameter value * @@ -171,8 +182,8 @@ public function __set($key, $value) { $this->set($key, $value); } - - + + /** * Check to see if a property is set * @@ -198,8 +209,8 @@ public function __isset($key) return false; } } - - + + /** * Retrieve request parameters * @@ -212,15 +223,15 @@ public function params(array $params = array()) foreach($params as $pKey => $pValue) { $this->set($pKey, $pValue); } - + // Getting } else { $params = array_merge($_GET, $_POST, $this->_params); } return $params; } - - + + /** * Set additional request parameters */ @@ -232,8 +243,8 @@ public function setParams($params) } } } - - + + /** * Retrieve a member of the $params set variables * @@ -249,11 +260,11 @@ public function param($key = null, $default = null) if (null === $key) { return $this->_params; } - + return (isset($this->_params[$key])) ? $this->_params[$key] : $default; } - - + + /** * Retrieve a member of the $_GET superglobal * @@ -270,11 +281,11 @@ public function query($key = null, $default = null) // Return _GET params without routing param or other params set by Alloy or manually on the request object return array_diff_key($_GET, $this->param() + array('u' => 1)); } - + return (isset($_GET[$key])) ? $_GET[$key] : $default; } - - + + /** * Retrieve a member of the $_POST superglobal * @@ -287,14 +298,15 @@ public function query($key = null, $default = null) */ public function post($key = null, $default = null) { + if (null === $key) { return $_POST; } - + return (isset($_POST[$key])) ? $_POST[$key] : $default; } - - + + /** * Retrieve a member of the $_COOKIE superglobal * @@ -310,11 +322,11 @@ public function cookie($key = null, $default = null) if (null === $key) { return $_COOKIE; } - + return (isset($_COOKIE[$key])) ? $_COOKIE[$key] : $default; } - - + + /** * Retrieve a member of the $_SERVER superglobal * @@ -329,11 +341,11 @@ public function server($key = null, $default = null) if (null === $key) { return $_SERVER; } - + return (isset($_SERVER[$key])) ? $_SERVER[$key] : $default; } - - + + /** * Retrieve a member of the $_ENV superglobal * @@ -348,11 +360,11 @@ public function env($key = null, $default = null) if (null === $key) { return $_ENV; } - + return (isset($_ENV[$key])) ? $_ENV[$key] : $default; } - - + + /** * Return the value of the given HTTP header. Pass the header name as the * plain, HTTP-specified header name. Ex.: Ask for 'Accept' to get the @@ -368,7 +380,13 @@ public function header($header) if (!empty($_SERVER[$temp])) { return $_SERVER[$temp]; } - + + // Some headers do not have a HTTP_ prefix, like CONTENT_TYPE + $temp2 = strtoupper(str_replace('-', '_', $header)); + if (!empty($_SERVER[$temp2])) { + return $_SERVER[$temp2]; + } + // This seems to be the only way to get the Authorization header on Apache if (function_exists('apache_request_headers')) { $headers = apache_request_headers(); @@ -376,11 +394,11 @@ public function header($header) return $headers[$header]; } } - + return false; } - - + + /** * Return the method by which the request was made. Always returns HTTP_METHOD in UPPERCASE. * @@ -441,8 +459,8 @@ public function port() { return $this->server('SERVER_PORT'); } - - + + /** * Get a user's correct IP address * Retrieves IP's behind firewalls or ISP proxys like AOL @@ -452,10 +470,10 @@ public function port() public function ip() { $ip = FALSE; - + if( !empty( $_SERVER["HTTP_CLIENT_IP"] ) ) $ip = $_SERVER["HTTP_CLIENT_IP"]; - + if( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ){ // Put the IP's into an array which we shall work with shortly. $ips = explode( ", ", $_SERVER['HTTP_X_FORWARDED_FOR'] ); @@ -463,7 +481,7 @@ public function ip() array_unshift( $ips, $ip ); $ip = false; } - + for( $i = 0; $i < count($ips); $i++ ){ if (!eregi ("^(10|172\.16|192\.168)\.", $ips[$i])) { $ip = $ips[$i]; @@ -473,8 +491,8 @@ public function ip() } return ($ip ? $ip : $_SERVER['REMOTE_ADDR']); } - - + + /** * Determine is incoming request is POST * @@ -484,8 +502,8 @@ public function isPost() { return ($this->method() == "POST"); } - - + + /** * Determine is incoming request is GET * @@ -495,8 +513,8 @@ public function isGet() { return ($this->method() == "GET"); } - - + + /** * Determine is incoming request is PUT * @@ -506,8 +524,8 @@ public function isPut() { return ($this->method() == "PUT"); } - - + + /** * Determine is incoming request is DELETE * @@ -517,8 +535,8 @@ public function isDelete() { return ($this->method() == "DELETE"); } - - + + /** * Determine is incoming request is HEAD * @@ -539,8 +557,8 @@ public function isOptions() { return ($this->method() == "OPTIONS"); } - - + + /** * Determine is incoming request is secure HTTPS * @@ -550,8 +568,8 @@ public function isSecure() { return (bool) ((!isset($_SERVER['HTTPS']) || strtolower($_SERVER['HTTPS']) != 'on') ? false : true); } - - + + /** * Is the request a Javascript XMLHttpRequest? * @@ -564,6 +582,10 @@ public function isAjax() return ($this->header('X_REQUESTED_WITH') == 'XMLHttpRequest'); } + public function isJSON() + { + return (strpos($this->header('CONTENT_TYPE'),'application/json')===0); + } /** * Is the request coming from a mobile device? @@ -584,12 +606,12 @@ public function isMobile() || $op != '' || strpos($ua, 'iphone') !== false || strpos($ua, 'android') !== false - || strpos($ua, 'iemobile') !== false + || strpos($ua, 'iemobile') !== false || strpos($ua, 'kindle') !== false - || strpos($ua, 'sony') !== false - || strpos($ua, 'symbian') !== false - || strpos($ua, 'nokia') !== false - || strpos($ua, 'samsung') !== false + || strpos($ua, 'sony') !== false + || strpos($ua, 'symbian') !== false + || strpos($ua, 'nokia') !== false + || strpos($ua, 'samsung') !== false || strpos($ua, 'mobile') !== false || strpos($ua, 'windows ce') !== false || strpos($ua, 'epoc') !== false @@ -630,8 +652,8 @@ public function isMobile() || strpos($ua, 'wap2.') !== false ); } - - + + /** * Is the request coming from a bot or spider? * @@ -651,8 +673,8 @@ public function isBot() false !== strpos($ua, 'spider') ); } - - + + /** * Is the request from CLI (Command-Line Interface)? * @@ -662,11 +684,11 @@ public function isCli() { return !isset($_SERVER['HTTP_HOST']); } - - + + /** * Is this a Flash request? - * + * * @return bool */ public function isFlash() diff --git a/alloy/lib/Alloy/View/Generic/Form.php b/alloy/lib/Alloy/View/Generic/Form.php index cfcf43b..6b9e3ef 100644 --- a/alloy/lib/Alloy/View/Generic/Form.php +++ b/alloy/lib/Alloy/View/Generic/Form.php @@ -3,7 +3,7 @@ /** * Generic Form View - * + * * @package Alloy * @license http://www.opensource.org/licenses/bsd-license.php * @link http://alloyframework.com/ @@ -13,8 +13,8 @@ class Form extends \Alloy\View\Template protected $_fields = array(); protected $_fieldValues = array(); protected $_submitButtonText = 'Save'; - - + + /** * Setup form object */ @@ -24,13 +24,13 @@ public function init() $this->path(__DIR__ . '/templates/'); // Default enctype - $this->set('enctype', 'appliaction/x-www-form-urlencoded'); + $this->set('enctype', 'application/x-www-form-urlencoded'); // Default settings $this->set('_form_tags', true); } - - + + /** * Action param of form * @@ -41,8 +41,8 @@ public function action($action = '') $this->set('action', $action); return $this; } - - + + /** * HTTP Method param of form * @@ -81,8 +81,8 @@ public function type($type = null) } return $this; } - - + + /** * Field setter/getter */ @@ -94,8 +94,8 @@ public function fields(array $fields = array()) } return $this->_fields; } - - + + /** * Get params set on field * @@ -109,8 +109,8 @@ public function field($field) return false; } } - - + + /** * Value by field name */ @@ -120,12 +120,12 @@ public function data($field = null, $value = null) if(null === $field) { return $this->_fieldValues; } - + // Set data for single field if(null !== $value) { $this->_fieldValues[$field] = $value; return $this; - + // Set data from array for many fields } elseif(is_array($field)) { foreach($field as $fieldx => $val) { @@ -133,12 +133,12 @@ public function data($field = null, $value = null) } return $this; } - + // Return data for given field return isset($this->_fieldValues[$field]) ? $this->_fieldValues[$field] : null; } - - + + /** * Remove fields by name * @@ -163,8 +163,8 @@ public function removeFields($fieldName) } return $this; } - - + + /** * Set the text for the submit button * @@ -191,8 +191,8 @@ public function formTags($show = true) $this->set('_form_tags', $show); return $this; } - - + + /** * Return template content */ @@ -200,7 +200,7 @@ public function content($parsePHP = true) { // Set template vars $this->set('fields', $this->fields()); - + return parent::content($parsePHP); } } \ No newline at end of file