|
|
#include <module.h> |
#include <roxen.h> |
|
|
|
|
#define LOCALE(X,Y) \ |
([string](mixed)Locale.translate("roxen_config",roxenp()->locale->get(),X,Y)) |
|
|
|
protected int unique_vid; |
protected string unique_prefix = (string) getpid(); |
|
|
|
|
|
protected mapping(string:mixed) changed_values = ([]); |
protected mapping(string:function(object:void)) changed_callbacks = ([]); |
protected mapping(string:int) all_flags = ([]); |
protected mapping(string:string) all_warnings = ([]); |
protected mapping(string:function(RequestID,object:int)) |
invisibility_callbacks = set_weak_flag( ([]), 1 ); |
|
mapping(string:Variable) all_variables = set_weak_flag( ([]), 1 ); |
|
mapping get_all_variables() |
{ |
return all_variables; |
} |
|
Variable get_variables( string v ) |
{ |
return all_variables[v]; |
} |
|
string get_diff_def_html( Variable v, |
string button_tag, |
string def_url, |
string diff_url, |
int page ) |
{ |
if( page ) |
return v->diff( 2 ); |
|
if( v->is_defaulted() || (v->get_flags() & VAR_NO_DEFAULT) ) |
return ""; |
|
string oneliner = v->diff( 0 ), diff_button=""; |
mapping m; |
|
if( !oneliner ) |
{ |
if( v->diff( 1 ) ) |
{ |
m = ([ "href":diff_url,"target":"_new", ]); |
diff_button = |
Roxen.make_container( "a",m, |
Roxen.make_container( |
button_tag, |
([]), |
LOCALE(474,"Show changes") |
) ); |
} |
} |
m = ([ "href" : def_url, |
"onclick" : "return confirm('" + LOCALE(1041, "Are you sure you want " |
"to restore the default " |
"value?") + "');" ]); |
return diff_button + " " + |
Roxen.make_container( "a",m, |
Roxen.make_container( button_tag, ([]), |
LOCALE(475, "Restore default value" )+ |
(oneliner||"") ) ); |
|
} |
|
class Diff |
{ |
private array(string) diff; |
|
private |
array(string) print_row(array(string) diff_old, array(string) diff_new, |
int line, int|void start, int|void end) |
{ |
if(!sizeof(diff_old) && sizeof(diff_new)) |
|
return Array.map(diff_new, lambda(string s) {return "+ " + s;} ); |
|
if(sizeof(diff_old) && !sizeof(diff_new)) |
|
return Array.map(diff_old, lambda(string s) {return "- " + s;} ); |
|
if(diff_old != diff_new) |
|
return Array.map(diff_old, lambda(string s) {return "- " + s;} ) |
+ Array.map(diff_new, lambda(string s) {return "+ " + s;} ); |
|
if(start + end < sizeof(diff_old) && (start || end)) |
{ |
if(start && !end) |
diff_old = diff_old[.. start - 1]; |
else |
{ |
diff_old = diff_old[.. start - 1] + |
({ line + sizeof(diff_old) - end }) + |
diff_old[sizeof(diff_old) - end ..]; |
} |
} |
|
return Array.map(diff_old, lambda(string|int s) |
{ if(intp(s)) return "Line "+s+":"; |
return " " + s; } ); |
} |
|
string html(void|int hide_header) |
{ |
string r = ""; |
int added, deleted; |
if(sizeof(diff) && diff[-1] == " ") |
diff = diff[..sizeof(diff)-2]; |
foreach(diff, string row) |
{ |
row = Roxen.html_encode_string(row); |
row = replace(row, "\t", " "); |
row = replace(row, " ", " "); |
switch(row[0]) |
{ |
case '&': r += "<tt>"+row+"</tt><br>\n"; |
break; |
case '+': r += "<font color='darkgreen'><tt>"+row+"</tt></font><br>\n"; |
added++; |
break; |
case '-': r += "<font color='darkred'><tt>"+row+"</tt></font><br>\n"; |
deleted++; |
break; |
case 'L': r += "<i>"+row+"</i><br>\n"; |
break; |
} |
} |
if (!hide_header) |
r = |
"<b>" + LOCALE(476, "Change in content") + "</b><br />\n"+ |
"<i>"+(added==1? LOCALE(477, "1 line added."): |
sprintf(LOCALE(478, "%d lines added."), added)) + " " + |
(deleted==1? LOCALE(479, "1 line deleted."): |
sprintf(LOCALE(480, "%d lines deleted."), deleted)) + |
"</i><p>\n"+ |
r; |
return r; |
} |
|
array get() |
{ |
return diff; |
} |
|
void create(array(string) new, array(string) old, int context) |
{ |
array(array(string)) diff_old, diff_new; |
|
[diff_old, diff_new] = Array.diff(old, new); |
int line = 1; |
int diffp = 0; |
diff = ({ }); |
for(int i = 0; i < sizeof(diff_old); i++) |
{ |
if(diff_old[i] != diff_new[i]) |
{ |
diff += print_row(diff_old[i], diff_new[i], line); |
|
diffp = 1; |
} |
else if(sizeof(diff_old) > 1) |
{ |
diff += print_row(diff_old[i], diff_new[i], line, |
diffp?context:0, |
sizeof(diff_old) - 1 > i?context:0 ); |
diffp = 0; |
} |
line += sizeof(diff_old[i] - ({ })); |
} |
} |
} |
|
|
|
class Variable |
|
|
{ |
constant is_variable = 1; |
|
constant type = "Basic"; |
|
|
string _id = unique_prefix + "_" + (string) unique_vid++; |
|
|
protected mixed _initial; |
protected string _path = sprintf("v%s",_id); |
protected LocaleString __name, __doc; |
|
string diff( int render ) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
return 0; |
} |
|
void destroy() |
{ |
if (global::this) { |
|
m_delete( all_flags, _id ); |
m_delete( all_warnings, _id ); |
m_delete( invisibility_callbacks, _id ); |
m_delete( changed_values, _id ); |
} |
} |
|
string get_warnings() |
|
{ |
return all_warnings[ _id ]; |
} |
|
int get_flags() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
return all_flags[_id]; |
} |
|
void set_flags( int flags ) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
if(!flags ) |
m_delete( all_flags, _id ); |
else |
all_flags[_id] = flags; |
} |
|
int check_visibility( RequestID id, |
int more_mode, |
int expert_mode, |
int devel_mode, |
int initial, |
int|void variable_in_cfif ) |
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
int flags = get_flags(); |
function cb; |
if( flags & VAR_INVISIBLE ) return 0; |
if( initial && !(flags & VAR_INITIAL) ) return 0; |
if( (flags & VAR_EXPERT) && !expert_mode ) return 0; |
if( (flags & VAR_MORE) && !more_mode ) return 0; |
if( (flags & VAR_DEVELOPER) && !devel_mode ) return 0; |
if( (flags & VAR_NOT_CFIF) && variable_in_cfif ) return 0; |
if( (cb = get_invisibility_check_callback() ) && |
cb( id, this_object() ) ) |
return 0; |
return 1; |
} |
|
void set_invisibility_check_callback( function(RequestID,Variable:int) cb ) |
|
|
|
|
{ |
if( functionp( cb ) ) |
invisibility_callbacks[ _id ] = cb; |
else |
m_delete( invisibility_callbacks, _id ); |
} |
|
function(Variable:void) get_changed_callback( ) |
|
{ |
return changed_callbacks[ _id ]; |
} |
|
void set_changed_callback( function(Variable:void) cb ) |
|
|
|
|
{ |
if( functionp( cb ) ) |
changed_callbacks[ _id ] = cb; |
else |
m_delete( changed_callbacks, _id ); |
} |
|
void add_changed_callback( function(Variable:void) cb ) |
|
|
|
{ |
mixed oc = get_changed_callback( ); |
if( arrayp( oc ) ) |
oc += ({ cb }); |
else |
oc = ({ oc, cb }) - ({ 0 }); |
changed_callbacks[ _id ] = oc; |
} |
|
function(RequestID,Variable:int) get_invisibility_check_callback() |
|
{ |
return invisibility_callbacks[_id]; |
} |
|
LocaleString doc( ) |
|
|
|
|
{ |
return __doc || ""; |
} |
|
void set_doc (LocaleString doc) |
|
{ |
__doc = doc; |
} |
|
LocaleString name( ) |
|
|
|
|
{ |
return __name || LOCALE(326,"unnamed")+" "+_id; |
} |
|
void set_name (LocaleString name) |
|
{ |
__name = name; |
} |
|
LocaleString type_hint( ) |
|
|
|
{ |
} |
|
mixed default_value() |
|
{ |
return _initial; |
} |
|
void set_default_value (mixed to) |
|
|
{ |
_initial = to; |
} |
|
void set_warning( string to ) |
|
{ |
if( to && strlen(to) ) |
all_warnings[ _id ] = to; |
else |
m_delete( all_warnings, _id ); |
} |
|
void add_warning( string to ) |
|
{ |
if(to) set_warning( (get_warnings()||"") + to ); |
} |
|
int set( mixed to ) |
|
|
|
|
|
|
|
|
|
|
|
{ |
string err; |
mixed e2; |
if( e2 = catch( [err,to] = verify_set( to )) ) |
{ |
if( stringp( e2 ) ) |
{ |
add_warning( e2 ); |
return ([])[0]; |
} |
throw( e2 ); |
} |
add_warning( err ); |
return low_set( to ); |
} |
|
int low_set( mixed to ) |
|
|
|
|
{ |
if( equal( to, query() ) ) |
return 0; |
|
if( !equal(to, default_value() ) ) |
{ |
changed_values[ _id ] = to; |
if( get_changed_callback() ) |
get_changed_callback()( this_object() ); |
return 1; |
} |
else |
{ |
m_delete( changed_values, _id ); |
if( get_changed_callback() ) |
get_changed_callback()( this_object() ); |
return -1; |
} |
} |
|
mixed query() |
|
{ |
mixed v; |
if( !zero_type( v = changed_values[ _id ] ) ) |
return v; |
return default_value(); |
} |
|
mixed encode() |
|
|
|
|
|
|
{ |
return query(); |
} |
|
int decode(mixed encoded) |
|
|
|
|
|
|
|
{ |
return set(encoded); |
} |
|
int is_defaulted() |
|
{ |
return zero_type( changed_values[ _id ] ) || |
equal(changed_values[ _id ], default_value()); |
} |
|
array(string|mixed) verify_set_from_form( mixed new_value ) |
|
|
{ |
return ({ 0, new_value }); |
} |
|
array(string|mixed) verify_set( mixed new_value ) |
|
|
|
|
|
|
|
|
{ |
return ({ 0, new_value }); |
} |
|
mapping(string:string) get_form_vars( RequestID id ) |
|
{ |
string p = path(); |
array names = glob( p+"*", indices(id->real_variables) ); |
mapping res = ([ ]); |
foreach( sort(names), string n ) |
res[ n[strlen(p).. ] ] = id->real_variables[ n ][0]; |
return res; |
} |
|
mixed transform_from_form( string what, mapping|void v ) |
|
|
{ |
return what; |
} |
|
int(0..1) set_from_form( RequestID id, void|int(0..1) force ) |
|
|
|
|
|
|
|
|
|
|
|
{ |
mixed val; |
if( sizeof( val = get_form_vars(id)) && val[""]) |
{ |
set_warning(0); |
val = transform_from_form( val[""], val ); |
if( !force && val == query() ) |
return 0; |
array b; |
mixed q = catch( b = verify_set_from_form( val ) ); |
if( q || sizeof( b ) != 2 ) |
{ |
if( q ) |
add_warning( q ); |
else |
add_warning( "Internal error: Illegal sized array " |
"from verify_set_from_form\n" ); |
return 0; |
} |
if( b ) |
{ |
add_warning( b[0] ); |
set( b[1] ); |
return 1; |
} |
} |
} |
|
string path() |
|
|
|
|
|
|
|
|
{ |
return _path; |
} |
|
void set_path( string to ) |
|
|
|
|
|
|
{ |
m_delete( all_variables, _path ); |
_path = to; |
all_variables[ to ] = this_object(); |
} |
|
string render_form( RequestID id, void|mapping additional_args ); |
|
|
|
|
string render_view( RequestID id ) |
|
{ |
mixed v = query(); |
if( arrayp(v) ) v = map(v,lambda(mixed v){return(string)v;})*", " ; |
return Roxen.html_encode_string( (string)v ); |
} |
|
protected string _sprintf( int i ) |
{ |
if( i == 'O' ) |
return sprintf( "Variable.%s(%s)",type,(string)name()); |
} |
|
protected void create(mixed default_value, void|int flags, |
void|LocaleString std_name, void|LocaleString std_doc) |
|
|
|
|
|
|
|
|
|
|
{ |
set_flags( flags ); |
_initial = default_value; |
__name = std_name; |
__doc = std_doc; |
all_variables[ path() ] = this_object(); |
} |
} |
|
class NoLimit |
{ |
string _sprintf (int flag) |
{ |
switch (flag) { |
case 's': return "n/a"; |
case 'O': return this == no_limit ? "no_limit" : "<bogus no_limit clone>"; |
default: return 0; |
} |
} |
} |
|
NoLimit no_limit = NoLimit(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Float |
|
{ |
inherit Variable; |
constant type = "Float"; |
protected float|NoLimit _max = no_limit, _min = no_limit; |
protected int _prec = 2; |
protected int _may_be_empty = 0; |
protected int(0..1) _is_empty = 0; |
|
protected string _format( float|NoLimit m ) |
{ |
if (m == no_limit) |
return "n/a"; |
if( !_prec ) |
return sprintf( "%d", (int)m ); |
return sprintf( "%1."+_prec+"f", m ); |
} |
|
string diff( int render ) |
{ |
if(!render) |
return "("+_format(default_value())+")"; |
} |
|
void set_range(float|NoLimit minimum, float|NoLimit maximum ) |
|
|
|
|
{ |
if (maximum != no_limit && minimum != no_limit && maximum < minimum) |
_max = _min = no_limit; |
else { |
_max = maximum; |
_min = minimum; |
} |
} |
|
void set_precision( int prec ) |
|
|
|
{ |
_prec = prec; |
} |
|
array(string|float) verify_set( float new_value ) |
{ |
if (new_value == (float)0 && _is_empty) |
return ({ 0, new_value }); |
string warn; |
if(_max != no_limit && new_value > _max) |
{ |
warn = sprintf(LOCALE(328,"Value is bigger than %s, adjusted"), |
_format(_max) ); |
new_value = _max; |
} |
else if(_min != no_limit && new_value < _min) |
{ |
warn = sprintf(LOCALE(329,"Value is less than %s, adjusted"), |
_format(_min) ); |
new_value = _min; |
} |
return ({ warn, new_value }); |
} |
|
float transform_from_form( mixed what ) |
{ |
if (!sizeof(what) && _may_be_empty) { |
_is_empty = 1; |
return (float)0; |
} |
string junk; |
if(!sizeof(what)) { |
add_warning(LOCALE(80, "No data entered.\n")); |
return _min; |
} |
sscanf(what, "%f%s", what, junk); |
if(!junk) { |
add_warning(LOCALE(81, "Data is not a float.\n")); |
return _min; |
} |
if(sizeof(junk)) |
add_warning(sprintf(LOCALE(82, "Found the string %O trailing after the float.\n"), junk)); |
return (float)what; |
} |
|
string render_view( RequestID id ) |
{ |
return Roxen.html_encode_string( _format(query()) ); |
} |
|
string render_form( RequestID id, void|mapping additional_args ) |
{ |
int size = 15; |
if( _max != no_limit && _min != no_limit ) |
size = max( strlen(_format(_max)), strlen(_format(_min)) )+2; |
string value; |
catch { |
if (_may_be_empty && (float)query() == (float)0) |
value = ""; |
else |
value = query()==""? "" : _format( (float)query() ); |
}; |
|
additional_args = additional_args || ([]); |
if (!additional_args->type) |
additional_args->type="text"; |
|
return input(path(), value, size, additional_args); |
} |
|
void may_be_empty(int(0..1) state) |
|
{ |
_may_be_empty = state; |
} |
} |
|
|
|
|
|
|
|
|
class Int |
|
{ |
inherit Variable; |
constant type = "Int"; |
protected int|NoLimit _max = no_limit, _min = no_limit; |
|
protected int(0..1) _may_be_empty = 0; |
protected int(0..1) _is_empty = 0; |
|
void set_range(int|NoLimit minimum, int|NoLimit maximum ) |
|
|
|
|
{ |
if (maximum != no_limit && minimum != no_limit && maximum < minimum) |
_max = _min = no_limit; |
else { |
_max = maximum; |
_min = minimum; |
} |
} |
|
string diff( int render ) |
{ |
if(!render) |
return "("+default_value()+")"; |
} |
|
array(string|int) verify_set( mixed new_value ) |
{ |
if (new_value == 0 && _is_empty) |
return ({ 0, new_value }); |
string warn; |
if(!intp( new_value ) ) |
return ({ sprintf(LOCALE(152,"%O is not an integer"),new_value), |
query() }); |
if( _max != no_limit && new_value > _max) |
{ |
warn = sprintf(LOCALE(328,"Value is bigger than %s, adjusted"), |
(string)_max ); |
new_value = _max; |
} |
else if( _min != no_limit && new_value < _min) |
{ |
warn = sprintf(LOCALE(329,"Value is less than %s, adjusted"), |
(string)_min ); |
new_value = _min; |
} |
return ({ warn, new_value }); |
} |
|
int transform_from_form( mixed what ) |
{ |
if (!sizeof(what) && _may_be_empty) { |
_is_empty = 1; |
return 0; |
} |
string junk; |
if(!sizeof(what)) { |
add_warning(LOCALE(80, "No data entered.\n")); |
return _min; |
} |
sscanf( what, "%d%s", what, junk ); |
if(!junk) { |
add_warning(LOCALE(83, "Data is not an integer\n")); |
return _min; |
} |
if(sizeof(junk)) |
add_warning(sprintf(LOCALE(84, "Found the string %O trailing after the integer.\n"), junk)); |
return what; |
} |
|
string render_form( RequestID id, void|mapping additional_args ) |
{ |
int size = 10; |
if( _min != no_limit && _max != no_limit ) |
size = max( strlen((string)_max), strlen((string)_min) )+2; |
string value = (query() == 0 && _is_empty)? "" : (string)query(); |
|
additional_args = additional_args || ([]); |
if (!additional_args->type) |
additional_args->type="text"; |
|
return input(path(), value, size, additional_args); |
} |
|
void may_be_empty(int(0..1) state) |
|
{ |
_may_be_empty = state; |
} |
} |
|
class TmpInt |
|
{ |
inherit Int; |
void save() {} |
} |
|
class Priority |
|
{ |
inherit Int; |
constant type = "Priority"; |
protected int|NoLimit _max = 9, _min = 0; |
|
void set_range(int|NoLimit minimum, int|NoLimit maximum ) |
|
|
|
|
{ |
if (_max != maximum) { |
if (!maximum || !_max) { |
set_default_value(0); |
low_set(0); |
} else { |
|
int new_val = (query() * maximum)/_max; |
if (new_val < minimum) new_val = minimum; |
int new_default = (default_value() * maximum)/_max; |
set_default_value(new_default); |
low_set(new_val); |
} |
} |
_max = maximum; |
_min = minimum; |
} |
|
string render_form( RequestID id, void|mapping additional_args ) |
{ |
if ((_max != 9) || _min) return ::render_form(id, additional_args); |
|
|
string res = "<select name='"+path()+"'>\n"; |
string current = (string)query(); |
int selected = 0; |
foreach( ({ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }), int elem ) |
{ |
mapping m = ([]); |
m->value = (string)elem; |
if( equal( m->value, current ) ) { |
m->selected="selected"; |
selected = 1; |
} |
res += " "+Roxen.make_container( "option", m, (string)elem )+"\n"; |
} |
if (!selected) |
|
|
|
res += " " + Roxen.make_container ( |
"option", (["value":current, "selected": "selected"]), |
sprintf(LOCALE(332,"(keep stale value %s)"),current)); |
return res + "</select>"; |
} |
|
string|int encode() |
{ |
if (!_max) return 0; |
int ones = _max/9; |
int val = query(); |
if (val % ones) { |
|
int digits = sizeof(sprintf("%d", ones)); |
|
|
return sprintf("%*0d", digits, val); |
} |
|
return val / ones; |
} |
|
int decode(string|int encoded) |
{ |
if (!_max) { |
return set(0); |
} |
int ones = _max/9; |
if (intp(encoded)) { |
return set(encoded * ones); |
} |
if (encoded == "") { |
|
return set(5 * ones); |
} |
|
int digits = sizeof(sprintf("%d", ones)); |
while (sizeof(encoded) < digits) { |
encoded += encoded; |
} |
if (sizeof(encoded) > digits) { |
encoded = encoded[..digits-1]; |
} |
return set(array_sscanf(encoded, "%d")[0]); |
} |
|
LocaleString|string doc() |
{ |
return ::doc() + |
sprintf((string)LOCALE(1120, "<p>%d is the highest priority and " |
"0 the lowest.</p>"), |
_max); |
} |
} |
|
|
|
|
class String |
|
{ |
inherit Variable; |
constant type = "String"; |
int width = 60; |
|
|
string diff( int render ) |
{ |
if(!render) |
return "("+Roxen.html_encode_string( default_value() )+")"; |
} |
|
array(string) verify_set_from_form( mixed new ) |
{ |
return ({ 0, [string]new-"\r" }); |
} |
|
string render_form( RequestID id, void|mapping additional_args ) |
{ |
additional_args = additional_args || ([]); |
if (!additional_args->type) |
additional_args->type="text"; |
return input(path(), (string)query(), width, additional_args); |
} |
} |
|
|
|
|
class Text |
|
{ |
inherit String; |
constant type = "Text"; |
|
int cols = 56; |
|
|
int rows = 10; |
|
|
string diff( int render ) |
{ |
switch( render ) |
{ |
case 0: return 0; |
case 1: return ""; |
case 2: |
array lines_orig = default_value()/"\n"; |
array lines_new = query()/"\n"; |
|
Diff diff = Diff( lines_new, lines_orig, 2 ); |
|
if( sizeof(diff->get()) ) |
return diff->html(); |
else |
return "<i>"+LOCALE(481,"No difference\n" )+"</i>"; |
} |
} |
|
array(string) verify_set_from_form( mixed new ) |
{ |
return ({ 0, [string]new-"\r" }); |
} |
|
string render_form( RequestID id, void|mapping additional_args ) |
{ |
return "<textarea cols='"+cols+"' rows='"+rows+"' name='"+path()+"' wrap='off'>" |
+ Roxen.html_encode_string( query() || "" ) + |
"</textarea>"; |
} |
|
protected void create(mixed default_value, void|int flags, |
void|LocaleString std_name, void|LocaleString std_doc) |
|
|
|
|
|
|
|
|
|
|
{ |
if( strlen( default_value ) && default_value[0] == '\n' ) |
|
default_value = default_value[1..]; |
::create( default_value, flags, std_name, std_doc ); |
} |
|
} |
|
|
|
|
|
|
class Password |
|
{ |
inherit String; |
int width = 40; |
constant type = "Password"; |
|
int(0..1) set_from_form( RequestID id ) |
{ |
mapping val; |
if( sizeof( val = get_form_vars(id)) && |
val[""] && strlen(val[""]) ) { |
set( crypt_password( val[""] ) ); |
return 1; |
} |
return 0; |
} |
|
string render_view( RequestID id ) |
{ |
return "******"; |
} |
|
string render_form( RequestID id, void|mapping additional_args ) |
{ |
additional_args = additional_args || ([]); |
additional_args->type="password"; |
return input(path(), "", 30, additional_args); |
} |
} |
|
class File |
|
{ |
inherit String; |
constant type = "File"; |
int width = 60; |
|
string read( ) |
|
{ |
return Stdio.read_bytes( query() ); |
} |
|
Stat stat() |
|
{ |
return file_stat( query() ); |
} |
|
#ifdef __NT__ |
array verify_set( string value ) |
{ |
return ::verify_set( replace( value, "\\", "/" ) ); |
} |
#endif |
|
} |
|
class Location |
|
{ |
inherit String; |
constant type = "Location"; |
int width = 60; |
|
array verify_set( string value ) |
{ |
if( !strlen( value ) || !((<'~','/'>)[value[-1]]) ) |
return ({ |
LOCALE(330,"You most likely want an ending '/' on this variable"), |
value |
}); |
return ::verify_set( value ); |
} |
} |
|
class URL |
|
{ |
inherit String; |
constant type = "URL"; |
int width = 60; |
|
array verify_set_from_form( string new_value ) |
{ |
return verify_port( new_value ); |
} |
} |
|
class Directory |
|
{ |
inherit String; |
constant type = "Directory"; |
int width = 60; |
|
array verify_set( string value ) |
{ |
#ifdef __NT__ |
value = replace( value, "\\", "/" ); |
#endif |
if( strlen(value) && value[-1] != '/' ) |
value += "/"; |
if( !strlen( value ) ) |
return ::verify_set( value ); |
if( !(r_file_stat( value ) && (r_file_stat( value )[ ST_SIZE ] == -2 ))) |
return ({sprintf(LOCALE(331,"%s is not a directory"),value)+"\n",value}); |
return ::verify_set( value ); |
} |
|
Stat stat() |
|
{ |
return file_stat( query() ); |
} |
|
array get( ) |
|
{ |
return get_dir( query() ); |
} |
} |
|
|
|
|
|
|
|
class MultipleChoice |
|
{ |
inherit Variable; |
protected array _list = ({}); |
protected mapping _table = ([]); |
|
protected int(0..1) multiselect; |
|
|
|
constant multiselect_supported = 1; |
|
array(string|array(string)) verify_set(mixed to) |
{ |
if (multiselect && stringp(to)) { |
return ({ "Compatibility: " |
"Converted to multi-select.\n", |
({ to }), |
}); |
} else if (!multiselect && arrayp(to)) { |
return ({ "Compatibility: " |
"Converted to single-select.\n", |
sizeof (to) ? to[0] : default_value(), |
}); |
} |
|
|
return ::verify_set(to); |
} |
|
string diff( int render ) |
{ |
if(!render) { |
if (multiselect) |
return "(" + map(default_value(), _title) * ", " + ")"; |
return "("+_title( default_value() )+")"; |
} |
} |
|
void set_choice_list( array to ) |
|
{ |
_list = to; |
} |
|
array get_choice_list( ) |
|
|
{ |
return _list; |
} |
|
void set_translation_table( mapping to ) |
|
{ |
_table = to; |
} |
|
mapping get_translation_table( ) |
|
|
{ |
return _table; |
} |
|
int(0..1) set_from_form(RequestID id, void|int(0..1) force) |
{ |
if (!multiselect) return ::set_from_form(id); |
if (!id->real_variables[path()]) return 0; |
set_warning(0); |
mapping(string:string) m = get_form_vars(id); |
array(mixed) values = ({}); |
foreach(id->real_variables[path()] || ({}), string form_val) { |
mixed val = transform_from_form(form_val, m); |
array b = ({ 0, val }); |
mixed err = catch { b = verify_set_from_form(val); }; |
if (err) { |
add_warning(err); |
return 0; |
} else if (sizeof(b) != 2) { |
add_warning("Internal error: Illegal sized array " |
"from verify_set_from_form\n"); |
return 0; |
} |
if (b[0]) { |
add_warning(b[0]); |
} |
values += ({ b[1] }); |
} |
set(values); |
return 1; |
} |
|
protected string _name( mixed what ) |
|
|
{ |
return (string)what; |
} |
|
protected string _title( mixed what ) |
|
|
{ |
if( mapping tt = get_translation_table() ) |
return tt[ what ] || (string)what; |
return (string)what; |
} |
|
string render_form( RequestID id, void|mapping additional_args ) |
{ |
string autosubmit = ""; |
if(additional_args && additional_args->autosubmit) |
autosubmit = " autosubmit='autosubmit' onChange='javascript:submit();'"; |
if (multiselect) { |
array(string) current = map(query(), _name); |
string res = "<table>\n"; |
foreach( get_choice_list(), mixed elem ) |
{ |
mapping m = ([ |
"type": "checkbox", |
"name": path(), |
"value": _name(elem), |
]); |
if(has_value(current, m->value)) { |
m->checked="checked"; |
current -= ({ m->value }); |
} |
res += sprintf("<tr><td>%s</td><td>%s</td></tr>\n", |
Roxen.make_tag( "input", m), |
Roxen.html_encode_string(_title(elem))); |
} |
|
|
|
foreach(current, string value) |
{ |
mapping m = ([ |
"type": "checkbox", |
"name": path(), |
"value": value, |
"checked": "checked", |
]); |
string title = sprintf(LOCALE(1121,"(stale value %s)"), value); |
res += sprintf("<tr><td>%s</td><td>%s</td></tr>\n", |
Roxen.make_tag( "input", m), |
Roxen.html_encode_string(title)); |
} |
return res + "</table>"; |
} else { |
string current = _name (query()); |
int selected = 0; |
string res = "<select name='"+path()+"'"+autosubmit+">\n"; |
foreach( get_choice_list(), mixed elem ) |
{ |
mapping m = ([]); |
m->value = _name( elem ); |
if( equal( m->value, current ) ) { |
m->selected="selected"; |
selected = 1; |
} |
res += " "+Roxen.make_container( "option", m, _title( elem ) )+"\n"; |
} |
if (!selected) |
|
|
|
res += " " + Roxen.make_container ( |
"option", (["value":current, "selected": "selected"]), |
sprintf(LOCALE(332,"(keep stale value %s)"),current)); |
return res + "</select>"; |
} |
} |
|
protected void create( mixed default_value, array|mapping choices, |
void|int _flags, void|LocaleString std_name, |
void|LocaleString std_doc ) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
::create( default_value, _flags, std_name, std_doc ); |
multiselect = arrayp(default_value); |
if( mappingp( choices ) ) { |
set_translation_table( choices ); |
set_choice_list( sort(indices(choices)) ); |
} else |
set_choice_list( choices ); |
} |
} |
|
|
|
|
|
|
class StringChoice |
|
{ |
inherit MultipleChoice; |
constant type = "StringChoice"; |
} |
|
|
class IntChoice |
|
{ |
inherit MultipleChoice; |
constant type = "IntChoice"; |
int transform_from_form( string what ) |
{ |
return (int)what; |
} |
} |
|
class FloatChoice |
|
{ |
inherit MultipleChoice; |
constant type = "FloatChoice"; |
protected int _prec = 3; |
|
void set_precision( int prec ) |
|
|
|
{ |
_prec = prec; |
} |
|
protected string _title( mixed what ) |
{ |
if( !_prec ) |
return sprintf( "%d", (int)what ); |
return sprintf( "%1."+_prec+"f", what ); |
} |
|
int transform_from_form( string what ) |
{ |
array q = get_choice_list(); |
mapping a = mkmapping( map( q, _name ), q ); |
return a[what] || (float)what; |
} |
} |
|
class FontChoice |
|
{ |
inherit StringChoice; |
constant type = "FontChoice"; |
void set_choice_list() |
{ |
} |
array get_choice_list() |
{ |
return roxenp()->fonts->available_fonts(); |
} |
|
protected void create(mixed default_value, void|int flags, |
void|LocaleString std_name, void|LocaleString std_doc) |
|
|
|
|
|
|
|
|
|
|
{ |
::create( default_value, 0, flags,std_name, std_doc ); |
} |
} |
|
class TableChoice |
{ |
inherit StringChoice; |
constant type = "TableChoice"; |
Variable db; |
|
array(string) get_choice_list( ) |
{ |
return sort(DBManager.db_tables( db->query() )); |
} |
|
void create( string default_value, |
void|int flags, |
void|LocaleString std_name, |
void|LocaleString std_doc, |
Variable _dbchoice ) |
{ |
::create( default_value, ({}), flags, std_name, std_doc ); |
db = _dbchoice; |
} |
} |
|
|
class DatabaseChoice |
|
{ |
inherit StringChoice; |
constant type = "DatabaseChoice"; |
|
function(void:void|object) config = lambda() { return 0; }; |
|
DatabaseChoice set_configuration_pointer( function(void:object) configuration ) |
|
|
|
|
{ |
config = configuration; |
return this_object(); |
} |
|
array get_choice_list( ) |
{ |
if (!functionp(config)) { |
|
|
report_warning("Incorrect usage of Variable.DatabaseChoice:\n\n%s", |
describe_backtrace(backtrace())); |
return ({ " none" }); |
} |
return ({ " none" }) + sort(DBManager.list( config() )); |
} |
|
protected void create(string default_value, void|int flags, |
void|LocaleString std_name, void|LocaleString std_doc) |
{ |
::create( default_value, ({}), flags, std_name, std_doc ); |
} |
} |
|
class AuthMethodChoice |
{ |
inherit StringChoice; |
constant type = "AuthMethodChoice"; |
|
protected Configuration config; |
|
array get_choice_list( ) |
{ |
return ({ " all" }) + sort( config->auth_modules()->name ); |
} |
|
protected void create( string default_value, int flags, |
string std_name, string std_doc, |
Configuration c ) |
{ |
config = c; |
::create( default_value, ({}), flags, std_name, std_doc ); |
} |
} |
|
class UserDBChoice |
{ |
inherit StringChoice; |
constant type = "UserDBChoice"; |
|
protected Configuration config; |
|
array get_choice_list( ) |
{ |
return ({ " all" }) + sort( config->user_databases()->name ); |
} |
|
protected void create( string default_value, int flags, |
string std_name, string std_doc, |
Configuration c ) |
{ |
config = c; |
::create( default_value, ({}), flags, std_name, std_doc ); |
} |
} |
|
|
class ModuleChoice |
{ |
inherit StringChoice; |
constant type = "ModuleChoice"; |
protected Configuration conf; |
protected string|array(string) module_id; |
protected string|array(string) default_id; |
protected int automatic_dependency; |
|
int low_set(array(RoxenModule)|RoxenModule to) |
{ |
array(RoxenModule)|RoxenModule old = changed_values[_id]; |
if (!old) { |
if (module_id) { |
if (multiselect) { |
old = map(module_id, transform_from_form); |
} else { |
old = transform_from_form(module_id); |
} |
} else { |
old = default_value(); |
if (old) { |
module_id = _name(old); |
} |
} |
if (old) { |
changed_values[_id] = old; |
} |
} |
if (equal (to, old)) return 0; |
changed_values[_id] = to; |
if (multiselect) { |
array(string) names = map (to, _name); |
if (equal (module_id, names)) return 0; |
module_id = names; |
} else { |
if (module_id == _name(to)) return 0; |
module_id = _name(to); |
} |
if( get_changed_callback() ) |
get_changed_callback()( this_object() ); |
return 1; |
} |
|
|
int set(string|array(string)|RoxenModule|array(RoxenModule) to) |
{ |
if (multiselect && arrayp(to) && sizeof(to) && stringp(to[0])) { |
module_id = to; |
array(RoxenModule) mods = map(to, transform_from_form); |
if (automatic_dependency) { |
foreach(mods; int i; RoxenModule mod) { |
if (!mod && conf->enabled_modules[to[i]]) { |
conf->add_modules(({to[i]}), 1); |
mod = transform_from_form(to[i]); |
} |
if (!mod && conf->enabled_modules[to[i]]) |
|
|
return 0; |
mods[i] = mod; |
} |
} |
|
|
|
|
to = mods - ({ 0 }); |
} else if (stringp(to)) { |
module_id = to; |
RoxenModule mod = transform_from_form (to); |
if (!mod && automatic_dependency && conf->enabled_modules[to]) { |
conf->add_modules (({to}), 1); |
mod = transform_from_form (to); |
} |
if (!mod && conf->enabled_modules[to]) |
|
|
return 0; |
to = mod; |
} |
return ::set(to); |
} |
|
RoxenModule|array(RoxenModule) query() |
{ |
array(RoxenModule)|RoxenModule res = changed_values[_id]; |
if (!res || (multiselect && has_value(res, 0))) { |
if (module_id) { |
|
|
if (multiselect) { |
res = map(module_id, transform_from_form) - ({ 0 }); |
} else { |
res = transform_from_form(module_id); |
} |
} else { |
res = default_value(); |
} |
if (res) low_set(res); |
} |
return res; |
} |
|
|
protected array low_get_choice_list() |
{ |
return indices(conf->otomod); |
} |
|
array get_choice_list() |
{ |
array res = low_get_choice_list(); |
|
|
|
|
sort(res->module_local_id(), res); |
sort(map(res, _title), res); |
res = reverse(res); |
sort(res->query("_priority"), res); |
res = reverse(res); |
return res; |
} |
|
protected string _name(RoxenModule val) |
{ |
return val?val->module_local_id():""; |
} |
|
protected string _title(RoxenModule val) |
{ |
return val?Roxen.get_modfullname(val):""; |
} |
|
RoxenModule transform_from_form(string module_id, mapping|void v) |
{ |
return conf->find_module(module_id); |
} |
|
RoxenModule|array(RoxenModule) default_value() |
{ |
if (default_id) { |
if (multiselect) return map(default_id, transform_from_form); |
return transform_from_form(default_id); |
} |
array(RoxenModule) modules = get_choice_list(); |
if (sizeof(modules)) { |
return modules[0]; |
} |
return UNDEFINED; |
} |
|
array(string|mixed) verify_set( mixed new_value ) |
{ |
if (!new_value) { |
return ({ "Not configured", 0 }); |
} |
return ({ 0, new_value }); |
} |
|
|
|
|
|
|
|
|
|
|
protected void create(string|array(string) default_id, int flags, |
string std_name, string std_doc, |
Configuration conf, |
void|int no_automatic_dependency) |
{ |
this_program::default_id = default_id; |
this_program::conf = conf; |
automatic_dependency = !no_automatic_dependency; |
::create(0, ({}), flags, std_name, std_doc); |
multiselect = arrayp(default_id); |
} |
} |
|
|
class ProviderChoice |
{ |
inherit ModuleChoice; |
constant type = "ProviderChoice"; |
protected string provides; |
|
protected array low_get_choice_list() |
{ |
return conf->get_providers(provides); |
} |
|
|
|
|
|
|
|
protected void create(string default_id, int flags, |
string std_name, string std_doc, |
string provides, Configuration conf) |
{ |
this_program::provides = provides; |
::create(default_id, flags, std_name, std_doc, conf); |
} |
} |
|
|
|
|
class List |
|
{ |
inherit Variable; |
constant type="List"; |
int width = 60; |
|
array(string|array(string)) verify_set(mixed to) |
{ |
if (stringp(to)) { |
|
return ({ "Compatibility: " |
"Converted from TYPE_STRING to TYPE_STRING_LIST.\n", |
map(to/",", global.String.trim_all_whites), |
}); |
} |
return ::verify_set(to); |
} |
|
string transform_to_form( mixed what ) |
|
|
{ |
return (string)what; |
} |
|
mixed transform_from_form( string what,mapping v ) |
{ |
return what; |
} |
|
protected int _current_count = time()*100+(gethrtime()/10000); |
int(0..1) set_from_form(RequestID id) |
{ |
int rn, do_goto; |
array l = copy_value(query()); |
mapping vl = get_form_vars(id); |
|
if( (int)vl[".count"] != _current_count ) |
return 0; |
_current_count++; |
set_warning(0); |
|
foreach( indices( vl ), string vv ) |
if( sscanf( vv, ".set.%d", rn ) && (vv == ".set."+rn) ) |
{ |
if ((rn >= 0) && (rn < sizeof(l))) { |
m_delete( id->real_variables, path()+vv ); |
l[rn] = transform_from_form( vl[vv], vl ); |
m_delete( vl, vv ); |
} else { |
report_debug("set_from_form(%O): vv:%O sizeof(l):%d\n", |
id, vv, sizeof(l)); |
} |
} |
|
foreach( indices(vl), string vv ) |
if( sscanf( vv, ".up.%d.x%*s", rn ) == 2 ) |
{ |
do_goto = 1; |
m_delete( id->real_variables, path()+vv ); |
m_delete( vl, vv ); |
l = l[..rn-2] + l[rn..rn] + l[rn-1..rn-1] + l[rn+1..]; |
} |
else if( sscanf( vv, ".down.%d.x%*s", rn )==2 ) |
{ |
do_goto = 1; |
m_delete( id->real_variables, path()+vv ); |
l = l[..rn-1] + l[rn+1..rn+1] + l[rn..rn] + l[rn+2..]; |
} |
|
if( vl[".new.x"] ) |
{ |
do_goto = 1; |
m_delete( id->real_variables, path()+".new.x" ); |
l += ({ transform_from_form( "",vl ) }); |
} |
|
|
foreach( indices(vl), string vv ) |
if( sscanf( vv, ".delete.%d.x%*s", rn )==2 ) |
{ |
do_goto = 1; |
m_delete( id->real_variables, path()+vv ); |
l = l[..rn-1] + l[rn+1..]; |
} |
|
array b; |
mixed q = catch( b = verify_set_from_form( l ) ); |
if( q || sizeof( b ) != 2 ) |
{ |
if( q ) |
add_warning( q ); |
else |
add_warning( "Internal error: Illegal sized array " |
"from verify_set_from_form\n" ); |
return 0; |
} |
|
int ret; |
if( b ) |
{ |
add_warning( b[0] ); |
set( b[1] ); |
ret = 1; |
} |
|
if( do_goto && !id->misc->do_not_goto ) |
{ |
RequestID nid = id; |
while( nid->misc->orig ) |
nid = id->misc->orig; |
|
string section = RXML.get_var("section", "var"); |
string query = nid->query; |
if( !query ) |
query = ""; |
else |
query += "&"; |
|
|
|
|
query += |
(section ? ("section=" + section + "&") : "") + |
"random=" + random(4949494); |
query += "&_roxen_wizard_id=" + id->cookies["RoxenWizardId"]; |
|
string url = |
Roxen.http_encode_invalids (nid->not_query + |
(nid->misc->path_info || "") + |
"?" + query + "#" + path()); |
|
nid->set_response_header ("Location", url); |
if( nid->misc->defines ) |
nid->misc->defines[ " _error" ] = 302; |
else if( id->misc->defines ) |
id->misc->defines[ " _error" ] = 302; |
} |
|
return ret; |
} |
|
|
string render_row(string prefix, mixed val, int width) |
{ |
return input( prefix, val, width ); |
} |
|
string render_form( RequestID id, void|mapping additional_args ) |
{ |
string prefix = path()+"."; |
int i; |
|
string res = "<a name='"+path()+"'>\n</a><table class='auto rxn-var-list'>\n" |
"<input type='hidden' name='"+prefix+"count' value='"+_current_count+"' />\n"; |
|
foreach( map(query(), transform_to_form), mixed val ) |
{ |
res += "<tr>\n<td><span class='small'>"+ render_row(prefix+"set."+i, val, width) |
+ "</span></td>\n"; |
#define BUTTON(X,Y) ("<submit-gbutton2 name='"+X+"'>"+Y+"</submit-gbutton2>") |
#define REORDER(X,Y) ("<submit-gbutton2 name='"+X+"' icon-src='"+Y+"'></submit-gbutton2>") |
#define DIMBUTTON(X) ("<disabled-gbutton icon-src='"+X+"'></disabled-gbutton>") |
if( i ) |
res += "\n<td class='rxn-btn-td'>"+ |
REORDER(prefix+"up."+i, "/internal-roxen-up")+ |
"</td>"; |
else |
res += "\n<td class='rxn-btn-td'>"+DIMBUTTON("/internal-roxen-up")+"</td>"; |
if( i != sizeof( query())- 1 ) |
res += "\n<td class='rxn-btn-td'>"+ |
REORDER(prefix+"down."+i, "/internal-roxen-down") |
+"</td>"; |
else |
res += "\n<td class='rxn-btn-td'>"+DIMBUTTON("/internal-roxen-down")+"</td>"; |
res += "\n<td class='rxn-btn-td'>"+ |
BUTTON(prefix+"delete."+i, LOCALE(227, "Delete") ) |
+"</td>"; |
"</tr>"; |
i++; |
} |
res += |
"\n<tr><td colspan='4' class='rxn-new-row'>"+ |
BUTTON(prefix+"new", LOCALE(297, "New row") )+ |
"</td></tr></table>\n\n"; |
|
return res; |
} |
} |
|
|
|
|
|
class DirectoryList |
|
{ |
inherit List; |
constant type="DirectoryList"; |
|
array verify_set( array(string) value ) |
{ |
string warn = ""; |
foreach( value, string vi ) |
{ |
if(!strlen(vi)) |
continue; |
if( !(r_file_stat( vi ) && (r_file_stat( vi )[ ST_SIZE ] == -2 ))) |
warn += sprintf(LOCALE(331,"%s is not a directory"),vi)+"\n"; |
if( strlen(vi) && vi[-1] != '/' ) |
value = replace( value, vi, vi+"/" ); |
} |
#ifdef __NT__ |
value = map( value, replace, "\\", "/" ); |
#endif |
if( strlen( warn ) ) |
return ({ warn, value }); |
|
return ::verify_set( value ); |
} |
} |
|
class StringList |
|
{ |
inherit List; |
constant type="StringList"; |
} |
|
class IntList |
|
{ |
inherit List; |
constant type="IntList"; |
int width=20; |
|
string transform_to_form(int what) { return (string)what; } |
int transform_from_form(string what,mapping v) { return (int)what; } |
} |
|
class FloatList |
|
{ |
inherit List; |
constant type="FloatList"; |
int width=20; |
|
protected int _prec = 3; |
|
void set_precision( int prec ) |
|
|
|
{ |
_prec = prec; |
} |
|
string transform_to_form(int what) |
{ |
return sprintf("%1."+_prec+"f", what); |
} |
float transform_from_form(string what,mapping v) { return (float)what; } |
} |
|
class URLList |
|
{ |
inherit List; |
constant type="URLList"; |
|
array verify_set_from_form( array(string) new_value ) |
{ |
string warn = ""; |
array res = ({}); |
foreach( new_value, string vv ) |
{ |
string tmp1, tmp2; |
[tmp1,tmp2] = verify_port( vv ); |
if( tmp1 ) |
warn += tmp1; |
res += ({ tmp2 }); |
} |
if( !strlen( warn ) ) |
warn = 0; |
return ({ warn, res }); |
} |
} |
|
class PortList |
|
{ |
inherit List; |
constant type="PortList"; |
|
string render_row( string prefix, mixed val, int width ) |
{ |
string res = "<input type=hidden name='"+prefix+"' value='"+prefix+"' />"; |
|
Standards.URI split = Standards.URI( val ); |
|
res += "<div class='rxn-port'><div class='port-url'><select name='"+prefix+"prot'>"; |
int default_port; |
foreach( sort(indices( roxenp()->protocols )), string p ) |
{ |
if( p == split->scheme ) { |
res += "<option selected='t'>"+p+"</option>"; |
default_port = roxenp()->protocols[p]->default_port; |
} |
else |
res += "<option>"+p+"</option>"; |
} |
res += "</select>"; |
|
res += "://<input type=text name='"+prefix+"host' value='"+ |
Roxen.html_encode_string(split->host)+"' />"; |
res += ":<input type=text size=5 name='"+prefix+"port' value='"+ |
(split->port == default_port ? "" : split->port) +"' />"; |
|
res += "/<input type=text name='"+prefix+"path' value='"+ |
Roxen.html_encode_string(split->path[1..])+"' /></div>"; |
mapping opts = ([]); |
string a,b; |
foreach( (split->fragment||"")/";", string x ) |
{ |
sscanf( x, "%s=%s", a, b ); |
opts[a]=b; |
} |
res += "<div class='port-ip'>IP#: <input size=15 type=text name='"+prefix+"ip' value='"+ |
Roxen.html_encode_string(opts->ip||"")+"' /> "; |
res += LOCALE(510,"Bind this port: "); |
res += "<select name='"+prefix+"nobind'>"; |
if( (int)opts->nobind ) |
{ |
res += |
("<option value='0'>"+LOCALE("yes","Yes")+"</option>" |
"<option selected='t' value='1'>"+LOCALE("no","No")+"</option>"); |
} |
else |
{ |
res += |
("<option selected='t' value='0'>"+LOCALE("yes","Yes")+"</option>" |
"<option value='1'>"+LOCALE("no","No")+"</option>"); |
} |
res += "</select></div></div>"; |
return res; |
} |
|
string transform_from_form( string v, mapping va ) |
{ |
if( v == "" ) return "http://*/"; |
v = v[strlen(path())..]; |
if( strlen( va[v+"path"] ) && va[v+"path"][-1] != '/' ) |
va[v+"path"]+="/"; |
|
|
string host = va[v + "host"]; |
if (has_value(host, ":") && !has_prefix(host, "[")) |
host = "[" + host + "]"; |
|
return (string)Standards.URI(va[v+"prot"]+"://"+ host + |
(va[v+"port"] && sizeof (va[v+"port"]) ? |
":"+ va[v+"port"] : "") +"/"+va[v+"path"]+"#" |
|
"ip="+va[v+"ip"]+";" |
"nobind="+va[v+"nobind"]+";" |
); |
} |
|
array verify_set_from_form( array(string) new_value ) |
{ |
string warn = ""; |
array res = ({}); |
foreach( new_value, string vv ) |
{ |
string tmp1, tmp2; |
[tmp1,tmp2] = verify_port( vv ); |
if( tmp1 ) |
warn += tmp1; |
res += ({ tmp2 }); |
} |
if( !strlen( warn ) ) |
warn = ""; |
return ({ warn, res }); |
} |
} |
|
|
class FileList |
|
{ |
inherit List; |
constant type="FileList"; |
|
#ifdef __NT__ |
array(string|array(string)) verify_set(mixed value ) |
{ |
|
if (stringp(value)) |
return ::verify_set( replace(value, "\\", "/") ); |
|
return ::verify_set( map( value, replace, "\\", "/" ) ); |
} |
#endif |
} |
|
|
|
|
|
|
class Flag |
|
{ |
inherit Variable; |
constant type = "Flag"; |
|
int transform_from_form( string what ) |
{ |
return (int)what; |
} |
|
string render_form( RequestID id, void|mapping additional_args ) |
{ |
string res = "<select name=\""+path()+"\"> "; |
if(query()) |
res += "<option value=\"1\" selected=\"selected\">" + |
LOCALE("yes", "Yes")+ "</option>\n" |
"<option value=\"0\">" +LOCALE("no", "No")+ "</option>\n"; |
else |
res += "<option value=\"1\">" +LOCALE("yes", "Yes")+ "</option>\n" |
"<option value=\"0\" selected>" +LOCALE("no", "No")+ "</option>\n"; |
return res+"</select>"; |
} |
} |
|
|
|
|
|
|
|
protected array(string) verify_port( string port ) |
{ |
if(!strlen(port)) |
return ({ 0, port }); |
|
string warning=""; |
if( (int)port ) |
{ |
warning += sprintf(LOCALE(333,"Assuming http://*:%[0]d/ for %[0]d")+"\n", |
(int)port); |
port = "http://*:"+port+"/"; |
} |
string protocol, host, path; |
|
if(!strlen( port ) ) |
return ({ LOCALE(334,"Empty URL field")+"\n", port }); |
|
if(sscanf( port, "%[^:]://%[^/]%s", protocol, host, path ) != 3) |
return ({ sprintf(LOCALE(335,"%s does not conform to URL syntax")+"\n",port), |
port }); |
|
|
|
|
|
|
if( protocol != lower_case( protocol ) ) |
{ |
warning += sprintf(LOCALE(338,"Changed %s to %s"), |
protocol, lower_case( protocol ))+"\n"; |
protocol = lower_case( protocol ); |
} |
#if constant(SSL.File) |
|
#else |
if( (protocol == "https" || protocol == "ftps") ) |
warning += |
LOCALE(339,"SSL support not available in this Pike version.")+"\n"+ |
sprintf(LOCALE(340,"Please use %s instead."), |
protocol[..strlen(protocol)-2])+"\n"; |
#endif |
int pno; |
int default_pno = |
(roxenp()->protocols[lower_case(protocol)] || ([ ]) )->default_port; |
if (has_value(host, "[")) { |
|
Standards.URI uri = Standards.URI(port); |
pno = uri->port; |
port = (string) uri; |
} else { |
if (sscanf(host, "%s:%d", host, pno) == 2) |
if (pno != default_pno) |
host = host + ":" + pno; |
port = protocol+"://"+host+path; |
} |
if (default_pno && (pno == default_pno)) |
warning += sprintf(LOCALE(341, "Removed the default port number " |
"(%d) from %s"), pno, port) + "\n"; |
|
if( !roxenp()->protocols[ protocol ] ) |
warning += sprintf(LOCALE(342,"Warning: The protocol %s is not known " |
"by roxen"),protocol)+"\n"; |
return ({ (strlen(warning)?warning:0), port }); |
} |
|
string input(string name, string value, int size, |
void|mapping(string:string) args, void|int noxml) |
{ |
if(!args) |
args=([]); |
else |
args+=([]); |
|
args->name=name; |
if(value) |
args->value = Roxen.html_encode_string(value); |
if(!args->size && size) |
args->size=(string)size; |
|
string render="<input"; |
|
foreach(indices(args), string attr) { |
render+=" "+attr+"="; |
if(!has_value(args[attr], "\"")) render+="\""+args[attr]+"\""; |
else if(!has_value(args[attr], "'")) render+="'"+args[attr]+"'"; |
else render+="'"+replace(args[attr], "'", "'")+"'"; |
} |
|
|
|
if(noxml) return render+">"; |
return render+" />"; |
} |
|
|