class Knj::Web attr_reader :session, :cgi, :data def initialize(args = {}) @args = Knj::ArrayExt.hash_sym(args) @db = @args[:db] if @args[:db] @args[:tmp] = "/tmp" if !@args[:tmp] raise "No ID was given." if !@args[:id] raise "No DB was given." if !@args[:db] if @args[:cgi] @cgi = @args[:cgi] elsif $_CGI @cgi = $_CGI else if ENV["HTTP_HOST"] or $knj_eruby or Knj::Php.class_exists("Apache") @cgi = CGI.new end end $_CGI = @cgi if !$_CGI self.read_cgi if $_FCGI KnjEruby.connect("exit") do @session.close @post = nil @get = nil @server = nil @cookie = nil $_POST = nil $_GET = nil $_SERVER = nil $_COOKIE = nil end else Kernel.at_exit do @session.close @post = nil @get = nil @server = nil @cookie = nil $_POST = nil $_GET = nil $_SERVER = nil $_COOKIE = nil end end end def read_cgi(args = {}) args.each do |key, value| if key == :cgi @cgi = value else raise "No such key: #{key.to_s}" end end if $_FCGI_COUNT and $_FCGI and $_CGI @server = {} $_CGI.env_table.each do |key, value| @server[key] = value end elsif $_CGI and ENV["HTTP_HOST"] and ENV["REMOTE_ADDR"] @server = {} ENV.each do |key, value| @server[key] = value end elsif Knj::Php.class_exists("Apache") @server = { "HTTP_HOST" => Apache.request.hostname, "HTTP_USER_AGENT" => Apache.request.headers_in["User-Agent"], "REMOTE_ADDR" => Apache.request.remote_host(1), "REQUEST_URI" => Apache.request.unparsed_uri } else @server = {} end @files = {} @post = {} if @cgi and @cgi.request_method == "POST" @cgi.params.each do |pair| do_files = false isstring = true varname = pair[0] stringparse = nil if pair[1][0].class.name == "Tempfile" if varname[0..3] == "file" isstring = false do_files = true if pair[1][0].size > 0 stringparse = { "name" => pair[1][0].original_filename, "tmp_name" => pair[1][0].path, "size" => pair[1][0].size, "error" => 0 } stringparse["name"] = pair[1][0].original_filename if pair[1][0].respond_to?("original_filename") end else stringparse = File.read(pair[1][0].path) end elsif pair[1][0].is_a?(StringIO) if varname[0..3] == "file" tmpname = @args[:tmp] + "/knj_web_upload_#{Time.now.to_f.to_s}_#{rand(1000).to_s.untaint}" isstring = false do_files = true cont = pair[1][0].string Knj::Php.file_put_contents(tmpname, cont.to_s) if cont.length > 0 stringparse = { "tmp_name" => tmpname, "size" => cont.length, "error" => 0 } stringparse["name"] = pair[1][0].original_filename if pair[1][0].respond_to?("original_filename") end else stringparse = pair[1][0].string end else stringparse = pair[1][0] end if stringparse if !do_files if isstring Knj::Web.parse_name(@post, varname, stringparse) else @post[varname] = stringparse end else if isstring Knj::Web.parse_name(@files, varname, stringparse) else @files[varname] = stringparse end end end end end if @cgi and @cgi.query_string @get = Knj::Web.parse_urlquery(@cgi.query_string) else @get = {} end @cookie = {} if @cgi @cgi.cookies.each do |key, value| @cookie[key] = value[0] end end self.global_params if @args[:globals] if @cookie[@args[:id]] and (sdata = @args[:db].single(:sessions, :id => @cookie[@args[:id]])) @data = Knj::ArrayExt.hash_sym(sdata) if @data if @data[:user_agent] != @server["HTTP_USER_AGENT"] or @data[:ip] != @server["REMOTE_ADDR"] @data = nil else @db.update(:sessions, {"last_url" => @server["REQUEST_URI"].to_s, "date_active" => Time.new}, {"id" => @data[:id]}) session_id = @args[:id] + "_" + @data[:id] end end end if !@data or !session_id @db.insert(:sessions, :date_start => Time.new, :date_active => Time.new, :user_agent => @server["HTTP_USER_AGENT"], :ip => @server["REMOTE_ADDR"], :last_url => @server["REQUEST_URI"].to_s ) @data = Knj::ArrayExt.hash_sym(@db.single(:sessions, :id => @db.last_id)) session_id = @args[:id] + "_" + @data[:id] Knj::Php.setcookie(@args[:id], @data[:id]) end require "cgi/session" require "cgi/session/pstore" @session = CGI::Session.new(@session, "database_manager" => CGI::Session::PStore, "session_id" => session_id, "session_path" => @args[:tmp]) end def [](key) return @session[key.to_sym] end def []=(key, value) return @session[key.to_sym] = value end def self.parse_cookies(str) ret = {} str.split(/;\s*/).each do |cookie_str| if !match = cookie_str.match(/^(.*?)=\"(.*)\"$/) match = cookie_str.match(/^(.*?)=(.*)$/) end ret[self.urldec(match[1])] = self.urldec(match[2]) if match end return ret end def self.parse_set_cookies(str) str = String.new(str.to_s) return [] if str.length <= 0 args = {} cookie_start_regex = /^(.+?)=(.*?)(;\s*|$)/ match = str.match(cookie_start_regex) raise "Could not match cookie: '#{str}'." if !match str.gsub!(cookie_start_regex, "") args["name"] = self.urldec(match[1].to_s) args["value"] = self.urldec(match[2].to_s) while match = str.match(/(.+?)=(.*?)(;\s*|$)/) str = str.gsub(match[0], "") args[match[1].to_s.downcase] = match[2].to_s end return [args] end def self.cookie_str(cookie_data) raise "Not a hash: '#{cookie_data.class.name}', '#{cookie_data}'." unless cookie_data.is_a?(Hash) cookiestr = "#{self.urlenc(cookie_data["name"])}=#{self.urlenc(cookie_data["value"])}" cookie_data.each do |key, val| next if key == "name" or key == "value" if key.to_s.downcase == "expires" and val.is_a?(Time) cookiestr << "; Expires=#{val.httpdate}" else cookiestr << "; #{key}=#{val}" end end return cookiestr end def self.parse_urlquery(querystr, args = {}) get = {} querystr.to_s.split("&").each do |value| pos = value.index("=") if pos != nil name = value[0..pos-1] name = name.to_sym if args[:syms] valuestr = value.slice(pos+1..-1) Knj::Web.parse_name(get, self.urldec(name), valuestr, args) end end return get end def self.parse_secname(seton, secname, args) secname_empty = false if secname.length <= 0 secname_empty = true try = 0 loop do if !seton.key?(try.to_s) break else try += 1 end end secname = try.to_s end secname = secname.to_sym if args[:syms] and secname.is_a?(String) and !Knj::Php.is_numeric(secname) return [secname, secname_empty] end def self.parse_name(seton, varname, value, args = {}) if value.respond_to?(:filename) and value.filename realvalue = value else realvalue = value.to_s realvalue = self.urldec(realvalue) if args[:urldecode] realvalue = realvalue.force_encoding("utf-8") if args[:force_utf8] if realvalue.respond_to?(:force_encoding) end if varname and varname.index("[") != nil and match = varname.match(/\[(.*?)\]/) namepos = varname.index(match[0]) name = varname.slice(0..namepos - 1) name = name.to_sym if args[:syms] seton[name] = {} if !seton.key?(name) secname, secname_empty = Knj::Web.parse_secname(seton[name], match[1], args) valuefrom = namepos + secname.to_s.length + 2 restname = varname.slice(valuefrom..-1) if restname and restname.index("[") != nil seton[name][secname] = {} if !seton[name].key?(secname) Knj::Web.parse_name_second(seton[name][secname], restname, value, args) else seton[name][secname] = realvalue end else seton[varname] = realvalue end end def self.parse_name_second(seton, varname, value, args = {}) if value.respond_to?(:filename) and value.filename realvalue = value else realvalue = value.to_s realvalue = realvalue.force_encoding("utf-8") if args[:force_utf8] end match = varname.match(/^\[(.*?)\]/) if match namepos = varname.index(match[0]) name = match[1] secname, secname_empty = Knj::Web.parse_secname(seton, match[1], args) valuefrom = namepos + match[1].length + 2 restname = varname.slice(valuefrom..-1) if restname and restname.index("[") != nil seton[secname] = {} if !seton.key?(secname) Knj::Web.parse_name_second(seton[secname], restname, value, args) else seton[secname] = realvalue end else seton[varname] = realvalue end end def global_params $_POST = @post $_GET = @get $_COOKIE = @cookie $_FILES = @files $_SERVER = @server end def destroy @cgi = nil @post = nil @get = nil @session = nil @args = nil end def self.require_eruby(filepath) cont = File.read(filepath).untaint parse = Erubis.Eruby.new(cont) eval(parse.src.to_s) end def self.alert(string) require "#{$knjpath}strings" @alert_sent = true html = "" print html end def self.redirect(string, args = {}) do_js = true #Header way if !@alert_sent if args[:perm] Knj::Php.header("Status: 301 Moved Permanently") else Knj::Php.header("Status: 303 See Other") end Knj::Php.header("Location: #{string}") end print "" if do_js exit end def self.back print "" exit end def self.checkval(value, val1, val2 = nil) if val2 != nil if !value or value == "" or value == "false" return val2 else return val1 end else if !value or value == "" or value == "false" return val1 else return value end end end def self.inputs(arr) html = "" arr.each do |args| if RUBY_ENGINE == "rbx" html << self.input(args).to_s.encode(html.encoding) else html << self.input(args) end end return html end def self.style_html(css) return "" if css.length <= 0 str = " style=\"" css.each do |key, val| str << "#{key}: #{val};" end str << "\"" return str end def self.attr_html(attrs) return "" if attrs.length <= 0 html = "" attrs.each do |key, val| html << " #{key}=\"#{val.to_s.html}\"" end return html end def self.input(args) Knj::ArrayExt.hash_sym(args) if args.key?(:value) if args[:value].is_a?(Array) and args[:value].first.is_a?(NilClass) value = nil elsif args[:value].is_a?(Array) if !args[:value][2] or args[:value][2] == :key value = args[:value].first[args[:value][1]] elsif args[:value][2] == :callb value = args[:value].first.send(args[:value][1]) else value = args[:value] end elsif args[:value].is_a?(String) or args[:value].is_a?(Integer) value = args[:value].to_s else value = args[:value] end end args[:value_default] = args[:default] if args[:default] if value.is_a?(NilClass) and args[:value_default] value = args[:value_default] elsif value.is_a?(NilClass) value = "" end if value and args.key?(:value_func) and args[:value_func] cback = args[:value_func] if cback.is_a?(Method) value = cback.call(value) elsif cback.is_a?(Array) value = Knj::Php.call_user_func(args[:value_func], value) elsif cback.is_a?(Proc) value = cback.call(value) else raise "Unknown class: #{cback.class.name}." end end value = args[:values] if args[:values] args[:id] = args[:name] if !args[:id] if !args[:type] if args[:opts] args[:type] = :select elsif args[:name] and args[:name].to_s[0..2] == "che" args[:type] = :checkbox elsif args[:name] and args[:name].to_s[0..3] == "file" args[:type] = :file else args[:type] = :text end else args[:type] = args[:type].to_sym end attr = { "name" => args[:name], "id" => args[:id], "type" => args[:type], "class" => "input_#{args[:type]}" } attr.merge!(args[:attr]) if args[:attr] attr["disabled"] = "disabled" if args[:disabled] raise "No name given to the Web::input()-method." if !args[:name] and args[:type] != :info and args[:type] != :textshow and args[:type] != :plain and args[:type] != :spacer and args[:type] != :headline css = {} css["text-align"] = args[:align] if args.key?(:align) css.merge!(args[:css]) if args.key?(:css) attr_keys = [:onchange] attr_keys.each do |tag| if args.key?(tag) attr[tag] = args[tag] end end classes_tr = [] classes_tr += args[:classes_tr] if args[:classes_tr] if !classes_tr.empty? classes_tr_html = " class=\"#{classes_tr.join(" ")}\"" else classes_tr_html = "" end html = "" classes = ["input_#{args[:type]}"] classes = classes | args[:classes] if args.key?(:classes) attr["class"] = classes.join(" ") if args[:type] == :checkbox attr["value"] = args[:value_active] if args.key?(:value_active) attr["checked"] = "checked" if value.is_a?(String) and value == "1" or value.to_s == "1" or value.to_s == "on" or value.to_s == "true" attr["checked"] = "checked" if value.is_a?(TrueClass) html << "
" html << "" html << " | " raise "No path given for imageupload-input." if !args.key?(:path) raise "No value given in arguments for imageupload-input." if !args.key?(:value) path = args[:path].gsub("%value%", value.to_s).untaint if File.exists?(path) html << "" if args[:dellink] dellink = args[:dellink].gsub("%value%", value.to_s) html << "" end end html << " |