diff --git a/routeSQL.php b/routeSQL.php index b139839..ad6083d 100644 --- a/routeSQL.php +++ b/routeSQL.php @@ -42,6 +42,18 @@ class routeSQL public $path = ""; /** Authentication */ public $auth = array ("email"=>"anonymous"); + /** Authorization object. Should allow a method named + "allow ($module, $user, $object)" which return + - NO if the object is not defined + - RO if the object is in read-only mode + - RW if the object is in read-write mode */ + public $authorization = null; + /** Module name for authorization */ + public $module = null; + /** Chain multiple routeSQL. Wait for an routeSQL object */ + public $chained = null; + /** Chain multiple routeSQL. Wait for the foreign key */ + public $chainedForeign = null; /** The model file containing the database description */ private $model_file = ""; /** The model class included in the model file */ @@ -60,6 +72,8 @@ class routeSQL private $password = null; /** The Options to the PDO driver if needed */ private $driver_options = null; + /** The Datas are protected in read-only */ + private $readwriteAllowed = true; /** Connect to the database */ public function __construct ($model_file, $model_class, $url_prefix, $dsn, @@ -128,6 +142,7 @@ class routeSQL { // The maximum of links available in the paginator $maxClickPaginator = 10; + $route = new route (); $prePage = false; $postPage = false; $content = "
\n"; @@ -149,7 +164,7 @@ class routeSQL continue; } $displayedNumbers++; - $content .= " baseURL().$this->url_prefix. "?page=$i&num=$num&search=".urlencode ($search)."'"; if ($page == $i) $content .= " class='selected'"; @@ -158,7 +173,7 @@ class routeSQL if ($displayedNumbers === 0) { $i = 1; - $content .= " baseURL().$this->url_prefix. "?page=$i&num=$num&search=".urlencode($search)."'"; if ($page == $i) $content .= " class='selected'"; @@ -174,7 +189,7 @@ class routeSQL private function addNewArea ($nbentries, $page, $num, $search) { $content = ""; - if ($this->displayActions) + if ($this->displayActions && $this->readwriteAllowed) { $route = new route (); $content .= "
\n"; @@ -249,8 +264,18 @@ class routeSQL /** Create the routes and the associated actions */ public function routesHTML () { + // If chained routeSQL, the url_prefix must be adapted + if ($this->chained !== null) + { + if (strpos ($this->chained->url_prefix, "/{chain}/") !== false) + throw new Exception ("Chained can not have an already chained object", + 500); + $this->url_prefix = $this->chained->url_prefix."/{chain}/". + $this->url_prefix; + } /** Add HTML routes */ $route = new route (); + $route->allowSlashes=false; $route->get ($this->url_prefix."/", function () use ($route) { $route->redirect ("/".$this->url_prefix, ""); @@ -258,9 +283,16 @@ class routeSQL $route->get ($this->url_prefix. "(\?({p1}=({v1})?)(&{p2}=({v2})?(&{p3}=({v3})?)?)?)?", - function ($p1, $v1, $p2, $v2, $p3, $v3) use ($route) + function ($p1, $v1, $p2, $v2, $p3, $v3, $chain) use ($route) { // List all the objects of the table + if ($this->chained !== null && + $this->chained->accessright ($chain) !== TRUE) + { + if ($this->auth["email"] === "anonymous") + throw new Exception (_("Anonymous not allowed"), 401); + throw new Exception (_("Access forbidden"), 403); + } if ($this->accessright () !== TRUE) { if ($this->auth["email"] === "anonymous") @@ -268,6 +300,10 @@ class routeSQL throw new Exception (_("Access forbidden"), 403); } + if ($this->chained !== null && + $this->chained->editright ($chain) !== true) + $this->readwriteAllowed = false; + // num is the number of elements displayed by page // page is the page to display // Allow the parameters to be sent in any order @@ -292,6 +328,7 @@ class routeSQL setcookie ("page", $page, time()+3600*24*30, $this->path); setcookie ("num", $num, time()+3600*24*30, $this->path); setcookie ("search", $search, time()+3600*24*30, $this->path); + $this->url_prefix = str_replace ("{chain}", $chain, $this->url_prefix); //echo "PAGE=$page\n"; //echo "NUM=$num\n"; //echo "SEARCH=$search\n"; @@ -300,8 +337,13 @@ class routeSQL $csrf = new csrf (); $token = $csrf->createToken (); $titles = $this->objectDB->titles (); + unset ($titles[$this->chainedForeign]); + $foreignSelect = null; + if ($this->chained !== null) + $foreignSelect = array (array ($this->chainedForeign, $chain)); if ($search === "") - $datas = $this->objectDB->read (); + $datas = $this->objectDB->read (null, array_keys($titles), null, null, + $foreignSelect); else { $criteria = array (); @@ -318,7 +360,8 @@ class routeSQL $s = "$s%"; $criteria[] = array ($column, "$s", "LIKE"); } - $datas = $this->objectDB->read ($criteria, null, null, true); + $datas = $this->objectDB->read ($criteria, array_keys ($titles), null, + true, $foreignSelect); } $nbentries = count ($datas); if ($num > 1000) @@ -390,11 +433,13 @@ class routeSQL $content .= " \n"; $content .= " \n"; $content .= " \n"; - if ($this->displayActions && $this->actionsAtEnd === false) + if ($this->readwriteAllowed && $this->displayActions && + $this->actionsAtEnd === false) $content .= " \n"; foreach ($titles as $title) $content .= " \n"; - if ($this->displayActions && $this->actionsAtEnd !== false) + if ($this->readwriteAllowed && $this->displayActions && + $this->actionsAtEnd !== false) $content .= " \n"; $content .= " \n"; $content .= " \n"; @@ -403,7 +448,7 @@ class routeSQL { // Add one column more for actions $countTitles = count($titles); - if ($this->displayActions) + if ($this->readwriteAllowed && $this->displayActions) $countTitles++; $content .= " "; } - if ($this->displayActions) + if ($this->readwriteAllowed && $this->displayActions) { $content .= "
".dgettext("domframework","Actions")."".htmlentities ($title)."".dgettext("domframework","Actions")."
"; $content .= dgettext("domframework","No entry available"); @@ -428,7 +473,7 @@ class routeSQL foreach ($line as $col) $content .= "".htmlentities ($col).""; $content .= "