Example #1
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;
 }
Example #2
0
 /**
  *
  * @param <string> $name
  * @param <array<key => value>> $attributes
  * Constructor
  */
 public function Property($name, $attributes)
 {
     $this->_isSyndication = $this->_hasEPM = false;
     $this->_name = $name;
     $this->_attributes = $attributes;
     if (array_key_exists('FC_TargetPath', $this->_attributes)) {
         ValidateEPMAttributes($this->_attributes, $this->_attributes, $this->_name, true);
         $this->_hasEPM = true;
         $this->_isSyndication = SyndicationItemProperty::IsSyndicationItem($this->_attributes['FC_TargetPath']);
         if (!$this->_isSyndication) {
             $attribute = null;
             $segments = explode("/", $this->_attributes['FC_TargetPath']);
             $segment_count = count($segments);
             if ($segments[$segment_count - 1][0] == '@') {
                 $attribute = ltrim($segments[$segment_count - 1], '@');
                 $this->_attributes['NodeAttribute'] = $attribute;
                 unset($segments[$segment_count - 1]);
                 $segment_count--;
             }
             $FC_TargetPathWithNS = null;
             $nsPrefix = $this->_attributes['FC_NsPrefix'];
             $FC_TargetPathWithNS = $nsPrefix . ":" . $segments[0];
             for ($i = 1; $i < $segment_count; $i++) {
                 $FC_TargetPathWithNS = $FC_TargetPathWithNS . "/" . $nsPrefix . ":" . $segments[$i];
             }
             $this->_attributes['FC_TargetPathNS'] = $FC_TargetPathWithNS;
         }
     }
 }
Example #3
0
 protected function HandleProperties($xPath, $propertyQuery, $clientType, $object)
 {
     if ($clientType->hasEPM()) {
         $epmProperties = $clientType->getRawEPMProperties();
         foreach ($epmProperties as $epmProperty) {
             $propertyName = $epmProperty->getName();
             $attributes = $epmProperty->getAttributes();
             $targetQuery = null;
             $synd = false;
             if ($epmProperty->hasEPM($synd)) {
                 if ($synd) {
                     $targetQuery = SyndicationItemProperty::GetSyndicationItemPathwithNS($attributes['FC_TargetPath']);
                 } else {
                     $targetQuery = $attributes['FC_TargetPathNS'];
                     $xPath->registerNamespace($attributes['FC_NsPrefix'], $attributes['FC_NsUri']);
                 }
                 $nodes = $xPath->Query($targetQuery);
                 if ($nodes->length) {
                     $value = null;
                     if (isset($attributes['NodeAttribute'])) {
                         $attribute = $attributes['FC_NsPrefix'] . ":" . $attributes['NodeAttribute'];
                         $value = self::GetAttribute($nodes->item(0), $attribute);
                         if (is_null($value) && (isset($attributes['EdmType']) && ($attributes['EdmType'] == 'Edm.Int16' || $attributes['EdmType'] == 'Edm.Int32' || $attributes['EdmType'] == 'Edm.Int64'))) {
                             $value = '0';
                         }
                     } else {
                         $value = null;
                         if ($nodes->item(0)->hasChildNodes()) {
                             $value = $nodes->item(0)->firstChild->textContent;
                         } else {
                             $value = $nodes->item(0)->nodeValue;
                         }
                         if (empty($value)) {
                             $query1 = $propertyQuery . $propertyName;
                             $nodes1 = $xPath->Query($query1);
                             if ($nodes1->length) {
                                 $value1 = self::GetAttribute($nodes1->item(0), "m:null");
                                 if ($value1 == 'true') {
                                     $value = null;
                                 }
                             }
                         }
                     }
                     $property = new ReflectionProperty($object, $propertyName);
                     $property->setValue($object, $value);
                 } else {
                     //NOTE: Atom Entry not contains $targetQuery node its
                     //an error, becase in the case of projection also
                     //custmerizable feeds will be there.
                     //
                 }
             }
         }
     }
     $nonEpmProperties = $clientType->getRawNonEPMProperties(true);
     foreach ($nonEpmProperties as $nonEpmProperty) {
         $propertyName = $nonEpmProperty->getName();
         $propertyAttributes = $nonEpmProperty->getAttributes();
         //Now check for complex type. If type not start with 'Edm.'
         //it can be a complex type.
         if (isset($propertyAttributes['EdmType']) && strpos($propertyAttributes['EdmType'], 'Edm.') !== 0) {
             $complexPropertyObject = null;
             $complexPropertyName = '';
             if ($this->CheckAndProcessComplexType($xPath, $propertyQuery, $propertyName, $complexPropertyName, $complexPropertyObject)) {
                 $property = new ReflectionProperty($object, $complexPropertyName);
                 $property->setValue($object, $complexPropertyObject);
                 continue;
             }
         }
         $query = $propertyQuery . $propertyName;
         $nodes = $xPath->Query($query);
         if ($nodes->length) {
             $value = $nodes->item(0)->nodeValue;
             $property = new ReflectionProperty($object, $propertyName);
             $property->setValue($object, $value);
         } else {
             //NOTE: Atom Entry not contains the required property
             //not a bug projection can lead to this case
         }
     }
 }