Esempio n. 1
0
 private function writeOrderByEnumForType(KalturaTypeReflector $type)
 {
     $map = KAutoloader::getClassMap();
     if (!isset($map[$type->getType()])) {
         return;
     }
     $this->_txt = "";
     $parentType = $type;
     while (1) {
         $parentType = $parentType->getParentTypeReflector();
         if ($parentType === null || $parentType->isFilterable()) {
             break;
         }
     }
     $partnetClassName = $parentType ? $parentType->getType() . "OrderBy" : "KalturaStringEnum";
     $enumName = $type->getType() . "OrderBy";
     $enumPath = dirname($map[$type->getType()]) . "/filters/orderEnums/{$enumName}.php";
     $subpackage = ($type->getPackage() == 'api' ? '' : 'api.') . 'filters.enum';
     $this->appendLine("<?php");
     $this->appendLine("/**");
     $this->appendLine(" * @package " . $type->getPackage());
     $this->appendLine(" * @subpackage {$subpackage}");
     $this->appendLine(" */");
     $this->appendLine("class {$enumName} extends {$partnetClassName}");
     $this->appendLine("{");
     foreach ($type->getCurrentProperties() as $prop) {
         $filters = $prop->getFilters();
         foreach ($filters as $filter) {
             if ($filter == "order") {
                 $this->appendLine("\tconst " . $this->getOrderByConst($prop->getName()) . "_ASC = \"+" . $prop->getName() . "\";");
                 $this->appendLine("\tconst " . $this->getOrderByConst($prop->getName()) . "_DESC = \"-" . $prop->getName() . "\";");
             }
         }
     }
     $reflectionClass = new ReflectionClass($type->getType());
     if (!$type->isAbstract() && $reflectionClass->getMethod("getExtraFilters")->getDeclaringClass()->getName() === $reflectionClass->getName()) {
         $extraFilters = $type->getInstance()->getExtraFilters();
         if ($extraFilters) {
             foreach ($extraFilters as $filterFields) {
                 if (!isset($filterFields["order"])) {
                     continue;
                 }
                 $fieldName = $filterFields["order"];
                 $fieldConst = $this->getOrderByConst($fieldName);
                 $this->appendLine("\tconst {$fieldConst}_ASC = \"+{$fieldName}\";");
                 $this->appendLine("\tconst {$fieldConst}_DESC = \"-{$fieldName}\";");
             }
         }
     }
     $this->appendLine("}");
     $this->writeToFile($enumPath, $this->_txt);
 }
