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;
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.keys().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();
432 if ( value.isNull() )
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.keys().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.keys().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 QRegExp rx(
"\\(([^()]+)\\)" );
962 if ( rx.indexIn( expFilterName, 0 ) == -1 )
964 expFilterList << expFilterName;
969 while ( ( pos = rx.indexIn( expFilterName, pos ) ) != -1 )
971 expFilterList << rx.cap( 1 );
972 pos += rx.matchedLength();
977 if ( request.
deletes.size() == expFilterList.size() )
980 QList<transactionDelete>::iterator dIt = request.
deletes.begin();
981 QStringList::const_iterator expFilterIt = expFilterList.constBegin();
982 for ( ; dIt != request.
deletes.end(); ++dIt )
987 if ( expFilterIt != expFilterList.constEnd() )
989 expFilter = *expFilterIt;
991 std::shared_ptr<QgsExpression> filter(
new QgsExpression( expFilter ) );
994 if ( filter->hasParserError() )
1000 if ( filter->needsGeometry() )
1011 QgsMessageLog::logMessage(
"There has to be a 1:1 mapping between each element in a TYPENAME and the EXP_FILTER list" );
1015 if ( parameters.contains( QStringLiteral(
"BBOX" ) ) )
1018 QString bbox = parameters.value( QStringLiteral(
"BBOX" ) );
1019 if ( bbox.isEmpty() )
1025 QStringList corners = bbox.split(
',' );
1026 if ( corners.size() != 4 )
1034 for (
int i = 0; i < 4; i++ )
1036 corners[i].replace(
' ',
'+' );
1037 d[i] = corners[i].toDouble( &ok );
1047 QList<transactionDelete>::iterator dIt = request.
deletes.begin();
1048 for ( ; dIt != request.
deletes.end(); ++dIt )
1055 else if ( parameters.contains( QStringLiteral(
"FILTER" ) ) )
1057 QString filterName = parameters.value( QStringLiteral(
"FILTER" ) );
1058 QStringList filterList;
1059 QRegExp rx(
"\\(([^()]+)\\)" );
1060 if ( rx.indexIn( filterName, 0 ) == -1 )
1062 filterList << filterName;
1067 while ( ( pos = rx.indexIn( filterName, pos ) ) != -1 )
1069 filterList << rx.cap( 1 );
1070 pos += rx.matchedLength();
1075 if ( request.
deletes.size() != filterList.size() )
1081 QList<transactionDelete>::iterator dIt = request.
deletes.begin();
1082 QStringList::const_iterator filterIt = filterList.constBegin();
1083 for ( ; dIt != request.
deletes.end(); ++dIt )
1088 QDomDocument filter;
1089 if ( filterIt != filterList.constEnd() )
1092 if ( !filter.setContent( *filterIt,
true, &errorMsg ) )
1098 QDomElement filterElem = filter.firstChildElement();
1099 QStringList serverFids;
1103 if ( filterIt != filterList.constEnd() )
1118 QDomNodeList docChildNodes = docElem.childNodes();
1120 QDomElement actionElem;
1123 for (
int i = docChildNodes.count(); 0 < i; --i )
1125 actionElem = docChildNodes.at( i - 1 ).toElement();
1126 actionName = actionElem.localName();
1128 if ( actionName == QLatin1String(
"Insert" ) )
1131 request.
inserts.append( action );
1133 else if ( actionName == QLatin1String(
"Update" ) )
1136 request.
updates.append( action );
1138 else if ( actionName == QLatin1String(
"Delete" ) )
1141 request.
deletes.append( action );
1150 QString
typeName = actionElem.attribute( QStringLiteral(
"typeName" ) );
1154 QDomElement filterElem = actionElem.firstChild().toElement();
1155 if ( filterElem.tagName() != QLatin1String(
"Filter" ) )
1160 QStringList serverFids;
1167 action.
error =
false;
1169 if ( actionElem.hasAttribute( QStringLiteral(
"handle" ) ) )
1171 action.
handle = actionElem.attribute( QStringLiteral(
"handle" ) );
1179 QgsMessageLog::logMessage( QStringLiteral(
"parseUpdateActionElement" ), QStringLiteral(
"Server" ), Qgis::MessageLevel::Info );
1180 QString
typeName = actionElem.attribute( QStringLiteral(
"typeName" ) );
1184 QDomNodeList propertyNodeList = actionElem.elementsByTagName( QStringLiteral(
"Property" ) );
1185 if ( propertyNodeList.isEmpty() )
1190 QMap<QString, QString> propertyMap;
1191 QDomElement propertyElem;
1192 QDomElement nameElem;
1193 QDomElement valueElem;
1194 QDomElement geometryElem;
1196 for (
int l = 0; l < propertyNodeList.count(); ++l )
1198 propertyElem = propertyNodeList.at( l ).toElement();
1199 nameElem = propertyElem.elementsByTagName( QStringLiteral(
"Name" ) ).at( 0 ).toElement();
1200 valueElem = propertyElem.elementsByTagName( QStringLiteral(
"Value" ) ).at( 0 ).toElement();
1201 if ( nameElem.text() != QLatin1String(
"geometry" ) )
1203 propertyMap.insert( nameElem.text(), valueElem.text() );
1207 geometryElem = valueElem;
1211 QDomNodeList filterNodeList = actionElem.elementsByTagName( QStringLiteral(
"Filter" ) );
1213 QStringList serverFids;
1214 if ( filterNodeList.size() != 0 )
1216 QDomElement filterElem = filterNodeList.at( 0 ).toElement();
1219 QgsMessageLog::logMessage( QStringLiteral(
"parseUpdateActionElement: serverFids length %1" ).arg( serverFids.count() ), QStringLiteral(
"Server" ), Qgis::MessageLevel::Info );
1227 action.
error =
false;
1229 if ( actionElem.hasAttribute( QStringLiteral(
"handle" ) ) )
1231 action.
handle = actionElem.attribute( QStringLiteral(
"handle" ) );
1239 QDomNodeList featureNodeList = actionElem.childNodes();
1240 if ( featureNodeList.size() != 1 )
1246 for (
int i = 0; i < featureNodeList.count(); ++i )
1248 QString tempTypeName = featureNodeList.at( i ).toElement().localName();
1249 if ( tempTypeName.contains(
':' ) )
1250 tempTypeName = tempTypeName.section(
':', 1, 1 );
1256 else if ( tempTypeName !=
typeName )
1265 action.
error =
false;
1267 if ( actionElem.hasAttribute( QStringLiteral(
"handle" ) ) )
1269 action.
handle = actionElem.attribute( QStringLiteral(
"handle" ) );
1278 void addTransactionResult( QDomDocument &responseDoc, QDomElement &resultsElem,
1279 const QString &locator,
const QString &message )
1281 QDomElement trElem = responseDoc.createElement( QStringLiteral(
"Action" ) );
1282 resultsElem.appendChild( trElem );
1284 if ( !locator.isEmpty() )
1286 trElem.setAttribute( QStringLiteral(
"locator" ), locator );
1289 if ( !message.isEmpty() )
1291 QDomElement mesElem = responseDoc.createElement( QStringLiteral(
"Message" ) );
1292 mesElem.appendChild( responseDoc.createTextNode( message ) );
1293 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...
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