<?php
include_once "strings/".sys_lang.".php";
include_once "elem_DB.php";
include_once "engine.php";
//PEAR functions
include_once "DB.php";
//File system operations
include_once('libraries/lib_dir.php');
class CEngineObject extends CEngineBase
{
var $isProcElem;
var $db=0;
var $user=0;
function CEngineObject(){
$this->CEngineBase();
$this->open_db();
$this->new_dom();
$this->isProcElem=false;
}
function open_db(){
//if (!DB::isConnection($this->db))
{
$this->db = DB::Connect(sys_dsn);
if(DB::isError($this->db)){
echo $this->db->message.'('.$this->db->code.')';//." dsn=".sys_dsn;
$this->ErrorMsg($this->db->message);
return false;
}
//var_dump($this->db);
}
return true;
}
function query($query, $limit=""){
if(sys_debug)
$this->Timings->BeginTime("SQL");
if($limit){
//print $query; print_r($limit); echo "<br/>";
$res = $this->db->limitQuery($query, $limit->from,$limit->count);
}
else{
$res = $this->db->query($query);
}
if(DB::isError($res)){
$this->ErrorMsg(ErrorInQuery.$this->db->last_query);
}
if(sys_debug)
$this->Timings->EndTime("SQL");
return $res;
}
function GetPage($page_id)
{
//Get page's parameters
$page = new CElemDB($this, "page", $page_id);
if(!$page->Get()){
$this->ErrorMsg(CantCreateXmlNode);
echo "page id=".$page_id." not found";
return 0;
}
//check auth if it necessary
if($page->attrs["access"]!=0){
$this->auth($page->attrs["access"]);
}
if(!$page->ToXMLNode($this->xmlSiteDom)){
$this->ErrorMsg(CantCreateXmlNode);
return 0;
}
return $page;
}
function EditElem($xml_parent="")
{
if($xml_parent=="")
$xml_parent = &$this->xml_root;
//Edit Just Elem for Groups and Users
$this->cur_elem->Get();
$xml_elem = $this->cur_elem->ToXMLNode($this->xmlSiteDom);
//Insert elem to cur_page
$xml_parent->append_child($xml_elem);
}
function RefreshTree(){
if(!$this->cur_page_id)
return false;
$this->xml_root=0;
$this->GetTree("");
return true;
}
function CheckLinkDeadlockOk(&$parent_elem, &$cur_elem)
{
if($parent_elem->type== $cur_elem->type && $parent_elem->elem_id == $cur_elem->elem_id)
return false;
$table_contents = $cur_elem->LinkTableByType();
//print "$table_contents $parent_elem->type $parent_elem->elem_id == $cur_elem->elem_id<br />";
$sql = "SELECT * from `$table_contents` WHERE id=$parent_elem->elem_id and type='$parent_elem->type'";
$res = $this->query($sql);
if (DB::isError($res)) {
return true;
}
if (!$res->numRows())
return true;
//check all parents
while(($row = $res->fetchRow(DB_FETCHMODE_ASSOC))){
$next_parent_elem = new CElemDB($this, $row['parent_type'], $row['parent_id']);
if(!$this->CheckLinkDeadlockOk($next_parent_elem, $cur_elem))
return false;
}
return true;
}
function LinkElem(&$parent_elem, &$cur_elem, $isCheck = true)
{
if($cur_elem->elem_id==-1 || $parent_elem->elem_id==-1){
$this->ErrorMsg(NothingToLink." elem_id=$cur_elem->elem_id and parent_id=$parent_elem->elem_id");
return false;
}
if($isCheck)
{
if(!$this->CheckLinkDeadlockOk($parent_elem, $cur_elem)){
$this->ErrorMsg(MsgDeadLockLink);
return false;
}
}
$newpos = $this->GetPageMaxPos($cur_elem->LinkTableByType(), $parent_elem->elem_id);
//next pos
$newpos++;
$newstate = 1; //visible
$table_contents = $cur_elem->LinkTableByType();
$sql = "INSERT INTO `$table_contents` (`parent_id`, `parent_type`, `id`, `type`, `pos`, `state`) VALUES ($parent_elem->elem_id, '$parent_elem->type', $cur_elem->elem_id, '$cur_elem->type','$newpos','$newstate');";
//print $sql;
$this->query($sql);
}
function Update()
{
$this->db->autoCommit(false);
//Check for page access rights
$this->cur_elem->GetFromRequest();
//print_r($this);
if(!$this->cur_elem->Update($bNewElem)){
$this->ErrorMsg(CantCreateNewElement." elem_id=".$this->cur_elem->elem_id);
return false;
}
//make link
if($bNewElem && $this->cur_page_id){
if(!$this->parent_elem->LinkElem($this->cur_elem, false)){
$this->db->Rollback();
}
}
if($this->GetParam("state", $state))
$this->cur_elem->SetState($parent_elem, $state);
$this->db->Commit();
if($bNewElem && $this->cur_elem->type=='page')
array_pop($this->elems_path);
//TODO cache
//$Out=$this->output();
//include("functions/cache_do.php");
}
function GetPageMaxPos($table, $page_id)
{
$sql = "SELECT MAX(pos) as pos FROM $table WHERE parent_id=$page_id";
$res = $this->query($sql);
if (DB::isError($res)) {
return 0; //first pos =0
}
$row = $res->fetchRow(DB_FETCHMODE_ASSOC);
if(!is_array($row))
return 0; //first pos =0
return $row['pos'];
}
function GetElems($type)
{
return CElemDB::GetElemsByType($this, $type);
}
function ElemsToXML($xml_parent, $Elems)
{
foreach($Elems as $Elem){
$xml_elem = $Elem->ToXMLNode($this->xmlSiteDom);
$xml_elem = $xml_parent->append_Child($xml_elem);
}
}
function GetPageContent(&$parent)
{
$Elems = array();
//print ("Get Page($page_id) Content <br />");
if($this->cur_page_id == $parent->elem_id && $parent->type=='page' && count($this->elems_path))
{
//go until non page
$i=0;
while($i< count($this->elems_path)){
if(strncmp($this->elems_path[$i], 'page_', 5)!=0){
list($elem_type, $elem_id) = split('_', $this->elems_path[$i]);
break;
}
$i++;
}
}
if(!isset($elem_id)){
$elem_type="elem";
$elem_id="";
}
//print ("Take childs with mask $elem_type, $elem_id");
//check auth if it necessary //Check all path recursively
if(array_key_exists("access", $parent->attrs) && $parent->attrs["access"]!=0){
$this->auth($parent->attrs["access"]);
}
//clear output param
$this->limits_out = array();
if($elem_id && $elem_type!='page')
{
$Elems = $parent->GetChilds($elem_type, $elem_id);
}
else{
$Elems = $parent->GetChilds("elem","");
}
if(!isset($this->limits_out['image'])){
//temp hack for images field
if($parent->type!='page' && $parent->type !='section' && array_key_exists('images', $parent->attrs)){
$childs_image_ids = $parent->attrs['images'];
if(isset($childs_image_ids)){
$childs_image_ids = split(',',$childs_image_ids);
$img_count=0;
foreach($childs_image_ids as $id)
if($id){
$img = new CElemDB($this, 'image', $id);
$img->Get();
if($img->xml_node){
$img->xml_node = $parent->xml_node->append_child($img->xml_node);
$img_count++;
}
}
}
if($img_count){
$limit = new ElemsLimit('image_0_'.$img_count);
$limit->NumElems = 1;
$limit->toXML($this->xmlSiteDom, $parent->xml_node);
}
}
}
//temp hack --
if(is_array($Elems)){
foreach($this->limits_out as $type=>$limit){
if($limit->NumElems){
$limit->type = $type;
$limit->toXML($this->xmlSiteDom, $parent->xml_node);
}
}
$this->isSingleTextObj=true;
$Count=0;
foreach($Elems as $child_elem){
switch($child_elem->type)
{
case "xml":
case "event":
case "article":
$Count++;
}
if($Count>1){
$this->isSingleTextObj = false;
break;
}
}
foreach($Elems as $child_elem)
{
if(!$child_elem->Get()){
continue;
}
$elem_full_id = $child_elem->type.'_'.$child_elem->elem_id;
//echo $elem_full_id ;
if($this->isProcElem && $child_elem->state!=0){
$this->GetPageContent($child_elem);
}
else
if(in_array($elem_full_id, $this->elems_path)){
$this->GetPageContent($child_elem);
}
//Add to page DOM
$child_elem->xml_node = $parent->xml_node->append_Child( $child_elem->xml_node );
}
}
//print ("Got Page Content <br />");
}
function GetTree($xml_parent="", $expanded=true, $page="", $isChild=false, $ExpandedTree = false)
{
if($xml_parent==""){
if(!$this->xml_root)
$this->new_dom();
$xml_parent = $this->xml_root;
}
if($page==""){
$page = $this->GetPage(sys_root_page_id);
}
$page_id = $page->attrs["id"];
//Do page's DOM
if(!$page->ToXMLNode($this->xmlSiteDom)){
$this->ErrorMsg(CantCreateXmlNode);
return 0;
}
//Add page before other operations
$page->xml_node = $xml_parent->append_Child($page->xml_node);
if($this->cur_page_id == $page_id){
$this->cur_page = &$page;
$isChild=true;
}
if((array_key_exists("expanded", $page->attrs) AND $page->attrs["expanded"])){
$isChild=true;
}
$Count=0;
$Pages = $page->GetChilds("page","");
if(is_array($Pages)){
foreach($this->limits_out as $type=>$limit){
if($limit->NumElems && $type=='page'){
$limit->type = $type;
$limit->toXML($this->xmlSiteDom, $page->xml_node);
}
}
foreach($Pages as $child_page){
if($child_page->Get()){
$this->GetTree($page->xml_node, $expanded, $child_page, false, $ExpandedTree);
}
$Count++;
}
}
//Get current page's content
if($isChild || $ExpandedTree){
//print "ischild = $isChild || $ExpandedTree";
if($expanded){
$this->GetPageContent($page);
}
}
return $Count;
}
//XML Section
function attribute($elem, $name, $value)
{
$elem = $elem->set_attribute($name, iconv("CP1251","UTF-8",$value));
}
//Function create Node with text - <node>text</node>
function add_text_node($elem, $val){
$text_node = $this->xmlSiteDom->create_text_node(iconv("CP1251","UTF-8",$val));
$elem->append_child($text_node);
}
function InstallElements($path, $mask, $excludemask, $access)
{
GetDirArrayByMask($path, $mask,$elementsList);
$types = array();
if(is_array($elementsList))
foreach($elementsList as $elemsql){
$elem_dir = dirname($elemsql);
$newtype = basename($elem_dir);
if($newtype=='elems' || preg_match($excludemask,$newtype))
continue;
if(!in_array($newtype,$types)){
$types[] = $newtype;
}
}
print_r($types);
foreach($types as $newtype){
if(!$this->AddElementsType($path, $newtype, $access))
return false;
}
return true;
}
function AddElementsType($sqlpath, $type, $access)
{
include_once "libraries/DB_backup.php";
$script = new DB_Backup(sys_dsn, sys_dbprefix);
echo 'Install table<br />';
$sqlfilename = $sqlpath."/$type/$type.sql";
$ret = $script->RunFromDump($sqlfilename);
if(!$ret)
return false;
$sqlfilename = $sqlpath."/$type/".$type."s.sql";
if(file_exists($sqlfilename)){
echo 'Install data';
$ret = $script->RunFromDump($sqlfilename);
if(!$ret)
return false;
}
//Register new type
$sql = "SELECT COUNT(1) as count from ".sys_dbprefix.$type.'s';
echo "$sql<br />";
$res = $this->db->query($sql);
if(DB::isError($res))
return false;
if (!$res->numRows())
return false;
$row = $res->fetchRow(DB_FETCHMODE_ASSOC);
$count = $row['count'];
$sql = "INSERT INTO ".sys_dbprefix."types (`name`, `title`, `count`, `access`) VALUES ('$type', '$type', $count, $access);";
echo "$sql<br />";
if(!$this->db->query($sql))
return false;
$sql = "SELECT COUNT(1) as count from ".sys_dbprefix.'types';
echo "$sql<br />";
$res = $this->db->query($sql);
if(DB::isError($res))
return false;
if (!$res->numRows())
return false;
$row = $res->fetchRow(DB_FETCHMODE_ASSOC);
$count = $row['count'];
$sql = "UPDATE ".sys_dbprefix."types SET `count` = $count WHERE `name` = 'type'";
echo "$sql<br />";
if(!$this->db->query($sql))
return false;
$this->installPatterns($sqlpath."$type/");
$this->installStrings($sqlpath."$type/");
return true;
}
function Install()
{
//Clear prev installation
$this->Uninstall();
include_once "libraries/DB_backup.php";
$script = new DB_Backup(sys_dsn, sys_dbprefix);
//Create system tables
$ret = $script->RunFromDump(sys_engine_path."elems/db_install.sql");
//install system elements
if($ret)
$ret = $this->InstallElements(sys_engine_path.'elems/', '*.sql', '/db_.*/i', 1);
if($ret){
$ret = $this->InstallElements(sys_srv_path.'_elems/', '*.sql', '/db_.*/i', 0);
}
if($ret)
$this->ErrorMsg(EngineInstalledSuccessefull);
else
$this->ErrorMsg(EngineInstallFailed);
CEngineBase::Install();
}
function Uninstall()
{
include_once "libraries/DB_backup.php";
$script = new DB_Backup(sys_dsn, sys_dbprefix);
$pattern = 'DROP TABLE IF EXISTS %ss;';
$InstalledElems = $this->GetElems('type');
if(is_array($InstalledElems))
foreach($InstalledElems as $cur_elem){
$sql = sprintf($pattern, $cur_elem->attrs['name']);
$script->RunScript(array($sql));
}
//Clear db
if($script->RunFromDump(sys_engine_path."elems/db_uninstall.sql"))
$this->ErrorMsg(EngineUninstalledSuccessefull);
else
$this->ErrorMsg(EngineUninstallFailed);
}
};
?>