X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=modules%2Fluci-base%2Fluasrc%2Fcbi.lua;h=d275c5b27564366041a56fc3010b07d4a938e8dc;hb=e987c7e069b820e5eb6956c166a3cda3822054b6;hp=9b88e9fd9fba6ba81fb0e605f48168c78837cea4;hpb=6509e007e29f438d74b01eb6e23a09f02775dd6c;p=oweals%2Fluci.git diff --git a/modules/luci-base/luasrc/cbi.lua b/modules/luci-base/luasrc/cbi.lua index 9b88e9fd9..d275c5b27 100644 --- a/modules/luci-base/luasrc/cbi.lua +++ b/modules/luci-base/luasrc/cbi.lua @@ -38,7 +38,7 @@ function load(cbimap, ...) require("luci.config") require("luci.util") - local upldir = "/lib/uci/upload/" + local upldir = "/etc/luci-uploads/" local cbidir = luci.util.libpath() .. "/model/cbi/" local func, err @@ -262,6 +262,7 @@ function Node.render_children(self, ...) local k, node for k, node in ipairs(self.children) do node.last_child = (k == #self.children) + node.index = k node:render(...) end end @@ -336,7 +337,7 @@ function Map.__init__(self, config, ...) end function Map.formvalue(self, key) - return self.readinput and luci.http.formvalue(key) + return self.readinput and luci.http.formvalue(key) or nil end function Map.formvaluetable(self, key) @@ -385,41 +386,45 @@ function Map.parse(self, readinput, ...) Node.parse(self, ...) - self:_run_hooks("on_save", "on_before_save") - for i, config in ipairs(self.parsechain) do - self.uci:save(config) - end - self:_run_hooks("on_after_save") - if (not self.proceed and self.flow.autoapply) or luci.http.formvalue("cbi.apply") then - self:_run_hooks("on_before_commit") + if self.save then + self:_run_hooks("on_save", "on_before_save") + local i, config for i, config in ipairs(self.parsechain) do - self.uci:commit(config) + self.uci:save(config) + end + self:_run_hooks("on_after_save") + if (not self.proceed and self.flow.autoapply) or luci.http.formvalue("cbi.apply") then + self:_run_hooks("on_before_commit") + if self.apply_on_parse == false then + for i, config in ipairs(self.parsechain) do + self.uci:commit(config) + end + end + self:_run_hooks("on_commit", "on_after_commit", "on_before_apply") + if self.apply_on_parse == true or self.apply_on_parse == false then + self.uci:apply(self.apply_on_parse) + self:_run_hooks("on_apply", "on_after_apply") + else + -- This is evaluated by the dispatcher and delegated to the + -- template which in turn fires XHR to perform the actual + -- apply actions. + self.apply_needed = true + end - -- Refresh data because commit changes section names - self.uci:load(config) + -- Reparse sections + Node.parse(self, true) end - self:_run_hooks("on_commit", "on_after_commit", "on_before_apply") - if self.apply_on_parse then - self.uci:apply(self.parsechain) - self:_run_hooks("on_apply", "on_after_apply") - else - -- This is evaluated by the dispatcher and delegated to the - -- template which in turn fires XHR to perform the actual - -- apply actions. - self.apply_needed = true + for i, config in ipairs(self.parsechain) do + self.uci:unload(config) + end + if type(self.commit_handler) == "function" then + self:commit_handler(self:submitstate()) end - - -- Reparse sections - Node.parse(self, true) - end - for i, config in ipairs(self.parsechain) do - self.uci:unload(config) - end - if type(self.commit_handler) == "function" then - self:commit_handler(self:submitstate()) end - if self.proceed then + if not self.save then + self.state = FORM_INVALID + elseif self.proceed then self.state = FORM_PROCEED elseif self.changed then self.state = FORM_CHANGED @@ -881,19 +886,24 @@ function AbstractSection.render_tab(self, tab, ...) local k, node for k, node in ipairs(self.tabs[tab].childs) do node.last_child = (k == #self.tabs[tab].childs) + node.index = k node:render(...) end end -- Parse optional options -function AbstractSection.parse_optionals(self, section) +function AbstractSection.parse_optionals(self, section, noparse) if not self.optional then return end self.optionals[section] = {} - local field = self.map:formvalue("cbi.opt."..self.config.."."..section) + local field = nil + if not noparse then + field = self.map:formvalue("cbi.opt."..self.config.."."..section) + end + for k,v in ipairs(self.children) do if v.optional and not v:cfgvalue(section) and not self:has_tabs() then if field == v.option then @@ -1071,6 +1081,11 @@ function NamedSection.__init__(self, map, section, stype, ...) self.section = section end +function NamedSection.prepare(self) + AbstractSection.prepare(self) + AbstractSection.parse_optionals(self, self.section, true) +end + function NamedSection.parse(self, novld) local s = self.section local active = self:cfgvalue(s) @@ -1120,6 +1135,15 @@ function TypedSection.__init__(self, map, type, ...) self.anonymous = false end +function TypedSection.prepare(self) + AbstractSection.prepare(self) + + local i, s + for i, s in ipairs(self:cfgsections()) do + AbstractSection.parse_optionals(self, s, true) + end +end + -- Return all matching UCI sections for this TypedSection function TypedSection.cfgsections(self) local sections = {} @@ -1202,13 +1226,14 @@ function TypedSection.parse(self, novld) local stval = RESORT_PREFIX .. self.config .. "." .. self.sectiontype local order = self.map:formvalue(stval) if order and #order > 0 then - local sid - local num = 0 + local sids, sid = { }, nil for sid in util.imatch(order) do - self.map.uci:reorder(self.config, sid, num) - num = num + 1 + sids[#sids+1] = sid + end + if #sids > 0 then + self.map.uci:reorder(self.config, sids) + self.changed = true end - self.changed = (num > 0) end end @@ -1272,7 +1297,6 @@ function AbstractValue.__init__(self, map, section, option, ...) self.tag_reqerror = {} self.tag_error = {} self.deps = {} - self.subdeps = {} --self.cast = "string" self.track_missing = false @@ -1296,7 +1320,30 @@ function AbstractValue.depends(self, field, value) deps = field end - table.insert(self.deps, {deps=deps, add=""}) + table.insert(self.deps, deps) +end + +-- Serialize dependencies +function AbstractValue.deplist2json(self, section, deplist) + local deps, i, d = { } + + if type(self.deps) == "table" then + for i, d in ipairs(deplist or self.deps) do + local a, k, v = { } + for k, v in pairs(d) do + if k:find("!", 1, true) then + a[k] = v + elseif k:find(".", 1, true) then + a['cbid.%s' % k] = v + else + a['cbid.%s.%s.%s' %{ self.config, section, k }] = v + end + end + deps[#deps+1] = a + end + end + + return util.serialize_json(deps) end -- Generates the unique CBID @@ -1370,6 +1417,12 @@ function AbstractValue.parse(self, section, novld) self:add_error(section, "invalid", val_err) end + if self.alias then + self.section.aliased = self.section.aliased or {} + self.section.aliased[section] = self.section.aliased[section] or {} + self.section.aliased[section][self.alias] = true + end + if fvalue and (self.forcewrite or not (fvalue == cvalue)) then if self:write(section, fvalue) then -- Push events @@ -1379,10 +1432,16 @@ function AbstractValue.parse(self, section, novld) end else -- Unset the UCI or error if self.rmempty or self.optional then - if self:remove(section) then - -- Push events - self.section.changed = true - --luci.util.append(self.map.events, self.events) + if not self.alias or + not self.section.aliased or + not self.section.aliased[section] or + not self.section.aliased[section][self.alias] + then + if self:remove(section) then + -- Push events + self.section.changed = true + --luci.util.append(self.map.events, self.events) + end end elseif cvalue ~= fvalue and not novld then -- trigger validator with nil value to get custom user error msg. @@ -1408,7 +1467,7 @@ function AbstractValue.cfgvalue(self, section) if self.tag_error[section] then value = self:formvalue(section) else - value = self.map:get(section, self.option) + value = self.map:get(section, self.alias or self.option) end if not value then @@ -1449,12 +1508,12 @@ AbstractValue.transform = AbstractValue.validate -- Write to UCI function AbstractValue.write(self, section, value) - return self.map:set(section, self.option, value) + return self.map:set(section, self.alias or self.option, value) end -- Remove from UCI function AbstractValue.remove(self, section) - return self.map:del(section, self.option) + return self.map:del(section, self.alias or self.option) end @@ -1577,15 +1636,16 @@ function ListValue.__init__(self, ...) AbstractValue.__init__(self, ...) self.template = "cbi/lvalue" - self.keylist = {} - self.vallist = {} self.size = 1 self.widget = "select" + + self:reset_values() end function ListValue.reset_values(self) self.keylist = {} self.vallist = {} + self.deplist = {} end function ListValue.value(self, key, val, ...) @@ -1596,10 +1656,7 @@ function ListValue.value(self, key, val, ...) val = val or key table.insert(self.keylist, tostring(key)) table.insert(self.vallist, tostring(val)) - - for i, deps in ipairs({...}) do - self.subdeps[#self.subdeps + 1] = {add = "-"..key, deps=deps} - end + table.insert(self.deplist, {...}) end function ListValue.validate(self, val) @@ -1623,11 +1680,10 @@ function MultiValue.__init__(self, ...) AbstractValue.__init__(self, ...) self.template = "cbi/mvalue" - self.keylist = {} - self.vallist = {} - self.widget = "checkbox" self.delimiter = " " + + self:reset_values() end function MultiValue.render(self, ...) @@ -1641,6 +1697,7 @@ end function MultiValue.reset_values(self) self.keylist = {} self.vallist = {} + self.deplist = {} end function MultiValue.value(self, key, val) @@ -1715,8 +1772,7 @@ function DynamicList.__init__(self, ...) AbstractValue.__init__(self, ...) self.template = "cbi/dynlist" self.cast = "table" - self.keylist = {} - self.vallist = {} + self:reset_values() end function DynamicList.reset_values(self) @@ -1790,6 +1846,15 @@ function DynamicList.formvalue(self, section) end +DropDown = class(MultiValue) + +function DropDown.__init__(self, ...) + ListValue.__init__(self, ...) + self.template = "cbi/dropdown" + self.delimiter = " " +end + + --[[ TextValue - A multi-line value rows: Rows