function parseFilter($filter, $table, $operator = "=") { global $postgisObject; global $postgisschema; global $srs; $table = dropAllNameSpaces($table); //die($table); $st = \app\inc\Model::explodeTableName($table); if (!$st['schema']) { $st['schema'] = $postgisschema; } $primeryKey = $postgisObject->getPrimeryKey($st['schema'] . "." . $st['table']); $serializer_options = array('indent' => ' '); $Serializer =& new XML_Serializer($serializer_options); if (!is_array($filter[0]) && isset($filter) && !(isset($filter['And']) or isset($filter['Or']) or isset($filter['Not']))) { $filter = array(0 => $filter); } $sridOfTable = $postgisObject->getGeometryColumns($table, "srid"); $i = 0; foreach ($filter as $key => $arr) { if ($key == "And" || $key == "Or") { $BoolOperator = $key; } if (isset($arr['Not'])) { //$where[] = parseFilter($arr['Not'],$table,"<>"); } if (isset($arr['And']) || isset($arr['Or'])) { // Recursive call $where[] = parseFilter($arr, $table); } // PropertyIsEqualTo $arr['PropertyIsEqualTo'] = addDiminsionOnArray($arr['PropertyIsEqualTo']); if (is_array($arr['PropertyIsEqualTo'])) { foreach ($arr['PropertyIsEqualTo'] as $value) { $where[] = $value['PropertyName'] . "=" . $postgisObject->quote($value['Literal']); } } // PropertyIsNotEqualTo $arr['PropertyIsNotEqualTo'] = addDiminsionOnArray($arr['PropertyIsNotEqualTo']); if (is_array($arr['PropertyIsNotEqualTo'])) { foreach ($arr['PropertyIsNotEqualTo'] as $value) { $where[] = $value['PropertyName'] . "<>'" . $value['Literal'] . "'"; } } // PropertyIsLessThan $arr['PropertyIsLessThan'] = addDiminsionOnArray($arr['PropertyIsLessThan']); if (is_array($arr['PropertyIsLessThan'])) { foreach ($arr['PropertyIsLessThan'] as $value) { $where[] = $value['PropertyName'] . "<'" . $value['Literal'] . "'"; } } // PropertyIsGreaterThan $arr['PropertyIsGreaterThan'] = addDiminsionOnArray($arr['PropertyIsGreaterThan']); if (is_array($arr['PropertyIsGreaterThan'])) { foreach ($arr['PropertyIsGreaterThan'] as $value) { $where[] = $value['PropertyName'] . ">'" . $value['Literal'] . "'"; } } // PropertyIsLessThanOrEqualTo $arr['PropertyIsLessThanOrEqualTo'] = addDiminsionOnArray($arr['PropertyIsLessThanOrEqualTo']); if (is_array($arr['PropertyIsLessThanOrEqualTo'])) { foreach ($arr['PropertyIsLessThanOrEqualTo'] as $value) { $where[] = $value['PropertyName'] . "<='" . $value['Literal'] . "'"; } } //PropertyIsGreaterThanOrEqualTo $arr['PropertyIsGreaterThanOrEqualTo'] = addDiminsionOnArray($arr['PropertyIsGreaterThanOrEqualTo']); if (is_array($arr['PropertyIsGreaterThanOrEqualTo'])) { foreach ($arr['PropertyIsGreaterThanOrEqualTo'] as $value) { $where[] = $value['PropertyName'] . ">='" . $value['Literal'] . "'"; } } //PropertyIsLike $arr['PropertyIsLike'] = addDiminsionOnArray($arr['PropertyIsLike']); if (is_array($arr['PropertyIsLike'])) { foreach ($arr['PropertyIsLike'] as $value) { $where[] = $value['PropertyName'] . " LIKE '%" . $value['Literal'] . "%'"; } } //PropertyIsBetween $arr['PropertyIsBetween'] = addDiminsionOnArray($arr['PropertyIsBetween']); if (is_array($arr['PropertyIsBetween'])) { foreach ($arr['PropertyIsBetween'] as $value) { if ($value['LowerBoundary']) { $w[] = $value['PropertyName'] . " > '" . $value['LowerBoundary']['Literal'] . "'"; } if ($value['UpperBoundary']) { $w[] = $value['PropertyName'] . " < '" . $value['UpperBoundary']['Literal'] . "'"; } } $where[] = implode(" AND ", $w); } // FeatureID if (!is_array($arr['FeatureId'][0]) && isset($arr['FeatureId'])) { $arr['FeatureId'] = array(0 => $arr['FeatureId']); } if (is_array($arr['FeatureId'])) { foreach ($arr['FeatureId'] as $value) { $value['fid'] = preg_replace("/{$table}\\./", "", $value['fid']); // remove table name $where[] = "{$primeryKey['attname']}=" . $value['fid']; } } // GmlObjectId $arr['GmlObjectId'] = addDiminsionOnArray($arr['GmlObjectId']); if (is_array($arr['GmlObjectId'])) { foreach ($arr['GmlObjectId'] as $value) { $value['id'] = preg_replace("/{$table}\\./", "", $value['id']); // remove table name $where[] = "{$primeryKey['attname']}=" . $value['id']; } } //Intersects $arr['Intersects'] = addDiminsionOnArray($arr['Intersects']); if (is_array($arr['Intersects'])) { foreach ($arr['Intersects'] as $value) { $status = $Serializer->serialize($value); $gmlCon = new gmlConverter(); //logfile::write($Serializer->getSerializedData()."\n\n"); $wktArr = $gmlCon->gmlToWKT($Serializer->getSerializedData(), array()); $sridOfFilter = $wktArr[1][0]; if (!$sridOfFilter) { $sridOfFilter = $srs; } // If no filter on BBOX we think it must be same as the requested srs if (!$sridOfFilter) { $sridOfFilter = $sridOfTable; } // If still no filter on BBOX we set it to native srs $where[] = "ST_Intersects" . "(public.ST_Transform(public.ST_GeometryFromText('" . $wktArr[0][0] . "'," . $sridOfFilter . "),{$sridOfTable})," . $value['PropertyName'] . ")"; unset($gmlCon); unset($wktArr); } } //BBox if ($arr['BBOX']) { if (is_array($arr['BBOX']['Box']['coordinates'])) { $arr['BBOX']['Box']['coordinates']['_content'] = str_replace(" ", ",", $arr['BBOX']['Box']['coordinates']['_content']); $coordsArr = explode(",", $arr['BBOX']['Box']['coordinates']['_content']); } else { $arr['BBOX']['Box']['coordinates'] = str_replace(" ", ",", $arr['BBOX']['Box']['coordinates']); $coordsArr = explode(",", $arr['BBOX']['Box']['coordinates']); } if (is_array($arr['BBOX']['Box'])) { $sridOfFilter = gmlConverter::parseEpsgCode($arr['BBOX']['Box']['srsName']); $axisOrder = gmlConverter::getAxisOrderFromEpsg($arr['BBOX']['Box']['srsName']); if (!$sridOfFilter) { $sridOfFilter = $srs; } // If no filter on BBOX we think it must be same as the requested srs if (!$sridOfFilter) { $sridOfFilter = $sridOfTable; } // If still no filter on BBOX we set it to native srs } if (is_array($arr['BBOX']['Envelope'])) { $coordsArr = array_merge(explode(" ", $arr['BBOX']['Envelope']['lowerCorner']), explode(" ", $arr['BBOX']['Envelope']['upperCorner'])); ob_start(); print_r($arr['BBOX']['Envelope']); print_r($coordsArr); $data = ob_get_clean(); //logfile::write($data); $sridOfFilter = gmlConverter::parseEpsgCode($arr['BBOX']['Envelope']['srsName']); $axisOrder = gmlConverter::getAxisOrderFromEpsg($arr['BBOX']['Envelope']['srsName']); if (!$sridOfFilter) { $sridOfFilter = $srs; } // If no filter on BBOX we think it must be same as the requested srs if (!$sridOfFilter) { $sridOfFilter = $sridOfTable; } // If still no filter on BBOX we set it to native srs } if ($axisOrder == "longitude") { $where[] = "ST_Intersects" . "(public.ST_Transform(public.ST_GeometryFromText('POLYGON((" . $coordsArr[0] . " " . $coordsArr[1] . "," . $coordsArr[0] . " " . $coordsArr[3] . "," . $coordsArr[2] . " " . $coordsArr[3] . "," . $coordsArr[2] . " " . $coordsArr[1] . "," . $coordsArr[0] . " " . $coordsArr[1] . "))'," . $sridOfFilter . "),{$sridOfTable})," . "\"" . ($arr['BBOX']['PropertyName'] ?: $postgisObject->getGeometryColumns($table, "f_geometry_column")) . "\")"; } else { $where[] = "ST_Intersects" . "(public.ST_Transform(public.ST_GeometryFromText('POLYGON((" . $coordsArr[1] . " " . $coordsArr[0] . "," . $coordsArr[3] . " " . $coordsArr[0] . "," . $coordsArr[3] . " " . $coordsArr[2] . "," . $coordsArr[1] . " " . $coordsArr[2] . "," . $coordsArr[1] . " " . $coordsArr[0] . "))'," . $sridOfFilter . "),{$sridOfTable})," . "\"" . ($arr['BBOX']['PropertyName'] ?: $postgisObject->getGeometryColumns($table, "f_geometry_column")) . "\")"; } /*$where[] = "public.ST_Transform(public.ST_GeometryFromText('POLYGON((".$coordsArr[0]." ".$coordsArr[1].",".$coordsArr[0]." ".$coordsArr[3].",".$coordsArr[2]." ".$coordsArr[3].",".$coordsArr[2]." ".$coordsArr[1].",".$coordsArr[0]." ".$coordsArr[1]."))'," .$sridOfFilter ."),$sridOfTable) && ".$arr['BBOX']['PropertyName'];*/ } // End of filter parsing $i++; } ob_start(); print_r($where); ob_get_clean(); if (!$BoolOperator) { $BoolOperator = "OR"; } return "(" . implode(" " . $BoolOperator . " ", $where) . ")"; }
function doParse($arr) { global $postgisObject; global $user; global $postgisschema; global $layerObj; global $parentUser; global $transaction; global $db; $serializer_options = array('indent' => ' '); // We start sql BEGIN block $postgisObject->connect("PDO"); $postgisObject->begin(); $Serializer = new XML_Serializer($serializer_options); $workflowData = array(); foreach ($arr as $key => $featureMember) { if ($key == "Insert") { if (!is_array($featureMember[0]) && isset($featureMember)) { $featureMember = array(0 => $featureMember); } foreach ($featureMember as $hey) { foreach ($hey as $typeName => $feature) { $typeName = dropAllNameSpaces($typeName); if (is_array($feature)) { // Skip handles // Remove ns from properties foreach ($feature as $field => $value) { $split = explode(":", $field); if ($split[1]) { $feature[dropAllNameSpaces($field)] = $value; unset($feature[$field]); } } // Check if table is versioned or has workflow. Add fields when clients doesn't send unaltered fields. $tableObj = new table($postgisschema . "." . $typeName); if (!array_key_exists("gc2_version_user", $feature) && $tableObj->versioning) { $feature["gc2_version_user"] = null; } if (!array_key_exists("gc2_status", $feature) && $tableObj->workflow) { $feature["gc2_status"] = null; } if (!array_key_exists("gc2_workflow", $feature) && $tableObj->workflow) { $feature["gc2_workflow"] = null; } foreach ($feature as $field => $value) { $fields[] = $field; $roleObj = $layerObj->getRole($postgisschema, $typeName, $user); $role = $roleObj["data"][$user]; if ($tableObj->workflow && ($role == "none" && $parentUser == false)) { makeExceptionReport("You don't have a role in the workflow of '{$typeName}'"); } if (is_array($value)) { // Must be geom if array // We serialize the geometry back to XML for parsing $Serializer->serialize($value); $gmlCon = new gmlConverter(); $wktArr = $gmlCon->gmlToWKT($Serializer->getSerializedData(), array()); $values[] = array("{$field}" => $wktArr[0][0], "srid" => $wktArr[1][0]); unset($gmlCon); unset($wktArr); //Log::write($Serializer->getSerializedData()."\n\n"); } elseif ($field == "gc2_version_user") { $values[] = $user; } elseif ($field == "gc2_status") { switch ($role) { case "author": $values[] = 1; break; case "reviewer": $values[] = 2; break; case "publisher": $values[] = 3; break; default: $values[] = 3; break; } } elseif ($field == "gc2_workflow") { switch ($role) { case "author": $values[] = "hstore('author', '{$user}')"; break; case "reviewer": $values[] = "hstore('reviewer', '{$user}')"; break; case "publisher": $values[] = "hstore('publisher', '{$user}')"; break; default: $values[] = "''"; break; } } else { $values[] = pg_escape_string($value); } } $forSql['tables'][] = $typeName; $forSql['fields'][] = $fields; $forSql['values'][] = $values; $fields = array(); $values = array(); //TODO check //$field = ""; //$value = ""; // Start HTTP basic authentication $auth = $postgisObject->getGeometryColumns($postgisschema . "." . $typeName, "authentication"); if ($auth == "Write" or $auth == "Read/write") { $HTTP_FORM_VARS["TYPENAME"] = $typeName; include 'inc/http_basic_authen.php'; } // End HTTP basic authentication } } } } if ($key == "Update") { if (!is_array($featureMember[0]) && isset($featureMember)) { $featureMember = array(0 => $featureMember); } $fid = 0; foreach ($featureMember as $hey) { $hey["typeName"] = dropAllNameSpaces($hey["typeName"]); if (!is_array($hey['Property'][0]) && isset($hey['Property'])) { $hey['Property'] = array(0 => $hey['Property']); } // Check if table is versioned or has workflow. Add fields when clients doesn't send unaltered fields. $tableObj = new table($postgisschema . "." . $hey["typeName"]); foreach ($hey["Property"] as $v) { if ($v["Name"] == "gc2_version_user") { $gc2_version_user_flag = true; } if ($v["Name"] == "gc2_version_start_date") { $gc2_version_start_date_flag = true; } if ($v["Name"] == "gc2_status") { $gc2_status_flag = true; } if ($v["Name"] == "gc2_workflow") { $gc2_workflow_flag = true; } } if (!$gc2_version_user_flag && $tableObj->versioning) { $hey["Property"][] = array("Name" => "gc2_version_user", "Value" => null); } if (!$gc2_version_start_date_flag && $tableObj->versioning) { $hey["Property"][] = array("Name" => "gc2_version_start_date", "Value" => null); } if (!$gc2_status_flag && $tableObj->workflow) { $hey["Property"][] = array("Name" => "gc2_status", "Value" => null); } if (!$gc2_workflow_flag && $tableObj->workflow) { $hey["Property"][] = array("Name" => "gc2_workflow", "Value" => null); } //makeExceptionReport(print_r($hey, true)); foreach ($hey['Property'] as $pair) { $fields[$fid][] = $pair['Name']; $roleObj = $layerObj->getRole($postgisschema, $hey['typeName'], $user); $role = $roleObj["data"][$user]; if ($tableObj->workflow && ($role == "none" && $parentUser == false)) { makeExceptionReport("You don't have a role in the workflow of '{$hey['typeName']}'"); } if (is_array($pair['Value'])) { // Must be geom if array // We serialize the geometry back to XML for parsing $Serializer->serialize($pair['Value']); Log::write($Serializer->getSerializedData() . "\n\n"); $gmlCon = new gmlConverter(); $wktArr = $gmlCon->gmlToWKT($Serializer->getSerializedData(), array()); $values[$fid][] = array("{$pair['Name']}" => current($wktArr[0]), "srid" => current($wktArr[1])); unset($gmlCon); unset($wktArr); } else { $values[$fid][] = $pair['Value']; } } $forSql2['tables'][$fid] = $hey['typeName']; $forSql2['fields'] = $fields; $forSql2['values'] = $values; $forSql2['wheres'][$fid] = parseFilter($hey['Filter'], $hey['typeName']); $fid++; // Start HTTP basic authentication $auth = $postgisObject->getGeometryColumns($postgisschema . "." . $hey['typeName'], "authentication"); if ($auth == "Write" or $auth == "Read/write") { $HTTP_FORM_VARS["TYPENAME"] = $hey['typeName']; include 'inc/http_basic_authen.php'; } // End HTTP basic authentication } $pair = array(); $values = array(); $fields = array(); } if ($key == "Delete") { if (!is_array($featureMember[0]) && isset($featureMember)) { $featureMember = array(0 => $featureMember); } foreach ($featureMember as $hey) { $hey['typeName'] = dropAllNameSpaces($hey['typeName']); $forSql3['tables'][] = $hey['typeName']; $forSql3['wheres'][] = parseFilter($hey['Filter'], $hey['typeName']); $roleObj = $layerObj->getRole($postgisschema, $hey['typeName'], $user); $role = $roleObj["data"][$user]; $tableObj = new table($postgisschema . "." . $hey["typeName"]); if ($tableObj->workflow && ($role == "none" && $parentUser == false)) { makeExceptionReport("You don't have a role in the workflow of '{$hey['typeName']}'"); } // Start HTTP basic authentication $auth = $postgisObject->getGeometryColumns($postgisschema . "." . $hey['typeName'], "authentication"); if ($auth == "Write" or $auth == "Read/write") { $HTTP_FORM_VARS["TYPENAME"] = $hey['typeName']; include 'inc/http_basic_authen.php'; } // End HTTP basic authentication } } } echo '<wfs:WFS_TransactionResponse version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd">'; // First we loop through inserts if (sizeof($forSql['tables']) > 0) { for ($i = 0; $i < sizeof($forSql['tables']); $i++) { if ($postgisObject->getGeometryColumns($postgisschema . "." . $forSql['tables'][$i], "editable")) { \app\controllers\Tilecache::bust($postgisschema . "." . $forSql['tables'][$i]); $gc2_workflow_flag = false; $roleObj = $layerObj->getRole($postgisschema, $forSql['tables'][$i], $user); $primeryKey = $postgisObject->getPrimeryKey($postgisschema . "." . $forSql['tables'][$i]); $sql = "INSERT INTO {$postgisschema}.{$forSql['tables'][$i]} ("; foreach ($forSql['fields'][$i] as $key => $field) { if ($field != "gc2_version_uuid" && $field != "gc2_version_start_date" && $field != "gc2_version_gid") { $fields[] = "\"" . $field . "\""; } } $sql .= implode(",", $fields); unset($fields); $sql .= ") VALUES("; foreach ($forSql['values'][$i] as $key => $value) { if ($forSql['fields'][$i][$key] != "gc2_version_uuid" && $forSql['fields'][$i][$key] != "gc2_version_start_date" && $forSql['fields'][$i][$key] != "gc2_version_gid") { if (is_array($value)) { $values[] = "public.ST_Transform(public.ST_GeometryFromText('" . current($value) . "'," . next($value) . ")," . $postgisObject->getGeometryColumns($postgisschema . "." . $forSql['tables'][$i], "srid") . ")"; } elseif (!$value) { $values[] = "NULL"; } elseif ($forSql['fields'][$i][$key] == "gc2_workflow") { // Don't quote a hstore $values[] = $value; $gc2_workflow_flag = true; } else { $values[] = $postgisObject->quote($value); } } } $sql .= implode(",", $values); unset($values); $sql .= ") RETURNING {$primeryKey['attname']} as gid"; // The query will return the new key if ($gc2_workflow_flag) { $sql .= ",gc2_version_gid,gc2_status,gc2_workflow," . \app\inc\PgHStore::toPg($roleObj["data"]) . " as roles"; $gc2_workflow_flag = false; } $sqls['insert'][] = $sql; } else { $notEditable[$forSql['tables'][0]] = true; } } } // Second we loop through updates if (sizeof($forSql2['tables']) > 0) { for ($i = 0; $i < sizeof($forSql2['tables']); $i++) { if ($postgisObject->getGeometryColumns($postgisschema . "." . $forSql2['tables'][$i], "editable")) { \app\controllers\Tilecache::bust($postgisschema . "." . $forSql2['tables'][$i]); $primeryKey = $postgisObject->getPrimeryKey($postgisschema . "." . $forSql2['tables'][$i]); $tableObj = new table($postgisschema . "." . $forSql2['tables'][$i]); if ($tableObj->versioning) { // Get original feature $query = "SELECT * FROM {$postgisschema}.{$forSql2['tables'][$i]} WHERE {$forSql2['wheres'][$i]}"; $res = $postgisObject->execQuery($query); $originalFeature = $postgisObject->fetchRow($res); // Check if feature is ended if ($originalFeature["gc2_version_end_date"]) { makeExceptionReport("You can't change the history!"); } // Clone original feature for ended version $intoArr = array(); $selectArr = array(); foreach ($originalFeature as $k => $v) { if ($k != $primeryKey['attname']) { if ($k == "gc2_version_end_date") { $intoArr[] = $k; $selectArr[] = "now()"; } else { $intoArr[] = $selectArr[] = $k; } } } $sql = "INSERT INTO {$postgisschema}.{$forSql2['tables'][$i]}("; $sql .= implode(",", $intoArr); $sql .= ")"; $sql .= " SELECT "; $sql .= implode(",", $selectArr); $sql .= " FROM {$postgisschema}.{$forSql2['tables'][$i]}"; $sql .= " WHERE {$forSql2['wheres'][$i]}"; //makeExceptionReport($sql); $postgisObject->execQuery($sql); } $sql = "UPDATE {$postgisschema}.{$forSql2['tables'][$i]} SET "; $roleObj = $layerObj->getRole($postgisschema, $forSql2['tables'][$i], $user); $role = $roleObj["data"][$user]; foreach ($forSql2['fields'][$i] as $key => $field) { if (is_array($forSql2['values'][$i][$key])) { // is geometry $value = "public.ST_Transform(public.ST_GeometryFromText('" . current($forSql2['values'][$i][$key]) . "'," . next($forSql2['values'][$i][$key]) . ")," . $postgisObject->getGeometryColumns($postgisschema . "." . $forSql2['tables'][$i], "srid") . ")"; } elseif ($field == "gc2_version_user") { $value = $postgisObject->quote($user); } elseif ($field == "gc2_status") { switch ($role) { case "author": if ($originalFeature[$field] > 1) { makeExceptionReport("This feature has been " . ($originalFeature[$field] == 2 ? "reviewed" : "published") . ", so an author can't edit it."); } $value = 1; break; case "reviewer": if ($originalFeature[$field] > 2) { makeExceptionReport("This feature has been published, so a reviewer can't edit it."); } $value = 2; break; case "publisher": $value = 3; break; default: $value = $originalFeature[$field]; break; } } elseif ($field == "gc2_workflow") { switch ($role) { case "author": $value = "'{$originalFeature[$field]}'::hstore || hstore('author', '{$user}')"; break; case "reviewer": $value = "'{$originalFeature[$field]}'::hstore || hstore('reviewer', '{$user}')"; break; case "publisher": $value = "'{$originalFeature[$field]}'::hstore || hstore('publisher', '{$user}')"; break; default: $value = "'{$originalFeature[$field]}'::hstore"; break; } } elseif ($field == "gc2_version_start_date") { $value = "now()"; } elseif (!$forSql2['values'][$i][$key]) { $value = "NULL"; } else { $value = $postgisObject->quote($forSql2['values'][$i][$key]); // We need to escape the string } $pairs[] = "\"" . $field . "\" =" . $value; } $sql .= implode(",", $pairs); $sql .= " WHERE {$forSql2['wheres'][$i]} RETURNING {$primeryKey['attname']} as gid"; if ($tableObj->workflow) { $sql .= ",gc2_version_gid,gc2_status,gc2_workflow," . \app\inc\PgHStore::toPg($roleObj["data"]) . " as roles"; } //makeExceptionReport($sql); unset($pairs); $sqls['update'][] = $sql; } else { $notEditable[$forSql2['tables'][0]] = true; } } } // Third we loop through deletes if (sizeof($forSql3['tables']) > 0) { for ($i = 0; $i < sizeof($forSql3['tables']); $i++) { if ($postgisObject->getGeometryColumns($postgisschema . "." . $forSql3['tables'][$i], "editable")) { \app\controllers\Tilecache::bust($postgisschema . "." . $forSql3['tables'][$i]); $primeryKey = $postgisObject->getPrimeryKey($postgisschema . "." . $forSql3['tables'][$i]); $tableObj = new table($postgisschema . "." . $forSql3['tables'][$i]); if ($tableObj->versioning) { // Check if its history $res = $postgisObject->execQuery("SELECT gc2_version_end_date FROM {$postgisschema}.{$forSql3['tables'][$i]} WHERE {$forSql3['wheres'][$i]}", "PDO", "select"); $checkRow = $postgisObject->fetchRow($res); if ($checkRow["gc2_version_end_date"]) { makeExceptionReport("You can't change the history!"); } // Update old record start $sql = "UPDATE {$postgisschema}.{$forSql3['tables'][$i]} SET gc2_version_end_date = now(), gc2_version_user='******'"; if ($tableObj->workflow) { // get original feature from feature $query = "SELECT * FROM {$postgisschema}.{$forSql3['tables'][$i]} WHERE {$forSql3['wheres'][$i]}"; $resStatus = $postgisObject->execQuery($query); $originalFeature = $postgisObject->fetchRow($resStatus); $status = $originalFeature["gc2_status"]; // Get role $roleObj = $layerObj->getRole($postgisschema, $forSql3['tables'][$i], $user); $role = $roleObj["data"][$user]; switch ($role) { case "author": if ($status > 1) { makeExceptionReport("This feature has been " . ($status == 2 ? "reviewed" : "published") . ", so an author can't delete it."); } $value = 1; break; case "reviewer": if ($status > 2) { makeExceptionReport("This feature has been published so a reviewer can't delete it."); } $value = 2; break; case "publisher": $value = 3; break; default: $value = $status; break; } $sql .= ", gc2_status = {$value}"; } // Update workflow if ($tableObj->workflow) { $workflow = $originalFeature["gc2_workflow"]; switch ($role) { case "author": $value = "'{$workflow}'::hstore || hstore('author', '{$user}')"; break; case "reviewer": $value = "'{$workflow}'::hstore || hstore('reviewer', '{$user}')"; break; case "publisher": $value = "'{$workflow}'::hstore || hstore('publisher', '{$user}')"; break; default: $value = "'{$workflow}'::hstore"; break; } $sql .= ", gc2_workflow = {$value}"; } $sql .= " WHERE {$forSql3['wheres'][$i]} RETURNING {$primeryKey['attname']} as gid"; if ($tableObj->workflow) { $sql .= ",gc2_version_gid,gc2_status,gc2_workflow," . \app\inc\PgHStore::toPg($roleObj["data"]) . " as roles"; } $sqls['delete'][] = $sql; // Update old record end } else { $sqls['delete'][] = "DELETE FROM {$postgisschema}.{$forSql3['tables'][$i]} WHERE {$forSql3['wheres'][$i]} RETURNING {$primeryKey['attname']} as gid"; } } else { $notEditable[$forSql3['tables'][0]] = true; } } } // We fire the sqls if (isset($sqls)) { foreach ($sqls as $operation => $sql) { foreach ($sql as $singleSql) { $results[$operation][] = $postgisObject->execQuery($singleSql, "PDO", "select"); // Returning PDOStatement object Log::write("Sqls fired\n"); Log::write("{$singleSql}\n"); } } } // If a layer is not editable, PDOerror is set. if (sizeof($notEditable) > 0) { $postgisObject->PDOerror[0] = "Layer not editable"; } // WFS message echo '<wfs:Message>'; echo '</wfs:Message>'; // TransactionResult if (sizeof($postgisObject->PDOerror) == 0) { echo '<wfs:TransactionResult handle="mygeocloud-WFS-default-handle"><wfs:Status><wfs:SUCCESS/></wfs:Status></wfs:TransactionResult>'; } else { echo '<wfs:TransactionResult handle="mygeocloud-WFS-default-handle"><wfs:Status><wfs:FAILURE/></wfs:Status></wfs:TransactionResult>'; Log::write("Error in\n"); foreach ($postgisObject->PDOerror as $str) { Log::write("{$str}\n"); } Log::write("ROLLBACK\n"); $postgisObject->rollback(); $results['insert'] = NULL; // Was object $results['update'] = NULL; // Was object $results['delete'] = 0; makeExceptionReport($postgisObject->PDOerror); // This output a exception and kills the script } // InsertResult if (sizeof($results['insert']) > 0) { if (isset($forSql['tables'])) { reset($forSql['tables']); } echo '<wfs:InsertResult>'; foreach ($results['insert'] as $res) { echo '<ogc:FeatureId fid="'; if (isset($forSql['tables'])) { echo current($forSql['tables']) . "."; } $row = $postgisObject->fetchRow($res); echo $row['gid']; echo '"/>'; if (isset($row["gc2_workflow"])) { $workflowData[] = array("schema" => $postgisschema, "table" => current($forSql['tables']), "gid" => $row['gid'], "user" => $user, "status" => $row['gc2_status'], "workflow" => $row['gc2_workflow'], "roles" => $row['roles'], "version_gid" => $row['gc2_version_gid'], "operation" => "insert"); } if (isset($forSql['tables'])) { next($forSql['tables']); } } echo '</wfs:InsertResult>'; } // UpdateResult if (sizeof($results['update']) > 0) { if (isset($forSql2['tables'])) { reset($forSql2['tables']); } echo '<wfs:UpdateResult>'; foreach ($results['update'] as $res) { echo '<ogc:FeatureId fid="'; if (isset($forSql2['tables'])) { echo current($forSql2['tables']) . "."; } $row = $postgisObject->fetchRow($res); echo $row['gid']; echo '" />'; if (isset($row["gc2_workflow"])) { $workflowData[] = array("schema" => $postgisschema, "table" => current($forSql2['tables']), "gid" => $row['gid'], "user" => $user, "status" => $row['gc2_status'], "workflow" => $row['gc2_workflow'], "roles" => $row['roles'], "version_gid" => $row['gc2_version_gid'], "operation" => "update"); } if (isset($forSql2['tables'])) { next($forSql2['tables']); } } echo '</wfs:UpdateResult>'; } // deleteResult if (sizeof($results['delete']) > 0) { if (isset($forSql3['tables'])) { reset($forSql3['tables']); } foreach ($results['delete'] as $res) { $row = $postgisObject->fetchRow($res); if (isset($row["gc2_workflow"])) { $workflowData[] = array("schema" => $postgisschema, "table" => current($forSql3['tables']), "gid" => $row['gid'], "user" => $user, "status" => $row['gc2_status'], "workflow" => $row['gc2_workflow'], "roles" => $row['roles'], "version_gid" => $row['gc2_version_gid'], "operation" => "delete"); } if (isset($forSql2['tables'])) { next($forSql2['tables']); } } } // TransactionSummary echo '<wfs:TransactionSummary>'; if (isset($results)) { foreach ($results as $operation => $result) { if ($operation == "insert") { echo "<wfs:totalInserted>" . sizeof($result) . "</wfs:totalInserted>"; } if ($operation == "update") { echo "<wfs:totalUpdated>" . sizeof($result) . "</wfs:totalUpdated>"; } if ($operation == "delete") { echo "<wfs:totalDeleted>" . sizeof($result) . "</wfs:totalDeleted>"; } } } echo '</wfs:TransactionSummary>'; echo '</wfs:WFS_TransactionResponse>'; if (sizeof($workflowData) > 0) { $sqls = array(); foreach ($workflowData as $w) { $sql = "INSERT INTO settings.workflow (f_schema_name,f_table_name,gid,status,gc2_user,roles,workflow,version_gid,operation)"; $sql .= " VALUES('{$w["schema"]}','{$w["table"]}',{$w["gid"]},{$w["status"]},'{$w["user"]}','{$w["roles"]}'::hstore,'{$w["workflow"]}'::hstore,{$w["version_gid"]},'{$w["operation"]}')"; $sqls[] = $sql; } // We fire the sqls foreach ($sqls as $sql) { $postgisObject->execQuery($sql, "PDO", "transaction"); } if (sizeof($postgisObject->PDOerror) > 0) { makeExceptionReport($postgisObject->PDOerror); // This output a exception and kills the script } } //makeExceptionReport(print_r($sqls, true)); $postgisObject->commit(); $postgisObject->free($result); }