e82bb42ad5b9c508e31876b32d7da2e58d21cfd7
[Pman.Core] / DataObjects / Events.php
1 <?php
2 /**
3  * Table Definition for Events
4  *
5  * objects can implement relatedWhere(), which should return
6  *    'tablename' => array of ids
7  *
8  * 
9  */
10 require_once 'DB/DataObject.php';
11
12 class Pman_Core_DataObjects_Events extends DB_DataObject 
13 {
14     ###START_AUTOCODE
15     /* the code below is auto generated do not remove the above tag */
16
17     public $__table = 'Events';                          // table name
18     public $id;                              // int(11)  not_null primary_key auto_increment
19     public $person_name;                     // string(128)  
20     public $event_when;                      // datetime(19)  binary
21     public $action;                          // string(32)  
22     public $ipaddr;                          // string(16)  
23     public $on_id;                           // int(11)  
24     public $on_table;                        // string(64)  
25     public $person_id;                       // int(11)  
26     public $remarks;                         // blob(65535)  blob
27     public $person_table;                    // string(64)
28     
29     /* the code above is auto generated do not remove the tag below */
30     ###END_AUTOCODE
31     
32     
33     
34     
35     //  ------------ROO HOOKS------------------------------------
36     function applyFilters($q, $au ,$roo)
37     {
38      
39         $tn = $this->tableName();
40         
41         // if not empty on_table
42         if(!empty($q['person_table'])){
43             $jt = DB_DataObject::factory($q['person_table']);
44         
45             $this->_join = "LEFT JOIN {$jt->tableName()} AS join_person_id_id ON (join_person_id_id.id=Events.person_id)";
46             $this->selectAdd();
47             $this->selectAs();
48             
49             $this->selectAs($jt, 'person_id_%s', 'join_person_id_id');
50         
51         } else {
52             $jt = DB_DataObject::factory('Person');
53             $this->whereAdd("
54                     person_table  = '{$jt->tableName()}'
55                     OR
56                     person_table = ''
57                     OR person_table IS NULL"
58             ); // default to  our standard.. - unless otherwise requested..
59         }
60         
61         
62         if (!empty($q['query']['from'])) {
63             $dt = date('Y-m-d' , strtotime($q['query']['from']));
64             $this->whereAdd(" {$tn}.event_when >=  '$dt' ");
65         }
66         if (!empty($q['query']['to'])) {
67             $dt = date('Y-m-d' , strtotime($q['query']['to']));
68             $this->whereAdd(" {$tn}.event_when <=  '$dt' ");
69         }
70         /*
71         if (!empty($q['query']['grouped']) && $q['query']['grouped'] == 'gr') {
72             // grouped..
73             DB_DataObject::Debuglevel(1);
74             $this->groupBy('on_id');
75             $this->selectAdd('
76                 (SELECT count(id) FROM core_event_audit WHERE event_id = Events.id) as changed
77                 ');
78         }
79         */
80         
81         if (!$au->hasPerm("Admin.Admin_Tab", 'S')) {
82             //DB_DataObject::DebugLevel(1);
83             // they can only view their changes..
84             $this->person_id = $au->id;
85             
86         }
87         // _join = tablename,tablename...
88         
89         /// on_table=cohead
90         //   &_join=cohead
91         //   &_join_cols=cohead_number
92         //    &_columns=on_id_cohead_number,event_when << this is ignored at present.
93         // max(event_when) is not supported... by any query yet..
94         
95         if (isset($q['on_table']) && !strlen($q['on_table'])) {
96             // empty ontable queries.. these are valid..
97             $this->whereAdd("$tn.on_table = ''");
98         }
99         
100         
101         
102         if (isset($q['query']['person_sum'])) {
103             //DB_DataObject::debugLevel(1);
104             $this->_extra_cols = array('qty' );
105             $this->selectAdd("count($tn.id) as qty");
106             $this->selectAdd("count( distinct $tn.on_id) as uqty");
107             $this->whereAdd('LENGTH(join_person_id_id.name) > 0 ');
108             $this->groupBy('person_id,join_person_id_id.name,join_person_id_id.email');
109         }
110          if (isset($q['query']['table_sum'])) {
111             //DB_DataObject::debugLevel(1);
112             $this->_extra_cols = array('qty' , 'uqty');
113             $this->selectAdd("count($tn.id) as qty");
114             $this->selectAdd("count( distinct $tn.on_table, $tn.on_id) as uqty");
115             
116             $this->groupBy('on_table');
117         }
118          if (isset($q['query']['day_sum'])) {
119             //DB_DataObject::debugLevel(1);
120             $this->_extra_cols = array('qty' , 'uqty');
121             $this->selectAdd("DATE_FORMAT(event_when, '%Y-%m-%d') as on_day");
122             $this->selectAdd("count($tn.id) as qty");
123             $this->selectAdd("count( distinct $tn.on_id) as uqty");
124             
125             $this->groupBy('on_day');
126         }
127         
128         if (isset($q['_join'])) {
129             //DB_DataObject::DebugLevel(1);
130             $joins = explode(',',$q['_join']);
131             
132             $this->selectAdd(); // ???
133             $distinct = false;
134             
135             foreach($joins as $t) {
136                 $t = preg_replace('/[^a-z_]+/', '', $t); // protection.
137                 $x = DB_DataObject::Factory($t);
138                 if (!is_a($x,'DB_DataObject')) {
139                     continue;
140                 }
141                 $jtn = $x->tableName();
142                 $jk = array_shift($x->keys());
143                 $this->_join .= "
144                 
145                     LEFT JOIN {$jtn} as join_on_id_{$jtn} ON {$tn}.on_id = join_on_id_{$jtn}.{$jk}
146                         AND on_table = '{$jtn}'
147                 ";
148                 $keys = array_keys($x->table());
149                 if (isset($q['_join_cols'])) {
150                     $jcs = explode(',',$q['_join_cols'] );
151                     //DB_DataObject::DebugLevel(1);
152                     
153                     foreach($jcs as $jc) { 
154                         if (! in_array($jc, $keys)) {
155                             continue;
156                         }
157                         if ($distinct) { 
158                         
159                        
160                             $this->selectAdd( " join_on_id_{$jtn}.{$jc}   as on_id_{$jc} ");
161                         } else {
162                             $this->selectAdd( " distinct(join_on_id_{$jtn}.{$jc}  ) as on_id_{$jc} ");
163                             $distinct = true;
164                         }
165                         $this->groupBy("on_id_{$jc} ");
166                         $this->whereAdd("join_on_id_{$jtn}.{$jc} IS NOT NULL");
167                     }
168                     $this->selectAdd( "MAX(events.event_when) as event_when");
169                     $this->orderBy('event_when DESC');
170                    // $this->selectAs(array($q['_join_cols']) , 'on_id_%s', "join_on_id_{$jtn}");
171                 } else { 
172                     $this->selectAs($x, 'on_id_%s', "join_on_id_{$jtn}");
173                 }
174             }
175                 
176                 
177             
178             
179         }
180         
181         if (isset($q['_related_on_id']) && isset($q['_related_on_table'])) {
182             // example: sales order - has invoices,
183             ///DB_DataObject::DebugLevel(1);
184             $ev  =$this->factory('Events');
185             $ev->setFrom(array(
186                 'on_id' => $q['_related_on_id'],
187                 'on_table' => $q['_related_on_table'],
188                                ));
189             $obj = $ev->object();
190             
191             if (!$obj) {
192                 $roo->jerr("ontable is invalid");
193             }
194             if (!method_exists($obj,'relatedWhere')) {
195                 $roo->jerr( $q['_related_on_table'] . " Does not have method relatedWhere :" .
196                            implode(',', get_class_methods($obj)));
197             }
198             if ($obj && method_exists($obj,'relatedWhere')) {
199                 $ar = $obj->relatedWhere();
200                 $tn = $this->tableName();
201                 
202                 $w = array();
203                 $w[] = "( {$tn}.on_table = '" .
204                         $this->escape($q['_related_on_table']) .
205                         "' AND {$tn}.on_id = ". ((int)  $q['_related_on_id']) .
206                     ")";
207                 
208                 
209                 foreach($ar as $k=>$v) {
210                     if (empty($v)) {
211                         continue;
212                     }                
213                      $w[] = "( {$tn}.on_table = '$k' AND {$tn}.on_id IN (". implode(',', $v). "))";
214                     
215                 }
216                 $this->whereAdd(implode(' OR ' , $w));
217             }
218             
219             
220             
221             
222             
223         }
224         // since roo does not support autojoin yet..
225         if (!isset($q['_distinct'])) {
226             //$this->autoJoinExtra();
227         }
228         
229         
230         
231             
232     }
233       
234     
235     
236     /**
237      * check who is trying to access this. false == access denied..
238      * @return {boolean} true if access is allowed.
239      */
240     function checkPerm($lvl, $au) 
241     {
242         if ($lvl == 'S') {
243             return true;
244         }
245         // listing is controleed by applyfilters..
246         return $au->hasPerm("Admin.Admin_Tab", 'S');
247     }
248     /**
249      * object :
250      * return the object that this relates to.
251      * 
252      * @return {DB_DataObject} related object
253      */
254     function object()
255     {
256         $o = DB_DataObject::factory($this->on_table);
257         $o->get($this->on_id);
258         return $o;
259         
260     }
261     
262     
263     /**
264      * init:
265      * Initialize an event - ready to insert..
266      * 
267      * @param {String} action  - group/name of event
268      * @param {DataObject|false} obj - dataobject action occured on.
269      * @param {String} any remarks 
270      */
271     
272     function init($act, $obj, $remarks)
273     {
274         $ff = HTML_FlexyFramework::get();
275         $pg = $ff->page;
276         $au = $pg->getAuthUser();
277         
278         if ($ff->cli) { // && empty($au) && isset($obj->person_id)) {
279             $au = false;
280            // $au = DB_DataObject::Factory('Person'); // not always a person..
281            // $au->get($obj->person_id);
282         } 
283           
284         $this->person_name = $au && !empty($au->name) ? $au->name : '';
285         $this->person_id = $au ? $au->id : -1;
286         $this->person_table = $au ? $au->tableName() : '';
287         $this->ipaddr = isset($_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : 'cli';
288         $this->action = $act;
289         $this->on_table = $obj ? $obj->tableName() : '';
290         $pk = $obj ? $obj->keys()  : false;
291         $this->on_id  = $obj && $pk ? $obj->{$pk[0]}: 0;
292         $rem  = array();
293         // should this really go in remarks? - 
294         if ($obj && method_exists($obj,'toEventString')) {
295             $rem[] = $obj->toEventString() ;
296         }
297         $rem[] = $remarks;
298         $this->remarks = implode(' : ', $rem);
299     }
300     
301     /**
302      * Generate an audit for this field.
303      *
304      * @param {DB_DataObject} new data
305      * @param {DB_DataObject} old data
306      * 
307      * @return {int} number of entries logged.
308      */
309     
310     function audit($new, $old = false)
311     {
312         if ($old == $new) {
313             return 0; // they are the same...
314         }
315          
316         $ret = 0;
317         foreach(array_keys($new->table()) as $k) {
318             // should we JSON serialize this?
319             $n = empty($new->$k) ? '' : $new->$k;
320             $o = empty($old->$k) || empty($old->$k) ? '' : $old->$k;
321             if ($n == $o) {
322                 continue;
323             }
324             $this->auditField($k, $o, $n, $old);
325             $ret++;
326         }
327         return $ret;
328     }
329     /**
330      * Record an audited change, in theory so we can audit data that is not just
331      * database Fields...
332      *
333      * @param {string} $name    table field anme
334      * @param {mixed} $ov  old value
335      * @param {mixed} $onv  new value
336      * @param {mixed} $old  old object (false if we are creating..)
337      */
338     function auditField($name, $ov, $nv, $old=false )
339     {
340         // hack..
341         if (is_object($nv)) {
342             return;
343         
344         }
345         
346         $x = DB_DataObject::factory('core_event_audit');
347         $x->setFrom(array(
348             'event_id' => $this->id,
349             'name' => $name,
350             'old_audit_id' => $old ? $x->findLast($this, $name) : 0,
351             'newvalue' => $nv
352
353         ));
354         $x->insert();
355     
356     }
357     
358     
359     
360     function onInsert($request,$roo)
361     {
362         $this->writeEventLog();
363     }
364     
365     function writeEventLog()
366     {
367         $ff  = HTML_FlexyFramework::get();
368         if (empty($ff->Pman['event_log_dir'])) {
369             return false;
370         }
371         
372         // add user (eg. www-data or local user if not..)
373         if (function_exists('posix_getpwuid')) {
374             $uinfo = posix_getpwuid( posix_getuid () ); 
375          
376             $user = $uinfo['name'];
377         } else {
378             $user = getenv('USERNAME'); // windows.
379         }
380         //print_r($this);
381         $file = $ff->Pman['event_log_dir']. '/'. $user. date('/Y/m/d/'). $this->id . ".json";
382         if (!file_exists(dirname($file))) {
383             mkdir(dirname($file),0700,true);
384         }
385         
386         // Remove all the password from logs...
387         $p =  empty($_POST) ? array() : $_POST;
388         foreach(array('passwd', 'password', 'passwd2', 'password2') as $rm) {
389             if (isset($p[$rm])) {
390                 $p['passwd'] = '******';
391             }
392         }
393         $i=0;
394         $files = array();
395         foreach ($_FILES as $k=>$f){
396             if (empty($f['tmp_name']) || !file_exists($f['tmp_name'])) {
397                 continue;
398             }
399             $i++;
400             $files[$k] = $f;
401             $files[$k]['tmp_name'] = $this->id . '.file_'. $i.'.jpg';
402             $nf = $ff->Pman['event_log_dir']. '/'. $this->id . ".file_$i.jpg";
403             if (!copy($f['tmp_name'], $nf)) {
404                 print_r("failed to copy {$f['tmp_name']}...\n");
405             }
406         }
407         
408         file_put_contents($file, json_encode(array(
409             'REQUEST_URI' => empty($_SERVER['REQUEST_URI']) ? 'cli' : $_SERVER['REQUEST_URI'],
410             'GET' => empty($_GET) ? array() : $_GET,
411             'POST' =>$p,
412             'FILES' => $files,
413         )));
414         
415     }
416     
417     
418 }