pid ] = ist ( $root -> actv ) ; } } return ( $USER and $EDS [ $USER ] ) ; } function isroot () { global $USER, $EDS ; $sink = is_adm () ; return ( $USER and array_key_exists ( $USER, $EDS ) ) ; } function assert_isroot () { global $USER ; if ( ! isroot () ) { html_exit ( "you aren't an admin ($USER)" ) ; } } function switch_url () { $adm = is_adm () ? 'OFF' : 'ON' ; $txt = ITA ( is_adm () ? 'inactive' : 'active' ) ; $uri = $_SERVER [ "REQUEST_URI" ] ; $uri .= ( preg_match ( '/\?/', $uri ) ? '&' : '?' ) . "ADM=$adm" ; return URL ( $uri, $txt ) ; } function login_url () { $uri = $_SERVER [ 'REQUEST_URI' ] ; if ( ! preg_match ( '/login=1/', $uri ) ) { $uri .= ( preg_match ( '/\?/', $uri ) ? '&' : '?' ) . 'login=1' ; } # echo $uri ; if ( preg_match ( '/[\'"]/', urldecode ( $uri ) ) ) { $uri = "/?login=1" ; } return URL ( $uri, 'login' ) ; } function logout_url () { return URL ( "index.php?logout=1", 'logout' ) ; } $GETVAR_pats = array ( 'MAIL' => '/^[^;\'"]*$/' , 'UID' => '/^[0-9]+$/' , 'RID' => '/^[0-9]+$/' , 'XID' => '/^[0-9]+$/' , 'ID' => '/^[0-9]*$/' , 'PID' => '/^[0-9]+$/' , 'AUSR' => '/^([-@.\w]+)?$/i' , 'AMOD' => '/^ro|rw|nx$/' , 'ADM' => '/^(OFF|ON)?$/' , 'PATH' => '/^(\w+(\/\w+)*)?$/' , 'APTH' => '/^(\w+(\/\w+)*\/?)?$/' , 'PUBL' => '/^[tf]$/' , 'UPBL' => '/^[tf]$/' , 'RIDS' => '/^(\d+(,\d+)*)?$/' ) ; function GETVAR ( $var ) { global $GETVAR_pats ; $res = trim ( $_GET [ $var ] ) or $res = trim ( $_POST [ $var ] ) ; $txt = htmlentities ( $res ) ; if ( func_num_args() == 2 ) { $pat = func_get_arg ( 1 ) ; if ( $res and ! preg_match ( $pat, $res ) ) { html_exit ( "$var ($txt) != '$pat'" ) ; } } elseif ( $GETVAR_pats [ $var ] ) { $pat = $GETVAR_pats [ $var ] ; if ( ! preg_match ( $pat, $res ) ) { html_exit ( "$var ($txt) != '$pat'" ) ; } } return $res ; } function CHKVAR ( $name ) # or CHKVAR ( $name, $idx ) { return ( ( ! array_key_exists ( $name, $_POST ) or ( ( func_num_args() == 2 ) and ( ! array_key_exists ( func_get_arg ( 1 ), $_POST [ $name ] ) ) ) ) ? 'f' : 't' ) ; } function REPO_TIT ( $txt ) { global $DEV_TIT ; $www = Conf ( 'www_server' ) ; return "repocafe self-service $www$DEV_TIT - $txt" ; } function G_CLASS () { return 'guests' ; } function G_PREFIX () { return 'g_' ; } function STAR () { return BLD ( SPN ( '*', 'red' ) ) . ' ' ; } function ist ( $b ) { return ( is_bool ( $b ) ? $b : $b == 't' ) ; } function repr_bool ( $b ) { return ist ( $b ) ? 'yes' : 'no' ; } function dmp ( $m ) { echo sprintf ( "%s
\n", htmlspecialchars ( $m ) ) ; } function EPS () { return '' ; } function alpha_date ( $date ) { $time = time () ; if ( $date ) { list ( $y, $m, $d ) = explode ( '-', $date ) ; $time = mktime ( 12, 12, 12, $m, $d, $y ) ; } return date ( 'd F Y', $time ) ; } function KMGB ( $s ) { if ( ! $s ) { return 'unknown' ; } $x = $s -> size ; if ( $x > 1024 * 1024 ) { $res = sprintf ( "%.1f GB", $x / 1024 / 1024 ) ; } elseif ( $x > 1024 ) { $res = sprintf ( "%.1f MB", $x / 1024 ) ; } else { $res = sprintf ( "%d KB", $x ) ; } $date = date ( 'r', $s -> time ) ; return "± $res on $date" ; } function checkbox ( $name, $val ) { $chk = ist ( $val ) ? 'CHECKED' : '' ; return "" ; } function form_row ( $opt, $th, $td ) { $S = STAR () ; if ( func_num_args() == 4 ) { $spn = func_get_arg ( 3 ) ; $colspan = "COLSPAN=$spn" ; } return TR ( THA ( "ALIGN=RIGHT", ( $opt == 'req' ? $S : '' ) . $th ) . TDA ( "$colspan CLASS=$opt", $td ) ) ; } function repo_guests_url () { return URL ( "users.php", G_CLASS () ) ; } function new_repo_guest_url () { return URL ( "users.php?ACT=NEW_USER_FORM", 'create a new guest' ) ; } function conf_url () { return URL ( "access.php", 'access' ) ; } function about_url () { return URL ( "about.php", 'documentation' ) ; } function stats_url () { return URL ( "stats.php", 'stats' ) ; } function prefs_url () { $txt = 'preferences' ; return URL ( "prefs.php?ACT=UPD_PREF_FORM", $txt ) ; } function is_guest () { global $CLAS ; return $CLAS == G_CLASS () ; } function is_login_name ( $name ) { $res = '' ; if ( is_a_group_name ( $name ) ) { ; } else { $user = new User ; $user -> init ( $name ) ; if ( $user -> find () ) { $res = $user -> clas ; } } return $res ; } function is_a_group_name ( $name ) { return substr ( $name, 0, 1 ) == '@' ; } function is_group_name ( $name ) { $res = '' ; if ( is_a_group_name ( $name ) ) { $res = try_repo_group_by_name ( $name ) ; } return $res ; } function name_login ( $login, $sep = ' - ' ) { $res = "$login" ; if ( ! is_a_group_name ( $login ) ) { if ( $name = full_name ( $login ) ) { $res = "$name$sep$res" ; } else { $res = BLD ( SPN ( $res, 'red' ) ) ; } } return $res ; } function gen_conf_repo ( $repo, $group4name ) { $res = '' ; $subs = $repo -> subs ; foreach ( $subs as $sub ) { $side = $sub -> side ; $ownr = $sub -> ownr ; $name = $sub -> repo_name () ; $path = $sub -> path ; $res .= "\n[$name:/$path]\n" ; $ros = array () ; $rws = array () ; $nxs = array () ; foreach ( $sub -> rights as $rr ) { $mod = $rr -> mod ; $pid = $rr -> pid ; if ( $group4name !== NULL ) { if ( is_a_group_name ( $pid ) and ! $group4name [ $pid ] ) { $res .= "# group not found ($pid=$mod)\n" ; } } if ( $mod == 'ro' ) { $ros [ $pid ] ++ ; } elseif ( $mod == 'rw' ) { $rws [ $pid ] ++ ; } elseif ( $mod == 'nx' ) { $nxs [ $pid ] ++ ; } # $res .= "# $pid -> $mod\n" ; } $k_ros = array_keys ( $ros ) ; sort ( $k_ros ) ; $k_rws = array_keys ( $rws ) ; sort ( $k_rws ) ; $k_nxs = array_keys ( $nxs ) ; sort ( $k_nxs ) ; if ( ! $sub -> rights ) { $tag = $sub -> tag () ; $res .= "# gen_conf: no rights for ($tag)\n" ; } if ( count ( $k_rws ) ) { foreach ( $k_rws as $pid ) { $res .= "$pid = rw\n" ; } } if ( $sub -> is_public () ) { $res .= "# anonymous read allowed\n" . "* = r\n" ; } elseif ( count ( $k_ros ) ) { foreach ( $k_ros as $pid ) { $res .= "$pid = r\n" ; } } if ( ! $sub -> is_public () ) { $res .= "# anonymous read not allowed\n" . "* =\n" ; } elseif ( count ( $k_nxs ) ) { foreach ( $k_nxs as $pid ) { $res .= "$pid =\n" ; } } } return $res ; } function gen_conf ( $repos, $groups ) { $res = '' ; $group4name = array () ; if ( count ( $groups ) ) { $res .= "[groups]\n" ; foreach ( $groups as $group ) { $name = $group -> name ; $group4name [ $name ] = $group ; $mems = array () ; foreach ( $group -> mems as $mem ) { if ( ist ( $mem -> mem ) ) { $mems [ $mem -> pid ] ++ ; } } ksort ( $mems ) ; $res .= sprintf ( "%s = %s\n" , substr ( $name, 1 ) , implode ( ",", array_keys ( $mems ) ) ) ; } } if ( count ( $repos ) ) { $res .= "\n[/]\n" . "# default : no access\n" . "* =\n" ; foreach ( $repos as $repo ) { $res .= gen_conf_repo ( $repo, $group4name ) ; } } return $res ; } ################################################################ function make_guest_list () { $prog = MK_GUEST_LIST () ; $file = GUEST_LIST () ; $ADMIN = DIR_ADMIN () ; $perl = Conf ( 'cmd_perl' ) ; $line = system ( "cd $ADMIN ; $perl $prog $file", $err ) ; if ( $err ) { $res = "cd $ADMIN ; /usr/bin/perl $prog $file : FAIL ($line ($err))" ; html_exit ( $res ) ; } } function make_svnaccess_file ( $res = 0 ) { $repos = get_repos ( '', '', 'side,ownr,name' ) ; $groups = get_repo_groups ( '', '', '' ) ; $conf = gen_conf ( $repos, $groups ) ; $file = SVN_ACC_FILE () ; $temp = "$file.tmp" ; $err = file_put_contents ( $temp, $conf ) ; if ( $err === FALSE ) { html_exit ( "FAIL : file_put_contents $temp" ) ; } elseif ( ! rename ( $temp, $file ) ) { html_exit ( "FAIL : rename $temp $file" ) ; } return $res ? $conf : '' ; } function get_repo_guest ( $id ) { $res = new Repo_guest ; $res -> db_get_id ( $id ) || html_exit ( "can't get repo_guest ($id)" ) ; return $res ; } function get_repo_guests ( $from, $sql, $order ) { $res = new Repo_guest ; return $res -> db_get_all ( $from, $sql, $order ) ; } function try_repo_guest_by_login ( $login ) { $res = get_repo_guests ( '', "login = '$login'", 'login' ) ; if ( count ( $res ) == 1 ) { return $res [ 0 ] ; } else { return '' ; } } function get_repo_guest_by_login ( $login ) { if ( $user = try_repo_guest_by_login ( $login ) ) { return $user ; } else { html_exit ( "no repo_guest with login ($login)" ) ; } } function repo_guests_info_head () { $may = is_adm () ; return TR ( ( may_create_guest () ? TH ( 'act' ) : '' ) . TH ( 'login' ) . TH ( 'name' ) . ( $may ? TH ( 'email' ) . TH ( 'created' ) . TH ( 'by' ) : '' ) ) ; } class Repo_table extends Table { function table_init ( $name, $id ) { parent::table_init ( Conf ( 'db_pref' ) . $name, $id ) ; } function _init_object ( $tup, $flds ) { foreach ( $flds as $attr => $key ) { $this -> $attr = $tup -> $key ; } return $this ; } static function init_objects ( $typ, $tups, $map ) { $new = new $typ ; $flds = $new -> all_fields () ; foreach ( $flds as $key => $descr ) { $flds [ $key ] = $key ; } foreach ( $map as $attr => $key ) { $flds [ $attr ] = $key ; } $patt = $new -> _pkey ; $pkey = $flds [ $patt ] ; $res = array () ; $idx = array () ; $cnt = 0 ; $res = array () ; foreach ( $tups as $tup ) { if ( ! $idx [ $tup -> $pkey ] ) { $new = new $typ ; $new -> _init_object ( $tup, $flds ) ; # echo ++ $cnt ; echo " patt ($patt) pkey ($pkey)
\n" ; # var_dump ( $new ) ; echo "
\n" ; $idx [ $new -> $patt ] = $new ; $res [] = $new ; } } return $res ; } static function init_object ( $typ, $tups, $map ) { $repos = self::init_objects ( $typ, $tups, $map ) ; return array_shift ( $repos ) ; } } function may_create_guest () { global $CLAS ; return ( is_adm () or array_key_exists ( $CLAS, Conf ( 'creag' ) ) ) ; } class Repo_guest extends Repo_table { static $fields_bool = array () ; function inst () { return new Repo_guest ; } function Repo_guest () { $this -> table_init ( 'repo_guests', 'id' ) ; } function next_val () { return parent::_next_val () ; } function class_name () { return "guest" ; } function tag () { return sprintf ( '%s (%s)', $this -> login, $this -> name ) ; } function fields () { return array ( 'login' => 'user name' , 'name' => 'full name' , 'email' => 'email address' , 'parent' => 'created by' , 'passwd' => 'password' , 'nwmail' => 'new mail address' , 'nwcode' => 'update code' ) ; } function reget () { $login = $this -> login ; if ( $this -> id ) { $res = get_repo_guest ( $this -> id ) ; } else { html_exit ( "can't reget repo_guest ($login) : no id" ) ; } return $res ; } function get_repos ( $order ) { $pid = $this -> login ; $Repos = TBL ( 'repos' ) ; $Rights = TBL ( 'rights' ) ; $sub = "SELECT rid FROM $Rights WHERE pid = '$pid'" ; $qwe = "$Repos.id in ( $sub )" ; return get_repos ( '' , $qwe , $order ) ; } function get_repo_groups ( $order ) { $pid = $this -> login ; $tab_mems = TBL ( 'repo_group_members' ) ; $sub = "SELECT gid FROM $tab_mems WHERE pid = '$pid'" ; $qwe = "gid in ( $sub )" ; return get_repo_groups ( '' , $qwe , $order ) ; } function may_update () { global $USER ; return ( is_adm () or $this -> parent == $USER ) ; } function assert_may_update () { if ( ! $this -> may_update () ) { html_exit ( "you may not update this guest '{$this->name}'" ) ; } } function upd_url ( $txt ) { return URL ( "users.php?ACT=UPD_USER_FORM&UID={$this->id}", $txt) ; } function del_url () { $txt = SPN ( 'delete this guest', 'red' ) ; return URL ( "users.php?ACT=DEL&UID={$this->id}", $txt ) ; } function mail_pwd_url ( $txt ) { return URL ( "users.php?ACT=MAIL&UID={$this->id}", $txt ) ; } function repr ( $fld ) { $res = $this -> $fld ; if ( self::$fields_bool [ $fld ] ) { $res = repr_bool ( $res ) ; } return $res ; } function info_row () { return TR ( ( may_create_guest () ? TD ( $this -> may_update () ? $this -> upd_url ( 'upd' ) : '' ) : '' ) . TD ( $this -> login ) . TD ( $this -> name ) . ( is_adm () ? TD ( $this -> email ) . TD ( $this -> creat ) . TD ( $this -> parent ) : '' ) ) ; } function gen_rand ( $n ) { # abc = [a-zA-Z0-9] - [giloqIOQ019] ; to avo1d typos $abc = 'abcdefhjkmnprstuvwxyzABCDEFGHJKLMNPRSTUVWXYZ2345678' ; $res = '' ; for ( $i = 0 ; $i < $n ; $i ++ ) { $r = rand ( 0, strlen ( $abc ) - 1 ) ; $res .= substr ( $abc, $r, 1 ) ; } ; return $res ; } function set_pw () { $pswd = $this -> gen_rand ( 8 ) ; $salt = $this -> gen_rand ( 2 ) ; $this -> passwd = crypt ( $pswd, $salt ) ; $this -> update_pw () ; return $pswd ; } function set_defaults () { global $USER ; $this -> login = '' ; $this -> passwd = 'eeeeeeeeeeeee' ; $this -> name = '' ; $this -> email = '' ; $this -> parent = $USER ; $this -> nwmail = '' ; $this -> nwcode = '' ; } # for "guest create" and "guest password reset" function send_mail ( $doit ) { global $USER ; $conf = Conf () ; $serv = $conf -> www_server ; $schm = $conf -> www_scheme ; $from = $conf -> mail_from_admin ; $to = $this -> email ; $name = $this -> name ; $login = $this -> login ; $pswd = $this -> set_pw () ; $uname = $USER ? full_name ( $USER ) : '' ; $head = "From: $from\n" ; $txt = << TXT; if ( ! $doit ) { $head .= "X-to: $to\n" ; $to = 'henkp@cs.uu.nl' ; } if ( mail ( $to, "$serv registration", $txt, $head ) ) { $res = "sent passwd to $to" ; } else { $res = "failed: mail to $to" ; } return $res ; } function gen_form_guest ( $act ) { $login = $this -> login ; $passwd = $this -> passwd ; $name = $this -> name ; $email = $this -> email ; $PREF = G_PREFIX () ; if ( $login == '' ) { $login = $PREF ; } $fields = $this -> fields () ; $R = STAR () ; $login_txt = <<{$fields['login']} starts with $PREF LOGIN; if ( $this -> id ) { $login_txt = '' ; } $res = <<
$login_txt
$R {$fields['name']}
$R {$fields['email']}

FORM; return $res ; } function get_form () { $res = '' ; $_id = trim ( $_POST [ 'ID' ] ) ; $_login = trim ( $_POST [ 'LOGIN' ] ) ; $_name = trim ( $_POST [ 'NAME' ] ) ; $_email = trim ( $_POST [ 'EMAIL' ] ) ; if ( $this -> id ) { $_id = $this -> id ; $_login = $this -> login ; } else { # we may use 'name' as a base for the login-name if ( $_login == G_PREFIX () ) { $_login = G_PREFIX () . $_name ; } $_login = strtolower ( $_login ) ; $_login = preg_replace ( '/\s/', '', $_login ) ; } $this -> id = $_id ; $this -> login = $_login ; $this -> name = $_name ; $this -> email = $_email ; $PREF = G_PREFIX () ; if ( ! may_create_guest () ) { $err .= "you may not create guests" ; } if ( ! preg_match ( "/^[a-z]\w+$/", $_login ) ) { $res .= LI ( "bad characters in user-name ($_login)" ) ; } if ( ! preg_match ( "/^\w[-\w\s.,()]+$/", $_name ) ) { $res .= LI ( "bad characters in full name ($_name)" ) ; } if ( ! preg_match ( "/^\w[-\w.@]+$/", $_email ) ) { $res .= LI ( "bad characters in email ($_email)" ) ; } if ( substr ( $_login, 2 ) == '' ) { $res .= LI ( "user-name must not be empty" ) ; } if ( $_name == '' ) { $res .= LI ( "full name must not be empty" ) ; } if ( $_email == '' ) { $res .= LI ( "email must not be empty" ) ; } if ( ! preg_match ( "/^$PREF/", $_login ) ) { $res .= LI ( "login doesn't begin with '$PREF' ($_login)" ) ; } if ( ! $_id and try_repo_guest_by_login ( $_login ) ) { $res .= LI ( "login already exists ($_login)" ) ; } return ( $res ? UL ( $res ) : '' ) ; } function gen_form_prefs ( $act ) { $res = <<
current password
new password
... again

FORM; return $res ; } function get_form_prefs () { $res = '' ; $passwd = trim ( $_POST [ 'OLDPWD' ] ) ; $newpw1 = trim ( $_POST [ 'NEWPW1' ] ) ; $newpw2 = trim ( $_POST [ 'NEWPW2' ] ) ; if ( $passwd == '' ) { $res .= LI ( "password must not be empty" ) ; } else { $salt = $this -> passwd ; if ( crypt ( $passwd, $salt ) != $this -> passwd ) { $res .= LI ( "incorrect old password" ) ; } } if ( $newpw1 == '' ) { $res .= LI ( "new password must not be empty" ) ; } elseif ( $newpw1 != $newpw2 ) { $res .= LI ( "new passwords not equal" ) ; } if ( ! $res ) { $this -> passwd = crypt ( $newpw1, $this -> gen_rand ( 2 ) ) ; } return ( $res ? UL ( $res ) : '' ) ; } function insert () { $this -> id = $this -> next_val () ; $flds = $this -> fields () ; $flds [ 'id' ] = 'id' ; $res = parent::insert ( $flds ) ; make_guest_list () ; return $res ; } function update () { $res = parent::update () ; make_guest_list () ; return ULmk ( $res ? $res : 'no change' ) ; } function update_pw () { $res = parent::update ( array ( 'passwd' => 'password' ) ) ; if ( $res ) { make_guest_list () ; } return ULmk ( $res ? 'changed password' : 'no change' ) ; } function delete () { $pid = $this -> login ; $lis = '' ; # delete in repo_rights $repos = $this -> get_repos ( 'side,name' ) ; foreach ( $repos as $idx => $repo ) { if ( $rr = $repo -> rights [ $pid ] ) { $name = $repo -> repo_name () ; $lis .= LI ( $name . ' : ' . UL ( $rr -> delete () ) ) ; } } # delete in repo_group_members $groups = $this -> get_repo_groups ( 'name' ) ; foreach ( $groups as $group ) { if ( $mem = $group -> mems [ $pid ] ) { $name = $group -> name ; $lis .= LI ( $name . ' : ' . UL ( $mem -> delete () ) ) ; } } # delete in repo_guests $qwe = sprintf ( 'DELETE FROM %s WHERE id = %s' , $this -> _tab , '$1' ) ; $tab = array ( $this -> id ) ; db_query_params ( $qwe, $tab ) ; make_guest_list () ; $lis .= LI ( "deleted : $pid ({$this->name})" ) ; return UL ( $lis ) ; } } ################################################################ function try_repo ( $id ) { $Repos = TBL ( 'repos' ) ; $res = get_repos ( '', "$Repos.id = '$id'", "$Repos.id" ) ; # $cnt = count ( $res ) ; print "cnt ($cnt)
\n" ; # var_dump ( $res [ 0 ] ) ; return ( count ( $res ) == 1 ? $res [ 0 ] : '' ) ; } function get_repo ( $id ) { $res = try_repo ( $id ) ; if ( ! $res ) { html_exit ( "can't get repo ($id)" ) ; } return $res ; } function try_repo_by_son ( $side, $ownr, $name ) { $qwe = "side = '$side' and ownr = '$ownr' and name = '$name' " ; $res = get_repos ( '', $qwe, 'id' ) ; if ( count ( $res ) == 1 ) { return $res [ 0 ] ; } else { return '' ; } } function get_repos ( $from, $sql, $order ) { $Repos = TBL ( 'repos' ) ; $Paths = TBL ( 'paths' ) ; $Rights = TBL ( 'rights' ) ; if ( $order ) { $list = array () ; foreach ( explode ( ',', $order ) as $fld ) { $list [] = ( strstr ( $fld, '.' ) ? '' : "$Repos." ) . $fld ; } $order = implode ( ',', $list ) ; } $WHERE = $sql ? "WHERE $sql" : '' ; $ORDER = $order ? "ORDER BY $order" : '' ; $qwe = << 'repos_id' ) ) ; $paths = Repo_table::init_objects ( 'Repo_paths', $tups, array ( 'id' => 'paths_id' , 'rid' => 'repos_id' ) ) ; $repo_idx = array () ; foreach ( $repos as $repo ) { $repo_idx [ $repo -> id ] = $repo ; } $path_idx = array () ; # echo count ( $paths ) ; echo " #paths
\n" ; foreach ( $paths as $Path ) { $Path_id = $Path -> id ; $path_idx [ $Path_id ] = $Path ; $path = $Path -> path ; $repo_id = $Path -> rid ; $Repo = $repo_idx [ $repo_id ] ; $Repo -> paths [ $path ] = $Path ; $Repo -> prrs [ $path ] = array () ; $Repo -> pids [ $Path_id ] = $Path ; $Path -> rrs = array () ; # var_dump ( $Path ) ; echo "
\n" ; } # echo "end paths
\n" ; $rights = Repo_table::init_objects ( 'Repo_rights', $tups, array ( 'id' => 'rights_id' ) ) ; # echo count ( $rights ) ; echo " #rights
\n" ; foreach ( $rights as $rid => $rr ) { $Path = $path_idx [ $rr -> rid ] ; $path = $Path -> path ; $path_id = $Path -> id ; $repo_id = $Path -> rid ; $Repo = $repo_idx [ $repo_id ] ; # echo "path ($path) repo_id ($repo_id) Repo ($Repo)
\n" ; $Repo -> rrids [ $rr -> id ] = $rr ; $Repo -> prrs [ $path ] [ $rr -> pid ] = $rr ; $Path -> rrs [ $rr -> pid ] = $rr ; } foreach ( $repos as $repo ) { ksort ( $repo -> paths ) ; $repo -> subs = $repo -> make_subs () ; } return ( $order ? $repos : $repo_idx ) ; } function cnt_repos ( $from, $sql ) { $sel = new Repo ; return $sel -> db_get_cnt ( $from, $sql ) ; } function get_repos_xusers ( $order, $pid = '' ) { $Repos = TBL ( 'repos' ) ; $Paths = TBL ( 'paths' ) ; $Rights = TBL ( 'rights' ) ; $tab_xusers = TBL ( 'repo_xusers' ) ; $from = "$Paths LEFT JOIN $Rights ON ( $Paths.id = $Rights.rid )" ; $sub = ( $pid ? " = '$pid' " : " in ( SELECT pid from $tab_xusers )" ) ; $sub1 = "SELECT $Paths.rid FROM $from where $Rights.pid $sub" ; $qwe = "$Repos.id in ( $sub1 )" ; return get_repos ( '' , $qwe , $order ) ; } function repos_url () { return URL ( "index.php", "repositories" ) ; } function new_repo_url () { return URL ( "index.php?ACT=NEW_REPO_FORM", 'create a new repository' ) ; } function repos_info_head () { global $USER ; return TR ( TH ( 'meta' ) . TH ( 'repository' ) . TH ( 'description' ) . ( $USER ? TH ( 'public' ) . TH ( 'created' ) . TH ( 'by' ) : '' ) ) ; } function may_create_repo () { global $CLAS ; return count ( paths4clas ( $CLAS ) ) ; } class Repo extends Repo_table { static $fields_bool = array () ; public $rrids = array () ; public $prrs = array () ; public $pids = array () ; public $subs = array () ; function inst () { return new Repo ; } function Repo () { $this -> table_init ( 'repos', 'id' ) ; } function tag () { return $this -> repo_name () ; } function class_name () { return 'repo' ; } function next_val () { return parent::_next_val () ; } static function fields ( $act ) { if ( $act == 'new' ) { $res = array ( 'id' => 'id' , 'side' => 'side' , 'ownr' => 'owner' , 'name' => 'name' , 'dscr' => 'description' ) ; if ( is_adm () ) { $res [ 'lock' ] = 'locked' ; } } elseif ( $act == 'upd' ) { $res = array ( 'dscr' => 'description' ) ; } else { html_exit ( "bad act for fields ($act)" ) ; } return $res ; } static function all_fields () { $res = self::fields ( 'new' ) ; $res [ 'id' ] = 'id' ; $res [ 'lock' ] = 'lock' ; $res [ 'creat' ] = 'creat' ; return $res ; } function cnt_rr_by_group ( $pid, $sql ) { global $TBL ; $rid = $this -> id ; $Groups = TBL ( 'groups' ) ; $Mems = TBL ( 'gr_mem' ) ; $Paths = TBL ( 'paths' ) ; $Rights = TBL ( 'rights' ) ; $qwe = << count ; } function has_public () { foreach ( $this -> paths as $path => $Path ) { if ( ist ( $Path -> publ ) ) { return 1 ; } } return 0 ; } function has_reader () { global $USER, $USER_GROUPS ; if ( ! $this -> id ) { return 0 ; } if ( $this -> has_public () ) { return 1 ; } if ( ! $USER ) { return 0 ; } foreach ( $USER_GROUPS as $name ) { $pids [ $name ] ++ ; } foreach ( $this -> rrids as $rrid => $rr ) { if ( $pids [ $rr -> pid ] and ( $rr -> mod == 'ro' or $rr -> mod == 'rw' ) ) { return 1 ; } } return 0 ; } function has_manager () { global $USER ; if ( ! $this -> id ) { return 0 ; } if ( ! $USER ) { return 0 ; } if ( is_adm () ) { return 1 ; } foreach ( $this -> rrids as $rrid => $rr ) { if ( $rr -> pid == $USER and ist ( $rr -> man ) ) { return 1 ; } } return 0 ; } function assert_has_manager () { global $USER ; $name = $this -> repo_name () ; if ( $this -> has_manager () ) { return 1 ; } else { html_exit ( "you are not a manager for repo $name ($USER)" ) ; } } function reget () { $side = $this -> side ; $ownr = $this -> ownr ; $name = $this -> name ; if ( $this -> id ) { $res = get_repo ( $this -> id ) ; } else { html_exit ( "can't reget repo : no id ($side,$ownr,$name)" ) ; } return $res ; } function get_rights () { if ( ! $this -> id ) { $res = array () ; } else { $res = get_repo_rights_by_rid ( $this -> id ) ; } $this -> rights = $res ; return $res ; } function add_owner_rights () { $path_id = $this -> paths [ EPS() ] -> id ; if ( ! $path_id ) { html_exit ( "no path EPS for repo {$this->id}" ) ; } $rr = new Repo_rights ; $rr -> pid = $this -> ownr ; $rr -> rid = $path_id ; $rr -> mod = 'rw' ; $rr -> wat = 't' ; $rr -> man = 't' ; return $rr -> insert () ; } function upd_url ( $txt ) { return URL ( "index.php?ACT=UPD_REPO_FORM&RID={$this->id}", $txt ) ; } function shw_url ( $txt = 'info' ) { return URL ( "index.php?RID={$this->id}", $txt) ; } function url () { return $this -> shw_url ( $this -> tag () ) ; } function del_url () { $txt = SPN ( 'delete this repository', 'red' ) ; return URL ( "index.php?ACT=DEL&RID={$this->id}", $txt) ; } function svn_url () { $home = REPO_HOME_URL () ; $hrf = $home . 'repos/' . $this -> repo_name () ; return URL ( $hrf, $hrf ) ; } function viewvc_url () { $home = REPO_HOME_URL () ; $hrf = $home . 'viewvc/' . $this -> repo_name () ; return URL ( $hrf, $hrf ) ; } function svn_dump_url () { $home = REPO_HOME_URL () ; $hrf = $home . 'svndump/' . $this -> repo_name () ; return URL ( $hrf, $hrf ) ; } function sum () { return substr ( md5 ( Conf ( 'www_secret' ) . $this -> id ), 0, 8 ) ; } function plot_url ( $atr ) { $sum = $this -> sum () ; $hrf = "plot.php?RID={$this->id}&SUM=$sum" ; $atr = "BORDER=0 $atr" ; $img = IMGA ( "$hrf&STY=SML", 'stats' , $atr ) ; return URL ( $hrf, $img ) ; } function repo_name ( $styled = 0 ) { $side = $this -> side ; $ownr = $this -> ownr ; $name = $this -> name ; if ( ! $tree = try_tree_path ( $side ) ) { html_exit ( "repo_name : no path for repo ($side,$ownr,$name)" ) ; } $fmt = $tree -> pref ; $fmt .= ( $fmt ? '.' : '' ) . '%n' ; $res = preg_replace ( array ( '/%p/', '/%o/', '/%n/' ) , array ( $side , $ownr , $name ) , $fmt ) ; if ( $styled ) { $row = explode ( '.', $res ) ; $cnt = count ( $row ) ; if ( $cnt == 1 ) { $row [ 0 ] = SPN ( $row [ 0 ], 'red' ) ; } elseif ( $cnt > 1 ) { $row [ 1 ] = SPN ( $row [ 1 ], 'red' ) ; } ; $res = implode ( TT ( '.' ), $row ) ; } return $res ; } function name () { return $this -> name ; } function _a_dir ( $a ) { return sprintf ( "%s/%s", $a, $this -> repo_name () ) ; } function repo_dir () { return $this -> _a_dir ( REPO_DIR () ) ; } function arch_dir () { return $this -> _a_dir ( ARCH_DIR () ) ; } function revision ( $add_date = 0 ) { $path = $this -> repo_dir () ; if ( ! is_dir ( $path ) ) { return -1 ; } $cmd = SVN_LOOK_CMD () . ' youngest' ; $pip = popen ( "$cmd '$path'", "r" ) ; if ( $pip === FALSE ) { return -1 ; } $res = trim ( fgets ( $pip, 1024 ) ) ; pclose ( $pip ) ; if ( $add_date ) { $cmd = SVN_LOOK_CMD () . ' date' ; $pip = popen ( "$cmd '$path'", "r" ) ; if ( $pip !== FALSE ) { $line = trim ( fgets ( $pip, 1024 ) ) ; pclose ( $pip ) ; $tmp = explode ( ' ', $line ) ; $res .= sprintf ( ' → %s', $tmp[0] ) ; } } return $res ; } function size () { $stat = get_repo_stats_by_rid_last ( $this -> id ) ; return $stat ? $stat [ 0 ] : 0 ; } function cnt_stats () { return ( $this -> id ? cnt_repo_stats_by_rid ( $this -> id ) : 0 ) ; } function repr ( $fld ) { $res = $this -> $fld ; if ( $fld == 'publ' or $fld == 'lock' ) { $res = repr_bool ( $res ) ; } elseif ( $fld == 'dscr' ) { if ( $res ) { $res = htmlspecialchars ( $res, ENT_QUOTES, 'UTF-8' ) ; } else { $res = 'none' ; } } return $res ; } function txt4rights () { $tab = array () ; if ( ist ( $this -> publ ) ) { $tab [ 'ro' ] [] = SPN ( 'anonymous', 'red' ) ; } foreach ( $this -> rights as $pid => $rr ) { $tags = array () ; if ( ist ( $rr -> man ) ) { $tags [] = 'm' ; } if ( ist ( $rr -> wat ) ) { $tags [] = 'w' ; } $tag = ( $tags ? implode ( '.', $tags ) : '' ) ; $tab [ $rr -> mod ] [] = $pid . ( $tag ? " ($tag)" : '' ) ; } $keys = array_keys ( $tab ) ; sort ( $keys ) ; $txts = array () ; $rr = new Repo_rights ; foreach ( $keys as $key ) { $txts [] = sprintf ( NAV ( "%s" ) . " : %s" , $rr -> mod_tab ( $key ) , implode ( ", ", $tab [ $key ] ) ) ; } return implode ( " ;\n", $txts ) ; } function info_row () { global $USER ; $atr = 'CLASS=main' ; return TR ( ( $USER ? TDc ( ( $this -> has_manager () ) ? $this -> upd_url ( 'update' ) : ( $this -> has_reader () ? $this -> shw_url () : '  ' ) ) : TDc ( $this -> shw_url () ) ) . TDA ( $atr, $this -> repo_name ( 'red' ) ) . TD ( $this -> repr ( 'dscr' ) ) . ( $USER ? TDc ( $this -> has_public () ? 'yes' : 'no' ) . TD ( $this -> creat ) . TD ( $this -> ownr ) : '' ) ) ; } function set_defaults () { global $USER, $CLAS ; $p4c = paths4clas ( $CLAS ) ; if ( ! count ( $p4c ) ) { html_exit ( "set_defaults : no paths for ($USER, $CLAS)" ) ; } $arrk = array_keys ( $p4c ) ; $path = new Repo_paths ; $this -> side = $arrk [ 0 ] ; $this -> name = '' ; $this -> ownr = $USER ; $this -> publ = 'f' ; $this -> lock = 'f' ; $this -> dscr = '' ; $this -> paths = array ( '' => $path -> set_defaults ( $this -> id ) ) ; } function clear_errs () { $this -> errs = array () ; } function err ( $err ) { $this -> errs [] = $err ; } function gen_form_new ( $act ) { global $CLAS ; $side = $this -> side ; $ownr = $this -> ownr ; $name = $this -> name ; $dscr = $this -> dscr ; $fields = $this -> fields ( 'new' ) ; $new_paths = new T_tree ( paths4clas ( $CLAS, 'paths' ) ) ; $bools = array ( 'f' => 'no', 't' => 'yes' ) ; $txt_path = $side ; $txt_ownr = name_login ( $ownr ) ; $txt_name = $this -> repo_name ( 'red' ) ; $txt_dscr = "" ; $txt_creat = alpha_date ( $this -> creat ) ; $txt_path = $new_paths -> input ( 'SIDx', $CLAS ) ; $txt_name = "" ; if ( is_adm () ) { $txt_path = $new_paths -> input ( 'SIDx', $side ) ; $txt_ownr = "" ; $txt_name = "" ; } $top_trs = '' . TR ( THA ( 'COLSPAN=2 CLASS=form', 'properties' ) ) . form_row ( 'opt', $fields [ 'side' ], $txt_path ) . form_row ( 'opt', $fields [ 'ownr' ], $txt_ownr ) . form_row ( 'req', $fields [ 'name' ], $txt_name ) . form_row ( 'opt', $fields [ 'dscr' ], $txt_dscr ) ; $res = <<
$top_trs

FORM; return $res ; } function gen_form_top ( $act ) { global $CLAS ; if ( ! $this -> id ) { return $this -> gen_form_new ( $act ) ; } $side = $this -> side ; $ownr = $this -> ownr ; $name = $this -> name ; $lock = $this -> lock ; $dscr = $this -> dscr ; $fields = $this -> fields ( 'new' ) ; $new_paths = new T_tree ( paths4clas ( $CLAS, 'paths' ) ) ; $bools = array ( 'f' => 'no', 't' => 'yes' ) ; $txt_path = $side ; $txt_ownr = name_login ( $ownr ) ; $txt_name = $this -> repo_name ( 'red' ) ; $txt_dscr = "" ; $txt_creat = alpha_date ( $this -> creat ) ; $txt_apth = "" ; $txt_upbl = form_radio_tab ( 'UPBL', $bools, 'f', '' ) ; $txt_lock = ( is_adm () ? form_radio_tab ( 'LOCK', $bools, $lock, '' ) : "\n" . $this -> repr ( 'lock' ) ) ; if ( is_adm () ) { $txt_path = $new_paths -> input ( 'SIDx', $side ) ; $txt_ownr = "" ; $txt_name = "" ; } $top_trs = '' . TR ( THA ( 'COLSPAN=2 CLASS=form', 'properties' ) ) . ( is_adm () ? form_row ( 'opt', $fields [ 'side' ], $txt_path ) : '' ) . form_row ( 'opt', $fields [ 'ownr' ], $txt_ownr ) . form_row ( 'opt', $fields [ 'name' ], $txt_name ) . form_row ( 'opt', $fields [ 'dscr' ], $txt_dscr ) . form_row ( 'opt', 'revision', $this -> revision ( 1 ) ) . form_row ( 'opt', 'size', KMGB ( $this -> size () ), 3 ) . form_row ( 'opt', 'created', $txt_creat ) . form_row ( 'opt', 'locked', $txt_lock ) . ( $this -> id ? TR ( THA ( 'COLSPAN=2 CLASS=form', 'add permission path' ) ) . form_row ( 'opt', 'path', $txt_apth ) . form_row ( 'opt', 'public', $txt_upbl ) : '' ) ; $res = <<
$top_trs

FORM; return $res ; } # xxx function get_form_repo () { global $USER, $CLAS ; if ( $this -> is_sub () ) { html_exit ( "this is a sub ({$this->id})" ) ; } $this -> clear_errs () ; $side = trim ( $_POST [ 'SIDx' ] ) ; $ownr = trim ( $_POST [ 'OWNR' ] ) ; $name = trim ( $_POST [ 'NAME' ] ) ; $lock = trim ( $_POST [ 'LOCK' ] ) ; $dscr = trim ( $_POST [ 'DSCR' ] ) ; $ownr = strtolower ( $ownr ) ; if ( is_adm () ) { $prev_name = $this -> repo_name () ; $prev_dir = $this -> repo_dir () ; $this -> side = $side ; $this -> ownr = $ownr ; $this -> name = $name ; $this -> lock = $lock ; $this_name = $this -> repo_name () ; if ( $this -> id and ( $this_name != $prev_name ) ) { if ( try_repo_by_son ( $side, $ownr, $name ) ) { $this -> err ( "already have a repo $this_name " ) ; } else { $this -> prev_dir = $prev_dir ; } } } elseif ( $this -> id ) { $side = $this -> side ; $ownr = $this -> ownr ; $name = $this -> name ; $lock = $this -> lock ; } else { $ownr = $USER ; $this -> side = $side ; $this -> name = $name ; $this -> ownr = $ownr ; $lock = $this -> lock ; } $this -> dscr = $dscr ; if ( ! try_tree_path ( $side ) ) { $this -> err ( "bad side ($side)" ) ; } if ( ! preg_match ( "/^[A-Za-z][-.\w]*$/", $name ) ) { $this -> err ( "bad repo name ($name)" ) ; } if ( strlen ( $name ) > 32 ) { $this -> err ( "repo name too long (max 32) ($name)" ) ; } if ( ! preg_match ( "/^[tf]$/", $lock ) ) { $this -> err ( "bad lock ($lock)" ) ; } if ( strlen ( $dscr ) > 1024 ) { $this -> err ( "description too long (max 1024) ($dscr)" ) ; } if ( ! preg_match ( "/^[-@.\w]+$/", $ownr ) ) { $this -> err ( "bad string owner ($ownr)" ) ; } elseif ( ! is_login_name ( $ownr ) ) { $this -> err ( "unknown owner ($ownr)" ) ; } if ( ! $this -> id ) { if ( file_exists ( $this -> repo_dir () ) ) { $dir = $this -> repo_dir () ; $this -> err ( "already exists : $dir" ) ; } if ( try_repo_by_son ( $side, $ownr, $name ) ) { $this -> err ( "already have repo ($side, $ownr, $name)" ) ; } if ( ! is_adm () and $USER != $ownr ) { $this -> err ( "USER ($USER) != owner ($ownr)" ) ; } if ( ! array_key_exists ( $side, paths4clas ( $CLAS ) ) ) { $this -> err ( "tree ($side) not in your class ($CLAS)" ) ; } } if ( $this -> id and $apth = GETVAR ( 'APTH' ) ) { $apth = preg_replace ( '/\/+$/', '', $apth ) ; $upbl = GETVAR ( 'UPBL' ) ; if ( $this -> paths [ $apth ] ) { $this -> err ( "already have a path '$apth'" ) ; } elseif ( ! preg_match ( "/^[tf]$/", $upbl ) ) { $this -> err ( "bad publ ($upbl)" ) ; } else { $Path = new Repo_paths ; $Path -> path = $apth ; $Path -> rid = $this -> id ; $Path -> publ = $upbl ; $this -> add_path = $Path ; } } return ULmk ( $this -> errs ) ; } function gen_form_del_ack ( $act ) { $tag = $this -> tag () ; $id = ( $this -> is_sub () ? $this -> Path () -> id : $this -> id ) ; return <<
repo$tag
  • do you really want to delete $tag ?
FORM; } function show_top () { global $USER ; $side = $this -> side ; $ownr = $this -> ownr ; $name = $this -> repo_name ( 'red' ) ; $publ = $this -> repr ( 'publ' ) ; $lock = $this -> repr ( 'lock' ) ; $dscr = $this -> repr ( 'dscr' ) ; $crea = $this -> repr ( 'creat' ) ; $fields = $this -> fields ( 'new' ) ; $atr1 = 'ALIGN=RIGHT' ; $atr2 = 'COLSPAN=3 CLASS=opt' ; $atr3 = '' ; $trs = '' . TR ( THA ( 'COLSPAN=4 CLASS=form', 'properties' ) ) . form_row ( 'opt', $fields['name'], $name, 3 ) . form_row ( 'opt', $fields['dscr'], $dscr, 3 ) . form_row ( 'opt', 'size', KMGB ( $this -> size () ), 3 ) . form_row ( 'opt', 'created', alpha_date ( $crea ), 3 ) . form_row ( 'opt', 'revision', $this -> revision ( 1 ), 3 ) . ( $USER ? form_row ( 'opt', 'owner', name_login ( $ownr ), 3 ) : '' ) . form_row ( 'opt', 'locked' , $lock, 3 ) ; return TAB ( $trs ) ; } function svn_create () { $name = $this -> repo_name () ; $ownr = $this -> ownr ; $dest = sprintf ( "%s/%s", REPO_DIR (), $name ) ; $perl = Conf ( 'cmd_perl' ) ; $err = 0 ; if ( file_exists ( $dest ) ) { return "FAIL : something exists ($dest)" ; } $cmd = SVN_ADMIN_CMD () ; if ( ! file_exists ( $cmd ) ) { return "command not found ($cmd)" ; } $sys = "$cmd create '$dest'" ; putlog ( "$ownr $sys" ) ; $line = system ( $sys, $err ) ; if ( $err ) { return "FAIL : ($sys)($err,$line)" ; } $cmd = NEW_COMMIT_HOOK () ; $dir = Conf ( 'dir_admin' ) ; $rid = $this -> id ; $sys = "cd $dir ; $perl $cmd -f $rid" ; putlog ( "$ownr $sys" ) ; $line = system ( $sys, $err ) ; if ( $err ) { return "FAIL : ($sys)($err,$line)" ; } return "created repo $name" ; } function insert () { $this -> id = $this -> next_val () ; $res = array ( parent::insert ( $this -> fields ( 'new' ) ) ) ; $rr = new Repo_rights ; $rr -> pid = $this -> ownr ; $rr -> rid = get_path_id_rid_empty ( $this -> id ) ; $rr -> mod = 'rw' ; $rr -> wat = 't' ; $rr -> man = 't' ; $res [] = $rr -> insert () ; $res [] = $this -> svn_create () ; # make_svnaccess_file is now called in index.php return ULmk ( $res ) ; } function update () { $tag4fld = $this -> fields ( is_adm () ? 'new' : 'upd' ) ; $res = array () ; if ( $upd = parent::update ( $tag4fld ) ) { $res [] = $upd ; } if ( $res and is_adm () and $this -> prev_dir ) { $this_dir = $this -> repo_dir () ; $prev_dir = $this -> prev_dir ; if ( $this_dir != $prev_dir ) { $res [] = $this -> rename ( $prev_dir ) ; } } if ( $this -> add_path ) { $res [] = $this -> add_path -> insert () ; } if ( $res ) { make_svnaccess_file () ; } return ULor ( $res, 'no change' ) ; } function delete () { $res = array ( parent::delete() ) ; $res [] = $this -> archive () ; make_svnaccess_file () ; return ULmk ( $res ) ; } function archive () { $name = $this -> repo_name () ; $from = $this -> repo_dir () ; $arch = $this -> arch_dir () ; if ( ! is_dir ( $from ) ) { return "FAIL : repo not found ($from,$arch)" ; } $idx = 1 ; $max = 1000 ; $dst = sprintf ( "%s.%03d", $arch, $idx ) ; while ( $idx < $max and file_exists ( $dst ) ) { $idx ++ ; $dst = sprintf ( "%s.%03d", $arch, $idx ) ; } if ( $idx >= $max ) { return "FAIL : archive count exceeded ($from,$arch)" ; } if ( ! $res = rename ( $from, $dst ) ) { return "FAIL : rename ( $from, $dst )" ; } else { touch ( $dst ) ; return "removed repo $name ($idx)" ; } } function rename ( $src ) { $dst = $this -> repo_dir () ; if ( ! is_dir ( $src ) ) { return "FAIL : src not found (src=$src,$dst)" ; } if ( is_dir ( $dst ) ) { return "FAIL : dst exists ($src,dst=$dst)" ; } if ( ! $res = rename ( $src, $dst ) ) { return "FAIL : rename ( $src, $dst )" ; } else { return "repo moved to " . $this -> repo_name () ; } } function load_form () { return $form = <<
svn (up)load this file :
FORM; } function is_sub () { return 0 ; } function make_sub ( $path ) { if ( ! $this -> paths [ $path ] ) { html_exit ( "no sub ($path)" ) ; } $res = new Sub_repo ; return $res -> make ( $this, $path ) ; } function find_sub ( $path ) { $res = '' ; foreach ( $this -> subs as $sub ) { if ( $sub -> path == $path ) { $res = $sub ; break ; } } if ( ! $res ) { html_exit ( "can't find sub ($path)" ) ; } return $res ; } function make_subs () { $res = array () ; foreach ( $this -> paths as $Path ) { $res [] = $this -> make_sub ( $Path -> path ) ; } return $res ; } function root () { return $this -> find_sub ( '' ) ; } function is_root_manager () { return $this -> root () -> is_manager () ; } function is_writer () { return $this -> root () -> is_writer () ; } function check_managers () { $this -> clear_errs () ; foreach ( $this -> subs as $sub ) { if ( ! $sub -> cnt_mans () ) { $this -> err ( 'there is no manager for ' . $sub -> tag () ) ; } } return ULmk ( $this -> errs ) ; } } ################################################################ function _starts_with ( $a, $b ) { $a_len = strlen ( $a ) ; $b_len = strlen ( $b ) ; if ( $b_len == 0 ) { return 1 ; } return ( $a_len >= $b_len and substr ( $a, 0, $b_len ) == $b ) ; } class Sub_repo extends Repo { public $path = '' ; public $rights = array () ; static function fields ( $act ) { return array ( 'path' => 'path' , 'publ' => 'public' ) ; } function tag () { return sprintf ( '%s → %s' , parent::tag(), $this -> Path () -> tag () ) ; } function is_sub () { return 1 ; } function Path () { return $this -> paths [ $this -> path ] ; } function is_public () { return ist ( $this -> Path () -> publ ) ; } function _rights ( $del = 0 ) { $res = array () ; ksort ( $this -> prrs ) ; foreach ( $this -> prrs as $path => $rrs ) { if ( _starts_with ( $this -> path, $path ) ) { foreach ( $rrs as $pid => $rr ) { if ( ! ( $del and ist ( $rr -> del ) ) ) { $res [ $pid ] = $rr ; } } } } return $res ; } function _set_rights () { $this -> rights = $this -> _rights () ; } function make ( $parent, $path ) { foreach ( $parent as $key => $val ) { $this -> $key = $val ; } $this -> path = $path ; $this -> _set_rights () ; return $this ; } function cnt_mans () { $rights = $this -> _rights ( 1 ) ; $res = 0 ; foreach ( $rights as $pid => $rr ) { if ( ist ( $rr -> man ) ) { $res ++ ; } } return $res ; } function is_reader () { global $USER, $USER_GROUPS ; if ( $this -> is_public () ) { return 1 ; } if ( ! $USER ) { return 0 ; } foreach ( $USER_GROUPS as $pid ) { if ( $rr = $this -> rights [ $pid ] and ( $rr -> mod == 'ro' or $rr -> mod == 'rw' ) ) { return 1 ; } } return 0 ; } function is_writer () { global $USER, $USER_GROUPS ; if ( ! $USER ) { return 0 ; } if ( ! $this -> id ) { return 0 ; } foreach ( $USER_GROUPS as $pid ) { if ( $rr = $this -> rights [ $pid ] and $rr -> mod == 'rw' ) { return 1 ; } } return 0 ; } function is_manager () { global $USER ; if ( ! $USER ) { return 0 ; } if ( is_adm () ) { return 1 ; } if ( ! $this -> rights [ $USER ] ) { return 0 ; } return ist ( $this -> rights [ $USER ] -> man ) ; } function assert_is_manager () { global $USER ; $name = $this -> repo_name () ; $path = $this -> path ; $tag = $this -> tag () ; if ( $this -> is_manager () ) { return 1 ; } else { html_exit ( "you are not a manager for $tag ($USER)" ) ; } } function del_url () { $txt = SPN ( "delete path {$this->tag()}", 'red' ) ; $rid = $this -> id ; $pid = $this -> Path () -> id ; return URL ( "index.php?ACT=DEL_PATH&RID=$rid&PID=$pid", $txt) ; } function svn_url () { $home = REPO_HOME_URL () ; $path = $this -> path ; $hrf = $home . 'repos/' . $this -> repo_name () . ( $path ? "/$path" : '' ) ; return URL ( $hrf, $hrf ) ; } function viewvc_url () { $home = REPO_HOME_URL () ; $path = $this -> path ; $hrf = $home . 'viewvc/' . $this -> repo_name () . ( $path ? "/$path" : '' ) ; return URL ( $hrf, $hrf ) ; } function gen_mod_tab ( $opt ) { $path = $this -> path ; $res = TR ( TH ( 'user/group' ) . TH ( 'delete' ) . TH ( 'rights' ) ) ; foreach ( $this -> prrs [ $path ] as $pid => $rr ) { $atr = "CLASS=$opt" ; $rrid = $rr -> id ; $res .= TR ( TDA ( $atr, name_login ( $pid, '
' ) ) . TDA ( "ALIGN=CENTER $atr" , checkbox ( "DEL[$rrid]", 'f' ) ) . TDA ( $atr , $rr -> gen_radio ( "MOD[$rrid]" ) . ( ( ! is_a_group_name ( $pid ) ) ? ' ' . checkbox ( "MAN[$rrid]", $rr -> man ) . 'manager' . ' ' . checkbox ( "WAT[$rrid]", $rr -> wat ) . 'watcher' : '' ) ) ) ; } return ( $res ) ; } function gen_form_sub ( $act ) { global $CLAS ; $path = $this -> path ; $Path = $this -> Path () ; $brws = $this -> svn_url () ; $view = $this -> viewvc_url () ; $dump = $this -> svn_dump_url () ; $fields = $this -> fields ( 'new' ) ; $bools = array ( 'f' => 'no', 't' => 'yes' ) ; $txt_publ = form_radio_tab ( 'PUBL', $bools, $Path -> publ, '' ) ; $txt_path = "path}\">" ; $new = new Repo_rights ; $new -> set_defaults () ; $mod_box = $new -> gen_radio ( 'AMOD' ) . ' ' . checkbox ( 'AMAN', $this -> man ) . 'manager' . ' ' . checkbox ( 'AWAT', $this -> wat ) . 'watcher' ; $txt_ausr = '' ; $upd_trs = '' . TR ( THA ( 'COLSPAN=4 CLASS=form', $this -> tag () ) ) . ( $this -> is_reader () ? form_row ( 'opt', 'browse, checkout', $brws, 4 ) . ( Conf ( 'viewvc' ) ? form_row ( 'opt', 'view history', $view, 4 ) : '' ) . ( $path == '' ? form_row ( 'opt', 'svn dump', $dump, 4 ) : '' ) : '' ) . ( $path ? form_row ( 'opt', 'path', $txt_path, 2 ) : "" ) . form_row ( 'opt', 'public', $txt_publ, 2 ) . TR ( THA ( 'COLSPAN=3 CLASS=form', 'add user/group rights' ) ) . form_row ( 'opt', 'user/group', $txt_ausr, 2 ) . form_row ( 'opt', 'rights', $mod_box, 2 ) ; if ( count ( $this -> prrs [ $path ] ) ) { $th = THA ( 'COLSPAN=3 CLASS=form', 'set user/group rights' ) ; $upd_trs .= TR ( $th ) . $this -> gen_mod_tab ( 'opt' ) ; } $res = <<
$upd_trs