Esempio n. 2
0
 private function getClassElement(KalturaTypeReflector $typeReflector)
 {
     $properties = $typeReflector->getProperties();
     $classElement = $this->_doc->createElement("class");
     $classElement->setAttribute("name", $typeReflector->getType());
     $parentTypeReflector = $typeReflector->getParentTypeReflector();
     if ($typeReflector->isAbstract()) {
         $classElement->setAttribute("abstract", true);
     }
     if ($parentTypeReflector) {
         $parentType = $parentTypeReflector->getType();
         $classElement->setAttribute("base", $parentType);
     }
     $plugin = $this->extractPluginNameFromPackage($typeReflector->getPackage());
     if ($plugin) {
         $classElement->setAttribute("plugin", $plugin);
     }
     $description = $typeReflector->getDescription();
     $description = $this->fixDescription($description);
     $classElement->setAttribute("description", $description);
     $properties = $typeReflector->getCurrentProperties();
     foreach ($properties as $property) {
         /* @var $property KalturaPropertyInfo */
         if ($property->isServerOnly()) {
             continue;
         }
         $propType = $property->getType();
         $propName = $property->getName();
         $propertyElement = $this->_doc->createElement("property");
         $propertyElement->setAttribute("name", $propName);
         if ($property->isAssociativeArray()) {
             $propertyElement->setAttribute("type", "map");
             $propertyElement->setAttribute("arrayType", $property->getArrayType());
         } else {
             if ($property->isArray()) {
                 $propertyElement->setAttribute("type", "array");
                 $propertyElement->setAttribute("arrayType", $property->getArrayType());
             } else {
                 if ($property->isEnum()) {
                     $propertyElement->setAttribute("type", "int");
                     $propertyElement->setAttribute("enumType", $property->getType());
                 } else {
                     if ($property->isStringEnum()) {
                         $propertyElement->setAttribute("type", "string");
                         $propertyElement->setAttribute("enumType", $property->getType());
                     } else {
                         if ($propType == 'KalturaObject') {
                             $propertyElement->setAttribute("type", 'KalturaObjectBase');
                         } else {
                             $propertyElement->setAttribute("type", $propType);
                         }
                     }
                 }
             }
         }
         $propertyElement->setAttribute("readOnly", $property->isReadOnly() ? "1" : "0");
         $propertyElement->setAttribute("insertOnly", $property->isInsertOnly() ? "1" : "0");
         $description = $property->getDescription();
         $description = $this->fixDescription($description);
         $propertyElement->setAttribute("description", $description);
         $classElement->appendChild($propertyElement);
     }
     return $classElement;
 }
 private static function loadClassRecursively(KalturaTypeReflector $classTypeReflector, &$enumClasses)
 {
     $class = $classTypeReflector->getType();
     if ($class == 'KalturaEnum' || $class == 'KalturaStringEnum' || $class == 'KalturaObject') {
         return;
     }
     $enumClasses[$class] = $classTypeReflector;
     $parentClassTypeReflector = $classTypeReflector->getParentTypeReflector();
     if ($parentClassTypeReflector) {
         self::loadClassRecursively($parentClassTypeReflector, $enumClasses);
     }
 }
 private function buildObject(KalturaTypeReflector $typeReflector, array &$params, $objectName)
 {
     // if objectType was specified, we will use it only if the anotation type is it's base type
     if (array_key_exists("objectType", $params)) {
         $possibleType = $params["objectType"];
         if (strtolower($possibleType) !== strtolower($typeReflector->getType())) {
             if ($typeReflector->isParentOf($possibleType)) {
                 $newTypeReflector = KalturaTypeReflectorCacher::get($possibleType);
                 if ($newTypeReflector) {
                     $typeReflector = $newTypeReflector;
                 }
             }
         }
     }
     if ($typeReflector->isAbstract()) {
         throw new KalturaAPIException(KalturaErrors::OBJECT_TYPE_ABSTRACT, $typeReflector->getType());
     }
     $class = $typeReflector->getType();
     $obj = new $class();
     $properties = $typeReflector->getProperties();
     foreach ($properties as $property) {
         /* @var $property KalturaPropertyInfo */
         $name = $property->getName();
         $type = $property->getType();
         if ($property->isSimpleType() || $property->isEnum() || $property->isStringEnum()) {
             if (array_key_exists($name . '__null', $params)) {
                 $obj->{$name} = new KalturaNullField();
                 continue;
             }
             if (!array_key_exists($name, $params)) {
                 // missing parameters should be null or default propery value
                 continue;
             }
             $value = $params[$name];
             if ($property->isSimpleType()) {
                 $value = $this->castSimpleType($type, $value);
                 if (!kXml::isXMLValidContent($value)) {
                     throw new KalturaAPIException(KalturaErrors::INVALID_PARAMETER_CHAR, $name);
                 }
                 $obj->{$name} = $value;
                 continue;
             }
             if ($property->isEnum()) {
                 if (!$property->getTypeReflector()->checkEnumValue($value)) {
                     throw new KalturaAPIException(KalturaErrors::INVALID_ENUM_VALUE, $value, $name, $property->getType());
                 }
                 if ($type == 'KalturaNullableBoolean') {
                     $obj->{$name} = KalturaNullableBoolean::toBoolean($value);
                     continue;
                 }
                 $obj->{$name} = $this->castSimpleType("int", $value);
                 continue;
             }
             if ($property->isStringEnum()) {
                 if (!$property->getTypeReflector()->checkStringEnumValue($value)) {
                     throw new KalturaAPIException(KalturaErrors::INVALID_ENUM_VALUE, $value, $name, $property->getType());
                 }
                 $value = $this->castSimpleType("string", $value);
                 if (!kXml::isXMLValidContent($value)) {
                     throw new KalturaAPIException(KalturaErrors::INVALID_PARAMETER_CHAR, $name);
                 }
                 $obj->{$name} = $value;
                 continue;
             }
         }
         if ($property->isArray()) {
             if (isset($params[$name]) && is_array($params[$name])) {
                 ksort($params[$name]);
                 $arrayObj = new $type();
                 foreach ($params[$name] as $arrayItemParams) {
                     $arrayObj[] = $this->buildObject($property->getArrayTypeReflector(), $arrayItemParams, "{$objectName}:{$name}");
                 }
                 $obj->{$name} = $arrayObj;
             }
             continue;
         }
         if ($property->isComplexType()) {
             if (isset($params[$name]) && is_array($params[$name])) {
                 $obj->{$name} = $this->buildObject($property->getTypeReflector(), $params[$name], "{$objectName}:{$name}");
             }
             continue;
         }
         if ($property->isFile()) {
             if (isset($params[$name])) {
                 $obj->{$name} = $params[$name];
             }
             continue;
         }
     }
     return $obj;
 }
