Esempio n. 1
0
 /**
  *
  * @param <string> $type
  * Constructor
  */
 public function ClientType($type)
 {
     $this->_attributes = array();
     $this->_properties = array();
     $this->_navigationProperties = array();
     $this->_sortedEPMProperties = array();
     $targetPathToCount = array();
     try {
         $rClass = new ReflectionClass($type);
         $this->_hasEPM = false;
         $this->_attributes = Utility::getAttributes($rClass);
         $sourceProperty = null;
         if (array_key_exists('FC_SourcePath', $this->_attributes)) {
             $this->_hasEPM = true;
             $sourceProperty = $this->_attributes['FC_SourcePath'];
         }
         $properties = $rClass->getProperties();
         foreach ($properties as $property) {
             if ($property->isPublic()) {
                 $attributes = Utility::getAttributes($property);
                 $propertyName = $property->name;
                 if ($sourceProperty != null && $sourceProperty == $propertyName) {
                     ValidateEPMAttributes($this->_attributes, $attributes, $sourceProperty, false);
                 }
                 if (isset($attributes['Type']) && $attributes['Type'] == 'EntityProperty') {
                     $propertyObj = new Property($propertyName, $attributes);
                     $this->_properties[$propertyName] = $propertyObj;
                     if ($propertyObj->hasEPM($syn)) {
                         $this->_hasEPM = true;
                         $attrs = $propertyObj->getAttributes();
                         if ($syn) {
                             $targetPath = SyndicationItemProperty::GetSyndicationItemPathNoNS($attrs['FC_TargetPath']);
                         } else {
                             $targetPath = $attrs['FC_TargetPathNS'];
                             if (isset($attrs['NodeAttribute'])) {
                                 $targetPath .= '/@' . $attrs['NodeAttribute'];
                             }
                         }
                         $targetPathToCount[$targetPath] = substr_count($targetPath, "/");
                     }
                 } else {
                     if (isset($attributes['Type']) && $attributes['Type'] == 'NavigationProperty') {
                         $this->_navigationProperties[$propertyName] = new Property($propertyName, $attributes);
                     }
                 }
             }
         }
         asort($targetPathToCount);
         $properties = $this->_properties;
         foreach ($targetPathToCount as $key => $value) {
             foreach ($properties as $property) {
                 $syn = false;
                 $targetPath = null;
                 if ($property->hasEPM($syn)) {
                     $attrs = $property->getAttributes();
                     if ($syn) {
                         $targetPath = SyndicationItemProperty::GetSyndicationItemPathNoNS($attrs['FC_TargetPath']);
                     } else {
                         $targetPath = $attrs['FC_TargetPathNS'];
                         if (isset($attrs['NodeAttribute'])) {
                             $targetPath .= '/@' . $attrs['NodeAttribute'];
                         }
                     }
                     if ($key == $targetPath) {
                         $this->_sortedEPMProperties[] = $property;
                     }
                 }
             }
         }
     } catch (ReflectionException $exception) {
         throw new InvalidOperation('ReflectionException in ClientType constructor');
     }
 }
