#472 REST API: finalized the implementation of core/get_related + added the support for AttributeBlob (to manage documents and attachments)

SVN:trunk[2669]
This commit is contained in:
Romain Quetiez
2013-04-02 13:31:52 +00:00
parent 57b34d2d91
commit 3d79e3fe8f
4 changed files with 106 additions and 21 deletions

View File

@@ -909,6 +909,10 @@ class RestUtils
}
$value = DBObjectSet::FromArray($sLnkClass, $aLinks);
}
else
{
$value = $oAttDef->FromJSONToValue($value);
}
}
catch (Exception $e)
{

View File

@@ -426,6 +426,26 @@ abstract class AttributeDefinition
return (string)$sValue;
}
/**
* Helper to get a value that will be JSON encoded
* The operation is the opposite to FromJSONToValue
*/
public function GetForJSON($value)
{
// In most of the cases, that will be the expected behavior...
return $this->GetEditValue($value);
}
/**
* Helper to form a value, given JSON decoded data
* The operation is the opposite to GetForJSON
*/
public function FromJSONToValue($json)
{
// Passthrough in most of the cases
return $json;
}
/**
* Override to display the value in the GUI
*/
@@ -3322,6 +3342,11 @@ class AttributeBlob extends AttributeDefinition
public function GetDefaultValue() {return "";}
public function IsNullAllowed() {return $this->GetOptional("is_null_allowed", false);}
public function GetEditValue($sValue, $oHostObj = null)
{
return '';
}
// Facilitate things: allow the user to Set the value from a string
public function MakeRealValue($proposedValue, $oHostObj)
@@ -3450,6 +3475,44 @@ class AttributeBlob extends AttributeDefinition
{
return ''; // Not exportable in XML, or as CDATA + some subtags ??
}
/**
* Helper to get a value that will be JSON encoded
* The operation is the opposite to FromJSONToValue
*/
public function GetForJSON($value)
{
if ($value instanceOf ormDocument)
{
$aValues = array();
$aValues['data'] = base64_encode($value->GetData());
$aValues['mimetype'] = $value->GetMimeType();
$aValues['filename'] = $value->GetFileName();
}
else
{
$aValues = null;
}
return $aValues;
}
/**
* Helper to form a value, given JSON decoded data
* The operation is the opposite to GetForJSON
*/
public function FromJSONToValue($json)
{
if (isset($json->data))
{
$data = base64_decode($json->data);
$value = new ormDocument($data, $json->mimetype, $json->filename);
}
else
{
$value = null;
}
return $value;
}
}
/**

View File

@@ -99,14 +99,9 @@ class ObjectResult
$value[] = $aLnkValues;
}
}
elseif ($oAttDef->IsExternalKey())
{
$value = $oObject->Get($sAttCode);
}
else
{
// Still to be refined...
$value = $oObject->GetEditValue($sAttCode);
$value = $oAttDef->GetForJSON($oObject->Get($sAttCode));
}
}
return $value;
@@ -147,22 +142,20 @@ class RestResultWithObjects extends RestResult
* @param array $aFields An array of attribute codes. List of the attributes to be reported.
* @return void
*/
public function AddObject($iCode, $sMessage, $oObject = null, $aFields = null)
public function AddObject($iCode, $sMessage, $oObject, $aFields)
{
$oObjRes = new ObjectResult();
$oObjRes->code = $iCode;
$oObjRes->message = $sMessage;
if ($oObject)
$oObjRes->class = get_class($oObject);
foreach ($aFields as $sAttCode)
{
$oObjRes->class = get_class($oObject);
foreach ($aFields as $sAttCode)
{
$oObjRes->AddField($oObject, $sAttCode);
}
$oObjRes->AddField($oObject, $sAttCode);
}
$this->objects[] = $oObjRes;
$sObjKey = get_class($oObject).'::'.$oObject->GetKey();
$this->objects[$sObjKey] = $oObjRes;
}
}
@@ -182,7 +175,7 @@ class RestResultWithRelations extends RestResultWithObjects
{
$this->relations[$sSrcKey] = array();
}
$this->relations[$sSrcKey][] = $sDestKey;
$this->relations[$sSrcKey][] = array('key' => $sDestKey);
}
}
@@ -389,14 +382,16 @@ class CoreServices implements iRestServiceProvider
$sClass = RestUtils::GetClass($aParams, 'class');
$key = RestUtils::GetMandatoryParam($aParams, 'key');
$sRelation = RestUtils::GetMandatoryParam($aParams, 'relation');
$iMaxRecursionDepth = RestUtils::GetOptionalParam($aParams, 'depth', 20 /* = MAX_RECUSTION_DEPTH */);
$aShowFields = RestUtils::GetFieldList($sClass, $aParams, 'output_fields');
$iMaxRecursionDepth = RestUtils::GetOptionalParam($aParams, 'depth', 20 /* = MAX_RECURSION_DEPTH */);
$aShowFields = array('id', 'friendlyname');
$oObjectSet = RestUtils::GetObjectSetFromKey($sClass, $key);
$aIndexByClass = array();
while ($oObject = $oObjectSet->Fetch())
{
$aRelated = array();
$aGraph = array();
$aIndexByClass[get_class($oObject)][$oObject->GetKey()] = null;
$oResult->AddObject(0, '', $oObject, $aShowFields);
$this->GetRelatedObjects($oObject, $sRelation, $iMaxRecursionDepth, $aRelated, $aGraph);
@@ -404,15 +399,31 @@ class CoreServices implements iRestServiceProvider
{
foreach($aObjects as $oRelatedObj)
{
$aIndexByClass[get_class($oRelatedObj)][$oRelatedObj->GetKey()] = null;
$oResult->AddObject(0, '', $oRelatedObj, $aShowFields);
}
}
foreach($aGraph as $sSrcKey => $sDestKey)
foreach($aGraph as $sSrcKey => $aDestinations)
{
$oResult->AddRelation($sSrcKey, $sDestKey);
foreach ($aDestinations as $sDestKey)
{
$oResult->AddRelation($sSrcKey, $sDestKey);
}
}
}
$oResult->message = "Found: ".$oObjectSet->Count();
if (count($aIndexByClass) > 0)
{
$aStats = array();
foreach ($aIndexByClass as $sClass => $aIds)
{
$aStats[] = $sClass.'= '.count($aIds);
}
$oResult->message = "Scope: ".$oObjectSet->Count()."; Related objects: ".implode(', ', $aStats);
}
else
{
$oResult->message = "Nothing found";
}
break;
default:

View File

@@ -150,6 +150,13 @@ $aOperations = array(
),
'output_fields' => 'id, friendlyname, title, contacts_list', // list of fields to show in the results (* or a,b,c)
),
array(
'operation' => 'core/get_related', // operation code
'class' => 'Server',
'key' => 'SELECT Server',
'relation' => 'impacts', // relation code
'depth' => 4, // max recursion depth
),
);
$sUrl = "http://localhost/rest-services/webservices/rest.php?version=1.0";