Esempio n. 5
0
 protected function writeType(KalturaTypeReflector $typeReflector)
 {
     $type = $typeReflector->getType();
     if ($typeReflector->isEnum()) {
         $contants = $typeReflector->getConstants();
         $this->echoLine("class {$type}");
         $this->echoLine("{");
         foreach ($contants as $contant) {
             $name = $contant->getName();
             $value = $contant->getDefaultValue();
             $this->echoLine("\tconst {$name} = {$value};");
         }
         $this->echoLine("}");
         $this->echoLine();
     } else {
         if (!$typeReflector->isArray()) {
             // class definition
             $properties = $typeReflector->getProperties();
             $this->echoLine("class {$type} extends KalturaObjectBase");
             $this->echoLine("{");
             // class properties
             foreach ($properties as $property) {
                 $propType = $property->getType();
                 $propName = $property->getName();
                 $this->echoLine("\t/**");
                 $description = str_replace("\n", "\n\t * ", $property->getDescription());
                 // to format multiline descriptions
                 $this->echoLine("\t * " . $description);
                 $this->echoLine("\t *");
                 $this->echoLine("\t * @var {$propType}");
                 if ($property->isReadOnly()) {
                     $this->echoLine("\t * @readonly");
                 }
                 if ($property->isInsertOnly()) {
                     $this->echoLine("\t * @insertonly");
                 }
                 $this->echoLine("\t */");
                 $propertyLine = "public \${$propName}";
                 if ($property->isSimpleType() || $property->isEnum()) {
                     $propertyLine .= " = null";
                 }
                 $this->echoLine("\t{$propertyLine};");
                 $this->echoLine("");
             }
             $this->echoLine();
             $this->echoLine("\tpublic function toParams()");
             $this->echoLine("\t{");
             $this->echoLine("\t\t\$kparams = array();");
             foreach ($properties as $property) {
                 $propType = $property->getType();
                 $propName = $property->getName();
                 if ($property->isSimpleType() || $property->isEnum()) {
                     $this->echoLine("\t\t\$this->addIfNotNull(\$kparams, \"{$propName}\", \$this->{$propName});");
                 } else {
                     continue;
                     // ignore sub objects and arrays
                 }
             }
             $this->echoLine("\t\treturn \$kparams;");
             $this->echoLine("\t}");
             // close class
             $this->echoLine("}");
             $this->echoLine();
         }
     }
 }
Esempio n. 6
0
 protected function addType(KalturaTypeReflector $objectReflector)
 {
     $type = $objectReflector->getType();
     if (isset($this->_types[$type])) {
         return;
     }
     if (in_array($type, $this->_typesToIgnore)) {
         KalturaLog::info("Type should be ignored [{$type}]");
         return;
     }
     if ($objectReflector->isServerOnly()) {
         KalturaLog::info("Type is server only [{$type}]");
         return;
     }
     $this->_types[$type] = $objectReflector;
 }
