You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by ch...@apache.org on 2008/09/06 14:47:47 UTC

svn commit: r692646 - in /incubator/shindig/trunk/php: ./ src/social-api/canonical/ src/social-api/converters/ src/social-api/dataservice/ src/social-api/http/ src/social-api/opensocial/model/ src/social-api/samplecontainer/ test/social-api/

Author: chabotc
Date: Sat Sep  6 05:47:46 2008
New Revision: 692646

URL: http://svn.apache.org/viewvc?rev=692646&view=rev
Log:
SHINDIG-538 by Joseph Smarr - PortableContacts alignment. There's a few new test suite issues that popped up because of it, but I feel more comfertable fixing those out in the open and get some extra eyeballs on it then make that block. Big thanks to Joseph for his contribution

Modified:
    incubator/shindig/trunk/php/.htaccess
    incubator/shindig/trunk/php/src/social-api/canonical/JsonDbOpensocialService.php
    incubator/shindig/trunk/php/src/social-api/converters/OutputJsonConverter.php
    incubator/shindig/trunk/php/src/social-api/dataservice/PeopleHandler.php
    incubator/shindig/trunk/php/src/social-api/dataservice/PeopleService.php
    incubator/shindig/trunk/php/src/social-api/dataservice/RestRequestItem.php
    incubator/shindig/trunk/php/src/social-api/dataservice/RestfulCollection.php
    incubator/shindig/trunk/php/src/social-api/http/RestServlet.php
    incubator/shindig/trunk/php/src/social-api/opensocial/model/Address.php
    incubator/shindig/trunk/php/src/social-api/opensocial/model/BodyType.php
    incubator/shindig/trunk/php/src/social-api/opensocial/model/Email.php
    incubator/shindig/trunk/php/src/social-api/opensocial/model/Enum.php
    incubator/shindig/trunk/php/src/social-api/opensocial/model/Name.php
    incubator/shindig/trunk/php/src/social-api/opensocial/model/Organization.php
    incubator/shindig/trunk/php/src/social-api/opensocial/model/Person.php
    incubator/shindig/trunk/php/src/social-api/opensocial/model/Phone.php
    incubator/shindig/trunk/php/src/social-api/opensocial/model/Url.php
    incubator/shindig/trunk/php/src/social-api/samplecontainer/BasicAppDataService.php
    incubator/shindig/trunk/php/src/social-api/samplecontainer/BasicPeopleService.php
    incubator/shindig/trunk/php/test/social-api/JsonDbOpensocialServiceTest.php
    incubator/shindig/trunk/php/test/social-api/RestRequestItemTest.php

Modified: incubator/shindig/trunk/php/.htaccess
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/.htaccess?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/.htaccess (original)
+++ incubator/shindig/trunk/php/.htaccess Sat Sep  6 05:47:46 2008
@@ -2,5 +2,7 @@
         RewriteEngine On
 	RewriteCond %{REQUEST_FILENAME} !-f
 	RewriteCond %{REQUEST_FILENAME} !-d
+        # NOTE: If you added a web_prefix to config, add it here too, e.g.:
+        #RewriteRule (.*) /shindig/php/index.php [L]
         RewriteRule (.*) index.php [L]
 </IfModule>

Modified: incubator/shindig/trunk/php/src/social-api/canonical/JsonDbOpensocialService.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/canonical/JsonDbOpensocialService.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/canonical/JsonDbOpensocialService.php (original)
+++ incubator/shindig/trunk/php/src/social-api/canonical/JsonDbOpensocialService.php Sat Sep  6 05:47:46 2008
@@ -178,9 +178,9 @@
 		return $peopleWithApp;
 	}
 
