40#include <QRegularExpression>
41#include <QRegularExpressionMatch>
48 void addTransactionResult( QDomDocument &responseDoc, QDomElement &resultsElem,
49 const QString &locator,
const QString &message );
60 response.
setHeader(
"Content-Type",
"text/xml; charset=utf-8" );
61 response.
write( doc.toByteArray() );
75 if ( doc.setContent( request.
data(),
true, &errorMsg ) )
77 QDomElement docElem = doc.documentElement();
86 if ( actionCount == 0 )
97 QDomElement respElem = resp.createElement( QStringLiteral(
"TransactionResponse" ) );
98 respElem.setAttribute( QStringLiteral(
"xmlns" ),
WFS_NAMESPACE );
99 respElem.setAttribute( QStringLiteral(
"xmlns:xsi" ), QStringLiteral(
"http://www.w3.org/2001/XMLSchema-instance" ) );
100 respElem.setAttribute( QStringLiteral(
"xsi:schemaLocation" ),
WFS_NAMESPACE +
" http://schemas.opengis.net/wfs/1.1.0/wfs.xsd" );
101 respElem.setAttribute( QStringLiteral(
"xmlns:ogc" ),
OGC_NAMESPACE );
102 respElem.setAttribute( QStringLiteral(
"version" ), QStringLiteral(
"1.1.0" ) );
103 resp.appendChild( respElem );
105 int totalInserted = 0;
106 int totalUpdated = 0;
107 int totalDeleted = 0;
111 QDomElement trsElem = doc.createElement( QStringLiteral(
"TransactionResults" ) );
114 QDomElement irsElem = doc.createElement( QStringLiteral(
"InsertResults" ) );
115 QList<transactionInsert>::iterator tiIt = aRequest.
inserts.begin();
116 for ( ; tiIt != aRequest.
inserts.end(); ++tiIt )
122 QString locator = action.
handle;
123 if ( locator.isEmpty() )
125 locator = QStringLiteral(
"Insert:%1" ).arg( action.
typeName );
127 addTransactionResult( resp, trsElem, locator, action.
errorMsg );
134 QString fidStr = *fidIt;
135 QDomElement irElem = doc.createElement( QStringLiteral(
"Feature" ) );
136 if ( !action.
handle.isEmpty() )
138 irElem.setAttribute( QStringLiteral(
"handle" ), action.
handle );
140 QDomElement fiElem = doc.createElement( QStringLiteral(
"ogc:FeatureId" ) );
141 fiElem.setAttribute( QStringLiteral(
"fid" ), fidStr );
142 irElem.appendChild( fiElem );
143 irsElem.appendChild( irElem );
149 QList<transactionUpdate>::iterator tuIt = aRequest.
updates.begin();
150 for ( ; tuIt != aRequest.
updates.end(); ++tuIt )
156 QString locator = action.
handle;
157 if ( locator.isEmpty() )
159 locator = QStringLiteral(
"Update:%1" ).arg( action.
typeName );
161 addTransactionResult( resp, trsElem, locator, action.
errorMsg );
166 QList<transactionDelete>::iterator tdIt = aRequest.
deletes.begin();
167 for ( ; tdIt != aRequest.
deletes.end(); ++tdIt )
173 QString locator = action.
handle;
174 if ( locator.isEmpty() )
176 locator = QStringLiteral(
"Delete:%1" ).arg( action.
typeName );
178 addTransactionResult( resp, trsElem, locator, action.
errorMsg );
184 QDomElement summaryElem = doc.createElement( QStringLiteral(
"TransactionSummary" ) );
185 if ( aRequest.
inserts.size() > 0 )
187 QDomElement totalInsertedElem = doc.createElement( QStringLiteral(
"totalInserted" ) );
188 totalInsertedElem.appendChild( doc.createTextNode( QString::number( totalInserted ) ) );
189 summaryElem.appendChild( totalInsertedElem );
191 if ( aRequest.
updates.size() > 0 )
193 QDomElement totalUpdatedElem = doc.createElement( QStringLiteral(
"totalUpdated" ) );
194 totalUpdatedElem.appendChild( doc.createTextNode( QString::number( totalUpdated ) ) );
195 summaryElem.appendChild( totalUpdatedElem );
197 if ( aRequest.
deletes.size() > 0 )
199 QDomElement totalDeletedElem = doc.createElement( QStringLiteral(
"totalDeleted" ) );
200 totalDeletedElem.appendChild( doc.createTextNode( QString::number( totalDeleted ) ) );
201 summaryElem.appendChild( totalDeletedElem );
203 respElem.appendChild( summaryElem );
206 if ( errorCount > 0 && trsElem.hasChildNodes() )
208 respElem.appendChild( trsElem );
212 if ( aRequest.
inserts.size() > 0 && irsElem.hasChildNodes() )
214 respElem.appendChild( irsElem );
221#ifndef HAVE_SERVER_PYTHON_PLUGINS
225 QStringList typeNameList;
227 QList<transactionInsert>::iterator tiIt = aRequest.
inserts.begin();
228 for ( ; tiIt != aRequest.
inserts.end(); ++tiIt )
230 QString name = ( *tiIt ).typeName;
231 if ( !typeNameList.contains( name ) )
232 typeNameList << name;
234 QList<transactionUpdate>::iterator tuIt = aRequest.
updates.begin();
235 for ( ; tuIt != aRequest.
updates.end(); ++tuIt )
237 QString name = ( *tuIt ).typeName;
238 if ( !typeNameList.contains( name ) )
239 typeNameList << name;
241 QList<transactionDelete>::iterator tdIt = aRequest.
deletes.begin();
242 for ( ; tdIt != aRequest.
deletes.end(); ++tdIt )
244 QString name = ( *tdIt ).typeName;
245 if ( !typeNameList.contains( name ) )
246 typeNameList << name;
249#ifdef HAVE_SERVER_PYTHON_PLUGINS
263 QMap<QString, QgsVectorLayer *> mapLayerMap;
264 for (
int i = 0; i < wfsLayerIds.size(); ++i )
278 if ( !typeNameList.contains( name ) )
305 if ( !wfstUpdateLayerIds.contains( vlayer->
id() )
306 && !wfstDeleteLayerIds.contains( vlayer->
id() )
307 && !wfstInsertLayerIds.contains( vlayer->
id() ) )
311#ifdef HAVE_SERVER_PYTHON_PLUGINS
324 mapLayerMap[name] = vlayer;
328 tuIt = aRequest.
updates.begin();
329 for ( ; tuIt != aRequest.
updates.end(); ++tuIt )
334 if ( !mapLayerMap.contains(
typeName ) )
337 action.
errorMsg = QStringLiteral(
"TypeName '%1' unknown" ).arg(
typeName );
345 if ( !wfstUpdateLayerIds.contains( vlayer->
id() ) )
348 action.
errorMsg = QStringLiteral(
"No permissions to do WFS updates on layer '%1'" ).arg(
typeName );
351#ifdef HAVE_SERVER_PYTHON_PLUGINS
355 action.
errorMsg = QStringLiteral(
"No permissions to do WFS updates on layer '%1'" ).arg(
typeName );
367 action.
errorMsg = QStringLiteral(
"No capabilities to do WFS updates on layer '%1'" ).arg(
typeName );
390#ifdef HAVE_SERVER_PYTHON_PLUGINS
399 int totalUpdated = 0;
401 QMap<QString, QString> propertyMap = action.
propertyMap;
405 const QMap<QString, int> fieldMap = provider->
fieldNameMap();
406 QMap<QString, int>::const_iterator fieldMapIt;
408 bool conversionSuccess;
412#ifdef HAVE_SERVER_PYTHON_PLUGINS
413 if ( accessControl && !accessControl->
allowToEdit( vlayer, feature ) )
416 action.
errorMsg = QStringLiteral(
"Feature modify permission denied on layer '%1'" ).arg(
typeName );
421 QMap< QString, QString >::const_iterator it = propertyMap.constBegin();
422 for ( ; it != propertyMap.constEnd(); ++it )
424 fieldName = it.key();
425 fieldMapIt = fieldMap.find( fieldName );
426 if ( fieldMapIt == fieldMap.constEnd() )
430 QgsField field = fields.
at( fieldMapIt.value() );
431 QVariant value = it.value();
437 action.
errorMsg = QStringLiteral(
"NOT NULL constraint error on layer '%1', field '%2'" ).arg(
typeName, field.
name() );
444 if ( field.
type() == QMetaType::Type::Int )
446 value = it.value().toInt( &conversionSuccess );
447 if ( !conversionSuccess )
450 action.
errorMsg = QStringLiteral(
"Property conversion error on layer '%1'" ).arg(
typeName );
455 else if ( field.
type() == QMetaType::Type::Double )
457 value = it.value().toDouble( &conversionSuccess );
458 if ( !conversionSuccess )
461 action.
errorMsg = QStringLiteral(
"Property conversion error on layer '%1'" ).arg(
typeName );
466 else if ( field.
type() == QMetaType::Type::LongLong )
468 value = it.value().toLongLong( &conversionSuccess );
469 if ( !conversionSuccess )
472 action.
errorMsg = QStringLiteral(
"Property conversion error on layer '%1'" ).arg(
typeName );
485 if ( !geometryElem.isNull() )
491 action.
errorMsg = QStringLiteral(
"Geometry from GML error on layer '%1'" ).arg(
typeName );
498 action.
errorMsg = QStringLiteral(
"Error in change geometry on layer '%1'" ).arg(
typeName );
509#ifdef HAVE_SERVER_PYTHON_PLUGINS
516 if ( accessControl && !accessControl->
allowToEdit( vlayer, feature ) )
519 action.
errorMsg = QStringLiteral(
"Feature modify permission denied on layer '%1'" ).arg(
typeName );
535 action.
errorMsg = QStringLiteral(
"Error committing updates: %1" ).arg( vlayer->
commitErrors().join( QLatin1String(
"; " ) ) );
541 action.
error =
false;
546 tdIt = aRequest.
deletes.begin();
547 for ( ; tdIt != aRequest.
deletes.end(); ++tdIt )
552 if ( !mapLayerMap.contains(
typeName ) )
555 action.
errorMsg = QStringLiteral(
"TypeName '%1' unknown" ).arg(
typeName );
563 if ( !wfstDeleteLayerIds.contains( vlayer->
id() ) )
566 action.
errorMsg = QStringLiteral(
"No permissions to do WFS deletes on layer '%1'" ).arg(
typeName );
569#ifdef HAVE_SERVER_PYTHON_PLUGINS
573 action.
errorMsg = QStringLiteral(
"No permissions to do WFS deletes on layer '%1'" ).arg(
typeName );
585 action.
errorMsg = QStringLiteral(
"No capabilities to do WFS deletes on layer '%1'" ).arg(
typeName );
605 action.
errorMsg = QStringLiteral(
"No feature ids to do WFS deletes on layer '%1'" ).arg(
typeName );
612#ifdef HAVE_SERVER_PYTHON_PLUGINS
626#ifdef HAVE_SERVER_PYTHON_PLUGINS
627 if ( accessControl && !accessControl->
allowToEdit( vlayer, feature ) )
630 action.
errorMsg = QStringLiteral(
"Feature modify permission denied" );
635 fids << feature.
id();
645 action.
errorMsg = QStringLiteral(
"Delete features failed on layer '%1'" ).arg(
typeName );
654 action.
errorMsg = QStringLiteral(
"Error committing deletes: %1" ).arg( vlayer->
commitErrors().join( QLatin1String(
"; " ) ) );
660 action.
error =
false;
664 tiIt = aRequest.
inserts.begin();
665 for ( ; tiIt != aRequest.
inserts.end(); ++tiIt )
670 if ( !mapLayerMap.contains(
typeName ) )
673 action.
errorMsg = QStringLiteral(
"TypeName '%1' unknown" ).arg(
typeName );
681 if ( !wfstInsertLayerIds.contains( vlayer->
id() ) )
684 action.
errorMsg = QStringLiteral(
"No permissions to do WFS inserts on layer '%1'" ).arg(
typeName );
687#ifdef HAVE_SERVER_PYTHON_PLUGINS
691 action.
errorMsg = QStringLiteral(
"No permissions to do WFS inserts on layer '%1'" ).arg(
typeName );
703 action.
errorMsg = QStringLiteral(
"No capabilities to do WFS inserts on layer '%1'" ).arg(
typeName );
723 if ( featureList.empty() )
726 action.
errorMsg = QStringLiteral(
"No features to insert in layer '%1'" ).arg(
typeName );
730#ifdef HAVE_SERVER_PYTHON_PLUGINS
734 QgsFeatureList::iterator featureIt = featureList.begin();
735 while ( featureIt != featureList.end() )
737 if ( !accessControl->
allowToEdit( vlayer, *featureIt ) )
740 action.
errorMsg = QStringLiteral(
"Feature modify permission denied on layer '%1'" ).arg(
typeName );
757 action.
errorMsg = QStringLiteral(
"Insert features failed on layer '%1'" ).arg(
typeName );
758 if ( provider ->hasErrors() )
770 action.
errorMsg = QStringLiteral(
"Error committing inserts: %1" ).arg( vlayer->
commitErrors().join( QLatin1String(
"; " ) ) );
775 action.
error =
false;
779 for (
const QgsFeature &feat : std::as_const( featureList ) )
786 filterRestorer.reset();
798 const QMap<QString, int> fieldMap = provider->fieldNameMap();
799 QMap<QString, int>::const_iterator fieldMapIt;
801 for (
int i = 0; i < featureNodeList.count(); i++ )
805 QDomElement featureElem = featureNodeList.at( i ).toElement();
806 QDomNode currentAttributeChild = featureElem.firstChild();
807 bool conversionSuccess =
true;
809 while ( !currentAttributeChild.isNull() )
811 QDomElement currentAttributeElement = currentAttributeChild.toElement();
812 QString attrName = currentAttributeElement.localName();
814 if ( attrName != QLatin1String(
"boundedBy" ) )
816 if ( attrName != QLatin1String(
"geometry" ) )
818 fieldMapIt = fieldMap.find( attrName );
819 if ( fieldMapIt == fieldMap.constEnd() )
824 QgsField field = fields.
at( fieldMapIt.value() );
825 QString attrValue = currentAttributeElement.text();
826 int attrType = field.
type();
828 QgsMessageLog::logMessage( QStringLiteral(
"attr: name=%1 idx=%2 value=%3" ).arg( attrName ).arg( fieldMapIt.value() ).arg( attrValue ) );
830 if ( attrType == QMetaType::Type::Int )
831 feat.
setAttribute( fieldMapIt.value(), attrValue.toInt( &conversionSuccess ) );
832 else if ( attrType == QMetaType::Type::Double )
833 feat.
setAttribute( fieldMapIt.value(), attrValue.toDouble( &conversionSuccess ) );
837 if ( !conversionSuccess )
853 currentAttributeChild = currentAttributeChild.nextSibling();
863 if ( !parameters.contains( QStringLiteral(
"OPERATION" ) ) )
867 if ( parameters.value( QStringLiteral(
"OPERATION" ) ).toUpper() != QLatin1String(
"DELETE" ) )
873 if ( ( parameters.contains( QStringLiteral(
"FEATUREID" ) )
874 && ( parameters.contains( QStringLiteral(
"FILTER" ) ) || parameters.contains( QStringLiteral(
"BBOX" ) ) ) )
875 || ( parameters.contains( QStringLiteral(
"FILTER" ) )
876 && ( parameters.contains( QStringLiteral(
"FEATUREID" ) ) || parameters.contains( QStringLiteral(
"BBOX" ) ) ) )
877 || ( parameters.contains( QStringLiteral(
"BBOX" ) )
878 && ( parameters.contains( QStringLiteral(
"FEATUREID" ) ) || parameters.contains( QStringLiteral(
"FILTER" ) ) ) )
886 QStringList typeNameList;
888 if ( parameters.contains( QStringLiteral(
"FEATUREID" ) ) )
890 QStringList fidList = parameters.value( QStringLiteral(
"FEATUREID" ) ).split(
',' );
892 QMap<QString, QStringList> fidsMap;
894 QStringList::const_iterator fidIt = fidList.constBegin();
895 for ( ; fidIt != fidList.constEnd(); ++fidIt )
898 QString fid = *fidIt;
901 if ( !fid.contains(
'.' ) )
906 QString
typeName = fid.section(
'.', 0, 0 );
907 fid = fid.section(
'.', 1, 1 );
908 if ( !typeNameList.contains(
typeName ) )
922 QMap<QString, QStringList>::const_iterator fidsMapIt = fidsMap.constBegin();
923 while ( fidsMapIt != fidsMap.constEnd() )
931 request.
deletes.append( action );
936 if ( !parameters.contains( QStringLiteral(
"TYPENAME" ) ) )
941 typeNameList = parameters.value( QStringLiteral(
"TYPENAME" ) ).split(
',' );
944 QStringList::const_iterator typeNameIt = typeNameList.constBegin();
945 for ( ; typeNameIt != typeNameList.constEnd(); ++typeNameIt )
953 request.
deletes.append( action );
957 if ( parameters.contains( QStringLiteral(
"EXP_FILTER" ) ) )
959 QString expFilterName = parameters.value( QStringLiteral(
"EXP_FILTER" ) );
960 QStringList expFilterList;
961 const thread_local QRegularExpression rx(
"\\(([^()]+)\\)" );
962 QRegularExpressionMatchIterator matchIt = rx.globalMatch( expFilterName );
963 if ( !matchIt.hasNext() )
965 expFilterList << expFilterName;
969 while ( matchIt.hasNext() )
971 const QRegularExpressionMatch match = matchIt.next();
972 if ( match.hasMatch() )
974 QStringList matches = match.capturedTexts();
976 expFilterList.append( matches );
982 if ( request.
deletes.size() == expFilterList.size() )
985 QList<transactionDelete>::iterator dIt = request.
deletes.begin();
986 QStringList::const_iterator expFilterIt = expFilterList.constBegin();
987 for ( ; dIt != request.
deletes.end(); ++dIt )
992 if ( expFilterIt != expFilterList.constEnd() )
994 expFilter = *expFilterIt;
996 std::shared_ptr<QgsExpression> filter(
new QgsExpression( expFilter ) );
999 if ( filter->hasParserError() )
1005 if ( filter->needsGeometry() )
1016 QgsMessageLog::logMessage(
"There has to be a 1:1 mapping between each element in a TYPENAME and the EXP_FILTER list" );
1020 if ( parameters.contains( QStringLiteral(
"BBOX" ) ) )
1023 QString bbox = parameters.value( QStringLiteral(
"BBOX" ) );
1024 if ( bbox.isEmpty() )
1030 QStringList corners = bbox.split(
',' );
1031 if ( corners.size() != 4 )
1039 for (
int i = 0; i < 4; i++ )
1041 corners[i].replace(
' ',
'+' );
1042 d[i] = corners[i].toDouble( &ok );
1052 QList<transactionDelete>::iterator dIt = request.
deletes.begin();
1053 for ( ; dIt != request.
deletes.end(); ++dIt )
1060 else if ( parameters.contains( QStringLiteral(
"FILTER" ) ) )
1062 QString filterName = parameters.value( QStringLiteral(
"FILTER" ) );
1063 QStringList filterList;
1064 const thread_local QRegularExpression rx(
"\\(([^()]+)\\)" );
1065 QRegularExpressionMatchIterator matchIt = rx.globalMatch( filterName );
1066 if ( !matchIt.hasNext() )
1068 filterList << filterName;
1072 while ( matchIt.hasNext() )
1074 const QRegularExpressionMatch match = matchIt.next();
1075 if ( match.hasMatch() )
1077 QStringList matches = match.capturedTexts();
1078 matches.pop_front();
1079 filterList.append( matches );
1085 if ( request.
deletes.size() != filterList.size() )
1091 QList<transactionDelete>::iterator dIt = request.
deletes.begin();
1092 QStringList::const_iterator filterIt = filterList.constBegin();
1093 for ( ; dIt != request.
deletes.end(); ++dIt )
1098 QDomDocument filter;
1099 if ( filterIt != filterList.constEnd() )
1102 if ( !filter.setContent( *filterIt,
true, &errorMsg ) )
1108 QDomElement filterElem = filter.firstChildElement();
1109 QStringList serverFids;
1113 if ( filterIt != filterList.constEnd() )
1128 QDomNodeList docChildNodes = docElem.childNodes();
1130 QDomElement actionElem;
1133 for (
int i = docChildNodes.count(); 0 < i; --i )
1135 actionElem = docChildNodes.at( i - 1 ).toElement();
1136 actionName = actionElem.localName();
1138 if ( actionName == QLatin1String(
"Insert" ) )
1141 request.
inserts.append( action );
1143 else if ( actionName == QLatin1String(
"Update" ) )
1146 request.
updates.append( action );
1148 else if ( actionName == QLatin1String(
"Delete" ) )
1151 request.
deletes.append( action );
1160 QString
typeName = actionElem.attribute( QStringLiteral(
"typeName" ) );
1164 QDomElement filterElem = actionElem.firstChild().toElement();
1165 if ( filterElem.tagName() != QLatin1String(
"Filter" ) )
1170 QStringList serverFids;
1177 action.
error =
false;
1179 if ( actionElem.hasAttribute( QStringLiteral(
"handle" ) ) )
1181 action.
handle = actionElem.attribute( QStringLiteral(
"handle" ) );
1190 QString
typeName = actionElem.attribute( QStringLiteral(
"typeName" ) );
1194 QDomNodeList propertyNodeList = actionElem.elementsByTagName( QStringLiteral(
"Property" ) );
1195 if ( propertyNodeList.isEmpty() )
1200 QMap<QString, QString> propertyMap;
1201 QDomElement propertyElem;
1202 QDomElement nameElem;
1203 QDomElement valueElem;
1204 QDomElement geometryElem;
1206 for (
int l = 0; l < propertyNodeList.count(); ++l )
1208 propertyElem = propertyNodeList.at( l ).toElement();
1209 nameElem = propertyElem.elementsByTagName( QStringLiteral(
"Name" ) ).at( 0 ).toElement();
1210 valueElem = propertyElem.elementsByTagName( QStringLiteral(
"Value" ) ).at( 0 ).toElement();
1211 if ( nameElem.text() != QLatin1String(
"geometry" ) )
1213 propertyMap.insert( nameElem.text(), valueElem.text() );
1217 geometryElem = valueElem;
1221 QDomNodeList filterNodeList = actionElem.elementsByTagName( QStringLiteral(
"Filter" ) );
1223 QStringList serverFids;
1224 if ( filterNodeList.size() != 0 )
1226 QDomElement filterElem = filterNodeList.at( 0 ).toElement();
1237 action.
error =
false;
1239 if ( actionElem.hasAttribute( QStringLiteral(
"handle" ) ) )
1241 action.
handle = actionElem.attribute( QStringLiteral(
"handle" ) );
1249 QDomNodeList featureNodeList = actionElem.childNodes();
1250 if ( featureNodeList.size() != 1 )
1256 for (
int i = 0; i < featureNodeList.count(); ++i )
1258 QString tempTypeName = featureNodeList.at( i ).toElement().localName();
1259 if ( tempTypeName.contains(
':' ) )
1260 tempTypeName = tempTypeName.section(
':', 1, 1 );
1266 else if ( tempTypeName !=
typeName )
1275 action.
error =
false;
1277 if ( actionElem.hasAttribute( QStringLiteral(
"handle" ) ) )
1279 action.
handle = actionElem.attribute( QStringLiteral(
"handle" ) );
1288 void addTransactionResult( QDomDocument &responseDoc, QDomElement &resultsElem,
1289 const QString &locator,
const QString &message )
1291 QDomElement trElem = responseDoc.createElement( QStringLiteral(
"Action" ) );
1292 resultsElem.appendChild( trElem );
1294 if ( !locator.isEmpty() )
1296 trElem.setAttribute( QStringLiteral(
"locator" ), locator );
1299 if ( !message.isEmpty() )
1301 QDomElement mesElem = responseDoc.createElement( QStringLiteral(
"Message" ) );
1302 mesElem.appendChild( responseDoc.createTextNode( message ) );
1303 trElem.appendChild( mesElem );
@ AddFeatures
Allows adding features.
@ ChangeGeometries
Allows modifications of geometries.
@ DeleteFeatures
Allows deletion of features.
@ ChangeAttributeValues
Allows modification of attribute values.
@ NoFlags
No flags are set.
@ Info
Information message.
QFlags< VectorProviderCapability > VectorProviderCapabilities
Vector data provider capabilities.
A helper class that centralizes restrictions given by all the access control filter plugins.
bool layerUpdatePermission(const QgsVectorLayer *layer) const
Returns the layer update right.
void filterFeatures(const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures) const override
Filter the features of the layer.
bool layerInsertPermission(const QgsVectorLayer *layer) const
Returns the layer insert right.
bool allowToEdit(const QgsVectorLayer *layer, const QgsFeature &feature) const
Are we authorized to modify the following geometry.
bool layerDeletePermission(const QgsVectorLayer *layer) const
Returns the layer delete right.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Class for parsing and evaluation of expressions (formerly called "search strings").
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
QgsFeatureRequest & setExpressionContext(const QgsExpressionContext &context)
Sets the expression context used to evaluate filter expressions.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Q_INVOKABLE bool setAttribute(int field, const QVariant &attr)
Sets an attribute's value by field index.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
@ ConstraintNotNull
Field may not be null.
Encapsulate a field in an attribute table or data source.
QgsFieldConstraints constraints
Container of fields for a vector layer.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
A geometry is the spatial representation of a feature.
Base class for all map layer types.
QgsCoordinateTransformContext transformContext() const
Returns the layer data provider coordinate transform context or a default transform context if the la...
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
RAII class to restore layer filters on destruction.
static void applyAccessControlLayerFilters(const QgsAccessControl *accessControl, QgsMapLayer *mapLayer, QHash< QgsMapLayer *, QString > &originalLayerFilters)
Apply filter from AccessControl.
Exception base class for service exceptions.
QString message() const
Returns the exception message.
static QgsGeometry geometryFromGML(const QString &xmlString, const QgsOgcUtils::Context &context=QgsOgcUtils::Context())
Static method that creates geometry from GML.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
A rectangle specified with double values.
QgsServerInterface Class defining interfaces exposed by QGIS Server and made available to plugins.
virtual QgsAccessControl * accessControls() const =0
Gets the registered access control filters.
QgsServerRequest Class defining request interface passed to services QgsService::executeRequest() met...
QgsServerRequest::Parameters parameters() const
Returns a map of query parameters with keys converted to uppercase.
QMap< QString, QString > Parameters
virtual QByteArray data() const
Returns post/put data Check for QByteArray::isNull() to check if data is available.
QgsServerResponse Class defining response interface passed to services QgsService::executeRequest() m...
virtual void write(const QString &data)
Write string This is a convenient method that will write directly to the underlying I/O device.
virtual void setHeader(const QString &key, const QString &value)=0
Set Header entry Add Header entry to the response Note that it is usually an error to set Header afte...
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
This is the base class for vector data providers.
void clearErrors()
Clear recorded errors.
virtual Q_INVOKABLE Qgis::VectorProviderCapabilities capabilities() const
Returns flags containing the supported capabilities.
virtual QgsAttributeList pkAttributeIndexes() const
Returns list of indexes of fields that make up the primary key.
bool addFeatures(QgsFeatureList &flist, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
QgsFields fields() const override=0
Returns the fields associated with this data provider.
QMap< QString, int > fieldNameMap() const
Returns a map where the key is the name of the field and the value is its index.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE bool deleteFeatures(const QgsFeatureIds &fids, QgsVectorLayer::DeleteContext *context=nullptr)
Deletes a set of features from the layer (but does not commit it)
Q_INVOKABLE bool startEditing()
Makes the layer editable.
Q_INVOKABLE bool changeAttributeValue(QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue=QVariant(), bool skipDefaultValues=false, QgsVectorLayerToolsContext *context=nullptr)
Changes an attribute value for a feature (but does not immediately commit the changes).
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
QStringList commitErrors() const
Returns a list containing any error messages generated when attempting to commit changes to the layer...
Q_INVOKABLE bool rollBack(bool deleteBuffer=true)
Stops a current editing operation and discards any uncommitted edits.
Q_INVOKABLE bool commitChanges(bool stopEditing=true)
Attempts to commit to the underlying data provider any buffered changes made since the last to call t...
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
bool changeGeometry(QgsFeatureId fid, QgsGeometry &geometry, bool skipDefaultValue=false)
Changes a feature's geometry within the layer's edit buffer (but does not immediately commit the chan...
Exception thrown when data access violates access controls.
SERVER_EXPORT QgsFeatureRequest updateFeatureRequestFromServerFids(QgsFeatureRequest &featureRequest, const QStringList &serverFids, const QgsVectorDataProvider *provider)
Returns the feature request based on feature ids build with primary keys.
SERVER_EXPORT QString getServerFid(const QgsFeature &feature, const QgsAttributeList &pkAttributes)
Returns the feature id based on primary keys.
SERVER_EXPORT QStringList wfsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WFS.
SERVER_EXPORT QStringList wfstUpdateLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published as WFS-T with update capabilities.
SERVER_EXPORT QStringList wfstInsertLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published as WFS-T with insert capabilities.
SERVER_EXPORT QStringList wfstDeleteLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published as WFS-T with delete capabilities.
QString layerTypeName(const QgsMapLayer *layer)
Returns typename from vector layer.
transactionRequest parseTransactionRequestBody(QDomElement &docElem, const QgsProject *project)
Transform RequestBody root element to getFeatureRequest.
const QString OGC_NAMESPACE
transactionRequest parseTransactionParameters(QgsServerRequest::Parameters parameters, const QgsProject *project)
const QString WFS_NAMESPACE
void performTransaction(transactionRequest &aRequest, QgsServerInterface *serverIface, const QgsProject *project)
Perform the transaction.
QgsFeatureList featuresFromGML(QDomNodeList featureNodeList, QgsVectorLayer *layer)
Transform GML feature nodes to features.
void writeTransaction(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response)
Output WFS transaction response.
QgsFeatureRequest parseFilterElement(const QString &typeName, QDomElement &filterElem, QgsProject *project)
Transform a Filter element to a feature request.
QDomDocument createTransactionDocument(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request)
Create a wfs transaction document.
transactionInsert parseInsertActionElement(QDomElement &actionElem)
Transform Insert element to transactionInsert.
transactionDelete parseDeleteActionElement(QDomElement &actionElem, const QgsProject *project)
Transform Delete element to transactionDelete.
transactionUpdate parseUpdateActionElement(QDomElement &actionElem, const QgsProject *project)
Transform Update element to transactionUpdate.
QList< QgsFeature > QgsFeatureList
QSet< QgsFeatureId > QgsFeatureIds
QList< int > QgsAttributeList
The Context struct stores the current layer and coordinate transform context.
QgsFeatureRequest featureRequest
QDomNodeList featureNodeList
QStringList insertFeatureIds
QList< transactionInsert > inserts
QList< transactionDelete > deletes
QList< transactionUpdate > updates
QgsFeatureRequest featureRequest
QDomElement geometryElement
QMap< QString, QString > propertyMap