<?php
/* Ulyxex version 1.6.7.8 ***************/
/* code http://ulyxex.logz.org **********/
/* Andre Lozano http://andre-lozano.org */
class Tree extends Ulyxex {
public object $h;
public object $t;
public array $parentOf;
public array $name;
public array $type;
public array $hasChild;
public array $hasAncestor;
public string $ch;
public string $spchar;
function __construct(){
$this->h = New Htmlz();
$this->t = New Translate();
$this->ch = "↘"; // "↘" sud/est flèche or "./" or "⤥" flèche courbée
$this->spchar = " ";
}
public function paths($hide=null,$userId=null){
$paths = array();
$this->parentOf = array();
$this->name = array();
$this->type = array();
$this->hasChild = array();
$this->childs = array();
$this->hasAncestor = array();
if ($hide){
$query = SELECT."ID,NAME,TYPEPAGE,PARENTID,PRIORITY".FROM.PAGES.WHERE."HIDE != 1";
if ($userId) $query .= _AND_."USERID = ".$userId;
} else {
$query = SELECT."ID,NAME,TYPEPAGE,PARENTID,PRIORITY".FROM.PAGES;
if ($userId) $query .= WHERE."USERID = ".$userId;
}
$query = $this->q($query);
while ( $line = $this->fetch($query) ){
$this->parentOf[$line['ID']] = $line['PARENTID'];
$priority = ($line['PRIORITY'] != "99")?$line['PRIORITY']:"";
$this->name[$line['ID']] = $priority.$line['NAME'];
$this->titleName[$line['ID']] = $line['NAME'];
$this->type[$line['ID']] = $line['TYPEPAGE'];
$this->hasAncestor[$line['ID']] = array();
$this->childs[$line['ID']] = array();
}
foreach($this->parentOf as $child => $parent){
$this->childs[$parent][] = $this->titleName[$child];
$ancestorId = 0;
$ancestorsNames = array();
if ($parent == 0){
// if parent is website root
$lineage = "/".$this->name[$child]."/";
$paths[$lineage] = array($this->type[$child],$child);
} else {
// if parent other than website root
// add parent
if (isset($this->name[$parent])){
// prevent error in lineage
if ( in_array($this->name[$parent],$ancestorsNames) ){echo " ERROR TREE ! ? = ".$this->name[$parent];break;}
$ancestorsNames[] = $this->name[$parent];
$this->hasAncestor[$child][] = $parent;
$this->hasChild[] = $parent;
}
// if a gran parent exist
if (array_key_exists($parent, $this->parentOf)){
$ancestorId = $this->parentOf[$parent];
// if others gran gran... parent exist
while ($ancestorId != 0){
if (isset($this->name[$ancestorId])){
// prevent error in lineage
if ( in_array($this->name[$ancestorId],$ancestorsNames) ){echo " ERROR TREE ! ? = ".$this->name[$ancestorId];break;}
$ancestorsNames[] = $this->name[$ancestorId];
$this->hasAncestor[$child][] = $ancestorId;
}
if (isset($this->parentOf[$ancestorId]) && $this->parentOf[$ancestorId] != 0){
$ancestorId = $this->parentOf[$ancestorId];
} else {
$ancestorId = 0;
}
}
$ancestorsNames = array_reverse($ancestorsNames);
$lineage = "/".implode("/",$ancestorsNames)."/".$this->name[$child]."/";
$paths[$lineage] = array($this->type[$child],$child);
}
}
}
return $paths;
}
public function pathsSelect($selected=null,$root=1,$type=null,$userId=null,$hide=null){
$t = $this->t;$h = $this->h;
$paths = $this->paths($hide,$userId);
ksort($paths);
$options = array();
if ($root) $options[$t->w("website ROOT")] = 0;
foreach($paths as $path => $idVal){
$pathDepth = array_slice(explode("/",$path),1,-1);// first "/", last "/" and array position
$ch = str_repeat($this->ch,count($pathDepth)-1);
$path = array_pop($pathDepth);
$path = preg_replace("/^\d{2}/","",$path); // rip priority
$path = $ch.$path;
if ($type) {
if ($idVal[0] == $type) {
$options[$path." [".$idVal[1]."]"] = $idVal[1];
} elseif ($idVal[0] == "link") {
$options[$path." [".$idVal[1]."][link]"] = $idVal[1];
} else {
$options[$path." [".$idVal[1]."][".$idVal[0]."]"] = $idVal[1];
}
} else {
$options[$path] = $idVal[1];
}
}
if (empty($options)){// check if at least one page is created
return $h->color($t->w("No page => add to SANDBOX"),"red");
} else {
return $h->select($options,"parent",$selected);
}
}
public function pathsSelectSiteParams($pageId,$name){
$t = $this->t;$h = $this->h;
$paths = $this->paths();
ksort($paths);
$options = array();
foreach($paths as $path => $idVal){
$pathDepth = array_slice(explode("/",$path),1,-1);// first "/", last "/" and array position
$ch = str_repeat($this->ch,count($pathDepth)-1);
$path = array_pop($pathDepth);
$path = preg_replace("/^\d{2}/","",$path); // rip priority
$path = $ch.$path;
if ($pageId == $idVal[1]) {
$optionSelectect = "k=".$idVal[0]."&v=".$idVal[1];
}
$options[$path] = "k=".$idVal[0]."&v=".$idVal[1];
}
return $h->select($options,$name,$optionSelectect,$h->v("onchange","fillFieldSite(this.value,'".$t->w("afficher")."')"));
}
public function pathTest($page=0,$parent=0){
$paths = $this->paths();
$lineage = explode("/",array_search($parent,$paths));
return (in_array($this->name[$page],$lineage))?0:1;
}
public function pathPage($parent=0){
$paths = $this->paths();
return array_search($parent,$paths);
}
public function ripPriorityPath($path=""){
$cleanItems = array();
$separator = " ⤷ ";
$items = array_slice(explode("/",$path),1,-1);// first "/", last "/" and array position
$cleanItems = $this->ripPriority($items);
if (count($cleanItems) > 1) {
$result = implode($separator,$cleanItems);
return $result;
} else {
return null;
}
}
public function ripPriority($items=array()){
$cleanItems = array();
foreach($items as $item){
$item = preg_replace("/^\d{2}/","",$item); // rip priority
$cleanItems[] = $item;
}
return $cleanItems;
}
//~ menus type
//~ menu inline
function getMenuLine($pageId=0){
$h = $this->h;$t = $this->t;
$home = $this->site_params();
$homeId = $home['PAGEID'];
$menu = array();
$query = SELECT."ID,NAME,TYPEPAGE,PRIORITY".FROM.PAGES.WHERE."HIDE != 1";
$query = $this->q($query);
while ( $line = $this->fetch($query) ){
$priority = ($line['PRIORITY'] != "00")?$line['PRIORITY']:"";
$alt = $h->alt($t->wz("show").$line['NAME']);
if ($line['ID'] == $pageId){
$menu[$priority.$line['NAME']] = $h->ahref("index.php?k=".$line['TYPEPAGE']."&v=".$line['ID'],$line['NAME'],$h->v("class","current").$alt);
} else {
$menu[$priority.$line['NAME']] = $h->ahref("index.php?k=".$line['TYPEPAGE']."&v=".$line['ID'],$line['NAME'],$h->v("class","menu").$alt);
}
}
ksort($menu,SORT_STRING | SORT_FLAG_CASE);
$menu = implode(" ",array_values($menu));
return $h->div($menu,$h->v("id","inline"));
}
//~ menu inline nav
function getMenuInlineNav($pageId=0,$pageType=null) {
$h = $this->h;$t = $this->t;
//~ triangle
//~ down ▿
//~ up ▵
//~ right ▹
//~ left ◃
$triangleDown = "▿";
$triangleUp = "▵";
$home = $this->site_params();
$homeId = $home['PAGEID'];
//~ init paths
$paths = $this->paths($hide=1);
//~ create data array from pages
$ancestor = array();
$name = array();
$typePg = array();
$priority = array();
//~ menu elements
$returnHome = "";
$returnAncestor = "";
$current = "";
$query = SELECT."*".FROM.PAGES.WHERE."HIDE != 1";
$query = $this->q($query);
while ( $line = $this->fetch($query) ) {
$ancestor[$line['ID']] = $line['PARENTID'];
$typePg[$line['ID']] = $line['TYPEPAGE'];
$name[$line['ID']] = $line['NAME'];
$priorityLevel[$line['ID']] = $line['PRIORITY'];
$alt[$line['ID']] = $h->alt($t->wz("show").$line['NAME']);
}
$menu = array();
//~ if home then
if ($pageId == $homeId){ // current (home), childs, childs of 0
//~ show current (home)
$returnHome = $h->span($name[$homeId],$h->v("class","current").$alt[$homeId]);
//~ get childs links from home and show them
$query = SELECT."ID".FROM.PAGES.WHERE."PARENTID = ".$homeId._AND_."HIDE != 1";
$query = $this->q($query);
while ( $line = $this->fetch($query) ) {
$priority = ($priorityLevel[$line['ID']]!= "99")?$priorityLevel[$line['ID']]:"";
$item = $priority.$name[$line['ID']].$line['ID'];
$triangleOrNot = in_array($line['ID'],$this->hasChild)?$triangleDown:"";
$menu[$item] = $h->ahref(
"index.php?k=".$typePg[$line['ID']]."&v=".$line['ID'],
$name[$line['ID']].$triangleOrNot,
$h->v("class","menu").$alt[$line['ID']]
);
}
//~ get links from parent id root (0)
$query = SELECT."ID".FROM.PAGES.WHERE."PARENTID = 0"._AND_."HIDE != 1"._AND_."ID != ".$homeId;
$query = $this->q($query);
while ( $line = $this->fetch($query) ) {
$priority = ($priorityLevel[$line['ID']] != "99")?$priorityLevel[$line['ID']]:"";
$item = $priority.$name[$line['ID']].$line['ID'];
$triangleOrNot = in_array($line['ID'],$this->hasChild)?$triangleDown:"";
$menu[$item] = $h->ahref(
"index.php?k=".$typePg[$line['ID']]."&v=".$line['ID'],
$name[$line['ID']].$triangleOrNot,
$h->v("class","menu").$alt[$line['ID']]
);
}
} else if (!in_array($pageType,array("contact","user"))) { // home, current, childs
//~ show home link with two triangles up
$returnHome = $h->ahref(
"index.php?k=".$typePg[$homeId]."&v=".$homeId,
$triangleUp.$name[$homeId].$triangleUp,
$h->v("class","menu").$alt[$homeId]
);
//~ get ancestor if not home and not website root and exist
$ancestorId = isset($ancestor[$pageId])?$ancestor[$pageId]:$homeId;
if ($ancestorId != $homeId && $ancestorId != 0) {
$returnAncestor = $h->ahref(
"index.php?k=".$typePg[$ancestorId]."&v=".$ancestorId,
$name[$ancestorId].$triangleUp,
$h->v("class","menu").$alt[$ancestorId]
);
}
//~ show current
$current = isset($ancestor[$pageId])?$h->span($name[$pageId],$h->v("class","current").$alt[$pageId]):"";
//~ get childs links from page id and show them
$query = SELECT."ID".FROM.PAGES.WHERE."PARENTID = ".$pageId._AND_."HIDE != 1;";
$query = $this->q($query);
while ( $line = $this->fetch($query) ) {
$priority = ($priorityLevel[$line['ID']] != "99")?$priorityLevel[$line['ID']]:"";
$item = $priority.$name[$line['ID']].$line['ID'];
$triangleOrNot = in_array($line['ID'],$this->hasChild)?$triangleDown:"";
$menu[$item] = $h->ahref(
"index.php?k=".$typePg[$line['ID']]."&v=".$line['ID'],
$name[$line['ID']].$triangleOrNot,
$h->v("class","menu").$alt[$line['ID']]
);
}
} else { // if others like contact, user (not pages)
//~ show home link with two triangles up
$returnHome = $h->ahref(
"index.php?k=".$typePg[$homeId]."&v=".$homeId,
$triangleUp.$name[$homeId].$triangleUp,
$h->v("class","menu").$alt[$homeId]
);
}
ksort($menu,SORT_STRING | SORT_FLAG_CASE);
$menu = array_values($menu);
$menu = implode(" ",$menu);
//~ return home and return ancestor and current always at beginning
if ($current != "") $menu = $current." ".$menu;
if ($returnAncestor != "") $menu = $returnAncestor." ".$menu;
$menu = $returnHome." ".$menu;
return $h->div($menu,$h->v("id","inlinenav"));
}
//~ menu type form
function getMenuForm($pageId=0,$pageType=""){
//~ you can usualy use chars for space
//~ ☰ ☰ "☰" Trigram For Heaven
//~ ↳ ↳ "↳" DOWNWARDS ARROW WITH TIP RIGHTWARDS
//~     " " IDEOGRAPHIC SPACE
//~     " " PUNCTUATION SPACE
//~     " " FIGURE SPACE
//~     " " Figure Space is invisible whitespace character that has the same width as a digit
//~   breakable space
//~ if you want to use netspace 2.02 don't use blank space or - or unicode as first char, use underscore "_"
$this->spchar = " "; // figure space   (set again)
$h = $this->h;$t = $this->t;
$paths = $this->paths($hide=1); // prevent showing hide links
ksort($paths,SORT_STRING | SORT_FLAG_CASE);
$pages_paths = array();
$selectedPath = $pageType.",".$pageId;
$navigationTitle = "--".$t->w("Pages").str_repeat("-",20-strlen($t->w("Pages")));
// pages
$pages_paths[$navigationTitle] = "limit";
foreach($paths as $path => $idVal){
$pathDepth = array_slice(explode("/",$path),1,-1);// first "/", last "/" and array position
$ch = str_repeat($this->spchar,count($pathDepth)-1);
if (count($pathDepth)-1 > 0) $ch .= SITETAB." ";
$path = array_pop($pathDepth);
$path = preg_replace("/^\d{2}/","",$path); // rip priority
$path = $ch.$path; // add before spaces
$pages_paths[$path] = $idVal[0].",".(string)$idVal[1];
}
$options = $pages_paths;
//~ refresh button ico, rond ◉ oplus ⊕ loz ◊ phi Φ refresh ico : up right ↺ down left ⟳
$refreshIco = "⟳";
$menu = $h->p(
$this->selectOnChangeMenu($options,"navSelect",$selectedPath,$h->alt($t->w("click to select page")))
." ".
$h->input("submit","OK",$refreshIco,$h->v("class","navsubmit").$h->alt($t->w("click to select page")))
);
$menu = $h->form($menu,"navform","post","index.php");
return $h->div($menu,$h->v("id","scrollmenu"));
}
/* special change menu for getMenuForm */
function selectOnChangeMenu($options=null,$name=null,$selected=null,$params=null){
$h = $this->h;$t = $this->t;
if ($name != null) $name = $h->v("id",$name).$h->v("name",$name);
$params = $h->_($params);
$optionsList = array();
foreach($options as $item=>$value){
if ($value == $selected){
$attributes = $h->v("value",$value).$h->v("selected","selected");
$optionsList[] = "<option ".rtrim($attributes).">"."☰".$this->spchar.$item."</option>";
} else {
$attributes = $h->v("value",$value);
$optionsList[] = "<option ".rtrim($attributes).">".$this->spchar.$this->spchar.$item."</option>";
}
}
$options = implode("\n",$optionsList);
return "<select ".$name." ".$h->v("onchange","this.form.submit()").$h->v("onmouseover","this.click()").$params.">\n".$options."</select>\n";
}
//~ menu type list
function getMenuList($type="ul",$pageId=0){
$h = $this->h;$t = $this->t;
$paths = $this->paths($hide=1); // prevent showing hide links
ksort($paths,SORT_STRING | SORT_FLAG_CASE);
$depth = 2;
$listMenu = "";
$triangleDown = " ▿ ";//~ triangle down ▿
foreach($paths as $path => $idVal){
$pathParts = array_slice(explode("/",$path),1,-1);
$pathPartsPop = array_slice(explode("/",$path),1,-1);
$name = $pathParts[count($pathParts)-1];
$name = preg_replace("/^\d{2}/","",$name); // rip priority
$alt = $h->alt($t->wz("show").$name);
$pathDepth = count($pathParts);
$styleDisplayOff = $h->v("style","display:none; overflow:visible;");
$styleDisplayOn = $h->v("style","display: ; overflow:visible;");
$triangleOrNot = in_array($idVal[1],$this->hasChild)?$triangleDown:"";
$currentOrNot = ($idVal[1] == $pageId)?$h->v("class","current"):"";
$onMouseOver = $h->v("onmouseenter","toogleDropMenuList(this.id)");
$ahrefVal = "index.php?k=".$idVal[0]."&v=".$idVal[1];
$onMouseClick = $h->v("onclick","location.href='".$ahrefVal."'").$h->v("style","cursor:pointer;");;
if ($pathDepth > $depth) {
for ($i=0; $i < $pathDepth-$depth; $i++) {// cascade list
array_pop($pathPartsPop);
$key = "/".implode("/",$pathPartsPop)."/";
$childOf = (isset($paths[$key][1]))?$h->v("id","childof_".$paths[$key][1]):null;
if ( isset($this->hasAncestor[$pageId]) && in_array($paths[$key][1],$this->hasAncestor[$pageId]) ){
$styleDisplay = $styleDisplayOn;
} else {
$styleDisplay = $styleDisplayOff;
}
if ($childOf) {
$attributes = $h->v("class","menulist").$childOf.$styleDisplay;
$listMenu .= "<".$type.$h->_($attributes).">";
} else {
$attributes = $h->v("class","menulist");
$listMenu .= "<".$type.$h->_($attributes).">";
}
}
$depth = $pathDepth;
$listMenu .= $h->li(
$h->ahref($ahrefVal,$name).$triangleOrNot,
$h->v("id",$idVal[1]).$onMouseOver.$onMouseClick.$currentOrNot.$alt
);
} elseif ($pathDepth < $depth) {
for ($i=0; $i < $depth-$pathDepth; $i++) {
//~ prevenir une fermeture de balise quand le menu est vide
if (!empty($listMenu)) $listMenu .= "</".$type.">";
}
$depth = $pathDepth;
$listMenu .= $h->li(
$h->ahref($ahrefVal,$name).$triangleOrNot,
$h->v("id",$idVal[1]).$onMouseOver.$onMouseClick.$currentOrNot.$alt
);
} else {
$listMenu .= $h->li(
$h->ahref($ahrefVal,$name).$triangleOrNot,
$h->v("id",$idVal[1]).$onMouseOver.$onMouseClick.$currentOrNot.$alt
);
}
}
$listMenu = ($type == "ul")?$h->ul($listMenu,$h->v("class","menulist")):$h->ol($listMenu,$h->v("class","menulist"));
return $h->div($listMenu,$h->v("id","menulist"));
}
function getPageBottomLinks(){
$h = $this->h;$t = $this->t;
$menu = array();
$query = SELECT."ID,NAME,TYPEPAGE".FROM.PAGES.WHERE."HIDE != 1"._AND_."TYPEPAGE != 'link'";
$query = $this->q($query);
while ( $line = $this->fetch($query) ){
//~ ajoutez id pour éviter les pages ayant le même nom ne s'écrasent
$menu[$line['NAME'].$line['ID']] = $h->ahref("index.php?k=".$line['TYPEPAGE']."&v=".$line['ID']."&t=".$h->clean_short_url($line['NAME']),$line['NAME'],$h->v("class","bottomlinks").$h->alt($t->wz("page").$line['NAME']) );
}
ksort($menu);
$result = implode(" ",array_values($menu));
return $result;
}
//~ selection navigation
public function pagesNavigation($pageId=0,$pageType="page",$menuStyle=null){
$home = $this->site_params();
if ($menuStyle == null) $menuStyle = $home['NAVTYPE'];
if ($menuStyle == "one_line") {
return $this->getMenuLine($pageId=$pageId);
} elseif($menuStyle == "line_nav") {
return $this->getMenuInlineNav($pageId=$pageId,$pageType=$pageType);
} elseif($menuStyle == "ul_list") {
return $this->getMenuList($type="ul",$pageId=$pageId);
} elseif($menuStyle == "ol_list") {
return $this->getMenuList($type="ol",$pageId=$pageId);
} elseif($menuStyle == "bottom_links") {
return $this->getPageBottomLinks();
} else { // default navigation;
return $this->getMenuForm($pageId=$pageId,$pageType=$pageType);
}
}
//~ menus options
function getSearch($type=null,$id=null) {
$h = $this->h;$t = $this->t;
$inputs[] = $h->input("text","searchwebsite",null,$h->alt($t->w("search")));
$inputs[] = $h->input("submit",null,$t->w("search"));
$inputs = $h->p(implode(" ",$inputs),$h->v("class","searchpage"));
return $h->form($inputs,"searchform","post","index.php?k=".$type."&v=".$id);
}
function getListPagesMenu(){
$h = $this->h;$t = $this->t;
$menu = array();
$query = SELECT.PAGES.".ID,".PAGES.".NAME,".USERS.".ID USERID";
$query .= FROM.PAGES.INNERJOIN.USERS._ON_.PAGES.".USERID = ".USERS.".ID";
switch ($_SESSION['level']){
case 1:
if ($_SESSION['userid'] != 1){// all level 2, 3 and 4 user's pages, user's pages
$query .= WHERE."(".USERS.".USERLEVEL > ".$_SESSION['level']._OR_.USERS.".ID = ".$_SESSION['userid'].")"._AND_.USERS.".ID != 1"._AND_.PAGES.".TYPEPAGE != 'link'"; // but not admin articles
} else {// else no restriction but link
$query .= WHERE.PAGES.".TYPEPAGE != 'link'";
}
break;
default:
$query .= WHERE.PAGES.".USERID = ".$_SESSION['userid']._AND_.USERS.".ID != 1"._AND_.PAGES.".TYPEPAGE != 'link'";
}
$query = $this->q($query);
while ($line = $this->fetch($query)){
//~ Add an ID to prevent pages with the same name from overwriting each other.
//~ $h->nbsp() non-breaking spaces to prevent text wrapping
$menu[$line['NAME'].$line['ID']] = $h->ahref(
"admin.php?action=articles&resetPos=1&pageFilter=".$line['ID'],
$h->nbsp($line['NAME']),
$h->v("class","linkbtn").$h->v("style","text-wrap-mode: nowrap;").$h->alt($t->wz("filter by").$line['NAME'])
);
}
ksort($menu);
return $h->b($t->w("filter by page"),$h->v("style","font-size:small;")).implode(" ",array_values($menu));
}
function getListUsersMenu($via="articles"){
$h = $this->h;$t = $this->t;
$menu = array();
$query = SELECT.USERS.".ID,".USERS.".USERNAME".FROM.USERS;
switch ($_SESSION['level']){
case 1:
if ($_SESSION['userid'] != 1){
// all level 2, 3 and 4 user's pages
// but not admin
// else no restriction
$query .= WHERE."(".USERS.".USERLEVEL > ".$_SESSION['level']._OR_.USERS.".ID = ".$_SESSION['userid'].")"._AND_.USERS.".ID != 1";
}
break;
default:
$query .= WHERE."(".USERS.".ID = ".$_SESSION['userid']._OR_.USERS.".USEROWNER = ".$_SESSION['userid'].")"._AND_.USERS.".ID != 1";
}
$query = $this->q($query);
while ($line = $this->fetch($query)){
$menu[$line['USERNAME'].$line['ID']] = $h->ahref(
"admin.php?action=".$via."&resetPos=1&ownerFilter=".$line['ID'],
$h->nbsp($line['USERNAME']),
$h->v("class","linkbtn").$h->v("style","text-wrap-mode: nowrap;").$h->alt($t->wz("filter by").$line['USERNAME'])
);
}
ksort($menu);
return $h->b($t->w("filter by user"),$h->v("style","font-size:small;")).implode(" ",array_values($menu));
}
}
?>