FORM; return $res ; } # has ID ; $USER is manager ; $this -> paths [ $this -> path ] exists function get_form_sub () { global $USER, $CLAS ; $path = $this -> path ; $Path = $this -> Path () ; $PUBL = GETVAR ( 'PUBL' ) ; $APTH = GETVAR ( 'APTH' ) ; $APTH = preg_replace ( '/\/+$/', '', $APTH ) ; if ( ! $this -> is_sub () ) { html_exit ( "this is not a sub ({$this->id})" ) ; } if ( ! $this -> id ) { html_exit ( "no id for sub" ) ; } if ( ! $Path ) { html_exit ( "no path ($path) for sub" ) ; } $this -> clear_errs () ; if ( $APTH != $path and $this -> paths [ $APTH ] ) { $this -> err ( "already have a path '$APTH'" ) ; } else { $Path -> path = $APTH ; } if ( ! preg_match ( "/^[tf]$/", $PUBL ) ) { $this -> err ( "bad publ ($publ)" ) ; } else { $Path -> publ = $PUBL ; } if ( $ausr = strtolower ( GETVAR ( 'AUSR' ) ) ) { if ( ! ( is_login_name ( $ausr ) or is_group_name ( $ausr ) ) ) { $this -> err ( sprintf ( "unknown %s ($ausr)" , ( is_a_group_name ( $ausr ) ? 'group' : 'user' ) ) ) ; } elseif ( cnt_repo_rights_by_pid_rid ( $ausr, $Path -> id ) ) { $this -> err ( "already have rights for '$ausr'" ) ; } else { $amod = GETVAR ( 'AMOD' ) ; $awat = CHKVAR ( 'AWAT' ) ; $aman = CHKVAR ( 'AMAN' ) ; if ( ! try_repo_mod ( $amod ) ) { $this -> err ( "unknown mod ($amod)" ) ; } elseif ( is_a_group_name ( $ausr ) and ist ( $aman ) ) { $this -> err ( "a group can't be a manager ; sorry" ) ; } elseif ( is_a_group_name ( $ausr ) and ist ( $awat ) ) { $this -> err ( "a group can't be a watcher ; sorry" ) ; } else { $rr = new Repo_rights ; $rr -> pid = $ausr ; $rr -> rid = $this -> Path () -> id ; $rr -> mod = $amod ; $rr -> wat = $awat ; $rr -> man = $aman ; $this -> rights [ $ausr ] = $rr ; $this -> prrs [ $path ] [ $ausr ] = $rr ; $Path -> rrs [ $ausr ] = $rr ; } } } $repo_mods = get_repo_mods ( '', '', '' ) ; $mods = $_POST [ 'MOD' ] ; if ( count ( $mods ) ) { foreach ( $mods as $rrid => $mod ) { if ( ! $this -> rrids [ $rrid ] ) { $this -> err ( "no existing right $rrid" ) ; var_dump ( $this ) ; } elseif ( ! $repo_mods [ $mod ] ) { $this -> err ( "bad mode ($mod)" ) ; } else { $man = CHKVAR ( 'MAN', $rrid ) ; $wat = CHKVAR ( 'WAT', $rrid ) ; $del = CHKVAR ( 'DEL', $rrid ) ; $pid = $this -> rrids [ $rrid ] -> pid ; $this -> rrids [ $rrid ] -> mod = $mod ; $this -> rrids [ $rrid ] -> man = $man ; $this -> rrids [ $rrid ] -> wat = $wat ; $this -> rrids [ $rrid ] -> del = $del ; } } } return ULmk ( $this -> errs ) ; } function show_sub () { global $USER ; $path = $this -> path ; $Path = $this -> Path () ; $txt_path = $Path -> tag () ; $txt_publ = $Path -> repr_bool ( 'publ' ) ; $fields = $this -> fields ( 'new' ) ; $brws = $this -> svn_url () ; $view = $this -> viewvc_url () ; $dump = $this -> svn_dump_url () ; $atr1 = 'ALIGN=RIGHT' ; $atr2 = 'COLSPAN=3 CLASS=opt' ; $atr3 = '' ; $trs = '' . TR ( THA ( 'COLSPAN=4 CLASS=form', 'properties' ) ) . ( $this -> is_reader () ? form_row ( 'opt', 'browse, checkout', $brws, 3 ) . ( Conf ( 'viewvc' ) ? form_row ( 'opt', 'view history', $view, 3 ) : '' ) . ( $path == '' ? form_row ( 'opt', 'svn dump', $dump, 3 ) : '' ) : '' ) . form_row ( 'opt', $fields['path'], $txt_path, 3 ) . form_row ( 'opt', $fields['publ'], $txt_publ, 3 ) ; if ( $USER and count ( $this -> rights ) ) { $trs .= TR ( THA ( 'COLSPAN=4 CLASS=form', 'user/group rights' ) ) ; $trs .= TR ( TH ( 'user/group' ) . TH ( 'access' ) . TH ( 'manager' ) . TH ( 'watcher' ) ) ; foreach ( $this -> rights as $pid => $rr ) { $trs .= TR ( TD ( name_login ( $pid, '
' ) ) . TDc ( $rr -> repr ( 'mod' ) ) . TDc ( $rr -> repr ( 'man' ) ) . TDc ( $rr -> repr ( 'wat' ) ) ) ; } } return TAB ( $trs ) ; } function update () { $Path = $this -> Path () ; $res = array () ; $res [] = $Path -> update () ; $tag = $this -> tag () ; if ( count ( $Path -> rrs ) ) { $res_rrs = array () ; foreach ( $Path -> rrs as $pid => $rr ) { if ( ! $rr -> id ) { $res_rrs [] = $rr -> insert () ; } elseif ( ist ( $rr -> del ) ) { $res_rrs [] = $rr -> delete () ; } else { $res_rrs [] = $rr -> update () ; } } $msg = ULmk ( $res_rrs ) ; } if ( $msg ) { $res [] = "rights $tag :" . $msg ; } return ULor ( $res, "$tag : no change" ) ; } } ################################################################ function get_repo_mods ( $from, $sql, $order ) { $res = new Repo_mods ; return $res -> db_get_all ( $from, $sql, $order ) ; } function try_repo_mod ( $s ) { $res = get_repo_mods ( '', "mod = '$s'", 'mod' ) ; if ( count ( $res ) == 1 ) { return $res [ 0 ] ; } else { return '' ; } } class Repo_mods extends Repo_table { function inst () { return new Repo_mods ; } function Repo_mods () { $this -> table_init ( 'repo_mods', 'mod' ) ; } function tag () { return $this -> mod ; } } ################################################################ # repo paths ################################################################ function get_path ( $id ) { $qwe = "id = '$id'" ; $res = new Repo_paths ; return $res -> db_get1 ( '', $qwe, 'id' ) ; } function get_path_id_rid_empty ( $rid ) { $qwe = "rid = '$rid' and path = ''" ; $res = new Repo_paths ; return $res -> db_get1 ( '', $qwe, 'id' ) -> id ; } class Repo_paths extends Repo_table { public $id ; public $rid ; public $path ; public $publ ; static $fields_bool = array ( 'publ' => 1 ) ; function inst () { return new Repo_paths ; } function Repo_paths () { $this -> table_init ( 'repo_paths', 'id' ) ; } function tag () { return ( $this -> path ? $this -> path : 'repository root' ) ; } function class_name () { return 'path' ; } function fields () { return array ( rid => 'repo id' , path => 'repo path' , publ => 'public' ) ; } function all_fields () { return array ( id => 'id' , rid => 'repo id' , path => 'repo path' , publ => 'public' ) ; } function set_defaults ( $rid ) { $this -> rid = $rid ; $this -> path = '' ; $this -> publ = 'f' ; return $this ; } function repr ( $fld ) { $res = $this -> $fld ; if ( $fld == 'publ' ) { $res = repr_bool ( $res ) ; } return $res ; } function insert () { return parent::insert () ; } function update () { return parent::update () ; } function delete () { return ULmk ( parent::delete () ) ; } } ################################################################ # repo rights ################################################################ function get_repo_right ( $id ) { $res = new Repo_rights ; $res -> db_get_id ( $id ) || html_exit ( "can't get repo_right ($id)" ) ; return $res ; } function get_repo_rights ( $from, $sql, $order ) { $res = new Repo_rights ; return $res -> db_get_all ( $from, $sql, $order ) ; } function cnt_repo_rights ( $from, $sql ) { $res = new Repo_rights ; return $res -> db_get_cnt ( $from, $sql ) ; } function get_repo_rights_by_pid ( $pid ) { return get_repo_rights ( '', "pid = '$pid'", 'pid' ) ; } function get_repo_rights_by_rid ( $rid ) { $rrs = get_repo_rights ( '', "rid = '$rid'", 'pid' ) ; $res = array () ; foreach ( $rrs as $rr ) { $res [ $rr -> pid ] = $rr ; } return $res ; } function cnt_repo_rights_by_pid_rid ( $pid, $rid ) { return cnt_repo_rights ( '', "pid = '$pid' and rid = '$rid'" ) ; } class Repo_rights extends Repo_table { static $mod_tab = array ( 'ro' => 'read' , 'rw' => 'commit' , 'nx' => 'none' ) ; static $fields_bool = array ( 'man' => 1 , 'wat' => 1 ) ; function inst () { return new Repo_rights ; } function Repo_rights () { $this -> table_init ( 'repo_rights', 'id' ) ; } function class_name () { return "rights" ; } function tag () { $atr = array ( $this -> mod ) ; if ( ist ( $this -> man ) ) { $atr [] = 'manager' ; } if ( ist ( $this -> wat ) ) { $atr [] = 'watcher' ; } return sprintf ( "%s (%s)", $this -> pid, implode ( ',', $atr ) ) ; } static function fields () { return array ( 'pid' => 'login' , 'rid' => 'repository' , 'mod' => 'mode' , 'man' => 'manager' , 'wat' => 'watcher' ) ; } static function all_fields () { $res = self::fields () ; $res [ 'id' ] = 'id' ; return $res ; } function set_defaults () { $this -> pid = '' ; $this -> rid = '' ; $this -> mod = 'ro' ; $this -> man = 'f' ; $this -> wat = 'f' ; } function mod_tab ( $mod ) { return self::$mod_tab [ $mod ] ; } function repr ( $fld ) { $res = $this -> $fld ; if ( $fld == 'mod' ) { $res = $this -> mod_tab ( $this -> mod ) ; } elseif ( self::$fields_bool [ $fld ] ) { $res = repr_bool ( $res ) ; } return $res ; } function gen_radio ( $name ) { $pid = $this -> pid ; $rid = $this -> rid ; $mod = $this -> mod ; $rr_tab = array ( 'ro' => NAV ( 'read' ) , 'rw' => NAV ( 'commit' ) , 'nx' => NAV ( 'none' ) ) ; return form_radio_tab ( $name, $rr_tab, $mod, '' ) ; } function get_form ( $repo ) { $mods = $_POST [ 'MOD' ] ; foreach ( $mods as $idx => $mod ) { if ( ! $rights [ $idx ] ) { $res .= LI ( "no existing right $idx" ) ; } else { $repo -> rights [ $idx ] -> mod = $mod ; } } return ( $res ? LI ( UL ( $res ) ) : '' ) ; } function insert () { $res = parent::insert () ; $tag = $this -> tag () ; return $res ? "rights $tag : " . ULmk ( $res ) : '' ; } function update () { return parent::update () ; $res = parent::update () ; $tag = $this -> tag () ; return $res ? "rights $tag : " . ULmk ( $res ) : '' ; } function delete () { $res = parent::delete () ; $tag = $this -> tag () ; return $res ? "rights $tag : " . ULmk ( $res ) : '' ; } } ################################################################ # repo groups ################################################################ function try_repo_group ( $gid ) { $res = new Repo_group ; if ( ! $res -> db_get_id ( $gid ) ) { $res = '' ; } else { $res -> get_group_mems () ; } return $res ; } function get_repo_group ( $gid ) { if ( ! ( $res = try_repo_group ( $gid ) ) ) { html_exit ( "can't get repo_group ($gid)" ) ; } return $res ; } function try_repo_group_by_name ( $name ) { $qwe = "name = '$name' " ; $res = get_repo_groups ( '', $qwe, 'gid' ) ; if ( count ( $res ) == 1 ) { return $res [ 0 ] ; } else { return '' ; } } function get_repo_groups ( $from, $sql, $order ) { $sel = new Repo_group ; $res = $sel -> db_get_all ( $from, $sql, $order ) ; if ( count ( $res ) ) { $idx = array () ; foreach ( $res as $repo_group ) { $repo_group -> mems = array () ; $idx [ $repo_group -> gid ] = $repo_group ; } $gids = array_keys ( $idx ) ; $qwe = sprintf ( 'gid in ( %s )' , implode ( ',', $gids ) ) ; $mems = get_group_mems ( '', $qwe, 'pid' ) ; foreach ( $mems as $mem ) { $idx [ $mem -> gid ] -> mems [ $mem -> pid ] = $mem ; } } return $res ; } function user_group_ids () { global $USER ; $res = array () ; if ( $USER ) { $res [] = $USER ; $Groups = TBL ( 'groups' ) ; $Mems = TBL ( 'gr_mem' ) ; $qwe = << name ; } } return $res ; } function get_groups_xusers ( $order, $pid = '' ) { $tab_groups = TBL ( 'repo_groups' ) ; $tab_mems = TBL ( 'repo_group_members' ) ; $tab_xusers = TBL ( 'repo_xusers' ) ; $sub = ( $pid ? "$tab_mems.pid = '$pid' " : "$tab_mems.pid in ( SELECT pid from $tab_xusers ) " ) ; $qwe = "$tab_groups.gid = $tab_mems.gid and $sub" ; return get_repo_groups ( $tab_mems , $qwe , $order ) ; } function repo_groups_url () { return URL ( "groups.php", 'groups' ) ; } function new_repo_group_url () { return URL ( "groups.php?ACT=NEW_GRP_FORM", 'create a new group' ) ; } function repo_groups_info_head () { global $USER ; return TR ( ( $USER ? TH ( 'info' ) : '' ) . TH ( 'group' ) . TH ( 'owner' ) . TH ( 'created' ) . TH ( 'members' ) ) ; } function may_create_repo_group () { global $CLAS ; return $CLAS != 'guests' ; } class Repo_group extends Repo_table { var $mems = array () ; function inst () { return new Repo_group ; } function Repo_group () { $this -> table_init ( 'repo_groups', 'gid' ) ; } function next_val () { return parent::_next_val () ; } function tag () { return $this -> name ; } function class_name () { return "group" ; } function fields ( $act ) { $res = array () ; if ( $act == 'new' ) { $res [ 'name' ] = 'name' ; $res [ 'ownr' ] = 'owner' ; } elseif ( $act == 'upd' ) { if ( is_adm () ) { $res [ 'ownr' ] = 'owner' ; } } else { html_exit ( "bad act for fields ($act)" ) ; } return $res ; } function is_manager () { global $USER ; $res = 0 ; if ( is_adm () or ( $this -> mems [ $USER ] and ist ( $this -> mems [ $USER ] -> man ) ) ) { $res = 1 ; } return $res ; } function assert_is_manager () { global $USER ; if ( $this -> is_manager () ) { return 1 ; } else { $name = $this -> name ; html_exit ( "you ($USER) are not a manager for this group ($name)" ) ; } } function reget () { $name = $this -> name ; if ( $this -> gid ) { $res = get_repo_group ( $this -> gid ) ; } else { html_exit ( "can't reget repo_group ($name) : no gid" ) ; } return $res ; } function is_used () { return cnt_repo_rights ( '', "pid = '{$this->name}'" ) ; } function get_group_mems () { if ( ! $this -> gid ) { $res = array () ; } else { foreach ( get_group_mems ( '', "gid = {$this->gid}", 'pid' ) as $mem ) { $this -> mems [ $mem -> pid ] = $mem ; } } } function url ( $txt ) { return URL ( "groups.php?ACT=SHW_GRP&GID={$this->gid}", $txt ) ; } function upd_url ( $txt ) { return URL ( "groups.php?ACT=UPD_GRP_FORM&GID={$this->gid}", $txt ) ; } function del_url () { $txt = SPN ( 'delete this group', 'red' ) ; return URL ( "groups.php?ACT=DEL&GID={$this->gid}", $txt ) ; } function repr ( $fld ) { $res = $this -> $fld ; if ( $fld == 'mem' or $fld == 'man' ) { $res = repr_bool ( $res ) ; } return $res ; } function txt4mems () { $tab = array () ; $mems = $this -> mems ; if ( ! count ( $mems ) ) { return ITA ( 'none' ) ; } foreach ( $mems as $idx => $mem ) { if ( ist ( $mem -> mem ) ) { $tab [ 'member' ] [ $mem -> pid ] ++ ; } if ( ist ( $mem -> man ) ) { $tab [ 'manager' ] [ $mem -> pid ] ++ ; } } $keys = array_keys ( $tab ) ; sort ( $keys ) ; $txts = array () ; foreach ( $keys as $key ) { $pids = array_keys ( $tab [ $key ] ) ; sort ( $pids ) ; $txts [] = sprintf ( NAV ( "%s" ) . " : %s" , $key , implode ( ", ", $pids ) ) ; } return implode ( " ;\n", $txts ) ; } function info_row () { global $USER ; $atr = 'CLASS=main' ; return TR ( ( $USER ? TD ( ( $this -> is_manager () ) ? $this -> upd_url ( 'update' ) : ' ' ) : '' ) . TDA ( $atr, $this -> name ) . TD ( $this -> ownr ) . TD ( $this -> creat ) . TD ( $this -> txt4mems () ) ) ; } function set_defaults () { global $USER ; $this -> name = '' ; $this -> ownr = $USER ; } function gen_mem_tab () { $res = TR ( TH ( 'user' ) . TH ( 'member' ) . TH ( 'manager' ) ) ; foreach ( $this -> mems as $pid => $mem ) { $res .= $mem -> input ( "MEM[$pid]" ) ; } return $res ; } function gen_form ( $act ) { $name = $this -> name ; $name = ( $name ? $name : '@' ) ; $ownr = $this -> ownr ; $fields = $this -> fields ( 'new' ) ; $creat = $this -> creat ; if ( is_adm () ) { $txt_ownr = "" ; } else { $txt_ownr = name_login ( $ownr ) . "" ; } if ( ! $this -> gid ) { $txt_name = "" ; } else # update { $txt_name = $name . "" ; $txt_ausr = '' ; $mems = new Repo_mems ; $mems -> set_defaults () ; $txt_rr = '' . TR ( THA ( 'COLSPAN=3 CLASS=form', 'add a member' ) ) . form_row ( 'opt', 'user', $txt_ausr, 2 ) . $mems -> input_fld ( 'AMAN', 'man' ) . ( count ( $this -> mems ) ? TR ( THA ( 'COLSPAN=3 CLASS=form', 'members' ) ) . $this -> gen_mem_tab () : '' ) ; } $optn = ( $this -> gid ? 'opt' : 'req' ) ; $txt_form = '' . TR ( THA ( 'COLSPAN=3 CLASS=form', 'repo group properties' ) ) . form_row ( $optn, $fields [ 'name' ], $txt_name, 2 ) . form_row ( 'opt', $fields [ 'ownr' ], $txt_ownr, 2 ) . ( $this -> gid ? form_row ( 'opt', 'created', $creat, 2 ) : '' ) ; $res = <<
$txt_form $txt_rr

