Exemplo n.º 1
0
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) . ")";
}
Exemplo n.º 2
0
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);
}