<?php
//#################################################################################################
// Programmers little helpers...
//#################################################################################################
// chillyCMS - Content Management System
// Copyright (C) 2008
// Stefanie Wiegand <hide@address.com> & Johannes Cox <hide@address.com>
//
// This program is licensed under the GPL 3.0 license. For more information see LICENSE.txt.
//#################################################################################################
// ## Text Operations ######################
// only_numbers($string)
// only_text($string)
// num_text($string)
// email_chars($string)
// no_semicola($string)
// no_colons($string)
// lower_case($string)
// filesize_text($bytes)
// cut_doubledots($string)
// escape_html($string)
// ## Array Operations #####################
// array_item($ar, $key)
// remove_by_val($array,$value)
// make_dropdown($array,$name,$selected,$assoc)
// zerofill ($num,$zerofill)
// ## File Operations ######################
// read_files($path)
// chmod_r($path,$filemode)
// make_dir($parent,$newfolder)
// delete_recursively($dirname)
// write_file($file,$text)
// ## Database Operations ##################
// db_query($sql)
// db_query_array($sql)
// db_next_autoincrement()
// escape($array)
// ## Miscellanous Operations ##############
// get_tree($id)
// sort_tree(&$tree,$startdepth,$startparent,&$newtree)
// make_ul($tree)
// sort_linked_list($list)
// move_item($id,$direction,$dbtable)
// get_siblings_r($id,&$items,&$siblings,$siblingdepth)
// js_confirm_link($question)
// exec_sql($script)
//#################################################################################################
defined('DOIT') or die('Restricted access');
//#################################################################################################
//########## Text Operations ######################################################################
//#################################################################################################
$numbers = "0123456789";
$bigletters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$smallletters = "abcdefghijklmnopqrstuvwxyz";
$letters = $bigletters.$smallletters;
$controlchars = array();
for ($i=0; $i<32; $i++) { $controlchars[]=chr($i); }
$asciimailchars = array(32,34,40,41,44,58,59,60,62,91,92,93,127);
$mailchars = array();
foreach ($asciimailchars as $mailchar) { $mailchars[]=chr($mailchar); }
$signs = array();
for ($i=32; $i<48; $i++) { $signs[]=chr($i); }
for ($i=58; $i<65; $i++) { $signs[]=chr($i); }
for ($i=91; $i<97; $i++) { $signs[]=chr($i); }
for ($i=123; $i<127; $i++) { $signs[]=chr($i); }
for ($i=128; $i<256; $i++) { $signs[]=chr($i); }
//Only numbers///////////////////////////////////
function only_numbers($string) {
global $controlchars,$letters,$signs;
$string=str_replace($controlchars,"",$string);
$string=str_replace($letters,"",$string);
$string=str_replace($signs,"",$string);
return $string;
}
//Only Text//////////////////////////////////////
function only_text($string) {
global $controlchars,$numbers,$signs;
$string=str_replace($controlchars,"",$string);
$string=str_replace($signs,"",$string);
$string=str_replace($numbers,"",$string);
return $string;
}
//Numbers and strings////////////////////////////
function num_text($string) {
global $controlchars,$signs;
$string=str_replace($controlchars,"",$string);
$string=str_replace($signs,"",$string);
return $string;
}
//E-mail/////////////////////////////////////////
function email_chars($email) {
$isValid = true;
$atIndex = strrpos($email, "@");
if (is_bool($atIndex) && !$atIndex) {
$isValid = false;
} else {
$domain = substr($email, $atIndex+1);
$local = substr($email, 0, $atIndex);
$localLen = strlen($local);
$domainLen = strlen($domain);
if ($localLen < 1 || $localLen > 64) {
// local part length exceeded
$isValid = false;
} elseif ($domainLen < 1 || $domainLen > 255) {
// domain part length exceeded
$isValid = false;
} elseif ($local[0] == '.' || $local[$localLen-1] == '.') {
// local part starts or ends with '.'
$isValid = false;
} elseif (preg_match('/\\.\\./', $local)) {
// local part has two consecutive dots
$isValid = false;
} elseif (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain)) {
// character not valid in domain part
$isValid = false;
} elseif (preg_match('/\\.\\./', $domain)) {
// domain part has two consecutive dots
$isValid = false;
} elseif (!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/',str_replace("\\\\","",$local))) {
// character not valid in local part unless local part is quoted
if (!preg_match('/^"(\\\\"|[^"])+"$/',str_replace("\\\\","",$local))) { $isValid = false; }
}
if ($isValid && !(checkdnsrr($domain,"MX") || checkdnsrr($domain,"A"))) {
// domain not found in DNS
$isValid = false;
}
}
if ($isValid===true) { return $email; } else { return false; }
}
//No ;///////////////////////////////////////////
function no_semicola($string) {
global $controlchars;
//Remove everything except numbers
$string=str_replace($controlchars,"",$string);
$string=str_replace(";","",$string);
return $string;
}
//No :///////////////////////////////////////////
function no_colons($string) {
global $controlchars;
//Remove everything except numbers
$string=str_replace($controlchars,"",$string);
$string=str_replace(":","",$string);
return $string;
}
//Test if the string contains html injections////
function is_safe($string) {
$container = strtolower($string);
$container = str_replace(' ', "", $string);
//search for injections
$string1 = "<script";
$string2 = "\">";
if(!strstr($string,$string1) && !strstr($string,$string2)) {
//none found
$result = true;
} else {
//found injections
$result = false;
}
return $result;
}
//Transform to lower case letters////////////////
function lower_case($string) {
$lower = array(
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u",
"v", "w", "x", "y", "z", "à ", "á", "â", "ã", "ä", "Ã¥", "æ", "ç", "è", "é", "ê", "ë", "ì", "Ã", "î", "ï",
"ð", "ñ", "ò", "ó", "ô", "õ", "ö", "ø", "ù", "ú", "û", "ü", "ý"
);
$upper = array(
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U",
"V", "W", "X", "Y", "Z", "Ã", "Ã", "Ã", "Ã", "Ã", "Ã
", "Ã", "Ã", "Ã", "Ã", "Ã", "Ã", "Ã", "Ã", "Ã", "Ã",
"Ã", "Ã", "Ã", "Ã", "Ã", "Ã", "Ã", "Ã", "Ã", "Ã", "Ã", "Ã", "Ã"
);
return str_replace($upper, $lower, $string);
}
//Make a readable filesize from a number of bytes
function filesize_text($bytes) {
if ($bytes<1024) {
$unit = " B";
} elseif ($bytes<1024000) {
$bytes=round($bytes/1024,0);
$unit = " kB";
} else {
$bytes=round($bytes/1024000,2);
$unit = " MB";
}
return $bytes.$unit;
}
//Cut .. to prevent a hack///////////////////////
function cut_doubledots($string) {
if (substr($string,0,strlen(PATH))==PATH) { $absolute=true; } else { $absolute=false; }
$string=explode("/",$string);
$newstring=array();
foreach($string as $layer) {
if ($layer!=".." && $layer!="") { $newstring[]=$layer; }
}
$string=implode("/",$newstring);
if ($absolute) { $string="/".$string; }
return $string;
}
//Escape a string for output in html/////////////
function escape_html($string) {
if (is_array($string)) {
foreach ($string as $s) {
escape_html($s);
}
} else {
$string=trim(htmlspecialchars($string, ENT_QUOTES, "ISO-8859-15", false));
}
return $string;
}
//#################################################################################################
//########## Array Operations #####################################################################
//#################################################################################################
//Return an arrayitem if it exists///////////////
function array_item($ar, $key) {
if(is_array($ar) && array_key_exists($key, $ar)) { return($ar[$key]); }
else { return false; }
}
//Remove a key=>value pair from an array/////////
function remove_by_val(&$array,$value) {
foreach ($array as $key=>$val) {
if ($val==$value) {
unset ($array[$key]);
return true;
}
}
return false;
}
//Make a dropdown menu from an array/////////////
function make_dropdown($array,$name,$selected,$assoc=1) {
$dropdown="<select name='$name'>\n";
if ($assoc==1) {
foreach ($array as $key=>$value) {
$dropdown.="<option ";
if ($key==$selected) { $dropdown.="selected='selected' "; }
$dropdown.="value='$key'>$value</option>\n";
}
} else {
foreach ($array as $option) {
$dropdown.="<option";
if ($option==$selected) { $dropdown.=" selected='selected'"; }
$dropdown.=">$option</option>\n";
}
}
$dropdown.="</select>\n";
return $dropdown;
}
//Fill a numberstring with additional zeroes/////
function zerofill ($num,$digits) {
while (strlen($num)<$digits) { $num = "0".$num; }
return $num;
}
//#################################################################################################
//########## File Operations ######################################################################
//#################################################################################################
//Read the contents of a directory///////////////
function read_files($path,&$files,$recursive=false) {
$handle = opendir($path);
//can the directory be accessed?
if ($handle) {
//read content
while (false !== ($file = readdir($handle))) {
//exclude special nodes
if ($file != "." && $file != "..") {
$name = $path."/".$file;
if (is_dir($name)) {
if ($recursive) {
$files[]=array("dir"=>$file,"content"=>read_files($name,$files,true));
}
} else {
$files[]=array("name"=>$file,"size"=>filesize($name),'path'=>$path);
}
}
}
} else {
return false;
}
closedir($handle);
return $files;
}
//Copy files recursively to their new folder/////
function copyfiles_r($files) {
global $page;
$return = true;
foreach ($files as $file) {
if ($file && trim($file!='')) {
//directory
if (isset($file['dir'])) {
$newfiles = $file['content'];
if (!copyfiles_r($newfiles)) { return false; }
} else {
//file
$src = $file["path"].'/'.$file['name'];
if ($file['name']=='tools.include.php' or $file['name']=='tools.site.php') {
//updater files to special folder
$dest = PATH.'/tmp/newupdater/'.$file['name'];
$page->debug($dest);
} else {
//all other files to normal update folder
$dest = PATH.substr($file["path"],strlen(PATH)+11).'/'.$file['name'];
}
if (!copy($src, $dest)) {
$return = false;
}
}
}
}
return $return;
}
//Change file permissions////////////////////////
function chmod_r($path, $filemode) {
if (!is_dir($path)) {
if (@chmod($path, $filemode)) { return true; }
else { return false; }
}
$dh = opendir($path);
while (($file = readdir($dh)) !== false) {
if($file != '.' && $file != '..') {
$fullpath = $path.'/'.$file;
if(is_link($fullpath)) {
return false;
} elseif(!is_dir($fullpath)) {
if (!@chmod($fullpath, $filemode)) {
return false;
} elseif(!chmod_r($fullpath, $filemode)) {
return false;
}
}
}
closedir($dh);
if(chmod($path,$filemode)) { return true; } else { return false; }
}
}
//Create a folder in the given path//////////////
function make_dir($parent,$newfolder) {
$return=false;
$parent=cut_doubledots($parent);
$newfolder=cut_doubledots($newfolder);
//add "/" if not already there
if (substr($parent, -1, 1)!="/") { $parent.="/"; }
//Path to the new folder
$path=$parent.$newfolder;
//absolute path? -> append / (removed by cut_doubledots)
if (substr($path,0,strlen(PATH)-1)==substr(PATH,1)) { $path="/".$path; }
if (!is_dir($path)) {
if(@mkdir($path)) { $return = true; }
} else {
$return=true;
}
return $return;
}
//Delete recursively/////////////////////////////
function delete_recursively($dirname) {
$dirname=cut_doubledots($dirname);
//absolute path? -> append / (removed by cut_doubledots)
if (substr($dirname,0,strlen(PATH)-1)==substr(PATH,1)) { $dirname="/".$dirname; }
//is it a directory?
if(is_dir($dirname) && $dirname!='/') {
//can it be accessed?
$dir_handle=@opendir($dirname);
while($file=@readdir($dir_handle)) {
//don't follow symlinks
if($file!="." && $file!=".." && !is_link($dirname)) {
if(!is_dir($dirname."/".$file)) {
if (!@unlink($dirname."/".$file)) { return false; }
} else {
delete_recursively($dirname."/".$file);
}
}
}
@closedir($dir_handle);
if (is_link($dirname)) {
if (!@unlink($dirname)) { return false; }
} else {
if (!@rmdir($dirname)) { return false; }
}
return true;
}
return false;
}
//Write text to file in w+ mode//////////////////
function write_file($file,$text) {
if (is_writable($file)) {
if (!$handle = fopen($file, "w+")) { return false; } //no permissions?
if (!fwrite($handle, $text)) { return false; } //else error
fclose($handle);
return true;
} else { return false; }
}
//Get all languages//////////////////////////////
function get_languages() {
$languages=array();
//Load all installation language files from language folder
$handle = opendir(PATH."/languages");
if ($handle) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != ".." && !is_dir($file)) {
$fileending = substr($file, strlen($file) - 4);
if ($fileending == ".php") {
$file = substr($file, 0, -4);
array_push($languages, $file);
}
}
}
}
if (empty($languages)) { $languages[]="en"; }
sort($languages);
return $languages;
}
//#################################################################################################
//########## Database Operations ##################################################################
//#################################################################################################
//Escape an array////////////////////////////////
function escape($array) {
if (is_array($array) && !empty($array)) {
$array = @array_map("trim", $array);
if(get_magic_quotes_gpc()) {
$array = array_map("stripslashes", $array);
}
$cleanarray = array_map("mysql_real_escape_string", $array);
return $cleanarray;
} elseif ($array!="" && $array!=null && $array) {
$string = trim($array);
if(get_magic_quotes_gpc()) {
$string = stripslashes($string);
}
$cleanstring = mysql_real_escape_string($string);
return $cleanstring;
} else {
return false;
}
}
//#################################################################################################
//########## Miscellanous Operations ##############################################################
//#################################################################################################
//Get Tree///////////////////////////////////////
function get_tree($id) {
global $page;
//Join data from site_navigation with the name from site_content
$sql="select distinct if(c4.id,1,0) as haschildren,u.user as uname,c1.*, m.name as modname ".
//prev/next
",ifnull(c2.id,0) as prev, ifnull(c3.id,0) as next ".
"from site_content as c1 ".
"left join system_users u on c1.uid=u.uid ".
"left join system_modules m on m.modid=c1.modid ".
//prev
"left join site_content c2 on c2.order=c1.order-1 and c1.parentid=c2.parentid ".
//next
"left join site_content c3 on c3.order=c1.order+1 and c1.parentid=c3.parentid ".
//has children?
"left join site_content c4 on (c4.parentid=c1.id or c4.treeid=c1.id) and c4.order=1 ".
"where c1.treeid=$id ".
"order by c1.depth,c1.order";
$page->query($sql);
$result = $page->db->getdata_array();
$tree=array();
if (!empty($result)) {
foreach ($result as $row) {
//Make new menuitem object
$mi=new Menuitem($row["id"],$row["name"],$row["treeid"],$row["depth"],$row["parentid"],
$row["order"],$row["prev"],$row["next"],$row["active"],$row["startpage"],$row["modid"],
$row["modname"],$row["settings"],$row["access"],$row["specialaccess"],$row["uid"],
$row["date_new"],$row["date_edit"],$row["views"],$row["content"],$row["haschildren"]);
//Just put inside a "tree"
$tree[$row["depth"]][$row["parentid"]][]=$mi;
}
}
$maxdepth=sizeof($tree)-1;
$newtree=array();
sort_tree($tree,0,0,$newtree);
return $newtree;
}
//Sort a tree (recursively)//////////////////////
function sort_tree(&$tree,$startdepth,$startparent,&$newtree) {
if (!empty($tree[$startdepth][$startparent])) {
foreach ($tree[$startdepth][$startparent] as $key=>$item) {
//append element
$newtree[]=$item;
//children?
if ($item->haschildren) {
sort_tree($tree,$startdepth+1,$item->id,$newtree);
}
unset($tree[$startdepth][$startparent][$key]);
}
}
}
//Converts a tree-array to a ul-array/////////////
function make_ul($tree) {
$depth = 1;
$ischild = false;
$ul = $tmp = array();
//heading
if (isset($tree[0])) {
$ul[]=$tree[0];
}
unset($tree[0]);
//items
foreach ($tree as $item) {
//same depth as prev item
if ($item->depth==$depth) {
if ($item->haschildren or $ischild) {
$tmp[]=$item;
$ischild=true;
} else {
$ul[]=$item;
}
//deeper (=child)
} else if ($item->depth>$depth) {
$depth+=1;
//first child
$tmp[]=$item;
//higher (=next to parent)
} else {
$depth-=1;
$ischild=false;
//prev item (including children if any)
$parent=$tmp[0];
unset($tmp[0]);
$children=$tmp;
$tmp=array();
$ul[]=array("parent"=>$parent,"children"=>$children);
if ($item->haschildren) {
$tmp[]=$item;
$ischild=true;
} else {
$ul[]=$item;
}
}
}
//last item(s)
if (!empty($tmp)) {
$parent=$tmp[0];
unset($tmp[0]);
$children=$tmp;
$tmp=array();
$ul[]=array("parent"=>$parent,"children"=>$children);
}
return $ul;
}
//Sort a linked list/////////////////////////////
function sort_linked_list($list) {
$list_sorted=array();
//begin with last item
$next=0;
//look at the rest of the items
while (!empty($list)) {
//look at each subitem to find the next one
foreach ($list as $key=>$item) {
//if the prev item was the last one we appended
if ($item->next==$next) {
//append it
$list_sorted[] = $item;
$next=$item->id;
//and delete it from array
unset($list[$key]);
}
}
}
//reverse list
$list_sorted=array_reverse($list_sorted);
return $list_sorted;
}
//Move Item up/down//////////////////////////////
function move_item($id,$direction,$dbtable) {
global $l_cont,$page;
$error = false;
$id = escape($id);
$direction = escape($direction);
$dbtable = escape($dbtable);
if ($dbtable=="site_content") { $parent="parentid"; }
elseif ($dbtable=="site_modules") { $parent="position"; }
if (!$page->query("start transaction")) { $error=true; }
//get data of items
$sql="select t1.`order`,t1.$parent as parent,max(t2.order) as maxorder from $dbtable as t1, $dbtable as t2 ".
"where t1.id=$id and t1.$parent=t2.$parent group by t1.parentid limit 1";
if (!$page->query($sql)) { $error=true; }
$item = $page->db->getdata();
$maxorder=$item["maxorder"];
if ($direction=="up") {
$page->debug("Moving item up...");
//if item is already at the topmost position
if ($item["order"]<=1) { return array($l_cont["msg_movetop_err"],"bad"); }
//move top element down
$sql="update $dbtable set `order`=$item[order] where `order`=$item[order]-1 and $parent='$item[parent]'";
if (!$page->query($sql)) { $error=true; }
//move element up
$sql="update $dbtable set `order`=`order`-1 where id=$id";
if (!$page->query($sql)) { $error=true; }
} else if ($direction=="down") {
$page->debug("Moving item down...");
//if item is already at the last position
if ($item["order"]==$maxorder) { return array($l_cont["msg_movebot_err"],"bad"); }
//move lower element up
$sql="update $dbtable set `order`=$item[order] where `order`=$item[order]+1 and $parent='$item[parent]'";
if (!$page->query($sql)) { $error=true; }
//move element down
$sql="update $dbtable set `order`=`order`+1 where id=$id";
if (!$page->query($sql)) { $error=true; }
}
if (!$error) {
$page->query("commit");
$msg = array($l_cont["msg_move_ok"],"good");
} else {
$page->query("rollback");
$msg = array($l_cont["msg_move_err"],"bad");
}
return $msg;
}
//Get all siblings recursively/////////////////////////////////////////////////////////////////////
function get_siblings_r($id,&$items,&$siblings,$siblingdepth) {
if (!empty($items)) {
foreach ($items as $key=>$i) {
if ($i["parentid"]==$id) {
$siblings[$i["id"]]=$i;
if ($i["haschildren"]==1) {
get_siblings_r($i["id"],$items,$siblings,$siblingdepth+1);
}
}
}
}
}
//Javascript confirmation popup//////////////////
function js_confirm_link($question) {
//$question=htmlentities($question);
$js="onclick=\" if (!confirm('$question')) { return false }\" ";
return $js;
}
//Execute an SQL script//////////////////////////
function exec_sql($script) {
global $page;
$destroy_after = false;
if (!@is_resource($page->db->connection) and !@is_resource($page->connection)) {
$page = new Database();
$destroy_after = true;
}
$return = false;
$handle=@fopen($script, "r");
if ($handle) {
$queries="";
while (!feof($handle)) {
$line=fgets($handle);
if (substr($line,0,2)!="--") { $queries.=$line; }
}
fclose($handle);
$queries=explode(";\n", $queries);
$page->query("start transaction");
$errors=0;
foreach ($queries as $query) {
$query=trim($query);
if ($query!="") {
//wait so the creation time of the tables differs (for backup)
if (strtolower(substr($query,0,6))=="create") {
sleep(1);
}
if (!$page->query($query)) {
$errors++;
//echo $query.'<br /><br />';
}
}
}
if ($errors==0) {
$page->query("commit");
$return = true;
} else {
$page->query("rollback");
}
if ($destroy_after === true) {
$page->close();
}
}
return $return;
}
//Postlink///////////////////////////////////////
function postlink($label, $hiddenvalues=array(), $action="", $button=false) {
if ($button==true) { $class = "button"; } else { $class = "linkbutton"; }
$postlink = "<form method=\"post\" action=\"$action\">\n";
foreach ($hiddenvalues as $k=>$v) {
$postlink .= "<input type=\"hidden\" name=\"$k\" value=\"$v\" />\n";
}
$postlink .= "<input type=\"submit\" class=\"$class\" value=\"$label\">\n".
"</form>\n";
return $postlink;
}
//generate a token///////////////////////////////
function make_token() {
return mt_rand().md5($_SERVER["HTTP_USER_AGENT"]).mt_rand().md5(time()).mt_rand();
}
//date dropdown fields///////////////////////////
function date_select($day=1,$month=1,$year=1970) {
//--day
$dayselect = "<select class=\"bday\" name=\"bday\" size=\"1\">";
for ($i=1;$i<=31;$i++) {
if ($i==$bday) { $selected = " selected=\"selected\""; } else { $selected = ""; }
$dayselect .= "<option value=\"$i\"$selected>$i</option>";
}
$dayselect .= "</select>";
//--month
$months = array(1=>"Januar", 2=>"Februar", 3=>"März", 4=>"April", 5=>"Mai", 6=>"Juni",
7=>"Juli", 8=>"August", 9=>"September", 10=>"Oktober", 11=>"November", 12=>"Dezember",);
$monthselect = "<select class=\"bmonth\" name=\"bmonth\" size=\"1\">";
foreach ($months as $i=>$monthname) {
if ($i==$bmonth) { $selected = " selected=\"selected\""; } else { $selected = ""; }
$monthselect .= "<option value=\"$i\"$selected>$monthname</option>";
}
$monthselect .= "</select>";
//--year
$yearselect = "<select class=\"byear\" name=\"byear\" size=\"1\">";
for ($i=date("Y");$i>=1900;$i--) {
if ($i==$byear) { $selected = " selected=\"selected\""; } else { $selected = ""; }
$yearselect .= "<option value=\"$i\"$selected>$i</option>";
}
$yearselect .= "</select>";
$dateselect = $dayselect.$monthselect.$yearselect;
return $dateselect;
}
//Message////////////////////////////////////////
function msg($msg=false,$class="good") {
$return = false;
//if the message is already formatted
if (is_array($msg) && sizeof($msg)==2 && ($msg[1]=='good' or $msg[1]=='bad')) {
$return = '<p class="msg_'.$msg[1].'">'.$msg[0].'<span></span></p>';
//the message comes in parts
} else {
if ($msg && trim($msg!='')) {
$return = '<p class="msg_'.$class.'">'.$msg.'<span></span></p>';
}
}
return $return;
}
?>