Esempio n. 7
0
 private function getClassElement(KalturaTypeReflector $typeReflector)
 {
     $properties = $typeReflector->getProperties();
     $classElement = $this->_doc->createElement("class");
     $classElement->setAttribute("name", $typeReflector->getType());
     $parentTypeReflector = $typeReflector->getParentTypeReflector();
     if ($typeReflector->isAbstract()) {
         $classElement->setAttribute("abstract", true);
     }
     if ($parentTypeReflector) {
         $parentType = $parentTypeReflector->getType();
         $classElement->setAttribute("base", $parentType);
     }
     $package = $typeReflector->getPackage();
     if (is_string($package)) {
         $packages = explode('.', $package, 2);
         if (count($packages) == 2 && $packages[0] == 'plugins') {
             $classElement->setAttribute("plugin", $packages[1]);
         }
     }
     $properties = $typeReflector->getCurrentProperties();
     foreach ($properties as $property) {
         $propType = $property->getType();
         $propName = $property->getName();
         $propertyElement = $this->_doc->createElement("property");
         $propertyElement->setAttribute("name", $propName);
         if ($property->isArray()) {
             $propertyElement->setAttribute("type", "array");
             $propertyElement->setAttribute("arrayType", $property->getArrayType());
         } else {
             if ($property->isEnum()) {
                 $propertyElement->setAttribute("type", "int");
                 $propertyElement->setAttribute("enumType", $property->getType());
             } else {
                 if ($property->isStringEnum()) {
                     $propertyElement->setAttribute("type", "string");
                     $propertyElement->setAttribute("enumType", $property->getType());
                 } else {
                     $propertyElement->setAttribute("type", $propType);
                 }
             }
         }
         $propertyElement->setAttribute("readOnly", $property->isReadOnly() ? "1" : "0");
         $propertyElement->setAttribute("insertOnly", $property->isInsertOnly() ? "1" : "0");
         $description = $property->getDescription();
         $description = $this->fixDescription($description);
         $propertyElement->setAttribute("description", $description);
         $classElement->appendChild($propertyElement);
     }
     return $classElement;
 }
 private function buildObject(KalturaTypeReflector $typeReflector, array &$params, $objectName)
 {
     // if objectType was specified, we will use it only if the anotation type is it's base type
     if (array_key_exists("objectType", $params)) {
         $possibleType = $params["objectType"];
         if (strtolower($possibleType) !== strtolower($typeReflector->getType())) {
             if ($typeReflector->isParentOf($possibleType)) {
                 $newTypeReflector = KalturaTypeReflectorCacher::get($possibleType);
                 if ($newTypeReflector) {
                     $typeReflector = $newTypeReflector;
                 }
             }
         }
     }
     if ($typeReflector->isAbstract()) {
         throw new KalturaAPIException(KalturaErrors::OBJECT_TYPE_ABSTRACT, $typeReflector->getType());
     }
     $class = $typeReflector->getType();
     $obj = new $class();
     $properties = $typeReflector->getProperties();
     foreach ($params as $name => $value) {
         $isNull = false;
         if (kString::endsWith($name, '__null')) {
             $name = str_replace('__null', '', $name);
             $isNull = true;
         }
         if (!array_key_exists($name, $properties)) {
             continue;
         }
         $property = $properties[$name];
         /* @var $property KalturaPropertyInfo */
         $type = $property->getType();
         if ($isNull && !$property->isArray()) {
             $obj->{$name} = new KalturaNullField();
             continue;
         }
         if ($property->isSimpleType()) {
             if ($property->isTime()) {
                 $type = "time";
             }
             $value = $this->castSimpleType($type, $value);
             if (!kXml::isXMLValidContent($value)) {
                 throw new KalturaAPIException(KalturaErrors::INVALID_PARAMETER_CHAR, $name);
             }
             $this->validateParameter($name, $value, $property);
             $obj->{$name} = $value;
             continue;
         }
         if ($property->isEnum()) {
             if (strtolower($value) == 'true') {
                 $value = 1;
             }
             if (strtolower($value) == 'false') {
                 $value = 0;
             }
             if (!$property->getTypeReflector()->checkEnumValue($value)) {
                 throw new KalturaAPIException(KalturaErrors::INVALID_ENUM_VALUE, $value, $name, $property->getType());
             }
             if ($type == 'KalturaNullableBoolean') {
                 $obj->{$name} = KalturaNullableBoolean::toBoolean($value);
                 continue;
             }
             $obj->{$name} = $this->castSimpleType("int", $value);
             continue;
         }
         if ($property->isStringEnum()) {
             if (!$property->getTypeReflector()->checkStringEnumValue($value)) {
                 throw new KalturaAPIException(KalturaErrors::INVALID_ENUM_VALUE, $value, $name, $property->getType());
             }
             $value = $this->castSimpleType("string", $value);
             if (!kXml::isXMLValidContent($value)) {
                 throw new KalturaAPIException(KalturaErrors::INVALID_PARAMETER_CHAR, $name);
             }
             $obj->{$name} = $value;
             continue;
         }
         if ($property->isArray() && is_array($value)) {
             $arrayObj = new $type();
             if ($property->isAssociativeArray()) {
                 foreach ($value as $arrayItemKey => $arrayItemParams) {
                     if ($arrayItemKey === '-') {
                         break;
                     }
                     $arrayObj[$arrayItemKey] = $this->buildObject($property->getArrayTypeReflector(), $arrayItemParams, "{$objectName}:{$name}");
                 }
             } else {
                 ksort($value);
                 foreach ($value as $arrayItemKey => $arrayItemParams) {
                     if ($arrayItemKey === '-') {
                         break;
                     }
                     $arrayObj[] = $this->buildObject($property->getArrayTypeReflector(), $arrayItemParams, "{$objectName}:{$name}");
                 }
             }
             $obj->{$name} = $arrayObj;
             continue;
         }
         if ($property->isComplexType() && is_array($value)) {
             $obj->{$name} = $this->buildObject($property->getTypeReflector(), $value, "{$objectName}:{$name}");
             continue;
         }
         if ($property->isFile()) {
             $obj->{$name} = $value;
             continue;
         }
     }
     return $obj;
 }
 /**
  *
  * Write the outpur data for the test
  * @param KalturaTypeReflector $outputTypeReflector
  */
 protected function setOutputData($outputTypeReflector, &$testParams, &$testValues, $isBase = false, &$validateValues = null)
 {
     $paramType = $outputTypeReflector->getType();
     $paramName = $outputTypeReflector->getName();
     $this->writeXmlSource("\t\t\t\t<OutputReference name = '{$paramName}' type = '{$paramType}' key = 'Fill the object key' />");
     if ($outputTypeReflector->isSimpleType() || $outputTypeReflector->isEnum() || $outputTypeReflector->isDynamicEnum() || $outputTypeReflector->isDynamicEnum()) {
         $defaultValue = $outputTypeReflector->getDefaultValue();
         $this->writeIni("test1.reference = " . $defaultValue);
         $this->writeXml("\t\t<OutputReference name = '{$paramName}' type = '{$paramType}' key = '{$defaultValue}' />");
     } elseif ($outputTypeReflector->isFile()) {
         $this->writeIni("test1.reference.objectType = file");
         $this->writeIni("test1.reference.path = ");
         //TODO: add support for files in XML
         $this->writeXml("\t\t<OutputReference name = '{$paramName}' type='file' key='path/to/file'/>");
     } else {
         $this->writeIni("test1.reference.objectType = {$paramType}");
         $this->writeXml("\t\t<OutputReference name = '{$paramName}' type = '{$paramType}' key = 'object key'>");
         $actionParamProperties = $outputTypeReflector->getTypeReflector()->getProperties();
         foreach ($actionParamProperties as $actionParamProperty) {
             /* @var $actionParamProperty KalturaPropertyInfo */
             if ($actionParamProperty->isReadOnly()) {
                 continue;
             }
             $propertyType = $actionParamProperty->getType();
             $propertyName = $actionParamProperty->getName();
             if ($actionParamProperty->isSimpleType() || $actionParamProperty->isEnum() || $actionParamProperty->isDynamicEnum() || $actionParamProperty->isDynamicEnum()) {
                 $paramDefaultValue = $actionParamProperty->getDefaultValue();
                 $this->writeIni("test1.reference.{$propertyName} = " . $paramDefaultValue);
                 $this->writeXml("\t\t\t<{$propertyName}>{$paramDefaultValue}</{$propertyName}>");
             } elseif ($actionParamProperty->isFile()) {
                 $this->writeIni("test1.reference.{$propertyName}.objectType = file");
                 $this->writeIni("test1.reference.{$propertyName}.path = ");
                 //TODO: add support for files in XML
                 $this->writeXml("\t\t\t<OutputReference name = '{$paramName}' type='file' key= 'path/to/file'>");
             } elseif (!$actionParamProperty->isAbstract()) {
                 if ($propertyName == 'type') {
                     //Causes bug in the Zend config
                     $this->writeIni("test1.reference.objType.{$propertyName} = {$propertyType}");
                 } else {
                     $this->writeIni("test1.reference.{$propertyName}.objectType = {$propertyType}");
                 }
                 $this->writeXml("\t\t\t<{$propertyName}>{$propertyType}</{$propertyName}>");
             }
         }
         $this->writeXml("\t\t</OutputReference>");
     }
     $paramDesc = strlen($outputTypeReflector->getDescription()) ? ' ' . $outputTypeReflector->getDescription() : '';
     if ($isBase) {
         $this->writeBase("\t * @param {$paramType} \$reference{$paramDesc}");
     } else {
         $this->writeTest("\t * @param {$paramType} \$reference{$paramDesc}");
     }
     if (!$outputTypeReflector->isComplexType() || $outputTypeReflector->isEnum() || $outputTypeReflector->isStringEnum() || $outputTypeReflector->isDynamicEnum()) {
         $testParam = "\$reference";
     } else {
         $testParam = "{$paramType} \$reference";
     }
     if ($outputTypeReflector->isOptional()) {
         if ($outputTypeReflector->getDefaultValue()) {
             if ($outputTypeReflector->getType() == 'string') {
                 $testParam .= " = '" . $outputTypeReflector->getDefaultValue() . "'";
             } else {
                 $testParam .= " = " . $outputTypeReflector->getDefaultValue();
             }
         } else {
             $testParam .= " = null";
         }
     }
     $testParams[] = $testParam;
     if ($isBase) {
         $validateValues[] = "\$reference";
     } else {
         //write to TestFile
         $testValues[] = "\$reference";
     }
 }
