43#include <QRegularExpression>
44#include <QRegularExpressionMatch>
51 void addTransactionResult( QDomDocument &responseDoc, QDomElement &resultsElem,
52 const QString &locator,
const QString &message );
63 response.
setHeader(
"Content-Type",
"text/xml; charset=utf-8" );
64 response.
write( doc.toByteArray() );
78 if ( doc.setContent( request.
data(),
true, &errorMsg ) )
80 QDomElement docElem = doc.documentElement();
89 if ( actionCount == 0 )
100 QDomElement respElem = resp.createElement( QStringLiteral(
"TransactionResponse" ) );
101 respElem.setAttribute( QStringLiteral(
"xmlns" ),
WFS_NAMESPACE );
102 respElem.setAttribute( QStringLiteral(
"xmlns:xsi" ), QStringLiteral(
"http://www.w3.org/2001/XMLSchema-instance" ) );
103 respElem.setAttribute( QStringLiteral(
"xsi:schemaLocation" ),
WFS_NAMESPACE +
" http://schemas.opengis.net/wfs/1.1.0/wfs.xsd" );
104 respElem.setAttribute( QStringLiteral(
"xmlns:ogc" ),
OGC_NAMESPACE );
105 respElem.setAttribute( QStringLiteral(
"version" ), QStringLiteral(
"1.1.0" ) );
106 resp.appendChild( respElem );
108 int totalInserted = 0;
109 int totalUpdated = 0;
110 int totalDeleted = 0;
114 QDomElement trsElem = doc.createElement( QStringLiteral(
"TransactionResults" ) );
117 QDomElement irsElem = doc.createElement( QStringLiteral(
"InsertResults" ) );
118 QList<transactionInsert>::iterator tiIt = aRequest.
inserts.begin();
119 for ( ; tiIt != aRequest.
inserts.end(); ++tiIt )
125 QString locator = action.
handle;
126 if ( locator.isEmpty() )
128 locator = QStringLiteral(
"Insert:%1" ).arg( action.
typeName );
130 addTransactionResult( resp, trsElem, locator, action.
errorMsg );
137 QString fidStr = *fidIt;
138 QDomElement irElem = doc.createElement( QStringLiteral(
"Feature" ) );
139 if ( !action.
handle.isEmpty() )
141 irElem.setAttribute( QStringLiteral(
"handle" ), action.
handle );
143 QDomElement fiElem = doc.createElement( QStringLiteral(
"ogc:FeatureId" ) );
144 fiElem.setAttribute( QStringLiteral(
"fid" ), fidStr );
145 irElem.appendChild( fiElem );
146 irsElem.appendChild( irElem );
152 QList<transactionUpdate>::iterator tuIt = aRequest.
updates.begin();
153 for ( ; tuIt != aRequest.
updates.end(); ++tuIt )
159 QString locator = action.
handle;
160 if ( locator.isEmpty() )
162 locator = QStringLiteral(
"Update:%1" ).arg( action.
typeName );
164 addTransactionResult( resp, trsElem, locator, action.
errorMsg );
169 QList<transactionDelete>::iterator tdIt = aRequest.
deletes.begin();
170 for ( ; tdIt != aRequest.
deletes.end(); ++tdIt )
176 QString locator = action.
handle;
177 if ( locator.isEmpty() )
179 locator = QStringLiteral(
"Delete:%1" ).arg( action.
typeName );
181 addTransactionResult( resp, trsElem, locator, action.
errorMsg );
187 QDomElement summaryElem = doc.createElement( QStringLiteral(
"TransactionSummary" ) );
188 if ( aRequest.
inserts.size() > 0 )
190 QDomElement totalInsertedElem = doc.createElement( QStringLiteral(
"totalInserted" ) );
191 totalInsertedElem.appendChild( doc.createTextNode( QString::number( totalInserted ) ) );
192 summaryElem.appendChild( totalInsertedElem );
194 if ( aRequest.
updates.size() > 0 )
196 QDomElement totalUpdatedElem = doc.createElement( QStringLiteral(
"totalUpdated" ) );
197 totalUpdatedElem.appendChild( doc.createTextNode( QString::number( totalUpdated ) ) );
198 summaryElem.appendChild( totalUpdatedElem );
200 if ( aRequest.
deletes.size() > 0 )
202 QDomElement totalDeletedElem = doc.createElement( QStringLiteral(
"totalDeleted" ) );
203 totalDeletedElem.appendChild( doc.createTextNode( QString::number( totalDeleted ) ) );
204 summaryElem.appendChild( totalDeletedElem );
206 respElem.appendChild( summaryElem );
209 if ( errorCount > 0 && trsElem.hasChildNodes() )
211 respElem.appendChild( trsElem );
215 if ( aRequest.
inserts.size() > 0 && irsElem.hasChildNodes() )
217 respElem.appendChild( irsElem );
224#ifndef HAVE_SERVER_PYTHON_PLUGINS
228 QStringList typeNameList;
230 QList<transactionInsert>::iterator tiIt = aRequest.
inserts.begin();
231 for ( ; tiIt != aRequest.
inserts.end(); ++tiIt )
233 QString name = ( *tiIt ).typeName;
234 if ( !typeNameList.contains( name ) )
235 typeNameList << name;
237 QList<transactionUpdate>::iterator tuIt = aRequest.
updates.begin();
238 for ( ; tuIt != aRequest.
updates.end(); ++tuIt )
240 QString name = ( *tuIt ).typeName;
241 if ( !typeNameList.contains( name ) )
242 typeNameList << name;
244 QList<transactionDelete>::iterator tdIt = aRequest.
deletes.begin();
245 for ( ; tdIt != aRequest.
deletes.end(); ++tdIt )
247 QString name = ( *tdIt ).typeName;
248 if ( !typeNameList.contains( name ) )
249 typeNameList << name;
252#ifdef HAVE_SERVER_PYTHON_PLUGINS
266 QMap<QString, QgsVectorLayer *> mapLayerMap;
281 if ( !typeNameList.contains( name ) )
314#ifdef HAVE_SERVER_PYTHON_PLUGINS
327 mapLayerMap[name] = vlayer;
331 tuIt = aRequest.
updates.begin();
332 for ( ; tuIt != aRequest.
updates.end(); ++tuIt )
337 if ( !mapLayerMap.keys().contains(
typeName ) )
340 action.
errorMsg = QStringLiteral(
"TypeName '%1' unknown" ).arg(
typeName );
351 action.
errorMsg = QStringLiteral(
"No permissions to do WFS updates on layer '%1'" ).arg(
typeName );
354#ifdef HAVE_SERVER_PYTHON_PLUGINS
358 action.
errorMsg = QStringLiteral(
"No permissions to do WFS updates on layer '%1'" ).arg(
typeName );
370 action.
errorMsg = QStringLiteral(
"No capabilities to do WFS updates on layer '%1'" ).arg(
typeName );
393#ifdef HAVE_SERVER_PYTHON_PLUGINS
402 int totalUpdated = 0;
404 QMap<QString, QString> propertyMap = action.
propertyMap;
408 const QMap<QString, int> fieldMap = provider->
fieldNameMap();
409 QMap<QString, int>::const_iterator fieldMapIt;
411 bool conversionSuccess;
415#ifdef HAVE_SERVER_PYTHON_PLUGINS
416 if ( accessControl && !accessControl->
allowToEdit( vlayer, feature ) )
419 action.
errorMsg = QStringLiteral(
"Feature modify permission denied on layer '%1'" ).arg(
typeName );
424 QMap< QString, QString >::const_iterator it = propertyMap.constBegin();
425 for ( ; it != propertyMap.constEnd(); ++it )
427 fieldName = it.key();
428 fieldMapIt = fieldMap.find( fieldName );
429 if ( fieldMapIt == fieldMap.constEnd() )
434 QVariant value = it.value();
447 if (
field.
type() == QVariant::Type::Int )
449 value = it.value().toInt( &conversionSuccess );
450 if ( !conversionSuccess )
453 action.
errorMsg = QStringLiteral(
"Property conversion error on layer '%1'" ).arg(
typeName );
458 else if (
field.
type() == QVariant::Type::Double )
460 value = it.value().toDouble( &conversionSuccess );
461 if ( !conversionSuccess )
464 action.
errorMsg = QStringLiteral(
"Property conversion error on layer '%1'" ).arg(
typeName );
469 else if (
field.
type() == QVariant::Type::LongLong )
471 value = it.value().toLongLong( &conversionSuccess );
472 if ( !conversionSuccess )
475 action.
errorMsg = QStringLiteral(
"Property conversion error on layer '%1'" ).arg(
typeName );
488 if ( !geometryElem.isNull() )
494 action.
errorMsg = QStringLiteral(
"Geometry from GML error on layer '%1'" ).arg(
typeName );
501 action.
errorMsg = QStringLiteral(
"Error in change geometry on layer '%1'" ).arg(
typeName );
512#ifdef HAVE_SERVER_PYTHON_PLUGINS
519 if ( accessControl && !accessControl->
allowToEdit( vlayer, feature ) )
522 action.
errorMsg = QStringLiteral(
"Feature modify permission denied on layer '%1'" ).arg(
typeName );
538 action.
errorMsg = QStringLiteral(
"Error committing updates: %1" ).arg( vlayer->
commitErrors().join( QLatin1String(
"; " ) ) );
544 action.
error =
false;
549 tdIt = aRequest.
deletes.begin();
550 for ( ; tdIt != aRequest.
deletes.end(); ++tdIt )
555 if ( !mapLayerMap.keys().contains(
typeName ) )
558 action.
errorMsg = QStringLiteral(
"TypeName '%1' unknown" ).arg(
typeName );
569 action.
errorMsg = QStringLiteral(
"No permissions to do WFS deletes on layer '%1'" ).arg(
typeName );
572#ifdef HAVE_SERVER_PYTHON_PLUGINS
576 action.
errorMsg = QStringLiteral(
"No permissions to do WFS deletes on layer '%1'" ).arg(
typeName );
588 action.
errorMsg = QStringLiteral(
"No capabilities to do WFS deletes on layer '%1'" ).arg(
typeName );
608 action.
errorMsg = QStringLiteral(
"No feature ids to do WFS deletes on layer '%1'" ).arg(
typeName );
615#ifdef HAVE_SERVER_PYTHON_PLUGINS
629#ifdef HAVE_SERVER_PYTHON_PLUGINS
630 if ( accessControl && !accessControl->
allowToEdit( vlayer, feature ) )
633 action.
errorMsg = QStringLiteral(
"Feature modify permission denied" );
638 fids << feature.
id();
648 action.
errorMsg = QStringLiteral(
"Delete features failed on layer '%1'" ).arg(
typeName );
657 action.
errorMsg = QStringLiteral(
"Error committing deletes: %1" ).arg( vlayer->
commitErrors().join( QLatin1String(
"; " ) ) );
663 action.
error =
false;
667 tiIt = aRequest.
inserts.begin();
668 for ( ; tiIt != aRequest.
inserts.end(); ++tiIt )
673 if ( !mapLayerMap.keys().contains(
typeName ) )
676 action.
errorMsg = QStringLiteral(
"TypeName '%1' unknown" ).arg(
typeName );
687 action.
errorMsg = QStringLiteral(
"No permissions to do WFS inserts on layer '%1'" ).arg(
typeName );
690#ifdef HAVE_SERVER_PYTHON_PLUGINS
694 action.
errorMsg = QStringLiteral(
"No permissions to do WFS inserts on layer '%1'" ).arg(
typeName );
706 action.
errorMsg = QStringLiteral(
"No capabilities to do WFS inserts on layer '%1'" ).arg(
typeName );
726 if ( featureList.empty() )
729 action.
errorMsg = QStringLiteral(
"No features to insert in layer '%1'" ).arg(
typeName );
733#ifdef HAVE_SERVER_PYTHON_PLUGINS
737 QgsFeatureList::iterator featureIt = featureList.begin();
738 while ( featureIt != featureList.end() )
740 if ( !accessControl->
allowToEdit( vlayer, *featureIt ) )
743 action.
errorMsg = QStringLiteral(
"Feature modify permission denied on layer '%1'" ).arg(
typeName );
760 action.
errorMsg = QStringLiteral(
"Insert features failed on layer '%1'" ).arg(
typeName );
761 if ( provider ->hasErrors() )
773 action.
errorMsg = QStringLiteral(
"Error committing inserts: %1" ).arg( vlayer->
commitErrors().join( QLatin1String(
"; " ) ) );
778 action.
error =
false;
782 for (
const QgsFeature &feat : std::as_const( featureList ) )
789 filterRestorer.reset();
801 const QMap<QString, int> fieldMap = provider->fieldNameMap();
802 QMap<QString, int>::const_iterator fieldMapIt;
804 for (
int i = 0; i < featureNodeList.count(); i++ )
808 QDomElement featureElem = featureNodeList.at( i ).toElement();
809 QDomNode currentAttributeChild = featureElem.firstChild();
810 bool conversionSuccess =
true;
812 while ( !currentAttributeChild.isNull() )
814 QDomElement currentAttributeElement = currentAttributeChild.toElement();
815 QString attrName = currentAttributeElement.localName();
817 if ( attrName != QLatin1String(
"boundedBy" ) )
819 if ( attrName != QLatin1String(
"geometry" ) )
821 fieldMapIt = fieldMap.find( attrName );
822 if ( fieldMapIt == fieldMap.constEnd() )
828 QString attrValue = currentAttributeElement.text();
831 QgsMessageLog::logMessage( QStringLiteral(
"attr: name=%1 idx=%2 value=%3" ).arg( attrName ).arg( fieldMapIt.value() ).arg( attrValue ) );
833 if ( attrType == QVariant::Int )
834 feat.
setAttribute( fieldMapIt.value(), attrValue.toInt( &conversionSuccess ) );
835 else if ( attrType == QVariant::Double )
836 feat.
setAttribute( fieldMapIt.value(), attrValue.toDouble( &conversionSuccess ) );
840 if ( !conversionSuccess )
856 currentAttributeChild = currentAttributeChild.nextSibling();
866 if ( !parameters.contains( QStringLiteral(
"OPERATION" ) ) )
870 if ( parameters.value( QStringLiteral(
"OPERATION" ) ).toUpper() != QLatin1String(
"DELETE" ) )
876 if ( ( parameters.contains( QStringLiteral(
"FEATUREID" ) )
877 && ( parameters.contains( QStringLiteral(
"FILTER" ) ) || parameters.contains( QStringLiteral(
"BBOX" ) ) ) )
878 || ( parameters.contains( QStringLiteral(
"FILTER" ) )
879 && ( parameters.contains( QStringLiteral(
"FEATUREID" ) ) || parameters.contains( QStringLiteral(
"BBOX" ) ) ) )
880 || ( parameters.contains( QStringLiteral(
"BBOX" ) )
881 && ( parameters.contains( QStringLiteral(
"FEATUREID" ) ) || parameters.contains( QStringLiteral(
"FILTER" ) ) ) )
889 QStringList typeNameList;
891 if ( parameters.contains( QStringLiteral(
"FEATUREID" ) ) )
893 QStringList fidList = parameters.value( QStringLiteral(
"FEATUREID" ) ).split(
',' );
895 QMap<QString, QStringList> fidsMap;
897 QStringList::const_iterator fidIt = fidList.constBegin();
898 for ( ; fidIt != fidList.constEnd(); ++fidIt )
901 QString fid = *fidIt;
904 if ( !fid.contains(
'.' ) )
909 QString
typeName = fid.section(
'.', 0, 0 );
910 fid = fid.section(
'.', 1, 1 );
911 if ( !typeNameList.contains(
typeName ) )
925 QMap<QString, QStringList>::const_iterator fidsMapIt = fidsMap.constBegin();
926 while ( fidsMapIt != fidsMap.constEnd() )
934 request.
deletes.append( action );
939 if ( !parameters.contains( QStringLiteral(
"TYPENAME" ) ) )
944 typeNameList = parameters.value( QStringLiteral(
"TYPENAME" ) ).split(
',' );
947 QStringList::const_iterator typeNameIt = typeNameList.constBegin();
948 for ( ; typeNameIt != typeNameList.constEnd(); ++typeNameIt )
956 request.
deletes.append( action );
960 if ( parameters.contains( QStringLiteral(
"EXP_FILTER" ) ) )
962 QString expFilterName = parameters.value( QStringLiteral(
"EXP_FILTER" ) );
963 QStringList expFilterList;
964 const thread_local QRegularExpression rx(
"\\(([^()]+)\\)" );
965 QRegularExpressionMatchIterator matchIt = rx.globalMatch( expFilterName );
966 if ( !matchIt.hasNext() )
968 expFilterList << expFilterName;
972 while ( matchIt.hasNext() )
974 const QRegularExpressionMatch match = matchIt.next();
975 if ( match.hasMatch() )
977 QStringList matches = match.capturedTexts();
979 expFilterList.append( matches );
985 if ( request.
deletes.size() == expFilterList.size() )
988 QList<transactionDelete>::iterator dIt = request.
deletes.begin();
989 QStringList::const_iterator expFilterIt = expFilterList.constBegin();
990 for ( ; dIt != request.
deletes.end(); ++dIt )
995 if ( expFilterIt != expFilterList.constEnd() )
997 expFilter = *expFilterIt;
999 std::shared_ptr<QgsExpression> filter(
new QgsExpression( expFilter ) );
1002 if ( filter->hasParserError() )
1008 if ( filter->needsGeometry() )
1019 QgsMessageLog::logMessage(
"There has to be a 1:1 mapping between each element in a TYPENAME and the EXP_FILTER list" );
1023 if ( parameters.contains( QStringLiteral(
"BBOX" ) ) )
1026 QString bbox = parameters.value( QStringLiteral(
"BBOX" ) );
1027 if ( bbox.isEmpty() )
1033 QStringList corners = bbox.split(
',' );
1034 if ( corners.size() != 4 )
1042 for (
int i = 0; i < 4; i++ )
1044 corners[i].replace(
' ',
'+' );
1045 d[i] = corners[i].toDouble( &ok );
1055 QList<transactionDelete>::iterator dIt = request.
deletes.begin();
1056 for ( ; dIt != request.
deletes.end(); ++dIt )
1063 else if ( parameters.contains( QStringLiteral(
"FILTER" ) ) )
1065 QString filterName = parameters.value( QStringLiteral(
"FILTER" ) );
1066 QStringList filterList;
1067 const thread_local QRegularExpression rx(
"\\(([^()]+)\\)" );
1068 QRegularExpressionMatchIterator matchIt = rx.globalMatch( filterName );
1069 if ( !matchIt.hasNext() )
1071 filterList << filterName;
1075 while ( matchIt.hasNext() )
1077 const QRegularExpressionMatch match = matchIt.next();
1078 if ( match.hasMatch() )
1080 QStringList matches = match.capturedTexts();
1081 matches.pop_front();
1082 filterList.append( matches );
1088 if ( request.
deletes.size() != filterList.size() )
1094 QList<transactionDelete>::iterator dIt = request.
deletes.begin();
1095 QStringList::const_iterator filterIt = filterList.constBegin();
1096 for ( ; dIt != request.
deletes.end(); ++dIt )
1101 QDomDocument filter;
1102 if ( filterIt != filterList.constEnd() )
1105 if ( !filter.setContent( *filterIt,
true, &errorMsg ) )
1111 QDomElement filterElem = filter.firstChildElement();
1112 QStringList serverFids;
1116 if ( filterIt != filterList.constEnd() )
1131 QDomNodeList docChildNodes = docElem.childNodes();
1133 QDomElement actionElem;
1136 for (
int i = docChildNodes.count(); 0 < i; --i )
1138 actionElem = docChildNodes.at( i - 1 ).toElement();
1139 actionName = actionElem.localName();
1141 if ( actionName == QLatin1String(
"Insert" ) )
1144 request.
inserts.append( action );
1146 else if ( actionName == QLatin1String(
"Update" ) )
1149 request.
updates.append( action );
1151 else if ( actionName == QLatin1String(
"Delete" ) )
1154 request.
deletes.append( action );
1163 QString
typeName = actionElem.attribute( QStringLiteral(
"typeName" ) );
1167 QDomElement filterElem = actionElem.firstChild().toElement();
1168 if ( filterElem.tagName() != QLatin1String(
"Filter" ) )
1173 QStringList serverFids;
1180 action.
error =
false;
1182 if ( actionElem.hasAttribute( QStringLiteral(
"handle" ) ) )
1184 action.
handle = actionElem.attribute( QStringLiteral(
"handle" ) );
1192 QgsMessageLog::logMessage( QStringLiteral(
"parseUpdateActionElement" ), QStringLiteral(
"Server" ), Qgis::MessageLevel::Info );
1193 QString
typeName = actionElem.attribute( QStringLiteral(
"typeName" ) );
1197 QDomNodeList propertyNodeList = actionElem.elementsByTagName( QStringLiteral(
"Property" ) );
1198 if ( propertyNodeList.isEmpty() )
1203 QMap<QString, QString> propertyMap;
1204 QDomElement propertyElem;
1205 QDomElement nameElem;
1206 QDomElement valueElem;
1207 QDomElement geometryElem;
1209 for (
int l = 0; l < propertyNodeList.count(); ++l )
1211 propertyElem = propertyNodeList.at( l ).toElement();
1212 nameElem = propertyElem.elementsByTagName( QStringLiteral(
"Name" ) ).at( 0 ).toElement();
1213 valueElem = propertyElem.elementsByTagName( QStringLiteral(
"Value" ) ).at( 0 ).toElement();
1214 if ( nameElem.text() != QLatin1String(
"geometry" ) )
1216 propertyMap.insert( nameElem.text(), valueElem.text() );
1220 geometryElem = valueElem;
1224 QDomNodeList filterNodeList = actionElem.elementsByTagName( QStringLiteral(
"Filter" ) );
1226 QStringList serverFids;
1227 if ( filterNodeList.size() != 0 )
1229 QDomElement filterElem = filterNodeList.at( 0 ).toElement();
1232 QgsMessageLog::logMessage( QStringLiteral(
"parseUpdateActionElement: serverFids length %1" ).arg( serverFids.count() ), QStringLiteral(
"Server" ), Qgis::MessageLevel::Info );
1240 action.
error =
false;
1242 if ( actionElem.hasAttribute( QStringLiteral(
"handle" ) ) )
1244 action.
handle = actionElem.attribute( QStringLiteral(
"handle" ) );
1252 QDomNodeList featureNodeList = actionElem.childNodes();
1253 if ( featureNodeList.size() != 1 )
1259 for (
int i = 0; i < featureNodeList.count(); ++i )
1261 QString tempTypeName = featureNodeList.at( i ).toElement().localName();
1262 if ( tempTypeName.contains(
':' ) )
1263 tempTypeName = tempTypeName.section(
':', 1, 1 );
1269 else if ( tempTypeName !=
typeName )
1278 action.
error =
false;
1280 if ( actionElem.hasAttribute( QStringLiteral(
"handle" ) ) )
1282 action.
handle = actionElem.attribute( QStringLiteral(
"handle" ) );
1291 void addTransactionResult( QDomDocument &responseDoc, QDomElement &resultsElem,
1292 const QString &locator,
const QString &message )
1294 QDomElement trElem = responseDoc.createElement( QStringLiteral(
"Action" ) );
1295 resultsElem.appendChild( trElem );
1297 if ( !locator.isEmpty() )
1299 trElem.setAttribute( QStringLiteral(
"locator" ), locator );
1302 if ( !message.isEmpty() )
1304 QDomElement mesElem = responseDoc.createElement( QStringLiteral(
"Message" ) );
1305 mesElem.appendChild( responseDoc.createTextNode( message ) );
1306 trElem.appendChild( mesElem );
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)
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags 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...
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.
Q_GADGET Constraints constraints
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.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
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)
Returns true if the specified variant should be considered a NULL value.
This is the base class for vector data providers.
@ ChangeGeometries
Allows modifications of geometries.
@ DeleteFeatures
Allows deletion of features.
@ ChangeAttributeValues
Allows modification of attribute values.
@ AddFeatures
Allows adding features.
void clearErrors()
Clear recorded errors.
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.
virtual Q_INVOKABLE QgsVectorDataProvider::Capabilities capabilities() const
Returns flags containing the supported capabilities.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE bool startEditing()
Makes the layer editable.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
bool deleteFeatures(const QgsFeatureIds &fids, DeleteContext *context=nullptr)
Deletes a set of features from the layer (but does not commit it)
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 changeAttributeValue(QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue=QVariant(), bool skipDefaultValues=false)
Changes an attribute value for a feature (but does not immediately commit the changes).
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.
@ VectorLayer
Vector layer.
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