Esempio n. 2
0
 /**
  * To create changeset body for an entity in ATOMPub format.
  *
  * @param ResourceBox $resourceBox
  * @param boolean $newline
  * @return string
  * @throws InvalidOperation, InternalError
  */
 protected function CreateChangeSetBodyForResource($resourceBox, $newline)
 {
     $syndicationUpdated = false;
     if (EntityStates::Deleted == $resourceBox->State) {
         return null;
     }
     if (EntityStates::Added != $resourceBox->State && EntityStates::Modified != $resourceBox->State) {
         throw new InternalError(Resource::UnexpectdEntityState);
     }
     $changesetBodyForResource = null;
     Utility::WriteLine($changesetBodyForResource, "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>");
     Utility::WriteLine($changesetBodyForResource, "<entry xmlns:d=\"http://schemas.microsoft.com/ado/2007/08/dataservices\" xmlns:m=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\" xmlns=\"http://www.w3.org/2005/Atom\">");
     $object = $resourceBox->getResource();
     $entityName = get_class($object);
     $type = ClientType::Create($entityName);
     $nullCFProperties = array();
     $CF_SyndicationXML = null;
     $CF_NonSyndicationXML = null;
     $this->HandleNCharProperties($type, $object);
     //Check this Client Type has Syndication or Custom Property mapping, if so
     //build the syndication XML/Custom XML.
     if ($type->hasEPM()) {
         $epmProperties = $type->getRawSortedEPMProperties();
         $FC_Synd_dom = new DOMDocument();
         $FC_NonSynd_dom = new DOMDocument();
         foreach ($epmProperties as $epmProperty) {
             $synd = false;
             if ($epmProperty->hasEPM($synd)) {
                 $propertyName = $epmProperty->getName();
                 $attributes = $epmProperty->getAttributes();
                 $refProperty = new ReflectionProperty($object, $propertyName);
                 $propertyValue = $refProperty->getValue($object);
                 if ($synd) {
                     if ($attributes['FC_TargetPath'] == 'SyndicationUpdated') {
                         $syndicationUpdated = true;
                         $propertyValue = Utility::TimeInISO8601();
                     }
                     if (is_null($propertyValue)) {
                         $nullCFProperties[] = $propertyName;
                     }
                     $path = SyndicationItemProperty::GetSyndicationItemPathNoNS($attributes['FC_TargetPath']);
                     XMLBuilder::BuildDOMFromPath($FC_Synd_dom, $path, $propertyValue, '', '', false);
                 } else {
                     if (is_null($propertyValue)) {
                         $nullCFProperties[] = $propertyName;
                     }
                     XMLBuilder::BuildDOMFromPath($FC_NonSynd_dom, $attributes['FC_TargetPath'], $propertyValue, $attributes['FC_NsPrefix'], $attributes['FC_NsUri'], true);
                 }
             }
         }
         $CF_SyndicationXML = trim(str_replace('<?xml version="1.0"?>', '', $FC_Synd_dom->SaveXML()));
         $CF_NonSyndicationXML = trim(str_replace('<?xml version="1.0"?>', '', $FC_NonSynd_dom->SaveXML()));
     }
     if (!empty($CF_SyndicationXML)) {
         Utility::WriteLine($changesetBodyForResource, $CF_SyndicationXML);
         if (!$syndicationUpdated) {
             Utility::WriteLine($changesetBodyForResource, '<updated>' . Utility::TimeInISO8601() . '</updated>');
         }
     } else {
         Utility::WriteLine($changesetBodyForResource, '<title />');
         Utility::WriteLine($changesetBodyForResource, '<author>');
         Utility::WriteLine($changesetBodyForResource, '<name />');
         Utility::WriteLine($changesetBodyForResource, '</author>');
         Utility::WriteLine($changesetBodyForResource, '<updated>' . Utility::TimeInISO8601() . '</updated>');
     }
     if (EntityStates::Modified == $resourceBox->State) {
         $editLinkUri = $resourceBox->Identity;
         Utility::WriteLine($changesetBodyForResource, '<id>' . $editLinkUri . '</id>');
         //While modifying, key properties cannot be null
         $keyPropertyNames = $type->geyKeyProperties();
         foreach ($keyPropertyNames as $keyPropertyName) {
             $prop = new ReflectionProperty($object, $keyPropertyName);
             $propertyValue = $prop->getValue($object);
             if (empty($propertyValue) && !$this->_processingMediaLinkEntry) {
                 throw new InvalidOperation(Resource::NullValueNotAllowedForKey . $keyPropertyName);
             }
         }
     } else {
         Utility::WriteLine($changesetBodyForResource, '<id />');
     }
     if (!$resourceBox->MediaLinkEntry) {
         Utility::WriteLine($changesetBodyForResource, "<content type=\"application/xml\">");
     }
     Utility::WriteLine($changesetBodyForResource, '<m:properties>');
     $nonEpmProperties = $type->getRawNonEPMProperties(true);
     foreach ($nonEpmProperties as $nonEpmProperty) {
         $propertyName = $nonEpmProperty->getName();
         $refProperty = new ReflectionProperty($object, $propertyName);
         $propertyValue = $refProperty->getValue($object);
         $body = $this->CheckAndCreateChangeSetBodyPartForComplexType($nonEpmProperty, $propertyValue);
         if ($body) {
             Utility::WriteLine($changesetBodyForResource, $body);
             continue;
         }
         $property = '';
         // determine if the property is null and should be output accordingly
         // for numeric types, utilize a numeric value
         if ($propertyValue) {
             Utility::GetPropertyType($refProperty, $notNullable);
             if (!$notNullable) {
                 $property = "<d:" . $propertyName . " " . "m:null=\"true\" />";
             } elseif (strpos($edmType, 'Edm.Decimal') === 0) {
                 $property = '<d:' . $propertyName . '>0.0M</d:' . $propertyName . '>';
             } elseif (strpos($edmType, 'Edm.Double') === 0) {
                 $property = '<d:' . $propertyName . '>0.0</d:' . $propertyName . '>';
             } elseif (strpos($edmType, 'Edm.Int') === 0) {
                 $property = '<d:' . $propertyName . '>0</d:' . $propertyName . '>';
             } elseif (strpos($edmType, 'Edm.Single') === 0) {
                 $property = '<d:' . $propertyName . '>0.0f</d:' . $propertyName . '>';
             } else {
                 /**
                  * The following comment is from the original authors and remains until
                  * further investigation can be made regarding proper behavior of
                  * non-nullable types.
                  */
                 //ex: In the case of OrderID, the ID is a autonumber, so user will not
                 //specify this value, since its a nonnullable value we cant set null=true
                 //property, in this case the correct property node should be
                 //<d:OrderID">0</d:OrderID">, but instead of this we can also achieve the
                 //same effect by not adding the property itself in xml
                 continue;
             }
         } else {
             $attributes = $nonEpmProperty->getAttributes();
             $edmType = '';
             if (isset($attributes['EdmType']) && $attributes['EdmType'] != 'Edm.String') {
                 $edmType = ' m:type="' . $attributes['EdmType'] . '"';
                 // wrap value in CDATA tag since strings may contain XML special characters
                 $propertyValue = "<![CDATA[" . $propertyValue . "]]>";
             }
             $property = '<d:' . $propertyName . $edmType . '>' . $propertyValue . '</d:' . $propertyName . '>';
         }
         Utility::WriteLine($changesetBodyForResource, $property);
     }
     //Check for CF properties for which user has set null value. In this
     //case these properties should be added in the content section.
     foreach ($nullCFProperties as $nullCFProperty) {
         $refProperty = new ReflectionProperty($object, $propertyName);
         $property = "<d:" . $nullCFProperty . " " . "m:null=\"true\" />";
         Utility::WriteLine($changesetBodyForResource, $property);
     }
     Utility::WriteLine($changesetBodyForResource, '</m:properties>');
     if (!$resourceBox->MediaLinkEntry) {
         Utility::WriteLine($changesetBodyForResource, '</content>');
     }
     //append CF Cutom XML
     if (!empty($CF_NonSyndicationXML)) {
         Utility::WriteLine($changesetBodyForResource, $CF_NonSyndicationXML);
     }
     Utility::WriteLine($changesetBodyForResource, '</entry>');
     if ($newline) {
         Utility::WriteLine($changesetBodyForResource, null);
     }
     return $changesetBodyForResource;
 }