luci-base: sys.lua: lazy-load luci.model.network
[oweals/luci.git] / modules / luci-base / luasrc / dispatcher.lua
index d85cb58243082e007a3144ca2ee03bbc50e2aca0..b43b94fdef9b6a56200ab36ffda919db89a39c0b 100644 (file)
@@ -62,9 +62,73 @@ function _ordered_children(node)
        return children
 end
 
+local function dependencies_satisfied(node)
+       if type(node.file_depends) == "table" then
+               for _, file in ipairs(node.file_depends) do
+                       local ftype = fs.stat(file, "type")
+                       if ftype == "dir" then
+                               local empty = true
+                               for e in (fs.dir(file) or function() end) do
+                                       empty = false
+                               end
+                               if empty then
+                                       return false
+                               end
+                       elseif ftype == nil then
+                               return false
+                       end
+               end
+       end
+
+       if type(node.uci_depends) == "table" then
+               for config, expect_sections in pairs(node.uci_depends) do
+                       if type(expect_sections) == "table" then
+                               for section, expect_options in pairs(expect_sections) do
+                                       if type(expect_options) == "table" then
+                                               for option, expect_value in pairs(expect_options) do
+                                                       local val = uci:get(config, section, option)
+                                                       if expect_value == true and val == nil then
+                                                               return false
+                                                       elseif type(expect_value) == "string" then
+                                                               if type(val) == "table" then
+                                                                       local found = false
+                                                                       for _, subval in ipairs(val) do
+                                                                               if subval == expect_value then
+                                                                                       found = true
+                                                                               end
+                                                                       end
+                                                                       if not found then
+                                                                               return false
+                                                                       end
+                                                               elseif val ~= expect_value then
+                                                                       return false
+                                                               end
+                                                       end
+                                               end
+                                       else
+                                               local val = uci:get(config, section)
+                                               if expect_options == true and val == nil then
+                                                       return false
+                                               elseif type(expect_options) == "string" and val ~= expect_options then
+                                                       return false
+                                               end
+                                       end
+                               end
+                       elseif expect_sections == true then
+                               if not uci:get_first(config) then
+                                       return false
+                               end
+                       end
+               end
+       end
+
+       return true
+end
+
 function node_visible(node)
    if node then
          return not (
+                (not dependencies_satisfied(node)) or
                 (not node.title or #node.title == 0) or
                 (not node.target or node.hidden == true) or
                 (type(node.target) == "table" and node.target.type == "firstchild" and
@@ -149,7 +213,11 @@ function httpdispatch(request, prefix)
        --context._disable_memtrace()
 end
 
-local function require_post_security(target)
+local function require_post_security(target, args)
+       if type(target) == "table" and target.type == "arcombine" and type(target.targets) == "table" then
+               return require_post_security((type(args) == "table" and #args > 0) and target.targets[2] or target.targets[1], args)
+       end
+
        if type(target) == "table" then
                if type(target.post) == "table" then
                        local param_name, required_val, request_val
@@ -328,7 +396,7 @@ function dispatch(request)
                        assert(media, "No valid theme found")
                end
 
-               local function _ifattr(cond, key, val)
+               local function _ifattr(cond, key, val, noescape)
                        if cond then
                                local env = getfenv(3)
                                local scope = (type(env.self) == "table") and env.self
@@ -339,13 +407,16 @@ function dispatch(request)
                                                val = util.serialize_json(val)
                                        end
                                end
-                               return string.format(
-                                       ' %s="%s"', tostring(key),
-                                       util.pcdata(tostring( val
-                                        or (type(env[key]) ~= "function" and env[key])
-                                        or (scope and type(scope[key]) ~= "function" and scope[key])
-                                        or "" ))
-                               )
+
+                               val = tostring(val or
+                                       (type(env[key]) ~= "function" and env[key]) or
+                                       (scope and type(scope[key]) ~= "function" and scope[key]) or "")
+
+                               if noescape ~= true then
+                                       val = util.pcdata(val)
+                               end
+
+                               return string.format(' %s="%s"', tostring(key), val)
                        else
                                return ''
                        end
@@ -467,7 +538,7 @@ function dispatch(request)
                return
        end
 
-       if c and require_post_security(c.target) then
+       if c and require_post_security(c.target, args) then
                if not test_post_security(c) then
                        return
                end
@@ -854,6 +925,15 @@ function template(name)
 end
 
 
+local _view = function(self, ...)
+       require "luci.template".render("view", { view = self.view })
+end
+
+function view(name)
+       return {type = "view", view = name, target = _view}
+end
+
+
 local function _cbi(self, ...)
        local cbi = require "luci.cbi"
        local tpl = require "luci.template"