Platform  3.1
PHP API documentation
 All Data Structures Namespaces Files Functions Variables Pages
Class.Action.php
Go to the documentation of this file.
1 <?php
2 /*
3  * @author Anakeen
4  * @license http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ Anakeen - licence CC
5  * @package FDL
6 */
7 /**
8  * Action Class
9  *
10  * @author Anakeen 2000
11  * @version $Id: Class.Action.php,v 1.40 2008/03/10 15:09:17 eric Exp $
12  * @license http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ Anakeen - licence CC
13  * @package FDL
14  * @subpackage CORE
15  */
16 /**
17  */
18 
19 require_once 'WHAT/autoload.php';
20 include_once ('Class.DbObj.php');
21 include_once ('Class.User.php');
22 include_once ('Class.QueryDb.php');
23 include_once ('Class.Application.php');
24 
25 define("THROW_EXITERROR", 1968);
26 
27 class Action extends DbObj
28 {
29  var $fields = array(
30  "id",
31  "id_application",
32  "name",
33  "short_name",
34  "long_name",
35  "script",
36  "function",
37  "layout",
38  "available",
39  "acl",
40  "grant_level",
41  "openaccess",
42  "root",
43  "icon",
44  "toc",
45  "father",
46  "toc_order"
47  );
48 
49  var $id_fields = array(
50  "id"
51  );
52 
53  var $idx = array(
54  "id",
55  "id_application",
56  "name"
57  );
58 
59  var $dbtable = "action";
60 
61  var $sqlcreate = '
62 create table action (id int not null,
63  primary key (id),
64  id_application int not null,
65  name varchar(30) not null,
66  short_name text ,
67  long_name text,
68  script text,
69  function text,
70  layout text ,
71  available varchar(3),
72  acl varchar(20),
73  grant_level int,
74  openaccess char,
75  root char,
76  icon varchar(100),
77  toc char,
78  father int ,
79  toc_order int);
80 create index action_idx1 on action(id);
81 create index action_idx2 on action(id_application);
82 create index action_idx3 on action(name);
83 create sequence SEQ_ID_ACTION;
84  ';
85 
86  var $parent;
87 
88  var $def = array(
89  "criteria" => "",
90  "order_by" => "name"
91  );
92 
93  var $criterias = array(
94  "name" => array(
95  "libelle" => "Nom",
96  "type" => "TXT"
97  )
98  );
99 
100  var $grant_level = 0;
101 
102  function Set($name, &$parent)
103  {
104  $this->script = "";
105  $this->layout = "";
106  $this->function = "";
107  $query = new QueryDb($this->dbaccess, "Action", "TABLE");
108  if ($name != "") {
109  $name = pg_escape_string($name);
110  $query->basic_elem->sup_where = array(
111  "name='$name'",
112  "id_application={$parent->id}"
113  );
114  } else {
115  $query->basic_elem->sup_where = array(
116  "root='Y'",
117  "id_application={$parent->id}"
118  );
119  }
120  $query->Query(0, 0, "TABLE");
121  if ($query->nb > 0) {
122  $this->Affect($query->list[0]);
123  $this->log->debug("Set Action to {$this->name}");
124  } else {
125  $err = sprintf(_("Action '%s' not declared for application %s (%d)") , $name, $parent->name, $parent->id);
126  print $err;
127  exit;
128  }
129 
130  $this->CompleteSet($parent);
131  }
132 
133  function CompleteSet(&$parent)
134  {
135  $this->parent = & $parent;
136  if ($this->script == "") $this->script = strtolower($this->name) . ".php";
137  if ($this->layout == "") $this->layout = strtolower($this->name) . ".xml";
138  if ($this->function == "") $this->function = substr($this->script, 0, strpos($this->script, '.php'));
139 
140  $this->session = & $parent->session;
141 
142  $this->user = & $parent->user;
143  // Set the hereurl if possible
144  $this->url = $this->GetParam("CORE_BASEURL") . "app=" . $this->parent->name . "&action=" . $this->name;
145  // Init a log attribute
146  $this->log->loghead = sprintf("%s %s [%d] - ", $this->user->firstname, $this->user->lastname, $this->user->id);
147  $this->log->function = $this->name;
148  $this->log->application = $this->parent->name;
149  return "";
150  }
151 
152  function Complete()
153  {
154  }
155 
156  function Read($k, $d = "")
157  {
158  if (is_object($this->session)) {
159  return ($this->session->Read($k, $d));
160  }
161  return ($d . "--");
162  }
163 
164  function Register($k, $v)
165  {
166  if (isset($this->session) && is_object($this->session)) {
167  return ($this->session->Register($k, $v));
168  }
169  }
170 
171  function Unregister($k)
172  {
173  if (is_object($this->session)) {
174  return ($this->session->Unregister($k));
175  }
176  }
177 
178  function ActRead($k, $d = "")
179  {
180  return ($this->Read("{$this->id}_" . $k, $d));
181  }
182 
183  function ActRegister($k, $v)
184  {
185  return ($this->Register("{$this->id}_" . $k, $v));
186  }
187 
188  function ActUnregister($k)
189  {
190  return ($this->Unregister("{$this->id}_" . $k));
191  }
192 
193  function PreInsert()
194  {
195  if ($this->Exists($this->name, $this->id_application)) return "Action {$this->name} already exists...";
196  $msg_res = $this->exec_query("select nextval ('seq_id_action')");
197  $arr = $this->fetch_array(0);
198  $this->id = $arr["nextval"];
199  }
200  function PreUpdate()
201  {
202  if ($this->dbid == - 1) return FALSE;
203  if ($this->Exists($this->name, $this->id_application, $this->id)) return "Action {$this->name} already exists...";
204  }
205 
206  function GetParam($name, $def = "")
207  {
208  if (isset($this->parent)) {
209  return ($this->parent->GetParam($name, $def));
210  }
211  }
212  /**
213  * set a new value for a user parameter
214  * @param string $name parameter key
215  * @param string $val new value for the parameter
216  * @return string error message if not succeeed else empty string
217  */
218  function setParamU($name, $val)
219  {
220  if (isset($this->parent)) {
221  return ($this->parent->setParamU($name, $val));
222  }
223  }
224  function GetImageUrl($name, $detectstyle = true, $size = null)
225  {
226  if (isset($this->parent)) {
227  return ($this->parent->GetImageUrl($name, $detectstyle, $size));
228  }
229  }
230 
232  {
233  if (isset($this->parent)) {
234  return ($this->parent->GetFilteredImageUrl($name));
235  }
236  }
237 
238  function GetImageFile($name)
239  {
240  if (isset($this->parent)) {
241  return ($this->parent->GetImageFile($name));
242  }
243  }
244 
245  function AddLogMsg($msg, $cut = 80)
246  {
247  if (isset($this->parent)) {
248  return ($this->parent->AddLogMsg($msg, $cut));
249  }
250  }
251 
252  function AddWarningMsg($msg)
253  {
254  if (isset($this->parent)) {
255  return ($this->parent->AddWarningMsg($msg));
256  }
257  }
258  /**
259  * store action done to be use in refreshing main window interface
260  * @param string $actdone the code of action
261  * @param string $args the argument of action
262  */
263  function AddActionDone($actdone, $arg = "")
264  {
265  if ($actdone != "") {
266  $sact = $this->session->read("actdone_name", array());
267  $sarg = $this->session->read("actdone_arg", array());
268  $sact[] = $actdone;
269  $sarg[] = $arg;
270  $sact = $this->session->register("actdone_name", $sact);
271  $sarg = $this->session->register("actdone_arg", $sarg);
272  }
273  }
274  /**
275  * clear action done to be use in refreshing main window interface
276  * @param string $actdone the code of action
277  * @param string $args the argument of action
278  */
279  function ClearActionDone()
280  {
281  $this->session->unregister("actdone_name");
282  $this->session->unregister("actdone_arg");
283  }
284  /**
285  * get action code and argument for action code done
286  * to be use in refreshing main window interface
287  * @param string &$actdone the code of action
288  * @param string &$args the argument of action
289  */
290  function GetActionDone(&$actdone, &$arg)
291  {
292  $actdone = $this->session->read("actdone_name", array());
293  $arg = $this->session->read("actdone_arg", array());
294  }
295  function GetIcon($name, $text, $width = "", $height = "")
296  {
297 
298  if ($width != "") $width = "width = \"" . $width . "\"";
299  if ($height != "") $height = "height = \"" . $height . "\"";
300 
301  return ("<img border=0 " . $width . " " . $height . " src=\"" . $this->GetImageUrl($name) . "\" title=\"" . $this->text($text) . "\" alt=\"" . $this->text($text) . "\">");
302  }
303 
304  function GetLayoutFile($layname)
305  {
306  if (isset($this->parent)) return ($this->parent->GetLayoutFile($layname));
307  }
308 
309  function Exists($name, $idapp, $id_func = '')
310  {
311  if ($idapp == '') return false;
312  $query = new QueryDb($this->dbaccess, "Action");
313 
314  if ($id_func != '') {
315  $query->basic_elem->sup_where = array(
316  "name='$name'",
317  "id!=$id_func",
318  "id_application=$idapp"
319  );
320  } else {
321  $query->basic_elem->sup_where = array(
322  "name='$name'",
323  "id_application=$idapp"
324  );
325  }
326 
327  $query->Query();
328 
329  return ($query->nb > 0);
330  }
331 
332  function HasPermission($acl_name = "", $app_name = "")
333  {
334  if ($acl_name == "") return (true); // no control for this action
335  return ($this->parent->HasPermission($acl_name, $app_name));
336  }
337  /**
338  * return true if user can execute the specified action
339  * @param string $actname action name
340  * @param string $appid application name or id (default itself)
341  * @return string error message (empty if no error)
342  *
343  */
344  function canExecute($actname, $appid = "")
345  {
346 
347  if ($this->user->id == 1) return;
348  if ($appid == "") $appid = $this->parent->id;
349  elseif (!is_numeric($appid)) $appid = $this->parent->GetIdFromName($appid);
350 
351  $aclname = $this->getAcl($actname, $appid);
352  if (!$aclname) return; // no control
353  $acl = new Acl($this->dbaccess);
354  if (!$acl->Set($aclname, $appid)) {
355  return sprintf(_("Acl [%s] not available for App %s") , $aclname, $appid);
356  }
357  $p = new Permission($this->dbaccess, array(
358  $this->user->id,
359  $appid
360  ));
361  if (!$p->HasPrivilege($acl->id)) return sprintf("no privilege %s for %s %s", $aclname, $appid, $actname);
362  }
363  /**
364  * return id from name for an application
365  * @param string $actname action name
366  * @param string $appid application id (default itself)
367  * @return string (false if not found)
368  */
369  function GetAcl($actname, $appid = "")
370  {
371  if ($appid == "") $appid = $this->parent->id;
372  $query = new QueryDb($this->dbaccess, $this->dbtable);
373  $query->AddQuery("name = '$actname'");
374  $query->AddQuery("id_application = $appid");
375  $q = $query->Query(0, 0, "TABLE");
376  if (is_array($q)) return $q[0]["acl"];
377  return false;
378  }
379  /**
380  * execute the action
381  * @return string the composed associated layout
382  */
383  function execute()
384  {
385  // If no parent set , it's a misconfiguration
386  if (!isset($this->parent)) return;
387 
388  if ($this->auth && $this->auth->parms["type"] == "open") {
389  if ($this->openaccess != 'Y') {
390  $allow = false;
391  if ($this->auth->token && $this->auth->token["context"]) {
392  print $this->auth->token->context;
393  //$this->exitForbidden('may be open');
394  $context = unserialize($this->auth->token["context"]);
395  if (is_array($context) && (count($context) > 0)) {
396  $allow = true;
397  foreach ($context as $k => $v) {
398  if (getHttpVars($k) != $v) {
399  $allow = false;
400  }
401  }
402  if (!$allow) $this->exitForbidden(sprintf(_("action %s is not declared to be access in open mode and token context not match") , $this->name));
403  }
404  }
405  if (!$allow) $this->exitForbidden(sprintf(_("action %s is not declared to be access in open mode") , $this->name));
406  }
407  }
408  // check if this action is permitted
409  if (!$this->HasPermission($this->acl)) {
410  $this->ExitError(sprintf(_("Access denied\nNeed ACL %s for action %s [%s]") , $this->acl, $this->short_name, $this->name));
411  }
412 
413  if ($this->id > 0) {
414  global $QUERY_STRING;
415  $this->log->info("{$this->parent->name}:{$this->name} [" . substr($QUERY_STRING, 48) . "]");
416  }
417  // Memo last application to return case of error
418  $err = $this->Read("FT_ERROR", "");
419  if ($err == "") {
420  if ($this->parent->name != "CORE") {
421  $this->register("LAST_ACT", $this->parent->name);
422  }
423  }
424  $this->log->push("{$this->parent->name}:{$this->name}");
425  $pubdir = $this->parent->GetParam("CORE_PUBDIR");
426  $nav = $this->Read("navigator");
427  if ($this->layout != "") {
428  $layout = $this->GetLayoutFile($this->layout);
429  } else {
430  $layout = "";
431  }
432  $this->lay = new Layout($layout, $this);
433  if (isset($this->script) && $this->script != "") {
434  $script = $pubdir . "/" . $this->parent->name . "/" . $this->script;
435  if (!file_exists($script)) // try generic application
436  $script = $pubdir . "/" . $this->parent->childof . "/" . $this->script;
437 
438  if (file_exists($script)) {
439  include_once ($script);
440  $call = $this->function;
441  $call($this);
442  } else {
443  $this->log->debug("$script does not exist");
444  }
445  } else {
446  $this->log->debug("No script provided : No script called");
447  }
448  // Is there any error messages
449  $err = $this->Read($this->parent->name . "_ERROR", "");
450  if ($err != "") {
451  $this->lay->Set("ERR_MSG", $err);
452  $this->Unregister($this->parent->name . "_ERROR");
453  } else {
454  $this->lay->Set("ERR_MSG", "");
455  }
456 
457  $out = $this->lay->gen();
458  $this->log->pop();
459 
460  return ($out);
461  }
462  /**
463  * display error to user and stop execution
464  * @param string $texterr the error message
465  */
466  function ExitError($texterr)
467  {
468  if ($_SERVER['HTTP_HOST'] != "") {
469  // redirect($this,"CORE&sole=Y","ERROR");
470  $this->lay = new Layout("CORE/Layout/error.xml", $this);
471  $this->lay->set("error", $texterr);
472  $this->lay->set("serror", str_replace("\n", "\\n", addslashes($texterr)));
473  $this->lay->set("appname", $this->parent->name);
474  $this->lay->set("appact", $this->name);
475  if ($this->parent && $this->parent->parent) { // reset js ans ccs
476  $this->parent->parent->cssref = array();
477  $this->parent->parent->jsref = array();
478  }
479  header('Warning: '.strtok($texterr,"\n"));
480  print $this->lay->gen();
481  exit;
482  } else {
483  throw new Exception($texterr, THROW_EXITERROR);
484  }
485  }
486 
487  function exitForbidden($texterr)
488  {
489  header("HTTP/1.0 401 Authorization Required ");
490  header("HTTP/1.0 301 Access Forbidden ");
491  print $texterr;
492  exit;
493  }
494  /**
495  * unregister FT error
496  */
497  function ClearError()
498  {
499  $this->Unregister("FT_ERROR");
500  $this->Unregister("FT_ERROR_ACT");
501  }
502 
503  function Init($app, $action_desc, $update = FALSE)
504  {
505  if (sizeof($action_desc) == 0) {
506  $this->log->info("No action available");
507  return ("");
508  }
509  $father[0] = "";
510 
511  foreach ($action_desc as $k => $node) {
512  // set some default values
513  $action = new Action($this->dbaccess);
514  $action->root = "N";
515  $action->available = "Y";
516  $action->id_application = $app->id;
517  $action->toc = "N";
518  // If the action already exists ,set it
519  if ($action->Exists($node["name"], $app->id)) {
520  $action->Set($node["name"], $app);
521  while (list($k, $v) = each($node)) {
522  if ($k == 'available' && $update) {
523  continue;
524  }
525  $action->$k = $v;
526  }
527  reset($node);
528  } else {
529  while (list($k, $v) = each($node)) {
530  $action->$k = $v;
531  }
532  reset($node);
533  }
534  // Get the acl grant level
535  $acl = new Acl($this->dbaccess);
536  if (isset($action->acl)) {
537  $acl->Set($action->acl, $action->id_application);
538  $action->grant_level = $acl->grant_level;
539  } else {
540  $action->grant_level = 0;
541  }
542  // set non set values if possible
543  if ($action->long_name == "") $action->long_name = $action->short_name;
544  if ($action->script == "") $action->script = strtolower($action->name) . ".php";
545  if ($action->layout == "") $action->layout = strtolower($action->name) . ".xml";
546  if (!isset($action->level)) $action->level = 0;
547 
548  $action->father = $father[$action->level];
549  if ($action->Exists($node["name"], $app->id)) {
550  $this->log->info("Update Action " . $node["name"]);
551  $action->Modify();
552  } else {
553  $action->Add();
554  $this->log->info("Create Action " . $node["name"]);
555  }
556  $father[$action->level + 1] = $action->id;
557  }
558  // if update , remove unused actions
559  if ($update) {
560  $query = new QueryDb($this->dbaccess, "Action");
561  $query->basic_elem->sup_where = array(
562  "id_application = {$app->id}"
563  );
564  $list = $query->Query();
565  while (list($k, $act) = each($list)) {
566  $find = FALSE;
567  reset($action_desc);
568  while ((list($k2, $v2) = each($action_desc)) && (!$find)) {
569  $find = ($v2["name"] == $act->name);
570  }
571  if (!$find) {
572  // remove the action
573  $this->log->info("Delete Action " . $act->name);
574  $act->Delete();
575  }
576  }
577  }
578  }
579  /**
580  * retrieve the value of an argument fot the action
581  * in web mode the value comes from http variable and in shell mode comes from args variable
582  * @param string $k the argument name
583  * @param any $def default value if no argument is not set
584  */
585  static function getArgument($k, $def = '')
586  {
587  $v = getHttpVars($k, null);
588  if ($v === null) return $def;
589  else return $v;
590  }
591 
592  function Text($code, $args = NULL)
593  {
594  if ($code == "") return "";
595  return _("$code");
596  }
597  // Log functions
598  function debug($msg)
599  {
600  $this->log->debug($msg);
601  }
602  function info($msg)
603  {
604  $this->log->info($msg);
605  }
606  function warning($msg)
607  {
608  $this->log->warning($msg);
609  }
610  function error($msg)
611  {
612  $this->log->error($msg);
613  }
614  function fatal($msg)
615  {
616  $this->log->fatal($msg);
617  }
618  /**
619  * verify if the application is really installed in localhost
620  * @return bool true if application is installed
621  */
623  {
624 
625  $pubdir = $this->parent->GetParam("CORE_PUBDIR");
626 
627  return (@is_dir($pubdir . "/" . $appname));
628  }
629  /**
630  * return available Applications for current user
631  * @return array
632  */
634  {
635 
636  $query = new QueryDb($this->dbaccess, "Application");
637  $query->basic_elem->sup_where = array(
638  "available='Y'",
639  "displayable='Y'"
640  );
641  $list = $query->Query(0, 0, "TABLE");
642  $tab = array();
643  if ($query->nb > 0) {
644  $i = 0;
645  foreach ($list as $k => $appli) {
646  if ($appli["access_free"] == "N") {
647 
648  if (isset($this->user)) {
649  if ($this->user->id != 1) { // no control for user Admin
650  //if ($p->id_acl == "") continue;
651  // test if acl of root action is granted
652  // search acl for root action
653  $queryact = new QueryDb($this->dbaccess, "Action");
654  $queryact->AddQuery("id_application=" . $appli["id"]);
655  $queryact->AddQuery("root='Y'");
656  $listact = $queryact->Query(0, 0, "TABLE");
657  $root_acl_name = $listact[0]["acl"];
658  if (!$this->HasPermission($root_acl_name, $appli["id"])) continue;
659  }
660  } else {
661  continue;
662  }
663  }
664  $appli["description"] = $this->text($appli["description"]); // translate
665  $appli["iconsrc"] = $this->GetImageUrl($appli["icon"]);
666  if ($appli["iconsrc"] == "CORE/Images/noimage.png") $appli["iconsrc"] = $appli["name"] . "/Images/" . $appli["icon"];
667 
668  $tab[$i++] = $appli;
669  }
670  }
671  return $tab;
672  }
673 }
674 ?>
← centre documentaire © anakeen - published under CC License - Dynacase