_usrAcl = $usrAcl; $this->_typeConverter = new Api_WfsGeomTypeConverter(); $this->_apiBaseUri = ''; } public function setBaseUri($uri) { $this->_apiBaseUri = $uri; } public function getBaseUri() {// TODO: RMME return $this->_apiBaseUri; } /** * @param string $typeName - 'p5_default_db:TEST_PERMS' */ public function getAclFromTypeName($typeName) { try { // TODO: use object cache `CRM_#CACHE_ACL_OBJECT` $namespace = str_replace([':', '__x3A__'], '/', $typeName); if ('p5_' === substr($namespace, 0, 3)) $namespace = substr($namespace, 3); Lib::loadClass('SchemaFactory'); $objItem = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, ['propertyName'=>"*,field"]); DBG::log($objItem, 'array', "DBG objItem({$namespace})"); if (!$objItem['idZasob']) throw new Exception("Missing idZasob for namespace '{$namespace}'"); if (!in_array($objItem['_type'], [ // 'TableAcl', // TODO: TEST - to replace TableAcl by AntAcl or use object with namespace + '/tableName'? 'AntAcl', ])) throw new Exception("Not Implemented acl type '{$objItem['_type']}'"); if (!$objItem['isObjectActive']) { if (!$objItem['hasStruct']) throw new Exception("namespace has no structure '{$namespace}'"); if (!$objItem['isStructInstalled']) throw new Exception("namespace structure not installed '{$namespace}'"); throw new Exception("namespace is not activated '{$namespace}'"); } Lib::loadClass('AntAclBase'); $acl = AntAclBase::buildInstance($objItem['idZasob'], $objItem); return $acl; } catch (Exception $e) { DBG::log($e); } $typeEx = explode(':', $typeName); $sourceName = $typeEx[0]; $objName = $typeEx[1]; if (2 != count($typeEx)) throw new Api_WfsException("Could not get acl for '{$typeName}' - syntax error"); if ('p5_' == substr($sourceName, 0, 3)) $sourceName = substr($sourceName, 3);// remove prefix 'p5_' $acl = $this->_usrAcl->getObjectAcl($sourceName, $objName); $forceTblAclInit = 0;//('1' == V::get('_force', '', $_GET)); $acl->init($forceTblAclInit); return $acl; } public function _getXmlSchemaLocation() { $schemaLocations = array(); //$schemaLocations[] = 'http://www.opengis.net/wfs http://webgis.regione.sardegna.it:80/geoserver/schemas/wfs/1.0.0/WFS-capabilities.xsd';// @from http://webgis.regione.sardegna.it/geoserver/ows?service=WFS&request=GetCapabilities return (!empty($schemaLocations))? 'xsi:schemaLocation="' . implode(' ', $schemaLocations) . '"' : ''; } public function _printXmlNamespaceList() { $listNs = array(); foreach (Api_WfsNs::getNsList() as $uri => $prefix) { $listNs[] = 'xmlns:' . $prefix . '="' . $uri . '"'; } return implode("\n", $listNs); } public function _getSourceNsList() { $usrObjList = array(); $tblsAcl = $this->_usrAcl->getTablesAcl(); foreach ($tblsAcl as $tblAcl) { $dataSourceName = 'default_db';// TODO: getSourceName $tblName = $tblAcl->getName(); $usrObjList[] = array($dataSourceName, $tblName); } $usrObjList[] = array('objects', 'File'); $usrObjList[] = array('objects', 'TestPerms'); $usrObjList[] = array('objects', 'Korespondencja'); return $usrObjList; } public function _parseTransactionXmlStruct($requestXml, $requestXmlTags) { $DBG = V::get('DBG_XML', 0, $_GET, 'int');// TODO: Profiler $rootTagName = V::get('tag', '', $requestXmlTags[0]); if ('Transaction' != $rootTagName) throw new Api_WfsException("Parse Request XML Error - Missing Transaction as root xml tag", __LINE__, null, 'TransactionParseError', 'request'); // TODO: special actions if action on nested objects // 1. convert request: wfs.transaction.convert-wfs-request.xsl // 2. validate converted request: wfs.transaction-converted-request.xsd // 3. execute request in data source // if($DBG){echo 'L.' . __LINE__ . ' $requestXmlTags:';print_r($requestXmlTags);echo "\n";} /* blank-wfs.gif R0lGODlhAQABAIAAAP///////yH+EUNyZWF0ZWQgd2l0aCBHSU1QACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== */ $actionXmlTags = array();// // [ 0 => [ 'action'=>Insert, 'typeName'=>str, 'tags'=>[] ] {// split xml for action tags (Insert, Update, Delete) $tagsCount = count($requestXmlTags); for ($i = 1, $actionTagName = null, $actionIdx = -1, $tagLvl = 0; $i < $tagsCount - 1; $i++) {// skip Transaction open/close tag $tag = $requestXmlTags[$i]; if (null == $actionTagName) { $actionTagName = $tag['tag']; $tagLvl = $tag['level']; $actionIdx += 1; $actionXmlTags[$actionIdx] = array(); $actionXmlTags[$actionIdx]['action'] = $actionTagName; $actionXmlTags[$actionIdx]['typeName'] = V::get('typeName', '', $tag['attributes']); $actionXmlTags[$actionIdx]['isDeepObject'] = null;// null - unknown, false - not seed, true - deep $actionXmlTags[$actionIdx]['tags'] = array(); } else if ($tag['tag'] == $actionTagName && 'close' == $tag['type'] && $tagLvl == $tag['level']) { $actionTagName = null; } else { $actionXmlTags[$actionIdx]['tags'][] = $tag; } } } {// Validate Request: WFS allow multiple tags inside Insert tag // TODO: implement multiple tags in Insert tag if reauired. Use array_splice($actionXmlTags, $actionIdx, 0, $insertTags); {// throw (Not Implemented, 501) if found multiple tags in Insert tag foreach ($actionXmlTags as $actionIdx => $action) { if ('Insert' !== $action['action']) continue; $lvl = $action['tags'][0]['level']; for ($i = 1, $cnt = count($action['tags']); $i < $cnt - 1; $i++) { $tag = $action['tags'][$i]; // if($DBG){echo 'L.' . __LINE__ . " actionXmlTags loop({$i}) \$tag:";print_r($tag);echo "\n";} if ($tag['level'] == $lvl) throw new Exception("Error Processing Request - multiple tags inside Insert tag is not implemented", 501); } } } } {// Insert tag - fix typeName from first tag, remove first and last tag - leave only fields foreach ($actionXmlTags as $actionIdx => $action) { if ('Insert' !== $action['action']) continue; array_pop($action['tags']);// remove last tag (close tag) $tag = array_shift($action['tags']);// remove last tag (close tag) $typeName = $tag['tag'];// eg. with prefix 'p5_objects:File' or without prefix but with @xmlns if (false === strpos($typeName, ':')) { $nsType = V::get('xmlns', '', $tag['attributes']); if (!$nsType) throw new Exception("Error Processing Request - Missing object namespace '{$tag['tag']}'"); $prefix = Api_WfsNs::getNsPrefix($nsType); if (!$prefix) { if ($typeName == substr(rtrim($nsType, '/'), -1 * strlen($typeName))) {// typeName may be added to ns uri $nsBaseForType = substr(rtrim($nsType, '/'), 0, -1 * strlen($typeName) - 1); $prefix = Api_WfsNs::getNsPrefix($nsBaseForType); } } if (!$prefix) throw new Exception("Error Processing Request - Unrecognized namespace uri '{$nsType}' for object '{$tag['tag']}'"); $typeName = "{$prefix}:{$typeName}"; } $action['typeName'] = $typeName; $actionXmlTags[$actionIdx] = $action; } } {// validate // if($DBG){echo 'L.' . __LINE__ . ' before validate $actionXmlTags:';print_r($actionXmlTags);echo "\n";} foreach ($actionXmlTags as $actionIdx => $action) { if ('Insert' == $action['action']) { if (empty($action['typeName'])) throw new Exception("Error Processing Request - unknown object typeName to Insert"); $acl = $this->getAclFromTypeName($action['typeName']); $actionXmlTags[$actionIdx] = $acl->validateInsertXml($action); } else if ('Update' == $action['action']) { $acl = $this->getAclFromTypeName($action['typeName']); $actionXmlTags[$actionIdx] = $acl->validateUpdateXml($action); } else if ('Delete' == $action['action']) { if($DBG>1){echo'
$action: ';print_r($action);echo'
';} $acl = $this->getAclFromTypeName($action['typeName']); $actionXmlTags[$actionIdx] = $acl->validateDeleteXml($action); } else { if($DBG>1){echo'
$action: ';print_r($action);echo'
';} throw new Exception("{$action['action']} action not implemented", 501); } // continue;// TODO: validate all by type } } if ('1' == V::get('DBG_DONT_CHANGE_DB', '', $_REQUEST)) { echo "----------------- action xml tags: ---------------" . "\n"; print_r($actionXmlTags); die(".EOF\n"); } {// execute $returnIds = array(); $changesList = array(); foreach ($actionXmlTags as $actionIdx => $action) { if ('Insert' == $action['action']) { if (empty($action['typeName'])) throw new Exception("Error Processing Request - unknown object typeName to Insert"); $acl = $this->getAclFromTypeName($action['typeName']); $newId = $acl->insertXml($action); $returnIds[$actionIdx] = $newId; $changesList[$actionIdx] = array('Status'=>(($newId > 0)? 'SUCCESS' : 'FAILED'), 'Message'=>"created {$newId}.", 'Action' => $action['action']); if ($newId > 0) $changesList[$actionIdx]['fid'] = $acl->getName() . '.' . $newId; } else if ('Update' == $action['action']) { if($DBG>1){echo'
$action: ';print_r($action);echo'
';} $acl = $this->getAclFromTypeName($action['typeName']); $affected = $acl->updateXml($action); $changesList[$actionIdx] = array('Status'=>(($affected >= 0)? 'SUCCESS' : 'FAILED'), 'Message'=>"affected {$affected}.", 'Action' => $action['action']); } else if ('Delete' == $action['action']) { $acl = $this->getAclFromTypeName($action['typeName']); $affected = $acl->deleteXml($action); $changesList[$actionIdx] = array('Status'=>(($affected >= 0)? 'SUCCESS' : 'FAILED'), 'Message'=>"deleted {$affected}.", 'Action' => $action['action']); } else throw new Exception("TODO: {$action['action']} action not implemented", 501); } if($DBG){echo 'L.' . __LINE__ . ' $changesList:';print_r($changesList);echo "\n";} } return $this->_transactionResponse($changesList); } public function _transactionResponse($changesList) { // // // : SUCCESS / FAILED / PARTIAL // [ $change) { if ('FAILED' == $change['Status']) { $statusIsFailed = true; } if ('SUCCESS' == $change['Status'] && !empty($change['fid'])) { $createdFeatureId[] = $change['fid']; } // if (!empty($change['Message'])) $messageTag .= "Feature '{$featureId}' {$change['Status']}: {$change['Message']}\n"; } $statusTag = ($statusIsFailed)? 'FAILED' : 'SUCCESS'; $statusTag = ""; $messageTag = '';//"{$messageTag}"; /* Example: */ // TODO: build xml by DOMDocument // TODO: xsi:schemaLocation="http://www.opengis.net/wfs http://localhost:8080/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd" $wfsInsertResult = ''; if (!empty($createdFeatureId)) { $wfsInsertResult = "\n\n"; foreach ($createdFeatureId as $fid) { $wfsInsertResult .= '' . "\n"; } $wfsInsertResult .= "\n\n"; EOF; } $tranRes = << {$wfsInsertResult} {$statusTag} {$messageTag} EOF; return $tranRes; } public function _convertTransactionXml($requestXmlString, $sourceNsList) { $DBG = (V::get('DBG_XSL', '', $_GET) > 0);// TODO: Profiler if($DBG){echo 'L.' . __LINE__ . ' sourceNsList:';print_r($sourceNsList);echo "\n";} $updateActionsXsd = array(); $insertActionsXsd = array(); $deleteActionsXsd = array(); // foreach ($sourceNsList as $nsInd => $sourceNs) { // $theGeomField = 'the_geom';// TODO: get from fields list $typeName = "p5_{$sourceNs[0]}:{$sourceNs[1]}"; if($DBG){echo 'L.' . __LINE__ . ' typeName:';print_r($typeName);echo "\n";} $updateElementName = "UpdateNs{$nsInd}"; $geomCoordsUpdateXpath = "//wfs:Value/*/gml:outerBoundaryIs/gml:LinearRing/gml:coordinates"; $geomCoordsInsertXpath = "//*/gml:outerBoundaryIs/gml:LinearRing/gml:coordinates"; $acl = $this->getAclFromTypeName($typeName); $geomType = $acl->getGeomFieldType($theGeomField); if ('polygon' == $geomType) { $geomCoordsUpdateXpath = ".//wfs:Value/*/gml:outerBoundaryIs/gml:LinearRing/gml:coordinates"; $geomCoordsUpdateXpath = "(())"; $geomCoordsInsertXpath = ".//*/gml:outerBoundaryIs/gml:LinearRing/gml:coordinates"; $geomCoordsInsertXpath = "(())"; } else if ('linestring' == $geomType) { $geomCoordsUpdateXpath = ".//wfs:Value/*/gml:coordinates"; $geomCoordsUpdateXpath = "()"; $geomCoordsInsertXpath = ".//*/gml:coordinates"; $geomCoordsInsertXpath = "()"; } else if ('point' == $geomType) { $geomCoordsUpdateXpath = ".//wfs:Value/*/gml:coordinates"; $geomCoordsUpdateXpath = "()"; $geomCoordsInsertXpath = ".//*/gml:coordinates"; $geomCoordsInsertXpath = "()"; } $actionXsd = << {$geomCoordsUpdateXpath} EOF; $updateActionsXsd[] = $actionXsd; $typeName = "{$sourceNs[1]}";//"p5_{$sourceNs[0]}:{$sourceNs[1]}"; $insertElementName = "InsertNs{$nsInd}"; $actionXsd = << {$geomCoordsInsertXpath} EOF; $insertActionsXsd[] = $actionXsd; $deleteElementName = "DeleteNs{$nsInd}"; $typeName = "p5_{$sourceNs[0]}:{$sourceNs[1]}"; $actionXsd = << EOF; $deleteActionsXsd[] = $actionXsd; } if (!empty($updateActionsXsd)) { $updateActionsXsd = implode("\n", $updateActionsXsd); $updateActionsXsd = << {$updateActionsXsd} EOF; } else { $updateActionsXsd = ''; } if (!empty($insertActionsXsd)) { $insertActionsXsd = implode("\n", $insertActionsXsd); $insertActionsXsd = << {$insertActionsXsd} EOF; } else { $insertActionsXsd = ''; } if (!empty($deleteActionsXsd)) { $deleteActionsXsd = implode("\n", $deleteActionsXsd); $deleteActionsXsd = << {$deleteActionsXsd} EOF; } else { $deleteActionsXsd = ''; } $convertTransactionXslString = ''; $convertTransactionXslString .= << {$updateActionsXsd} {$insertActionsXsd} {$deleteActionsXsd} EOF; if($DBG){echo 'L.' . __LINE__ . ' $convertTransactionXslString:' . $convertTransactionXslString . "\n";} $requestXml = new DOMDocument(); $requestXml->loadXml($requestXmlString); $convertTransactionXsl = new DOMDocument(); $convertTransactionXsl->loadXml($convertTransactionXslString); $proc = new XSLTProcessor(); $proc->importStylesheet($convertTransactionXsl); return $proc->transformToXML($requestXml); } public function _validateConvertedTransactionXml($convertedTransaction, $sourceNsList) { $DBG = (V::get('DBG_XSD', '', $_GET) > 0);// TODO: Profiler if($DBG){echo 'L.' . __LINE__ . ' sourceNsList:';print_r($sourceNsList);echo "\n";} $dom = new DOMDocument('1.0', 'utf-8'); $dom->formatOutput = true; $dom->preserveWhiteSpace = false; $rootNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:schema'); $dom->appendChild($rootNode); $rootNode->setAttribute('elementFormDefault', 'qualified'); $rootNode->setAttribute('version', '1.0'); {// $elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element'); $rootNode->appendChild($elNode); $elNode->setAttribute('name', 'Transaction'); $elNode->setAttribute('type', 'TransactionType'); $cTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexType'); $rootNode->appendChild($cTypeNode); $cTypeNode->setAttribute('name', 'TransactionType'); $seqNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:sequence'); $cTypeNode->appendChild($seqNode); $choiceNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:choice'); $seqNode->appendChild($choiceNode); $choiceNode->setAttribute('minOccurs', '0'); $choiceNode->setAttribute('maxOccurs', 'unbounded'); // foreach ($sourceNsList as $nsInd => $sourceNs) { $typeName = "p5_{$sourceNs[0]}:{$sourceNs[1]}"; $updateElementName = "UpdateNs{$nsInd}"; $updateElementType = "UpdateNs{$nsInd}ElementType"; $updateElemNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element'); $choiceNode->appendChild($updateElemNode); $updateElemNode->setAttribute('name', $updateElementName); $updateElemNode->setAttribute('type', $updateElementType); } // foreach ($sourceNsList as $nsInd => $sourceNs) { $typeName = "p5_{$sourceNs[0]}:{$sourceNs[1]}"; $insertElementName = "InsertNs{$nsInd}"; $insertElementType = "InsertNs{$nsInd}ElementType"; $insertElemNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element'); $choiceNode->appendChild($insertElemNode); $insertElemNode->setAttribute('name', $insertElementName); $insertElemNode->setAttribute('type', $insertElementType); } // foreach ($sourceNsList as $nsInd => $sourceNs) { $typeName = "p5_{$sourceNs[0]}:{$sourceNs[1]}"; $deleteElementName = "DeleteNs{$nsInd}"; $deleteElementType = "DeleteNs{$nsInd}ElementType"; $deleteElemNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element'); $choiceNode->appendChild($deleteElemNode); $deleteElemNode->setAttribute('name', $deleteElementName); $deleteElemNode->setAttribute('type', $deleteElementType); } // $attrNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute'); $cTypeNode->appendChild($attrNode); $attrNode->setAttribute('name', 'version'); $attrNode->setAttribute('type', 'xsd:string'); $attrNode->setAttribute('use', 'required'); $attrNode->setAttribute('fixed', '1.0.0'); $attrNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute'); $cTypeNode->appendChild($attrNode); $attrNode->setAttribute('name', 'service'); $attrNode->setAttribute('type', 'xsd:string'); $attrNode->setAttribute('use', 'required'); $attrNode->setAttribute('fixed', 'WFS'); } foreach ($sourceNsList as $nsInd => $sourceNs) { $transactionTypesList = array(); $transactionTypesList[] = 'Update'; $transactionTypesList[] = 'Insert'; foreach ($transactionTypesList as $transactionType) { $typeName = "p5_{$sourceNs[0]}:{$sourceNs[1]}"; if($DBG){echo 'L.' . __LINE__ . ' TODO: get acl typeName:';print_r($typeName);echo "\n";} $acl = $this->getAclFromTypeName($typeName); $updateElementName = "{$transactionType}Ns{$nsInd}"; $updateElementType = "{$transactionType}Ns{$nsInd}ElementType"; /* */ $updateTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexType'); $rootNode->appendChild($updateTypeNode); $updateTypeNode->setAttribute('name', $updateElementType); { $seqNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:all'); $updateTypeNode->appendChild($seqNode); { $pKeyField = $acl->getPrimaryKeyField(); $fldList = $this->_getFieldListFromAcl($acl); // fields without geometry fields foreach ($fldList as $fldName) { if ($acl->isGeomField($fldName)) continue; $elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element'); $seqNode->appendChild($elNode); $elNode->setAttribute('name', $fldName); $minOccurs = 0; if ($pKeyField == $fldName) { $minOccurs = '1'; } else { $minOccurs = '0'; } $elNode->setAttribute('minOccurs', $minOccurs); $fldType = null; if ($acl->isIntegerField($fldName)) { $fldType = 'xsd:integer'; } else if ($acl->isDecimalField($fldName)) { $fldType = 'xsd:decimal'; } else if ($acl->isDateField($fldName)) { $fldType = 'xsd:date'; } else if ($acl->isDateTimeField($fldName)) { // $fldType = 'xsd:dateTime'; $fldType = null;// 'xsd:string'; $patternDataTime = "(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})(:(\d{2}))?"; // // // // // // // $simpleTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:simpleType'); $restrictionNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:restriction'); $patternNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:pattern'); $restrictionNode->setAttribute('base', 'xsd:string'); $patternNode->setAttribute('value', $patternDataTime); $restrictionNode->appendChild($patternNode); $simpleTypeNode->appendChild($restrictionNode); $elNode->appendChild($simpleTypeNode); // continue;// TODO: ? below added nillable = true, minOccurs = 0, type = $fldType } else if ($acl->isBinaryField($fldName)) { $fldType = 'xsd:base64Binary'; } else { $fldType = 'xsd:string'; } if ($fldType) $elNode->setAttribute('type', $fldType); $elNode->setAttribute('nillable', 'true'); $elNode->setAttribute('minOccurs', '0'); } // only geometry fields foreach ($fldList as $fldName) { if (!$acl->isGeomField($fldName)) continue; $elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element'); $seqNode->appendChild($elNode); $elNode->setAttribute('name', $fldName); $minOccurs = 0; if ($pKeyField == $fldName) { $minOccurs = '1'; } else { $minOccurs = '0'; } $elNode->setAttribute('minOccurs', $minOccurs); if ($acl->isGeomField($fldName)) { //$fldType = 'gml:GeometryPropertyType'; // TODO: use geom types from gml to wkt // TODO: pattern wg atrybutów gml:coordinates decimal="." cs="," ts=" " $patternWkt = '';// TODO: error if empty - unsupported geom type $patternNum = '\-?\d+\.?\d*'; $patternPoint = $patternNum . ',' . $patternNum; $patternPoints = '(' . $patternPoint . ')( ' . $patternPoint . ')+'; $geomType = $acl->getGeomFieldType($fldName); if ('polygon' == $geomType) { // [a-zA-Z]+\(\((\-?\d+\.?\d*,\-?\d+\.?\d*)( (\-?\d+\.?\d*,\-?\d+\.?\d*))+\)\) $patternWkt = '[a-zA-Z]+\(\(' . $patternPoints . '\)\)'; } else if ('linestring' == $geomType) { // [a-zA-Z]+\((\-?\d+\.?\d*,\-?\d+\.?\d*)( (\-?\d+\.?\d*,\-?\d+\.?\d*))+\) $patternWkt = '[a-zA-Z]+\(' . $patternPoints . '\)'; } else if ('point' == $geomType) { // [a-zA-Z]+\(\-?\d\.?\d*,\-?\d\.?\d*\) $patternWkt = '[a-zA-Z]+\(' . $patternPoint . '\)'; } $simpleTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:simpleType'); $restrictionNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:restriction'); $patternNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:pattern'); $restrictionNode->setAttribute('base', 'xsd:string'); $patternNode->setAttribute('value', $patternWkt); $restrictionNode->appendChild($patternNode); $simpleTypeNode->appendChild($restrictionNode); $elNode->appendChild($simpleTypeNode); } $elNode->setAttribute('nillable', 'true'); $elNode->setAttribute('minOccurs', '0'); } } } $attrNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute'); $updateTypeNode->appendChild($attrNode); $attrNode->setAttribute('name', 'typeName'); $attrNode->setAttribute('type', 'xsd:token'); $attrNode->setAttribute('use', 'required'); if ($transactionType == 'Insert') { $attrNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute'); $updateTypeNode->appendChild($attrNode); $attrNode->setAttribute('name', 'typeNsUri'); $attrNode->setAttribute('type', 'xsd:anyURI'); $attrNode->setAttribute('use', 'required'); } if ($transactionType == 'Update') { $attrNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute'); $updateTypeNode->appendChild($attrNode); $attrNode->setAttribute('name', 'featureId'); $attrNode->setAttribute('use', 'required'); $sTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:simpleType'); $attrNode->appendChild($sTypeNode); $resNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:restriction'); $sTypeNode->appendChild($resNode); $resNode->setAttribute('base', 'xsd:string'); $patternNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:pattern'); $resNode->appendChild($patternNode); $patternNode->setAttribute('value', '[a-zA-Z_][a-zA-Z0-9_]*\.[0-9]*'); } } {// 'Delete' $typeName = "p5_{$sourceNs[0]}:{$sourceNs[1]}"; $acl = $this->getAclFromTypeName($typeName); $deleteElementType = "DeleteNs{$nsInd}ElementType"; $deleteTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexType'); $rootNode->appendChild($deleteTypeNode); $deleteTypeNode->setAttribute('name', $deleteElementType); /* */ $attrNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute'); $deleteTypeNode->appendChild($attrNode); $attrNode->setAttribute('name', 'typeName'); $attrNode->setAttribute('type', 'xsd:token'); $attrNode->setAttribute('use', 'required'); /* */ $attrNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute'); $deleteTypeNode->appendChild($attrNode); $attrNode->setAttribute('name', 'featureId'); $attrNode->setAttribute('use', 'required'); $sTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:simpleType'); $attrNode->appendChild($sTypeNode); $resNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:restriction'); $sTypeNode->appendChild($resNode); $resNode->setAttribute('base', 'xsd:string'); $patternNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:pattern'); $resNode->appendChild($patternNode); $patternNode->setAttribute('value', '[a-zA-Z_][a-zA-Z0-9_]*\.[0-9]*'); } } $validateConvertedTransactionXsdString = $dom->saveXml(); if($DBG){echo 'L.' . __LINE__ . ' $validateConvertedTransactionXsdString:';print_r($validateConvertedTransactionXsdString);echo "\n";} $reqXml = new DOMDocument(); $reqXml->loadXml($convertedTransaction); // TODO: fetch PHP Warning: DOMDocument::schemaValidateSource(): Element 'PARENT_ID': 'abc' is not a valid value of the atomic type 'xs:integer'. return $reqXml->schemaValidateSource($validateConvertedTransactionXsdString); } public function getInstanceFeatures($name, $args) { $acl = $this->getAclFromTypeName("{$args['typePrefix']}:{$name}"); $baseNsUri = Api_WfsNs::getBaseWfsUri(); $rootWfsNs = 'p5'; $rootWfsNsUri = "{$baseNsUri}"; $wfsNs = $args['typePrefix']; $wfsNsUri = "{$baseNsUri}/" . ('p5_' == substr($args['typePrefix'], 0, 3)) ? substr($args['typePrefix'], 3) : $args['typePrefix']; $featureTypeUri = $this->getBaseUri() . "?SERVICE=WFS&VERSION=1.0.0&TYPENAME={$args['xsd:type']}&REQUEST=DescribeFeatureType"; header('Content-type: application/xml; charset=utf-8'); $xmlWriter = new Core_XmlWriter(); if (!$xmlWriter) throw new HttpException("Error no XMLWriter", 404); $xmlWriter->openUri('php://output'); $xmlWriter->setIndent(true); $xmlWriter->startDocument('1.0','UTF-8'); $xmlWriter->startElement('wfs:FeatureCollection'); $xmlWriter->writeAttribute('xmlns:wfs', 'http://www.opengis.net/wfs'); $xmlWriter->writeAttribute('xmlns', 'http://www.opengis.net/wfs'); $xmlWriter->writeAttribute('xmlns:gml', 'http://www.opengis.net/gml'); $xmlWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); $xmlWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); $xmlWriter->writeAttribute("xmlns:{$wfsNs}", $wfsNsUri); if (!$simple) $xmlWriter->writeAttribute("xmlns:{$rootWfsNs}", $rootWfsNsUri); $xmlWriter->writeAttribute('xsi:schemaLocation', "{$wfsNsUri} {$featureTypeUri}"); $xmlWriter->writeComment("INSTANCE TABLE: " . Core_AclHelper::getInstanceTable($acl->getRootTableName())); // // // 64 $xmlWriter->endElement();// wfs:FeatureCollection $xmlWriter->endDocument(); exit; } public function _describeInstanceAttributeTable($nsPrefix, $name) { $acl = $this->getAclFromTypeName("{$nsPrefix}:{$name}"); header('Content-type: application/xml; charset=utf-8'); $xmlWriter = new Core_XmlWriter(); if (!$xmlWriter) throw new HttpException("Error no XMLWriter", 404); $xmlWriter->openUri('php://output'); $xmlWriter->setIndent(true); $xmlWriter->startDocument('1.0','UTF-8'); $xmlWriter->startElement('xsd:schema'); $xmlWriter->writeAttribute('xmlns:xsd', 'http://www.w3.org/2001/XMLSchema'); $xmlWriter->writeAttribute('xmlns:gml', 'http://www.opengis.net/gml'); foreach (Api_WfsNs::getNsList() as $uri => $prefix) { $xmlWriter->writeAttribute("xmlns:{$prefix}", $uri); } $xmlWriter->writeAttribute('elementFormDefault', 'qualified'); $xsdInstanceType = $acl->getName() . "_instanceType"; $xsdPrimaryKey = "xsd:string";// TODO: get from $acl $xmlWriter->h('xsd:element', ['name'=>"instance"], [ [ 'xsd:complexType', [ [ 'xsd:sequence', [ [ 'xsd:element', ['name'=>"primaryKey", 'type'=>$xsdPrimaryKey], null ], [ 'xsd:element', ['name'=>"instance_name", 'type'=>$xsdInstanceType], null ], [ 'xsd:element', ['name'=>"instance_type", 'type'=>"xsd:string"], null ],// TODO: instance, derived, matching [ 'xsd:element', ['name'=>"create_author", 'type'=>"xsd:string"], null ], [ 'xsd:element', ['name'=>"create_date", 'type'=>"xsd:dateTime"], null ], [ 'xsd:element', ['name'=>"update_author", 'type'=>"xsd:string"], null ], [ 'xsd:element', ['name'=>"updage_date", 'type'=>"xsd:dateTime"], null ], [ 'xsd:element', ['name'=>"verified", 'type'=>"xsd:integer"], null ], ] ] ] ] ]); $instanceList = (method_exists($acl, 'getInstanceList')) ? array_map(function ($instanceName) { return [ 'xsd:enumeration', ['value'=>$instanceName], null ]; }, $acl->getInstanceList()) : [ [ 'xsd:enumeration', ['value'=>$acl->getName()], null ] ] ; $xmlWriter->h('xsd:simpleType', ['name'=>$xsdInstanceType], [ [ 'xsd:restriction', ['base'=>"xsd:string"], $instanceList ], ]); $xmlWriter->endElement();// xsd:schema $xmlWriter->endDocument(); exit; } public function _getDescribeFeatureType($nsPrefix, $type, $simple = true) { return $this->_getDescribeFeatureTypes(array(array($nsPrefix, $type)), $simple); } public function _parseDescribeFeatureTypeRequest($reqContent, $simple = true) { $parserXml = xml_parser_create(); xml_parser_set_option($parserXml, XML_OPTION_CASE_FOLDING, 0); xml_parser_set_option($parserXml, XML_OPTION_SKIP_WHITE, 1); if (0 == xml_parse_into_struct($parserXml, $reqContent, $tags)) { throw new Exception("Error parsing xml"); } xml_parser_free($parserXml); if (empty($tags)) { throw new Exception("Empty structure from request"); } $rootTagName = V::get('tag', '', $tags[0]); if ('DescribeFeatureType' != $rootTagName) { throw new Api_WfsException("Wrong xml root tag '{$rootTagName}' #" . __LINE__, 501); } $requestXmlTags = $tags; $DBG = (V::get('DBG_XML', '', $_GET) > 0);// TODO: Profiler $rootTagName = V::get('tag', '', $requestXmlTags[0]); if ('DescribeFeatureType' != $rootTagName) { throw new Exception("Parse Request xml error #" . __LINE__); } /*[1] => Array( [tag] => TypeName [type] => complete [level] => 2 [value] => p5_default_db:Rozdzielcza_rurociag_wsg84) */ $typeNames = array(); $totalTypes = count($requestXmlTags) - 1; for ($i = 1; $i < $totalTypes; $i++) { if($DBG){echo "TAG[{$i}]:" . json_encode($requestXmlTags[$i]) . "\n";} $typeNames[] = explode(':', $requestXmlTags[$i]['value'], 2); } //echo "typeNames: " . json_encode($typeNames) . "\n"; return $this->_getDescribeFeatureTypes($typeNames, $simple); } public function _getDescribeFeatureAllTypes($simple = true) { $db = DB::getDB(); $idDefaultDB = $db->_zasob_id; $tblsAcl = $this->_getTableAclList(); foreach ($tblsAcl as $tblAcl) { $dataSourceName = 'default_db';// TODO: getSourceName $tblName = $tblAcl->getName(); $typeNames[] = array("p5_{$dataSourceName}", $tblName); } return $this->_getDescribeFeatureTypes($typeNames, $simple); } // @param $typeNames = array( array( $nsPrefix, $type ) ) public function _getDescribeFeatureTypes($typeNames, $simple = true) { if (empty($typeNames)) throw new HttpException("Feature Type Names not defined", 400); $this->DBG("types:" . json_encode($typeNames), __LINE__, __FUNCTION__, __CLASS__); DBG::log($typeNames, 'array', "DescribeFeatureType \$typeNames"); // TODO: fix namespace BUG for multiple types: // - fetch namespace for first type // - if another object has another namespace then -> import tag $baseNsUri = Api_WfsNs::getBaseWfsUri(); $rootWfsNs = 'p5'; $rootWfsNsUri = "{$baseNsUri}"; $featureTypeUri = Api_WfsNs::getBaseWfsUri() . "?SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType"; header('Content-type: application/xml'); $nsMap = Api_WfsNs::getNsList();// uri => prefix $xsdTargetNamespace = null; { // targetNamespace list($nsPrefix, $objectName) = reset($typeNames); $typeName = "{$nsPrefix}:{$objectName}"; $acl = $this->getAclFromTypeName($typeName); $aclNamespaceUri = Api_WfsNs::getNsUri($acl->getSourceName()); $xsdTargetNamespace = $aclNamespaceUri; if (!array_key_exists($aclNamespaceUri, $nsMap)) $nsMap[$aclNamespaceUri] = $acl->getSourceName(); } $xmlWriter = new Core_XmlWriter(); if (!$xmlWriter) throw new HttpException("Error no XMLWriter", 404); $xmlWriter->openMemory();// openUri('php://output'); $xmlWriter->setIndent(true); $xmlWriter->startDocument('1.0','UTF-8'); $xmlWriter->startElement('xsd:schema'); $xmlWriter->writeAttribute('xmlns:xsd', 'http://www.w3.org/2001/XMLSchema'); $xmlWriter->writeAttribute('xmlns:gml', 'http://www.opengis.net/gml'); foreach (Api_WfsNs::getNsList() as $uri => $prefix) { $xmlWriter->writeAttribute("xmlns:{$prefix}", $uri); } $xmlWriter->writeAttribute('elementFormDefault', "qualified"); if ($xsdTargetNamespace) $xmlWriter->writeAttribute('targetNamespace', $xsdTargetNamespace); $schemaLocations = []; //$schemaLocations[] = 'http://www.opengis.net/wfs http://webgis.regione.sardegna.it:80/geoserver/schemas/wfs/1.0.0/WFS-capabilities.xsd';// @from http://webgis.regione.sardegna.it/geoserver/ows?service=WFS&request=GetCapabilities if (!empty($schemaLocations)) $xmlWriter->writeAttribute('xsi:schemaLocation', implode(' ', $schemaLocations)); $xmlWriter->writeAttribute('version', "1.0.0"); $xmlWriter->h('xsd:import', [ 'namespace' => "http://www.opengis.net/gml", 'schemaLocation' => Request::getPathUri() . "schema/gml/2.1.2/feature.xsd" ], null); foreach ($typeNames as $typeNameEx) { list($nsPrefix, $objectName) = $typeNameEx; $typeName = "{$nsPrefix}:{$objectName}"; $xmlWriter->writeComment("typeName '{$typeName}'"); $acl = $this->getAclFromTypeName($typeName); $aclNamespaceUri = Api_WfsNs::getNsUri($acl->getSourceName()); if (!array_key_exists($aclNamespaceUri, $nsMap)) $nsMap[$aclNamespaceUri] = $acl->getSourceName(); if ($xsdTargetNamespace != $aclNamespaceUri) { $xmlWriter->writeComment("TODO: typeName '{$typeName}' by import namespace '{$aclNamespaceUri}'");// TODO: ; continue; } DBG::log($acl->hasSimpleSchema(), 'array', "\$acl({$typeName})->hasSimpleSchema()"); if ($acl->hasSimpleSchema()) { $simpleSchema = $acl->getSimpleSchema(); $xmlWriter->writeComment("TODO: typeName '{$typeName}' hasSimpleSchema L." . __LINE__); $aliasRefMap = array();// fieldName => namespace uri foreach ($simpleSchema as $ssName => $schema) { if ('root' == $ssName) $ssName = $objectName; foreach ($schema as $fieldName => $field) { if (is_array($field) && !empty($field['@ref']) && false !== strpos($field['@ref'], '/') ) {// @ref_uri $aliasRefMap[ "{$ssName}_{$fieldName}" ] = $field['@ref']; } } } if (!empty($aliasRefMap)) { foreach ($aliasRefMap as $fieldName => $aliasNsUri) { list($nsUri, $prefix, $name) = Api_WfsNs::parseObjectNsUri($aliasNsUri); if (!array_key_exists($nsUri, $nsMap)) $nsMap[$nsUri] = $prefix; $xmlWriter->h('xsd:import', ['namespace' => $nsUri, 'schemaLocation' => "{$nsUri}.xsd"], null); // TODO: real file url -> DescribeFeatureType[Advanced] } } foreach ($simpleSchema as $ssName => $schema) { {// code from Code_AclSimpleSchema if ('root' == $ssName) $ssName = $objectName; // // // // // // // // // // // // // $tnsPrefix = $acl->getSourceName(); $xmlWriter->startElement('xsd:complexType'); $xmlWriter->writeAttribute('name', "{$ssName}Type"); $xmlWriter->startElement('xsd:sequence'); foreach ($schema as $fieldName => $field) { // [@namespace] => default_db/ZALICZKA_POZYCJA/ZaliczkaPozycja // [id] => xsd:integer // [kwota] => xsd:decimal // [korespondencja] => [ '@ref' => Korespondencja ] // [projekt] => [ '@ref' => Projekt ] // TODO: p5:field_name if ('@' == substr($fieldName, 0, 1)) continue;// skip tags $xmlWriter->startElement('xsd:element'); if (!is_array($field)) throw new Exception("Error Processing simpleSchema: '{$ssName}/{$fieldName}'"); if (!empty($field['@type'])) { $xmlWriter->writeAttribute('name', $fieldName); $xmlWriter->writeAttribute('type', $field['@type']); $xmlWriter->writeAttribute('nillable', "true"); } else if (!empty($field['@ref'])) { if (false !== strpos($field['@ref'], '/')) {// @ref_uri $xmlWriter->writeAttribute('ref', "{$tnsPrefix}:{$ssName}_{$fieldName}"); $xmlWriter->writeAttributeNS($rootWfsNs, "name", $rootWfsNsUri, $fieldName); } else { $xmlWriter->writeAttribute('ref', "{$tnsPrefix}:{$field['@ref']}"); if ($fieldName != $field['@ref']) { $xmlWriter->writeAttributeNS($rootWfsNs, "name", $rootWfsNsUri, $fieldName); } } } else { throw new Exception("Error Processing simpleSchema - missing @type or @ref: '{$ssName}/{$fieldName}'"); } if (array_key_exists('@minOccurs', $field)) $xmlWriter->writeAttribute('minOccurs', $field['@minOccurs']); if (array_key_exists('@maxOccurs', $field)) $xmlWriter->writeAttribute('maxOccurs', $field['@maxOccurs']); $xmlWriter->endElement(); // 'xsd:element' } $xmlWriter->endElement(); // 'xsd:sequence' $xmlWriter->endElement(); // 'xsd:complexType' $xmlWriter->startElement('xsd:element'); $xmlWriter->writeAttribute('name', $ssName); $xmlWriter->writeAttribute('type', "{$tnsPrefix}:{$ssName}Type"); if (!$simple) { if (!empty($schema['@namespace'])) {// TODO: @namespace is required? list($nsUri, $prefix, $name) = Api_WfsNs::parseObjectNsUri($schema['@namespace']); $xmlWriter->writeAttributeNS($rootWfsNs, "namespace", $rootWfsNsUri, "{{$nsUri}}{$name}"); } } $xmlWriter->endElement(); // 'xsd:element' } } if (!empty($aliasRefMap)) { foreach ($aliasRefMap as $fieldName => $aliasNsUri) { list($nsUri, $prefix, $name) = Api_WfsNs::parseObjectNsUri($aliasNsUri); $xmlWriter->h('xsd:element', ['name' => $fieldName, 'type' => "{$prefix}:{$name}Type"], null); } } } else { $objectXsdName = "{$objectName}Type"; $xmlWriter->startElement('xsd:complexType'); $xmlWriter->writeAttribute('name', $objectXsdName); // if (!$simple) $xmlWriter->writeAttribute("xlmns:{$rootWfsNs}", $rootWfsNsUri); if (!$simple) $xmlWriter->writeAttributeNS($rootWfsNs, "web_link", $rootWfsNsUri, Request::getPathUri() . "index.php?_route=ViewTableAjax&namespace=" . $acl->getNamespace()); if (!$simple && ($lastUpdateDate = $acl->lastUpdateDate())) $xmlWriter->writeAttributeNS($rootWfsNs, "last_update_date", $rootWfsNsUri, $lastUpdateDate); $xmlWriter->startElement('xsd:complexContent'); $xmlWriter->startElement('xsd:extension'); $xmlWriter->writeAttribute('base', "gml:AbstractFeatureType"); $xmlWriter->startElement('xsd:sequence'); $pKeyField = $acl->getPrimaryKeyField(); $p5Attributes = ($simple)? array() : $acl->getAttributesFromZasoby(); $fldList = $this->_getFieldListFromAcl($acl); foreach ($fldList as $fldName) { $xmlWriter->startElement('xsd:element'); // TODO: get minOccurs from $acl->xsd() $xmlWriter->writeAttribute('minOccurs', (method_exists($acl, 'getXsdMinOccurs')) ? $acl->getXsdMinOccurs($fldName) : (($pKeyField == $fldName) ? '1' : '0') ); $xmlWriter->writeAttribute('maxOccurs', (method_exists($acl, 'getXsdMaxOccurs')) ? $acl->getXsdMaxOccurs($fldName) : '1' ); $fldType = $acl->getXsdFieldType($fldName); if (!$simple && $acl->isEnumerationField($fldName)) { $fldType = $acl->getSourceName() . ":{$fldName}Type"; } if ('ref:' == substr($fldType, 0, 4)) { $xmlWriter->writeAttribute("ref", substr($fldType, 4)); $xmlWriter->writeAttributeNS($rootWfsNs, "name", $rootWfsNsUri, $fldName); } else if ('local_ref:' == substr($fldType, 0, 10)) { $xmlWriter->writeAttribute("type", "{$fldName}Type"); $xmlWriter->writeAttributeNS($rootWfsNs, "name", $rootWfsNsUri, $fldName); } else if ('alias_ref:' == substr($fldType, 0, 10)) { $xmlWriter->writeAttribute("ref", $acl->getSourceName() . ":{$fldName}"); $xmlWriter->writeAttributeNS($rootWfsNs, "name", $rootWfsNsUri, $fldName); } else { $xmlWriter->writeAttribute('name', $fldName); $xmlWriter->writeAttribute('type', $fldType); $xmlWriter->writeAttribute('nillable', 'true');// nillable not allowed in ref } if (!$simple) { if (!empty($p5Attributes[$fldName])) { $p5attrs = $p5Attributes[$fldName]; if (!empty($p5attrs['id_zasob'])) $xmlWriter->writeAttributeNS($rootWfsNs, "id_zasob", $rootWfsNsUri, $p5attrs['id_zasob']); if (!empty($p5attrs['label'])) $xmlWriter->writeAttributeNS($rootWfsNs, "label", $rootWfsNsUri, $p5attrs['label']); if (!empty($p5attrs['description'])) $xmlWriter->writeAttributeNS($rootWfsNs, "description", $rootWfsNsUri, $p5attrs['description']); } if ($acl->canWriteField($fldName)) $xmlWriter->writeAttributeNS($rootWfsNs, "allow_write", $rootWfsNsUri, "true"); if ($acl->canCreateField($fldName)) $xmlWriter->writeAttributeNS($rootWfsNs, "allow_create", $rootWfsNsUri, "true"); if (!$acl->canReadField($fldName)) $xmlWriter->writeAttributeNS($rootWfsNs, "allow_read", $rootWfsNsUri, "false"); } $xmlWriter->endElement(); // xsd:element } $xmlWriter->endElement(); // xsd:sequence if (!$simple) $xmlWriter->h('xsd:attribute', ['name' => "instance", 'type' => $acl->getSourceName() . ":instanceType"], null); $xmlWriter->endElement(); // xsd:extension $xmlWriter->endElement(); // xsd:complexContent $xmlWriter->endElement(); // xsd:complexType if (!$simple) { $xsdInstanceList = (method_exists($acl, 'getInstanceList')) ? array_map(function ($instanceName) { return [ 'xsd:enumeration', ['value'=>$instanceName], null ]; }, $acl->getInstanceList()) : [ [ 'xsd:enumeration', ['value'=>$acl->getName()], null ] ] ; DBG::log($xsdInstanceList, 'array', "\$xsdInstanceList"); $xmlWriter->h('xsd:simpleType', ['name' => 'instanceType'], [ [ 'xsd:restriction', ['base' => 'xsd:string'], $xsdInstanceList ] ]); } $xmlWriter->h('xsd:element', ['name' => $objectName, 'type' => $acl->getSourceName() . ':' . $objectXsdName, 'substitutionGroup'=>"gml:_Feature"], null); foreach ($fldList as $fldName) { $fldType = $acl->getXsdFieldType($fldName); if ('alias_ref:' == substr($fldType, 0, 10)) { $localRefType = substr($fldType, 10); $xmlWriter->h('xsd:element', ['name' => $fldName, 'type' => $localRefType], null); } else if ('local_ref:' == substr($fldType, 0, 10)) { $localRefType = substr($fldType, 10); $xmlWriter->writeComment("TODO: "); } } if (!$simple) { foreach ($fldList as $fldName) { if (!$acl->isEnumerationField($fldName)) continue; $xsdEnumList = []; $enum = $acl->getEnumerations($fldName); foreach ($enum as $val => $label) { $xsdEnum = ['xsd:enumeration', ['value' => $val], null]; if (!empty($p5Attributes[$fldName]['valuesMap'][$val])) { $xsdEnum[1]["xmlns:{$rootWfsNs}"] = $rootWfsNsUri; $xsdEnum[1]["{$rootWfsNs}:label"] = $p5Attributes[$fldName]['valuesMap'][$val]; } $xsdEnumList[] = $xsdEnum; } $xmlWriter->h('xsd:simpleType', ['name' => "{$fldName}Type"], [ [ 'xsd:restriction', ['base' => "xsd:string"], $xsdEnumList ] ]); } } } } $xmlWriter->endElement(); // 'xsd:schema' $xmlWriter->endDocument(); echo $xmlWriter->outputMemory($flush = true); } public function _getTableAclList() {// Use only Tables from default_db $tblAclList = array(); $idDefaultDB = DB::getPDO()->getZasobId(); $fullTblAclList = $this->_usrAcl->getTablesAcl(); foreach ($fullTblAclList as $tblAcl) { if ($idDefaultDB != $tblAcl->getDB()) {// hide non default_db tables continue; } // $dataSourceName = 'default_db';// TODO: getSourceName // $tblName = $tblAcl->getName(); // try { // $acl = $this->getAclFromTypeName($typeName = "p5_{$dataSourceName}:{$tblName}"); // } catch (Exception $e) { // // echo "Error for table({$tblName}): " . $e->getMessage() . "\n"; // } // if (!$acl) { // // TODO: error log msg // continue; // } $tblAclList[] = $tblAcl; } return $tblAclList; } public function _getFieldListFromAcl($acl) { $fldList = $acl->getRealFieldListByIdZasob(); return $fldList; } public function setLogger($logger) { $this->_logger = $logger; } public function DBG($reqLog, $lineNr = null, $funName = null, $className = null) { if (!$this->_logger) return; $this->_logger->DBG($reqLog, $lineNr, $funName, $className); } }