Pman/Images.php
[Pman.Base] / Pman / Roo.php
index e56f494..0257aa6 100644 (file)
@@ -5,34 +5,48 @@ require_once 'Pman.php';
 /**
  * 
  * 
- * not really sure how save our factory method is....!!!
- * 
+  * 
  * 
  * Uses these methods of the dataobjects:
+ * 
  * - checkPerm('L'/'E'/'A', $authuser) - can we list the stuff
  * 
  * - applySort($au, $sortcol, $direction, $array_of_columns, $multisort) -- does not support multisort at present..
- * - applyFilters($_REQUEST, $authUser) -- apply any query filters on data. and hide stuff not to be seen.
+ * - applyFilters($_REQUEST, $authUser, $roo) -- apply any query filters on data. and hide stuff not to be seen.
  * - postListExtra($_REQUEST) : array(extra_name => data) - add extra column data on the results (like new messages etc.)
  * - postListFilter($data, $authUser, $request) return $data - add extra data to an object
  * 
  * - toRooSingleArray($authUser, $request) // single fetch, add data..
  * - toRooArray($request) /// toArray if you need to return different data.. for a list fetch.
+ *
  * 
- * 
- * - beforeDelete($ar) -- return false for fail and set DO->err;
- *                        Argument is an array of un-find/fetched dependant items.
+ *  CRUD - before/after handlers..
+ * - setFromRoo($ar, $roo) - values from post (deal with dates etc.) - return true|error string.
+ *      ... call $roo->jerr() on failure...
+ *
+ *  BEFORE
+ * - beforeDelete($dependants_array, $roo) Argument is an array of un-find/fetched dependant items.
+ *                      - jerr() will stop insert.. (Prefered)
+ *                      - return false for fail and set DO->err;
+ * - beforeUpdate($old, $request,$roo) - after update - jerr() will stop insert..
+ * - beforeInsert($request,$roo) - before insert - jerr() will stop insert..
+ *
+ *  AFTER
  * - onUpdate($old, $request,$roo) - after update // return value ignored
  * - onInsert($request,$roo) - after insert
  * - onUpload($roo)
- * - setFromRoo($ar) - values from post (deal with dates etc.) - return true|error string.
+ * 
  * 
  * - toEventString (for logging - this is generically prefixed to all database operations.)
  */
 
 class Pman_Roo extends Pman
 {
-    
+    /**
+     * if set to an array (when extending this, then you can restrict which tables are available
+     */
+    var $validTables = false; 
     
     var $key; // used by update currenly to store primary key.
     
@@ -46,36 +60,74 @@ class Pman_Roo extends Pman
         return true;
     }
     /**
-     * GET method   Roo/TABLENAME.php 
-     * -- defaults to listing data. with args.
+     * GET method   Roo/TABLENAME.php
      *
+     * Generally for SELECT or Single SELECT
+     *
+     * Single SELECT:
+     *    _id=value          single fetch based on primary id.
+     *    lookup[key]=value  single fetch based on a single key value lookup.
+     *                       multiple key/value can be used. eg. ontable+onid..
+     *    _columns           what to return.
+     *
+     *    
+     * Search SELECT
+     *    COLUMNS to fetch
+     *      _columns=a,b,c,d     comma seperated list of columns.
+     *      _distinct=name        a distinct column lookup.
+     *
+     *    WHERE 
+     *       !colname=....                 => colname != ....
+     *       !colname[0]=... !colname[1]=... => colname NOT IN (.....) ** only supports main table at present..
+     *       colname[0]=... colname[1]=... => colname IN (.....) ** only supports main table at present..
+     *
+     *    ORDER BY
+     *       sort=name          what to sort.
+     *       sort=a,b,d         can support multiple columns
+     *       dir=ASC            what direction
+     *       _multisort ={...}  JSON encoded { sort : { row : direction }, order : [ row, row, row ] }
+     *
+     *    LIMIT
+     *      start=0         limit start
+     *      limit=25        limit number 
      * 
-     * !colname=....                 => colname != ....
-     * !colname[0]=... !colname[1]=... => colname NOT IN (.....) ** only supports main table at present..
-     * colname[0]=... colname[1]=... => colname IN (.....) ** only supports main table at present..
-     * 
-     * other opts:
-     * _post      = simulate a post with debuggin on.
-     * lookup     =  array( k=>v) single fetch based on a key/value pair
-     * _id        =  single fetch based on id.
-     * _delete    = delete a list of ids element. (seperated by ,);
-     * _columns   = comma seperated list of columns.
-     * _distinct   = a distinct column lookup.
-     * _requestMeta = default behaviour of Roo stores.. on first query..
-     * 
-     * csvCols[0] csvCols[1]....    = .... column titles for CSV output
      * 
-     * csvTitles[0], csvTitles[1] ....  = columns to use for CSV output
+     *    Simple CSV support
+     *      csvCols[0] csvCols[1]....    = .... column titles for CSV output
+     *      csvTitles[0], csvTitles[1] ....  = columns to use for CSV output
      *
-     * sort        = sort column (',' comma delimited)
-     * dir         = sort direction ?? in future comma delimited...
-     * _multisort  = JSON encoded { sort : { row : direction }, order : [ row, row, row ] }
-     * start       = limit start
-     * limit       = limit number 
-     * 
-     * _toggleActive !:!:!:! - this hsould not really be here..
-     * query[add_blank] - add a line in with an empty option...  - not really needed???
+     *  Depricated  
+     *      _toggleActive !:!:!:! - this hsould not really be here..
+     *      query[add_blank] - add a line in with an empty option...  - not really needed???
+     *
+     * DEBUGGING
+     *  _post      = simulate a post with debuggin on.
+     *  _delete    = delete a list of ids element. (depricated.. this will be removed...)
+     *  _debug     = turn on DB_dataobject deubbing, must be admin at present..
+     *
+     *
+     * CALLS methods on dataobjects if they exist
+     *   checkPerm('S' , $authuser)
+     *                      - can we list the stuff
+     *                      - return false to disallow...
+     *   applySort($au, $sortcol, $direction, $array_of_columns, $multisort)
+     *                     -- does not support multisort at present..
+     *   applyFilters($_REQUEST, $authUser, $roo)
+     *                     -- apply any query filters on data. and hide stuff not to be seen.
+     *                     -- can exit by calling $roo->jerr()
+     *   postListExtra($_REQUEST) : array(extra_name => data)
+     *                     - add extra column data on the results (like new messages etc.)
+     *   postListFilter($data, $authUser, $request) return $data
+     *                      - add extra data to an object
      * 
+     *   toRooSingleArray($authUser, $request) : array
+     *                       - called on single fetch only, add or maniuplate returned array data.
+     *   toRooArray($request) : array
+     *                      - called if singleArray is unavailable on single fetch.
+     *                      - always tried for mutiple results.
+     *   autoJoin($request) 
+     *                      - standard DataObject feature - causes all results to show all
+     *                        referenced data.
      */
     function get($tab)
     {
@@ -83,59 +135,42 @@ class Pman_Roo extends Pman
        //echo '<PRE>';print_R($_GET);
       //DB_DataObject::debuglevel(1);
         
-        $this->init(); // from pnan.
+        $this->init(); // from pman.
         //DB_DataObject::debuglevel(1);
         HTML_FlexyFramework::get()->generateDataobjectsCache($this->isDev);
+        
+        
+   
+        
         // debugging...
         if (!empty($_GET['_post'])) {
             $_POST  = $_GET;
             //DB_DAtaObject::debuglevel(1);
             return $this->post($tab);
         }
-        $tab = str_replace('/', '',$tab); // basic protection??
         
-        $x = DB_DataObject::factory($tab);
-        
-        if (!is_a($x, 'DB_DataObject')) {
-            $this->jerr('invalid url');
+        if (isset($_REQUEST['_debug']) && in_array('Administrators', $this->authUser->groups('name'))) {
+            DB_DAtaObject::debuglevel((int)$_REQUEST['_debug']);
         }
-        $_columns = !empty($_REQUEST['_columns']) ? explode(',', $_REQUEST['_columns']) : false;
         
-        if (isset( $_REQUEST['lookup'] )) { // single fetch based on key/value pairs
-            if (method_exists($x, 'checkPerm') && !$x->checkPerm('S', $this->authUser))  {
-                $this->jerr("PERMISSION DENIED");
-            }
-            $this->loadMap($x, $_columns);
-            $x->setFrom($_REQUEST['lookup'] );
-            $x->limit(1);
-            if (!$x->find(true)) {
-                $this->jok(false);
-            }
-            $this->jok($x->toArray());
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+   
+         
+        $x = $this->dataObject($tab);
+        
+         $_columns = !empty($_REQUEST['_columns']) ? explode(',', $_REQUEST['_columns']) : false;
+        
+        if (isset( $_REQUEST['lookup'] ) && is_array($_REQUEST['lookup'] )) { // single fetch based on key/value pairs
+            $this->jok($this->selectSingle($x, $_REQUEST['lookup']));
         }
         
         
         
-        if (isset($_REQUEST['_id'])) { // single fetch
-            
-            if (empty($_REQUEST['_id'])) {
-                $this->jok($x->toArray());  // return an empty array!
-            }
-           
-            $this->loadMap($x, $_columns);
-            
-            if (!$x->get($_REQUEST['_id'])) {
-                $this->jerr("no such record");
-            }
-            
-            if (method_exists($x, 'checkPerm') && !$x->checkPerm('S', $this->authUser))  {
-                $this->jerr("PERMISSION DENIED");
-            }
-            
-            $this->jok(method_exists($x, 'toRooSingleArray') ? $x->toRooSingleArray($this->authUser, $_REQUEST) : $x->toArray());
-            
+        if (isset($_REQUEST['_id']) && is_numeric($_REQUEST['_id'])) { // single fetch
+            $this->jok($this->selectSingle($x, $_REQUEST['_id']));
         }
         
+        
        
         if (isset($_REQUEST['_delete'])) {
             
@@ -152,7 +187,7 @@ class Pman_Roo extends Pman
         } 
         
         
-        
+        // Depricated...
         
         if (isset($_REQUEST['_toggleActive'])) {
             // do we really delete stuff!?!?!?
@@ -197,47 +232,45 @@ class Pman_Roo extends Pman
         
         $queryObj = clone($x);
         //DB_DataObject::debuglevel(1);
-        $x->find();
+        if (false === $x->find()) {
+            $this->jerr($x->_lastError->toString());
+            
+        }
         
         
         
         $ret = array();
         
+        // ---------------- THESE ARE DEPRICATED.. they should be moved to the model...
+        
+        
         if (!empty($_REQUEST['query']['add_blank'])) {
             $ret[] = array( 'id' => 0, 'name' => '----');
             $total+=1;
         }
-        // MOVE ME...
-        
-        //if (($tab == 'Groups') && ($_REQUEST['type'] != 0))  { // then it's a list of teams..
-        if ($tab == 'Groups') {
-            
-            $ret[] = array( 'id' => 0, 'name' => 'EVERYONE');
-            $ret[] = array( 'id' => -1, 'name' => 'NOT_IN_GROUP');
-            //$ret[] = array( 'id' => 999999, 'name' => 'ADMINISTRATORS');
-            $total+=2;
-        }
-        
-        // DOWNLOAD...
-        
-          
+         
         $rooar = method_exists($x, 'toRooArray');
-        
+        $_columnsf = $_columns  ? array_flip($_columns) : false;
         while ($x->fetch()) {
             //print_R($x);exit;
             $add = $rooar  ? $x->toRooArray($_REQUEST) : $x->toArray();
             
-            $ret[] =  !$_columns ? $add : array_intersect_key($add, array_flip($_columns));
+            $ret[] =  !$_columns ? $add : array_intersect_key($add, $_columnsf);
         }
+        
         $extra = false;
         if (method_exists($queryObj ,'postListExtra')) {
-            $extra = $queryObj->postListExtra($_REQUEST);
+            $extra = $queryObj->postListExtra($_REQUEST, $this);
         }
+        
+        
         // filter results, and add any data that is needed...
         if (method_exists($x,'postListFilter')) {
             $ret = $x->postListFilter($ret, $this->authUser, $_REQUEST);
         }
         
+        
+        
         if (!empty($_REQUEST['csvCols']) && !empty($_REQUEST['csvTitles']) ) {
             header('Content-type: text/csv');
             
@@ -276,10 +309,168 @@ class Pman_Roo extends Pman
         }
         
        // echo "<PRE>"; print_r($ret);
-        $this->jdata($ret,$total, $extra );
+        $this->jdata($ret, max(count($ret), $total), $extra );
 
     
     }
+    
+     /**
+     * POST method   Roo/TABLENAME  
+     * -- creates, updates, or deletes data.
+     *
+     * INSERT
+     *    if the primary key is empty, this happens
+     *    will automatically set these to current date and authUser->id
+     *        created, created_by, created_dt
+     *        updated, update_by, updated_dt
+     *        modified, modified_by, modified_dt
+     *        
+     *   will return a GET request SINGLE SELECT (and accepts same)
+     *    
+     * DELETE
+     *    _delete=1,2,3     delete a set of data.
+     * UPDATE
+     *    if the primary key value is set, then update occurs.
+     *    will automatically set these to current date and authUser->id
+     *        updated, update_by, updated_dt
+     *        modified, modified_by, modified_dt
+     *        
+     *
+     * Params:
+     *   _delete=1,2,3   causes a delete to occur.
+     *   _ids=1,2,3,4    causes update to occur on all primary ids.
+     *  
+     *  RETURNS
+     *     = same as single SELECT GET request..
+     *
+     *
+     *
+     * DEBUGGING
+     *   _debug=1    forces debug
+     *   _get=1 - causes a get request to occur when doing a POST..
+     *
+     *
+     * CALLS
+     *   these methods on dataobjects if they exist
+     * 
+     *   checkPerm('E' / 'D' , $authuser)
+     *                      - can we list the stuff
+     *                      - return false to disallow...
+   
+     *   toRooSingleArray($authUser, $request) : array
+     *                       - called on single fetch only, add or maniuplate returned array data.
+     *   toRooArray($request) : array
+     *                      - Called if toSingleArray does not exist.
+     *                      - if you need to return different data than toArray..
+     *
+     *   toEventString()
+     *                  (for logging - this is generically prefixed to all database operations.)
+     *
+     *  
+     *   onUpload($roo)
+     *                  called when $_FILES is not empty
+     *
+     *                  
+     *   setFromRoo($ar, $roo)
+     *                      - alternative to setFrom() which is called if this method does not exist
+     *                      - values from post (deal with dates etc.) - return true|error string.
+     *                      - call $roo->jerr() on failure...
+     *
+     * CALLS BEFORE change occurs:
+     *  
+     *     beforeDelete($dependants_array, $roo)
+     *                      Argument is an array of un-find/fetched dependant items.
+     *                      - jerr() will stop insert.. (Prefered)
+     *                      - return false for fail and set DO->err;
+     *                      
+     *      beforeUpdate($old, $request,$roo)
+     *                      - after update - jerr() will stop insert..
+     *      beforeInsert($request,$roo)
+     *                      - before insert - jerr() will stop insert..
+     *
+     * CALLS AFTER change occured
+     * 
+     *      onUpdate($old, $request,$roo)
+     *               - after update // return value ignored
+     *
+     *      onInsert($request,$roo)
+     *                  - after insert
+     * 
+     *
+     * 
+     */                     
+     
+    function post($tab) // update / insert (?? delete??)
+    {
+        
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+   
+        
+        //DB_DataObject::debugLevel(1);
+        if (!empty($_REQUEST['_debug'])) {
+            DB_DataObject::debugLevel(1);
+        }
+        
+        if (!empty($_REQUEST['_get'])) {
+            return $this->get($tab);
+        }
+      
+         
+        $x = $this->dataObject($tab);
+        // find the key and use that to get the thing..
+        $keys = $x->keys();
+        if (empty($keys) ) {
+            $this->jerr('no key');
+        }
+        
+        $this->key = $keys[0];
+        
+          // delete should be here...
+        if (isset($_REQUEST['_delete'])) {
+            // do we really delete stuff!?!?!?
+            return $this->delete($x,$_REQUEST);
+        } 
+         
+        
+        $old = false;
+        
+        // not sure if this is a good idea here...
+        
+        if (!empty($_REQUEST['_ids'])) {
+            $ids = explode(',',$_REQUEST['_ids']);
+            $x->whereAddIn($this->key, $ids, 'int');
+            $ar = $x->fetchAll();
+            foreach($ar as $x) {
+                $this->update($x, $_REQUEST);
+                
+            }
+            // all done..
+            $this->jok("UPDATED");
+            
+            
+        }
+         
+        if (!empty($_REQUEST[$this->key])) {
+            // it's a create..
+            if (!$x->get($this->key, $_REQUEST[$this->key]))  {
+                $this->jerr("Invalid request");
+            }
+            $this->jok($this->update($x, $_REQUEST));
+        } else {
+            
+            if (empty($_POST)) {
+                $this->jerr("No data recieved for inserting");
+            }
+            
+            $this->jok($this->insert($x, $_REQUEST));
+            
+        }
+        
+        
+        
+    }
+    
+    
     /**
      * applySort
      * 
@@ -359,104 +550,61 @@ class Pman_Roo extends Pman
         if ($sort_str) {
             $x->orderBy(implode(', ', $sort_str ));
         }
-         
-        
+          
         
     }
     
     
     
-     /**
-     * POST method   Roo/TABLENAME.php 
-     * -- updates the data..
-     * 
-     * other opts:
-     * _debug - forces debugging on.
-     * _get - forces a get request
-     * _ids - multiple update of records.
-     * {colid} - forces fetching
-     * 
-     */
-    function post($tab) // update / insert (?? dleete??)
+    
+    function selectSingle($x, $id)
     {
-        //DB_DataObject::debugLevel(1);
-        if (!empty($_REQUEST['_debug'])) {
-            DB_DataObject::debugLevel(1);
-        }
         
-        if (!empty($_REQUEST['_get'])) {
-            return $this->get($tab);
-        }
-      
-        $_columns = !empty($_REQUEST['_columns']) ? explode(',', $_REQUEST['_columns']) : false;
         
-        $tab = str_replace('/', '',$tab); // basic protection??
-        $x = DB_DataObject::factory($tab);
-        if (!is_a($x, 'DB_DataObject')) {
-            $this->jerr('invalid url');
-        }
-        // find the key and use that to get the thing..
-        $keys = $x->keys();
-        if (empty($keys) ) {
-            $this->jerr('no key');
-        }
-        
-        $this->key = $keys[0];
-        
-          // delete should be here...
-        if (isset($_REQUEST['_delete'])) {
-            // do we really delete stuff!?!?!?
-            return $this->delete($x,$_REQUEST);
-        } 
          
         
-        $old = false;
+        $_columns = !empty($_REQUEST['_columns']) ? explode(',', $_REQUEST['_columns']) : false;
+
+        if (!is_array($id) && empty($id)) {
+            $this->jok($x->toArray());  // return an empty array!
+        }
+       
+        $this->loadMap($x, $_columns);
         
-        // not sure if this is a good idea here...
+        $this->setFilters($x, $_REQUEST);
         
-        if (!empty($_REQUEST['_ids'])) {
-            $ids = explode(',',$_REQUEST['_ids']);
-            $x->whereAddIn($this->key, $ids, 'int');
-            $ar = $x->fetchAll();
-            foreach($ar as $x) {
-                $this->update($x, $_REQUEST);
-                
+        if (is_array($id)) {
+            // lookup...
+            $x->setFrom($_REQUEST['lookup'] );
+            $x->limit(1);
+            if (!$x->find(true)) {
+                $this->jok(false);
             }
-            // all done..
-            $this->jok("UPDATED");
-            
             
+        } else if (!$x->get($id)) {
+            $this->jerr("no such record");
         }
-         
-        if (!empty($_REQUEST[$this->key])) {
-            // it's a create..
-            if (!$x->get($this->key, $_REQUEST[$this->key]))  {
-                $this->jerr("Invalid request");
-            }
-            $this->jok($this->update($x, $_REQUEST));
-        } else {
-            
-            if (empty($_POST)) {
-                $this->jerr("No data recieved for inserting");
-            }
-            
-            $this->jok($this->insert($x, $_REQUEST));
-            
+        
+        if (method_exists($x, 'checkPerm') && !$x->checkPerm('S', $this->authUser))  {
+            $this->jerr("PERMISSION DENIED");
         }
         
+        $m = method_exists($x, 'toRooSingleArray') ? 'toRooSingleArray' : false;
+        $m = !$m && method_exists($x, 'toRooArray') ? 'toRooArray' : $m;
+        $m = $m ? $m : 'toArray';
+        
+        $this->jok($m == 'toArray' ? $x->toArray() : $x->$m($this->authUser, $_REQUEST) );
         
         
     }
+    
     function insert($x, $req)
     {
         
     
-        if (method_exists($x, 'checkPerm') && !$x->checkPerm('A', $this->authUser, $req))  {
-            $this->jerr("PERMISSION DENIED");
-        }
+       
+        
         
-        $_columns = !empty($req['_columns']) ? explode(',', $req['_columns']) : false;
-   
         if (method_exists($x, 'setFromRoo')) {
             $res = $x->setFromRoo($req, $this);
             if (is_string($res)) {
@@ -466,7 +614,9 @@ class Pman_Roo extends Pman
             $x->setFrom($req);
         }
         
-         
+        if (method_exists($x, 'checkPerm') && !$x->checkPerm('A', $this->authUser, $req))  {
+            $this->jerr("PERMISSION DENIED");
+        }
         $cols = $x->table();
      
         if (isset($cols['created'])) {
@@ -501,7 +651,9 @@ class Pman_Roo extends Pman
         }
         
      
-        
+        if (method_exists($x, 'beforeInsert')) {
+            $x->beforeInsert($_REQUEST, $this);
+        }
         
         
         $res = $x->insert();
@@ -521,17 +673,11 @@ class Pman_Roo extends Pman
             $x->onUpload($this);
         }
         
-        $r = DB_DataObject::factory($x->tableName());
-        // let's assume it has a key!!!
-        
-        $r->{$this->key} = $x->{$this->key};
-        $this->loadMap($r, $_columns);
-        $r->limit(1);
-        $r->find(true);
+        return $this->selectSingle(
+            DB_DataObject::factory($x->tableName()),
+            $x->{$this->key}
+        );
         
-        $rooar = method_exists($r, 'toRooArray');
-        //print_r(var_dump($rooar)); exit;
-        return $rooar  ? $r->toRooArray($_REQUEST) : $r->toArray();
     }
     
     
@@ -575,8 +721,7 @@ class Pman_Roo extends Pman
         
         
        
-        $_columns = !empty($req['_columns']) ? explode(',', $req['_columns']) : false;
-
+         
        
         $old = clone($x);
         $this->old = $x;
@@ -616,6 +761,10 @@ class Pman_Roo extends Pman
             $x->updated_by = $this->authUser->id;
         }
         
+        if (method_exists($x, 'beforeUpdate')) {
+            $x->beforeUpdate($old, $req, $this);
+        }
+        
         //DB_DataObject::DebugLevel(1);
         $res = $x->update($old);
         if ($res === false) {
@@ -631,16 +780,11 @@ class Pman_Roo extends Pman
             $this->jerr($lock_warning);
         }
         
+        return $this->selectSingle(
+            DB_DataObject::factory($x->tableName()),
+            $x->{$this->key}
+        );
         
-        $r = DB_DataObject::factory($x->tableName());
-        // let's assume it has a key!!!
-        $r->{$this->key}= $x->{$this->key};
-        $this->loadMap($r, $_columns);
-        $r->limit(1);
-        $r->find(true);
-        $rooar = method_exists($r, 'toRooArray');
-        //print_r(var_dump($rooar)); exit;
-        return $rooar  ? $r->toRooArray($_REQUEST) : $r->toArray();
     }
     /**
      * Delete a number of records.
@@ -728,7 +872,7 @@ class Pman_Roo extends Pman
             $match_total = 0;
             
             if ( method_exists($xx, 'beforeDelete') ) {
-                if ($xx->beforeDelete($match_ar) === false) {
+                if ($xx->beforeDelete($match_ar, $this) === false) {
                     $errs[] = "Delete failed ({$xx->id})\n".
                         (isset($xx->err) ? $xx->err : '');
                     continue;
@@ -742,7 +886,7 @@ class Pman_Roo extends Pman
                     if (!is_a($chk,'DB_DataObject')) {
                         $this->jerr('Unable to load referenced table, check the links config: ' .$ka[0]);
                     }
-                    $chk->{$ka[1]} =  $xx->$pk;
+                    $chk->{$ka[1]} =  $xx->{$this->key};
                     $matches = $chk->count();
                     $match_total += $matches;
                     if ($matches) {
@@ -972,7 +1116,7 @@ class Pman_Roo extends Pman
        // DB_DataObject::debugLevel(1);
         if (method_exists($x, 'applyFilters')) {
            // DB_DataObject::debugLevel(1);
-            $x->applyFilters($q, $this->authUser);
+            $x->applyFilters($q, $this->authUser, $this);
         }
         $q_filtered = array();
         
@@ -1091,13 +1235,63 @@ class Pman_Roo extends Pman
         }
         
         // - projectdirectory staff list - persn queuy
-      
-         
-       
-         
-          
+     
+        
+    }
+    /**
+     * create the  dataobject from (usually the url)
+     * This uses $this->validTables
+     *           $this->validPrefix (later..)
+     * to determine if class can be created..
+     *
+     */
+     
+    function dataObject($tab)
+    {
+        if (is_array($this->validTables) &&  !in_array($tab,$this->validTables)) {
+            $this->jerr("Invalid url");
+        }
+        $tab = str_replace('/', '',$tab); // basic protection??
+        
+        $x = DB_DataObject::factory($tab);
+        
+        if (!is_a($x, 'DB_DataObject')) {
+            $this->jerr('invalid url');
+        }
+        return $x;
+        
+    }
+    
+    
+    function onPearError($err)
+    {
+        static $reported = false;
+        if ($reported) {
+            return;
+        }
+        $reported = true;
+        $out = $err->toString();
+        
+        
+        //print_R($bt); exit;
+        $ret = array();
+        $n = 0;
+        foreach($err->backtrace as $b) {
+            $ret[] = @$b['file'] . '(' . @$b['line'] . ')@' .   @$b['class'] . '::' . @$b['function'];
+            if ($n > 20) {
+                break;
+            }
+            $n++;
+        }
+        //convert the huge backtrace into something that is readable..
+        $out .= "\n" . implode("\n",  $ret);
+     
+        
+        $this->jerr($out);
+        
         
         
     }
     
+    
 }
\ No newline at end of file