40#include <QRegularExpression>
48 void addTransactionResult( QDomDocument &responseDoc, QDomElement &responseElem,
const QString &status,
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(
"WFS_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.0.0/wfs.xsd" );
101 respElem.setAttribute( QStringLiteral(
"xmlns:ogc" ),
OGC_NAMESPACE );
102 respElem.setAttribute( QStringLiteral(
"version" ), QStringLiteral(
"1.0.0" ) );
103 resp.appendChild( respElem );
106 QStringList errorLocators;
107 QStringList errorMessages;
109 QList<transactionUpdate>::iterator tuIt = aRequest.
updates.begin();
110 for ( ; tuIt != aRequest.
updates.end(); ++tuIt )
116 if ( action.
handle.isEmpty() )
118 errorLocators << QStringLiteral(
"Update:%1" ).arg( action.
typeName );
122 errorLocators << action.
handle;
128 QList<transactionDelete>::iterator tdIt = aRequest.
deletes.begin();
129 for ( ; tdIt != aRequest.
deletes.end(); ++tdIt )
135 if ( action.
handle.isEmpty() )
137 errorLocators << QStringLiteral(
"Delete:%1" ).arg( action.
typeName );
141 errorLocators << action.
handle;
147 QList<transactionInsert>::iterator tiIt = aRequest.
inserts.begin();
148 for ( ; tiIt != aRequest.
inserts.end(); ++tiIt )
154 if ( action.
handle.isEmpty() )
156 errorLocators << QStringLiteral(
"Insert:%1" ).arg( action.
typeName );
160 errorLocators << action.
handle;
169 QString fidStr = *fidIt;
170 QDomElement irElem = doc.createElement( QStringLiteral(
"InsertResult" ) );
171 if ( !action.
handle.isEmpty() )
173 irElem.setAttribute( QStringLiteral(
"handle" ), action.
handle );
175 QDomElement fiElem = doc.createElement( QStringLiteral(
"ogc:FeatureId" ) );
176 fiElem.setAttribute( QStringLiteral(
"fid" ), fidStr );
177 irElem.appendChild( fiElem );
178 respElem.appendChild( irElem );
184 if ( errorCount == 0 )
186 addTransactionResult( resp, respElem, QStringLiteral(
"SUCCESS" ), QString(), QString() );
190 QString locator = errorLocators.join( QLatin1String(
"; " ) );
191 QString message = errorMessages.join( QLatin1String(
"; " ) );
192 if ( errorCount != actionCount )
194 addTransactionResult( resp, respElem, QStringLiteral(
"PARTIAL" ), locator, message );
198 addTransactionResult( resp, respElem, QStringLiteral(
"ERROR" ), locator, message );
207 QStringList typeNameList;
209 QList<transactionInsert>::iterator tiIt = aRequest.
inserts.begin();
210 for ( ; tiIt != aRequest.
inserts.end(); ++tiIt )
212 QString name = ( *tiIt ).typeName;
213 if ( !typeNameList.contains( name ) )
214 typeNameList << name;
216 QList<transactionUpdate>::iterator tuIt = aRequest.
updates.begin();
217 for ( ; tuIt != aRequest.
updates.end(); ++tuIt )
219 QString name = ( *tuIt ).typeName;
220 if ( !typeNameList.contains( name ) )
221 typeNameList << name;
223 QList<transactionDelete>::iterator tdIt = aRequest.
deletes.begin();
224 for ( ; tdIt != aRequest.
deletes.end(); ++tdIt )
226 QString name = ( *tdIt ).typeName;
227 if ( !typeNameList.contains( name ) )
228 typeNameList << name;
231#ifdef HAVE_SERVER_PYTHON_PLUGINS
247 QMap<QString, QgsVectorLayer *> mapLayerMap;
258 if ( !typeNameList.contains( name ) )
291#ifdef HAVE_SERVER_PYTHON_PLUGINS
304 mapLayerMap[name] = vlayer;
308 tuIt = aRequest.
updates.begin();
309 for ( ; tuIt != aRequest.
updates.end(); ++tuIt )
314 if ( !mapLayerMap.keys().contains(
typeName ) )
317 action.
errorMsg = QStringLiteral(
"TypeName '%1' unknown" ).arg(
typeName );
328 action.
errorMsg = QStringLiteral(
"No permissions to do WFS updates on layer '%1'" ).arg(
typeName );
331#ifdef HAVE_SERVER_PYTHON_PLUGINS
335 action.
errorMsg = QStringLiteral(
"No permissions to do WFS updates on layer '%1'" ).arg(
typeName );
347 action.
errorMsg = QStringLiteral(
"No capabilities to do WFS updates on layer '%1'" ).arg(
typeName );
370#ifdef HAVE_SERVER_PYTHON_PLUGINS
380 QMap<QString, QString> propertyMap = action.
propertyMap;
384 const QMap<QString, int> fieldMap = provider->
fieldNameMap();
385 QMap<QString, int>::const_iterator fieldMapIt;
387 bool conversionSuccess;
391#ifdef HAVE_SERVER_PYTHON_PLUGINS
392 if ( accessControl && !accessControl->
allowToEdit( vlayer, feature ) )
395 action.
errorMsg = QStringLiteral(
"Feature modify permission denied on layer '%1'" ).arg(
typeName );
400 QMap< QString, QString >::const_iterator it = propertyMap.constBegin();
401 for ( ; it != propertyMap.constEnd(); ++it )
403 fieldName = it.key();
404 fieldMapIt = fieldMap.find( fieldName );
405 if ( fieldMapIt == fieldMap.constEnd() )
410 QVariant value = it.value();
423 if (
field.
type() == QVariant::Type::Int )
425 value = it.value().toInt( &conversionSuccess );
426 if ( !conversionSuccess )
429 action.
errorMsg = QStringLiteral(
"Property conversion error on layer '%1'" ).arg(
typeName );
434 else if (
field.
type() == QVariant::Type::Double )
436 value = it.value().toDouble( &conversionSuccess );
437 if ( !conversionSuccess )
440 action.
errorMsg = QStringLiteral(
"Property conversion error on layer '%1'" ).arg(
typeName );
445 else if (
field.
type() == QVariant::Type::LongLong )
447 value = it.value().toLongLong( &conversionSuccess );
448 if ( !conversionSuccess )
451 action.
errorMsg = QStringLiteral(
"Property conversion error on layer '%1'" ).arg(
typeName );
464 if ( !geometryElem.isNull() )
472 action.
errorMsg = QStringLiteral(
"Geometry from GML error on layer '%1'" ).arg(
typeName );
479 action.
errorMsg = QStringLiteral(
"Error in change geometry on layer '%1'" ).arg(
typeName );
489#ifdef HAVE_SERVER_PYTHON_PLUGINS
496 if ( accessControl && !accessControl->
allowToEdit( vlayer, feature ) )
499 action.
errorMsg = QStringLiteral(
"Feature modify permission denied on layer '%1'" ).arg(
typeName );
515 action.
errorMsg = QStringLiteral(
"Error committing updates: %1" ).arg( vlayer->
commitErrors().join( QLatin1String(
"; " ) ) );
520 action.
error =
false;
525 tdIt = aRequest.
deletes.begin();
526 for ( ; tdIt != aRequest.
deletes.end(); ++tdIt )
531 if ( !mapLayerMap.keys().contains(
typeName ) )
534 action.
errorMsg = QStringLiteral(
"TypeName '%1' unknown" ).arg(
typeName );
545 action.
errorMsg = QStringLiteral(
"No permissions to do WFS deletes on layer '%1'" ).arg(
typeName );
548#ifdef HAVE_SERVER_PYTHON_PLUGINS
552 action.
errorMsg = QStringLiteral(
"No permissions to do WFS deletes on layer '%1'" ).arg(
typeName );
564 action.
errorMsg = QStringLiteral(
"No capabilities to do WFS deletes on layer '%1'" ).arg(
typeName );
584 action.
errorMsg = QStringLiteral(
"No feature ids to do WFS deletes on layer '%1'" ).arg(
typeName );
591#ifdef HAVE_SERVER_PYTHON_PLUGINS
605#ifdef HAVE_SERVER_PYTHON_PLUGINS
606 if ( accessControl && !accessControl->
allowToEdit( vlayer, feature ) )
609 action.
errorMsg = QStringLiteral(
"Feature modify permission denied" );
614 fids << feature.
id();
624 action.
errorMsg = QStringLiteral(
"Delete features failed on layer '%1'" ).arg(
typeName );
633 action.
errorMsg = QStringLiteral(
"Error committing deletes: %1" ).arg( vlayer->
commitErrors().join( QLatin1String(
"; " ) ) );
638 action.
error =
false;
642 tiIt = aRequest.
inserts.begin();
643 for ( ; tiIt != aRequest.
inserts.end(); ++tiIt )
648 if ( !mapLayerMap.keys().contains(
typeName ) )
651 action.
errorMsg = QStringLiteral(
"TypeName '%1' unknown" ).arg(
typeName );
662 action.
errorMsg = QStringLiteral(
"No permissions to do WFS inserts on layer '%1'" ).arg(
typeName );
665#ifdef HAVE_SERVER_PYTHON_PLUGINS
669 action.
errorMsg = QStringLiteral(
"No permissions to do WFS inserts on layer '%1'" ).arg(
typeName );
681 action.
errorMsg = QStringLiteral(
"No capabilities to do WFS inserts on layer '%1'" ).arg(
typeName );
701 if ( featureList.empty() )
704 action.
errorMsg = QStringLiteral(
"No features to insert in layer '%1'" ).arg(
typeName );
708#ifdef HAVE_SERVER_PYTHON_PLUGINS
712 QgsFeatureList::iterator featureIt = featureList.begin();
713 while ( featureIt != featureList.end() )
715 if ( !accessControl->
allowToEdit( vlayer, *featureIt ) )
718 action.
errorMsg = QStringLiteral(
"Feature modify permission denied on layer '%1'" ).arg(
typeName );
735 action.
errorMsg = QStringLiteral(
"Insert features failed on layer '%1'" ).arg(
typeName );
736 if ( provider ->hasErrors() )
748 action.
errorMsg = QStringLiteral(
"Error committing inserts: %1" ).arg( vlayer->
commitErrors().join( QLatin1String(
"; " ) ) );
753 action.
error =
false;
757 for (
const QgsFeature &feat : std::as_const( featureList ) )
764 filterRestorer.reset();
773 Q_ASSERT( provider );
777 const QMap<QString, int> fieldMap = provider->fieldNameMap();
778 QMap<QString, int>::const_iterator fieldMapIt;
780 for (
int i = 0; i < featureNodeList.count(); i++ )
784 QDomElement featureElem = featureNodeList.at( i ).toElement();
785 QDomNode currentAttributeChild = featureElem.firstChild();
786 bool conversionSuccess =
true;
788 while ( !currentAttributeChild.isNull() )
790 QDomElement currentAttributeElement = currentAttributeChild.toElement();
791 QString attrName = currentAttributeElement.localName();
793 if ( attrName != QLatin1String(
"boundedBy" ) )
795 if ( attrName != QLatin1String(
"geometry" ) )
797 fieldMapIt = fieldMap.find( attrName );
798 if ( fieldMapIt == fieldMap.constEnd() )
804 QString attrValue = currentAttributeElement.text();
807 QgsMessageLog::logMessage( QStringLiteral(
"attr: name=%1 idx=%2 value=%3" ).arg( attrName ).arg( fieldMapIt.value() ).arg( attrValue ) );
809 if ( attrType == QVariant::Int )
810 feat.
setAttribute( fieldMapIt.value(), attrValue.toInt( &conversionSuccess ) );
811 else if ( attrType == QVariant::Double )
812 feat.
setAttribute( fieldMapIt.value(), attrValue.toDouble( &conversionSuccess ) );
816 if ( !conversionSuccess )
832 currentAttributeChild = currentAttributeChild.nextSibling();
842 if ( !parameters.contains( QStringLiteral(
"OPERATION" ) ) )
846 if ( parameters.value( QStringLiteral(
"OPERATION" ) ).toUpper() != QLatin1String(
"DELETE" ) )
852 if ( ( parameters.contains( QStringLiteral(
"FEATUREID" ) )
853 && ( parameters.contains( QStringLiteral(
"FILTER" ) ) || parameters.contains( QStringLiteral(
"BBOX" ) ) ) )
854 || ( parameters.contains( QStringLiteral(
"FILTER" ) )
855 && ( parameters.contains( QStringLiteral(
"FEATUREID" ) ) || parameters.contains( QStringLiteral(
"BBOX" ) ) ) )
856 || ( parameters.contains( QStringLiteral(
"BBOX" ) )
857 && ( parameters.contains( QStringLiteral(
"FEATUREID" ) ) || parameters.contains( QStringLiteral(
"FILTER" ) ) ) )
865 QStringList typeNameList;
867 if ( parameters.contains( QStringLiteral(
"FEATUREID" ) ) )
869 QStringList fidList = parameters.value( QStringLiteral(
"FEATUREID" ) ).split(
',' );
871 QMap<QString, QStringList> fidsMap;
873 QStringList::const_iterator fidIt = fidList.constBegin();
874 for ( ; fidIt != fidList.constEnd(); ++fidIt )
877 QString fid = *fidIt;
880 if ( !fid.contains(
'.' ) )
885 QString
typeName = fid.section(
'.', 0, 0 );
886 fid = fid.section(
'.', 1, 1 );
887 if ( !typeNameList.contains(
typeName ) )
901 QMap<QString, QStringList>::const_iterator fidsMapIt = fidsMap.constBegin();
902 while ( fidsMapIt != fidsMap.constEnd() )
910 request.
deletes.append( action );
915 if ( !parameters.contains( QStringLiteral(
"TYPENAME" ) ) )
920 typeNameList = parameters.value( QStringLiteral(
"TYPENAME" ) ).split(
',' );
923 QStringList::const_iterator typeNameIt = typeNameList.constBegin();
924 for ( ; typeNameIt != typeNameList.constEnd(); ++typeNameIt )
932 request.
deletes.append( action );
936 if ( parameters.contains( QStringLiteral(
"EXP_FILTER" ) ) )
938 QString expFilterName = parameters.value( QStringLiteral(
"EXP_FILTER" ) );
939 QStringList expFilterList;
940 const thread_local QRegularExpression rx(
"\\(([^()]+)\\)" );
941 QRegularExpressionMatchIterator matchIt = rx.globalMatch( expFilterName );
942 if ( !matchIt.hasNext() )
944 expFilterList << expFilterName;
948 while ( matchIt.hasNext() )
950 const QRegularExpressionMatch match = matchIt.next();
951 if ( match.hasMatch() )
953 QStringList matches = match.capturedTexts();
955 expFilterList.append( matches );
961 if ( request.
deletes.size() == expFilterList.size() )
964 QList<transactionDelete>::iterator dIt = request.
deletes.begin();
965 QStringList::const_iterator expFilterIt = expFilterList.constBegin();
966 for ( ; dIt != request.
deletes.end(); ++dIt )
971 if ( expFilterIt != expFilterList.constEnd() )
973 expFilter = *expFilterIt;
975 std::shared_ptr<QgsExpression> filter(
new QgsExpression( expFilter ) );
978 if ( filter->hasParserError() )
984 if ( filter->needsGeometry() )
999 if ( parameters.contains( QStringLiteral(
"BBOX" ) ) )
1002 QString bbox = parameters.value( QStringLiteral(
"BBOX" ) );
1003 if ( bbox.isEmpty() )
1009 QStringList corners = bbox.split(
',' );
1010 if ( corners.size() != 4 )
1018 for (
int i = 0; i < 4; i++ )
1020 corners[i].replace(
' ',
'+' );
1021 d[i] = corners[i].toDouble( &ok );
1031 QList<transactionDelete>::iterator dIt = request.
deletes.begin();
1032 for ( ; dIt != request.
deletes.end(); ++dIt )
1039 else if ( parameters.contains( QStringLiteral(
"FILTER" ) ) )
1041 QString filterName = parameters.value( QStringLiteral(
"FILTER" ) );
1042 QStringList filterList;
1044 const thread_local QRegularExpression rx(
"\\(([^()]+)\\)" );
1045 QRegularExpressionMatchIterator matchIt = rx.globalMatch( filterName );
1046 if ( !matchIt.hasNext() )
1048 filterList << filterName;
1052 while ( matchIt.hasNext() )
1054 const QRegularExpressionMatch match = matchIt.next();
1055 if ( match.hasMatch() )
1057 QStringList matches = match.capturedTexts();
1058 matches.pop_front();
1059 filterList.append( matches );
1065 if ( request.
deletes.size() != filterList.size() )
1071 QList<transactionDelete>::iterator dIt = request.
deletes.begin();
1072 QStringList::const_iterator filterIt = filterList.constBegin();
1073 for ( ; dIt != request.
deletes.end(); ++dIt )
1078 QDomDocument filter;
1079 if ( filterIt != filterList.constEnd() )
1082 if ( !filter.setContent( *filterIt,
true, &errorMsg ) )
1088 QDomElement filterElem = filter.firstChildElement();
1089 QStringList serverFids;
1093 if ( filterIt != filterList.constEnd() )
1108 QDomNodeList docChildNodes = docElem.childNodes();
1110 QDomElement actionElem;
1113 for (
int i = docChildNodes.count(); 0 < i; --i )
1115 actionElem = docChildNodes.at( i - 1 ).toElement();
1116 actionName = actionElem.localName();
1118 if ( actionName == QLatin1String(
"Insert" ) )
1121 request.
inserts.append( action );
1123 else if ( actionName == QLatin1String(
"Update" ) )
1126 request.
updates.append( action );
1128 else if ( actionName == QLatin1String(
"Delete" ) )
1131 request.
deletes.append( action );
1140 QString
typeName = actionElem.attribute( QStringLiteral(
"typeName" ) );
1144 QDomElement filterElem = actionElem.firstChild().toElement();
1145 if ( filterElem.tagName() != QLatin1String(
"Filter" ) )
1150 QStringList serverFids;
1157 action.
error =
false;
1159 if ( actionElem.hasAttribute( QStringLiteral(
"handle" ) ) )
1161 action.
handle = actionElem.attribute( QStringLiteral(
"handle" ) );
1169 QString
typeName = actionElem.attribute( QStringLiteral(
"typeName" ) );
1173 QDomNodeList propertyNodeList = actionElem.elementsByTagName( QStringLiteral(
"Property" ) );
1174 if ( propertyNodeList.isEmpty() )
1179 QMap<QString, QString> propertyMap;
1180 QDomElement propertyElem;
1181 QDomElement nameElem;
1182 QDomElement valueElem;
1183 QDomElement geometryElem;
1185 for (
int l = 0; l < propertyNodeList.count(); ++l )
1187 propertyElem = propertyNodeList.at( l ).toElement();
1188 nameElem = propertyElem.elementsByTagName( QStringLiteral(
"Name" ) ).at( 0 ).toElement();
1189 valueElem = propertyElem.elementsByTagName( QStringLiteral(
"Value" ) ).at( 0 ).toElement();
1190 if ( nameElem.text() != QLatin1String(
"geometry" ) )
1192 propertyMap.insert( nameElem.text(), valueElem.text() );
1196 geometryElem = valueElem;
1200 QDomNodeList filterNodeList = actionElem.elementsByTagName( QStringLiteral(
"Filter" ) );
1202 QStringList serverFids;
1203 if ( filterNodeList.size() != 0 )
1205 QDomElement filterElem = filterNodeList.at( 0 ).toElement();
1215 action.
error =
false;
1217 if ( actionElem.hasAttribute( QStringLiteral(
"handle" ) ) )
1219 action.
handle = actionElem.attribute( QStringLiteral(
"handle" ) );
1227 QDomNodeList featureNodeList = actionElem.childNodes();
1228 if ( featureNodeList.size() != 1 )
1234 for (
int i = 0; i < featureNodeList.count(); ++i )
1236 QString tempTypeName = featureNodeList.at( i ).toElement().localName();
1237 if ( tempTypeName.contains(
':' ) )
1238 tempTypeName = tempTypeName.section(
':', 1, 1 );
1244 else if ( tempTypeName !=
typeName )
1253 action.
error =
false;
1255 if ( actionElem.hasAttribute( QStringLiteral(
"handle" ) ) )
1257 action.
handle = actionElem.attribute( QStringLiteral(
"handle" ) );
1266 void addTransactionResult( QDomDocument &responseDoc, QDomElement &responseElem,
const QString &status,
1267 const QString &locator,
const QString &message )
1269 QDomElement trElem = responseDoc.createElement( QStringLiteral(
"TransactionResult" ) );
1270 QDomElement stElem = responseDoc.createElement( QStringLiteral(
"Status" ) );
1271 QDomElement successElem = responseDoc.createElement( status );
1272 stElem.appendChild( successElem );
1273 trElem.appendChild( stElem );
1274 responseElem.appendChild( trElem );
1276 if ( !locator.isEmpty() )
1278 QDomElement locElem = responseDoc.createElement( QStringLiteral(
"Locator" ) );
1279 locElem.appendChild( responseDoc.createTextNode( locator ) );
1280 trElem.appendChild( locElem );
1283 if ( !message.isEmpty() )
1285 QDomElement mesElem = responseDoc.createElement( QStringLiteral(
"Message" ) );
1286 mesElem.appendChild( responseDoc.createTextNode( message ) );
1287 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.
QgsCoordinateTransformContext transformContext() const
Returns data provider coordinate transform context.
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.
transactionInsert parseInsertActionElement(QDomElement &actionElem)
Transform Insert element to transactionInsert.
transactionDelete parseDeleteActionElement(QDomElement &actionElem, const QgsProject *project)
Transform Delete element to transactionDelete.
void performTransaction(transactionRequest &aRequest, QgsServerInterface *serverIface, const QgsProject *project)
Perform the transaction.
QDomDocument createTransactionDocument(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request)
Create a wfs transaction document.
transactionRequest parseTransactionRequestBody(QDomElement &docElem, const QgsProject *project)
Transform RequestBody root element to getFeatureRequest.
transactionRequest parseTransactionParameters(QgsServerRequest::Parameters parameters, const QgsProject *project)
void writeTransaction(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response)
Output WFS transaction response.
QgsFeatureList featuresFromGML(QDomNodeList featureNodeList, QgsVectorLayer *layer)
Transform GML feature nodes to features.
transactionUpdate parseUpdateActionElement(QDomElement &actionElem, const QgsProject *project)
Transform Update element to transactionUpdate.
QString layerTypeName(const QgsMapLayer *layer)
Returns typename from vector layer.
const QString OGC_NAMESPACE
const QString WFS_NAMESPACE
QgsFeatureRequest parseFilterElement(const QString &typeName, QDomElement &filterElem, QgsProject *project)
Transform a Filter element to a feature request.
QList< QgsFeature > QgsFeatureList
QSet< QgsFeatureId > QgsFeatureIds
QList< int > QgsAttributeList
The Context struct stores the current layer and coordinate transform context.
QgsFeatureRequest featureRequest
QStringList insertFeatureIds
QDomNodeList featureNodeList
QList< transactionUpdate > updates
QList< transactionInsert > inserts
QList< transactionDelete > deletes
QMap< QString, QString > propertyMap
QgsFeatureRequest featureRequest
QDomElement geometryElement