FORM; return $res ; } function get_form () { global $USER ; $res = '' ; $name = trim ( $_POST [ 'NAME' ] ) ; $ownr = trim ( $_POST [ 'OWNR' ] ) ; $BOOL = new T_bool ; if ( is_adm () ) { $this -> name = $name ; $this -> ownr = $ownr ; } elseif ( ! $this -> gid ) { $this -> name = $name ; $ownr = $this -> ownr ; } else { $name = $this -> name ; $ownr = $this -> ownr ; } if ( ! preg_match ( "/^@/", $name ) ) { $res .= LI ( "group name must start with '@' ($name)" ) ; } if ( ! preg_match ( "/^@[a-z][a-z0-9_]*$/", $name ) ) { $res .= LI ( "group name must be lowercase alpha-numeric ($name)" ) ; } if ( strlen ( $name ) > 32 ) { $res .= LI ( "group name too long (max 32) ($name)" ) ; } if ( ! $this -> gid and try_repo_group_by_name ( $name ) ) { $res .= LI ( "group ($name) already exists" ) ; } if ( $ownr == '' ) { $res .= LI ( "should not be empty : owner" ) ; } if ( is_adm () and ! is_login_name ( $ownr ) ) { $res .= LI ( "unknown user ($ownr)" ) ; } if ( $this -> gid and $ausr = strtolower ( GETVAR ( 'AUSR' ) ) ) { $mem = new Repo_mems ; $mem -> from_form ( 'AUSR', 'AMEM', 'AMAN' ) ; if ( ! is_login_name ( $ausr ) ) { $res .= LI ( "unknown user ($ausr)" ) ; } elseif ( get_group_mems_by_pid_gid ( $ausr, $this -> gid ) ) { $res .= LI ( "already have member '$ausr'" ) ; } else { $amem = GETVAR ( 'AMEM' ) ; $aman = GETVAR ( 'AMAN' ) ; if ( ! $BOOL -> vals [ $amem ] ) { $res .= LI ( "bad member val $amem" ) ; } elseif ( ! $BOOL -> vals [ $aman ] ) { $res .= LI ( "bad manager val $aman" ) ; } else { $mem = new Repo_mems ; $mem -> gid = $this -> gid ; $mem -> pid = $ausr ; $mem -> mem = $amem ; $mem -> man = $aman ; $this -> add_mem = $mem ; } } } if ( $this -> gid ) { $mems = $_POST [ 'MEM' ] ; $mans = $_POST [ 'MAN' ] ; $mem_cnt = 0 ; if ( $this -> add_mem and ist ( $this -> add_mem -> man ) ) { $mem_cnt ++ ; } if ( count ( $mems ) ) { foreach ( $mems as $pid => $val ) { $mem = $mems [ $pid ] ; $man = $mans [ $pid ] ; if ( ! $this -> mems [ $pid ] ) { $res .= LI ( "no existing member $pid" ) ; } elseif ( ! $BOOL -> vals [ $mem ] ) { $res .= LI ( "bad member val $mem" ) ; } elseif ( ! $BOOL -> vals [ $man ] ) { $res .= LI ( "bad manager val $man" ) ; } else { $this -> mems [ $pid ] -> mem = $mem ; $this -> mems [ $pid ] -> man = $man ; if ( ist ( $man ) ) { $mem_cnt ++ ; } } } } if ( $mem_cnt == 0 ) { $res .= LI ( "you can't remove all managers" ) ; } } return ( $res ? UL ( $res . LI ( 'nothing is updated' ) ) : '' ) ; } function gen_form_del_ack ( $act ) { $name = $this -> name ; return <<
repo group$name
  • do you really want to delete this group ?
FORM; } function insert () { global $USER ; $this -> gid = $this -> next_val () ; $fields = $this -> fields ( 'new' ) ; $fields [ 'gid' ] = 'gid' ; $res = array ( parent::insert ( $fields ) ) ; $mem = new Repo_mems ; $mem -> gid = $this -> gid ; $mem -> pid = $USER ; $mem -> mem = 't' ; $mem -> man = 't' ; $res [] = $mem -> insert () ; make_svnaccess_file () ; return ULmk ( $res ) ; } function update () { $fields = $this -> fields ( is_adm () ? 'new' : 'upd' ) ; $res = parent::update ( $fields ) ; $mes = array () ; if ( $this -> add_mem ) { $mes [] = $this -> add_mem -> insert () ; } if ( count ( $this -> mems ) ) { foreach ( $this -> mems as $pid => $mem ) { if ( $mem -> mem == 'f' and $mem -> man == 'f' ) { $mes [] = $mem -> delete () ; } else { $msg = $mem -> update () ; if ( $msg ) { $mes [] = $msg ; } } } } if ( $mes ) { $res [] = 'members:' . ULmk ( $mes ) ; } make_svnaccess_file () ; return ULmk ( $res ? $res : 'no change' ) ; } function delete () { $res = parent::delete () ; make_svnaccess_file () ; return ULmk ( $res ) ; } } ################################################################ function get_group_mem ( $id ) { $res = new Repo_mems ; $res -> db_get_id ( $id ) || html_exit ( "can't get group_mem ($id)" ) ; return $res ; } function get_group_mems ( $from, $sql, $order ) { $res = new Repo_mems ; return $res -> db_get_all ( $from, $sql, $order ) ; } function get_group_mems_by_pid_gid ( $pid, $gid ) { return get_group_mems ( '', "pid = '$pid' and gid = '$gid'", '' ) ; } class Repo_mems extends Repo_table { static $fields_bool = array ( 'mem' => 1 , 'man' => 1 ) ; function inst () { return new Repo_mems ; } function Repo_mems () { $this -> table_init ( 'repo_group_members', 'id' ) ; } function tag () { $res = $this -> pid ; if ( ist ( $this -> man ) ) { $res .= ' (manager)' ; } return $res ; } function class_name () { return "group member" ; } function fields () { return array ( 'gid' => 'group id' , 'pid' => 'login' , 'mem' => 'member?' , 'man' => 'manager?' ) ; } function set_defaults () { $this -> gid = '' ; $this -> pid = '' ; $this -> mem = 't' ; $this -> man = 'f' ; } function repr ( $fld ) { $res = $this -> $fld ; if ( self::$fields_bool [ $fld ] ) { $res = repr_bool ( $res ) ; } return $res ; } function input_fld ( $name, $fld ) { global $USER ; $fields = $this -> fields () ; $atr = 'CLASS=opt COLSPAN=2' ; $bool = new T_bool ; return TR ( THr ( $fields [ $fld ] ) . TDA ( $atr, $bool -> input ( $name, $this -> $fld ) ) ) ; } function input () { global $USER ; $fields = $this -> fields () ; $bool = new T_bool ; $mem = $this -> mem ; $man = $this -> man ; if ( $pid = $this -> pid ) { $atr = 'CLASS=opt' ; return TR ( TD ( name_login ( $pid ) ) . TDA ( $atr, $bool -> input ( "MEM[$pid]", $mem ) ) . TDA ( $atr, $bool -> input ( "MAN[$pid]", $man ) ) ) ; } } function from_form ( $nm_usr, $nm_mem, $nm_man ) { $usr = new T_txt ; $mem = new T_bool ; $man = new T_bool ; $usr -> fld_from_form ( $this, 'pid', $nm_usr ) ; $mem -> fld_from_form ( $this, 'mem', $nm_mem ) ; $man -> fld_from_form ( $this, 'man', $nm_man ) ; } } ################################################################ function get_repo_roots ( $from, $sql, $order ) { $res = new Repo_roots ; return $res -> db_get_all ( $from, $sql, $order ) ; } function try_repo_root ( $pid ) { $res = get_repo_roots ( '', "pid = '$pid'", 'pid' ) ; if ( count ( $res ) == 1 ) { return $res [ 0 ] ; } else { return '' ; } } function actv_root ( $actv ) { global $USER, $EDS ; if ( ! $root = try_repo_root ( $USER ) ) { html_exit ( "you ($USER) are not an admin" ) ; } elseif ( $root -> actv != $actv ) { $root -> actv = $actv ; $root -> update () ; $EDS [ $USER ] = ist ( $actv ) ; } } class Repo_roots extends Repo_table { function inst () { return new Repo_roots ; } function Repo_roots () { $this -> table_init ( 'repo_roots', 'pid' ) ; } function tag () { return $this -> pid ; } function update () { $tab = array ( $this -> actv ) ; $qwe = sprintf ( "UPDATE %s SET actv = $1 WHERE pid = '%s' ; " , $this -> _tab , $this -> pid ) ; db_query_params ( $qwe, $tab ) ; } } ################################################################ function paths4clas ( $clas, $paths = 0 ) { $trees = Conf ( 'trees' ) ; $is_adm = is_adm () ; $res = array () ; foreach ( $trees as $tree ) { if ( $is_adm or $tree -> crea [ $clas ] ) { $path = $tree -> path ; $res [ $path ] = ( $paths ? $path : $tree ) ; } } return $res ; } function try_tree_path ( $b ) { $trees = Conf ( 'trees' ) ; $res = '' ; foreach ( $trees as $tree ) { if ( $tree -> path == $b ) { $res = $tree ; break ; } } return $res ; } class Repo_tree { # $creas is an array of class names ; checked by Config::make_trees() function init ( $path, $pref, $creas ) { $this -> path = $path ; $this -> pref = $pref ; $this -> crea = array () ; foreach ( $creas as $idx => $clas ) { $this -> crea [ $clas ] ++ ; } return $this ; } function dmp () { printf ( "tree path (%s) pref (%s) crea (%s)
\n" , $this -> path , $this -> pref , implode ( '|', array_keys ( $this -> crea ) ) ) ; } } ################################################################ class Uclas { function init ( $x ) { $this -> clas = $x [ 'clas' ] ; $this -> dscr = $x [ 'dscr' ] ; $this -> typ = $x [ 'typ' ] ; } function dmp () { printf ( "user typ (%s) " , $this -> typ ) ; } } class Uclas_table extends Uclas { function init ( $x ) { parent::init ( $x ) ; $this -> tab = $x [ 'table' ] ; $this -> login = $x [ 'login' ] ; $this -> paswd = $x [ 'paswd' ] ; $this -> cname = $x [ 'cname' ] ; return $this ; } function dmp () { parent::dmp () ; printf ( "tab (%s) login (%s) paswd (%s)
\n" , $this -> tab, $this -> login, $this -> paswd ) ; } } ################################################################ class Uclas_ldap extends Uclas { function init ( $x ) { parent::init ( $x ) ; $this -> tag = $x [ 'tag' ] ; $this -> ldap = $x [ 'ldap' ] ; $this -> pat = $x [ 'pat' ] ; return $this ; } function dmp () { parent::dmp () ; printf ( "tag (%s) serv (%s) base (%s) pat (%s)
\n" , $this -> tag , $this -> ldap -> serv , $this -> ldap -> base , $this -> pat ) ; } } ################################################################ function get_repo_stats ( $from, $sql, $order ) { $res = new Repo_stats ; return $res -> db_get_all ( $from, $sql, $order ) ; } function get_repo_stats_by_rid ( $rid ) { return get_repo_stats ( '', "rid = '$rid'", 'date' ) ; } function cnt_repo_stats_by_rid ( $rid ) { $sel = new Repo_stats ; return $sel -> db_get_cnt ( '', "rid = '$rid'" ) ; } function get_repo_stats_by_rid_last ( $rid ) { return get_repo_stats ( '', "rid = '$rid'", 'date desc limit 1' ) ; } class Repo_stats extends Repo_table { function inst () { return new Repo_stats ; } function Repo_stats () { $this -> table_init ( 'repo_stats', 'id' ) ; } function tag () { return $this -> date ; } } ################################################################ function try_repo_xuser ( $id ) { $res = new Repo_xuser ; if ( ! $res -> db_get_id ( $id ) ) { $res = '' ; } return $res ; } function get_repo_xuser ( $id ) { if ( ! ( $res = try_repo_xuser ( $id ) ) ) { html_exit ( "can't get repo_xuser ($id)" ) ; } return $res ; } function get_repo_xusers ( $from, $sql, $order ) { $res = new Repo_xuser ; return $res -> db_get_all ( $from, $sql, $order ) ; } class Repo_xuser extends Repo_table { function inst () { return new Repo_xuser ; } function Repo_xuser () { $this -> table_init ( 'repo_xusers', 'id' ) ; } function tag () { return $this -> pid ; } function class_name () { return "xuser" ; } function delete_url () { $id = $this -> id ; $pid = $this -> pid ; $hrf = "stats.php?ACT=DEL&ID=$id" ; return URL ( $hrf, SPN ( "delete xuser $pid", 'red' ) ) ; } function delete_rrs_mems_url () { $id = $this -> id ; $pid = $this -> pid ; $hrf = "stats.php?ACT=DEL_RRS&ID=$id" ; $txt = "delete rights/memberships xuser $pid" ; return URL ( $hrf, SPN ( $txt, 'red' ) ) ; } function delete () { $pid = $this -> pid ; $res = array () ; # $repos = get_repos ( '', "ownr = '$pid'",'side,ownr,name' ) ; # foreach ( $repos as $idx => $repo ) # { $name = $repo -> repo_name () ; # $res [] = $repo -> delete () ; # } $repos = get_repos_xusers ( 'side,ownr,name', $pid ) ; foreach ( $repos as $idx => $repo ) { foreach ( $repo -> subs as $sub ) { if ( $rr = $sub -> rights [ $pid ] ) { $res [] = $sub -> tag () . ' : ' . $rr -> delete () ; } } } $groups = get_groups_xusers ( 'name', $pid ) ; foreach ( $groups as $idx => $group ) { if ( $mem = $group -> mems [ $pid ] ) { $res [] = $group -> tag() . ' : ' . $mem -> delete () ; } } $res [] = parent::delete () ; return ULmk ( $res ) ; } function delete_rrs_mems () { $pid = $this -> pid ; $res = array () ; $repos = get_repos_xusers ( 'side,ownr,name', $pid ) ; foreach ( $repos as $idx => $repo ) { foreach ( $repo -> subs as $sub ) { if ( $rr = $sub -> rights [ $pid ] ) { $res [] = $sub -> tag () . ' : ' . $rr -> delete () ; } else { var_dump ( $sub -> rights ) ; html_exit ( "stats delete_rrs : no rr for pid $pid" ) ; } } } $groups = get_groups_xusers ( 'name', $pid ) ; foreach ( $groups as $idx => $group ) { if ( $mem = $group -> mems [ $pid ] ) { $res [] = $group -> tag() . ' : ' . $mem -> delete () ; } } return ULmk ( $res ) ; } } ################################################################ class Ftyp { function inst () { return new Ftyp ; } function typ_init ( $typ ) { $this -> _typ = $typ ; } function pat () { return '' ; } function selectbox ( $name, $pval, $vals ) { $res = "\n" ; return $res ; } function input ( $name, $pval ) { if ( $vals = $this -> vals ) { $cnt = count ( $vals ) ; if ( ! $vals [ $pval ] ) { $keys = array_keys ( $vals ) ; $pval = $keys [ 0 ] ; } if ( $cnt == 1 ) { $res = $pval ; $res .= sprintf ( '' . "\n" , $name , $pval ) ; } elseif ( $cnt < 4 ) { $res = form_radio_tab ( $name, $vals, $pval, '' ) ; } elseif ( $cnt < 6 ) { $res = form_radio_tab ( $name, $vals, $pval ) ; } else { $res = $this -> selectbox ( $name, $pval, $vals ) ; } } else { $res = "\n" ; } return $res ; } function check () { $res = 1 ; $val = $this -> val ; if ( $vals = $this -> vals () ) { $res = array_key_exists ( $val, $vals ) ; } elseif ( $pat = $this -> pat () ) { $res = preg_match ( $pat, $val ) ; } return $res ; } function repr ( $val ) { $res = $val ; if ( $vals = $this -> vals () ) { if ( array_key_exists ( $val, $vals ) ) { $res = $vals [ $val ] ; } } return $res ; } function from_form ( $name ) { $res = '' ; $matches = array () ; if ( preg_match ( '/^([A-Za-z]+)\[([0-9]*)\]/', $name, $matches ) ) { $nam = $matches [ 1 ] ; $idx = $matches [ 2 ] ; $val = $_POST [ $nam ] [ $idx ] ; echo "nam $nam idx $idx val $val
\n" ; } else { $val = $_POST [ $name ] ; } $res = htmlentities ( trim ( $val ) ) ; $this -> val = $res ; return $res ; } function fld_from_form ( $obj, $fld, $name ) { $res = '' ; $matches = array () ; if ( preg_match ( '/^([A-Za-z]+)\[([0-9]*)\]/', $name, $matches ) ) { $nam = $matches [ 1 ] ; $idx = $matches [ 2 ] ; if ( array_key_exists ( $nam, $_POST ) and array_key_exists ( $idx, $_POST [ $nam ] ) ) { $val = $_POST [ $nam ] [ $idx ] ; echo "nam $nam idx $idx val $val
\n" ; $res = htmlentities ( $val ) ; $obj -> $fld = $res ; $this -> val = $res ; } } elseif ( array_key_exists ( $name, $_POST ) ) { $val = $_POST [ $name ] ; $res = htmlentities ( trim ( $_POST [ $name ] ) ) ; $obj -> $fld = $res ; $this -> val = $res ; } return $res ; } } class T_typs extends Ftyp { var $vals = array ( 'T_bool' => 'bool' , 'T_int' => 'integer' , 'T_txt' => 'text' , 'T_alpha' => 'alpha' ) ; function T_typs () { $this -> typ_init ( 'T_typs' ) ; } } class T_bool extends Ftyp { var $vals = array ( 't' => 'yes' , 'f' => 'no' ) ; function T_bool () { $this -> typ_init ( 'T_bool' ) ; } } class T_txt extends Ftyp { function T_txt () { $this -> typ_init ( 'T_txt' ) ; } } class T_alpha extends T_txt { function T_alpha () { $this -> typ_init ( 'T_alpha' ) ; } function pat () { return '^[A-Za-z][A-Za-z0-9_]*$' ; } } class T_int extends Ftyp { function T_int () { $this -> typ_init ( 'T_int' ) ; } function pat () { return '/^-?[0-9]+$/' ; } } class T_tree extends Ftyp { var $vals ; function T_tree ( $vals = array () ) { $this -> typ_init ( 'T_tree' ) ; $this -> vals = $vals ; } }