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;
271 if ( layer->
type() != Qgis::LayerType::Vector )
278 if ( !typeNameList.contains( name ) )
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 );
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() )
431 QVariant value = it.value();
444 if (
field.
type() == QVariant::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() == QVariant::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() == QVariant::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 );
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 );
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() )
825 QString attrValue = currentAttributeElement.text();
828 QgsMessageLog::logMessage( QStringLiteral(
"attr: name=%1 idx=%2 value=%3" ).arg( attrName ).arg( fieldMapIt.value() ).arg( attrValue ) );
830 if ( attrType == QVariant::Int )
831 feat.
setAttribute( fieldMapIt.value(), attrValue.toInt( &conversionSuccess ) );
832 else if ( attrType == QVariant::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" ) );
1189 QgsMessageLog::logMessage( QStringLiteral(
"parseUpdateActionElement" ), QStringLiteral(
"Server" ), Qgis::MessageLevel::Info );
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();
1229 QgsMessageLog::logMessage( QStringLiteral(
"parseUpdateActionElement: serverFids length %1" ).arg( serverFids.count() ), QStringLiteral(
"Server" ), Qgis::MessageLevel::Info );
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 );
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.
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