reinsert
This commit is contained in:
parent
2949dbe982
commit
13ecac28d0
|
@ -0,0 +1,227 @@
|
||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Auth library</title>
|
||||||
|
<meta content="Tomas Hlava" name="author">
|
||||||
|
<style type="text/css"><!--
|
||||||
|
* { font-family: 'Arial CE', 'Helvetica CE', Arial, sans-serif; font-size: 10pt; }
|
||||||
|
body { padding: 1em; }
|
||||||
|
h1 { font-size: 14pt; padding:1px; background-color: #66aaff; }
|
||||||
|
h2 { font-size: 11pt; padding:1px; padding-left:1ex; background-color: #aaccff; }
|
||||||
|
h3 { font-size: 10pt; padding:1px; padding-left:2ex; background-color: #aaffcc; }
|
||||||
|
p { width: 90%; text-indent: 1em; }
|
||||||
|
p#ps { clear: both; }
|
||||||
|
.center { text-align:center; }
|
||||||
|
.aart { width: 90%; font-family:monospace; }
|
||||||
|
.aart span{ font-family:monospace; padding:0ex 1ex; background-color: #eee; }
|
||||||
|
.aart div{ font-family:monospace; padding:0ex 1ex; }
|
||||||
|
code { font-family:monospace; font-weight:bold; background-color: #e4e4e4; }
|
||||||
|
.b { font-weight:bold; }
|
||||||
|
.ulg p { margin-bottom: 0px; }
|
||||||
|
.ulg ul,ol { margin-top: 0px; }
|
||||||
|
.ex { padding:1em; background-color:#f0f0f0; width:80%; overflow:auto; }
|
||||||
|
.bg { padding:2px 4px; background-color:#eaeaea; }
|
||||||
|
table { border: 2px solid black; border-collapse: collapse; }
|
||||||
|
table th { border: solid black; border-width: 2px 1px; }
|
||||||
|
table td { border: 1px solid black; text-align:center; }
|
||||||
|
hr { border:0px; border-bottom: 1px solid #66aaff; }
|
||||||
|
hr.hr2 { border:0px; border-bottom: 2px solid #66aaff; }
|
||||||
|
/*#date { float: left; width:30%; padding:1ex; }*/
|
||||||
|
/*#signature { float: right; width:30%; padding:1ex; text-align: right; }*/
|
||||||
|
#signature { float: left; width:30%; padding:1ex; }
|
||||||
|
--></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Auth library - request for comments</h1>
|
||||||
|
22.7.2004
|
||||||
|
<h2>Authentication & authorization</h2>
|
||||||
|
<p> <span class="b">Authentication</span> - as user's identity
|
||||||
|
checking - login call create and return auth token, client sends this token
|
||||||
|
with all subsequent calls, logout call make this token invalid<br>
|
||||||
|
</p>
|
||||||
|
<p> <span class="b">Authorization</span> - as checking user's
|
||||||
|
permission for called action on some object - that's main solved problem.
|
||||||
|
</p>
|
||||||
|
<h2>Basic model</h2>
|
||||||
|
<div class="aart center"><span>Subject --- Action ---> Object</span></div>
|
||||||
|
<div class="ulg">
|
||||||
|
<p>Where:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Subject<br>
|
||||||
|
is one user or user group (or role - in this aproach group and role are the same)<br>
|
||||||
|
</li>
|
||||||
|
<li>Action<br>
|
||||||
|
is item from predefined action set
|
||||||
|
</li>
|
||||||
|
<li>Object<br>
|
||||||
|
is a object from tree or class of objects
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<h2>Subject implementation</h2>
|
||||||
|
<p> Subjects are divided into two types - users and groups. There is membership relation
|
||||||
|
(type N:M) from subjects table to itself with "linearization" feature - for
|
||||||
|
questions about it send me a mail please ;)<br>
|
||||||
|
This approach allows inserting user to group or group to group with quick
|
||||||
|
searching of direct and indirect membership.
|
||||||
|
</p>
|
||||||
|
<h2>Object implementation</h2>
|
||||||
|
<p> For simple use with existing projects, there would be a object tree
|
||||||
|
always separated from project's database tables. It would be implemented by
|
||||||
|
table of objects and information about parent/child (or other) relation
|
||||||
|
between objects.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
There is also class table and N:M membership relation between objects and
|
||||||
|
classes.
|
||||||
|
</p>
|
||||||
|
<h3>Example:</h3>
|
||||||
|
<div class="ex">
|
||||||
|
<pre class="aart">
|
||||||
|
RootNode
|
||||||
|
|
|
||||||
|
|-> Publication_A(publication)
|
||||||
|
| \-> Issue_1(issue) <--\
|
||||||
|
| |-> Sport(section) | <--\
|
||||||
|
| \-> Politics(section) | |
|
||||||
|
\-> Publication_B(publication) | |
|
||||||
|
|-> Issue_1(issue) <--| |
|
||||||
|
| |-> Politics(section) | |
|
||||||
|
| |-> Sport(section) | <--|
|
||||||
|
| \-> Culture(section) | |
|
||||||
|
\-> Issue_2(issue) <--| |
|
||||||
|
|-> Culture(section) | |
|
||||||
|
\-> Politics(section) | |
|
||||||
|
| |
|
||||||
|
Class "Issues" -------------------------------------------/ |
|
||||||
|
Class "Sport sections" -------------------------------------------/
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Object table structure:<br>
|
||||||
|
<code><span class="b">[</span> id, name, type, parid, lft, rgt, level <span class="b">]</span></code><br>
|
||||||
|
class table structure:<br>
|
||||||
|
<code><span class="b">[</span> id, cname <span class="b">]</span></code><br>
|
||||||
|
and class membership table structure:<br>
|
||||||
|
<code><span class="b">[</span> objid, cid <span class="b">]</span></code><br>
|
||||||
|
-->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<h2>Permissions for actions</h2>
|
||||||
|
<p> There are several ways to handle permissions - I've used this:<br>
|
||||||
|
<span class="b">allow/deny</span> - all without allow
|
||||||
|
permission is denied, but more specified setting may overcome less
|
||||||
|
specified<br>
|
||||||
|
(e.g. group of users is allowed to do smth., but one specified group-member is
|
||||||
|
denied)
|
||||||
|
</p>
|
||||||
|
<p> Permissions are stored as triple <code class="bg"><span
|
||||||
|
class="b">[</span>subject, action, object<span class="b">]</span></code>
|
||||||
|
and <span class="b">allow/deny</span> flag.<br>
|
||||||
|
</p>
|
||||||
|
<div class="ulg">
|
||||||
|
<p>Procedure of permission checking:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Select all permissions on corresponding object + all objects in tree path<br>
|
||||||
|
for actual user + all groups, where user have direct or indirect membership.
|
||||||
|
</li>
|
||||||
|
<li>Sort it by:<ol>
|
||||||
|
<li>diference in tree levels for object
|
||||||
|
<li>membership level for subject
|
||||||
|
<li>record with '_all' action have lower priority
|
||||||
|
<li>'deny' records have higher priority then 'allow'
|
||||||
|
</ol></li>
|
||||||
|
<li>If no record found then repeat similar query with class table instead of object tree table. (+ similar sorting)</li>
|
||||||
|
<li>If record on the top of sorted sequence have 'allow' type then return allow else deny</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<p>Rem.: Some cache system for authorization decisions would be good ...
|
||||||
|
</p>
|
||||||
|
<h2>Auth system usage</h2>
|
||||||
|
<div class="ulg">
|
||||||
|
<p>There are 3 main types of usage:</p>
|
||||||
|
<ol>
|
||||||
|
<li>authorization of called action</li>
|
||||||
|
<li>automatic modification of user interface in dependence on user
|
||||||
|
permissions</li>
|
||||||
|
<li>automatic generation of admin interface for permissions settings</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
<h2>Important part of API:</h2>
|
||||||
|
<div class="ulg">
|
||||||
|
<ul>
|
||||||
|
<li>function <code>Alib(&$dbc, $config)</code> returns object<br>
|
||||||
|
constructor
|
||||||
|
</li>
|
||||||
|
<li>function <code>login($login, $pass)</code> returns token<br>
|
||||||
|
</li>
|
||||||
|
<li>function <code>logout($sessid)</code> returns boolean<br>
|
||||||
|
</li>
|
||||||
|
<li>function <code>checkToken($sessid)</code> returns boolean<br>
|
||||||
|
check validity of the token
|
||||||
|
</li>
|
||||||
|
<li>function <code>addObj($name, $type, $parid, $aftid, $param)</code> returns int<br>
|
||||||
|
adds object to tree as child of object with id=$parid after object with id=$aftid
|
||||||
|
</li>
|
||||||
|
<li>function <code>removeObj($id)</code> returns boolean<br>
|
||||||
|
</li>
|
||||||
|
<li>function <code>addSubj($login, $pass)</code> returns int<br>
|
||||||
|
add user (or group - with $pass=null)
|
||||||
|
</li>
|
||||||
|
<li>function <code>removeSubj($login)</code> returns boolean<br>
|
||||||
|
</li>
|
||||||
|
<li>function <code>addPerm($sid, $action, $oid, $type)</code> returns int<br>
|
||||||
|
add permission record - type is A(allow) or D(deny)
|
||||||
|
</li>
|
||||||
|
<li>function <code>removePerm($permid, $subj, $obj)</code> returns null<br>
|
||||||
|
remove permission record
|
||||||
|
</li>
|
||||||
|
<li>function <code>checkPerm($sid, $action, $oid)</code> returns boolean<br>
|
||||||
|
check permission for action on object with id=$oid for subject with id=$sid
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>function <code>copyObj($id, $newParid, $after)</code> returns int<br>
|
||||||
|
</li>
|
||||||
|
<li>function <code>renameObj($id, $newName)</code> returns boolean<br>
|
||||||
|
</li>
|
||||||
|
<li>function <code>getParent($oid)</code> returns string<br>
|
||||||
|
</li>
|
||||||
|
<li>function <code>getPath($id, $flds)</code> returns array<br>
|
||||||
|
</li>
|
||||||
|
<li>function <code>getDir($id, $flds, $order)</code> returns array<br>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>function <code>addClass($cname)</code> returns int<br>
|
||||||
|
</li>
|
||||||
|
<li>function <code>removeClass($cname)</code> returns boolean<br>
|
||||||
|
</li>
|
||||||
|
<li>function <code>addObj2Class($cid, $oid)</code> returns boolean<br>
|
||||||
|
</li>
|
||||||
|
<li>function <code>removeObjFromClass($oid, $cid)</code> returns boolean<br>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>function <code>addSubj2Gr($login, $gname)</code> returns int<br>
|
||||||
|
</li>
|
||||||
|
<li>function <code>removeSubjFromGr($login, $gname)</code> returns boolean<br>
|
||||||
|
</li>
|
||||||
|
<li>function <code>isGroup($gid)</code> returns boolean<br>
|
||||||
|
</li>
|
||||||
|
<li>function <code>listGroup($gid)</code> returns array<br>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>All methods may return PEAR::error object if fails ...</p>
|
||||||
|
</div>
|
||||||
|
<h2>Connection to existing applications</h2>
|
||||||
|
<p> PHP applications could include Alib class and call API methods
|
||||||
|
directly.<br>
|
||||||
|
Other programming platforms should call XMLRPC or HTTP layer above this API.
|
||||||
|
</p>
|
||||||
|
<hr class="hr2">
|
||||||
|
<div id="footer">
|
||||||
|
<div id="signature"> Tomas Hlava<br>
|
||||||
|
<a href="mailto:th@red2head.com">th@red2head.com</a><br>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p id="ps">P.S.: sorry for my English ... ;)</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,60 @@
|
||||||
|
<html><head>
|
||||||
|
<!-- $Id: reference.html,v 1.1 2004/07/23 00:22:13 tomas Exp $ -->
|
||||||
|
<title>Alib reference</title>
|
||||||
|
<style type="text/css">
|
||||||
|
<!--
|
||||||
|
* { font-family: 'Arial CE', 'Helvetica CE', Arial, sans-serif; font-size: 10pt; }
|
||||||
|
body { padding: 1em; }
|
||||||
|
h1 { font-size: 14pt; padding:1px; background-color: #66aaff; }
|
||||||
|
h2 { font-size: 11pt; padding:1px; padding-left:1ex; background-color: #aaccff; }
|
||||||
|
h3 { font-size: 10pt; padding:1px; padding-left:2ex; background-color: #aaffcc; }
|
||||||
|
p { width: 90%; text-indent: 1em; }
|
||||||
|
pre { border: 1px dashed grey; padding:1em; }
|
||||||
|
p:first-letter { padding-left:2em; }
|
||||||
|
.center { text-align:center; }
|
||||||
|
.aart { width: 90%; font-family:monospace; }
|
||||||
|
.aart span{ font-family:monospace; padding:0ex 1ex; background-color: #eee; }
|
||||||
|
.aart div{ font-family:monospace; padding:0ex 1ex; }
|
||||||
|
code { font-family:monospace; }
|
||||||
|
.b { font-weight:bold; }
|
||||||
|
-->
|
||||||
|
</style>
|
||||||
|
</head></body>
|
||||||
|
|
||||||
|
<h1>Alib reference</h1>
|
||||||
|
|
||||||
|
in construction - sorry ;)
|
||||||
|
|
||||||
|
<a name="contents"></a>
|
||||||
|
<h2>Contents</h2>
|
||||||
|
<ol>
|
||||||
|
<li><a href="#subjs">Subjects</a></li>
|
||||||
|
<li><a href="#perms">Perms</a></li>
|
||||||
|
<li><a href="#objs">Objects</a></li>
|
||||||
|
<li><a href="#classes">Classes</a></li>
|
||||||
|
<li><a href="#dbstr">DB structure</a></li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<a name="subjs"></a>
|
||||||
|
<h2>Subjects</h2>
|
||||||
|
|
||||||
|
<a name="perms"></a>
|
||||||
|
<h2>Perms</h2>
|
||||||
|
|
||||||
|
<a name="objects"></a>
|
||||||
|
<h2>Objects</h2>
|
||||||
|
|
||||||
|
<a name="classes"></a>
|
||||||
|
<h2>Classes</h2>
|
||||||
|
<p>Classes may be replaced by one branch in object tree ...</p>
|
||||||
|
|
||||||
|
<a name="dbstr"></a>
|
||||||
|
<h2>DB structure</h2>
|
||||||
|
<pre>
|
||||||
|
subjects < perms > objects/classes
|
||||||
|
< smemb
|
||||||
|
cmemb >
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
</body></html>
|
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
$Id: todo.txt,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
|
||||||
|
* delete old sessions
|
||||||
|
* if user have 'classes' permission:
|
||||||
|
-> create new class ('X')
|
||||||
|
-> add '_all' perm on class 'X' to himself
|
||||||
|
-> insert RootNode to class 'X'
|
||||||
|
=> user have all perms ;)
|
||||||
|
* complete xmlrpc layer
|
||||||
|
|
||||||
|
---
|
||||||
|
partialy done:
|
||||||
|
|
||||||
|
. actions would have priority order (or set lower priority to '_all' action only),
|
||||||
|
temp hack: '_all' action is in string sort after all act names => with ASC order have '_all' lower prio ...
|
||||||
|
---
|
|
@ -0,0 +1,444 @@
|
||||||
|
<?php
|
||||||
|
// $Id: alib.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alib class
|
||||||
|
*
|
||||||
|
* authentication/authorization class
|
||||||
|
**/
|
||||||
|
require_once 'subj.php';
|
||||||
|
define('ALIBERR_NOTLOGGED', 30);
|
||||||
|
define('ALIBERR_NOTEXISTS', 31);
|
||||||
|
|
||||||
|
class Alib extends Subjects{
|
||||||
|
var $permTable;
|
||||||
|
var $sessTable;
|
||||||
|
var $login=NULL;
|
||||||
|
var $userid=NULL;
|
||||||
|
var $sessid=NULL;
|
||||||
|
/** Alib - constructor
|
||||||
|
*
|
||||||
|
* @param object DB
|
||||||
|
* @param config array
|
||||||
|
* @return this
|
||||||
|
**/
|
||||||
|
function Alib(&$dbc, $config)
|
||||||
|
{
|
||||||
|
parent::Subjects(&$dbc, $config);
|
||||||
|
$this->permTable = $config['tblNamePrefix'].'perms';
|
||||||
|
$this->sessTable = $config['tblNamePrefix'].'sess';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== public methods: ========== */
|
||||||
|
|
||||||
|
/* --- session/authentication --- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* login
|
||||||
|
*
|
||||||
|
* @param login string
|
||||||
|
* @param pass string
|
||||||
|
* @return boolean/sessionId/err
|
||||||
|
**/
|
||||||
|
function login($login, $pass)
|
||||||
|
{
|
||||||
|
if(FALSE === $this->authenticate($login, $pass)) return FALSE;
|
||||||
|
for($c=1; $c>0;){
|
||||||
|
$sessid = md5(uniqid(rand()));
|
||||||
|
$c = $this->dbc->getOne("SELECT count(*) FROM {$this->sessTable} WHERE sessid='$sessid'");
|
||||||
|
if(PEAR::isError($c)) return $c;
|
||||||
|
}
|
||||||
|
$userid = $this->getSubjId($login);
|
||||||
|
$r = $this->dbc->query("INSERT INTO {$this->sessTable} (sessid, userid, login)
|
||||||
|
VALUES ('$sessid', '$userid', '$login')");
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
$this->login = $login;
|
||||||
|
$this->userid = $userid;
|
||||||
|
$this->sessid = $sessid;
|
||||||
|
return $sessid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* logout
|
||||||
|
*
|
||||||
|
* @param sessid string
|
||||||
|
* @return true/err
|
||||||
|
**/
|
||||||
|
function logout($sessid)
|
||||||
|
{
|
||||||
|
$ct = $this->checkToken($sessid);
|
||||||
|
if($ct === FALSE)
|
||||||
|
return PEAR::raiseError('Alib::logout: not logged ($ct)', ALIBERR_NOTLOGGED, PEAR_ERROR_RETURN);
|
||||||
|
elseif(PEAR::isError($ct))
|
||||||
|
return $ct;
|
||||||
|
else{
|
||||||
|
$r = $this->dbc->query("DELETE FROM {$this->sessTable} WHERE sessid='$sessid'");
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
$this->login = NULL;
|
||||||
|
$this->userid = NULL;
|
||||||
|
$this->sessid = NULL;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checkToken
|
||||||
|
*
|
||||||
|
* @param sessid string
|
||||||
|
* @return boolean/err
|
||||||
|
**/
|
||||||
|
function checkToken($sessid)
|
||||||
|
{
|
||||||
|
$c = $this->dbc->getOne("SELECT count(*) as cnt FROM {$this->sessTable} WHERE sessid='$sessid'");
|
||||||
|
return ($c == 1 ? TRUE : (PEAR::isError($c) ? $c : FALSE ));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setToken
|
||||||
|
*
|
||||||
|
* @param sessid string
|
||||||
|
* @return boolean/err
|
||||||
|
**/
|
||||||
|
function setToken($sessid)
|
||||||
|
{
|
||||||
|
$r = checkToken($sessid);
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
if(!$r) return PEAR::raiseError("ALib::setToken: invalid token ($sessid)");
|
||||||
|
$this->sessid = $sessid;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- authorization --- */
|
||||||
|
/**
|
||||||
|
* addPerm
|
||||||
|
*
|
||||||
|
* @param sid int
|
||||||
|
* @param action string
|
||||||
|
* @param oid int
|
||||||
|
* @param type char
|
||||||
|
* @return int/err
|
||||||
|
**/
|
||||||
|
function addPerm($sid, $action, $oid, $type='A')
|
||||||
|
{
|
||||||
|
$permid = $this->dbc->nextId("{$this->permTable}_id_seq");
|
||||||
|
$r = $this->dbc->query($q = "
|
||||||
|
INSERT INTO {$this->permTable} (permid, subj, action, obj, type)
|
||||||
|
VALUES ($permid, $sid, '$action', $oid, '$type')
|
||||||
|
");
|
||||||
|
if(PEAR::isError($r)) return($r);
|
||||||
|
return $permid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* removePerm
|
||||||
|
*
|
||||||
|
* @param permid int OPT
|
||||||
|
* @param subj int OPT
|
||||||
|
* @param obj int OPT
|
||||||
|
* @return null/error
|
||||||
|
**/
|
||||||
|
function removePerm($permid=NULL, $subj=NULL, $obj=NULL)
|
||||||
|
{
|
||||||
|
return $this->dbc->query("DELETE FROM {$this->permTable} WHERE 1=1".
|
||||||
|
($permid ? " AND permid=$permid" : '').
|
||||||
|
($subj ? " AND subj=$subj" : '').
|
||||||
|
($obj ? " AND obj=$obj" : '')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checkPerm
|
||||||
|
*
|
||||||
|
* @param sid int
|
||||||
|
* @param action string
|
||||||
|
* @param oid int OPT
|
||||||
|
* @return boolean/err
|
||||||
|
**/
|
||||||
|
function checkPerm($sid, $action, $oid=NULL)
|
||||||
|
{
|
||||||
|
if(!is_numeric($sid)) return FALSE;
|
||||||
|
if(is_null($oid)) $oid = $this->getObjId($this->RootNode);
|
||||||
|
if(PEAR::isError($oid)) return $oid;
|
||||||
|
if(!is_numeric($oid)) return FALSE;
|
||||||
|
// query elements
|
||||||
|
$q_flds = "m.level as S_lvl, p.subj, s.login, action, p.type, p.obj";
|
||||||
|
$q_from = "{$this->subjTable} s, {$this->permTable} p";
|
||||||
|
$q_join = "LEFT JOIN {$this->smembTable} m ON p.subj=m.gid ";
|
||||||
|
$q_cond = "p.action in('_all', '$action') AND (m.uid=$sid OR p.subj=$sid) AND s.id=p.subj";
|
||||||
|
$q_ordb = "ORDER BY S_lvl, action, p.type DESC"; // action ASC order is hack for lower priority of '_all'
|
||||||
|
$qc0 = $q_cond;
|
||||||
|
// test if object is class:
|
||||||
|
$iscls = $this->isClass($oid); if(PEAR::isError($iscls)) return $iscls;
|
||||||
|
if($iscls){
|
||||||
|
$q_from .= ", {$this->classTable} c";
|
||||||
|
$q_cond .= " AND c.id=p.obj AND c.id=$oid";
|
||||||
|
}else{
|
||||||
|
// object is normal node => path search => retrieve L/R values for oid:
|
||||||
|
$r1 = $this->dbc->getRow("SELECT lft, rgt, level FROM {$this->treeTable} WHERE id=$oid");
|
||||||
|
if(is_null($r1))
|
||||||
|
return PEAR::raiseError('Alib::checkPerm: object not exists', ALIBERR_NOTEXISTS, PEAR_ERROR_RETURN);
|
||||||
|
if(PEAR::isError($r1)) return($r1);
|
||||||
|
// fetch all path to oid + join with perms
|
||||||
|
$q_flds .= ", t.name, ({$r1['level']}-t.level)as T_lvl";
|
||||||
|
$q_from = "{$this->treeTable} t, ".$q_from;
|
||||||
|
$q_cond .= " AND t.id=p.obj AND t.lft<={$r1['lft']} AND t.rgt>={$r1['rgt']}";
|
||||||
|
$q_ordb = "ORDER BY T_lvl, S_lvl, action, p.type DESC"; // action ASC order is hack for lower priority of '_all'
|
||||||
|
}
|
||||||
|
$query="SELECT $q_flds FROM $q_from $q_join WHERE $q_cond $q_ordb";
|
||||||
|
$r2 = $this->dbc->getAll($query);
|
||||||
|
if(PEAR::isError($r2)) return($r2);
|
||||||
|
if(!$iscls && !(is_array($r2) && count($r2)>0)){
|
||||||
|
// no perm found, search in classes:
|
||||||
|
$q_from = "{$this->cmembTable} cm, ".$q_from;
|
||||||
|
$q_cond = $qc0.
|
||||||
|
" AND t.lft<={$r1['lft']} AND t.rgt>={$r1['rgt']}".
|
||||||
|
" AND cm.cid=p.obj AND cm.objid=t.id";
|
||||||
|
$query="SELECT $q_flds FROM $q_from $q_join WHERE $q_cond $q_ordb";
|
||||||
|
$r2 = $this->dbc->getAll($query);
|
||||||
|
if(PEAR::isError($r2)) return($r2);
|
||||||
|
}
|
||||||
|
// if there is row with type='A' on the top => permit
|
||||||
|
return (is_array($r2) && count($r2)>0 && $r2[0]['type']=='A');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- object tree --- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* removeObj
|
||||||
|
*
|
||||||
|
* @param id int
|
||||||
|
* @return void/error
|
||||||
|
**/
|
||||||
|
function removeObj($id)
|
||||||
|
{
|
||||||
|
$r = $this->removePerm(NULL, NULL, $id); if(PEAR::isError($r)) return $r;
|
||||||
|
return parent::removeObj($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- users/groups --- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* removeSubj
|
||||||
|
*
|
||||||
|
* @param login string
|
||||||
|
* @return void/error
|
||||||
|
**/
|
||||||
|
function removeSubj($login)
|
||||||
|
{
|
||||||
|
$uid = $this->getSubjId($login); if(PEAR::isError($uid)) return $uid;
|
||||||
|
$r = $this->removePerm(NULL, $uid); if(PEAR::isError($r)) return $r;
|
||||||
|
return parent::removeSubj($login, $uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- sessions --- */
|
||||||
|
/**
|
||||||
|
* getSessLogin
|
||||||
|
*
|
||||||
|
* @param sessid string
|
||||||
|
* @return string/error
|
||||||
|
**/
|
||||||
|
function getSessLogin($sessid)
|
||||||
|
{
|
||||||
|
return $this->dbc->getOne("
|
||||||
|
SELECT login FROM {$this->sessTable} WHERE sessid='$sessid'");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getSessUserId
|
||||||
|
*
|
||||||
|
* @param sessid string
|
||||||
|
* @return int/error
|
||||||
|
**/
|
||||||
|
function getSessUserId($sessid)
|
||||||
|
{
|
||||||
|
return $this->dbc->getOne("
|
||||||
|
SELECT userid FROM {$this->sessTable} WHERE sessid='$sessid'");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- info methods: --- */
|
||||||
|
/**
|
||||||
|
* getObjPerms
|
||||||
|
*
|
||||||
|
* @param id int
|
||||||
|
* @return array/null/err
|
||||||
|
**/
|
||||||
|
function getObjPerms($id)
|
||||||
|
{
|
||||||
|
return $this->dbc->getAll("
|
||||||
|
SELECT s.login, p.* FROM {$this->permTable} p, {$this->subjTable} s
|
||||||
|
WHERE s.id=p.subj AND p.obj=$id");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getSubjPerms
|
||||||
|
*
|
||||||
|
* @param sid int
|
||||||
|
* @return array
|
||||||
|
**/
|
||||||
|
function getSubjPerms($sid)
|
||||||
|
{
|
||||||
|
$a1 = $this->dbc->getAll("
|
||||||
|
SELECT t.name, t.type as otype , p.* FROM {$this->permTable} p, {$this->treeTable} t
|
||||||
|
WHERE t.id=p.obj AND p.subj=$sid");
|
||||||
|
if(PEAR::isError($a1)) return $a1;
|
||||||
|
$a2 = $this->dbc->getAll("
|
||||||
|
SELECT c.cname as name, 'C'as otype, p.* FROM {$this->permTable} p, {$this->classTable} c
|
||||||
|
WHERE c.id=p.obj AND p.subj=$sid");
|
||||||
|
if(PEAR::isError($a2)) return $a2;
|
||||||
|
return array_merge($a1, $a2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- info methods related to application structure: --- */
|
||||||
|
/* (this part should be added/rewritten to allow defining/modifying/using application structure) */
|
||||||
|
/* (only very simple structure definition - in config - supported now) */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getAllActions
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
**/
|
||||||
|
function getAllActions()
|
||||||
|
{
|
||||||
|
return $this->config['allActions'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getAllowedActions
|
||||||
|
*
|
||||||
|
* @param type string
|
||||||
|
* @return array
|
||||||
|
**/
|
||||||
|
function getAllowedActions($type)
|
||||||
|
{
|
||||||
|
return $this->config['allowedActions'][$type];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ========== test and debug methods: ========== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dumpPerms
|
||||||
|
*
|
||||||
|
* @param indstr string // indentation string
|
||||||
|
* @param ind string // aktual indentation
|
||||||
|
* @return string
|
||||||
|
**/
|
||||||
|
function dumpPerms($indstr=' ', $ind='')
|
||||||
|
{
|
||||||
|
$r = $ind.join(', ', array_map(create_function('$v', 'return "{$v[\'action\']}/{$v[\'type\']}";'),
|
||||||
|
$this->dbc->getAll("SELECT action, type FROM {$this->permTable}")
|
||||||
|
))."\n";
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deleteData
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function deleteData()
|
||||||
|
{
|
||||||
|
$this->dbc->query("DELETE FROM {$this->permTable}");
|
||||||
|
parent::deleteData();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* testData
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
**/
|
||||||
|
function testData()
|
||||||
|
{
|
||||||
|
parent::testData();
|
||||||
|
$t =& $this->tdata['tree'];
|
||||||
|
$c =& $this->tdata['classes'];
|
||||||
|
$s =& $this->tdata['subjects'];
|
||||||
|
$o[] = $this->addPerm($s[0], '_all', $t[0], 'A');
|
||||||
|
$o[] = $this->addPerm($s[1], '_all', $t[4], 'A');
|
||||||
|
$o[] = $this->addPerm($s[1], '_all', $t[7], 'D');
|
||||||
|
# $o[] = $this->addPerm($s[2], 'addChilds', $t[6], 'A');
|
||||||
|
$o[] = $this->addPerm($s[2], 'read', $t[5], 'A');
|
||||||
|
$o[] = $this->addPerm($s[2], 'edit', $t[6], 'A');
|
||||||
|
$o[] = $this->addPerm($s[3], 'read', $c[0], 'A');
|
||||||
|
$o[] = $this->addPerm($s[4], 'editPerms', $c[1], 'A');
|
||||||
|
$o[] = $this->addPerm($s[4], 'editPerms', $t[7], 'D');
|
||||||
|
|
||||||
|
$o[] = $this->addPerm($s[1], 'addChilds', $t[3], 'A');
|
||||||
|
$o[] = $this->addPerm($s[1], 'addChilds', $t[1], 'A');
|
||||||
|
$o[] = $this->addPerm($s[5], 'addChilds', $t[3], 'A');
|
||||||
|
$o[] = $this->addPerm($s[5], 'addChilds', $t[1], 'A');
|
||||||
|
$o[] = $this->addPerm($s[6], 'addChilds', $t[3], 'A');
|
||||||
|
$o[] = $this->addPerm($s[6], 'addChilds', $t[1], 'A');
|
||||||
|
$o[] = $this->addPerm($s[7], 'addChilds', $t[3], 'A');
|
||||||
|
$o[] = $this->addPerm($s[7], 'addChilds', $t[1], 'A');
|
||||||
|
$this->tdata['perms'] = $o;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test
|
||||||
|
*
|
||||||
|
* @return boolean/error
|
||||||
|
**/
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
if(PEAR::isError($p = parent::test())) return $p;
|
||||||
|
$this->deleteData();
|
||||||
|
$this->testData();
|
||||||
|
$this->test_correct = "_all/A, _all/A, _all/D, read/A, edit/A, read/A, editPerms/A, editPerms/D, addChilds/A, addChilds/A, addChilds/A, addChilds/A, addChilds/A, addChilds/A, addChilds/A, addChilds/A\nno, yes\n";
|
||||||
|
$this->test_dump = $this->dumpPerms().
|
||||||
|
($this->checkPerm($this->tdata['subjects'][1], 'edit', $this->tdata['tree'][7])? 'yes':'no').", ".
|
||||||
|
($this->checkPerm($this->tdata['subjects'][2], 'read', $this->tdata['tree'][5])? 'yes':'no')."\n"
|
||||||
|
;
|
||||||
|
$this->removePerm($this->tdata['perms'][1]);
|
||||||
|
$this->removePerm($this->tdata['perms'][3]);
|
||||||
|
$this->test_correct .= "_all/A, _all/D, edit/A, read/A, editPerms/A, editPerms/D, addChilds/A, addChilds/A, addChilds/A, addChilds/A, addChilds/A, addChilds/A, addChilds/A, addChilds/A\n";
|
||||||
|
$this->test_dump .= $this->dumpPerms();
|
||||||
|
$this->deleteData();
|
||||||
|
if($this->test_dump==$this->test_correct){ $this->test_log.="alib: OK\n"; return TRUE; }
|
||||||
|
else return PEAR::raiseError('Alib::test', 1, PEAR_ERROR_DIE, '%s'.
|
||||||
|
"<pre>\ncorrect:\n{$this->test_correct}\ndump:\n{$this->test_dump}\n</pre>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* install - create tables + initialize
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function install()
|
||||||
|
{
|
||||||
|
parent::install();
|
||||||
|
$this->dbc->query("CREATE TABLE {$this->permTable} (
|
||||||
|
permid int not null,
|
||||||
|
subj int,
|
||||||
|
action varchar(20),
|
||||||
|
obj int,
|
||||||
|
type char(1)
|
||||||
|
)");
|
||||||
|
$this->dbc->query("CREATE UNIQUE INDEX {$this->permTable}_permid_idx on {$this->permTable} (permid)");
|
||||||
|
$this->dbc->query("CREATE INDEX {$this->permTable}_subj_obj_idx on {$this->permTable} (subj, obj)");
|
||||||
|
$this->dbc->createSequence("{$this->permTable}_id_seq");
|
||||||
|
|
||||||
|
$this->dbc->query("CREATE TABLE {$this->sessTable} (
|
||||||
|
sessid char(32) not null,
|
||||||
|
userid int,
|
||||||
|
login varchar(255),
|
||||||
|
ts timestamp
|
||||||
|
)");
|
||||||
|
$this->dbc->query("CREATE UNIQUE INDEX {$this->sessTable}_sessid_idx on {$this->sessTable} (sessid)");
|
||||||
|
$this->dbc->query("CREATE INDEX {$this->sessTable}_userid_idx on {$this->sessTable} (userid)");
|
||||||
|
$this->dbc->query("CREATE INDEX {$this->sessTable}_login_idx on {$this->sessTable} (login)");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* uninstall
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function uninstall()
|
||||||
|
{
|
||||||
|
$this->dbc->query("DROP TABLE {$this->permTable}");
|
||||||
|
$this->dbc->dropSequence("{$this->permTable}_id_seq");
|
||||||
|
$this->dbc->query("DROP TABLE {$this->sessTable}");
|
||||||
|
parent::uninstall();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,265 @@
|
||||||
|
<?php
|
||||||
|
// $Id: class.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ObjClass class
|
||||||
|
*
|
||||||
|
* class for 'object classes' handling - i.e. groups of object in tree
|
||||||
|
* @parent Mtree
|
||||||
|
**/
|
||||||
|
require_once"mtree.php";
|
||||||
|
|
||||||
|
class ObjClasses extends Mtree{
|
||||||
|
var $classTable;
|
||||||
|
var $cmembTable;
|
||||||
|
/** ObjClasses - constructor
|
||||||
|
*
|
||||||
|
* @param dbc object
|
||||||
|
* @param config array
|
||||||
|
* @return this
|
||||||
|
**/
|
||||||
|
function ObjClasses(&$dbc, $config)
|
||||||
|
{
|
||||||
|
parent::MTree(&$dbc, $config);
|
||||||
|
$this->classTable = $config['tblNamePrefix'].'classes';
|
||||||
|
$this->cmembTable = $config['tblNamePrefix'].'cmemb';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== public methods: ========== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addClass
|
||||||
|
*
|
||||||
|
* @param cname string
|
||||||
|
* @return id/error
|
||||||
|
**/
|
||||||
|
function addClass($cname)
|
||||||
|
{
|
||||||
|
$id = $this->dbc->nextId("{$this->treeTable}_id_seq"); if(PEAR::isError($id)) return $id;
|
||||||
|
$r = $this->dbc->query("
|
||||||
|
INSERT INTO {$this->classTable} (id, cname)
|
||||||
|
VALUES ($id, '$cname')
|
||||||
|
");
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
return $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* removeClass
|
||||||
|
*
|
||||||
|
* @param cname string
|
||||||
|
* @return boolean/err
|
||||||
|
**/
|
||||||
|
function removeClass($cname)
|
||||||
|
{
|
||||||
|
$cid = $this->getClassId($cname); if(PEAR::isError($cid)) return($cid);
|
||||||
|
return $this->removeClassById($cid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* removeClassById
|
||||||
|
*
|
||||||
|
* @param cid int
|
||||||
|
* @return boolean/err
|
||||||
|
**/
|
||||||
|
function removeClassById($cid)
|
||||||
|
{
|
||||||
|
$r = $this->dbc->query("DELETE FROM {$this->cmembTable} WHERE cid=$cid");
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
$r = $this->dbc->query("DELETE FROM {$this->classTable} WHERE id=$cid");
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addObj2Class
|
||||||
|
*
|
||||||
|
* @param cid int
|
||||||
|
* @param oid int
|
||||||
|
* @return boolean/err
|
||||||
|
**/
|
||||||
|
function addObj2Class($cid, $oid)
|
||||||
|
{
|
||||||
|
$r = $this->dbc->query("INSERT INTO {$this->cmembTable} (cid, objid) VALUES ($cid, $oid)");
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* removeObjFromClass
|
||||||
|
*
|
||||||
|
* @param oid int
|
||||||
|
* @param cid int OPT // if not specified, remove obj from all classes
|
||||||
|
* @return boolean/err
|
||||||
|
**/
|
||||||
|
function removeObjFromClass($oid, $cid=NULL)
|
||||||
|
{
|
||||||
|
$r = $this->dbc->query("DELETE FROM {$this->cmembTable} WHERE objid=$oid".(is_null($cid)? '':" AND cid=$cid"));
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- object tree --- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* removeObj
|
||||||
|
*
|
||||||
|
* @param id int
|
||||||
|
* @return boolean/err
|
||||||
|
**/
|
||||||
|
function removeObj($id)
|
||||||
|
{
|
||||||
|
$r = $this->removeObjFromClass($id); if(PEAR::isError($r)) return $r;
|
||||||
|
return parent::removeObj($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- info methods: --- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getClassId
|
||||||
|
*
|
||||||
|
* @param cname string
|
||||||
|
* @return int/err
|
||||||
|
**/
|
||||||
|
function getClassId($cname)
|
||||||
|
{
|
||||||
|
return $this->dbc->getOne($query = "SELECT id FROM {$this->classTable} WHERE cname='$cname'");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getClassName
|
||||||
|
*
|
||||||
|
* @param id int
|
||||||
|
* @return string/err
|
||||||
|
**/
|
||||||
|
function getClassName($id)
|
||||||
|
{
|
||||||
|
return $this->dbc->getOne($query = "SELECT cname FROM {$this->classTable} WHERE id=$id");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* isClass
|
||||||
|
*
|
||||||
|
* @param id int
|
||||||
|
* @return boolean/err
|
||||||
|
**/
|
||||||
|
function isClass($id)
|
||||||
|
{
|
||||||
|
$r = $this->dbc->getOne("SELECT count(*) FROM {$this->classTable} WHERE id=$id");
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
return ($r > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getClasses
|
||||||
|
*
|
||||||
|
* @return array/err
|
||||||
|
**/
|
||||||
|
function getClasses()
|
||||||
|
{
|
||||||
|
return $this->dbc->getAll("SELECT * FROM {$this->classTable}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* listClass
|
||||||
|
*
|
||||||
|
* @param id int
|
||||||
|
* @return array/err
|
||||||
|
**/
|
||||||
|
function listClass($id)
|
||||||
|
{
|
||||||
|
return $this->dbc->getAll("SELECT t.* FROM {$this->cmembTable} cm, {$this->treeTable} t
|
||||||
|
WHERE cm.cid=$id AND cm.objid=t.id");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== test and debug methods: ========== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dumpClasses
|
||||||
|
*
|
||||||
|
* @param id int
|
||||||
|
* @param indstr string // indentation string
|
||||||
|
* @param ind string // aktual indentation
|
||||||
|
* @return string
|
||||||
|
**/
|
||||||
|
function dumpClasses($indstr=' ', $ind='')
|
||||||
|
{
|
||||||
|
$r = $ind.join(', ', array_map(create_function('$v', 'return "{$v[\'cname\']} ({$v[\'cnt\']})";'),
|
||||||
|
$this->dbc->getAll("
|
||||||
|
SELECT cname, count(cm.objid)as cnt FROM {$this->classTable} c
|
||||||
|
LEFT JOIN {$this->cmembTable} cm ON c.id=cm.cid
|
||||||
|
GROUP BY cname, c.id ORDER BY c.id
|
||||||
|
")
|
||||||
|
))."\n";
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testData
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
function deleteData()
|
||||||
|
{
|
||||||
|
$this->dbc->query("DELETE FROM {$this->cmembTable}");
|
||||||
|
$this->dbc->query("DELETE FROM {$this->classTable}");
|
||||||
|
parent::deleteData();
|
||||||
|
}
|
||||||
|
function testData()
|
||||||
|
{
|
||||||
|
parent::testData();
|
||||||
|
$o[] = $this->addClass('Sections b');
|
||||||
|
$o[] = $this->addClass('Class 2');
|
||||||
|
$this->addObj2Class($o[1], $this->tdata['tree'][4]);
|
||||||
|
$this->addObj2Class($o[1], $this->tdata['tree'][9]);
|
||||||
|
$this->tdata['classes'] = $o;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
if(PEAR::isError($p = parent::test())) return $p;
|
||||||
|
$this->deleteData();
|
||||||
|
$this->testData();
|
||||||
|
$this->test_correct = "Sections b (0), Class 2 (2)\n";
|
||||||
|
$this->test_dump = $this->dumpClasses();
|
||||||
|
$this->removeClass('Sections b');
|
||||||
|
$this->removeObjFromClass($this->tdata['tree'][4], $this->tdata['classes'][1]);
|
||||||
|
$this->test_correct .= "Class 2 (1)\n";
|
||||||
|
$this->test_dump .= $this->dumpClasses();
|
||||||
|
$this->deleteData();
|
||||||
|
if($this->test_dump==$this->test_correct){ $this->test_log.="class: OK\n"; return TRUE; }
|
||||||
|
else return PEAR::raiseError('ObjClasses::test:', 1, PEAR_ERROR_DIE, '%s'.
|
||||||
|
"<pre>\ncorrect:\n{$this->test_correct}\ndump:\n{$this->test_dump}\n</pre>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* install - create tables + initialize
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
function install()
|
||||||
|
{
|
||||||
|
parent::install();
|
||||||
|
$this->dbc->query("CREATE TABLE {$this->classTable} (
|
||||||
|
id int not null,
|
||||||
|
cname varchar(20)
|
||||||
|
)");
|
||||||
|
$this->dbc->query("CREATE UNIQUE INDEX {$this->classTable}_id_idx on {$this->classTable} (id)");
|
||||||
|
$this->dbc->query("CREATE UNIQUE INDEX {$this->classTable}_cname_idx on {$this->classTable} (cname)");
|
||||||
|
|
||||||
|
$this->dbc->query("CREATE TABLE {$this->cmembTable} (
|
||||||
|
objid int not null,
|
||||||
|
cid int not null
|
||||||
|
)");
|
||||||
|
$this->dbc->query("CREATE UNIQUE INDEX {$this->cmembTable}_idx on {$this->cmembTable} (objid, cid)");
|
||||||
|
}
|
||||||
|
function uninstall()
|
||||||
|
{
|
||||||
|
$this->dbc->query("DROP TABLE {$this->classTable}");
|
||||||
|
$this->dbc->query("DROP TABLE {$this->cmembTable}");
|
||||||
|
parent::uninstall();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,126 @@
|
||||||
|
<?php
|
||||||
|
// $Id: alibExCls.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
require_once"alib_h.php";
|
||||||
|
require_once"alibExTestAuth.php";
|
||||||
|
|
||||||
|
if(isset($_GET['id']) && is_numeric($_GET['id'])){ $id = $_GET['id']; $list=false; }
|
||||||
|
else $list=true;
|
||||||
|
|
||||||
|
// prefill data structure for template
|
||||||
|
if($list){
|
||||||
|
$d = array(
|
||||||
|
'cls' => $alib->getClasses(),
|
||||||
|
'loggedAs' => $login,
|
||||||
|
);
|
||||||
|
}else{
|
||||||
|
$d = array(
|
||||||
|
'rows' => $alib->listClass($id),
|
||||||
|
'id' => $id,
|
||||||
|
'loggedAs' => $login,
|
||||||
|
'cname' => $alib->getClassName($id),
|
||||||
|
'cls' => $alib->getClasses(),
|
||||||
|
'objs' => $alib->getSubTree(null, true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$d['msg'] = $_SESSION['alertMsg']; unset($_SESSION['alertMsg']);
|
||||||
|
|
||||||
|
require_once"alib_f.php";
|
||||||
|
// template follows:
|
||||||
|
?>
|
||||||
|
<html><head>
|
||||||
|
<title>Alib - class editor</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
|
<link rel="stylesheet" type="text/css" href="default.css">
|
||||||
|
<style type="text/css">
|
||||||
|
<!--
|
||||||
|
#menu { float:right; margin-right:1em; border:1px solid black; background-color:#ddd; padding:2px 1ex; }
|
||||||
|
#parent, #parent a { background-color:#888; font-weight:bold; color:white; }
|
||||||
|
#tree { width:60%; }
|
||||||
|
-->
|
||||||
|
</style>
|
||||||
|
</head><body>
|
||||||
|
<div id="menu">
|
||||||
|
Logged as: <span class="b"><?php echo$d['loggedAs']?></span><br>
|
||||||
|
<a href="alibHttp.php?act=logout">logout</a><br>
|
||||||
|
<a href="alibExTree.php">Tree editor</a><br>
|
||||||
|
<?php if(!$list){?>
|
||||||
|
<a href="alibExPerms.php?id=<?php echo$d['id']?>">Perm editor</a><br>
|
||||||
|
<?php }?>
|
||||||
|
<a href="alibExSubj.php">User/Group editor</a><br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1>Class editor</h1>
|
||||||
|
|
||||||
|
<?php if($list){?>
|
||||||
|
<h3>All classes:</h3>
|
||||||
|
<table id="tree" border="0" cellpadding="5">
|
||||||
|
<?php if(is_array($d['cls'])&&count($d['cls'])>0) foreach($d['cls'] as $k=>$c) {?>
|
||||||
|
<tr class="<?php echo(($o=1-$o) ? 'odd' : 'ev')?>">
|
||||||
|
<td><?php echo$c['id']?></td>
|
||||||
|
<td class="b"><a href="alibExCls.php?id=<?php echo$c['id']?>"><?php echo$c['cname']?></a></td>
|
||||||
|
<?php # <td><?php echo$c['cond']? ></td>?>
|
||||||
|
<td>
|
||||||
|
<a class="lnkbutt" href="alibHttp.php?act=removeClass&id=<?php echo$c['id']?>">delete</a>
|
||||||
|
<a class="lnkbutt" href="alibExPerms.php?id=<?php echo$c['id']?>&reid=<?php echo$d['id']?>">permissions</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php }else{?>
|
||||||
|
<tr class="odd"><td colspan="3">none</td></tr>
|
||||||
|
<?php }?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<form action="alibHttp.php" method="post">
|
||||||
|
Add class with name
|
||||||
|
<input type="text" name="name" value="" size="10">
|
||||||
|
<input type="hidden" name="act" value="addClass">
|
||||||
|
<input type="submit" value="Do it!">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?php }else{?>
|
||||||
|
|
||||||
|
<h2>Objects in class <?php echo$d['cname']?>:</h2>
|
||||||
|
|
||||||
|
<table id="tree" border="0" cellpadding="5">
|
||||||
|
<tr id="parent">
|
||||||
|
<td colspan="4">
|
||||||
|
<a href="alibExCls.php">All classes</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php if(is_array($d['rows'])&&count($d['rows'])>0) foreach($d['rows'] as $k=>$row) {?>
|
||||||
|
<tr class="<?php echo(($o=1-$o) ? 'odd' : 'ev')?>">
|
||||||
|
<td><?php echo$row['id']?></td>
|
||||||
|
<td class="b"><a href="alibExTree.php?id=<?php echo$row['id']?>"><?php echo$row['name']?></a></td>
|
||||||
|
<td><?php echo$row['type']?></td>
|
||||||
|
<td>
|
||||||
|
<a class="lnkbutt" href="alibHttp.php?act=removeObjFromClass&oid=<?php echo$row['id']?>&id=<?php echo$d['id']?>">removeFromClass</a>
|
||||||
|
<?php /*?> <a class="lnkbutt" href="alibExPerms.php?id=<?php echo$row['id']?>&reid=<?php echo$d['id']?>">permissions</a><?php */?>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php }else{?>
|
||||||
|
<tr class="odd"><td colspan="4">none</td></tr>
|
||||||
|
<?php }?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<form action="alibHttp.php" method="post">
|
||||||
|
Add object
|
||||||
|
<select name="oid">
|
||||||
|
<?php if(is_array($d['objs'])) foreach($d['objs'] as $k=>$row) {?>
|
||||||
|
<option value="<?php echo$row['id']?>"><?php echo str_repeat(' ', $row['level'])?><?php echo$row['name']?></option>
|
||||||
|
<?php }?>
|
||||||
|
</select>
|
||||||
|
to class <?php echo$d['cname']?>
|
||||||
|
<input type="hidden" name="act" value="addObj2Class">
|
||||||
|
<input type="hidden" name="id" value="<?php echo$d['id']?>">
|
||||||
|
<input type="submit" value="Do it!">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?php }?>
|
||||||
|
|
||||||
|
<?php if($d['msg']){?>
|
||||||
|
<script type="text/javascript">
|
||||||
|
<!--
|
||||||
|
alert('<?php echo$d['msg']?>');
|
||||||
|
-->
|
||||||
|
</script>
|
||||||
|
<?php }?>
|
||||||
|
</body></html>
|
|
@ -0,0 +1,112 @@
|
||||||
|
<?php
|
||||||
|
// $Id: alibExLogin.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
require_once"alib_h.php";
|
||||||
|
|
||||||
|
// prefill data structure for template
|
||||||
|
$d = array(
|
||||||
|
'users' => $alib->getSubjects(),
|
||||||
|
'actions' => $alib->getAllActions(),
|
||||||
|
'objects' => $alib->getAllObjects(),
|
||||||
|
'msg' => $_SESSION['alertMsg']
|
||||||
|
);
|
||||||
|
unset($_SESSION['alertMsg']);
|
||||||
|
|
||||||
|
// forms prefill:
|
||||||
|
if(is_array($_SESSION['lastPost'])) $d = array_merge($d, array(
|
||||||
|
'lastSubj' => $_SESSION['lastPost']['subj'],
|
||||||
|
'lastAction'=> $_SESSION['lastPost']['permAction'],
|
||||||
|
'lastObj' => $_SESSION['lastPost']['obj']
|
||||||
|
));
|
||||||
|
unset($_SESSION['lastPost']);
|
||||||
|
|
||||||
|
#header("Content-type: text/plain"); print_r($d); exit;
|
||||||
|
require_once"alib_f.php";
|
||||||
|
// template follows:
|
||||||
|
?>
|
||||||
|
<html><head>
|
||||||
|
<title>Alib - example login</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="default.css">
|
||||||
|
<style type="text/css">
|
||||||
|
<!--
|
||||||
|
#help { float:right; margin-right:1em; border:1px solid black; background-color:#ddd; padding:2px 1ex; }
|
||||||
|
-->
|
||||||
|
</style>
|
||||||
|
<script type="text/javascript">
|
||||||
|
<!--
|
||||||
|
function preloadLogin(u, p)
|
||||||
|
{
|
||||||
|
var f=document.getElementById('loginform');
|
||||||
|
f.login.value=u;
|
||||||
|
f.pass.value=p;
|
||||||
|
}
|
||||||
|
-->
|
||||||
|
</script>
|
||||||
|
</head><body>
|
||||||
|
|
||||||
|
<div id="help">
|
||||||
|
Test accounts/pass:
|
||||||
|
<ul style="margin:1px 0px">
|
||||||
|
<li><a href="javascript:preloadLogin('root', 'q')">root/q</a></li>
|
||||||
|
<li><a href="javascript:preloadLogin('test1', 'a')">test1/a</a></li>
|
||||||
|
<li><a href="javascript:preloadLogin('test2', 'a')">test2/a</a></li>
|
||||||
|
<li><a href="javascript:preloadLogin('test3', 'a')">test3/a</a></li>
|
||||||
|
<li><a href="javascript:preloadLogin('test4', 'a')">test4/a</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1>ALib - tests/example</h1>
|
||||||
|
|
||||||
|
<form action="alibHttp.php" method="post" id="loginform">
|
||||||
|
<table>
|
||||||
|
<tr><td>Login:</td><td><input type="text" name="login"></td></tr>
|
||||||
|
<tr><td>Password:</td><td><input type="password" name="pass"></td></tr>
|
||||||
|
<tr><td colspan="2"><input type="hidden" name="act" value="login">
|
||||||
|
<input type="submit" value="Go!">
|
||||||
|
</td></tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<form action="alibHttp.php" method="post">
|
||||||
|
Permission test:<br>
|
||||||
|
Subject: <select name="subj">
|
||||||
|
<?php if(is_array($d['users'])) foreach($d['users'] as $k=>$u) {?>
|
||||||
|
<option value="<?php echo$u['id']?>"<?php echo($d['lastSubj']==$u['id'] ? ' selected':'')?>><?php echo$u['login']?></option>
|
||||||
|
<?php }?>
|
||||||
|
</select>
|
||||||
|
action: <select name="permAction">
|
||||||
|
<?php if(is_array($d['actions'])) foreach($d['actions'] as $k=>$a) {?>
|
||||||
|
<option value="<?php echo$a?>"<?php echo($d['lastAction']==$a ? ' selected':'')?>><?php echo$a?></option>
|
||||||
|
<?php }?>
|
||||||
|
</select>
|
||||||
|
object: <select name="obj">
|
||||||
|
<?php if(is_array($d['objects'])) foreach($d['objects'] as $k=>$o) {?>
|
||||||
|
<option value="<?php echo$o['id']?>"<?php echo($d['lastObj']==$o['id'] ? ' selected':'')?>><?php echo$o['name']?></option>
|
||||||
|
<?php }?>
|
||||||
|
</select>
|
||||||
|
<input type="hidden" name="act" value="checkPerm">
|
||||||
|
<input type="submit" value="Go!">
|
||||||
|
</form>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<form action="alibExPMatrix.php" method="get">
|
||||||
|
Permission matrix for subject: <select name="subj">
|
||||||
|
<?php if(is_array($d['users'])) foreach($d['users'] as $k=>$u) {?>
|
||||||
|
<option value="<?php echo$u['id']?>"<?php echo($d['lastSubj']==$u['id'] ? ' selected':'')?>><?php echo$u['login']?></option>
|
||||||
|
<?php }?>
|
||||||
|
</select>
|
||||||
|
<input type="submit" value="Go!">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<a href="../install.php?ak=inst">reset db + test all</a><br/>
|
||||||
|
|
||||||
|
<?php if($d['msg']){ //error message printing: ?>
|
||||||
|
<script type="text/javascript">
|
||||||
|
<!--
|
||||||
|
alert('<?php echo$d['msg']?>');
|
||||||
|
-->
|
||||||
|
</script>
|
||||||
|
<?php }?>
|
||||||
|
<body></html>
|
|
@ -0,0 +1,75 @@
|
||||||
|
<?php
|
||||||
|
// $Id: alibExPList.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
require_once"alib_h.php";
|
||||||
|
require_once"alibExTestAuth.php";
|
||||||
|
|
||||||
|
if(isset($_GET['id']) && is_numeric($_GET['id'])){ $id = $_GET['id']; }
|
||||||
|
else $id=1;
|
||||||
|
|
||||||
|
// prefill data structure for template
|
||||||
|
$d = array(
|
||||||
|
'rows' => $alib->getSubjPerms($id),
|
||||||
|
'id' => $id,
|
||||||
|
'loggedAs' => $login,
|
||||||
|
'actions' => $alib->getAllActions(),
|
||||||
|
'name' => $alib->getSubjName($id)
|
||||||
|
);
|
||||||
|
$d['msg'] = $_SESSION['alertMsg']; unset($_SESSION['alertMsg']);
|
||||||
|
|
||||||
|
require_once"alib_f.php";
|
||||||
|
// template follows:
|
||||||
|
?>
|
||||||
|
<html><head>
|
||||||
|
<title>Alib - permission list</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
|
<link rel="stylesheet" type="text/css" href="default.css">
|
||||||
|
<style type="text/css">
|
||||||
|
<!--
|
||||||
|
#menu { float:right; margin-right:1em; border:1px solid black; background-color:#ddd; padding:2px 1ex; }
|
||||||
|
#parent, #parent a { background-color:#888; font-weight:bold; color:white; }
|
||||||
|
#tree { width:60%; }
|
||||||
|
-->
|
||||||
|
</style>
|
||||||
|
</head><body>
|
||||||
|
<div id="menu">
|
||||||
|
Logged as: <span class="b"><?php echo$d['loggedAs']?></span><br>
|
||||||
|
<a href="alibHttp.php?act=logout">logout</a><br>
|
||||||
|
<a href="alibExTree.php">Tree editor</a><br>
|
||||||
|
<a href="alibExCls.php">Class editor</a><br>
|
||||||
|
<a href="alibExSubj.php">User/group editor</a><br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1>Subject permission list</h1>
|
||||||
|
|
||||||
|
<h2>Permissions for subject <?php echo$d['name']?>:</h2>
|
||||||
|
|
||||||
|
<table id="tree" border="0" cellpadding="5">
|
||||||
|
<tr id="parent">
|
||||||
|
<td colspan="4">
|
||||||
|
<a href="alibExSubj.php">All subjects</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php if(is_array($d['rows'])&&count($d['rows'])>0) foreach($d['rows'] as $k=>$row) {?>
|
||||||
|
<tr class="<?php echo(($o=1-$o) ? 'odd' : 'ev')?>">
|
||||||
|
<td><a class="b" href="alibExPerms.php?id=<?php echo$row['obj']?>"><?php echo$row['name']?></a>
|
||||||
|
(<?php echo($row['otype']=='C' ? 'class' : $row['otype'])?>)
|
||||||
|
</td
|
||||||
|
<td class="b"><?php echo$row['action']?></td>
|
||||||
|
<td><?php echo($row['type']=='A' ? 'allow' : ($row['type']=='D' ? '<b>deny</b>' : $row['type']))?></td>
|
||||||
|
<td>
|
||||||
|
<a class="lnkbutt" href="alibHttp.php?act=removePerm&permid=<?php echo$row['permid']?>&oid=<?php echo$row['obj']?>&reurl=plist&reid=<?php echo$d['id']?>">delete</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php }else{?>
|
||||||
|
<tr class="odd"><td colspan="4">none</td></tr>
|
||||||
|
<?php }?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<?php if($d['msg']){?>
|
||||||
|
<script type="text/javascript">
|
||||||
|
<!--
|
||||||
|
alert('<?php echo$d['msg']?>');
|
||||||
|
-->
|
||||||
|
</script>
|
||||||
|
<?php }?>
|
||||||
|
</body></html>
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
// $Id: alibExPMatrix.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
require_once"alib_h.php";
|
||||||
|
|
||||||
|
$sid=$_GET['subj'];
|
||||||
|
|
||||||
|
foreach($alib->getAllObjects() as $it){
|
||||||
|
$aa=array();
|
||||||
|
foreach($alib->getAllActions() as $a){
|
||||||
|
$aa[$a]=$alib->checkPerm($sid, $a, $it['id']);
|
||||||
|
# if(PEAR::isError($aa[$a])){ errCallback($aa[$a]); }
|
||||||
|
}
|
||||||
|
$m[]=array($it['name'], $aa);
|
||||||
|
}
|
||||||
|
$u=$alib->getSubjName($sid);
|
||||||
|
|
||||||
|
?>
|
||||||
|
<html><head>
|
||||||
|
<title>ALib - permission matrix</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="default.css">
|
||||||
|
</head><body>
|
||||||
|
<h2>Permission matrix</h2>
|
||||||
|
<h2>User: <?php echo$u?></h2>
|
||||||
|
<table style="border:1px solid black">
|
||||||
|
<tr class="ev"><th>object</th>
|
||||||
|
<?php foreach($alib->getAllActions() as $a){?>
|
||||||
|
<th><?php echo$a?></th>
|
||||||
|
<?php }?>
|
||||||
|
</tr>
|
||||||
|
<?php if(is_array($m)) foreach($m as $k=>$v){ list($obj, $aa)=$v;?>
|
||||||
|
<tr class="<?php echo(($o=1-$o) ? 'odd' : 'ev')?>">
|
||||||
|
<td><?php echo$obj?></td>
|
||||||
|
<?php foreach($aa as $pr){?>
|
||||||
|
<td><?php echo($pr ? 'Y' : '-')?></td>
|
||||||
|
<?php }?>
|
||||||
|
</tr>
|
||||||
|
<?php }?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<a href="javascript:back()">Back</a>
|
||||||
|
<hr>
|
||||||
|
Tree dump:
|
||||||
|
<pre><?php echo$alib->dumpTree()?></pre>
|
||||||
|
</body></html>
|
|
@ -0,0 +1,118 @@
|
||||||
|
<?php
|
||||||
|
// $Id: alibExPerms.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
require_once"alib_h.php";
|
||||||
|
require_once"alibExTestAuth.php";
|
||||||
|
|
||||||
|
if(isset($_GET['id']) && is_numeric($_GET['id'])){
|
||||||
|
$id = $_GET['id'];
|
||||||
|
}else{
|
||||||
|
$id = $alib->getRootNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// prefill data structure for template
|
||||||
|
if(!$alib->isClass($id)){
|
||||||
|
$d = array(
|
||||||
|
'path' => $alib->getPath($id, 'id,name'),
|
||||||
|
'perms' => $alib->getObjPerms($id),
|
||||||
|
'actions' => $alib->getAllowedActions($alib->getObjType($id)),
|
||||||
|
'subjects' => $alib->getSubjects(),
|
||||||
|
'id' => $id,
|
||||||
|
'loggedAs' => $login
|
||||||
|
);
|
||||||
|
}else{
|
||||||
|
$d = array(
|
||||||
|
'path' => '',
|
||||||
|
'name' => $alib->getClassName($id),
|
||||||
|
'perms' => $alib->getObjPerms($id),
|
||||||
|
'actions' => $alib->getAllowedActions('_class'),
|
||||||
|
'subjects' => $alib->getSubjects(),
|
||||||
|
'id' => $id,
|
||||||
|
'loggedAs' => $login
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$d['msg'] = $_SESSION['alertMsg']; unset($_SESSION['alertMsg']);
|
||||||
|
|
||||||
|
require_once"alib_f.php";
|
||||||
|
// template follows:
|
||||||
|
?>
|
||||||
|
<html><head>
|
||||||
|
<title>Alib - permission editor</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
|
<link rel="stylesheet" type="text/css" href="default.css">
|
||||||
|
<style type="text/css">
|
||||||
|
<!--
|
||||||
|
#menu { float:right; margin-right:1em; border:1px solid black; background-color:#ddd; padding:2px 1ex; }
|
||||||
|
#tbl { width:60%; }
|
||||||
|
-->
|
||||||
|
</style>
|
||||||
|
</head><body>
|
||||||
|
<div id="menu">
|
||||||
|
Logged as: <span class="b"><?php echo$d['loggedAs']?></span><br>
|
||||||
|
<a href="alibHttp.php?act=logout">Logout</a><br>
|
||||||
|
<?php if(is_array($d['path'])){?>
|
||||||
|
<a href="alibExTree.php?id=<?php echo$d['id']?>">Tree editor</a><br>
|
||||||
|
<?php }else{?>
|
||||||
|
<a href="alibExTree.php">Tree editor</a><br>
|
||||||
|
<?php }?>
|
||||||
|
<a href="alibExCls.php">Class editor</a><br>
|
||||||
|
<a href="alibExSubj.php">User/Group editor</a><br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1>Permission editor</h1>
|
||||||
|
<?php if(is_array($d['path'])){?>
|
||||||
|
<h2><a href="alibExTree.php?id=<?php echo$d['id']?>" title="Tree editor">Path</a>:
|
||||||
|
<?php foreach($d['path'] as $k=>$it) {?>
|
||||||
|
<a <?php if($it["id"]!=$id){?>href="?id=<?php echo $it["id"]?>"<?php }?>><?php echo$it["name"]?></a><span class="slash">/</span>
|
||||||
|
<?php }?>
|
||||||
|
<?php }else{?>Class <a href="alibExCls.php?id=<?php echo$d['id']?>"><?php echo$d['name']?></a>
|
||||||
|
<?php }?>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<table id="tbl" border="0" cellpadding="5">
|
||||||
|
<?php if(is_array($d['perms'])&&count($d['perms'])>0) foreach($d['perms'] as $k=>$row) {?>
|
||||||
|
<tr class="<?php echo(($o=1-$o) ? 'odd' : 'ev')?>">
|
||||||
|
<td class="b"><a href="alibExPList.php?id=<?php echo$row['subj']?>"><?php echo$row['login']?></a></td>
|
||||||
|
<td class="b"><?php echo$row['action']?></td>
|
||||||
|
<td><?php echo($row['type']=='A' ? 'allow' : ($row['type']=='D' ? '<b>deny</b>' : $row['type']))?></td>
|
||||||
|
<td>
|
||||||
|
<a class="lnkbutt" href="alibHttp.php?act=removePerm&permid=<?php echo$row['permid']?>&oid=<?php echo$d['id']?>&reid=<?php echo$d['id']?>">delete</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php }else{?>
|
||||||
|
<tr class="odd"><td colspan="4">none</td></tr>
|
||||||
|
<?php }?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<form action="alibHttp.php" method="post">
|
||||||
|
Add permission
|
||||||
|
<select name="allowDeny">
|
||||||
|
<option value="A">Allow</option>
|
||||||
|
<option value="D">Deny</option>
|
||||||
|
</select>
|
||||||
|
for action
|
||||||
|
<select name="permAction">
|
||||||
|
<option value="_all">all</option>
|
||||||
|
<?php if(is_array($d['actions'])) foreach($d['actions'] as $k=>$it) {?>
|
||||||
|
<option value="<?php echo$it?>"><?php echo$it?></option>
|
||||||
|
<?php }?>
|
||||||
|
</select>
|
||||||
|
to subject
|
||||||
|
<select name="subj">
|
||||||
|
<?php if(is_array($d['subjects'])) foreach($d['subjects'] as $k=>$it) {?>
|
||||||
|
<option value="<?php echo$it['id']?>"><?php echo$it['login']?></option>
|
||||||
|
<?php }?>
|
||||||
|
</select>
|
||||||
|
<input type="hidden" name="act" value="addPerm">
|
||||||
|
<input type="hidden" name="reid" value="<?php echo$d['id']?>">
|
||||||
|
<input type="hidden" name="id" value="<?php echo$d['id']?>">
|
||||||
|
<input type="submit" value="Do it!">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?php if($d['msg']){?>
|
||||||
|
<script type="text/javascript">
|
||||||
|
<!--
|
||||||
|
alert('<?php echo$d['msg']?>');
|
||||||
|
-->
|
||||||
|
</script><noscript><hr><b><?php echo$d['msg']?></b></hr></noscript>
|
||||||
|
<?php }?>
|
||||||
|
</body></html>
|
|
@ -0,0 +1,141 @@
|
||||||
|
<?php
|
||||||
|
// $Id: alibExSubj.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
require_once"alib_h.php";
|
||||||
|
require_once"alibExTestAuth.php";
|
||||||
|
|
||||||
|
if(isset($_GET['id']) && is_numeric($_GET['id'])){ $id = $_GET['id']; $list=false; }
|
||||||
|
else $list=true;
|
||||||
|
|
||||||
|
// prefill data structure for template
|
||||||
|
if($list){
|
||||||
|
$d = array(
|
||||||
|
'subj' => $alib->getSubjectsWCnt(),
|
||||||
|
'loggedAs' => $login
|
||||||
|
);
|
||||||
|
}else{
|
||||||
|
$d = array(
|
||||||
|
'rows' => $alib->listGroup($id),
|
||||||
|
'id' => $id,
|
||||||
|
'loggedAs' => $login,
|
||||||
|
'gname' => $alib->getSubjName($id),
|
||||||
|
'subj' => $alib->getSubjects()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$d['msg'] = $_SESSION['alertMsg']; unset($_SESSION['alertMsg']);
|
||||||
|
|
||||||
|
require_once"alib_f.php";
|
||||||
|
// template follows:
|
||||||
|
?>
|
||||||
|
<html><head>
|
||||||
|
<title>Alib - subjects editor</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
|
<link rel="stylesheet" type="text/css" href="default.css">
|
||||||
|
<style type="text/css">
|
||||||
|
<!--
|
||||||
|
#menu { float:right; margin-right:1em; border:1px solid black; background-color:#ddd; padding:2px 1ex; }
|
||||||
|
#parent, #parent a { background-color:#888; font-weight:bold; color:white; }
|
||||||
|
#tree { width:60%; }
|
||||||
|
-->
|
||||||
|
</style>
|
||||||
|
</head><body>
|
||||||
|
<div id="menu">
|
||||||
|
Logged as: <span class="b"><?php echo$d['loggedAs']?></span><br>
|
||||||
|
<a href="alibHttp.php?act=logout">logout</a><br>
|
||||||
|
<a href="alibExTree.php">Tree editor</a><br>
|
||||||
|
<?php if(!$list){?>
|
||||||
|
<a href="alibExPList.php?id=<?php echo$d['id']?>">Perms editor</a><br>
|
||||||
|
<?php }?>
|
||||||
|
<a href="alibExCls.php">Class editor</a><br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1>User/Group editor</h1>
|
||||||
|
|
||||||
|
<?php if($list){?>
|
||||||
|
<h3>Subjects:</h3>
|
||||||
|
<table id="tree" border="0" cellpadding="5">
|
||||||
|
<?php if(is_array($d['subj'])&&count($d['subj'])>0) foreach($d['subj'] as $k=>$c) {?>
|
||||||
|
<tr class="<?php echo(($o=1-$o) ? 'odd':'ev')?>">
|
||||||
|
<td><?php echo$c['id']?></td>
|
||||||
|
<td class="b">
|
||||||
|
<?php if($c['type']=='G'){?>
|
||||||
|
<a href="alibExSubj.php?id=<?php echo$c['id']?>"><?php echo$c['login']?></a>
|
||||||
|
<?php }else{?><?php echo$c['login']?>
|
||||||
|
<?php }?>
|
||||||
|
</td
|
||||||
|
<td><?php if($c['type']=='G'){?>(G:<?php echo$c['cnt']?>)<?php }else{?> (U)<?php }?></td>
|
||||||
|
<td>
|
||||||
|
<a class="lnkbutt" href="alibHttp.php?act=removeSubj&login=<?php echo urlencode($c['login'])?>">delete</a>
|
||||||
|
<?php /*?> <a class="lnkbutt" href="alibExPerms.php?id=<?php echo$c['id']?>&reid=<?php echo$d['id']?>">permissions</a><?php */?>
|
||||||
|
<a class="lnkbutt" href="alibExPMatrix.php?subj=<?php echo$c['id']?>">permsMatrix</a>
|
||||||
|
<a class="lnkbutt" href="alibExPList.php?id=<?php echo$c['id']?>">permsList</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php }else{?>
|
||||||
|
<tr class="odd"><td colspan="4">none</td></tr>
|
||||||
|
<?php }?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<form action="alibHttp.php" method="post">
|
||||||
|
Add subject with name: <input type="text" name="login" value="" size="10">
|
||||||
|
[and password: <input type="password" name="pass" value="" size="10">]
|
||||||
|
<input type="hidden" name="act" value="addSubj">
|
||||||
|
<input type="submit" value="Do it!">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?php }else{?>
|
||||||
|
|
||||||
|
<h2>Subjects in group <?php echo$d['gname']?>:</h2>
|
||||||
|
|
||||||
|
<table id="tree" border="0" cellpadding="5">
|
||||||
|
<tr id="parent">
|
||||||
|
<td colspan="5">
|
||||||
|
<a href="alibExSubj.php">All subjects</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php if(is_array($d['rows'])&&count($d['rows'])>0) foreach($d['rows'] as $k=>$row) {?>
|
||||||
|
<tr class="<?php echo(($o=1-$o) ? 'odd':'ev')?>">
|
||||||
|
<td><?php echo$row['id']?></td>
|
||||||
|
<td class="b">
|
||||||
|
<?php if($row['type']=='G'){?>
|
||||||
|
<a href="alibExSubj.php?id=<?php echo$row['id']?>"><?php echo$row['login']?></a>
|
||||||
|
<?php }else{?><?php echo$row['login']?>
|
||||||
|
<?php }?>
|
||||||
|
</td
|
||||||
|
<td><?php if($row['type']=='G'){?> (G)<?php }else{?> (U)<?php }?></td>
|
||||||
|
<td>
|
||||||
|
<a class="lnkbutt"
|
||||||
|
href="alibHttp.php?act=removeSubjFromGr&login=<?php echo urlencode($row['login'])?>&gname=<?php echo urlencode($d['gname'])?>&reid=<?php echo$d['id']?>">
|
||||||
|
removeFromGroup
|
||||||
|
</a>
|
||||||
|
<?php /*?> <a class="lnkbutt" href="alibExPerms.php?id=<?php echo$row['id']?>&reid=<?php echo$d['id']?>">permissions</a><?php */?>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php }else{?>
|
||||||
|
<tr class="odd"><td colspan="3">none</td></tr>
|
||||||
|
<?php }?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<form action="alibHttp.php" method="post">
|
||||||
|
Add subject
|
||||||
|
<select name="login">
|
||||||
|
<?php if(is_array($d['subj'])) foreach($d['subj'] as $k=>$row) {?>
|
||||||
|
<option value="<?php echo$row['login']?>"><?php echo$row['login']?></option>
|
||||||
|
<?php }?>
|
||||||
|
</select>
|
||||||
|
to group <?php echo$d['gname']?>
|
||||||
|
<input type="hidden" name="act" value="addSubj2Gr">
|
||||||
|
<input type="hidden" name="reid" value="<?php echo$d['id']?>">
|
||||||
|
<input type="hidden" name="gname" value="<?php echo$d['gname']?>">
|
||||||
|
<input type="submit" value="Do it!">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?php }?>
|
||||||
|
|
||||||
|
<?php if($d['msg']){?>
|
||||||
|
<script type="text/javascript">
|
||||||
|
<!--
|
||||||
|
alert('<?php echo$d['msg']?>');
|
||||||
|
-->
|
||||||
|
</script>
|
||||||
|
<?php }?>
|
||||||
|
</body></html>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
// $Id: alibExTestAuth.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
$login = $alib->getSessLogin($_REQUEST['alibsid']);
|
||||||
|
if(!isset($login)||$login==''){
|
||||||
|
$_SESSION['alertMsg'] = "Login required";
|
||||||
|
header("Location: alibExLogin.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,111 @@
|
||||||
|
<?php
|
||||||
|
// $Id: alibExTree.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
require_once"alib_h.php";
|
||||||
|
require_once"alibExTestAuth.php";
|
||||||
|
|
||||||
|
if(isset($_GET['id']) && is_numeric($_GET['id'])) $id = $_GET['id'];
|
||||||
|
else $id = $alib->getRootNode();
|
||||||
|
|
||||||
|
// prefill data structure for template
|
||||||
|
$d = array(
|
||||||
|
'parid' => $alib->getParent($id),
|
||||||
|
'oname' => $alib->getObjName($id),
|
||||||
|
'path' => $alib->getPath($id, 'id, name'),
|
||||||
|
'rows' => $alib->getDir($id, 'id, name, type'),
|
||||||
|
'addtypes' => $alib->getAllowedChildTypes($alib->getObjType($id)),
|
||||||
|
'dump' => $alib->dumpTree($id),
|
||||||
|
'id' => $id,
|
||||||
|
'loggedAs' => $login
|
||||||
|
);
|
||||||
|
$d['msg'] = $_SESSION['alertMsg']; unset($_SESSION['alertMsg']);
|
||||||
|
|
||||||
|
require_once"alib_f.php";
|
||||||
|
// template follows:
|
||||||
|
?>
|
||||||
|
<html><head>
|
||||||
|
<title>Alib - tree editor</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
|
<link rel="stylesheet" type="text/css" href="default.css">
|
||||||
|
<style type="text/css">
|
||||||
|
<!--
|
||||||
|
#menu { float:right; margin-right:1em; border:1px solid black; background-color:#ddd; padding:2px 1ex; }
|
||||||
|
#current { background-color:#aaa; }
|
||||||
|
#parent, #parent a { background-color:#888; font-weight:bold; color:white; }
|
||||||
|
#tree { width:60%; }
|
||||||
|
-->
|
||||||
|
</style>
|
||||||
|
</head><body>
|
||||||
|
<div id="menu">
|
||||||
|
Logged as: <span class="b"><?php echo$d['loggedAs']?></span><br>
|
||||||
|
<a href="alibHttp.php?act=logout">logout</a><br>
|
||||||
|
<?php /*?> <a href="alibExPerms.php?id=<?php echo$d['id']?>">Permission editor</a><br><?php */?>
|
||||||
|
<a href="alibExCls.php">Class editor</a><br>
|
||||||
|
<a href="alibExSubj.php">User/Group editor</a><br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1>Tree editor</h1>
|
||||||
|
<h3>Path:
|
||||||
|
<?php if(is_array($d['path'])) foreach($d['path'] as $k=>$it) {?>
|
||||||
|
<a <?php if($it["id"]!=$id){?>href="alibExTree.php?id=<?php echo $it["id"]?>"<?php }?>><?php echo$it["name"]?></a><span class="slash">/</span><?php }?>
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<table id="tree" border="0" cellpadding="5">
|
||||||
|
<tr id="current">
|
||||||
|
<td colspan="2">Current node: <b><?php echo $d['oname']?></b></dt>
|
||||||
|
<td>
|
||||||
|
<a class="lnkbutt" href="alibExPerms.php?id=<?php echo$d['id']?>&reid=<?php echo$d['id']?>">permissions</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr id="parent">
|
||||||
|
<td colspan="3">
|
||||||
|
<?php if(is_numeric($d['parid'])){?><a href="alibExTree.php?id=<?php echo$d['parid']?>">Parent: ..</a>
|
||||||
|
<?php }else{?>/<?php }?>
|
||||||
|
</dt>
|
||||||
|
</tr>
|
||||||
|
<?php if(is_array($d['rows'])&&count($d['rows'])>0) foreach($d['rows'] as $k=>$row) {?>
|
||||||
|
<tr class="<?php echo(($o=1-$o) ? 'odd' : 'ev')?>">
|
||||||
|
<td><?php echo$row['id']?></td>
|
||||||
|
<td><a href="alibExTree.php?id=<?php echo$row['id']?>" class="b"><?php echo$row['name']?></a> (<?php echo$row['type']?>)</td>
|
||||||
|
<td>
|
||||||
|
<a class="lnkbutt" href="alibHttp.php?act=deleteNode&id=<?php echo$row['id']?>&reid=<?php echo$d['id']?>">delete</a>
|
||||||
|
<a class="lnkbutt" href="alibExPerms.php?id=<?php echo$row['id']?>&reid=<?php echo$d['id']?>">permissions</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php }else{?>
|
||||||
|
<tr class="odd"><td colspan="3">none</td></tr>
|
||||||
|
<?php }?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<form action="alibHttp.php" method="post">
|
||||||
|
Add object of type
|
||||||
|
<select name="type">
|
||||||
|
<?php if(is_array($d['addtypes'])) foreach($d['addtypes'] as $k=>$row) {?>
|
||||||
|
<option value="<?php echo$row?>"><?php echo$row?></option>
|
||||||
|
<?php }?>
|
||||||
|
</select>
|
||||||
|
with name
|
||||||
|
<input type="text" name="name" value="" size="10">
|
||||||
|
<select name="position">
|
||||||
|
<option value="<?php echo$d['id']?>">as first node</option>
|
||||||
|
<?php if(is_array($d['rows'])) foreach($d['rows'] as $k=>$row) {?>
|
||||||
|
<option value="<?php echo$row['id']?>">after <?php echo$row['name']?></option>
|
||||||
|
<?php }?>
|
||||||
|
<option value="<?php echo$row['id']?>" selected>as last node</option>
|
||||||
|
</select>
|
||||||
|
<input type="hidden" name="act" value="addNode">
|
||||||
|
<input type="hidden" name="id" value="<?php echo$d['id']?>">
|
||||||
|
<input type="hidden" name="reid" value="<?php echo$d['id']?>">
|
||||||
|
<input type="submit" value="Do it!">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<pre><b>Subtree dump:</b><br><?php echo$d['dump']?></pre>
|
||||||
|
<?php #php echo"pre">; print_r($d); echo"</pre>";?>
|
||||||
|
|
||||||
|
<?php if($d['msg']){?>
|
||||||
|
<script type="text/javascript">
|
||||||
|
<!--
|
||||||
|
alert('<?php echo$d['msg']?>');
|
||||||
|
-->
|
||||||
|
</script>
|
||||||
|
<?php }?>
|
||||||
|
</body></html>
|
|
@ -0,0 +1,125 @@
|
||||||
|
<?php
|
||||||
|
// $Id: alibHttp.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
require_once"alib_h.php";
|
||||||
|
|
||||||
|
#header("Content-type: text/plain"); echo"GET:\n"; print_r($_GET); echo"POST:\n"; print_r($_POST); exit;
|
||||||
|
|
||||||
|
function getPGval($vn, $dfl='')
|
||||||
|
{
|
||||||
|
return (isset($_POST[$vn])?$_POST[$vn]:(isset($_GET[$vn])?$_GET[$vn]:$dfl));
|
||||||
|
}
|
||||||
|
|
||||||
|
$userid = $alib->getSessUserId($_REQUEST['alibsid']);
|
||||||
|
$login = $alib->getSessLogin($_REQUEST['alibsid']);
|
||||||
|
|
||||||
|
$redirUrl="alibExTree.php".(($reid=getPGval('reid', '')) ? "?id=$reid":"");
|
||||||
|
$act = getPGval('act', 'nop');
|
||||||
|
switch($act)
|
||||||
|
{
|
||||||
|
case"login";
|
||||||
|
if($sessid = $alib->login($_POST['login'], $_POST['pass'])){
|
||||||
|
setcookie('alibsid', $sessid);
|
||||||
|
$redirUrl="alibExTree.php";
|
||||||
|
}else{ $redirUrl="alibExLogin.php"; $_SESSION['alertMsg']='Login failed.'; }
|
||||||
|
break;
|
||||||
|
case"logout";
|
||||||
|
$r = $alib->logout($_REQUEST['alibsid']);
|
||||||
|
if(PEAR::isError($r)) $_SESSION['alertMsg'] = $r->getMessage().", ".$r->getUserInfo();
|
||||||
|
setcookie('alibsid', '');
|
||||||
|
$redirUrl="alibExLogin.php";
|
||||||
|
break;
|
||||||
|
case"addNode";
|
||||||
|
if($alib->checkPerm($userid, 'addChilds', $_POST['id'])
|
||||||
|
&& $_POST['type']!=''
|
||||||
|
&& $_POST['name']!=''
|
||||||
|
){
|
||||||
|
$oid = $alib->addObj($_POST['name'], $_POST['type'], $_POST['id'], $_POST['position']);
|
||||||
|
$alib->addPerm($userid, '_all', $oid);
|
||||||
|
}else $_SESSION['alertMsg']='Access denied.';
|
||||||
|
break;
|
||||||
|
case"deleteNode";
|
||||||
|
if($alib->checkPerm($userid, 'delete', $_REQUEST['id']))
|
||||||
|
$alib->removeObj($_GET['id']);
|
||||||
|
else $_SESSION['alertMsg']='Access denied.';
|
||||||
|
break;
|
||||||
|
case"addPerm";
|
||||||
|
$a = $alib->isClass($_POST['id']) ? 'classes':'editPerms';
|
||||||
|
$id = $alib->isClass($_POST['id']) ? '':$_POST['id'];
|
||||||
|
if($alib->checkPerm($userid, $a, $id))
|
||||||
|
$alib->addPerm($_POST['subj'], $_POST['permAction'], $_POST['id'], $_POST['allowDeny']);
|
||||||
|
else $_SESSION['alertMsg']='Access denied.';
|
||||||
|
$redirUrl="alibExPerms.php".(($reid=getPGval('reid', '')) ? "?id=$reid":"");
|
||||||
|
break;
|
||||||
|
case"removePerm";
|
||||||
|
$a = $alib->isClass($_REQUEST['oid']) ? 'classes':'editPerms';
|
||||||
|
$oid = $alib->isClass($_REQUEST['oid']) ? '':$_REQUEST['oid'];
|
||||||
|
if($alib->checkPerm($userid, $a, $oid))
|
||||||
|
$alib->removePerm($_GET['permid']);
|
||||||
|
else $_SESSION['alertMsg']='Access denied.';
|
||||||
|
$redirUrl=($_REQUEST['reurl']==plist ? "alibExPList.php":"alibExPerms.php").(($reid=getPGval('reid', '')) ? "?id=$reid":"");
|
||||||
|
break;
|
||||||
|
case"checkPerm";
|
||||||
|
$res = $alib->checkPerm($_POST['subj'], $_POST['permAction'], $_POST['obj']);
|
||||||
|
$_SESSION['alertMsg'] = ($res ? "permitted: ":"DENIED: ").
|
||||||
|
" {$_POST['permAction']} for ".$alib->getSubjName($_POST['subj']).
|
||||||
|
" on ".$alib->getObjName($_POST['obj']);
|
||||||
|
$_SESSION['lastPost']=$_POST;
|
||||||
|
$redirUrl="alibExLogin.php";
|
||||||
|
break;
|
||||||
|
case"addClass";
|
||||||
|
if($alib->checkPerm($userid, 'classes'))
|
||||||
|
$alib->addClass($_POST['name']);
|
||||||
|
else $_SESSION['alertMsg']='Access denied.';
|
||||||
|
$redirUrl="alibExCls.php";
|
||||||
|
break;
|
||||||
|
case"removeClass";
|
||||||
|
if($alib->checkPerm($userid, 'classes'))
|
||||||
|
$alib->removeClassById($_GET['id']);
|
||||||
|
else $_SESSION['alertMsg']='Access denied.';
|
||||||
|
$redirUrl="alibExCls.php";
|
||||||
|
break;
|
||||||
|
case"addSubj";
|
||||||
|
if($alib->checkPerm($userid, 'subjects'))
|
||||||
|
$alib->addSubj($_POST['login'], $_POST['pass']);
|
||||||
|
else $_SESSION['alertMsg']='Access denied.';
|
||||||
|
$redirUrl="alibExSubj.php";
|
||||||
|
break;
|
||||||
|
case"removeSubj";
|
||||||
|
if($alib->checkPerm($userid, 'subjects'))
|
||||||
|
$alib->removeSubj($_GET['login']);
|
||||||
|
else $_SESSION['alertMsg']='Access denied.';
|
||||||
|
$redirUrl="alibExSubj.php";
|
||||||
|
break;
|
||||||
|
case"addSubj2Gr";
|
||||||
|
if($alib->checkPerm($userid, 'subjects'))
|
||||||
|
$alib->addSubj2Gr($_POST['login'], $_POST['gname']);
|
||||||
|
else $_SESSION['alertMsg']='Access denied.';
|
||||||
|
$redirUrl="alibExSubj.php".(($id=getPGval('reid', '')) ? "?id=$reid":"");
|
||||||
|
break;
|
||||||
|
case"removeSubjFromGr";
|
||||||
|
if($alib->checkPerm($userid, 'subjects'))
|
||||||
|
$alib->removeSubjFromGr($_GET['login'], $_GET['gname']);
|
||||||
|
else $_SESSION['alertMsg']='Access denied.';
|
||||||
|
$redirUrl="alibExSubj.php".(($id=getPGval('reid', '')) ? "?id=$reid":"");
|
||||||
|
break;
|
||||||
|
case"addObj2Class";
|
||||||
|
if($alib->checkPerm($userid, 'classes'))
|
||||||
|
$alib->addObj2Class($_POST['id'], $_POST['oid']);
|
||||||
|
else $_SESSION['alertMsg']='Access denied. X1';
|
||||||
|
$redirUrl="alibExCls.php".(($id=getPGval('id', '')) ? "?id=$id":"");
|
||||||
|
break;
|
||||||
|
case"removeObjFromClass";
|
||||||
|
$id=getPGval('id', '');
|
||||||
|
if($alib->checkPerm($userid, 'classes'))
|
||||||
|
$alib->removeObjFromClass($_GET['oid'], $id);
|
||||||
|
else $_SESSION['alertMsg']='Access denied.';
|
||||||
|
$redirUrl="alibExCls.php".($id ? "?id=$id":"");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$_SESSION['alertMsg']="Unknown method: $act";
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once"alib_f.php";
|
||||||
|
|
||||||
|
header("Location: $redirUrl");
|
||||||
|
?>
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?
|
||||||
|
// $Id: alib_f.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
$dbc->disconnect();
|
||||||
|
?>
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?
|
||||||
|
// $Id: alib_h.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||||
|
header("Pragma: no-cache");
|
||||||
|
session_start();
|
||||||
|
require_once 'conf.php';
|
||||||
|
require_once 'DB.php';
|
||||||
|
require_once '../alib.php';
|
||||||
|
|
||||||
|
#PEAR::setErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
#PEAR::setErrorHandling(PEAR_ERROR_PRINT, "%s<hr>\n");
|
||||||
|
#PEAR::setErrorHandling(PEAR_ERROR_TRIGGER, E_USER_WARNING);
|
||||||
|
PEAR::setErrorHandling(PEAR_ERROR_DIE);
|
||||||
|
PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'errCallback');
|
||||||
|
|
||||||
|
function errCallback($err)
|
||||||
|
{
|
||||||
|
if(assert_options(ASSERT_ACTIVE)==1) return;
|
||||||
|
echo "<pre>\n";
|
||||||
|
echo "request: "; print_r($_REQUEST);
|
||||||
|
echo "\ngm:\n".$err->getMessage()."\nui:\n".$err->getUserInfo()."\n";
|
||||||
|
echo "<hr>BackTrace:\n";
|
||||||
|
print_r($err->backtrace);
|
||||||
|
echo "</pre>\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dbc = DB::connect($config['dsn'], TRUE);
|
||||||
|
$dbc->setFetchMode(DB_FETCHMODE_ASSOC);
|
||||||
|
$alib =& new Alib($dbc, $config);
|
||||||
|
?>
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
// $Id: conf.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
$config = array(
|
||||||
|
'dsn' => array( // data source definition
|
||||||
|
'username' => 'tomash',
|
||||||
|
'password' => '',
|
||||||
|
'hostspec' => 'localhost',
|
||||||
|
'phptype' => 'pgsql',
|
||||||
|
'database' => 'mdlf'
|
||||||
|
),
|
||||||
|
'tblNamePrefix' => 'al_',
|
||||||
|
# 'tblNamePrefix' => 'gb_',
|
||||||
|
'RootNode' =>'RootNode',
|
||||||
|
'objtypes' => array(
|
||||||
|
'RootNode' => array('Publication'),
|
||||||
|
'Publication' => array('Issue'),
|
||||||
|
'Issue' => array('Title', 'Section'),
|
||||||
|
'Section' => array('Title', 'Image', 'Par')
|
||||||
|
),
|
||||||
|
'allowedActions'=> array(
|
||||||
|
'RootNode' => array('addChilds', 'editPerms', 'read', 'edit', 'delete', 'classes', 'subjects'),
|
||||||
|
'Publication' => array('addChilds', 'editPerms', 'read', 'edit', 'delete'),
|
||||||
|
'Issue' => array('addChilds', 'editPerms', 'read', 'edit', 'delete'),
|
||||||
|
'Section' => array('addChilds', 'editPerms', 'read', 'edit', 'delete'),
|
||||||
|
'Title' => array('editPerms', 'read', 'edit', 'delete'),
|
||||||
|
'Image' => array('editPerms', 'read', 'edit', 'delete'),
|
||||||
|
'Par' => array('editPerms', 'read', 'edit', 'delete'),
|
||||||
|
'_class' => array('addChilds', 'editPerms', 'read', 'edit', 'delete')
|
||||||
|
),
|
||||||
|
'allActions'=> array('editPerms', 'addChilds', 'read', 'edit', 'delete', 'classes', 'subjects')
|
||||||
|
);
|
||||||
|
?>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<!--
|
||||||
|
/* $Id: default.css,v 1.1 2004/07/23 00:22:13 tomas Exp $ */
|
||||||
|
body { font-family:'Arial CE', 'Helvetica CE', Arial, helvetica, sans-serif; background-color:#fff; }
|
||||||
|
h1 { border:0px solid black; margin-bottom:2px; font-size:x-large; }
|
||||||
|
h2 { border:0px solid black; margin-bottom:2px; margin-top:2px; font-size:large; }
|
||||||
|
h3 { border:0px solid black; margin-bottom:2px; margin-top:2px; font-size:medium; font-weight:bold; }
|
||||||
|
table { border-collapse:collapse; margin:1ex 0px; }
|
||||||
|
tr.odd { background-color:#ccc; }
|
||||||
|
tr.ev { background-color:#bbb; }
|
||||||
|
td { border:0px solid black; padding:2px 1em; }
|
||||||
|
pre { border:solid black; border-width:1px 0px; padding:1em 1px;}
|
||||||
|
.b { font-weight:bold; }
|
||||||
|
.slash { padding:0px 2px; font-weigt:bolder; }
|
||||||
|
.lnkbutt { padding:0px 4px; font-weigt:bolder; }
|
||||||
|
-->
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
// $Id: index.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
|
||||||
|
header ("location: alibExLogin.php");
|
||||||
|
die;
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
// $Id: index.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
|
||||||
|
header ("location: install.php");
|
||||||
|
die;
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,65 @@
|
||||||
|
<?
|
||||||
|
// $Id: install.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
require_once 'example/conf.php';
|
||||||
|
require_once 'DB.php';
|
||||||
|
require_once 'alib.php';
|
||||||
|
|
||||||
|
function errCallback($err)
|
||||||
|
{
|
||||||
|
if(assert_options(ASSERT_ACTIVE)==1) return;
|
||||||
|
echo "<pre>\n";
|
||||||
|
echo "request: "; print_r($_REQUEST);
|
||||||
|
echo "gm:\n".$err->getMessage()."\ndi:\n".$err->getDebugInfo()."\nui:\n".$err->getUserInfo()."\n</pre>\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PEAR::setErrorHandling(PEAR_ERROR_PRINT, "%s<hr>\n");
|
||||||
|
$dbc = DB::connect($config['dsn'], TRUE);
|
||||||
|
if(PEAR::isError($dbc)){
|
||||||
|
echo "Database connection problem.\n";
|
||||||
|
echo "Create database '{$config['dsn']['database']}' or change 'dsn' values in conf.php.\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dbc->setFetchMode(DB_FETCHMODE_ASSOC);
|
||||||
|
$alib =& new Alib($dbc, $config);
|
||||||
|
?>
|
||||||
|
<html><head>
|
||||||
|
<title>ALib install</title>
|
||||||
|
</head><body>
|
||||||
|
<h3>Alib install</h3>
|
||||||
|
<pre>
|
||||||
|
<?
|
||||||
|
if($_REQUEST['ak']=='inst'){
|
||||||
|
$dbc->setErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
# $dbc->setErrorHandling(PEAR_ERROR_PRINT, "%s<hr>\n");
|
||||||
|
echo "Trying to uninstall all ...\n";
|
||||||
|
$alib->uninstall();
|
||||||
|
$dbc->setErrorHandling(PEAR_ERROR_PRINT, "%s<hr>\n");
|
||||||
|
# $dbc->setErrorHandling(PEAR_ERROR_CALLBACK, 'errCallback');
|
||||||
|
echo "Install ...\n";
|
||||||
|
$alib->install();
|
||||||
|
|
||||||
|
echo "Testing ...\n";
|
||||||
|
$alib->test();
|
||||||
|
$log = $alib->test_log;
|
||||||
|
echo "TESTS:\n$log\n---\n";
|
||||||
|
|
||||||
|
echo "Reinstall + testdata insert ...\n";
|
||||||
|
$alib->reinstall();
|
||||||
|
$alib->testData();
|
||||||
|
|
||||||
|
echo "TREE DUMP:\n";
|
||||||
|
echo $alib->dumpTree();
|
||||||
|
echo "\n<b>Alib is probably installed OK</b>\n\n\n";
|
||||||
|
}
|
||||||
|
$dbc->disconnect();
|
||||||
|
?>
|
||||||
|
</pre>
|
||||||
|
<a href="install.php?ak=inst">Install/reinstall !</a><br>
|
||||||
|
<br>
|
||||||
|
<a href="example/">Example</a><br>
|
||||||
|
<a href="xmlrpc/">XmlRpc test</a>
|
||||||
|
</body></html>
|
||||||
|
|
|
@ -0,0 +1,521 @@
|
||||||
|
<?php
|
||||||
|
// $Id: mtree.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mtree class
|
||||||
|
*
|
||||||
|
* class for tree hierarchy stored in db
|
||||||
|
*
|
||||||
|
* example config: example/conf.php
|
||||||
|
* example minimal config:
|
||||||
|
* $config = array(
|
||||||
|
* 'dsn' => array( // data source definition
|
||||||
|
* 'username' => DBUSER,
|
||||||
|
* 'password' => DBPASSWORD,
|
||||||
|
* 'hostspec' => 'localhost',
|
||||||
|
* 'phptype' => 'pgsql',
|
||||||
|
* 'database' => DBNAME
|
||||||
|
* ),
|
||||||
|
* 'tblNamePrefix' => 'al_',
|
||||||
|
* 'RootNode' =>'RootNode',
|
||||||
|
* );
|
||||||
|
* (mysql phptype is tested too, but psql is recommended)
|
||||||
|
**/
|
||||||
|
define('ALIBERR_MTREE', 10);
|
||||||
|
|
||||||
|
class Mtree{
|
||||||
|
var $dbc;
|
||||||
|
var $config;
|
||||||
|
var $treeTable;
|
||||||
|
var $rootNodeName;
|
||||||
|
/** Mtree - constructor
|
||||||
|
*
|
||||||
|
* @param dbc object
|
||||||
|
* @param config array
|
||||||
|
* @return this
|
||||||
|
**/
|
||||||
|
function Mtree(&$dbc, $config)
|
||||||
|
{
|
||||||
|
$this->dbc =& $dbc;
|
||||||
|
$this->config = $config;
|
||||||
|
$this->treeTable = $config['tblNamePrefix'].'tree';
|
||||||
|
$this->rootNodeName = $config['RootNode'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== public methods: ========== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addObj
|
||||||
|
*
|
||||||
|
* @param name string
|
||||||
|
* @param type string
|
||||||
|
* @param parid int OPT // parent id
|
||||||
|
* @param aftid int OPT // after id
|
||||||
|
* @param param string OPT
|
||||||
|
* @return int/err // new id of inserted object
|
||||||
|
**/
|
||||||
|
function addObj($name, $type, $parid=1, $aftid=NULL, $param='')
|
||||||
|
{
|
||||||
|
if($name=='' || $type=='') return PEAR::raiseError('Mtree::addObj: Wrong name or type', ALIBERR_MTREE);
|
||||||
|
$this->dbc->query("BEGIN");
|
||||||
|
$r = $this->dbc->query("LOCK TABLE {$this->treeTable}"); if(PEAR::isError($r)) return $r;
|
||||||
|
// position resolving:
|
||||||
|
if(is_null($aftid)){ // add object as last child
|
||||||
|
$after = $this->dbc->getOne("
|
||||||
|
SELECT max(rgt) FROM {$this->treeTable} WHERE parid='$parid'
|
||||||
|
");
|
||||||
|
}else{ // use 'aftid'
|
||||||
|
$after = $this->dbc->getOne("
|
||||||
|
SELECT ".($aftid == $parid ? 'lft' : 'rgt')."
|
||||||
|
FROM {$this->treeTable} WHERE id='$aftid'");
|
||||||
|
}
|
||||||
|
if(PEAR::isError($after)) return $this->_dbRollback($after);
|
||||||
|
if(is_null($after)){ // position not specified - add as first child
|
||||||
|
$after = $this->dbc->getOne("
|
||||||
|
SELECT lft FROM {$this->treeTable} WHERE id='$parid'
|
||||||
|
");
|
||||||
|
}
|
||||||
|
if(PEAR::isError($after)) return $this->_dbRollback($after);
|
||||||
|
$after = intval($after);
|
||||||
|
// tree level resolving:
|
||||||
|
$level = $this->dbc->getOne("SELECT level FROM {$this->treeTable} WHERE id='$parid'");
|
||||||
|
if(is_null($level)) return $this->_dbRollback('addObj: parent does not exist');
|
||||||
|
if(PEAR::isError($level)) return $this->_dbRollback($level);
|
||||||
|
$id = $this->dbc->nextId("{$this->treeTable}_id_seq");
|
||||||
|
if(PEAR::isError($id)) return $this->_dbRollback($id);
|
||||||
|
// creating space in rgt/lft sequencies:
|
||||||
|
$r = $this->dbc->query("UPDATE {$this->treeTable} SET rgt=rgt+2 WHERE rgt>$after");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
$r = $this->dbc->query("UPDATE {$this->treeTable} SET lft=lft+2 WHERE lft>$after");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
// inserting object:
|
||||||
|
$r = $this->dbc->query("
|
||||||
|
INSERT INTO {$this->treeTable} (id, name, type, parid, level, lft, rgt, param)
|
||||||
|
VALUES ('$id', '$name', '$type', $parid, ".($level+1).", ".($after+1).", ".($after+2).", '$param')
|
||||||
|
");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
$r = $this->dbc->query("COMMIT");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
return $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copyObj
|
||||||
|
*
|
||||||
|
* @param id int
|
||||||
|
* @param newParid int
|
||||||
|
* @param after int OPT
|
||||||
|
* @return int/err
|
||||||
|
**/
|
||||||
|
function copyObj($id, $newParid, $after=NULL)
|
||||||
|
{
|
||||||
|
$o = $this->dbc->getRow("SELECT * FROM {$this->treeTable} WHERE id='$id'");
|
||||||
|
if(PEAR::isError($o)) return $o;
|
||||||
|
$nid = $this->addObj($o['name'], $o['type'], $newParid, $after, $o['param']);
|
||||||
|
return $nid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* renameObj
|
||||||
|
*
|
||||||
|
* @param id int
|
||||||
|
* @param newName string
|
||||||
|
* @return int/err
|
||||||
|
**/
|
||||||
|
function renameObj($id, $newName)
|
||||||
|
{
|
||||||
|
$r = $this->dbc->query("UPDATE {$this->treeTable} SET name='$newName' WHERE id='$id'");
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* removeObj
|
||||||
|
*
|
||||||
|
* @param id int
|
||||||
|
* @return boolean/err
|
||||||
|
**/
|
||||||
|
function removeObj($id)
|
||||||
|
{
|
||||||
|
$dirarr = $this->getDir($id); if(PEAR::isError($dirarr)) return $dirarr;
|
||||||
|
foreach($dirarr as $k=>$snod)
|
||||||
|
{
|
||||||
|
$this->removeObj($snod['id']);
|
||||||
|
}
|
||||||
|
$this->dbc->query("BEGIN");
|
||||||
|
$r = $this->dbc->query("LOCK TABLE {$this->treeTable}"); if(PEAR::isError($r)) return $r;
|
||||||
|
$rgt = $this->dbc->getOne("SELECT rgt FROM {$this->treeTable} WHERE id='$id'");
|
||||||
|
if(is_null($rgt)) return $this->_dbRollback('removeObj: object not exists');
|
||||||
|
// deleting object:
|
||||||
|
$r = $this->dbc->query("DELETE FROM {$this->treeTable} WHERE id='$id'");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
// closing the space in rgt/lft sequencies:
|
||||||
|
$r = $this->dbc->query("UPDATE {$this->treeTable} SET rgt=rgt-2 WHERE rgt>$rgt");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
$r = $this->dbc->query("UPDATE {$this->treeTable} SET lft=lft-2 WHERE lft>$rgt");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
$r = $this->dbc->query("COMMIT");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- info methods: --- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getObjId - search dir for object by name
|
||||||
|
*
|
||||||
|
* @param name string
|
||||||
|
* @param parId int OPT
|
||||||
|
* @return int/err
|
||||||
|
**/
|
||||||
|
function getObjId($name, $parId=NULL)
|
||||||
|
{
|
||||||
|
if($name=='' && is_null($parId)) $name = $this->rootNodeName;
|
||||||
|
return $this->dbc->getOne(
|
||||||
|
"SELECT id FROM {$this->treeTable} WHERE name='$name' and ".($parId ? "parid='$parId'":"parid is null")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getObjName - get one value for object (default: get name)
|
||||||
|
*
|
||||||
|
* @param oid int
|
||||||
|
* @param fld string OPT
|
||||||
|
* @return string/err
|
||||||
|
**/
|
||||||
|
function getObjName($oid, $fld='name')
|
||||||
|
{
|
||||||
|
return $this->dbc->getOne("SELECT $fld FROM {$this->treeTable} WHERE id='$oid'");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getObjType
|
||||||
|
*
|
||||||
|
* @param oid int
|
||||||
|
* @return string/err
|
||||||
|
**/
|
||||||
|
function getObjType($oid)
|
||||||
|
{
|
||||||
|
return $this->getObjName($oid, 'type');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getParent
|
||||||
|
*
|
||||||
|
* @param id int
|
||||||
|
* @return string/err
|
||||||
|
**/
|
||||||
|
function getParent($oid)
|
||||||
|
{
|
||||||
|
return $this->getObjName($oid, 'parid');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getPath - get array of nodes in object's path
|
||||||
|
*
|
||||||
|
* @param id int
|
||||||
|
* @param flds string OPT
|
||||||
|
* @return array/err
|
||||||
|
**/
|
||||||
|
function getPath($id, $flds='id')
|
||||||
|
{
|
||||||
|
$this->dbc->query("BEGIN");
|
||||||
|
$a = $this->dbc->getRow("SELECT name, lft, rgt FROM {$this->treeTable} WHERE id='$id'");
|
||||||
|
$res = $this->dbc->getAll("
|
||||||
|
SELECT $flds FROM {$this->treeTable} WHERE lft<={$a['lft']} AND rgt>={$a['rgt']}
|
||||||
|
ORDER by lft
|
||||||
|
");
|
||||||
|
$this->dbc->query("COMMIT");
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getDir - get array of childnodes
|
||||||
|
*
|
||||||
|
* @param id int
|
||||||
|
* @param flds string OPT
|
||||||
|
* @param order string OPT
|
||||||
|
* @return array/err
|
||||||
|
**/
|
||||||
|
function getDir($id, $flds='id', $order='lft')
|
||||||
|
{
|
||||||
|
return $this->dbc->getAll("
|
||||||
|
SELECT $flds FROM {$this->treeTable} WHERE parid='$id' ORDER BY $order
|
||||||
|
");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getSubTree
|
||||||
|
*
|
||||||
|
* @param id int OPT
|
||||||
|
* @param withRoot boolean OPT
|
||||||
|
* @return array/err
|
||||||
|
**/
|
||||||
|
function getSubTree($id=NULL, $withRoot=FALSE)
|
||||||
|
{
|
||||||
|
if(is_null($id)) $id = $this->getRootNode();
|
||||||
|
$r = array();
|
||||||
|
if($withRoot) $r[] = $re = $this->dbc->getRow("SELECT id, name, level FROM {$this->treeTable} WHERE id='$id'");
|
||||||
|
if(PEAR::isError($re)) return $re;
|
||||||
|
$dirarr = $this->getDir($id); if(PEAR::isError($dirarr)) return $dirarr;
|
||||||
|
foreach($dirarr as $k=>$snod)
|
||||||
|
{
|
||||||
|
$r[] = $re = $this->dbc->getRow("SELECT id, name, level FROM {$this->treeTable} WHERE id={$snod['id']}");
|
||||||
|
if(PEAR::isError($re)) return $re;
|
||||||
|
$r = array_merge($r, $this->getSubTree($snod['id']));
|
||||||
|
}
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getRootNode - get id of root node
|
||||||
|
*
|
||||||
|
* @return int/err
|
||||||
|
**/
|
||||||
|
function getRootNode()
|
||||||
|
{
|
||||||
|
return $this->getObjId($this->rootNodeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getAllObjects
|
||||||
|
*
|
||||||
|
* @return array/err
|
||||||
|
**/
|
||||||
|
function getAllObjects()
|
||||||
|
{
|
||||||
|
return $this->dbc->getAll("SELECT * FROM {$this->treeTable} ORDER BY lft");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- info methods related to application structure: --- */
|
||||||
|
/* (this part should be added/rewritten to allow defining/modifying/using application structure) */
|
||||||
|
/* (only very simple structure definition - in config - supported now) */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getAllowedChildTypes
|
||||||
|
*
|
||||||
|
* @param type string
|
||||||
|
* @return array
|
||||||
|
**/
|
||||||
|
function getAllowedChildTypes($type)
|
||||||
|
{
|
||||||
|
return $this->config['objtypes'][$type];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ========== "private" methods: ========== */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _dbRollback
|
||||||
|
*
|
||||||
|
* @param r object/string
|
||||||
|
* @return err
|
||||||
|
**/
|
||||||
|
function _dbRollback($r)
|
||||||
|
{
|
||||||
|
$this->dbc->query("ROLLBACK");
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
elseif(is_string($r)) return PEAR::raiseError("ERROR: ".get_class($this).": $r", ALIBERR_MTREE, PEAR_ERROR_RETURN);
|
||||||
|
else return PEAR::raiseError("ERROR: ".get_class($this).": unknown error", ALIBERR_MTREE, PEAR_ERROR_RETURN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _relocateSubtree - move subtree to another node without removing/adding
|
||||||
|
*
|
||||||
|
* @param id int
|
||||||
|
* @param newParid int
|
||||||
|
* @param after int
|
||||||
|
* @return boolean/err
|
||||||
|
**/
|
||||||
|
function _relocateSubtree($id, $newParid, $after=NULL)
|
||||||
|
{
|
||||||
|
$this->dbc->query("BEGIN");
|
||||||
|
$r = $this->dbc->query("LOCK TABLE {$this->treeTable}"); if(PEAR::isError($r)) return $r;
|
||||||
|
// obtain values for source node:
|
||||||
|
$a1 = $this->dbc->getRow("SELECT lft, rgt, level FROM {$this->treeTable} WHERE id='$id'");
|
||||||
|
if(is_null($a1)) return $this->_dbRollback('_relocateSubtree: object not exists');
|
||||||
|
extract($a1);
|
||||||
|
// values for destination node:
|
||||||
|
$a2 = $this->dbc->getRow("SELECT rgt, level FROM {$this->treeTable} WHERE id='$newParid'");
|
||||||
|
if(is_null($a2)) return $this->_dbRollback('_relocateSubtree: new parent not exists');
|
||||||
|
$nprgt = $a2['rgt']; $newLevel = $a2['level'];
|
||||||
|
// calculate differencies:
|
||||||
|
if(is_null($after)) $after = $nprgt-1;
|
||||||
|
$dif1 = $rgt-$lft+1;
|
||||||
|
$dif2 = $after-$lft+1;
|
||||||
|
$dif3 = $newLevel-$level+1;
|
||||||
|
// relocate the object"
|
||||||
|
$r = $this->dbc->query("UPDATE {$this->treeTable} SET parid='$newParid' WHERE id='$id'");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
if($after>$rgt){
|
||||||
|
// relocate subtree to the right:
|
||||||
|
$r = $this->dbc->query("UPDATE {$this->treeTable} SET rgt=rgt+$dif1 WHERE rgt>$after");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
$r = $this->dbc->query("UPDATE {$this->treeTable} SET lft=lft+$dif1 WHERE lft>$after");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
$r = $this->dbc->query("UPDATE {$this->treeTable}
|
||||||
|
SET lft=lft+$dif2, rgt=rgt+$dif2, level=level+$dif3
|
||||||
|
WHERE lft>=$lft AND rgt <=$rgt");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
$r = $this->dbc->query("UPDATE {$this->treeTable} SET rgt=rgt-$dif1 WHERE rgt>$rgt");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
$r = $this->dbc->query("UPDATE {$this->treeTable} SET lft=lft-$dif1 WHERE lft>$rgt");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
}else{
|
||||||
|
// relocate subtree to the left:
|
||||||
|
$r = $this->dbc->query("UPDATE {$this->treeTable} SET rgt=rgt+$dif1 WHERE rgt>$after");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
$r = $this->dbc->query("UPDATE {$this->treeTable} SET lft=lft+$dif1 WHERE lft>$after");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
$r = $this->dbc->query("UPDATE {$this->treeTable}
|
||||||
|
SET lft=lft+$dif2-$dif1, rgt=rgt+$dif2-$dif1, level=level+$dif3
|
||||||
|
WHERE lft>=$lft+$dif1 AND rgt <=$rgt+$dif1");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
$r = $this->dbc->query("UPDATE {$this->treeTable} SET rgt=rgt-$dif1 WHERE rgt>$rgt+$dif1");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
$r = $this->dbc->query("UPDATE {$this->treeTable} SET lft=lft-$dif1 WHERE lft>$rgt+$dif1");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
}
|
||||||
|
$r = $this->dbc->query("COMMIT");
|
||||||
|
if(PEAR::isError($r)) return $this->_dbRollback($r);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _copySubtree - recursive copyObj
|
||||||
|
*
|
||||||
|
* @param id int
|
||||||
|
* @param newParid int
|
||||||
|
* @param after int
|
||||||
|
* @return array
|
||||||
|
**/
|
||||||
|
function _copySubtree($id, $newParid, $after=NULL)
|
||||||
|
{
|
||||||
|
$nid = $this->copyObj($id, $newParid, $after);
|
||||||
|
if(PEAR::isError($nid)) return $nid;
|
||||||
|
$dirarr = $this->getDir($id); if(PEAR::isError($dirarr)) return $dirarr;
|
||||||
|
foreach($dirarr as $k=>$snod)
|
||||||
|
{
|
||||||
|
$r = $this->_copySubtree($snod['id'], $nid);
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== test and debug methods: ========== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dumpTree
|
||||||
|
*
|
||||||
|
* @param id int
|
||||||
|
* @param indstr string // indentation string
|
||||||
|
* @param ind string // aktual indentation
|
||||||
|
* @return string
|
||||||
|
**/
|
||||||
|
function dumpTree($id=NULL, $indstr=' ', $ind='', $format='{name}', $withRoot=TRUE)
|
||||||
|
{
|
||||||
|
$r='';
|
||||||
|
foreach($this->getSubTree($id, $withRoot) as $o)
|
||||||
|
$r .= str_repeat($indstr, intval($o['level'])).
|
||||||
|
preg_replace(array('|\{name\}|', '|\{id\}|'), array($o['name'], $o['id']), $format).
|
||||||
|
"\n";
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deleteData
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
function deleteData()
|
||||||
|
{
|
||||||
|
$this->dbc->query("DELETE FROM {$this->treeTable} WHERE parid is not null");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testData
|
||||||
|
*
|
||||||
|
* @param id int OPT
|
||||||
|
* @return array
|
||||||
|
**/
|
||||||
|
function testData()
|
||||||
|
{
|
||||||
|
$o[] = $rootId = $this->getRootNode();
|
||||||
|
$o[] = $p1 = $this->addObj('Publication A', 'Publication', $rootId); // 1
|
||||||
|
$o[] = $p2 = $this->addObj('Publication B', 'Publication', $rootId); // 2
|
||||||
|
$o[] = $i1 = $this->addObj('Issue 1', 'Issue', $p1); // 3
|
||||||
|
$o[] = $i2 = $this->addObj('Issue 2', 'Issue', $p1); // 4
|
||||||
|
$o[] = $s1 = $this->addObj('Section a', 'Section', $i2);
|
||||||
|
$o[] = $s2 = $this->addObj('Section b', 'Section', $i2); // 6
|
||||||
|
$o[] = $s3 = $this->addObj('Section c', 'Section', $i2);
|
||||||
|
$o[] = $t1 = $this->addObj('Title', 'Title', $s2);
|
||||||
|
$o[] = $s4 = $this->addObj('Section a', 'Section', $i1);
|
||||||
|
$o[] = $s5 = $this->addObj('Section b', 'Section', $i1);
|
||||||
|
$this->tdata['tree'] = $o;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
$this->deleteData();
|
||||||
|
$this->testData();
|
||||||
|
$rootId = $this->getRootNode();
|
||||||
|
$this->test_correct ="RootNode\n Publication A\n Issue 1\n Section a\n Section b\n Issue 2\n Section a\n Section b\n Title\n Section c\n Publication B\nRootNode\n";
|
||||||
|
$this->test_dump = $this->dumpTree();
|
||||||
|
$this->removeObj($this->tdata['tree'][1]);
|
||||||
|
$this->removeObj($this->tdata['tree'][2]);
|
||||||
|
$this->test_dump .= $this->dumpTree();
|
||||||
|
$this->deleteData();
|
||||||
|
if($this->test_dump == $this->test_correct){ $this->test_log.="tree: OK\n"; return TRUE; }
|
||||||
|
else return PEAR::raiseError('Mtree::test:', 1, PEAR_ERROR_DIE, '%s'.
|
||||||
|
"<pre>\ncorrect:\n.{$this->test_correct}.\ndump:\n.{$this->test_dump}.\n</pre>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* install - create tables + initialize
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
function install()
|
||||||
|
{
|
||||||
|
$this->dbc->query("CREATE TABLE {$this->treeTable} (
|
||||||
|
id int not null,
|
||||||
|
name varchar(255) not null default'',
|
||||||
|
parid int,
|
||||||
|
lft int,
|
||||||
|
rgt int,
|
||||||
|
level int,
|
||||||
|
type varchar(255) not null default'',
|
||||||
|
param varchar(255)
|
||||||
|
)");
|
||||||
|
$this->dbc->query("CREATE UNIQUE INDEX {$this->treeTable}_id_idx on {$this->treeTable} (id)");
|
||||||
|
$this->dbc->query("CREATE INDEX {$this->treeTable}_name_idx on {$this->treeTable} (name)");
|
||||||
|
$this->dbc->createSequence("{$this->treeTable}_id_seq");
|
||||||
|
|
||||||
|
$id = $this->dbc->nextId("{$this->treeTable}_id_seq");
|
||||||
|
$this->dbc->query("INSERT INTO {$this->treeTable} (id, name, parid, level, lft, rgt, type)
|
||||||
|
VALUES ($id, '{$this->rootNodeName}', NULL, 0, 1, 2, 'RootNode')");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* uninstall
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
function uninstall()
|
||||||
|
{
|
||||||
|
$this->dbc->query("DROP TABLE {$this->treeTable}");
|
||||||
|
$this->dbc->dropSequence("{$this->treeTable}_id_seq");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reinstall
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
function reinstall()
|
||||||
|
{
|
||||||
|
$this->uninstall();
|
||||||
|
$this->install();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,441 @@
|
||||||
|
<?php
|
||||||
|
// $Id: subj.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subj class
|
||||||
|
*
|
||||||
|
* users + groups
|
||||||
|
* with "linearized recursive membership" ;)
|
||||||
|
* (allow adding users to groups or groups to groups)
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
require_once"class.php";
|
||||||
|
define('ALIBERR_NOTGR', 20);
|
||||||
|
define('ALIBERR_BADSMEMB', 21);
|
||||||
|
|
||||||
|
class Subjects extends ObjClasses{
|
||||||
|
var $subjTable;
|
||||||
|
var $smembTable;
|
||||||
|
/** Subjects - constructor
|
||||||
|
*
|
||||||
|
* @param dbc object
|
||||||
|
* @param config array
|
||||||
|
* @return this
|
||||||
|
**/
|
||||||
|
function Subjects(&$dbc, $config)
|
||||||
|
{
|
||||||
|
parent::ObjClasses(&$dbc, $config);
|
||||||
|
$this->subjTable = $config['tblNamePrefix'].'subjs';
|
||||||
|
$this->smembTable = $config['tblNamePrefix'].'smemb';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== public methods: ========== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addSubj
|
||||||
|
*
|
||||||
|
* @param login string
|
||||||
|
* @param pass string OPT
|
||||||
|
* @return int/err
|
||||||
|
**/
|
||||||
|
function addSubj($login, $pass=NULL)
|
||||||
|
{
|
||||||
|
$id = $this->dbc->nextId("{$this->subjTable}_id_seq"); if(PEAR::isError($id)) return $id;
|
||||||
|
$r = $this->dbc->query("
|
||||||
|
INSERT INTO {$this->subjTable} (id, login, pass, type)
|
||||||
|
VALUES ($id, '$login', ".(is_null($pass) ? "'!', 'G'" : "'".md5($pass)."', 'U'").")
|
||||||
|
");
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
return $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* removeSubj
|
||||||
|
*
|
||||||
|
* @param login string
|
||||||
|
* @param uid int OPT
|
||||||
|
* @return boolean/err
|
||||||
|
**/
|
||||||
|
function removeSubj($login, $uid=NULL)
|
||||||
|
{
|
||||||
|
if(is_null($uid)) $uid = $this->getSubjId($login);
|
||||||
|
if(PEAR::isError($uid)) return $uid;
|
||||||
|
$r = $this->dbc->query("DELETE FROM {$this->smembTable} WHERE (uid='$uid' OR gid='$uid') AND mid is null");
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
$r = $this->dbc->query("DELETE FROM {$this->subjTable} WHERE login='$login'");
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
return $this->_rebuildRels();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* authenticate
|
||||||
|
*
|
||||||
|
* @param login string
|
||||||
|
* @param pass string OPT
|
||||||
|
* @return boolean/int/err
|
||||||
|
**/
|
||||||
|
function authenticate($login, $pass='')
|
||||||
|
{
|
||||||
|
$cpass = md5($pass);
|
||||||
|
$id = $this->dbc->getOne("
|
||||||
|
SELECT id FROM {$this->subjTable}
|
||||||
|
WHERE login='$login' AND pass='$cpass' AND type='U'
|
||||||
|
");
|
||||||
|
if(PEAR::isError($id)) return $id;
|
||||||
|
return (is_null($id) ? FALSE : $id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- groups --- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addSubj2Gr - add {login} and direct/indirect members to {gname} and to groups, where {gname} is [in]direct member
|
||||||
|
*
|
||||||
|
* @param login string
|
||||||
|
* @param gname string
|
||||||
|
* @return int/err
|
||||||
|
**/
|
||||||
|
function addSubj2Gr($login, $gname)
|
||||||
|
{
|
||||||
|
$uid = $this->getSubjId($login); if(PEAR::isError($uid)) return $uid;
|
||||||
|
$gid = $this->getSubjId($gname); if(PEAR::isError($gid)) return $gid;
|
||||||
|
$isgr = $this->isGroup($gid); if(PEAR::isError($isgr)) return $isgr;
|
||||||
|
if(!$isgr) return PEAR::raiseError("Subjects::addSubj2Gr: Not a group ($gname)", ALIBERR_NOTGR);
|
||||||
|
// add subject and all [in]direct members to group $gname:
|
||||||
|
$mid = $this->_plainAddSubj2Gr($uid, $gid); if(PEAR::isError($mid)) return $mid;
|
||||||
|
// add it to all groups where $gname is [in]direct member:
|
||||||
|
$marr = $this->_listRMemb($gid); if(PEAR::isError($marr)) return $marr;
|
||||||
|
foreach($marr as $k=>$v){
|
||||||
|
$r = $this->_plainAddSubj2Gr($uid, $v['gid'], intval($v['level'])+1, $v['id']);
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
}
|
||||||
|
return $mid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* removeSubjFromGr
|
||||||
|
*
|
||||||
|
* @param login string
|
||||||
|
* @param gname string
|
||||||
|
* @return boolean/err
|
||||||
|
**/
|
||||||
|
function removeSubjFromGr($login, $gname)
|
||||||
|
{
|
||||||
|
$uid = $this->getSubjId($login); if(PEAR::isError($uid)) return $uid;
|
||||||
|
$gid = $this->getSubjId($gname); if(PEAR::isError($gid)) return $gid;
|
||||||
|
$mid = $this->dbc->getOne($q = "SELECT id FROM {$this->smembTable} WHERE uid='$uid' AND gid='$gid' AND mid is null");
|
||||||
|
if(is_null($mid)) return FALSE;
|
||||||
|
if(PEAR::isError($mid)) return $mid;
|
||||||
|
// remove it:
|
||||||
|
$r = $this->_removeMemb($mid); if(PEAR::isError($r)) return $r;
|
||||||
|
// and rebuild indirect memberships:
|
||||||
|
$r = $this->_rebuildRels(); if(PEAR::isError($r)) return $r;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- info methods: --- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getSubjId
|
||||||
|
*
|
||||||
|
* @param login string
|
||||||
|
* @return int/err
|
||||||
|
**/
|
||||||
|
function getSubjId($login)
|
||||||
|
{
|
||||||
|
return $this->dbc->getOne("SELECT id FROM {$this->subjTable} WHERE login='$login'");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getSubjName
|
||||||
|
*
|
||||||
|
* @param id int
|
||||||
|
* @param fld string
|
||||||
|
* @return string/err
|
||||||
|
**/
|
||||||
|
function getSubjName($id, $fld='login')
|
||||||
|
{
|
||||||
|
return $this->dbc->getOne("SELECT $fld FROM {$this->subjTable} WHERE id='$id'");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getSubjects
|
||||||
|
*
|
||||||
|
* @param flds string OPT
|
||||||
|
* @return array/err
|
||||||
|
**/
|
||||||
|
function getSubjects($flds='id, login')
|
||||||
|
{
|
||||||
|
return $this->dbc->getAll("SELECT $flds FROM {$this->subjTable}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getSubjectsWCnt - get subjects with count of direct members
|
||||||
|
*
|
||||||
|
* @return array/err
|
||||||
|
**/
|
||||||
|
function getSubjectsWCnt()
|
||||||
|
{
|
||||||
|
return $this->dbc->getAll("SELECT count(m.uid)as cnt, s.id, s.login, s.type
|
||||||
|
FROM {$this->subjTable} s LEFT JOIN {$this->smembTable} m ON m.gid=s.id
|
||||||
|
WHERE m.mid is null GROUP BY s.id, s.login, s.type ORDER BY s.id");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* isGroup
|
||||||
|
*
|
||||||
|
* @param gid int
|
||||||
|
* @return boolean/err
|
||||||
|
**/
|
||||||
|
function isGroup($gid)
|
||||||
|
{
|
||||||
|
$r = $this->dbc->getOne("SELECT type FROM {$this->subjTable} WHERE id='$gid'");
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
return ($r === 'G' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* listGroup - list direct members of group
|
||||||
|
*
|
||||||
|
* @param gid int
|
||||||
|
* @return array/err
|
||||||
|
**/
|
||||||
|
function listGroup($gid)
|
||||||
|
{
|
||||||
|
return $this->dbc->getAll("SELECT s.id, s.login, s.type FROM {$this->smembTable} m, {$this->subjTable} s
|
||||||
|
WHERE m.uid=s.id AND m.mid is null AND m.gid='$gid'");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== "private" methods: ========== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _addMemb - create membership record
|
||||||
|
*
|
||||||
|
* @param uid int
|
||||||
|
* @param gid int
|
||||||
|
* @param level int OPT
|
||||||
|
* @param mid int OPT
|
||||||
|
* @return int/err
|
||||||
|
**/
|
||||||
|
function _addMemb($uid, $gid, $level=0, $mid='null')
|
||||||
|
{
|
||||||
|
if($uid == $gid) return PEAR::raiseError("Subjects::_addMemb: uid==gid ($uid)", ALIBERR_BADSMEMB);
|
||||||
|
$a = $this->dbc->getAll("SELECT id, level, mid FROM {$this->smembTable} WHERE uid='$uid' AND gid='$gid' ORDER BY level ASC");
|
||||||
|
if(PEAR::isError($a)) return $a;
|
||||||
|
if(count($a)>0){
|
||||||
|
$a0 = $a[0];
|
||||||
|
$id = $a0['id'];
|
||||||
|
if($level < intval($a0['level'])){
|
||||||
|
$r = $this->dbc->query("UPDATE {$this->smembTable} SET level='$level', mid='$mid' WHERE id='{$a0['id']}'");
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$id = $this->dbc->nextId("{$this->smembTable}_id_seq"); if(PEAR::isError($id)) return $id;
|
||||||
|
$r = $this->dbc->query("
|
||||||
|
INSERT INTO {$this->smembTable} (id, uid, gid, level, mid) VALUES ($id, $uid, $gid, $level, $mid)
|
||||||
|
");
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
}
|
||||||
|
return $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _removeMemb
|
||||||
|
*
|
||||||
|
* @param mid int
|
||||||
|
* @return null/err
|
||||||
|
**/
|
||||||
|
function _removeMemb($mid)
|
||||||
|
{
|
||||||
|
return $this->dbc->query("DELETE FROM {$this->smembTable} WHERE id='$mid'");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _listMemb - list [in]direct members of group
|
||||||
|
*
|
||||||
|
* @param gid int
|
||||||
|
* @param uid int OPT
|
||||||
|
* @return array/err
|
||||||
|
**/
|
||||||
|
function _listMemb($gid, $uid=NULL)
|
||||||
|
{
|
||||||
|
return $this->dbc->getAll("SELECT id, uid, level FROM {$this->smembTable} WHERE gid='$gid'".(is_null($uid) ? '' : " AND uid='$uid'"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _listRMemb - list groups where uid is [in]direct member
|
||||||
|
*
|
||||||
|
* @param gid int
|
||||||
|
* @param uid int OPT
|
||||||
|
* @return array/err
|
||||||
|
**/
|
||||||
|
function _listRMemb($uid, $gid=NULL)
|
||||||
|
{
|
||||||
|
return $this->dbc->getAll("SELECT id, gid, level FROM {$this->smembTable} WHERE uid='$uid'".(is_null($gid) ? '' : " AND gid='$gid'"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _plainAddSubj2Gr - add uid and its [in]direct members to gid
|
||||||
|
*
|
||||||
|
* @param uid int
|
||||||
|
* @param gid int
|
||||||
|
* @param level int
|
||||||
|
* @param rmid int //
|
||||||
|
* @return int/err
|
||||||
|
**/
|
||||||
|
function _plainAddSubj2Gr($uid, $gid, $level=0, $rmid='null')
|
||||||
|
{
|
||||||
|
$mid = $this->_addMemb($uid, $gid, $level, $rmid); if(PEAR::isError($mid)) return $mid;
|
||||||
|
$marr = $this->_listMemb($uid); if(PEAR::isError($marr)) return $marr;
|
||||||
|
foreach($marr as $k=>$v){
|
||||||
|
$r = $this->_addMemb($v['uid'], $gid, intval($v['level'])+$level+1, $mid);
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
}
|
||||||
|
return $mid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _rebuildRels - rebuild indirect membership records
|
||||||
|
*
|
||||||
|
* @return true/err
|
||||||
|
**/
|
||||||
|
function _rebuildRels()
|
||||||
|
{
|
||||||
|
$this->dbc->query("BEGIN");
|
||||||
|
$r = $this->dbc->query("LOCK TABLE {$this->smembTable}"); if(PEAR::isError($r)) return $r;
|
||||||
|
$r = $this->dbc->query("DELETE FROM {$this->smembTable} WHERE mid is not null");
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
$arr = $this->dbc->getAll("SELECT uid, gid FROM {$this->smembTable}"); // WHERE mid is null
|
||||||
|
if(PEAR::isError($arr)) return $arr;
|
||||||
|
foreach($arr as $it){
|
||||||
|
$marr = $this->_listRMemb($it['gid']); if(PEAR::isError($marr)) return $marr;
|
||||||
|
foreach($marr as $k=>$v){
|
||||||
|
$r = $this->_plainAddSubj2Gr($it['uid'], $v['gid'], intval($v['level'])+1, $v['id']);
|
||||||
|
if(PEAR::isError($r)) return $r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$r = $this->dbc->query("COMMIT"); if(PEAR::isError($r)) return $r;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== test and debug methods: ========== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dumpSubjects
|
||||||
|
*
|
||||||
|
* @param indstr string // indentation string
|
||||||
|
* @param ind string // aktual indentation
|
||||||
|
* @return string
|
||||||
|
**/
|
||||||
|
function dumpSubjects($indstr=' ', $ind='')
|
||||||
|
{
|
||||||
|
# $r = $ind.join(', ', $this->dbc->getCol("SELECT login FROM {$this->subjTable}"))."\n";
|
||||||
|
$r = $ind.join(', ', array_map(create_function('$v', 'return "{$v[\'login\']}({$v[\'cnt\']})";'), $this->getSubjectsWCnt()))."\n";
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deleteData
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function deleteData()
|
||||||
|
{
|
||||||
|
$this->dbc->query("DELETE FROM {$this->subjTable}");
|
||||||
|
$this->dbc->query("DELETE FROM {$this->smembTable}");
|
||||||
|
parent::deleteData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testData
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
**/
|
||||||
|
function testData()
|
||||||
|
{
|
||||||
|
parent::testData();
|
||||||
|
$o[] = $this->addSubj('root', 'q');
|
||||||
|
$o[] = $this->addSubj('test1', 'a');
|
||||||
|
$o[] = $this->addSubj('test2', 'a');
|
||||||
|
$o[] = $this->addSubj('test3', 'a');
|
||||||
|
$o[] = $this->addSubj('test4', 'a');
|
||||||
|
$o[] = $this->addSubj('gr1');
|
||||||
|
$o[] = $this->addSubj('gr2');
|
||||||
|
# $this->addSubj2Gr('test1', 'gr1');
|
||||||
|
$this->addSubj2Gr('test2', 'gr1');
|
||||||
|
$this->addSubj2Gr('test3', 'gr1');
|
||||||
|
$this->addSubj2Gr('test4', 'gr2');
|
||||||
|
$this->addSubj2Gr('gr2', 'gr1');
|
||||||
|
$o[] = $this->addSubj('gr3');
|
||||||
|
$this->addSubj2Gr('test3', 'gr3');
|
||||||
|
$this->addSubj2Gr('test1', 'gr3');
|
||||||
|
$this->addSubj2Gr('gr3', 'gr2');
|
||||||
|
return $this->tdata['subjects'] = $o;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
if(PEAR::isError($p = parent::test())) return $p;
|
||||||
|
$this->deleteData();
|
||||||
|
$this->testData();
|
||||||
|
$this->test_correct = "root(0), test1(0), test2(0), test3(0), test4(0), gr1(3), gr2(2), gr3(2)\n";
|
||||||
|
$this->test_dump = $this->dumpSubjects();
|
||||||
|
$this->removeSubj('test1');
|
||||||
|
$this->removeSubj('test3');
|
||||||
|
$this->removeSubjFromGr('test2', 'gr1');
|
||||||
|
$this->removeSubjFromGr('gr3', 'gr2');
|
||||||
|
$this->test_correct .= "root(0), test2(0), test4(0), gr1(1), gr2(1), gr3(0)\n";
|
||||||
|
$this->test_dump .= $this->dumpSubjects();
|
||||||
|
$this->deleteData();
|
||||||
|
if($this->test_dump == $this->test_correct){ $this->test_log.="subj: OK\n"; return TRUE; }
|
||||||
|
else return PEAR::raiseError('Subjects::test:', 1, PEAR_ERROR_DIE, '%s'.
|
||||||
|
"<pre>\ncorrect:\n{$this->test_correct}\ndump:\n{$this->test_dump}\n</pre>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* install - create tables + initialize
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
function install()
|
||||||
|
{
|
||||||
|
parent::install();
|
||||||
|
$this->dbc->query("CREATE TABLE {$this->subjTable} (
|
||||||
|
id int not null,
|
||||||
|
login varchar(255) not null default'',
|
||||||
|
pass varchar(255) not null default'',
|
||||||
|
type char(1) not null default 'U'
|
||||||
|
)");
|
||||||
|
$this->dbc->query("CREATE UNIQUE INDEX {$this->subjTable}_id_idx on {$this->subjTable} (id)");
|
||||||
|
$this->dbc->query("CREATE UNIQUE INDEX {$this->subjTable}_login_idx on {$this->subjTable} (login)");
|
||||||
|
$this->dbc->createSequence("{$this->subjTable}_id_seq");
|
||||||
|
|
||||||
|
$this->dbc->query("CREATE TABLE {$this->smembTable} (
|
||||||
|
id int not null,
|
||||||
|
uid int not null default 0,
|
||||||
|
gid int not null default 0,
|
||||||
|
level int not null default 0,
|
||||||
|
mid int
|
||||||
|
)");
|
||||||
|
$this->dbc->query("CREATE UNIQUE INDEX {$this->smembTable}_id_idx on {$this->smembTable} (id)");
|
||||||
|
$this->dbc->createSequence("{$this->smembTable}_id_seq");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* uninstall
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function uninstall()
|
||||||
|
{
|
||||||
|
$this->dbc->query("DROP TABLE {$this->subjTable}");
|
||||||
|
$this->dbc->dropSequence("{$this->subjTable}_id_seq");
|
||||||
|
$this->dbc->query("DROP TABLE {$this->smembTable}");
|
||||||
|
$this->dbc->dropSequence("{$this->smembTable}_id_seq");
|
||||||
|
parent::uninstall();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,99 @@
|
||||||
|
<?php
|
||||||
|
// $Id: alib_xr.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
include_once"xmlrpc.inc";
|
||||||
|
include_once"xmlrpcs.inc";
|
||||||
|
require_once"../example/alib_h.php";
|
||||||
|
|
||||||
|
function v2xr($var, $struct=true){
|
||||||
|
if(is_array($var)){
|
||||||
|
$r = array();
|
||||||
|
foreach($var as $k=>$v) if($struct) $r[$k]=v2xr($v); else $r[]=v2xr($v);
|
||||||
|
return new xmlrpcval($r, ($struct?"struct":"array"));
|
||||||
|
}else if(is_int($var)){
|
||||||
|
return new xmlrpcval($var, "int");
|
||||||
|
}else{
|
||||||
|
return new xmlrpcval($var, "string");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class XR_Alib extends alib{
|
||||||
|
function xr_test($input){
|
||||||
|
$p1=$input->getParam(0);
|
||||||
|
if(isset($p1) && $p1->scalartyp()=="string") $s=$p1->scalarval();
|
||||||
|
else return new xmlrpcresp(0, 801, "xr_login: wrong 1st parameter, string expected.");
|
||||||
|
$p2=$input->getParam(1);
|
||||||
|
if(isset($p2) && $p2->scalartyp()=="string") $sessid=$p2->scalarval();
|
||||||
|
else return new xmlrpcresp(0, 801, "xr_login: wrong 2nd parameter, string expected.");
|
||||||
|
return new xmlrpcresp(v2xr(strtoupper($s)."_".$this->getSessLogin($sessid)."_".$sessid, false));
|
||||||
|
}
|
||||||
|
function xr_login($input){
|
||||||
|
$p1=$input->getParam(0);
|
||||||
|
if(isset($p1) && $p1->scalartyp()=="string") $login=$p1->scalarval();
|
||||||
|
else return new xmlrpcresp(0, 801, "xr_login: wrong 1st parameter, string expected.");
|
||||||
|
$p2=$input->getParam(1);
|
||||||
|
if(isset($p2) && $p2->scalartyp()=="string") $pass=$p2->scalarval();
|
||||||
|
else return new xmlrpcresp(0, 801, "xr_login: wrong 2nd parameter, string expected.");
|
||||||
|
if(!($res = $this->login($login, $pass)))
|
||||||
|
return new xmlrpcresp(0, 802, "xr_login: login failed - incorrect username or password.");
|
||||||
|
else
|
||||||
|
return new xmlrpcresp(v2xr($res, false));
|
||||||
|
}
|
||||||
|
function xr_logout($input){
|
||||||
|
$p1=$input->getParam(0);
|
||||||
|
if(isset($p1) && $p1->scalartyp()=="string") $sessid=$p1->scalarval();
|
||||||
|
else return new xmlrpcresp(0, 801, "xr_login: wrong 2nd parameter, string expected.");
|
||||||
|
$res = $this->logout($sessid);
|
||||||
|
if(!PEAR::isError($res)) return new xmlrpcresp(v2xr('Bye', false));
|
||||||
|
else return new xmlrpcresp(0, 803, "xr_logout: logout failed - not logged.");
|
||||||
|
}
|
||||||
|
function xr_getDir($input){
|
||||||
|
$p1=$input->getParam(0);
|
||||||
|
if(isset($p1) && ($p1->scalartyp()=="int") && is_numeric($id=$p1->scalarval()));
|
||||||
|
else return new xmlrpcresp(0, 801, "xr_getDir: wrong 1st parameter, int expected.");
|
||||||
|
$res = $this->getDir($id, 'name');
|
||||||
|
return new xmlrpcresp(v2xr($res, false));
|
||||||
|
}
|
||||||
|
function xr_getPath($input){
|
||||||
|
$p1=$input->getParam(0);
|
||||||
|
if(isset($p1) && ($p1->scalartyp()=="int") && is_numeric($id=$p1->scalarval()));
|
||||||
|
else return new xmlrpcresp(0, 801, "xr_getPath: wrong 1st parameter, int expected.");
|
||||||
|
$res = $this->getPath($id, 'id, name');
|
||||||
|
return new xmlrpcresp(v2xr($res, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$alib = &new XR_Alib($dbc, $config);
|
||||||
|
|
||||||
|
$s=new xmlrpc_server( array(
|
||||||
|
"alib.xrTest" => array(
|
||||||
|
"function" => array(&$alib, 'xr_test'),
|
||||||
|
"signature" => array(array($xmlrpcString, $xmlrpcString, $xmlrpcString)),
|
||||||
|
"docstring" => ""
|
||||||
|
),
|
||||||
|
"alib.login" => array(
|
||||||
|
"function" => array(&$alib, 'xr_login'),
|
||||||
|
"signature" => array(array($xmlrpcString, $xmlrpcString, $xmlrpcString)),
|
||||||
|
"docstring" => ""
|
||||||
|
),
|
||||||
|
"alib.logout" => array(
|
||||||
|
"function" => array(&$alib, 'xr_logout'),
|
||||||
|
"signature" => array(array($xmlrpcString, $xmlrpcString)),
|
||||||
|
"docstring" => ""
|
||||||
|
),
|
||||||
|
"alib.getDir" => array(
|
||||||
|
"function" => array(&$alib, 'xr_getDir'),
|
||||||
|
"signature" => array(array($xmlrpcArray, $xmlrpcInt)),
|
||||||
|
"docstring" => "returns directory listing of object with given id"
|
||||||
|
),
|
||||||
|
"alib.getPath" => array(
|
||||||
|
"function" => array(&$alib, 'xr_getPath'),
|
||||||
|
"signature" => array(array($xmlrpcArray, $xmlrpcInt)),
|
||||||
|
"docstring" => "returns listing of object in path from rootnode to object with given id"
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
#header("Content-type: text/plain");
|
||||||
|
#print_r($dirlist = getDir());
|
||||||
|
|
||||||
|
require_once"../example/alib_f.php";
|
||||||
|
?>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
// $Id: index.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
|
||||||
|
header ("location: xr_cli_test.php");
|
||||||
|
die;
|
||||||
|
|
||||||
|
?>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,450 @@
|
||||||
|
<?php
|
||||||
|
// by Edd Dumbill (C) 1999-2002
|
||||||
|
// <edd@usefulinc.com>
|
||||||
|
// $Id: xmlrpcs.inc,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
|
||||||
|
// Copyright (c) 1999,2000,2002 Edd Dumbill.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// * Neither the name of the "XML-RPC for PHP" nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// XML RPC Server class
|
||||||
|
// requires: xmlrpc.inc
|
||||||
|
|
||||||
|
// listMethods: either a string, or nothing
|
||||||
|
$_xmlrpcs_listMethods_sig=array(array($xmlrpcArray, $xmlrpcString), array($xmlrpcArray));
|
||||||
|
$_xmlrpcs_listMethods_doc='This method lists all the methods that the XML-RPC server knows how to dispatch';
|
||||||
|
function _xmlrpcs_listMethods($server, $m)
|
||||||
|
{
|
||||||
|
global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
|
||||||
|
$v=new xmlrpcval();
|
||||||
|
$dmap=$server->dmap;
|
||||||
|
$outAr=array();
|
||||||
|
for(reset($dmap); list($key, $val)=each($dmap); )
|
||||||
|
{
|
||||||
|
$outAr[]=new xmlrpcval($key, 'string');
|
||||||
|
}
|
||||||
|
$dmap=$_xmlrpcs_dmap;
|
||||||
|
for(reset($dmap); list($key, $val)=each($dmap); )
|
||||||
|
{
|
||||||
|
$outAr[]=new xmlrpcval($key, 'string');
|
||||||
|
}
|
||||||
|
$v->addArray($outAr);
|
||||||
|
return new xmlrpcresp($v);
|
||||||
|
}
|
||||||
|
|
||||||
|
$_xmlrpcs_methodSignature_sig=array(array($xmlrpcArray, $xmlrpcString));
|
||||||
|
$_xmlrpcs_methodSignature_doc='Returns an array of known signatures (an array of arrays) for the method name passed. If no signatures are known, returns a none-array (test for type != array to detect missing signature)';
|
||||||
|
function _xmlrpcs_methodSignature($server, $m)
|
||||||
|
{
|
||||||
|
global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
|
||||||
|
|
||||||
|
$methName=$m->getParam(0);
|
||||||
|
$methName=$methName->scalarval();
|
||||||
|
if (ereg("^system\.", $methName))
|
||||||
|
{
|
||||||
|
$dmap=$_xmlrpcs_dmap; $sysCall=1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$dmap=$server->dmap; $sysCall=0;
|
||||||
|
}
|
||||||
|
// print "<!-- ${methName} -->\n";
|
||||||
|
if (isset($dmap[$methName]))
|
||||||
|
{
|
||||||
|
if ($dmap[$methName]['signature'])
|
||||||
|
{
|
||||||
|
$sigs=array();
|
||||||
|
$thesigs=$dmap[$methName]['signature'];
|
||||||
|
for($i=0; $i<sizeof($thesigs); $i++)
|
||||||
|
{
|
||||||
|
$cursig=array();
|
||||||
|
$inSig=$thesigs[$i];
|
||||||
|
for($j=0; $j<sizeof($inSig); $j++)
|
||||||
|
{
|
||||||
|
$cursig[]=new xmlrpcval($inSig[$j], 'string');
|
||||||
|
}
|
||||||
|
$sigs[]=new xmlrpcval($cursig, 'array');
|
||||||
|
}
|
||||||
|
$r=new xmlrpcresp(new xmlrpcval($sigs, 'array'));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$r=new xmlrpcresp(new xmlrpcval('undef', 'string'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$r=new xmlrpcresp(0,$xmlrpcerr['introspect_unknown'], $xmlrpcstr['introspect_unknown']);
|
||||||
|
}
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
$_xmlrpcs_methodHelp_sig=array(array($xmlrpcString, $xmlrpcString));
|
||||||
|
$_xmlrpcs_methodHelp_doc='Returns help text if defined for the method passed, otherwise returns an empty string';
|
||||||
|
function _xmlrpcs_methodHelp($server, $m)
|
||||||
|
{
|
||||||
|
global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
|
||||||
|
|
||||||
|
$methName=$m->getParam(0);
|
||||||
|
$methName=$methName->scalarval();
|
||||||
|
if (ereg("^system\.", $methName))
|
||||||
|
{
|
||||||
|
$dmap=$_xmlrpcs_dmap; $sysCall=1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$dmap=$server->dmap; $sysCall=0;
|
||||||
|
}
|
||||||
|
// print "<!-- ${methName} -->\n";
|
||||||
|
if (isset($dmap[$methName]))
|
||||||
|
{
|
||||||
|
if ($dmap[$methName]['docstring'])
|
||||||
|
{
|
||||||
|
$r=new xmlrpcresp(new xmlrpcval($dmap[$methName]["docstring"]), 'string');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$r=new xmlrpcresp(new xmlrpcval('', 'string'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$r=new xmlrpcresp(0, $xmlrpcerr['introspect_unknown'], $xmlrpcstr['introspect_unknown']);
|
||||||
|
}
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
$_xmlrpcs_multicall_sig = array(array($xmlrpcArray, $xmlrpcArray));
|
||||||
|
$_xmlrpcs_multicall_doc = 'Boxcar multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details';
|
||||||
|
|
||||||
|
function _xmlrpcs_multicall_error($err)
|
||||||
|
{
|
||||||
|
if (is_string($err))
|
||||||
|
{
|
||||||
|
global $xmlrpcerr, $xmlrpcstr;
|
||||||
|
$str = $xmlrpcstr["multicall_${err}"];
|
||||||
|
$code = $xmlrpcerr["multicall_${err}"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$code = $err->faultCode();
|
||||||
|
$str = $err->faultString();
|
||||||
|
}
|
||||||
|
$struct['faultCode'] = new xmlrpcval($code, 'int');
|
||||||
|
$struct['faultString'] = new xmlrpcval($str, 'string');
|
||||||
|
return new xmlrpcval($struct, 'struct');
|
||||||
|
}
|
||||||
|
|
||||||
|
function _xmlrpcs_multicall_do_call($server, $call)
|
||||||
|
{
|
||||||
|
if ($call->kindOf() != 'struct')
|
||||||
|
return _xmlrpcs_multicall_error('notstruct');
|
||||||
|
$methName = $call->structmem('methodName');
|
||||||
|
if (!$methName)
|
||||||
|
return _xmlrpcs_multicall_error('nomethod');
|
||||||
|
if ($methName->kindOf() != 'scalar' || $methName->scalartyp() != 'string')
|
||||||
|
return _xmlrpcs_multicall_error('notstring');
|
||||||
|
if ($methName->scalarval() == 'system.multicall')
|
||||||
|
return _xmlrpcs_multicall_error('recursion');
|
||||||
|
|
||||||
|
$params = $call->structmem('params');
|
||||||
|
if (!$params)
|
||||||
|
return _xmlrpcs_multicall_error('noparams');
|
||||||
|
if ($params->kindOf() != 'array')
|
||||||
|
return _xmlrpcs_multicall_error('notarray');
|
||||||
|
$numParams = $params->arraysize();
|
||||||
|
|
||||||
|
$msg = new xmlrpcmsg($methName->scalarval());
|
||||||
|
for ($i = 0; $i < $numParams; $i++)
|
||||||
|
$msg->addParam($params->arraymem($i));
|
||||||
|
|
||||||
|
$result = $server->execute($msg);
|
||||||
|
|
||||||
|
if ($result->faultCode() != 0)
|
||||||
|
return _xmlrpcs_multicall_error($result); // Method returned fault.
|
||||||
|
|
||||||
|
return new xmlrpcval(array($result->value()), "array");
|
||||||
|
}
|
||||||
|
|
||||||
|
function _xmlrpcs_multicall($server, $m)
|
||||||
|
{
|
||||||
|
$calls = $m->getParam(0);
|
||||||
|
$numCalls = $calls->arraysize();
|
||||||
|
$result = array();
|
||||||
|
|
||||||
|
for ($i = 0; $i < $numCalls; $i++)
|
||||||
|
{
|
||||||
|
$call = $calls->arraymem($i);
|
||||||
|
$result[$i] = _xmlrpcs_multicall_do_call($server, $call);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new xmlrpcresp(new xmlrpcval($result, 'array'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$_xmlrpcs_dmap=array(
|
||||||
|
'system.listMethods' => array(
|
||||||
|
'function' => '_xmlrpcs_listMethods',
|
||||||
|
'signature' => $_xmlrpcs_listMethods_sig,
|
||||||
|
'docstring' => $_xmlrpcs_listMethods_doc),
|
||||||
|
'system.methodHelp' => array(
|
||||||
|
'function' => '_xmlrpcs_methodHelp',
|
||||||
|
'signature' => $_xmlrpcs_methodHelp_sig,
|
||||||
|
'docstring' => $_xmlrpcs_methodHelp_doc),
|
||||||
|
'system.methodSignature' => array(
|
||||||
|
'function' => '_xmlrpcs_methodSignature',
|
||||||
|
'signature' => $_xmlrpcs_methodSignature_sig,
|
||||||
|
'docstring' => $_xmlrpcs_methodSignature_doc),
|
||||||
|
'system.multicall' => array(
|
||||||
|
'function' => '_xmlrpcs_multicall',
|
||||||
|
'signature' => $_xmlrpcs_multicall_sig,
|
||||||
|
'docstring' => $_xmlrpcs_multicall_doc
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$_xmlrpc_debuginfo='';
|
||||||
|
function xmlrpc_debugmsg($m)
|
||||||
|
{
|
||||||
|
global $_xmlrpc_debuginfo;
|
||||||
|
$_xmlrpc_debuginfo=$_xmlrpc_debuginfo . $m . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
class xmlrpc_server
|
||||||
|
{
|
||||||
|
var $dmap=array();
|
||||||
|
|
||||||
|
function xmlrpc_server($dispMap='', $serviceNow=1)
|
||||||
|
{
|
||||||
|
global $HTTP_RAW_POST_DATA;
|
||||||
|
// dispMap is a dispatch array of methods
|
||||||
|
// mapped to function names and signatures
|
||||||
|
// if a method
|
||||||
|
// doesn't appear in the map then an unknown
|
||||||
|
// method error is generated
|
||||||
|
/* milosch - changed to make passing dispMap optional.
|
||||||
|
* instead, you can use the class add_to_map() function
|
||||||
|
* to add functions manually (borrowed from SOAPX4)
|
||||||
|
*/
|
||||||
|
if($dispMap)
|
||||||
|
{
|
||||||
|
$this->dmap = $dispMap;
|
||||||
|
if($serviceNow)
|
||||||
|
{
|
||||||
|
$this->service();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function serializeDebug()
|
||||||
|
{
|
||||||
|
global $_xmlrpc_debuginfo;
|
||||||
|
if ($_xmlrpc_debuginfo!='')
|
||||||
|
{
|
||||||
|
return "<!-- DEBUG INFO:\n\n" . $_xmlrpc_debuginfo . "\n-->\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function service()
|
||||||
|
{
|
||||||
|
global $xmlrpc_defencoding;
|
||||||
|
|
||||||
|
$r=$this->parseRequest();
|
||||||
|
$payload='<?xml version="1.0" encoding="' . $xmlrpc_defencoding . '"?>' . "\n"
|
||||||
|
. $this->serializeDebug()
|
||||||
|
. $r->serialize();
|
||||||
|
Header("Content-type: text/xml\r\nContent-length: " .
|
||||||
|
strlen($payload));
|
||||||
|
print $payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
add a method to the dispatch map
|
||||||
|
*/
|
||||||
|
function add_to_map($methodname,$function,$sig,$doc)
|
||||||
|
{
|
||||||
|
$this->dmap[$methodname] = array(
|
||||||
|
'function' => $function,
|
||||||
|
'signature' => $sig,
|
||||||
|
'docstring' => $doc
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifySignature($in, $sig)
|
||||||
|
{
|
||||||
|
for($i=0; $i<sizeof($sig); $i++)
|
||||||
|
{
|
||||||
|
// check each possible signature in turn
|
||||||
|
$cursig=$sig[$i];
|
||||||
|
if (sizeof($cursig)==$in->getNumParams()+1)
|
||||||
|
{
|
||||||
|
$itsOK=1;
|
||||||
|
for($n=0; $n<$in->getNumParams(); $n++)
|
||||||
|
{
|
||||||
|
$p=$in->getParam($n);
|
||||||
|
// print "<!-- $p -->\n";
|
||||||
|
if ($p->kindOf() == 'scalar')
|
||||||
|
{
|
||||||
|
$pt=$p->scalartyp();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$pt=$p->kindOf();
|
||||||
|
}
|
||||||
|
// $n+1 as first type of sig is return type
|
||||||
|
if ($pt != $cursig[$n+1])
|
||||||
|
{
|
||||||
|
$itsOK=0;
|
||||||
|
$pno=$n+1; $wanted=$cursig[$n+1]; $got=$pt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($itsOK)
|
||||||
|
{
|
||||||
|
return array(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array(0, "Wanted ${wanted}, got ${got} at param ${pno})");
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseRequest($data='')
|
||||||
|
{
|
||||||
|
global $_xh,$HTTP_RAW_POST_DATA;
|
||||||
|
global $xmlrpcerr, $xmlrpcstr, $xmlrpcerrxml, $xmlrpc_defencoding,
|
||||||
|
$_xmlrpcs_dmap;
|
||||||
|
|
||||||
|
if ($data=="")
|
||||||
|
{
|
||||||
|
$data=$HTTP_RAW_POST_DATA;
|
||||||
|
}
|
||||||
|
$parser = xml_parser_create($xmlrpc_defencoding);
|
||||||
|
|
||||||
|
$_xh[$parser]=array();
|
||||||
|
$_xh[$parser]['st']='';
|
||||||
|
$_xh[$parser]['cm']=0;
|
||||||
|
$_xh[$parser]['isf']=0;
|
||||||
|
$_xh[$parser]['params']=array();
|
||||||
|
$_xh[$parser]['method']='';
|
||||||
|
|
||||||
|
// decompose incoming XML into request structure
|
||||||
|
|
||||||
|
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
|
||||||
|
xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee');
|
||||||
|
xml_set_character_data_handler($parser, 'xmlrpc_cd');
|
||||||
|
xml_set_default_handler($parser, 'xmlrpc_dh');
|
||||||
|
if (!xml_parse($parser, $data, 1))
|
||||||
|
{
|
||||||
|
// return XML error as a faultCode
|
||||||
|
$r=new xmlrpcresp(0,
|
||||||
|
$xmlrpcerrxml+xml_get_error_code($parser),
|
||||||
|
sprintf("XML error: %s at line %d",
|
||||||
|
xml_error_string(xml_get_error_code($parser)),
|
||||||
|
xml_get_current_line_number($parser)));
|
||||||
|
xml_parser_free($parser);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xml_parser_free($parser);
|
||||||
|
$m=new xmlrpcmsg($_xh[$parser]['method']);
|
||||||
|
// now add parameters in
|
||||||
|
$plist="";
|
||||||
|
for($i=0; $i<sizeof($_xh[$parser]['params']); $i++)
|
||||||
|
{
|
||||||
|
//print "<!-- " . $_xh[$parser]['params'][$i]. "-->\n";
|
||||||
|
$plist.="$i - " . $_xh[$parser]['params'][$i]. " \n";
|
||||||
|
eval('$m->addParam(' . $_xh[$parser]['params'][$i]. ");");
|
||||||
|
}
|
||||||
|
// uncomment this to really see what the server's getting!
|
||||||
|
// xmlrpc_debugmsg($plist);
|
||||||
|
|
||||||
|
$r = $this->execute($m);
|
||||||
|
}
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
function execute ($m)
|
||||||
|
{
|
||||||
|
global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
|
||||||
|
// now to deal with the method
|
||||||
|
$methName = $m->method();
|
||||||
|
$sysCall = ereg("^system\.", $methName);
|
||||||
|
$dmap = $sysCall ? $_xmlrpcs_dmap : $this->dmap;
|
||||||
|
|
||||||
|
if (!isset($dmap[$methName]['function']))
|
||||||
|
{
|
||||||
|
// No such method
|
||||||
|
return new xmlrpcresp(0,
|
||||||
|
$xmlrpcerr['unknown_method'],
|
||||||
|
$xmlrpcstr['unknown_method']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check signature.
|
||||||
|
if (isset($dmap[$methName]['signature']))
|
||||||
|
{
|
||||||
|
$sig = $dmap[$methName]['signature'];
|
||||||
|
list ($ok, $errstr) = $this->verifySignature($m, $sig);
|
||||||
|
if (!$ok)
|
||||||
|
{
|
||||||
|
// Didn't match.
|
||||||
|
return new xmlrpcresp(0,
|
||||||
|
$xmlrpcerr['incorrect_params'],
|
||||||
|
$xmlrpcstr['incorrect_params'] . ": ${errstr}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$func = $dmap[$methName]['function'];
|
||||||
|
|
||||||
|
if ($sysCall)
|
||||||
|
{
|
||||||
|
return call_user_func($func, $this, $m);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return call_user_func($func, $m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function echoInput()
|
||||||
|
{
|
||||||
|
global $HTTP_RAW_POST_DATA;
|
||||||
|
|
||||||
|
// a debugging routine: just echos back the input
|
||||||
|
// packet as a string value
|
||||||
|
|
||||||
|
$r=new xmlrpcresp;
|
||||||
|
$r->xv=new xmlrpcval( "'Aha said I: '" . $HTTP_RAW_POST_DATA, 'string');
|
||||||
|
print $r->serialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,55 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
# $Id: xr_cli_pok.py,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
|
||||||
|
from xmlrpclib import *
|
||||||
|
import sys
|
||||||
|
|
||||||
|
if len(sys.argv)<3:
|
||||||
|
print """
|
||||||
|
Usage: xr_cli_pok.py http://<server>/<path>/xmlrpc/alib_xr.php <command> <args>
|
||||||
|
commands and args:
|
||||||
|
test <teststring> [<sessin_id>]
|
||||||
|
login <username> <password>
|
||||||
|
logout <session_id>
|
||||||
|
"""
|
||||||
|
sys.exit(1)
|
||||||
|
elif sys.argv[2]=="test":
|
||||||
|
if len(sys.argv)>3:
|
||||||
|
tstr=sys.argv[3]
|
||||||
|
if len(sys.argv)>4:
|
||||||
|
sessid=sys.argv[4]
|
||||||
|
else:
|
||||||
|
sessid=''
|
||||||
|
path=sys.argv[1]
|
||||||
|
server = Server(path)
|
||||||
|
try:
|
||||||
|
r = server.alib.xrTest(tstr, sessid)
|
||||||
|
print r
|
||||||
|
except Error, v:
|
||||||
|
print "XML-RPC Error:",v
|
||||||
|
elif sys.argv[2]=="login":
|
||||||
|
login=sys.argv[3]
|
||||||
|
passwd=sys.argv[4]
|
||||||
|
path=sys.argv[1]
|
||||||
|
server = Server(path)
|
||||||
|
try:
|
||||||
|
r = server.alib.login(login, passwd)
|
||||||
|
print r
|
||||||
|
except Error, v:
|
||||||
|
print "XML-RPC Error:",v
|
||||||
|
elif sys.argv[2]=="logout":
|
||||||
|
sessid=sys.argv[3]
|
||||||
|
path=sys.argv[1]
|
||||||
|
server = Server(path)
|
||||||
|
try:
|
||||||
|
r = server.alib.logout(sessid)
|
||||||
|
print r
|
||||||
|
except Error, v:
|
||||||
|
print "XML-RPC Error:",v
|
||||||
|
else:
|
||||||
|
print "Unknown command: "+sys.argv[2]
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
<?php
|
||||||
|
// $Id: xr_cli_test.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
|
||||||
|
|
||||||
|
include("xmlrpc.inc");
|
||||||
|
|
||||||
|
$host = "localhost";
|
||||||
|
$port = 80;
|
||||||
|
$serverscript = dirname($_SERVER['PHP_SELF'])."/alib_xr.php";
|
||||||
|
$log = '';
|
||||||
|
$ak = $_REQUEST['ak'];
|
||||||
|
$sessid = $_REQUEST['sessid'];
|
||||||
|
|
||||||
|
switch($ak){
|
||||||
|
case"test":
|
||||||
|
$f=new xmlrpcmsg('alib.xrTest',
|
||||||
|
array(new xmlrpcval($_REQUEST['str'], "string"),
|
||||||
|
new xmlrpcval($_REQUEST['sessid'], "string")));
|
||||||
|
break;
|
||||||
|
case"login":
|
||||||
|
$f=new xmlrpcmsg('alib.login', array(new xmlrpcval($_REQUEST['login'], "string"),
|
||||||
|
new xmlrpcval($_REQUEST['pass'], "string")));
|
||||||
|
break;
|
||||||
|
case"logout":
|
||||||
|
$f=new xmlrpcmsg('alib.logout', array(new xmlrpcval($_REQUEST['sessid'], "string")));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($ak){
|
||||||
|
case"test":
|
||||||
|
case"login":
|
||||||
|
case"logout":
|
||||||
|
$c=new xmlrpc_client($serverscript, $host, $port);
|
||||||
|
#$c->setDebug(1);
|
||||||
|
$r=$c->send($f);
|
||||||
|
if (!($r->faultCode()>0)) {
|
||||||
|
$v=$r->value();
|
||||||
|
$log = $v->serialize();
|
||||||
|
if($ak=='test')
|
||||||
|
{ $log = split('_',$log); $log="{$log[0]}\nusername: {$log[1]}\ntoken: {$log[2]}"; }
|
||||||
|
if($ak=='login') $sessid = $v->scalarval();
|
||||||
|
if($ak=='logout') $sessid = '';
|
||||||
|
} else {
|
||||||
|
$log = "Fault:\n Code: ".$r->faultCode()."\nReason:'".$r->faultString()."'<BR>\n";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
<html><head>
|
||||||
|
<title>Alib XMLRPC test client</title>
|
||||||
|
</head><body>
|
||||||
|
<h2>Alib XMLRPC test client</h2>
|
||||||
|
XMLRPC server: <b><?="http://$host:$port$serverscript"?></b><br>
|
||||||
|
|
||||||
|
<?=($log?'<h3>Output:</h3>':'')?>
|
||||||
|
<pre style="background-color:#ddd"><?=$log?></pre>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h3>test</h3>
|
||||||
|
flip teststring to uppercase and print username and session token<br>
|
||||||
|
<form method="post">
|
||||||
|
test string: <input type="text" name="str" value="abCDef"><br>
|
||||||
|
token: <input type="text" name="sessid" value="<?=$sessid?>" size="34"><br>
|
||||||
|
<input type="hidden" name="ak" value="test">
|
||||||
|
<input type="submit" value="Test">
|
||||||
|
</form>
|
||||||
|
<hr>
|
||||||
|
<h3>login</h3>
|
||||||
|
<form method="post">
|
||||||
|
username: <input type="text" name="login" value="test1"><br>
|
||||||
|
password: <input type="password" name="pass" value="a"><br>
|
||||||
|
<input type="hidden" name="ak" value="login">
|
||||||
|
<input type="submit" value="Login">
|
||||||
|
</form>
|
||||||
|
<hr>
|
||||||
|
<h3>logout</h3>
|
||||||
|
<form method="post">
|
||||||
|
token: <input type="text" name="sessid" value="<?=$sessid?>" size="34"><br>
|
||||||
|
<input type="hidden" name="ak" value="logout">
|
||||||
|
<input type="submit" value="Logout">
|
||||||
|
</form>
|
||||||
|
<hr>
|
||||||
|
<a href="../">Back</a>
|
||||||
|
</body></html>
|
Loading…
Reference in New Issue