Add WiFiManagerRequestArgs class and update saveParamsCallback to pass request arguments

- Created WiFiManagerRequestArgs nested class to encapsulate HTTP request arguments
- Updated setSaveParamsCallback to accept WiFiManagerRequestArgs by value
- Updated handleWifiSave() and handleParamSave() to build RequestArgs early
- Updated doParamSave() to accept and use RequestArgs for custom HTML params
- Updated test callbacks to match new signature
- All tests passing (43/43)
This commit is contained in:
2025-11-04 20:06:24 +10:00
parent 64c987a560
commit 4b1226bd05
3 changed files with 119 additions and 15 deletions
+74 -3
View File
@@ -131,6 +131,8 @@
#include <DNSServer.h>
#include <memory>
#include <unordered_map>
#include <string>
// Include wm strings vars
@@ -195,6 +197,8 @@
#define WFM_NO_LABEL 0
#define WFM_LABEL_DEFAULT 1
// WiFiManagerRequestArgs is defined as a nested class inside WiFiManager (after WM_WebServer is defined)
class WiFiManagerParameter {
public:
/**
@@ -247,6 +251,9 @@ class WiFiManagerParameter {
class WiFiManager
{
public:
// Forward declare nested class - defined later after WM_WebServer is available
class WiFiManagerRequestArgs;
WiFiManager(Print& consolePort);
WiFiManager();
~WiFiManager();
@@ -319,7 +326,7 @@ class WiFiManager
void setPreSaveParamsCallback( std::function<void()> func );
//called when saving either params-in-wifi or params page
void setSaveParamsCallback( std::function<void()> func );
void setSaveParamsCallback( std::function<void(WiFiManagerRequestArgs)> func );
//called just before doing OTA update
void setPreOtaUpdateCallback( std::function<void()> func );
@@ -514,6 +521,70 @@ class WiFiManager
std::unique_ptr<WM_WebServer> server;
public:
// Define WiFiManagerRequestArgs here after WM_WebServer is available
class WiFiManagerRequestArgs {
public:
std::unordered_map<std::string, std::string> args;
// Constructor - builds from WM_WebServer (ESP8266WebServer or WebServer)
WiFiManagerRequestArgs(WM_WebServer* server) {
if (server) {
for (uint8_t i = 0; i < server->args(); i++) {
String argName = server->argName(i);
String argValue = server->arg(i);
args[std::string(argName.c_str())] = std::string(argValue.c_str());
}
}
}
WiFiManagerRequestArgs() {}
// Check if argument exists
bool hasArg(const char* name) const {
return args.find(std::string(name)) != args.end();
}
bool hasArg(const String& name) const {
return hasArg(name.c_str());
}
// Get argument value as String
String getArg(const char* name, const String& defaultValue = "") const {
auto it = args.find(std::string(name));
if (it != args.end()) {
return String(it->second.c_str());
}
return defaultValue;
}
String getArg(const String& name, const String& defaultValue = "") const {
return getArg(name.c_str(), defaultValue);
}
// Type conversion helpers
int getArgAsInt(const char* name, int defaultValue = 0) const {
String value = getArg(name);
return value.length() > 0 ? value.toInt() : defaultValue;
}
float getArgAsFloat(const char* name, float defaultValue = 0.0f) const {
String value = getArg(name);
return value.length() > 0 ? value.toFloat() : defaultValue;
}
bool getArgAsBool(const char* name, bool defaultValue = false) const {
String value = getArg(name);
if (value.length() == 0) return defaultValue;
return value == "1" || value.equalsIgnoreCase("true") ||
value.equalsIgnoreCase("on") || value.equalsIgnoreCase("yes");
}
size_t count() const {
return args.size();
}
};
protected:
// vars
std::vector<uint8_t> _menuIds;
@@ -688,7 +759,7 @@ protected:
void handleWiFiStatus();
void handleRequest();
void handleParamSave();
void doParamSave();
void doParamSave(WiFiManagerRequestArgs requestArgs);
boolean captivePortal();
boolean configPortalHasTimeout();
@@ -841,7 +912,7 @@ protected:
std::function<void()> _savewificallback;
std::function<void()> _presavewificallback;
std::function<void()> _presaveparamscallback;
std::function<void()> _saveparamscallback;
std::function<void(WiFiManagerRequestArgs)> _saveparamscallback;
std::function<void()> _resetcallback;
std::function<void()> _preotaupdatecallback;
std::function<void()> _configportaltimeoutcallback;
+42 -11
View File
@@ -1826,6 +1826,9 @@ void WiFiManager::handleWifiSave() {
#endif
handleRequest();
// BUILD REQUEST ARGS STRUCT EARLY - captures all arguments while request is active
WiFiManagerRequestArgs requestArgs(server.get());
//SAVE/connect here
_ssid = server->arg(F("s")).c_str();
_pass = server->arg(F("p")).c_str();
@@ -1888,7 +1891,7 @@ void WiFiManager::handleWifiSave() {
_presavewificallback(); // @CALLBACK
}
if(_paramsInWifi) doParamSave();
if(_paramsInWifi) doParamSave(requestArgs);
String page;
@@ -1924,7 +1927,10 @@ void WiFiManager::handleParamSave() {
#endif
handleRequest();
doParamSave();
// BUILD REQUEST ARGS STRUCT
WiFiManagerRequestArgs requestArgs(server.get());
doParamSave(requestArgs);
String page = getHTTPHead(FPSTR(S_titleparamsaved), FPSTR(C_param)); // @token titleparamsaved
page += FPSTR(HTTP_PARAMSAVED);
@@ -1938,7 +1944,7 @@ void WiFiManager::handleParamSave() {
#endif
}
void WiFiManager::doParamSave(){
void WiFiManager::doParamSave(WiFiManagerRequestArgs requestArgs){
// @todo use new callback for before paramsaves, is this really needed?
if ( _presaveparamscallback != NULL) {
_presaveparamscallback(); // @CALLBACK
@@ -1958,13 +1964,38 @@ void WiFiManager::doParamSave(){
#endif
break; // @todo might not be needed anymore
}
//read parameter from server
String name = (String)FPSTR(S_parampre)+(String)i;
String value;
if(server->hasArg(name)) {
value = server->arg(name);
// Check if this is a custom HTML parameter (ID is null)
if (_params[i]->getID() == nullptr) {
// For custom HTML parameters, try to get from RequestArgs
String name = (String)FPSTR(S_parampre)+(String)i;
// Try RequestArgs first
if (requestArgs.hasArg(name)) {
value = requestArgs.getArg(name);
} else {
// Fallback to server for now (will be removed when DeviceFramework uses RequestArgs)
if(server->hasArg(name)) {
value = server->arg(name);
} else {
continue; // Skip if not found
}
}
} else {
value = server->arg(_params[i]->getID());
// Regular parameter - use existing logic
String name = (String)FPSTR(S_parampre)+(String)i;
if(server->hasArg(name)) {
value = server->arg(name);
} else {
value = server->arg(_params[i]->getID());
}
// Also check RequestArgs as fallback for custom params that might share ID
if (value.length() == 0 && requestArgs.hasArg(_params[i]->getID())) {
value = requestArgs.getArg(_params[i]->getID());
}
}
//store it in params array
@@ -1979,7 +2010,7 @@ void WiFiManager::doParamSave(){
}
if ( _saveparamscallback != NULL) {
_saveparamscallback(); // @CALLBACK
_saveparamscallback(requestArgs); // @CALLBACK - PASS RequestArgs
}
}
@@ -2869,9 +2900,9 @@ void WiFiManager::setConfigResetCallback( std::function<void()> func ) {
/**
* setSaveParamsCallback, set a save params callback on params save in wifi or params pages
* @access public
* @param {[type]} void (*func)(void)
* @param {[type]} void (*func)(WiFiManagerRequestArgs)
*/
void WiFiManager::setSaveParamsCallback( std::function<void()> func ) {
void WiFiManager::setSaveParamsCallback( std::function<void(WiFiManagerRequestArgs)> func ) {
_saveparamscallback = func;
}
@@ -29,8 +29,10 @@ void pre_save_config_callback() {
pre_save_config_callback_fired = true;
}
void save_params_callback() {
void save_params_callback(WiFiManager::WiFiManagerRequestArgs requestArgs) {
save_params_callback_fired = true;
// Test that we can access request args
(void)requestArgs; // Suppress unused variable warning
}
void pre_save_params_callback() {