Skip to content

Commit

Permalink
fixed a route resolver bug
Browse files Browse the repository at this point in the history
  • Loading branch information
Mashape committed Feb 1, 2011
1 parent 6c21b72 commit 5739f94
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 43 deletions.
5 changes: 2 additions & 3 deletions api.php
Expand Up @@ -2,8 +2,7 @@

require_once("mashape/mashape.php");

// The path of the XML configuration file required by Mashape.
// The path is relative to your implementation file. By default it's "./api.xml"
// The path of the XML configuration file required by Mashape. By default it's "./api.xml"
define("CONFIGURATION_FILEPATH", "./api.xml");

// This is the server key for your component
Expand All @@ -20,7 +19,7 @@ public function __construct() {
public function sayHello($name) {
return "Hello " . $name . "!";
}

}

// Init the library
Expand Down
1 change: 1 addition & 0 deletions mashape/exceptions/exceptionMessages.php
Expand Up @@ -84,6 +84,7 @@
define("EXCEPTION_JSONDECODE_REQUEST", "Can't deserialize the response JSON from Mashape. The json_decode function is missing on server");
define("EXCEPTION_INVALID_CALLBACK", "Invalid function name set as a callback");
define("EXCEPTION_INVALID_PERMISSION", "File permission denied: can't create and write to the file %s");
define("EXCEPTION_AMBIGUOUS_ROUTE", "Some routes are ambiguous and very similar, please verify the methods: %s");

define("EXCEPTION_INVALID_APIKEY_CODE", 2001);
define("EXCEPTION_EXCEEDED_LIMIT_CODE", 2002);
Expand Down
74 changes: 51 additions & 23 deletions mashape/methods/call/helpers/routeHelper.php
Expand Up @@ -25,49 +25,77 @@
*/

require_once(dirname(__FILE__) . "/../../../configuration/restConfigurationLoader.php");
require_once(dirname(__FILE__) . "/../../../exceptions/mashapeException.php");
require_once(dirname(__FILE__) . "/../../../utils/routeUtils.php");
require_once(dirname(__FILE__) . "/../../../utils/arrayUtils.php");