Esempio n. 10
0
 protected function addType(KalturaTypeReflector $objectReflector)
 {
     $type = $objectReflector->getType();
     if ($objectReflector->isDeprecated()) {
         KalturaLog::info("Type deprecated [{$type}]");
         return;
     }
     if (!array_key_exists($type, $this->_types)) {
         $this->_types[$type] = $objectReflector;
     }
 }
 private function buildObject(KalturaTypeReflector $typeReflector, array &$params)
 {
     // if objectType was specified, we will use it only if the anotation type is it's base type
     if (array_key_exists("objectType", $params)) {
         $possibleType = $params["objectType"];
         if (strtolower($possibleType) !== strtolower($typeReflector->getType())) {
             if ($typeReflector->isParentOf($possibleType)) {
                 // we know that the objectType that came from the user is right, and we can use it to initiate the object
                 $typeReflector = KalturaTypeReflectorCacher::get($possibleType);
             }
         }
     }
     $class = $typeReflector->getType();
     $obj = new $class();
     $properties = $typeReflector->getProperties();
     foreach ($properties as $property) {
         $name = $property->getName();
         $type = $property->getType();
         if ($property->isSimpleType() || $property->isEnum() || $property->isStringEnum()) {
             if (!array_key_exists($name, $params)) {
                 // missing parameters should be null or default propery value
                 continue;
             }
             $value = $params[$name];
             if ($property->isSimpleType()) {
                 $obj->{$name} = $this->castSimpleType($type, $value);
             } else {
                 if ($property->isEnum()) {
                     if (!$property->getTypeReflector()->checkEnumValue($value)) {
                         throw new KalturaAPIException(KalturaErrors::INVALID_ENUM_VALUE, $value, $name, $property->getType());
                     }
                     $obj->{$name} = $this->castSimpleType("int", $value);
                 } else {
                     if ($property->isStringEnum()) {
                         if (!$property->getTypeReflector()->checkStringEnumValue($value)) {
                             throw new KalturaAPIException(KalturaErrors::INVALID_ENUM_VALUE, $value, $name, $property->getType());
                         }
                         $obj->{$name} = $this->castSimpleType("string", $value);
                     }
                 }
             }
         } else {
             if ($property->isArray()) {
                 if (isset($params[$name]) && is_array($params[$name])) {
                     $arrayObj = new $type();
                     foreach ($params[$name] as $arrayItemParams) {
                         $arrayObj[] = $this->buildObject($property->getArrayTypeReflector(), $arrayItemParams);
                     }
                     $obj->{$name} = $arrayObj;
                 }
             } else {
                 if ($property->isComplexType()) {
                     if (isset($params[$name]) && is_array($params[$name])) {
                         $obj->{$name} = $this->buildObject($property->getTypeReflector(), $params[$name]);
                     }
                 }
             }
         }
     }
     return $obj;
 }