diff --git a/Conjuro/Conjuro.php b/Conjuro/Conjuro.php new file mode 100644 index 0000000..3e4d19c --- /dev/null +++ b/Conjuro/Conjuro.php @@ -0,0 +1,237 @@ +conf=$conf; + $this->loadControls(); + } + + // Return data from database + public function DBget($type,$key=""){ + if ($key!="") + $data=$this->db()->select($type,null,'where id=?','i',$key); + else + $data=$this->db()->select($type); + foreach($data as $i => $row){ + $data[$i]['$type']=$type; + $types=[]; + foreach($row as $k => $v){ + if ($v===null) + $types[$k]='!'; + else + $types[$k]=is_string($v)?'s':'i'; + } + $data[$i]['$types']=$types; + } + return $data; + } + + public function DBsave($data){ + $type=$data['$type']; + if ($type=='') // data is not entity + return; + $id=$data['id']; + $dbdata=$this->db()->select($type,null,'where id=?','i',$id); + if (count($dbdata)==0){ + $fields=''; + $types=''; + $values=[]; + foreach($data as $i => $v){ + if ($i[0]=='$') + continue; + if (strlen($fields)>0) + $fields.=','; + $fields.=$i; + $types.=$data['$types'][$i]; + $values[]=$v; + } + if ($fields!=''){ + $this->db->insert($type,$fields,$types,...$values); + $data['id']=$this->db->insert_id; + $this->db->insert('user-log','user,action,entity,entity_id','sssi',$_SESSION['user']['user'],'INSERT',$type,$this->db->insert_id); + } + }else{ + $dbdata=$dbdata[0]; // Select the first row + $set=''; + $types=''; + $values=[]; + foreach($data as $i => $v){ + if ($i[0]=='$') + continue; + if ($dbdata[$i]!=$v){// only differences + if (strlen($set)>0) + $set.=','; + $set.="$i = ?"; + $types.=$data['$types'][$i]; + $values[]=$v; + } + } + $types.='i'; + $values[]=$id; + if ($set!=''){ + $this->db->update($type,$set,'where id=?',$types,...$values); + $this->db->insert('user-log','user,action,entity,entity_id','sssi',$_SESSION['user']['user'],'UPDATE',$type,$id); + } + } + return $data; + } + + // Delete an entity, use DBdelete() or DBdelete(,) + public function DBdelete($data,$id=null){ + if (is_string($data)){ + if ($id){ + $type=$data; + } + }else{ + $type=$data['$type']; + if ($type=='') // data is not entity + return; + $id=$data['id']; + } + $this->db()->delete($type,'where id=?','i',$id); + $this->db->insert('user-log','user,action,entity,entity_id','sssi',$_SESSION['user']['user'],'DELETE',$type,$id); + return $data; + } + + // Database + public function db(){ + if(!isset($this->db)) + $this->db=new DB($conf); + return $this->db; + } + + //STATIC: loads a JSON + public static function loadJson($path){ + $json=file_get_contents($path); + return json_decode($json, true); + } + + /** + * Returns a loaded module or load + */ + public function module($name){ + if (!isset($name) || strpos($name,".")!==false || strpos($name,"/")!==false){ + throw new Exception("Module name error"); + } + if (!isset($this->modules[$name])){ + $conf=$this->conf; + $m=include "content/modules/$name.php"; + if (method_exists($m,"init")){ + $m->init($this); + } + $this->modules[$name]=$m; + } + return $this->modules[$name]; + } + + private function loadControlLibrary($name){ + if (!isset($name) || strpos($name,".")!==false || strpos($name,"/")!==false){ + throw new Exception("Name error"); + } + $ctrls = include "content/controls/$name.php"; + foreach($ctrls as $ctrl){ + $cname=$ctrl->getName(); + if (isset($controls[$cname])) + throw new Exception("Control '$cname' already defined loading library '$name'."); + $this->controls[$cname]=$ctrl; + } + } + + private function loadControls(){ + $this->loadControlLibrary("common"); + } + + public function control($name){ + if (isset($this->controls[$name])) + return $this->controls[$name]; + return new ErrorControl($name); + } + } + + /** + * Base class for module implementation + */ + abstract class ModuleBase{ + private $mapi=[]; + protected $conf; + + function __construct($conf) { + $this->conf=$conf; + } + + protected function register($name,$function){ + $this->mapi[$name]=$function; + } + + protected function deregister($name){ + unset($this->mapi[$name]); + } + + public function call($name,&...$attrs){ + if (!isset($this->mapi[$name])){ + throw new Exception("Function '$name 'does not exist"); + } + $this->mapi[$name](...$attrs); + } + } + + /** Class for module implementation */ + class Module extends ModuleBase{ + + } + + /** + * Base class for controls + */ + abstract class Control{ + private $name; + function __construct($name) { + $this->name=$name; + } + + public function getName(){ + return $this->name; + } + + public function render($meta=null,$data=null){ + $this->renderControl($meta,$data); + } + + abstract protected function renderControl($meta,$data); + } + + /** + * Error control class + */ + class ErrorControl extends Control{ + protected function renderControl($meta,$data){ + $name = $this->getName(); + echo "['$name' not found]"; + } + } + + function C(){ + global $c; + if (!isset($c)){ + $cfg=include "Config.php"; + if($cfg["debug"]){ + error_reporting(E_ALL ^ E_NOTICE); + ini_set('error_reporting', E_ALL ^ E_NOTICE); + ini_set('display_errors',1); + } + $c=new Conjuro($cfg); + } + return $c; + } + + function M($name){ + return C()->module($name); + } + +?> \ No newline at end of file diff --git a/Conjuro/ezDBclass.php b/Conjuro/ezDBclass.php new file mode 100644 index 0000000..cbbbfd7 --- /dev/null +++ b/Conjuro/ezDBclass.php @@ -0,0 +1,180 @@ +dbConnect($configuration["db-host"],$configuration["db-user"],$configuration["db-pass"],$configuration["db-name"],$configuration["db-charset"]); + $this->prefix=$configuration["db-prefix"]; + } + + private function dbConnect($host,$user,$pass,$db,$charset=null){ + $this->mysqli = new mysqli($host, $user, $pass, $db); + if ($this->mysqli->connect_errno) + die("Connection failed: (" . $this->mysqli->connect_errno . ") " . $this->mysqli->connect_error); + if ($charset) + $this->mysqli->set_charset($charset); + } + + private function dbPrepare($sql,$types,$data){ + if ($this->mysqli == null) + throw new Exception("No DB connection."); + if (!($q = $this->mysqli->prepare($sql))) + throw new Exception("Prepare: SQL Error: (" . $this->mysqli->errno . ") " . $this->mysqli->error); + if ($types != null && !$q->bind_param($types, ...$data)) + throw new Exception("Bind: SQL Error: (" . $q->errno . ") " . $q->error); + return $q; + } + + private function dbExec($sql,$types = null,...$data){ + $q = $this->dbPrepare($sql,$types,$data); + if (!$q->execute()) { + throw new Exception("Execute: SQL Error: (" . $q->errno . ") " . $q->error); + } + $q->close(); + } + + private function dbQuery($sql,$types = null,...$data){ + $q = $this->dbPrepare($sql,$types,$data); + if (!$q->execute()) { + throw new Exception("Execute: SQL Error: (" . $q->errno . ") " . $q->error); + } + if (!($res = $q->get_result())) { + throw new Exception("Result: SQL Error: (" . $q->errno . ") " . $q->error); + } + return [ "q"=>$q, "r"=>$res ]; + } + + private function dbFetch($res){ + return $res["r"]->fetch_assoc(); + } + + private function dbFree($res){ + $res["r"]->free(); + $res["q"]->close(); + } + + private function tn($table){ + return '`'.$this->prefix.$table.'`'; + } + + /** + * Exec command. + */ + public function exec($command,$table,$options='',$types=null,...$data){ + $sql=$command.' '.$this->tn($table).' '.$options; + $this->dbExec($sql,$types,...$data); + } + + public function info($command,$table,$options='',$types=null,...$data){ + $sql=$command.' '.$this->tn($table).' '.$options; + $q=$this->dbQuery($sql,$types,...$data); + $data=[]; + while($row = $this->dbFetch($q)) + $data[]=$row; + $this->dbFree($q); + return $data; + } + + public function insert($table,$fields,$types,...$data){ + if ($spos=strpos($fields,'|')!==false){// Para que? + $vals=substr($fields,$spos+1); + $fields=substr($fields,0,$spos); + }else{ + $vals=''; + if ($types){ + for($i=0;$i0) + $vals.=','; + $vals.='?'; + } + } + } + $sql='insert into '.$this->tn($table)." ($fields) values ($vals)"; + $this->dbExec($sql,$types,...$data); + } + + /** + * Select on table + * Structure: + * select(,,,,...) + * Usage sample: + * $db->select("table",,"where name=? and age>?","si",$name,$age); + * Returns: An array of associative arrays per row. + */ + public function select($table,$fields = null,$opt='',$types = null,...$data){ + if ($fields===null) + $fields='*'; + $sql="select $fields from ".$this->tn($table); + if ($opt) + $sql.=" $opt"; + $q=$this->dbQuery($sql,$types,...$data); + $data=[]; + while($row = $this->dbFetch($q)) + $data[]=$row; + $this->dbFree($q); + return $data; + } + + /** + * As select but only fetch one associative array with the row. + * Structure: + * selectOne(
,,,,...) + * Usage sample: + * $db->selectOne("table",,"where name=? and age>?","si",$name,$age); + */ + public function selectOne($table,$fields = null,$opt='',$types = null,...$data){ + if ($fields===null) + $fields='*'; + $sql="select $fields from ".$this->tn($table); + if ($opt) + $sql.=" $opt"; + $q=$this->dbQuery($sql,$types,...$data); + $data=$this->dbFetch($q); + $this->dbFree($q); + return $data; + } + + /** + * Update data on database. + * Structure: + * update(
,,,,...) + * Usage sample: + * $db->update("table","name=?","where id=?","si",$newName,$id); + */ + public function update($table,$set,$opt,$types = null,...$data){ + $sql='update '.$this->tn($table)." set $set $opt"; + $this->dbExec($sql,$types,...$data); + } + + /** + * Delete data on database. + * Structure: + * delete(
,,,...) + * Usage sample: + * $db->delete("table","where id=?","s",$id); + */ + public function delete($table,$opt,$types,...$data){ + $sql='delete from '.$this->tn($table)." $opt"; + $this->dbExec($sql,$types,...$data); + } +} + +?> \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bb38fb0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 XWolf Override + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/content/controls/common.php b/content/controls/common.php new file mode 100644 index 0000000..3324e7e --- /dev/null +++ b/content/controls/common.php @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/index.php b/index.php new file mode 100644 index 0000000..64edbd1 --- /dev/null +++ b/index.php @@ -0,0 +1,14 @@ +showPage(); + //M("Page")->call("showPage"); + //M("Page")->showPage(); + //M("Builder")->call("edit","index"); + c()->control("pollas")->render(); + c()->control("html")->render(["html"=>"
Hola caracola
"]); +?> \ No newline at end of file