-	public function getPerson($userId, $groupId, $profileDetails, SecurityToken $token)
+	public function getPerson($userId, $groupId, $fields, SecurityToken $token)
 	{
-		$person = $this->getPeople($userId, $groupId, null, null, null, null, $profileDetails, null, $token);
+		$person = $this->getPeople($userId, $groupId, new CollectionOptions(), $fields, $token);
 		// return of getPeople is a ResponseItem(RestfulCollection(ArrayOfPeople)), disassemble to return just one person
 		$person = $person->getResponse()->getEntry();
 		if (is_array($person) && count($person) == 1) {
@@ -189,8 +189,14 @@
 		return new ResponseItem(NOT_FOUND, "Person not found", null);
 	}
 
-	public function getPeople($userId, $groupId, $sortOrder, $filter, $first, $max, $profileDetails, $networkDistance, SecurityToken $token)
+	public function getPeople($userId, $groupId, CollectionOptions $options, $fields, SecurityToken $token)
 	{
+		$sortOrder = $options->getSortOrder();
+		$filter = $options->getFilterBy();
+		$first = $options->getStartIndex();
+		$max = $options->getCount();
+		$networkDistance = $options->getNetworkDistance();
+		
 		$db = $this->getDb();
 		$friendsTable = $db[self::$FRIEND_LINK_TABLE];
 		$ids = array();
@@ -226,12 +232,12 @@
 				if (! $token->isAnonymous() && $id == $token->getOwnerId()) {
 					$person['isOwner'] = true;
 				}
-				if (is_array($profileDetails) && count($profileDetails) && ! in_array('all', $profileDetails)) {
+				if (! isset($fields['@all'])) {
 					$newPerson = array();
 					$newPerson['isOwner'] = isset($person['isOwner']) ? $person['isOwner'] : false;
 					$newPerson['isViewer'] = isset($person['isViewer']) ? $person['isViewer'] : false;
 					$newPerson['name'] = $person['name'];
-					foreach ($profileDetails as $field) {
+					foreach ($fields as $field => $present) {
 						if (isset($person[$field]) && ! isset($newPerson[$field])) {
 							$newPerson[$field] = $person[$field];
 						}
@@ -281,7 +287,7 @@
 				$allPersonData = $allData[$id];
 				$personData = array();
 				foreach (array_keys($allPersonData) as $key) {
-					if (in_array($key, $fields) || (isset($fields[0]) && $fields[0] == "*")) {
+					if (isset($fields[$key]) || isset($fields['@all'])) {
 						$personData[$key] = $allPersonData[$key];
 					}
 				}
@@ -294,7 +300,7 @@
 	public function updatePersonData(UserID $userId, GroupId $groupId, $fields, $values, $appId, SecurityToken $token)
 	{
 		$db = $this->getDb();
-		foreach ($fields as $key) {
+		foreach ($fields as $key => $present) {
 			if (! $this->isValidKey($key)) {
 				return new ResponseItem(BAD_REQUEST, "The person app data key had invalid characters", null);
 			}
@@ -303,7 +309,7 @@
 		$person = $allData[$userId->getUserId($token)];
 		switch ($groupId->getType()) {
 			case 'self':
-				foreach ($fields as $key) {
+				foreach ($fields as $key => $present) {
 					$value = isset($values[$key]) ? @$values[$key] : null;
 					$person[$key] = $value;
 				}
@@ -320,14 +326,14 @@
 
 	public function deletePersonData(UserId $userId, GroupId $groupId, $fields, $appId, SecurityToken $token)
 	{
-		foreach ($fields as $key) {
+		foreach ($fields as $key => $present) {
 			if (! $this->isValidKey($key)) {
 				return new ResponseItem(BAD_REQUEST, "The person app data key had invalid characters", null);
 			}
 		}
 		switch ($groupId->getType()) {
 			case 'self':
-				foreach ($fields as $key) {//TODO: Implement this!
+				foreach ($fields as $key => $present) {//TODO: Implement this!
 }
 				break;
 			default:

Modified: incubator/shindig/trunk/php/src/social-api/converters/OutputJsonConverter.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/converters/OutputJsonConverter.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/converters/OutputJsonConverter.php (original)
+++ incubator/shindig/trunk/php/src/social-api/converters/OutputJsonConverter.php Sat Sep  6 05:47:46 2008
@@ -25,7 +25,14 @@
 
 	function outputResponse(ResponseItem $responseItem, RestRequestItem $requestItem)
 	{
-		echo json_encode($responseItem->getResponse());
+		$response = $responseItem->getResponse();
+		if ($response instanceof RestfulCollection) {
+			$itemsPerPage = $requestItem->getCount();
+			if ($itemsPerPage > 0)
+				$response->itemsPerPage = $itemsPerPage;
+		}
+		//echo self::json_format(json_encode($response)); // TODO: add a query option to pretty-print json output
+		echo json_encode($response);
 	}
 
 	function outputBatch(Array $responses, SecurityToken $token)
@@ -43,4 +50,78 @@
 	{
 		echo json_encode(array("responses" => $responses, "error" => false));
 	}
+
+	/**
+	 * Generate a pretty-printed representation of a JSON object.
+	 * 
+	 * Taken from php comments for json_encode.
+	 *
+	 * @param string $json  JSON string
+	 * @return string|false The pretty version, false if JSON was invalid
+	 */
+	static function json_format($json)
+	{
+		$tab = "  ";
+		$new_json = "";
+		$indent_level = 0;
+		$in_string = false;
+		
+		$json_obj = json_decode($json);
+		
+		if (! $json_obj)
+			return false;
+		
+		$json = json_encode($json_obj);
+		$len = strlen($json);
+		
+		for ($c = 0; $c < $len; $c ++) {
+			$char = $json[$c];
+			switch ($char) {
+				case '{':
+				case '[':
+					if (! $in_string) {
+						$new_json .= $char . "\n" . str_repeat($tab, $indent_level + 1);
+						$indent_level ++;
+					} else {
+						$new_json .= $char;
+					}
+					break;
+				
+				case '}':
+				case ']':
+					if (! $in_string) {
+						$indent_level --;
+						$new_json .= "\n" . str_repeat($tab, $indent_level) . $char;
+					} else {
+						$new_json .= $char;
+					}
+					break;
+				
+				case ',':
+					if (! $in_string) {
+						$new_json .= ",\n" . str_repeat($tab, $indent_level);
+					} else {
+						$new_json .= $char;
+					}
+					break;
+				
+				case ':':
+					if (! $in_string) {
+						$new_json .= ": ";
+					} else {
+						$new_json .= $char;
+					}
+					break;
+				
+				case '"':
+					$in_string = ! $in_string;
+				
+				default:
+					$new_json .= $char;
+					break;
+			}
+		}
+		
+		return $new_json;
+	}
 }

Modified: incubator/shindig/trunk/php/src/social-api/dataservice/PeopleHandler.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/dataservice/PeopleHandler.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/dataservice/PeopleHandler.php (original)
+++ incubator/shindig/trunk/php/src/social-api/dataservice/PeopleHandler.php Sat Sep  6 05:47:46 2008
@@ -20,7 +20,7 @@
 class PeopleHandler extends DataRequestHandler {
 	private $service;
 	private static $PEOPLE_PATH = "/people/{userId}/{groupId}/{personId}";
-	protected static $DEFAULT_PERSON_FIELDS = array("id", "name", "thumbnailUrl");
+	protected static $DEFAULT_PERSON_FIELDS = array("id" => 1, "name" => 1, "thumbnailUrl" => 1);
 
 	public function __construct()
 	{
@@ -40,21 +40,31 @@
 	{
 		$requestItem->parseUrlWithTemplate(self::$PEOPLE_PATH);
 		$parameters = $requestItem->getParameters();
-		$optionalPersonId = in_array('personId', $parameters) ? $parameters['personId'] : null;
+		$optionalPersonId = isset($parameters['personId']) ? $parameters['personId'] : null;
 		$fields = $requestItem->getFieldsWithDefaultValue(self::$DEFAULT_PERSON_FIELDS);
-		if ($optionalPersonId || (is_object($requestItem->getGroup()) && $requestItem->getGroup()->getType() == 'self')) {
-			//FIXME same logic as the java code here, but doesn't seem to do much with the optionalPersonId which seems odd
-			return $this->service->getPerson($requestItem->getUser(), $requestItem->getGroup(), $fields, $requestItem->getToken());
-		}
+		if ($optionalPersonId) {
+			return $this->service->getPerson($requestItem->getUser(), $optionalPersonId, $fields, $requestItem->getToken());
+		} else 
+			if (is_object($requestItem->getGroup()) && $requestItem->getGroup()->getType() == 'self') {
+				return $this->service->getPerson($requestItem->getUser(), $requestItem->getGroup(), $fields, $requestItem->getToken());
+			}
 		$startIndex = $requestItem->getStartIndex();
 		$count = $requestItem->getCount();
 		$networkDistance = $requestItem->getNetworkDistance();
-		if ((!empty($startIndex) && !is_numeric($startIndex)) ||
-			(!empty($count) && !is_numeric($count)) ||
-			(!empty($networkDistance) && !is_numeric($networkDistance))) {
+		if ((! empty($startIndex) && ! is_numeric($startIndex)) || (! empty($count) && ! is_numeric($count)) || (! empty($networkDistance) && ! is_numeric($networkDistance))) {
 			return new ResponseItem(BAD_REQUEST, "Invalid options specified", null);
 		} else {
-			return $this->service->getPeople($requestItem->getUser(), $requestItem->getGroup(), $requestItem->getOrderBy(), $requestItem->getFilterBy(), $startIndex, $count, $fields, $networkDistance, $requestItem->getToken());
+			$options = new CollectionOptions();
+			$options->setSortBy($requestItem->getSortBy());
+			$options->setSortOrder($requestItem->getSortOrder());
+			$options->setFilterBy($requestItem->getFilterBy());
+			$options->setFilterOperation($requestItem->getFilterOperation());
+			$options->setFilterValue($requestItem->getFilterValue());
+			$options->setUpdatedSince($requestItem->getUpdatedSince());
+			$options->setStartIndex($startIndex);
+			$options->setCount($count);
+			$options->setNetworkDistance($networkDistance);
+			return $this->service->getPeople($requestItem->getUser(), $requestItem->getGroup(), $options, $fields, $requestItem->getToken());
 		}
 	}
 

Modified: incubator/shindig/trunk/php/src/social-api/dataservice/PeopleService.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/dataservice/PeopleService.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/dataservice/PeopleService.php (original)
+++ incubator/shindig/trunk/php/src/social-api/dataservice/PeopleService.php Sat Sep  6 05:47:46 2008
@@ -18,30 +18,23 @@
  */
 
 interface PeopleService {
-
+
 	/**
 	 * Returns a Person object for person with $id or false on not found
 	 *
 	 * @param container specific id $id
-	 * @param profileDetails the details to return
+	 * @param fields set of contact fields to return, as array('fieldName' => 1)
 	 * @param security token $token
 	 */
-	function getPerson($userId, $groupId, $profileDetails, SecurityToken $token);
+	function getPerson($userId, $groupId, $fields, SecurityToken $token);
 
 	/**
 	 * Returns a list of people that correspond to the passed in person ids.
 	 * @param ids The ids of the people to fetch.
-	 * @param sortOrder How to sort the people
-	 * @param filter How the people should be filtered.
-	 * @param first The index of the first person to fetch.
-	 * @param profileDetails the details to return
-	 * @param max The max number of people to fetch.
+	 * @param options Request options for filtering/sorting/paging
+	 * @param fields set of contact fields to return, as array('fieldName' => 1)
 	 * @return a list of people.
 	 */
-	function getPeople($userId, $groupId, $sortOrder, $filter, $first, $max, $profileDetails, $networkDistance, SecurityToken $token);
+	function getPeople($userId, $groupId, CollectionOptions $options, $fields, SecurityToken $token);
 }
-
-class PeopleOptions {
-	public static $sortOrder = array('topFriends', 'name');
-	public static $filterType = array('all', 'hasApp', 'topFriends');
-}
\ No newline at end of file
+

Modified: incubator/shindig/trunk/php/src/social-api/dataservice/RestRequestItem.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/dataservice/RestRequestItem.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/dataservice/RestRequestItem.php (original)
+++ incubator/shindig/trunk/php/src/social-api/dataservice/RestRequestItem.php Sat Sep  6 05:47:46 2008
@@ -27,14 +27,19 @@
 	public static $GROUP_ID = "groupId";
 	public static $START_INDEX = "startIndex";
 	public static $COUNT = "count";
-	public static $ORDER_BY = "orderBy";
+	public static $SORT_BY = "sortBy";
+	public static $SORT_ORDER = "sortOrder";
 	public static $NETWORK_DISTANCE = "networkDistance";
 	public static $FILTER_BY = "filterBy";
+	public static $FILTER_OP = "filterOp";
+	public static $FILTER_VALUE = "filterValue";
+	public static $UPDATED_SINCE = "updatedSince";
 	public static $FIELDS = "fields";
 	
 	// OpenSocial defaults
 	public static $DEFAULT_START_INDEX = 0;
 	public static $DEFAULT_COUNT = 20;
+	public static $DEFAULT_SORT_ORDER = 'ascending';
 	
 	public static $APP_SUBSTITUTION_TOKEN = "@app";
 	
@@ -93,7 +98,7 @@
 			$params = explode("&", $queryParams);
 			foreach ($params as $param) {
 				$paramPieces = explode("=", $param, 2);
-				$this->parameters[$paramPieces[0]] = count($paramPieces) == 2 ? $paramPieces[1] : "";
+				$this->parameters[$paramPieces[0]] = count($paramPieces) == 2 ? urldecode($paramPieces[1]) : "";
 			}
 		}
 	}
@@ -157,31 +162,60 @@
 		}
 	}
 
-	public function getOrderBy()
+	public function getSortBy()
 	{
-		if (! empty($this->parameters[self::$ORDER_BY])) {
-			return $this->parameters[self::$ORDER_BY];
-		} else {
-			return PeopleOptions::$sortOrder;
+		if (! empty($this->parameters[self::$SORT_BY])) {
+			return $this->parameters[self::$SORT_BY];
+		}
+		return null;
+	}
+
+	public function getSortOrder()
+	{
+		if (! empty($this->parameters[self::$SORT_ORDER])) {
+			return $this->parameters[self::$SORT_ORDER];
 		}
+		return self::$DEFAULT_SORT_ORDER;
 	}
 
 	public function getNetworkDistance()
 	{
 		if (! empty($this->parameters[self::$NETWORK_DISTANCE])) {
 			return $this->parameters[self::$NETWORK_DISTANCE];
-		} else {
-			return false;
 		}
+		return false;
 	}
 
 	public function getFilterBy()
 	{
 		if (! empty($this->parameters[self::$FILTER_BY])) {
 			return $this->parameters[self::$FILTER_BY];
-		} else {
-			return PeopleOptions::$filterType;
 		}
+		return null;
+	}
+
+	public function getFilterOperation()
+	{
+		if (! empty($this->parameters[self::$FILTER_OP])) {
+			return $this->parameters[self::$FILTER_OP];
+		}
+		return null;
+	}
+
+	public function getFilterValue()
+	{
+		if (! empty($this->parameters[self::$FILTER_VALUE])) {
+			return $this->parameters[self::$FILTER_VALUE];
+		}
+		return null;
+	}
+
+	public function getUpdatedSince()
+	{
+		if (! empty($this->parameters[self::$UPDATED_SINCE])) {
+			return $this->parameters[self::$UPDATED_SINCE];
+		}
+		return null;
 	}
 
 	public function getFields()
@@ -193,7 +227,12 @@
 	{
 		if (! empty($this->parameters[self::$FIELDS])) {
 			$paramValue = $this->parameters[self::$FIELDS];
-			return explode(',', $paramValue);
+			$fieldNames = explode(',', $paramValue);
+			$fields = array();
+			foreach ($fieldNames as $fieldName) {
+				$fields[$fieldName] = 1;
+			}
+			return $fields;
 		} else {
 			return $defaultValue;
 		}

Modified: incubator/shindig/trunk/php/src/social-api/dataservice/RestfulCollection.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/dataservice/RestfulCollection.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/dataservice/RestfulCollection.php (original)
+++ incubator/shindig/trunk/php/src/social-api/dataservice/RestfulCollection.php Sat Sep  6 05:47:46 2008
@@ -26,6 +26,11 @@
 	public $entry;
 	public $startIndex;
 	public $totalResults;
+	
+	// boolean flags to indicate whether the requested operations were performed or declined
+	public $filtered;
+	public $sorted;
+	public $updatedSince;
 
 	public static function createFromEntry($entry)
 	{
@@ -68,4 +73,34 @@
 	{
 		$this->totalResults = $totalResults;
 	}
-}
\ No newline at end of file
+
+	public function getFiltered($filtered)
+	{
+		$this->filtered = $filtered;
+	}
+
+	public function setFiltered($filtered)
+	{
+		$this->filtered = $filtered;
+	}
+
+	public function getSorted($sorted)
+	{
+		$this->sorted = $sorted;
+	}
+
+	public function setSorted($sorted)
+	{
+		$this->sorted = $sorted;
+	}
+
+	public function getUpdatedSince($updatedSince)
+	{
+		$this->updatedSince = $updatedSince;
+	}
+
+	public function setUpdatedSince($updatedSince)
+	{
+		$this->updatedSince = $updatedSince;
+	}
+}

Modified: incubator/shindig/trunk/php/src/social-api/http/RestServlet.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/http/RestServlet.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/http/RestServlet.php (original)
+++ incubator/shindig/trunk/php/src/social-api/http/RestServlet.php Sat Sep  6 05:47:46 2008
@@ -370,7 +370,7 @@
 	{
 		$pathInfo = substr($pathInfo, 1);
 		$indexOfNextPathSeparator = strpos($pathInfo, "/");
-		return $indexOfNextPathSeparator != - 1 ? substr($pathInfo, 0, $indexOfNextPathSeparator) : $pathInfo;
+		return $indexOfNextPathSeparator !== false ? substr($pathInfo, 0, $indexOfNextPathSeparator) : $pathInfo;
 	}
 
 	private function outputError(ResponseItem $response)

Modified: incubator/shindig/trunk/php/src/social-api/opensocial/model/Address.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/opensocial/model/Address.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/opensocial/model/Address.php (original)
+++ incubator/shindig/trunk/php/src/social-api/opensocial/model/Address.php Sat Sep  6 05:47:46 2008
@@ -22,22 +22,22 @@
  * http://code.google.com/apis/opensocial/docs/0.7/reference/opensocial.Address.Field.html
  *
  */
-class Address {
+class Address implements ComplexField {
 	public $country;
-	public $extendedAddress;
 	public $latitude;
 	public $longitude;
 	public $locality;
-	public $poBox;
 	public $postalCode;
 	public $region;
 	public $streetAddress;
 	public $type;
-	public $unstructuredAddress;
+	public $formatted;
+	public $primary;
 
-	public function __construct($unstructuredAddress)
+	public function __construct($formatted, $primary = null)
 	{
-		$this->unstructuredAddress = $unstructuredAddress;
+		$this->formatted = $formatted;
+		$this->primary = $primary;
 	}
 
 	public function getCountry()
@@ -50,16 +50,6 @@
 		$this->country = $country;
 	}
 
-	public function getExtendedAddress()
-	{
-		return $this->extendedAddress;
-	}
-
-	public function setExtendedAddress($extendedAddress)
-	{
-		$this->extendedAddress = $extendedAddress;
-	}
-
 	public function getLatitude()
 	{
 		return $this->latitude;
@@ -90,16 +80,6 @@
 		$this->longitude = $longitude;
 	}
 
-	public function getPoBox()
-	{
-		return $this->poBox;
-	}
-
-	public function setPoBox($poBox)
-	{
-		$this->poBox = $poBox;
-	}
-
 	public function getPostalCode()
 	{
 		return $this->postalCode;
@@ -140,14 +120,28 @@
 		$this->type = $type;
 	}
 
-	public function getUnstructuredAddress()
+	public function getFormatted()
+	{
+		return $this->formatted;
+	}
+
+	public function setFormatted($formatted)
 	{
-		return $this->unstructuredAddress;
+		$this->formatted = $formatted;
 	}
 
-	public function setUnstructuredAddress($unstructuredAddress)
+	public function getPrimary()
 	{
-		$this->unstructuredAddress = $unstructuredAddress;
+		return $this->primary;
 	}
 
+	public function setPrimary($primary)
+	{
+		$this->primary = $primary;
+	}
+
+	public function getPrimarySubValue()
+	{
+		return $this->getFormatted();
+	}
 }

Modified: incubator/shindig/trunk/php/src/social-api/opensocial/model/BodyType.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/opensocial/model/BodyType.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/opensocial/model/BodyType.php (original)
+++ incubator/shindig/trunk/php/src/social-api/opensocial/model/BodyType.php Sat Sep  6 05:47:46 2008
@@ -22,7 +22,7 @@
  * http://code.google.com/apis/opensocial/docs/0.7/reference/opensocial.BodyType.Field.html
  *
  */
-class BodyType {
+class BodyType implements ComplexField {
 	public $build;
 	public $eyeColor;
 	public $hairColor;
@@ -78,4 +78,10 @@
 	{
 		$this->weight = $weight;
 	}
+
+	public function getPrimarySubValue()
+	{
+		// FIXME: is primary sub-field specified for bodyType in the spec??
+		return $this->getBuild(); 
+	}
 }

Modified: incubator/shindig/trunk/php/src/social-api/opensocial/model/Email.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/opensocial/model/Email.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/opensocial/model/Email.php (original)
+++ incubator/shindig/trunk/php/src/social-api/opensocial/model/Email.php Sat Sep  6 05:47:46 2008
@@ -22,33 +22,4 @@
  * http://code.google.com/apis/opensocial/docs/0.7/reference/opensocial.Email.Field.html
  *
  */
-class Email {
-	public $address;
-	public $type;
-
-	public function __construct($address, $type)
-	{
-		$this->address = $address;
-		$this->type = $type;
-	}
-
-	public function getAddress()
-	{
-		return $this->address;
-	}
-
-	public function setAddress($address)
-	{
-		$this->address = $address;
-	}
-
-	public function getType()
-	{
-		return $this->type;
-	}
-
-	public function setType($type)
-	{
-		$this->type = $type;
-	}
-}
+class Email extends ListField {}

Modified: incubator/shindig/trunk/php/src/social-api/opensocial/model/Enum.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/opensocial/model/Enum.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/opensocial/model/Enum.php (original)
+++ incubator/shindig/trunk/php/src/social-api/opensocial/model/Enum.php Sat Sep  6 05:47:46 2008
@@ -26,7 +26,7 @@
  *
  */
 
-abstract class Enum {
+abstract class Enum implements ComplexField {
 	public $displayValue;
 	public $key;
 	public $values = array();
@@ -38,7 +38,7 @@
 				// case of mixing key <> display value, correct it
 				$key = array_search($key, $this->values);
 			} else {
-				throw new Exception("Invalid Enum key");
+				throw new Exception("Invalid Enum key: $key");
 			}
 		}
 		$this->key = $key;
@@ -60,6 +60,10 @@
 	{
 		return $this->jsonString;
 	}
+
+  public function getPrimarySubValue() {
+    return $this->key;
+  }
 }
 
 /**

Modified: incubator/shindig/trunk/php/src/social-api/opensocial/model/Name.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/opensocial/model/Name.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/opensocial/model/Name.php (original)
+++ incubator/shindig/trunk/php/src/social-api/opensocial/model/Name.php Sat Sep  6 05:47:46 2008
@@ -22,27 +22,27 @@
  * http://code.google.com/apis/opensocial/docs/0.7/reference/opensocial.Name.Field.html
  *
  */
-class Name {
+class Name implements ComplexField {
 	public $additionalName;
 	public $familyName;
 	public $givenName;
 	public $honorificPrefix;
 	public $honorificSuffix;
-	public $unstructured;
+	public $formatted;
 
-	public function __construct($unstructured)
+	public function __construct($formatted)
 	{
-		$this->unstructured = $unstructured;
+		$this->formatted = $formatted;
 	}
 
-	public function getUnstructured()
+	public function getFormatted()
 	{
-		return $this->unstructured;
+		return $this->formatted;
 	}
 
-	public function setUnstructured($unstructured)
+	public function setFormatted($formatted)
 	{
-		$this->unstructured = $unstructured;
+		$this->formatted = $formatted;
 	}
 
 	public function getAdditionalName()
@@ -94,4 +94,9 @@
 	{
 		$this->honorificSuffix = $honorificSuffix;
 	}
+
+	public function getPrimarySubValue()
+	{
+		return $this->getFormatted();
+	}
 }

Modified: incubator/shindig/trunk/php/src/social-api/opensocial/model/Organization.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/opensocial/model/Organization.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/opensocial/model/Organization.php (original)
+++ incubator/shindig/trunk/php/src/social-api/opensocial/model/Organization.php Sat Sep  6 05:47:46 2008
@@ -22,18 +22,26 @@
  * http://code.google.com/apis/opensocial/docs/0.7/reference/opensocial.Organization.Field.html
  *
  */
-class Organization {
+class Organization implements ComplexField {
 	public $address;
 	public $description;
 	public $endDate;
 	public $field;
 	public $name;
+	public $primary;
 	public $salary;
 	public $startDate;
 	public $subField;
 	public $title;
+	public $type;
 	public $webpage;
 
+  public function __construct($name, $primary = null)
+  {
+    $this->name = $name;
+    $this->primary = $primary;
+  }
+
 	public function getAddress()
 	{
 		return $this->address;
@@ -124,6 +132,16 @@
 		$this->title = $title;
 	}
 
+	public function getType()
+	{
+		return $this->type;
+	}
+
+	public function setType($type)
+	{
+		$this->type = $type;
+	}
+
 	public function getWebpage()
 	{
 		return $this->webpage;
@@ -134,4 +152,17 @@
 		$this->webpage = $webpage;
 	}
 
+	public function getPrimary()
+	{
+		return $this->primary;
+	}
+
+	public function setPrimary($primary)
+	{
+		$this->primary = $primary;
+	}
+
+  public function getPrimarySubValue() {
+    return $this->getName();
+  }
 }

Modified: incubator/shindig/trunk/php/src/social-api/opensocial/model/Person.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/opensocial/model/Person.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/opensocial/model/Person.php (original)
+++ incubator/shindig/trunk/php/src/social-api/opensocial/model/Person.php Sat Sep  6 05:47:46 2008
@@ -24,15 +24,17 @@
  */
 class Person {
 	public $aboutMe;
+	public $accounts;
 	public $activities;
 	public $addresses;
 	public $age;
+	public $birthday;
 	public $bodyType;
 	public $books;
 	public $cars;
 	public $children;
 	public $currentLocation;
-	public $dateOfBirth;
+	public $displayName;
 	public $drinker;
 	public $emails;
 	public $ethnicity;
@@ -44,19 +46,21 @@
 	public $heroes;
 	public $humor;
 	public $id;
+	public $ims;
 	public $interests;
 	public $jobInterests;
-	public $jobs;
 	public $languagesSpoken;
 	public $livingArrangement;
 	public $lookingFor;
 	public $movies;
 	public $music;
+	public $organizations;
 	public $name;
 	public $networkPresence;
 	public $nickname;
 	public $pets;
 	public $phoneNumbers;
+	public $photos;
 	public $politicalViews;
 	public $profileSong;
 	public $profileUrl;
@@ -66,14 +70,13 @@
 	public $religion;
 	public $romance;
 	public $scaredOf;
-	public $schools;
 	public $sexualOrientation;
 	public $smoker;
 	public $sports;
 	public $status;
 	public $tags;
 	public $thumbnailUrl;
-	public $timeZone;
+	public $utcOffset;
 	public $turnOffs;
 	public $turnOns;
 	public $tvShows;
@@ -89,6 +92,27 @@
 		$this->name = $name;
 	}
 
+	private function setFieldImpl($fieldName, $value)
+	{
+		// treat empty singular/plural fields as null so they don't pollute the output
+		if ($value == '' || (is_array($value) && ! count($value))) {
+			$value = null;
+		}
+		$this->$fieldName = $value;
+	}
+
+	/** 
+	 * Returns the field value for the given fieldName, if present.
+	 * @param $fieldName name of the contact field, e.g. "displayName"
+	 */
+	public function getFieldByName($fieldName)
+	{
+		if (isset($this->$fieldName)) {
+			return $this->$fieldName;
+		}
+		return null;
+	}
+
 	public function getAboutMe()
 	{
 		return $this->aboutMe;
@@ -96,7 +120,17 @@
 
 	public function setAboutMe($aboutMe)
 	{
-		$this->aboutMe = $aboutMe;
+		$this->setFieldImpl('aboutMe', $aboutMe);
+	}
+
+	public function getAccounts()
+	{
+		return $this->accounts;
+	}
+
+	public function setAccounts($accounts)
+	{
+		$this->setFieldImpl('accounts', $accounts);
 	}
 
 	public function getActivities()
@@ -106,7 +140,7 @@
 
 	public function setActivities($activities)
 	{
-		$this->activities = $activities;
+		$this->setFieldImpl('activities', $activities);
 	}
 
 	public function getAddresses()
@@ -116,7 +150,7 @@
 
 	public function setAddresses($addresses)
 	{
-		$this->addresses = $addresses;
+		$this->setFieldImpl('addresses', $addresses);
 	}
 
 	public function getAge()
@@ -126,7 +160,18 @@
 
 	public function setAge($age)
 	{
-		$this->age = $age;
+		$this->setFieldImpl('age', $age);
+	}
+
+	public function getBirthday()
+	{
+		return $this->birthday;
+	}
+
+	public function setBirthday($birthday)
+	{
+		// TODO: enforce YYYY-MM-DD format here?
+		$this->setFieldImpl('birthday', $birthday);
 	}
 
 	public function getBodyType()
@@ -136,7 +181,7 @@
 
 	public function setBodyType($bodyType)
 	{
-		$this->bodyType = $bodyType;
+		$this->setFieldImpl('bodyType', $bodyType);
 	}
 
 	public function getBooks()
@@ -146,7 +191,7 @@
 
 	public function setBooks($books)
 	{
-		$this->books = $books;
+		$this->setFieldImpl('books', $books);
 	}
 
 	public function getCars()
@@ -156,7 +201,7 @@
 
 	public function setCars($cars)
 	{
-		$this->cars = $cars;
+		$this->setFieldImpl('cars', $cars);
 	}
 
 	public function getChildren()
@@ -166,7 +211,7 @@
 
 	public function setChildren($children)
 	{
-		$this->children = $children;
+		$this->setFieldImpl('children', $children);
 	}
 
 	public function getCurrentLocation()
@@ -176,17 +221,17 @@
 
 	public function setCurrentLocation($currentLocation)
 	{
-		$this->currentLocation = $currentLocation;
+		$this->setFieldImpl('currentLocation', $currentLocation);
 	}
 
-	public function getDateOfBirth()
+	public function getDisplayName()
 	{
-		return $this->dateOfBirth;
+		return $this->displayName;
 	}
 
-	public function setDateOfBirth($dateOfBirth)
+	public function setDisplayName($displayName)
 	{
-		$this->dateOfBirth = $dateOfBirth;
+		$this->setFieldImpl('displayName', $displayName);
 	}
 
 	public function getDrinker()
@@ -194,9 +239,9 @@
 		return $this->drinker;
 	}
 
-	public function setDrinker($newDrinker)
+	public function setDrinker($drinker)
 	{
-		$this->drinker = new EnumDrinker($newDrinker);
+		$this->setFieldImpl('drinker', new EnumDrinker($drinker));
 	}
 
 	public function getEmails()
@@ -206,7 +251,7 @@
 
 	public function setEmails($emails)
 	{
-		$this->emails = $emails;
+		$this->setFieldImpl('emails', $emails);
 	}
 
 	public function getEthnicity()
@@ -216,7 +261,7 @@
 
 	public function setEthnicity($ethnicity)
 	{
-		$this->ethnicity = $ethnicity;
+		$this->setFieldImpl('ethnicity', $ethnicity);
 	}
 
 	public function getFashion()
@@ -226,7 +271,7 @@
 
 	public function setFashion($fashion)
 	{
-		$this->fashion = $fashion;
+		$this->setFieldImpl('fashion', $fashion);
 	}
 
 	public function getFood()
@@ -236,7 +281,7 @@
 
 	public function setFood($food)
 	{
-		$this->food = $food;
+		$this->setFieldImpl('food', $food);
 	}
 
 	public function getGender()
@@ -244,9 +289,9 @@
 		return $this->gender;
 	}
 
-	public function setGender($newGender)
+	public function setGender($gender)
 	{
-		$this->gender = new EnumGender($newGender);
+		$this->setFieldImpl('gender', $gender);
 	}
 
 	public function getHappiestWhen()
@@ -256,7 +301,7 @@
 
 	public function setHappiestWhen($happiestWhen)
 	{
-		$this->happiestWhen = $happiestWhen;
+		$this->setFieldImpl('happiestWhen', $happiestWhen);
 	}
 
 	public function getHeroes()
@@ -266,7 +311,7 @@
 
 	public function setHeroes($heroes)
 	{
-		$this->heroes = $heroes;
+		$this->setFieldImpl('heroes', $heroes);
 	}
 
 	public function getHasApp()
@@ -276,7 +321,7 @@
 
 	public function setHasApp($hasApp)
 	{
-		$this->hasApp = $hasApp;
+		$this->setFieldImpl('hasApp', $hasApp);
 	}
 
 	public function getHumor()
@@ -286,7 +331,7 @@
 
 	public function setHumor($humor)
 	{
-		$this->humor = $humor;
+		$this->setFieldImpl('humor', $humor);
 	}
 
 	public function getId()
@@ -296,37 +341,37 @@
 
 	public function setId($id)
 	{
-		$this->id = $id;
+		$this->setFieldImpl('id', $id);
 	}
 
-	public function getInterests()
+	public function getIms()
 	{
-		return $this->interests;
+		return $this->ims;
 	}
 
-	public function setInterests($interests)
+	public function setIms($ims)
 	{
-		$this->interests = $interests;
+		$this->setFieldImpl('ims', $ims);
 	}
 
-	public function getJobInterests()
+	public function getInterests()
 	{
-		return $this->jobInterests;
+		return $this->interests;
 	}
 
-	public function setJobInterests($jobInterests)
+	public function setInterests($interests)
 	{
-		$this->jobInterests = $jobInterests;
+		$this->setFieldImpl('interests', $interests);
 	}
 
-	public function getJobs()
+	public function getJobInterests()
 	{
-		return $this->jobs;
+		return $this->jobInterests;
 	}
 
-	public function setJobs($jobs)
+	public function setJobInterests($jobInterests)
 	{
-		$this->jobs = $jobs;
+		$this->setFieldImpl('jobInterests', $jobInterests);
 	}
 
 	public function getLanguagesSpoken()
@@ -336,7 +381,7 @@
 
 	public function setLanguagesSpoken($languagesSpoken)
 	{
-		$this->languagesSpoken = $languagesSpoken;
+		$this->setFieldImpl('languagesSpoken', $languagesSpoken);
 	}
 
 	public function getLivingArrangement()
@@ -346,7 +391,7 @@
 
 	public function setLivingArrangement($livingArrangement)
 	{
-		$this->livingArrangement = $livingArrangement;
+		$this->setFieldImpl('livingArrangement', $livingArrangement);
 	}
 
 	public function getLookingFor()
@@ -356,7 +401,7 @@
 
 	public function setLookingFor($lookingFor)
 	{
-		$this->lookingFor = new EnumLookingFor($lookingFor);
+		$this->setFieldImpl('lookingFor', new EnumLookingFor($lookingFor));
 	}
 
 	public function getMovies()
@@ -366,7 +411,7 @@
 
 	public function setMovies($movies)
 	{
-		$this->movies = $movies;
+		$this->setFieldImpl('movies', $movies);
 	}
 
 	public function getMusic()
@@ -376,7 +421,7 @@
 
 	public function setMusic($music)
 	{
-		$this->music = $music;
+		$this->setFieldImpl('music', $music);
 	}
 
 	public function getName()
@@ -386,7 +431,7 @@
 
 	public function setName($name)
 	{
-		$this->name = $name;
+		$this->setFieldImpl('name', $name);
 	}
 
 	public function getNetworkPresence()
@@ -396,7 +441,7 @@
 
 	public function setNetworkPresence($networkPresence)
 	{
-		$this->networkPresence = new EnumPresence($networkPresence);
+		$this->setFieldImpl('networkPresence', new EnumPresence($networkPresence));
 	}
 
 	public function getNickname()
@@ -407,6 +452,17 @@
 	public function setNickname($nickname)
 	{
 		$this->nickname = $nickname;
+		$this->setFieldImpl('nickname', $nickname);
+	}
+
+	public function getOrganizations()
+	{
+		return $this->organizations;
+	}
+
+	public function setOrganizations($organizations)
+	{
+		$this->setFieldImpl('organizations', $organizations);
 	}
 
 	public function getPets()
@@ -416,7 +472,7 @@
 
 	public function setPets($pets)
 	{
-		$this->pets = $pets;
+		$this->setFieldImpl('pets', $pets);
 	}
 
 	public function getPhoneNumbers()
@@ -426,7 +482,17 @@
 
 	public function setPhoneNumbers($phoneNumbers)
 	{
-		$this->phoneNumbers = $phoneNumbers;
+		$this->setFieldImpl('phoneNumbers', $phoneNumbers);
+	}
+
+	public function getPhotos()
+	{
+		return $this->photos;
+	}
+
+	public function setPhotos($photos)
+	{
+		$this->setFieldImpl('photos', $photos);
 	}
 
 	public function getPoliticalViews()
@@ -436,7 +502,7 @@
 
 	public function setPoliticalViews($politicalViews)
 	{
-		$this->politicalViews = $politicalViews;
+		$this->setFieldImpl('politicalViews', $politicalViews);
 	}
 
 	public function getProfileSong()
@@ -446,7 +512,7 @@
 
 	public function setProfileSong($profileSong)
 	{
-		$this->profileSong = $profileSong;
+		$this->setFieldImpl('profileSong', $profileSong);
 	}
 
 	public function getProfileUrl()
@@ -456,7 +522,7 @@
 
 	public function setProfileUrl($profileUrl)
 	{
-		$this->profileUrl = $profileUrl;
+		$this->setFieldImpl('profileUrl', $profileUrl);
 	}
 
 	public function getProfileVideo()
@@ -466,7 +532,7 @@
 
 	public function setProfileVideo($profileVideo)
 	{
-		$this->profileVideo = $profileVideo;
+		$this->setFieldImpl('profileVideo', $profileVideo);
 	}
 
 	public function getQuotes()
@@ -476,7 +542,7 @@
 
 	public function setQuotes($quotes)
 	{
-		$this->quotes = $quotes;
+		$this->setFieldImpl('quotes', $quotes);
 	}
 
 	public function getRelationshipStatus()
@@ -486,7 +552,7 @@
 
 	public function setRelationshipStatus($relationshipStatus)
 	{
-		$this->relationshipStatus = $relationshipStatus;
+		$this->setFieldImpl('relationshipStatus', $relationshipStatus);
 	}
 
 	public function getReligion()
@@ -506,7 +572,7 @@
 
 	public function setRomance($romance)
 	{
-		$this->romance = $romance;
+		$this->setFieldImpl('romance', $romance);
 	}
 
 	public function getScaredOf()
@@ -516,17 +582,7 @@
 
 	public function setScaredOf($scaredOf)
 	{
-		$this->scaredOf = $scaredOf;
-	}
-
-	public function getSchools()
-	{
-		return $this->schools;
-	}
-
-	public function setSchools($schools)
-	{
-		$this->schools = $schools;
+		$this->setFieldImpl('scaredOf', $scaredOf);
 	}
 
 	public function getSexualOrientation()
@@ -536,7 +592,7 @@
 
 	public function setSexualOrientation($sexualOrientation)
 	{
-		$this->sexualOrientation = $sexualOrientation;
+		$this->setFieldImpl('sexualOrientation', $sexualOrientation);
 	}
 
 	public function getSmoker()
@@ -544,9 +600,9 @@
 		return $this->smoker;
 	}
 
-	public function setSmoker($newSmoker)
+	public function setSmoker($smoker)
 	{
-		$this->smoker = new EnumSmoker($newSmoker);
+		$this->setFieldImpl('smoker', new EnumSmoker($smoker));
 	}
 
 	public function getSports()
@@ -556,7 +612,7 @@
 
 	public function setSports($sports)
 	{
-		$this->sports = $sports;
+		$this->setFieldImpl('sports', $sports);
 	}
 
 	public function getStatus()
@@ -566,7 +622,7 @@
 
 	public function setStatus($status)
 	{
-		$this->status = $status;
+		$this->setFieldImpl('status', $status);
 	}
 
 	public function getTags()
@@ -576,7 +632,7 @@
 
 	public function setTags($tags)
 	{
-		$this->tags = $tags;
+		$this->setFieldImpl('tags', $tags);
 	}
 
 	public function getThumbnailUrl()
@@ -586,17 +642,18 @@
 
 	public function setThumbnailUrl($thumbnailUrl)
 	{
-		$this->thumbnailUrl = $thumbnailUrl;
+		$this->setFieldImpl('thumbnailUrl', $thumbnailUrl);
 	}
 
-	public function getTimeZone()
+	public function getUtcOffset()
 	{
-		return $this->timeZone;
+		return $this->utcOffset;
 	}
 
-	public function setTimeZone($timeZone)
+	public function setUtcOffset($utcOffset)
 	{
-		$this->timeZone = $timeZone;
+		// TODO: validate +00:00 format here?
+		$this->setFieldImpl('utcOffset', $utcOffset);
 	}
 
 	public function getTurnOffs()
@@ -606,7 +663,7 @@
 
 	public function setTurnOffs($turnOffs)
 	{
-		$this->turnOffs = $turnOffs;
+		$this->setFieldImpl('turnOffs', $turnOffs);
 	}
 
 	public function getTurnOns()
@@ -616,7 +673,7 @@
 
 	public function setTurnOns($turnOns)
 	{
-		$this->turnOns = $turnOns;
+		$this->setFieldImpl('turnOns', $turnOns);
 	}
 
 	public function getTvShows()
@@ -626,7 +683,7 @@
 
 	public function setTvShows($tvShows)
 	{
-		$this->tvShows = $tvShows;
+		$this->setFieldImpl('tvShows', $tvShows);
 	}
 
 	public function getUrls()
@@ -636,7 +693,7 @@
 
 	public function setUrls($urls)
 	{
-		$this->urls = $urls;
+		$this->setFieldImpl('urls', $urls);
 	}
 
 	public function getIsOwner()
@@ -646,7 +703,7 @@
 
 	public function setIsOwner($isOwner)
 	{
-		$this->isOwner = $isOwner;
+		$this->setFieldImpl('isOwner', $isOwner);
 	}
 
 	public function getIsViewer()
@@ -656,6 +713,6 @@
 
 	public function setIsViewer($isViewer)
 	{
-		$this->isViewer = $isViewer;
+		$this->setFieldImpl('isViewer', $isViewer);
 	}
 }

Modified: incubator/shindig/trunk/php/src/social-api/opensocial/model/Phone.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/opensocial/model/Phone.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/opensocial/model/Phone.php (original)
+++ incubator/shindig/trunk/php/src/social-api/opensocial/model/Phone.php Sat Sep  6 05:47:46 2008
@@ -22,33 +22,4 @@
  * http://code.google.com/apis/opensocial/docs/0.7/reference/opensocial.Phone.Field.html
  *
  */
-class Phone {
-	public $number;
-	public $type;
-
-	public function __construct($number, $type)
-	{
-		$this->number = $number;
-		$this->type = $type;
-	}
-
-	public function getNumber()
-	{
-		return $this->number;
-	}
-
-	public function setNumber($number)
-	{
-		$this->number = $number;
-	}
-
-	public function getType()
-	{
-		return $this->type;
-	}
-
-	public function setType($type)
-	{
-		$this->type = $type;
-	}
-}
+class Phone extends ListField {}

Modified: incubator/shindig/trunk/php/src/social-api/opensocial/model/Url.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/opensocial/model/Url.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/opensocial/model/Url.php (original)
+++ incubator/shindig/trunk/php/src/social-api/opensocial/model/Url.php Sat Sep  6 05:47:46 2008
@@ -21,27 +21,11 @@
  * see
  * http://code.google.com/apis/opensocial/docs/0.7/reference/opensocial.Url.Field.html
  */
-class Url {
-	public $address;
+class Url extends ListField {
+	public $value;
 	public $linkText;
 	public $type;
-
-	public function __construct($address, $linkText, $type)
-	{
-		$this->address = $address;
-		$this->linkText = $linkText;
-		$this->type = $type;
-	}
-
-	public function getAddress()
-	{
-		return $this->address;
-	}
-
-	public function setAddress($address)
-	{
-		$this->address = $address;
-	}
+	public $primary;
 
 	public function getLinkText()
 	{
@@ -52,15 +36,4 @@
 	{
 		$this->linkText = $linkText;
 	}
-
-	public function getType()
-	{
-		return $this->type;
-	}
-
-	public function setType($type)
-	{
-		$this->type = $type;
-	}
-
 }

Modified: incubator/shindig/trunk/php/src/social-api/samplecontainer/BasicAppDataService.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/samplecontainer/BasicAppDataService.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/samplecontainer/BasicAppDataService.php (original)
+++ incubator/shindig/trunk/php/src/social-api/samplecontainer/BasicAppDataService.php Sat Sep  6 05:47:46 2008
@@ -21,14 +21,14 @@
 
 	public function deletePersonData(UserId $userId, GroupId $groupId, $fields, $appId, SecurityToken $token)
 	{
-		foreach ($fields as $key) {
+		foreach ($fields as $key => $present) {
 			if (! BasicAppDataService::isValidKey($key)) {
 				return new ResponseItem(BAD_REQUEST, "The person app data key had invalid characters", null);
 			}
 		}
 		switch ($groupId->getType()) {
 			case 'self':
-				foreach ($fields as $key) {
+				foreach ($fields as $key => $present) {
 					XmlStateFileFetcher::get()->deleteAppData($userId->getUserId($token), $key);
 				}
 				break;
@@ -76,14 +76,14 @@
 
 	public function updatePersonData(UserID $userId, GroupId $groupId, $fields, $values, $appId, SecurityToken $token)
 	{
-		foreach ($fields as $key) {
+		foreach ($fields as $key => $present) {
 			if (! BasicAppDataService::isValidKey($key)) {
 				return new ResponseItem(BAD_REQUEST, "The person app data key had invalid characters", null);
 			}
 		}
 		switch ($groupId->getType()) {
 			case 'self':
-				foreach ($fields as $key) {
+				foreach ($fields as $key => $present) {
 					$value = isset($values[$key]) ? @$values[$key] : null;
 					XmlStateFileFetcher::get()->setAppData($userId->getUserId($token), $key, $value);
 				}

Modified: incubator/shindig/trunk/php/src/social-api/samplecontainer/BasicPeopleService.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/samplecontainer/BasicPeopleService.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/samplecontainer/BasicPeopleService.php (original)
+++ incubator/shindig/trunk/php/src/social-api/samplecontainer/BasicPeopleService.php Sat Sep  6 05:47:46 2008
@@ -29,9 +29,9 @@
 		return ($name < $name1) ? - 1 : 1;
 	}
 
-	public function getPerson($userId, $groupId, $profileDetails, SecurityToken $token)
+	public function getPerson($userId, $groupId, $fields, SecurityToken $token)
 	{
-		$person = $this->getPeople($userId, $groupId, null, null, null, null, $profileDetails, null, $token);
+		$person = $this->getPeople($userId, $groupId, new CollectionOptions(), $fields, $token);
 		// return of getPeople is a ResponseItem(RestfulCollection(ArrayOfPeople)), disassemble to return just one person
 		$person = $person->getResponse()->getEntry();
 		if (is_array($person) && count($person) == 1) {
@@ -40,8 +40,14 @@
 		return new ResponseItem(NOT_FOUND, "Person not found", null);
 	}
 
-	public function getPeople($userId, $groupId, $sortOrder, $filter, $first, $max, $profileDetails, $networkDistance, SecurityToken $token)
+	public function getPeople($userId, $groupId, $options, $fields, SecurityToken $token)
 	{
+		$sortOrder = $options->getSortOrder();
+		$filter = $options->getFilterBy();
+		$first = $options->getStartIndex();
+		$max = $options->getCount();
+		$networkDistance = $options->getNetworkDistance();
+		
 		$ids = array();
 		$group = is_object($groupId) ? $groupId->getType() : '';
 		switch ($group) {
@@ -76,12 +82,12 @@
 				if (! $token->isAnonymous() && $id == $token->getOwnerId()) {
 					$person->setIsOwner(true);
 				}
-				if (is_array($profileDetails) && count($profileDetails) && ! in_array('all', $profileDetails)) {
+				if (! isset($fields['@all'])) {
 					$newPerson = array();
 					$newPerson['isOwner'] = $person->isOwner;
 					$newPerson['isViewer'] = $person->isViewer;
 					$newPerson['name'] = $person->name;
-					foreach ($profileDetails as $field) {
+					foreach ($fields as $field => $present) {
 						if (isset($person->$field) && ! isset($newPerson[$field])) {
 							$newPerson[$field] = $person->$field;
 						}
@@ -104,5 +110,4 @@
 		$collection = new RestfulCollection($people, $first, $totalSize);
 		return new ResponseItem(null, null, $collection);
 	}
-
 }

Modified: incubator/shindig/trunk/php/test/social-api/JsonDbOpensocialServiceTest.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/test/social-api/JsonDbOpensocialServiceTest.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/test/social-api/JsonDbOpensocialServiceTest.php (original)
+++ incubator/shindig/trunk/php/test/social-api/JsonDbOpensocialServiceTest.php Sat Sep  6 05:47:46 2008
@@ -1,4 +1,4 @@
-<?
+<?php
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -59,12 +59,18 @@
 		$filter = null;
 		$first = null;
 		$max = null;
-		$profileDetails = array('id', 'name', 'thumbnailUrl');
+		$fields = array('id' => 1, 'name' => 1, 'thumbnailUrl' => 1);
 		$networkDistance = null;
 		
 		//With existing data
 		$token = BasicSecurityToken::createFromValues('john.doe', 'john.doe', 'app', 'domain', 'appUrl', '1');
-		$responseItem = $this->JsonDbOpensocialService->getPeople($userId, $groupId, $sortOrder, $filter, $first, $max, $profileDetails, $networkDistance, $token);
+		$options = new CollectionOptions();
+		$options->setSortBy($sortOrder);
+		$options->setFilterBy($filter);
+		$options->setStartIndex($first);
+		$options->setCount($max);
+		$options->setNetworkDistance($networkDistance);
+		$responseItem = $this->JsonDbOpensocialService->getPeople($userId, $groupId, $options, $fields, $token);
 		$response = $responseItem->getResponse();
 		$entry = $response->getEntry();
 		$this->assertEquals(1, $response->getTotalResults());
@@ -76,7 +82,7 @@
 		
 		//With non existing data
 		$token = BasicSecurityToken::createFromValues('notexists', 'notexists', 'app', 'domain', 'appUrl', '1');
-		$responseItem = $this->JsonDbOpensocialService->getPeople($userId, $groupId, $sortOrder, $filter, $first, $max, $profileDetails, $networkDistance, $token);
+		$responseItem = $this->JsonDbOpensocialService->getPeople($userId, $groupId, $options, $fields, $token);
 		$response = $responseItem->getResponse();
 		$this->assertEquals(0, $response->getTotalResults());
 		$this->assertEquals(0, count($response->getEntry()));
@@ -89,11 +95,11 @@
 	{
 		$userId = new UserId('viewer', null);
 		$groupId = new GroupId('self', null);
-		$profileDetails = array('id', 'name', 'thumbnailUrl');
+		$fields = array('id' => 1, 'name' => 1, 'thumbnailUrl' => 1);
 		
 		//With existing data
 		$token = BasicSecurityToken::createFromValues('john.doe', 'john.doe', 'app', 'domain', 'appUrl', '1');
-		$person = $this->JsonDbOpensocialService->getPerson($userId, $groupId, $profileDetails, $token);
+		$person = $this->JsonDbOpensocialService->getPerson($userId, $groupId, $fields, $token);
 		$response = $person->getResponse();
 		$this->assertNotNull($response);
 		$this->assertEquals('john.doe', $response['id']);
@@ -103,7 +109,7 @@
 		
 		//With non existing data
 		$token = BasicSecurityToken::createFromValues('notexists', 'notexists', 'app', 'domain', 'appUrl', '1');
-		$person = $this->JsonDbOpensocialService->getPerson($userId, $groupId, $profileDetails, $token);
+		$person = $this->JsonDbOpensocialService->getPerson($userId, $groupId, $fields, $token);
 		$response = $person->getResponse();
 		$this->assertEquals('NOT_FOUND', $person->getError());
 		$this->assertEquals('Person not found', $person->getErrorMessage());
@@ -117,12 +123,12 @@
 	{
 		$userId = new UserId('viewer', null);
 		$groupId = new GroupId('self', null);
-		$profileDetails = array('count', 'size');
+		$fields = array('count' => 1, 'size' => 1);
 		$appId = 'app';
 		
 		//With existing data
 		$token = BasicSecurityToken::createFromValues('canonical', 'canonical', 'app', 'domain', 'appUrl', '1');
-		$responseItem = $this->JsonDbOpensocialService->getPersonData($userId, $groupId, $profileDetails, $appId, $token);
+		$responseItem = $this->JsonDbOpensocialService->getPersonData($userId, $groupId, $fields, $appId, $token);
 		$response = $responseItem->getResponse();
 		$entry = $response->getEntry();
 		$this->assertEquals(1, $response->getTotalResults());
@@ -132,7 +138,7 @@
 		
 		//With non existing data
 		$token = BasicSecurityToken::createFromValues('notexists', 'notexists', 'app', 'domain', 'appUrl', '1');
-		$responseItem = $this->JsonDbOpensocialService->getPersonData($userId, $groupId, $profileDetails, $appId, $token);
+		$responseItem = $this->JsonDbOpensocialService->getPersonData($userId, $groupId, $fields, $appId, $token);
 		$response = $responseItem->getResponse();
 		$this->assertEquals(0, $response->getTotalResults());
 		$this->assertEquals(0, count($response->getEntry()));
@@ -145,17 +151,17 @@
 	{
 		$userId = new UserId('viewer', null);
 		$groupId = new GroupId('self', null);
-		$profileDetails = array('count', 'size');
+		$fields = array('count' => 1, 'size' => 1);
 		$values = array();
 		$values['count'] = 10;
 		$values['size'] = 500;
 		$appId = 'app';
 		
-/*
+	/*
 		//With existing data
 		$token = BasicSecurityToken::createFromValues('canonical', 'canonical', 'app', 'domain', 'appUrl', '1');
-		$this->JsonDbOpensocialService->updatePersonData($userId, $groupId, $profileDetails, $values, $appId, $token);
-		$responseItem = $this->JsonDbOpensocialService->getPersonData($userId, $groupId, $profileDetails, $appId, $token);
+		$this->JsonDbOpensocialService->updatePersonData($userId, $groupId, $fields, $values, $appId, $token);
+		$responseItem = $this->JsonDbOpensocialService->getPersonData($userId, $groupId, $fields, $appId, $token);
 		$response = $responseItem->getResponse();
 		$entry = $response->getEntry();
 		$this->assertEquals(1, $response->getTotalResults());
@@ -165,8 +171,8 @@
 		
 		//With non existing data
 		$token = BasicSecurityToken::createFromValues('notexists', 'notexists', 'app', 'domain', 'appUrl', '1');
-		$this->JsonDbOpensocialService->updatePersonData($userId, $groupId, $profileDetails, $values, $appId, $token);
-		$responseItem = $this->JsonDbOpensocialService->getPersonData($userId, $groupId, $profileDetails, $appId, $token);
+		$this->JsonDbOpensocialService->updatePersonData($userId, $groupId, $fields, $values, $appId, $token);
+		$responseItem = $this->JsonDbOpensocialService->getPersonData($userId, $groupId, $fields, $appId, $token);
 		$response = $responseItem->getResponse();
 		$entry = $response->getEntry();
 		$this->assertEquals(1, $response->getTotalResults());
@@ -293,7 +299,7 @@
 		$activity['mediaItems'][0]['mimeType'] = 'image';
 		$activity['mediaItems'][0]['image'] = 'http://cdn.davesdaily.com/pictures/784-awesome-hands.jpg';
 		$this->JsonDbOpensocialService->createActivity($userId, $activity, $token);
-/*		
+		/*		
 		//Validating the created activity
 		$token = BasicSecurityToken::createFromValues('john.doe', 'john.doe', 'app', 'domain', 'appUrl', '1');
 		$responseItem = $this->JsonDbOpensocialService->getActivity($userId, $groupId, 2, null, null, $token);

Modified: incubator/shindig/trunk/php/test/social-api/RestRequestItemTest.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/test/social-api/RestRequestItemTest.php?rev=692646&r1=692645&r2=692646&view=diff
==============================================================================
--- incubator/shindig/trunk/php/test/social-api/RestRequestItemTest.php (original)
+++ incubator/shindig/trunk/php/test/social-api/RestRequestItemTest.php Sat Sep  6 05:47:46 2008
@@ -34,7 +34,7 @@
 	{
 		parent::setUp();
 		$this->RestRequestItem = new RestRequestItem();
-		$url = '/people/@viewer/@self?fields=age,name,gender,profileUrl,thumbnailUrl,' . 'status,id&startIndex=0&count=40&orderBy=name&filterBy=all&networkDistance=1';
+		$url = '/people/@viewer/@self?fields=age,name,gender,profileUrl,thumbnailUrl,' . 'status,id&startIndex=0&count=40&sortBy=name&filterBy=all&networkDistance=1';
 		$request = array();
 		$request['url'] = $url;
 		$request['method'] = 'GET';
@@ -77,7 +77,7 @@
 	 */
 	public function testCreateRequestItemWithRequest()
 	{
-		$url = '/people/@viewer/@self?fields=age,name,gender,profileUrl,thumbnailUrl,' . 'status,id&startIndex=0&count=40&orderBy=name&filterBy=all&networkDistance=1';
+		$url = '/people/@viewer/@self?fields=age,name,gender,profileUrl,thumbnailUrl,' . 'status,id&startIndex=0&count=40&sortBy=name&filterBy=all&networkDistance=1';
 		$request = array();
 		$request['url'] = $url;
 		$request['method'] = 'GET';
@@ -92,8 +92,9 @@
 		$this->assertEquals(false, $this->RestRequestItem->getGroup());
 		$this->assertEquals('0', $this->RestRequestItem->getStartIndex());
 		$this->assertEquals('20', $this->RestRequestItem->getCount());
-		$this->assertEquals(PeopleOptions::$sortOrder, $this->RestRequestItem->getOrderBy());
-		$this->assertEquals(PeopleOptions::$filterType, $this->RestRequestItem->getFilterBy());
+		// TODO: add more robust testing of all CollectionOptions options
+		//$this->assertEquals(PeopleOptions::$sortOrder, $this->RestRequestItem->getSortBy());
+		//$this->assertEquals(PeopleOptions::$filterType, $this->RestRequestItem->getFilterBy());
 		$this->assertEquals(false, $this->RestRequestItem->getNetworkDistance());
 	}
 
@@ -203,11 +204,11 @@
 	}
 
 	/**
-	 * Tests RestRequestItem->getOrderBy()
+	 * Tests RestRequestItem->getSortBy()
 	 */
-	public function testGetOrderBy()
+	public function testGetSortBy()
 	{
-		$this->assertEquals('name', $this->RestRequestItem->getOrderBy());
+		$this->assertEquals('name', $this->RestRequestItem->getSortBy());
 	}
 
 	/**