function findRoute($requestUri, &$routeParameters, $serverKey) {
$routeMethod = null;

$configuration = RESTConfigurationLoader::loadConfiguration($serverKey);
$methods = $configuration->getMethods();

// Remove any folder before the route URL
$scriptUrl = $_SERVER["PHP_SELF"];

$fileParts = Explode('/', $scriptUrl);
unset($fileParts[count($fileParts) - 1]);
$requestUri = substr($requestUri, strlen(implode("/", $fileParts)));

$requestUri = Explode("?", substr($requestUri, 1));
$requestUriParts = Explode("/", $requestUri[0]);

foreach ($methods as $method) {
$route = $method->getRoute();
if (!empty($route)) {
$routeParts = Explode("/", substr($route, 1));
if (count($requestUriParts) == count($routeParts)) {
for ($i=0;$i<count($routeParts);$i++) {
if ($routeParts[$i] != $requestUriParts[$i]) {
if (RouteUtils::isRoutePlaceholder($routeParts[$i])) {
$placeHolder = RouteUtils::getRoutePlaceholder($routeParts[$i]);
$routeParameters[$placeHolder] = $requestUriParts[$i];
$likelyMethods = array();
$excludedMethods = array();
// Backward loop
for ($i=count($requestUriParts) - 1; $i>=0;$i--) {
// Find if there's a path like that, otherwise check for placeholders
foreach ($methods as $method) {
$methodName = $method->getName();
if (in_array($methodName, $excludedMethods)) {
continue;
}
// echo "Method " . $methodName . "\n\n";
$route = $method->getRoute();
if (!empty($route)) {
$routeParts = Explode("/", substr($route, 1));
$backwardIndex = count($routeParts) - (count($requestUriParts) - $i);
if ($backwardIndex >= 0) {
// echo "* RoutePart: " . $routeParts[$backwardIndex] . "\n";
// echo "* RequestPart: " . $requestUriParts[$i] . "\n\n";
if ($routeParts[$backwardIndex] == $requestUriParts[$i]) {
if (!ArrayUtils::existKey($methodName, $likelyMethods)) {
$likelyMethods[$methodName] = array();
}
} else if (RouteUtils::isRoutePlaceholder($routeParts[$backwardIndex])) {
$foundParameters;
$placeHolder = RouteUtils::getRoutePlaceholder($routeParts[$backwardIndex]);
if (!ArrayUtils::existKey($methodName, $likelyMethods)) {
$foundParameters = array();
} else {
break;
$foundParameters = $likelyMethods[$methodName];
}
}
if ($i == count($routeParts) - 1) {
$routeMethod = $method;
$foundParameters[$placeHolder] = $requestUriParts[$i];
$likelyMethods[$methodName] = $foundParameters;
} else {
array_push($excludedMethods, $methodName);
unset($likelyMethods[$methodName]);
}
}
}
}
if ($routeMethod != null) {
break;
}

if (count($likelyMethods) > 1) {
$ambiguousMethods = "";
foreach ($likelyMethods as $key => $value) {
$ambiguousMethods .= "\"" . $key . "\", ";
}
$ambiguousMethods = substr($ambiguousMethods, 0, strlen($ambiguousMethods) - 2);
throw new MashapeException(sprintf(EXCEPTION_AMBIGUOUS_ROUTE, $ambiguousMethods), EXCEPTION_SYSTEM_ERROR_CODE);
}


// Get the first item (just one or none item can exist)
foreach ($likelyMethods as $key => $value) {
$routeMethod = RESTConfigurationLoader::getMethod($key, $serverKey);
$routeParameters = array_merge($routeParameters, $value);
break;
}

return $routeMethod;
}

Expand Down
68 changes: 68 additions & 0 deletions mashape/methods/call/helpers/serializeArray.php
@@ -0,0 +1,68 @@
<?php

/*
* Mashape PHP library.
*
* Copyright (C) 2011 Mashape, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
* The author of this software is Mashape, Inc.
* For any question or feedback please contact us at: support@mashape.com
*
*/

require_once(dirname(__FILE__) . "/../../../configuration/restConfigurationLoader.php");
require_once(dirname(__FILE__) . "/../../../json/jsonUtils.php");
require_once(dirname(__FILE__) . "/../../../utils/arrayUtils.php");
require_once(dirname(__FILE__) . "/serializeObject.php");

function serializeArray($result, $instance, $isSimpleResult, $serverKey) {
$json = "";
if (is_array($result)) {
if (ArrayUtils::isAssociative($result)) {
foreach ($result as $key => $value) {
$json .= '{"' . $key . '":';
if (is_object($value)) {
$json .= serializeObject($value, $instance, false, $serverKey);
} else {
if (is_array($value)) {
$json .= "[";
$json .= serializeArray($value, $instance, $isSimpleResult, $serverKey);
$json .= "]";
} else {
$json .= serializeObject($value, $instance, !is_object($value), $serverKey);
}
}
$json .= "},";
}
} else {
for ($i=0;$i<count($result);$i++) {
$json .= serializeObject($result[$i], $instance, $isSimpleResult, $serverKey) . ",";
}
}
$json = JsonUtils::removeLastChar($result, $json);
}
return $json;
}


function checkIfSimpleResult($value) {
//if (is_string($value) || is_bool($value) || is_numeric($value) || )
}



?>
7 changes: 3 additions & 4 deletions mashape/methods/call/helpers/serializeMethodResult.php
Expand Up @@ -27,7 +27,9 @@
require_once(dirname(__FILE__) . "/../../../exceptions/mashapeException.php");
require_once(dirname(__FILE__) . "/../../../configuration/restConfigurationLoader.php");
require_once(dirname(__FILE__) . "/../../../json/jsonUtils.php");
require_once(dirname(__FILE__) . "/../../../utils/arrayUtils.php");
require_once(dirname(__FILE__) . "/serializeObject.php");
require_once(dirname(__FILE__) . "/serializeArray.php");

function serializeMethodResult($method, $result, $instance, $serverKey) {
$json = "";
Expand All @@ -47,10 +49,7 @@ function serializeMethodResult($method, $result, $instance, $serverKey) {
if ($method->isArray()) {
$json .= "[";
if (is_array($result)) {
for ($i=0;$i<count($result);$i++) {
$json .= serializeObject($result[$i], $instance, $isSimpleResult, $serverKey) . ",";
}
$json = JsonUtils::removeLastChar($result, $json);
$json .= serializeArray($result, $instance, $isSimpleResult, $serverKey);
} else {
// The result it's not an array although it was described IT WAS an array
throw new MashapeException(EXCEPTION_EXPECTED_ARRAY_RESULT, EXCEPTION_GENERIC_LIBRARY_ERROR_CODE);
Expand Down
10 changes: 4 additions & 6 deletions mashape/methods/call/helpers/serializeObject.php
Expand Up @@ -27,6 +27,7 @@
require_once(dirname(__FILE__) . "/../../../exceptions/mashapeException.php");
require_once(dirname(__FILE__) . "/../../../configuration/restConfigurationLoader.php");
require_once(dirname(__FILE__) . "/../../../json/jsonUtils.php");
require_once(dirname(__FILE__) . "/serializeArray.php");

function serializeObject($result, $instance, $isSimpleResult, $serverKey) {
$json = "";
Expand All @@ -38,7 +39,7 @@ function serializeObject($result, $instance, $isSimpleResult, $serverKey) {
$className = get_class($result);

$reflectedClass = new ReflectionClass($className);

$xmlObject = RESTConfigurationLoader::getObject($className, $serverKey);

if (empty($xmlObject)) {
Expand All @@ -62,6 +63,7 @@ function serializeObject($result, $instance, $isSimpleResult, $serverKey) {
if ($reflectedProperty->isPublic()) {
$fieldValue = $reflectedClass->getProperty($fieldName)->getValue($result);
} else {
// Try using the __get magic method
$fieldValue = $reflectedClass->getMethod("__get")->invokeArgs($result, array($fieldName));
}
} else {
Expand All @@ -83,11 +85,7 @@ function serializeObject($result, $instance, $isSimpleResult, $serverKey) {
if ($field->isArray()) {
$json .= "[";
if (is_array($fieldValue)) {

for ($t=0;$t<count($fieldValue);$t++) {
$json .= serializeObject($fieldValue[$t], $instance, $isSimpleField, $serverKey) . ",";
}
$json = JsonUtils::removeLastChar($fieldValue, $json);
$json .= serializeArray($fieldValue, $instance, isSimpleField($field), $serverKey);
} else {
// The result it's not an array although it was described IT WAS an array
throw new MashapeException(sprintf(EXCEPTION_EXPECTED_ARRAY_RESULT, $fieldName, $className), EXCEPTION_GENERIC_LIBRARY_ERROR_CODE);
Expand Down
2 changes: 1 addition & 1 deletion mashape/methods/call/helpers/validateParameters.php
Expand Up @@ -54,7 +54,7 @@ function validateCallParameters($method, $parameters, $instance) {
throw new MashapeException(sprintf(EXCEPTION_REQUIRED_PARAMETER, $parameterName), EXCEPTION_REQUIRED_PARAMETERS_CODE);
}
} else {
if (ArrayUtils::existKey($parameterName, $keys) == false && $reflectedParameters[$i]->isOptional() == false) {
if (in_array($parameterName, $keys) == false && $reflectedParameters[$i]->isOptional() == false) {
throw new MashapeException(sprintf(EXCEPTION_REQUIRED_PARAMETER, $parameterName), EXCEPTION_REQUIRED_PARAMETERS_CODE);
}
}
Expand Down
16 changes: 10 additions & 6 deletions mashape/utils/arrayUtils.php
Expand Up @@ -28,15 +28,19 @@ class ArrayUtils {

public static function existKey($key, $array) {
if (empty($array) == false) {
for ($i=0;$i<count($array);$i++) {
if ($array[$i] == $key) {
return true;
}
}
return array_key_exists($key, $array);
}
return false;
}


public function isAssociative($array) {
if ( !is_array($array) || empty($array) ) {
return false;
}
return array_keys($array) !== range(0, count($array) - 1);

}

}

?>

0 comments on commit 5739f94

Please sign in to comment.