par hika - 2005-02-06 17:12:52
crée le 2005-02-06 17:12:52
wakka.class.php
<?php
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* Version 0.4
* WAKKA_IMAGE_PROTECT; // default not defined
* If this variable is true, the displayimg() method
* only shows the real if the http referer is on the same realm
* otherwise, it shows an empty image or a replaced image with
* WAKKA_URL_IMAGE_DEFAULT as the URL // default not defined
*
* Version 0.3
* - Wakka is now implemented as an object
* - Upload image form is not always printed
* - Add a preview and reedit button
* - Add a cancel button
* - Can manage external users
* You must provide either a function that returns a userid
* or a function that returns a username
*
* Version 0.2
* - Add a new revision table to have a modification history
* - Here are the variables that can affect this script :
* $force_getvar = true; // défaut unset => true
* This variable force the use of $wakka_page
* instead of $_GET[WAKKA_PAGE_NAME] to select the wakka page
* (cf WAKKA_PAGE_NAME in wakka.inc.php)
* $force_postvar = true; // défaut unset => true
* This variable force the use of $wakka_page
* instead of $_POST[WAKKA_PAGE_NAME] to select the wakka page
* In *ALL* case, the $_POST has the priority
*
* $wakka_page = NULL; // default NULL
* $wakka_nl2br = true;
* $wakka_can_do_revision = false
* $wakka_can_edit = false
* $only_upload_form = false
* $show_header = false
* $show_footer = false
*/
define("REGEXP_WAKKA_PAGE", "[a-zA-Z0-9\-_]+");
define("REGEXP_WAKKA_IMG", "[a-zA-Z0-9\-_]+");
// This is a more restrictive URL regexp that only match http links
define("REGEXP_WAKKA_URL", "https{0,1}://[a-zA-Z0-9/\-\.\~\&\;\?:_\=]+");
define("REGEXP_WAKKA_INTERNAL_URL", "[a-zA-Z0-9/\-\.\~\&\;\?:_\=]+");
define("REGEXP_WAKKA_EMAIL", "[a-zA-Z0-9/\-\._\@]+");
define("REGEXP_WAKKA_CHAR", "[a-zA-Z0-9\ 'éèê@\-\._]");
Class Wakka {
private $wakka_gvars; /* Must be an array */
private $Conn_wakka; /* Must be a Connect object */
private $rewrite_rules;
private $rewrite_rule_enable;
public $wakka_page;
public $nl2br;
public $can_do_revision;
public $can_edit;
public $can_upload_img;
public $only_upload_form;
public $show_header;
public $show_footer;
function Wakka() {
$this->wakka_gvars = array();
$this->wakka_page = NULL;
$this->nl2br = true;
$this->can_do_revision = false;
$this->can_edit = false;
$this->can_upload_img = false;
$this->only_upload_form = false;
$this->show_header = false;
$this->show_footer = false;
$this->force_getvar = true;
$this->force_postvar = true;
$this->rewrite_rule_enable = false;
}
function setConnect(&$Conn) {
if ((is_object($Conn))
&& (get_class($Conn) == "Connect")) {
$this->Conn_wakka = $Conn;
return true;
}
return false;
}
function isConnected() {
return (is_object($this->Conn_wakka))
&& (get_class($this->Conn_wakka) == "Connect");
}
function addRewriteRule($regexp, $rewrite) {
if (!is_array($this->rewrite_rules))
$this->rewrite_rules = array(array($regexp, $rewrite));
else
array_push($this->rewrite_rules, array($regexp, $rewrite));
}
function escape_string($valeur) {
$new_val = str_replace("/", "/", $valeur);
$new_val = str_replace("*", "*", $new_val);
$new_val = str_replace("&", "\&", $new_val);
$new_val = str_replace("[", "[", $new_val);
$new_val = str_replace("]", "]", $new_val);
$new_val = str_replace("(", "\(", $new_val);
$new_val = str_replace(")", "\)", $new_val);
return str_replace("/", "/", $valeur);
}
/* -----------------------------------------------------------------------------
* Callback functions for preg_replace_callback
*/
function getservervars(&$tags, &$values) {
if (isset($_SERVER)) {
$tags = array();
$values = array();
foreach ($_SERVER as $name => $value) {
array_push($tags, "/\\${".$name."}/");
array_push($values, $value);
}
reset($_SERVER);
return true;
}
return false;
}
function include_php_source($matches) {
if (file_exists($matches[1])) {
Include($matches[1]);
}
}
function show_php_source($matches) {
if (substr($matches[1], 0, 7) == "http://") {
$source = highlight_file($matches[1], true);
}
else if (file_exists($matches[1])) {
$source = highlight_file($matches[1], true);
}
if (isset($source)) {
return "<div class=\"".WAKKA_DIV_PHPSOURCE_CSS_CLASS."\">".$source."</div>";
}
}
function show_php_source_string($matches) {
$source = html_entity_decode($matches[1]);
$source = str_replace("<br />", "", $source);
$source = highlight_string($source, true);
return "<div class=\"".WAKKA_DIV_PHPSOURCE_CSS_CLASS."\">".$source."</div>";
}
function mailto_email_protect($matches) {
switch (count($matches)) {
case 2:
$new_val = str_replace("@", " AT ", $matches[1]);
$new_val = str_replace(".", " DOT ", $new_val);
return "<a href=\"mailto:".$new_val."\">".$new_val."</a>";
break;
case 3:
$new_val = str_replace("@", " AT ", $matches[1]);
$new_val = str_replace(".", " DOT ", $new_val);
return "<a href=\"mailto:".$new_val."\">".$matches[2]."</a>";
break;
}
}
function tag_h_replace($matches) {
if (count($matches) == 4) {
$len1 = strlen($matches[1]);
$len2 = strlen($matches[3]);
if ($len1 == $len2 ) {
return "<h".$len1.">".$matches[2]."</h".$len1.">";
}
}
}
function tag_ul_li_replace($matches) {
$li = "";
$elements = explode("\n", $matches[0]);
for ($i = 0; $i < count($elements); $i++) {
$line = str_replace("<br />", "", $elements[$i]);
$line = str_replace("* ", "", $line);
$line = trim($line);
if ($line != "")
$li .= "<li>".$line."</li>\n";
}
return "<ul>".$li."</ul>";
}
function process_internal_url($matches) {
switch(count($matches)) {
case 2:
return "<a href=\"".$this->rewrite_url($matches[1])."\">".
$matches[1]."</a>";
break;
case 3:
return "<a href=\"".$this->rewrite_url($matches[1])."\">".
$matches[2]."</a>";
break;
}
}
function process_external_url($matches) {
switch(count($matches)) {
case 2:
return "<a target=\"_blank\" href=\"".$matches[1]."\">".
$matches[1]."</a>";
break;
case 3:
return "<a target=\"_blank\" href=\"".$matches[1]."\">".
$matches[2]."</a>";
break;
}
}
function process_wakka_url($matches) {
switch(count($matches)) {
case 2:
return "<a href=\"".$this->rewrite_url($_SERVER["SCRIPT_NAME"]."?".WAKKA_PAGE_NAME."=".$matches[1])."\">".
$matches[1]."</a>";
break;
case 3:
return "<a href=\"".$this->rewrite_url($_SERVER["SCRIPT_NAME"]."?".WAKKA_PAGE_NAME."=".$matches[1])."\">".
$matches[2]."</a>";
break;
}
}
function process_wakka_url_img($matches) {
$wakka_img_path = $this->getwakkaimgpath();
switch(count($matches)) {
case 2:
return "<img src=\"".$this->rewrite_url($wakka_img_path."?".WAKKA_IMG_NAME."=".$matches[1])."\" ".
"border=\"0\" alt=\"".$matches[1]."\" title=\"".$matches[1]."\" />";
break;
}
}
function process_wakka_url_img_href($matches) {
$wakka_img_path = $this->getwakkaimgpath();
switch(count($matches)) {
case 3:
return "<a target=\"_blank\" href=\"".$matches[2]."\">".
"<img src=\"".$this->rewrite_url($wakka_img_path."?".WAKKA_IMG_NAME."=".$matches[1])."\" ".
"border=\"0\" alt=\"".$matches[1]."\" title=\"".$matches[1]."\" /></a>";
break;
}
}
/* -------------------------------------------------------------------------- */
/* -----------------------------------------------------------------------------
* Functions that must be private
*/
function getauthorname($wakka_page, $wakka_revision = NULL) {
/* ---------------------------------------------------------------------------
* Get the wakka page 's author name
*
* @param string wakka page name
* @param int (optional) wakka revision number
* @return string author name or NULL
* ------------------------------------------------------------------------ */
if (!$this->isConnected())
return NULL;
if (!is_null($wakka_revision)) {
$SQL = "SELECT wakka_author_id, wakka_author_name
FROM ".WAKKA_TXT_REVISION_TABLE."
WHERE wakka_key = ".STRING_SQL($wakka_page)."
AND wakka_revision = ".NUM_SQL($wakka_revision);
}
else {
$SQL = "SELECT wakka_author_id, wakka_author_name
FROM ".WAKKA_TXT_TABLE."
WHERE wakka_key = ".STRING_SQL($wakka_page);
}
$result = $this->Conn_wakka->QueryDB($SQL);
if ($cur = $this->Conn_wakka->CursorDB($result)) {
$this->Conn_wakka->FreeDB($result);
$username = $this->getauthorname_byid($cur["wakka_author_id"]);
if (!is_null($username))
return $username;
if (!is_null($cur["wakka_author_name"]))
return $cur["wakka_author_name"];
}
else
$this->Conn_wakka->FreeDB($result);
return WAKKA_DEFAULT_UNKNOWN_USER;
}
function getauthorname_byid($id) {
/* ---------------------------------------------------------------------------
* Get the wakka page 's author name by author_id
*
* @param int wakka_author_id
* @return string author name or NULL
* ------------------------------------------------------------------------ */
if ((defined("WAKKA_FUNCTION_GETUSERNAMEBYID"))
&& (!is_null(WAKKA_FUNCTION_GETUSERNAMEBYID))
&& (is_string(WAKKA_FUNCTION_GETUSERNAMEBYID))
&& (WAKKA_FUNCTION_GETUSERNAMEBYID != "")
&& (function_exists(WAKKA_FUNCTION_GETUSERNAMEBYID))
&& (is_numeric($id))) {
return call_user_func(WAKKA_FUNCTION_GETUSERNAMEBYID, $id);
}
return NULL;
}
function getinfowakka($wakka_page, $wakka_revision = NULL) {
/* ---------------------------------------------------------------------------
* Get the wakka page 's raw information
*
* @param string wakka page name
* @param int (optional) wakka revision number
* @return array or NULL
* ------------------------------------------------------------------------ */
if (!$this->isConnected())
return NULL;
if (!is_null($wakka_revision)) {
$SQL = "SELECT *
FROM ".WAKKA_TXT_REVISION_TABLE."
WHERE wakka_key = ".STRING_SQL($wakka_page)."
AND wakka_revision = ".NUM_SQL($wakka_revision);
}
else {
$SQL = "SELECT *
FROM ".WAKKA_TXT_TABLE."
WHERE wakka_key = ".STRING_SQL($wakka_page);
}
$result = $this->Conn_wakka->QueryDB($SQL);
if ($cur = $this->Conn_wakka->CursorDB($result)) {
$this->Conn_wakka->FreeDB($result);
return $cur;
}
else
$this->Conn_wakka->FreeDB($result);
return NULL;
}
function getwakkaimgpath() {
// We get the URL wakka_img_path
$dirname = dirname($_SERVER["SCRIPT_NAME"]);
$included_files = get_included_files();
foreach ($included_files as $included_file) {
$p = str_replace($_SERVER["DOCUMENT_ROOT"], "", $included_file);
$p = str_replace($dirname."/", "", $p);
if (basename($p) == "wakka.class.php") {
return str_replace("wakka.class.php", "wakka_img.php", $p);
break;
}
}
}
function rewrite_url($url) {
if (!$this->rewrite_rule_enable)
return $url;
if (is_array($this->rewrite_rules)) {
foreach ($this->rewrite_rules as $rewrite_rule) {
//echo $rewrite_rule[0].' to '.$rewrite_rule[1].'<br />';
$url_rewrite = preg_replace('/'.$rewrite_rule[0].'/', $rewrite_rule[1], $url);
//echo $url.' => '.$url_rewrite.'<br />';
if ($url != $url_rewrite) {
if ($url_rewrite{0} != '/')
return '/'.$url_rewrite;
return $url_rewrite;
}
}
}
return $url;
}
function resize_image($file_src, &$bin_dst, &$size, $width = NULL, $height = NULL) {
/* ---------------------------------------------------------------------------
* Resize an image, by width, by height or both
* and get the binary result
*
* @param string
* @param ref the binary result
* @param ref the size of the binary result
* @param int (optional)
* @param int (optional)
* @return boolean
* ------------------------------------------------------------------------ */
if (!file_exists($file_src))
return false;
if ($info = getimagesize($file_src)) {
switch($info[2]) {
case 1: // GIF
if ((is_numeric($width)) || (is_numeric($height)))
$img_src = imagecreatefromgif($file_src);
break;
case 2: // JPEG
if ((is_numeric($width)) || (is_numeric($height)))
$img_src = imagecreatefromjpeg($file_src);
break;
case 3: // PNG
if ((is_numeric($width)) || (is_numeric($height)))
$img_src = imagecreatefrompng($file_src);
break;
default:
return false;
}
if ((!is_numeric($width)) && (!is_numeric($height))) {
// Read the original file
$fd = fopen($file_src, "rb");
$size = filesize($file_src);
$bin_dst = fread($fd, $size);
fclose($fd);
return true;
}
else if (isset($img_src)) {
if ((is_numeric($width))
&& (!is_numeric($height))
&& ($info[0] > $width)) {
// Resize by width only
$new_width = $width;
$new_height = (int)($info[1] * $width / $info[0]);
}
else if ((!is_numeric($width))
&& (is_numeric($height))
&& ($info[1] > $height)) {
// Resize by height only
$new_width = (int)($info[0] * $height / $info[1]);
$new_height = $height;
}
else if ((is_numeric($width))
&& (is_numeric($height))
&& ($info[0] > $width)
&& ($info[1] > $height)) {
// Resize by width and height
$new_width = $width;
$new_height = $height;
}
if ((isset($new_height)) && (isset($new_width))) {
$img_dst = imagecreatetruecolor($new_width, $new_height);
if (imagecopyresampled($img_dst, $img_src, 0, 0, 0, 0,
$new_width, $new_height, $info[0], $info[1])) {
imagedestroy($img_src);
ob_start();
switch($info[2]) {
case 1: // GIF
imagegif($img_dst);
break;
case 2: // JPEG
imagejpeg($img_dst);
break;
case 3: // PNG
imagepng($img_dst);
break;
}
$bin_dst = ob_get_contents();
$size = ob_get_length();
ob_end_clean();
imagedestroy($img_dst);
return true;
}
else
imagedestroy($img_src);
}
else
imagedestroy($img_src);
}
}
return false;
}
/* -------------------------------------------------------------------------- */
function parse_rewritefile($rewrite_file) {
/* ---------------------------------------------------------------------------
* parse file that contains rewrite rules
* !! URL rewrite variable must be on the same order than expression in brackets !!
* For example : we must have something like :
* /index.php?rub=$1&year=$2&month=$3&day=$4
* and not
* /index.php?rub=$4&year=$1&month=$2&day=$3
*
* @param string file path
* @return boolean
* ------------------------------------------------------------------------ */
if (file_exists($rewrite_file)) {
$fd = fopen($rewrite_file, "r");
$content = fread($fd, filesize($rewrite_file));
fclose($fd);
$lines = explode("\n", $content);
unset($content);
foreach ($lines as $line) {
if (($line != "")
&& ($line{0} != '#')) {
$words = split("(\t|\ )+", $line);
if ((count($words) >= 3)
&& ($words[0] == "RewriteRule")) {
/* Rewrite pattern replacement */
//echo $words[1]." <-> ".$words[2]."<br />";
/* Parse URL to rewrite */
$url_from = $words[2];
$url_from = str_replace('?', '\?', $url_from);
$url_from = str_replace('/', '/', $url_from);
$url_from = str_replace('&', '&', $url_from);
$tmp_url_from = "";
$array_n = array();
while(preg_match('/\$[1-9]/U', $url_from, $array)) {
array_push($array_n, $array[0]);
$url_from = preg_replace('/\$[1-9]/U', '(.+)', $url_from, 1);
}
/* Parse URL rewrited */
$url_to = $words[1];
$url_to = str_replace('\', '', $url_to);
$url_to = str_replace('^', '', $url_to);
$url_to = str_replace('$', '', $url_to);
$n = 1;
while(preg_match('/\(.+\)/U', $url_to)) {
$i = array_search('$'.$n, $array_n);
$url_to = preg_replace('/\(.+\)/U', '\$'.($i+1), $url_to, 1);
$n++;
}
//echo "result : ".$url_from." => ".$url_to."<br />";
$this->addRewriteRule($url_from, $url_to);
}
else if ((count($words) == 2)
&& ($words[0] == "RewriteEngine")) {
if (strtolower($words[1]) == "on") {
$this->rewrite_rule_enable = true;
}
}
}
}
return true;
}
return false;
}
function diff($str_from, $str_to) {
/* ---------------------------------------------------------------------------
* diff between 2 strings
*
* @param string
* @param string
* @return string result after procession
* ------------------------------------------------------------------------ */
$array_from = explode("\n", $str_from);
$array_to = explode("\n", $str_to);
$count_from = count($array_from);
$count_to = count($array_to);
for($i = 0; $i < $count_from; $i++) {
$array_from[$i] = preg_replace('/<br />$/', '', str_replace("\r", "", $array_from[$i]));
}
for($i = 0; $i < $count_to; $i++) {
$array_to[$i] = preg_replace('/<br />$/', '', str_replace("\r", "", $array_to[$i]));
}
$i = 0;
$j = 0;
$k = 0;
$nl = "<br />\n";
$result = "";
while (($i < $count_from)
&& ($j < $count_to)) {
/* Line are equals */
if ($array_from[$i] == $array_to[$j]) {
$result .= $array_from[$i].$nl;
$i++;
$j++;
}
else {
/* Line are different */
if ($count_to - $j == $count_from - $i) {
$result .= "<span class=\"".WAKKA_TEXT_ADD_CLASS."\">".$array_to[$j]."</span>".$nl;
$result .= "<span class=\"".WAKKA_TEXT_DEL_CLASS."\">".$array_from[$i]."</span>".$nl;
$j++;
$i++;
}
else if ($count_to - $j > $count_from - $i) {
$result .= "<span class=\"".WAKKA_TEXT_ADD_CLASS."\">".$array_to[$j]."</span>".$nl;
$j++;
}
else {
$result .= "<span class=\"".WAKKA_TEXT_DEL_CLASS."\">".$array_from[$i]."</span>"