浏览代码

Move some methods out of TextLib to clean up.

euromark 13 年之前
父节点
当前提交
cd0f1eec24

+ 323 - 0
Lib/Utility/TextAnalysisLib.php

@@ -0,0 +1,323 @@
+<?php
+App::uses('TextLib', 'Tools.Utility');
+
+/**
+ * TODO: extend the core String class some day?
+ *
+ * 2010-08-31 ms
+ */
+class TextAnalysisLib extends TextLib {
+
+	protected $text, $lenght, $char, $letter, $space, $word, $r_word, $sen, $r_sen, $para,
+		$r_para, $beautified;
+
+	public function __construct($text = null) {
+		$this->text = $text;
+	}
+
+	/**
+	 * @param string $stringToCheck
+	 * @param tolerance (in %: 0 ... 1)
+	 * @return boolean $success
+	 * 2011-10-13 ms
+	 */
+	public function isScreamFont($str = null, $tolerance = 0.4) {
+		if ($str === null) {
+			$str = $this->text;
+		}
+		if (empty($str)) {
+			return false;
+		}
+
+		$res = preg_match_all('/[A-ZÄÖÜ]/u', $str, $uppercase);
+		$uppercase = array_shift($uppercase);
+		//echo returns($uppercase);
+
+		$res = preg_match_all('/[a-zäöüß]/u', $str, $lowercase);
+		$lowercase = array_shift($lowercase);
+		//echo returns($lowercase);
+
+		if (($countUpper = count($uppercase)) && $countUpper >= count($lowercase)) {
+			return true;
+		}
+		//TODO: tolerance
+
+		return false;
+	}
+
+	/**
+	 * @param string
+	 * @param string $additionalChars
+	 * - e.g. `-()0123456789`
+	 */
+	public function isWord($str = null, $additionalChars = null) {
+		return preg_match('/^\w+$/', $str);
+	}
+
+
+/* utf8 generell stuff */
+
+	/**
+	 * Tests whether a string contains only 7-bit ASCII bytes. This is used to
+	 * determine when to use native functions or UTF-8 functions.
+	 *
+	 * $ascii = UTF8::is_ascii($str);
+	 *
+	 * @param string string to check
+	 * @return bool
+	 */
+	public function isAscii($str = null) {
+		if ($str === null) {
+			$str = $this->text;
+		}
+		return !preg_match('/[^\x00-\x7F]/S', $str);
+	}
+
+	/**
+	 * Strips out device control codes in the ASCII range.
+	 *
+	 * $str = UTF8::strip_ascii_ctrl($str);
+	 *
+	 * @param string string to clean
+	 * @return string
+	 */
+	public function stripAsciiCtrl($str = null) {
+		if ($str === null) {
+			$str = $this->text;
+		}
+		return preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S', '', $str);
+	}
+
+	/**
+	 * Strips out all non-7bit ASCII bytes.
+	 *
+	 * $str = UTF8::strip_non_ascii($str);
+	 *
+	 * @param string string to clean
+	 * @return string
+	 */
+	public function stripNonAscii($str = null) {
+		if ($str === null) {
+			$str = $this->text;
+		}
+		return preg_replace('/[^\x00-\x7F]+/S', '', $str);
+	}
+
+
+	public function convertToOrd($str = null, $separator = '-') {
+		/*
+		if (!class_exists('UnicodeLib')) {
+			App::uses('UnicodeLib', 'Tools.Lib');
+		}
+		*/
+		if ($str === null) {
+			$str = $this->text;
+		}
+		$chars = preg_split('//', $str, -1);
+		$res = array();
+		foreach ($chars as $char) {
+			//$res[] = UnicodeLib::ord($char);
+			$res[] = ord($char);
+		}
+		return implode($separator, $res);
+	}
+
+/* text object specific */
+
+	/**
+	 * @return array(char=>amount) for empty char or int amount for specific char
+	 * 2010-08-31 ms
+	 */
+	public function occurrences($char = null, $caseSensitive = false) {
+
+		if ($caseSensitive) {
+			$str = $this->text;
+		} else {
+			if ($char !== null) {
+				$char = strtolower($char);
+			}
+			$str = strtolower($this->text);
+		}
+
+		if ($char === null) {
+			$occ = array();
+			$str = str_split($str);
+			foreach ($str as $value) {
+				if (array_key_exists($value, $occ)) {
+					$occ[$value] += 1;
+				} else {
+					$occ[$value] = 1;
+				}
+			}
+			return $occ;
+
+		} else {
+
+			$occ = 0;
+			$pos = 0;
+			do {
+				$pos = strpos($str, $char, $pos);
+				if ($pos !== false) {
+					$occ++;
+					$pos++;
+				} else {
+					break;
+				}
+			} while (true);
+			return $occ;
+		}
+	}
+
+
+	/**
+	 * @return array(char=>amount) for empty char or int amount for specific char
+	 * 2010-08-31 ms
+	 */
+	public function maxOccurrences($caseSensitive = false) {
+
+		$arr = $this->occurrences(null, $caseSensitive);
+		$max = 0;
+		$occ = array();
+
+		foreach ($arr as $key => $value) {
+			if ($value === $max) {
+				$occ[$key] = $value;
+			} elseif ($value > $max) {
+				$max = $value;
+				$occ = array($key => $value);
+			}
+		}
+		echo returns($occ);
+		return $occ;
+	}
+
+
+	public function getLength() {
+		if (!$this->lenght) {
+			$this->lenght = mb_strlen($this->text);
+		}
+		return $this->lenght;
+	}
+
+	public function getCharacter() {
+		if (!$this->char) $this->char = mb_strlen(strtr($this->text, array("\n" => '', "\r" =>
+				'')));
+		return $this->char;
+	}
+
+	public function getLetter() {
+		if (!$this->letter) {
+			$l_text = mb_strtolower($this->text);
+			for ($i = 0; $i < $this->lenght; $i++)
+				if (mb_strpos("abcdefghijklmnopqrstuvwxyzäöü", $l_text[$i]) != false) $this->
+						letter++;
+		}
+		return $this->letter;
+	}
+
+	public function getSpace() {
+		if (!$this->space) $this->space = mb_substr_count($this->text, " ") +
+				mb_substr_count($this->text, "\t");
+		return $this->space;
+	}
+
+	public function getSymbol() {
+		return $this->getCharacter() - $this->getLetter() - $this->getSpace();
+	}
+
+	//TODO: improve it to work with case insensitivity and utf8 chars like é or î
+	public function getWord($parse = false) {
+		if (!$this->word && !$this->r_word) {
+			@preg_match_all("/[A-Za-zäöüÄÖÜß\-'\\\"]+/", $this->text, $m);
+			$this->word = count($m[0]);
+			$this->r_word = $m[0];
+		}
+		return $parse ? $this->r_word : $this->word;
+	}
+
+	/**
+	 * @param options
+	 * - min_char, max_char, case_sensititive, sort ('asc', 'desc', 'length', 'alpha', false), limit...
+	 * 2010-10-09 ms
+	 */
+	public function wordCount($options = array()) {
+		if (true || !$this->rr_word) {
+			$text = str_replace(array(NL, CR, PHP_EOL, TB), ' ', $this->text);
+			$res = array();
+			$search = array('*', '+', '~', ',', '.', ';', ':', '#', '', '(', ')', '{', '}', '[', ']', '$', '%', '“', '”', '—', '"', '‘', '’', '!', '?', '<', '>', '=', '/');
+			$search = array_merge($search, array(1, 2, 3, 4, 5, 6, 7, 8, 9, 0));
+			$text = str_replace($search, ' ', $text);
+
+			$pieces = explode(' ', $text);
+
+			//TODO: use array_count_values()?
+			foreach ($pieces as $key => $piece) {
+				if (empty($options['case_sensitive'])) {
+					$piece = mb_strtolower($piece);
+				}
+				$piece = trim($piece);
+
+				if (empty($piece) || !empty($options['min_char']) && mb_strlen($piece) < $options['min_char'] || !empty($options['max_char']) && mb_strlen($piece) > $options['max_char']) {
+					unset($pieces[$key]);
+					continue;
+				}
+
+				if (!array_key_exists($piece, $res)) {
+					$res[$piece] = 0;
+				}
+				$res[$piece]++;
+			}
+			if (!empty($options['sort'])) {
+				$sort = strtolower($options['sort']);
+				if ($sort === 'asc') {
+					asort($res);
+				} elseif ($sort === 'desc') {
+					arsort($res);
+				} elseif ($sort === 'length') {
+					//TODO:
+					//uasort($res, $callback);
+
+				} elseif ($sort === 'alpha') {
+					ksort($res);
+				}
+			}
+			if (!empty($options['limit'])) {
+				$res = array_slice($res, 0, (int)$options['limit'], true);
+			}
+
+			//$this->rr_word = $res;
+		}
+		return $res; // $this->rr_word;
+	}
+
+
+	public function getSentence($parse = false) {
+		if (!$this->sen && !$this->r_sen) {
+			@preg_match_all("/[^:|;|\!|\.]+(:|;|\!|\.| )+/", $this->text, $m);
+			$this->sen = count($m[0]);
+			foreach ($m[0] as $s) $this->r_sen[] = strtr(trim($s), array("\n" => '', "\r" =>
+					''));
+		}
+		return $parse ? $this->r_sen : $this->sen;
+	}
+
+	public function getParagraph($parse = false) {
+		if (!$this->para && !$this->r_para) {
+			@preg_match_all("/[^\n]+?(:|;|\!|\.| )+\n/s", strtr($this->text, array("\r" =>
+				'')) . "\n", $m);
+			$this->para = count($m[0]);
+			foreach ($m[0] as $p) $this->r_para[] = trim($p);
+		}
+		return $parse ? $this->r_para : $this->para;
+	}
+
+	public function beautify($wordwrap = false) {
+		if (!$this->beautified) {
+			$this->beautified = @preg_replace(array("/ {1,}/", "/\. {1,}\./", "/\. *(?!\.)/",
+				"/(,|:|;|\!|\)) */", "/(,|:|;|\!|\)|\.) *\r\n/", "/(\r\n) {3,}/"), array(" ", ".",
+				". ", "$1 ", "$1\r\n", "\r\n\r\n"), $this->text);
+		}
+		return $wordwrap ? wordwrap($this->beautified, $wordwrap) : $this->beautified;
+	}
+
+}

+ 14 - 315
Lib/Utility/TextLib.php

@@ -12,98 +12,26 @@ class TextLib extends String {
 		$r_para, $beautified;
 
 
-	public function __construct($text) {
+	public function __construct($text = null) {
 		$this->text = $text;
 	}
 
 	/**
-	 * @param string $stringToCheck
-	 * @param tolerance (in %: 0 ... 1)
-	 * @return boolean $success
-	 * 2011-10-13 ms
-	 */
-	public function isScreamFont($str = null, $tolerance = 0.4) {
-		if ($str === null) {
-			$str = $this->text;
-		}
-		if (empty($str)) {
-			return false;
-		}
-
-		$res = preg_match_all('/[A-ZÄÖÜ]/u', $str, $uppercase);
-		$uppercase = array_shift($uppercase);
-		//echo returns($uppercase);
-
-		$res = preg_match_all('/[a-zäöüß]/u', $str, $lowercase);
-		$lowercase = array_shift($lowercase);
-		//echo returns($lowercase);
-
-		if (($countUpper = count($uppercase)) && $countUpper >= count($lowercase)) {
-			return true;
-		}
-		//TODO: tolerance
-
-		return false;
-	}
-
-	/**
-	 * @param string
-	 * @param string $additionalChars
-	 * - e.g. `-()0123456789`
-	 */
-	public function isWord($str = null, $additionalChars = null) {
-		return preg_match('/^\w+$/', $str);
-	}
-
-
-/* utf8 generell stuff */
-
-	/**
-	 * Tests whether a string contains only 7-bit ASCII bytes. This is used to
-	 * determine when to use native functions or UTF-8 functions.
-	 *
-	 * $ascii = UTF8::is_ascii($str);
-	 *
-	 * @param string string to check
-	 * @return bool
-	 */
-	public function isAscii($str = null) {
-		if ($str === null) {
-			$str = $this->text;
-		}
-		return !preg_match('/[^\x00-\x7F]/S', $str);
-	}
-
-	/**
-	 * Strips out device control codes in the ASCII range.
-	 *
-	 * $str = UTF8::strip_ascii_ctrl($str);
-	 *
-	 * @param string string to clean
-	 * @return string
-	 */
-	public function stripAsciiCtrl($str = null) {
-		if ($str === null) {
-			$str = $this->text;
-		}
-		return preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S', '', $str);
+   * Return an abbreviated string, with characters in the middle of the
+   * excessively long string replaced by $ending.
+   *
+   * @param string $text The original string.
+   * @param integer $length The length at which to abbreviate.
+   * @return string The abbreviated string, if longer than $length.
+   */
+	public static function abbreviate($text, $length = 20, $ending = '...') {
+		return (mb_strlen($text) > $length)
+			? rtrim(mb_substr($text, 0, round(($length - 3) / 2))) . $ending . ltrim(mb_substr($text, (($length - 3) / 2) * -1))
+			: $text;
 	}
 
-	/**
-	 * Strips out all non-7bit ASCII bytes.
-	 *
-	 * $str = UTF8::strip_non_ascii($str);
-	 *
-	 * @param string string to clean
-	 * @return string
-	 */
-	public function stripNonAscii($str = null) {
-		if ($str === null) {
-			$str = $this->text;
-		}
-		return preg_replace('/[^\x00-\x7F]+/S', '', $str);
-	}
 
+/* other */
 
 	public function convertToOrd($str = null, $separator = '-') {
 		/*
@@ -147,9 +75,6 @@ class TextLib extends String {
 		return $res;
 	}
 
-
-/* other */
-
 	/**
 	 * Explode a string of given tags into an array.
 	 */
@@ -193,7 +118,7 @@ class TextLib extends String {
 
 
 
-		/**
+	/**
 	 * Prevents [widow words](http://www.shauninman.com/archive/2006/08/22/widont_wordpress_plugin)
 	 * by inserting a non-breaking space between the last two words.
 	 *
@@ -220,117 +145,6 @@ class TextLib extends String {
 /* text object specific */
 
 	/**
-	 * @return array(char=>amount) for empty char or int amount for specific char
-	 * 2010-08-31 ms
-	 */
-	public function occurrences($char = null, $caseSensitive = false) {
-
-		if ($caseSensitive) {
-			$str = $this->text;
-		} else {
-			if ($char !== null) {
-				$char = strtolower($char);
-			}
-			$str = strtolower($this->text);
-		}
-
-		if ($char === null) {
-			$occ = array();
-			$str = str_split($str);
-			foreach ($str as $value) {
-				if (array_key_exists($value, $occ)) {
-					$occ[$value] += 1;
-				} else {
-					$occ[$value] = 1;
-				}
-			}
-			return $occ;
-
-		} else {
-
-			$occ = 0;
-			$pos = 0;
-			do {
-				$pos = strpos($str, $char, $pos);
-				if ($pos !== false) {
-					$occ++;
-					$pos++;
-				} else {
-					break;
-				}
-			} while (true);
-			return $occ;
-		}
-	}
-
-
-	/**
-	 * @return array(char=>amount) for empty char or int amount for specific char
-	 * 2010-08-31 ms
-	 */
-	public function maxOccurrences($caseSensitive = false) {
-
-		$arr = $this->occurrences(null, $caseSensitive);
-		$max = 0;
-		$occ = array();
-
-		foreach ($arr as $key => $value) {
-			if ($value === $max) {
-				$occ[$key] = $value;
-			} elseif ($value > $max) {
-				$max = $value;
-				$occ = array($key => $value);
-			}
-		}
-		echo returns($occ);
-		return $occ;
-	}
-
-
-	public function getLength() {
-		if (!$this->lenght) {
-			$this->lenght = mb_strlen($this->text);
-		}
-		return $this->lenght;
-	}
-
-	public function getCharacter() {
-		if (!$this->char) $this->char = mb_strlen(strtr($this->text, array("\n" => '', "\r" =>
-				'')));
-		return $this->char;
-	}
-
-	public function getLetter() {
-		if (!$this->letter) {
-			$l_text = mb_strtolower($this->text);
-			for ($i = 0; $i < $this->lenght; $i++)
-				if (mb_strpos("abcdefghijklmnopqrstuvwxyzäöü", $l_text[$i]) != false) $this->
-						letter++;
-		}
-		return $this->letter;
-	}
-
-	public function getSpace() {
-		if (!$this->space) $this->space = mb_substr_count($this->text, " ") +
-				mb_substr_count($this->text, "\t");
-		return $this->space;
-	}
-
-	public function getSymbol() {
-		return $this->getCharacter() - $this->getLetter() - $this->getSpace();
-	}
-
-	//TODO: improve it to work with case insensitivity and utf8 chars like é or î
-	public function getWord($parse = false) {
-		if (!$this->word && !$this->r_word) {
-			@preg_match_all("/[A-Za-zäöüÄÖÜß\-'\\\"]+/", $this->text, $m);
-			$this->word = count($m[0]);
-			$this->r_word = $m[0];
-		}
-		return $parse ? $this->r_word : $this->word;
-	}
-
-	/**
 	 * @param options
 	 * - min_char, max_char, case_sensititive, ...
 	 * 2010-10-09 ms
@@ -404,92 +218,6 @@ class TextLib extends String {
 	}
 
 	/**
-	 * @param options
-	 * - min_char, max_char, case_sensititive, sort ('asc', 'desc', 'length', 'alpha', false), limit...
-	 * 2010-10-09 ms
-	 */
-	public function wordCount($options = array()) {
-		if (true || !$this->rr_word) {
-			$text = str_replace(array(NL, CR, PHP_EOL, TB), ' ', $this->text);
-			$res = array();
-			$search = array('*', '+', '~', ',', '.', ';', ':', '#', '', '(', ')', '{', '}', '[', ']', '$', '%', '“', '”', '—', '"', '‘', '’', '!', '?', '<', '>', '=', '/');
-			$search = array_merge($search, array(1, 2, 3, 4, 5, 6, 7, 8, 9, 0));
-			$text = str_replace($search, ' ', $text);
-
-			$pieces = explode(' ', $text);
-
-			//TODO: use array_count_values()?
-			foreach ($pieces as $key => $piece) {
-				if (empty($options['case_sensitive'])) {
-					$piece = mb_strtolower($piece);
-				}
-				$piece = trim($piece);
-
-				if (empty($piece) || !empty($options['min_char']) && mb_strlen($piece) < $options['min_char'] || !empty($options['max_char']) && mb_strlen($piece) > $options['max_char']) {
-					unset($pieces[$key]);
-					continue;
-				}
-
-				if (!array_key_exists($piece, $res)) {
-					$res[$piece] = 0;
-				}
-				$res[$piece]++;
-			}
-			if (!empty($options['sort'])) {
-				$sort = strtolower($options['sort']);
-				if ($sort === 'asc') {
-					asort($res);
-				} elseif ($sort === 'desc') {
-					arsort($res);
-				} elseif ($sort === 'length') {
-					//TODO:
-					//uasort($res, $callback);
-
-				} elseif ($sort === 'alpha') {
-					ksort($res);
-				}
-			}
-			if (!empty($options['limit'])) {
-				$res = array_slice($res, 0, (int)$options['limit'], true);
-			}
-
-			//$this->rr_word = $res;
-		}
-		return $res; // $this->rr_word;
-	}
-
-
-	public function getSentence($parse = false) {
-		if (!$this->sen && !$this->r_sen) {
-			@preg_match_all("/[^:|;|\!|\.]+(:|;|\!|\.| )+/", $this->text, $m);
-			$this->sen = count($m[0]);
-			foreach ($m[0] as $s) $this->r_sen[] = strtr(trim($s), array("\n" => '', "\r" =>
-					''));
-		}
-		return $parse ? $this->r_sen : $this->sen;
-	}
-
-	public function getParagraph($parse = false) {
-		if (!$this->para && !$this->r_para) {
-			@preg_match_all("/[^\n]+?(:|;|\!|\.| )+\n/s", strtr($this->text, array("\r" =>
-				'')) . "\n", $m);
-			$this->para = count($m[0]);
-			foreach ($m[0] as $p) $this->r_para[] = trim($p);
-		}
-		return $parse ? $this->r_para : $this->para;
-	}
-
-	public function beautify($wordwrap = false) {
-		if (!$this->beautified) {
-			$this->beautified = @preg_replace(array("/ {1,}/", "/\. {1,}\./", "/\. *(?!\.)/",
-				"/(,|:|;|\!|\)) */", "/(,|:|;|\!|\)|\.) *\r\n/", "/(\r\n) {3,}/"), array(" ", ".",
-				". ", "$1 ", "$1\r\n", "\r\n\r\n"), $this->text);
-		}
-		return $wordwrap ? wordwrap($this->beautified, $wordwrap) : $this->beautified;
-	}
-
-
-	/**
 	 * High ASCII to Entities
 	 *
 	 * Converts High ascii text and MS Word special characters to character entities
@@ -631,32 +359,3 @@ class TextLib extends String {
 	}
 
 }
-
-
-/*
-
-//explode string, return word and number of repeation
-$r = explode('[spilit]', $value);
-
-//regex
-if ( preg_match('/([a-z]+)/', $r[0])) {
-
-preg_match_all( '/'. $r[0] .'/', $this -> checkString[$arrays], $match);
-} else {
-
-preg_match_all( '/\\'. $r[0] .'/', $this -> checkString[$arrays], $match);
-}
-
-//count chars
-if ( count($match[0]) <= $r[1]) {
-
-$this -> _is_valid[$arrays][$valData] = true;
-} else {
-
-$this -> _is_valid[$arrays][$valData] = false;
-
-//set errors array
-$this -> error[$arrays][] = $r[0] . $this -> error_max_time_char;
-}
-
-*/

+ 56 - 53
Model/Behavior/LogableBehavior.php

@@ -76,6 +76,7 @@ class LogableBehavior extends ModelBehavior {
 		'enabled' => true,
 		'on' => 'save', // validate/save
 		'userModel' => CLASS_USER,
+		'logModel' => 'Tools.Log',
 		'userKey' => 'user_id',
 		'change' => 'list',
 		'descriptionIds' => true,
@@ -105,8 +106,9 @@ class LogableBehavior extends ModelBehavior {
 		$this->settings[$Model->alias] = array_merge($this->_defaults, $config);
 		$this->settings[$Model->alias]['ignore'][] = $Model->primaryKey;
 
-		$this->Log = ClassRegistry::init('Tools.Log');
-		if ($this->settings[$Model->alias]['userModel'] != $Model->alias) {
+		$this->Log = ClassRegistry::init($this->settings[$Model->alias]['logModel']);
+
+		if ($this->settings[$Model->alias]['userModel'] !== $Model->alias) {
 			$this->UserModel = ClassRegistry::init($this->settings[$Model->alias]['userModel']);
 		} else {
 			$this->UserModel = $Model;
@@ -231,38 +233,38 @@ class LogableBehavior extends ModelBehavior {
 		}
 		$result = array();
 		foreach ($data as $key => $row) {
-			$one = $row['Log'];
-			$result[$key]['Log']['id'] = $one['id'];
-			$result[$key]['Log']['event'] = $username;
+			$one = $row[$this->Log->alias];
+			$result[$key][$this->Log->alias]['id'] = $one['id'];
+			$result[$key][$this->Log->alias]['event'] = $username;
 			// have all the detail models and change as list :
 			if (isset($one[$this->settings[$Model->alias]['classField']]) && isset($one['action']) && isset($one['change']) && isset($one[$this->
 				settings[$Model->alias]['foreignKey']])) {
 				if ($one['action'] === 'edit') {
-					$result[$key]['Log']['event'] .= ' edited ' . $one['change'] . ' of ' . strtolower($one[$this->settings[$Model->alias]['classField']]) .
+					$result[$key][$this->Log->alias]['event'] .= ' edited ' . $one['change'] . ' of ' . strtolower($one[$this->settings[$Model->alias]['classField']]) .
 						'(id ' . $one[$this->settings[$Model->alias]['foreignKey']] . ')';
 					//	' at '.$one['created'];
 				} elseif ($one['action'] === 'add') {
-					$result[$key]['Log']['event'] .= ' added a ' . strtolower($one[$this->settings[$Model->alias]['classField']]) . '(id ' . $one[$this->
+					$result[$key][$this->Log->alias]['event'] .= ' added a ' . strtolower($one[$this->settings[$Model->alias]['classField']]) . '(id ' . $one[$this->
 						settings[$Model->alias]['foreignKey']] . ')';
 				} elseif ($one['action'] === 'delete') {
-					$result[$key]['Log']['event'] .= ' deleted the ' . strtolower($one[$this->settings[$Model->alias]['classField']]) . '(id ' . $one[$this->
+					$result[$key][$this->Log->alias]['event'] .= ' deleted the ' . strtolower($one[$this->settings[$Model->alias]['classField']]) . '(id ' . $one[$this->
 						settings[$Model->alias]['foreignKey']] . ')';
 				}
 
 			} elseif (isset($one[$this->settings[$Model->alias]['classField']]) && isset($one['action']) && isset($one[$this->settings[$Model->alias]['foreignKey']])) { // have model,foreign_id and action
 				if ($one['action'] === 'edit') {
-					$result[$key]['Log']['event'] .= ' edited ' . strtolower($one[$this->settings[$Model->alias]['classField']]) . '(id ' . $one[$this->
+					$result[$key][$this->Log->alias]['event'] .= ' edited ' . strtolower($one[$this->settings[$Model->alias]['classField']]) . '(id ' . $one[$this->
 						settings[$Model->alias]['foreignKey']] . ')';
 					//	' at '.$one['created'];
 				} elseif ($one['action'] === 'add') {
-					$result[$key]['Log']['event'] .= ' added a ' . strtolower($one[$this->settings[$Model->alias]['classField']]) . '(id ' . $one[$this->
+					$result[$key][$this->Log->alias]['event'] .= ' added a ' . strtolower($one[$this->settings[$Model->alias]['classField']]) . '(id ' . $one[$this->
 						settings[$Model->alias]['foreignKey']] . ')';
 				} elseif ($one['action'] === 'delete') {
-					$result[$key]['Log']['event'] .= ' deleted the ' . strtolower($one[$this->settings[$Model->alias]['classField']]) . '(id ' . $one[$this->
+					$result[$key][$this->Log->alias]['event'] .= ' deleted the ' . strtolower($one[$this->settings[$Model->alias]['classField']]) . '(id ' . $one[$this->
 						settings[$Model->alias]['foreignKey']] . ')';
 				}
 			} else { // only description field exist
-				$result[$key]['Log']['event'] = $one['description'];
+				$result[$key][$this->Log->alias]['event'] = $one['description'];
 			}
 
 		}
@@ -305,21 +307,21 @@ class LogableBehavior extends ModelBehavior {
 	 * @param array $values optional other values for your logs table
 	 */
 	public function customLog(Model $Model, $action, $id = null, $values = array()) {
-		$logData['Log'] = $values;
+		$logData[$this->Log->alias] = $values;
 		/**
 		@todo clean up $logData */
 		if ($id === null) {
 			$id = $Model->id;
 		}
 		if ($this->Log->hasField($this->settings[$Model->alias]['foreignKey']) && is_numeric($id)) {
-			$logData['Log'][$this->settings[$Model->alias]['foreignKey']] = $id;
+			$logData[$this->Log->alias][$this->settings[$Model->alias]['foreignKey']] = $id;
 		}
 		$title = null;
 		if (isset($values['title'])) {
 			$title = $values['title'];
-			unset($logData['Log']['title']);
+			unset($logData[$this->Log->alias]['title']);
 		}
-		$logData['Log']['action'] = $action;
+		$logData[$this->Log->alias]['action'] = $action;
 		$this->_saveLog($Model, $logData, $title);
 	}
 
@@ -357,16 +359,16 @@ class LogableBehavior extends ModelBehavior {
 		}
 		$logData = array();
 		if ($this->Log->hasField('description')) {
-			$logData['Log']['description'] = $Model->alias;
+			$logData[$this->Log->alias]['description'] = $Model->alias;
 			if (isset($Model->data[$Model->alias][$Model->displayField]) && $Model->displayField != $Model->primaryKey) {
-				$logData['Log']['description'] .= ' "' . $Model->data[$Model->alias][$Model->displayField] . '"';
+				$logData[$this->Log->alias]['description'] .= ' "' . $Model->data[$Model->alias][$Model->displayField] . '"';
 			}
 			if ($this->settings[$Model->alias]['descriptionIds']) {
-				$logData['Log']['description'] .= ' (' . $Model->id . ') ';
+				$logData[$this->Log->alias]['description'] .= ' (' . $Model->id . ') ';
 			}
-			$logData['Log']['description'] .= __('deleted');
+			$logData[$this->Log->alias]['description'] .= __('deleted');
 		}
-		$logData['Log']['action'] = 'delete';
+		$logData[$this->Log->alias]['action'] = 'delete';
 		$this->_saveLog($Model, $logData);
 	}
 
@@ -391,7 +393,8 @@ class LogableBehavior extends ModelBehavior {
 			$this->setUserData($Model);
 		}
 		if ($Model->id && empty($this->old)) {
-			$this->old = $Model->find('first', array('conditions' => array($Model->primaryKey => $Model->id), 'recursive' => -1));
+			$options = array('conditions' => array($Model->primaryKey => $Model->id), 'recursive' => -1);
+			$this->old = $Model->find('first', $options);
 		}
 	}
 
@@ -415,33 +418,33 @@ class LogableBehavior extends ModelBehavior {
 			$id = $Model->insertId;
 		}
 		if ($this->Log->hasField($this->settings[$Model->alias]['foreignKey'])) {
-			$logData['Log'][$this->settings[$Model->alias]['foreignKey']] = $id;
+			$logData[$this->Log->alias][$this->settings[$Model->alias]['foreignKey']] = $id;
 		}
 		if ($this->Log->hasField('description')) {
-			$logData['Log']['description'] = $Model->alias . ' ';
+			$logData[$this->Log->alias]['description'] = $Model->alias . ' ';
 			if (isset($Model->data[$Model->alias][$Model->displayField]) && $Model->displayField != $Model->primaryKey) {
-				$logData['Log']['description'] .= '"' . $Model->data[$Model->alias][$Model->displayField] . '" ';
+				$logData[$this->Log->alias]['description'] .= '"' . $Model->data[$Model->alias][$Model->displayField] . '" ';
 			}
 
 			if ($this->settings[$Model->alias]['descriptionIds']) {
-				$logData['Log']['description'] .= '(' . $id . ') ';
+				$logData[$this->Log->alias]['description'] .= '(' . $id . ') ';
 			}
 
 			if ($created) {
-				$logData['Log']['description'] .= __('added');
+				$logData[$this->Log->alias]['description'] .= __('added');
 			} else {
-				$logData['Log']['description'] .= __('updated');
+				$logData[$this->Log->alias]['description'] .= __('updated');
 			}
 		}
 		if ($this->Log->hasField('action')) {
 			if ($created) {
-				$logData['Log']['action'] = 'add';
+				$logData[$this->Log->alias]['action'] = 'add';
 			} else {
-				$logData['Log']['action'] = 'edit';
+				$logData[$this->Log->alias]['action'] = 'edit';
 			}
 		}
 		if ($this->Log->hasField('change')) {
-			$logData['Log']['change'] = '';
+			$logData[$this->Log->alias]['change'] = '';
 			$db_fields = array_keys($Model->schema());
 			$changed_fields = array();
 			foreach ($Model->data[$Model->alias] as $key => $value) {
@@ -465,11 +468,11 @@ class LogableBehavior extends ModelBehavior {
 				return true;
 			}
 			if ($this->settings[$Model->alias]['change'] === 'serialize') {
-				$logData['Log']['change'] = serialize($changed_fields);
+				$logData[$this->Log->alias]['change'] = serialize($changed_fields);
 			} else {
-				$logData['Log']['change'] = implode(', ', $changed_fields);
+				$logData[$this->Log->alias]['change'] = implode(', ', $changed_fields);
 			}
-			$logData['Log']['changes'] = $changes;
+			$logData[$this->Log->alias]['changes'] = $changes;
 		}
 
 		if (empty($logData)) {
@@ -492,65 +495,65 @@ class LogableBehavior extends ModelBehavior {
 	 */
 	public function _saveLog(Model $Model, $logData, $title = null) {
 		if ($title !== null) {
-			$logData['Log']['title'] = $title;
+			$logData[$this->Log->alias]['title'] = $title;
 		} elseif ($Model->displayField == $Model->primaryKey) {
-			$logData['Log']['title'] = $Model->alias . ' (' . $Model->id . ')';
+			$logData[$this->Log->alias]['title'] = $Model->alias . ' (' . $Model->id . ')';
 		} elseif (isset($Model->data[$Model->alias][$Model->displayField])) {
-			$logData['Log']['title'] = $Model->data[$Model->alias][$Model->displayField];
+			$logData[$this->Log->alias]['title'] = $Model->data[$Model->alias][$Model->displayField];
 		} else {
 			$Model->recursive = -1;
 			$Model->read(array($Model->displayField));
-			$logData['Log']['title'] = $Model->data[$Model->alias][$Model->displayField];
+			$logData[$this->Log->alias]['title'] = $Model->data[$Model->alias][$Model->displayField];
 		}
 
 		if ($this->Log->hasField($this->settings[$Model->alias]['classField'])) {
 			// by miha nahtigal
-			$logData['Log'][$this->settings[$Model->alias]['classField']] = $Model->name;
+			$logData[$this->Log->alias][$this->settings[$Model->alias]['classField']] = $Model->name;
 		}
 
-		if ($this->Log->hasField($this->settings[$Model->alias]['foreignKey']) && !isset($logData['Log'][$this->settings[$Model->alias]['foreignKey']])) {
+		if ($this->Log->hasField($this->settings[$Model->alias]['foreignKey']) && !isset($logData[$this->Log->alias][$this->settings[$Model->alias]['foreignKey']])) {
 			if ($Model->id) {
-				$logData['Log'][$this->settings[$Model->alias]['foreignKey']] = $Model->id;
+				$logData[$this->Log->alias][$this->settings[$Model->alias]['foreignKey']] = $Model->id;
 			} elseif ($Model->insertId) {
-				$logData['Log'][$this->settings[$Model->alias]['foreignKey']] = $Model->insertId;
+				$logData[$this->Log->alias][$this->settings[$Model->alias]['foreignKey']] = $Model->insertId;
 			}
 		}
 
 		if (!$this->Log->hasField('action')) {
-			unset($logData['Log']['action']);
+			unset($logData[$this->Log->alias]['action']);
 		} elseif (isset($Model->logableAction) && !empty($Model->logableAction)) {
-			$logData['Log']['action'] = implode(',', $Model->logableAction); // . ' ' . $logData['Log']['action'];
+			$logData[$this->Log->alias]['action'] = implode(',', $Model->logableAction); // . ' ' . $logData[$this->Log->alias]['action'];
 			unset($Model->logableAction);
 		}
 
 		if ($this->Log->hasField('version_id') && isset($Model->version_id)) {
-			$logData['Log']['version_id'] = $Model->version_id;
+			$logData[$this->Log->alias]['version_id'] = $Model->version_id;
 			unset($Model->version_id);
 		}
 
 		if ($this->Log->hasField('ip') && $this->userIP) {
-			$logData['Log']['ip'] = $this->userIP;
+			$logData[$this->Log->alias]['ip'] = $this->userIP;
 		}
 
 		if ($this->Log->hasField($this->settings[$Model->alias]['userKey']) && $this->user && isset($this->user[$this->UserModel->alias])) {
-			$logData['Log'][$this->settings[$Model->alias]['userKey']] = $this->user[$this->UserModel->alias][$this->UserModel->primaryKey];
+			$logData[$this->Log->alias][$this->settings[$Model->alias]['userKey']] = $this->user[$this->UserModel->alias][$this->UserModel->primaryKey];
 		}
 
 		if ($this->Log->hasField('description')) {
-			if (empty($logData['Log']['description'])) {
-				$logData['Log']['description'] = __('Custom action');
+			if (empty($logData[$this->Log->alias]['description'])) {
+				$logData[$this->Log->alias]['description'] = __('Custom action');
 			}
 			if ($this->user && $this->UserModel && isset($this->user[$this->UserModel->alias])) {
-				$logData['Log']['description'] .= ' ' . __('by') . ' ' . $this->settings[$Model->alias]['userModel'] . ' "' . $this->user[$this->UserModel->alias][$this->UserModel->displayField] . '"';
+				$logData[$this->Log->alias]['description'] .= ' ' . __('by') . ' ' . $this->settings[$Model->alias]['userModel'] . ' "' . $this->user[$this->UserModel->alias][$this->UserModel->displayField] . '"';
 				if ($this->settings[$Model->alias]['descriptionIds']) {
-					$logData['Log']['description'] .= ' (' . $this->user[$this->UserModel->alias][$this->UserModel->primaryKey] . ')';
+					$logData[$this->Log->alias]['description'] .= ' (' . $this->user[$this->UserModel->alias][$this->UserModel->primaryKey] . ')';
 				}
 
 			} else {
 				// UserModel is active, but the data hasnt been set. Assume system action.
-				$logData['Log']['description'] .= __(' by System');
+				$logData[$this->Log->alias]['description'] .= __(' by System');
 			}
-			$logData['Log']['description'] .= '.';
+			$logData[$this->Log->alias]['description'] .= '.';
 		}
 		$this->Log->create($logData);
 		$this->Log->save(null, false);

+ 4 - 0
Model/Behavior/SluggedBehavior.php

@@ -314,6 +314,10 @@ class SluggedBehavior extends ModelBehavior {
 			ob_start();
 			if (!App::import('Vendor', 'stop_words_' . $lang, array('file' => "stop_words".DS."$lang.txt"))) {
 				$res = App::import('Vendor', 'Tools.stop_words_' . $lang, array('file' => "stop_words".DS."$lang.txt"));
+				if (!$res) {
+					ob_get_clean();
+					return $string;
+				}
 			}
 			$stopWords = preg_replace('@/\*.*\*/@', '', ob_get_clean());
 			$this->stopWords[$lang] = array_filter(array_map('trim', explode("\n", $stopWords)));

+ 11 - 0
Model/Log.php

@@ -22,4 +22,15 @@ class Log extends ToolsAppModel {
 		),
 	);
 
+	/**
+	 * not really necessary probably
+	 */
+	public function find($type = null, $query = array()) {
+		if ($type === 'last') {
+			$options = array_merge(array('order'=>array($this->alias.'.id'=>'DESC')), $query);
+			return parent::find('first', $options);
+		}
+		return parent::find($type, $query);
+	}
+
 }

+ 125 - 0
Test/Case/Lib/Utility/TextAnalysisLibTest.php

@@ -0,0 +1,125 @@
+<?php
+App::uses('TextAnalysisLib', 'Tools.Utility');
+
+/**
+ * 2010-07-14 ms
+ */
+class TextAnalysisLibTest extends CakeTestCase {
+
+	public $TextAnalysis;
+
+	public function setUp() {
+		parent::setUp();
+
+		$this->TextAnalysis = new TextAnalysisLib();
+	}
+
+	public function testIsScreamFont() {
+		$strings = array(
+			'Some Äext' => false,
+			'SOME ÄEXT' => true,
+			'ST' => true,
+			'SOme TExt' => true,
+			'SOme Text' => false,
+		);
+
+		foreach ($strings as $string => $expected) {
+			$this->TextAnalysis = new TextAnalysisLib($string);
+			$is = $this->TextAnalysis->isScreamFont();
+			//pr($is);
+			$this->assertSame($expected, $is);
+		}
+	}
+
+	public function testWordCount() {
+		$this->TextAnalysis = new TextAnalysisLib('Hochhaus, Unter dem Bau von ae Äußeren Einflüssen - und von Autos.');
+		$is = $this->TextAnalysis->wordCount(array('min_char'=>3));
+		//pr($is);
+		$this->assertTrue(!empty($is) && is_array($is) && count($is) === 9);
+
+
+		$this->TextAnalysis = new TextAnalysisLib('Hochhaus, Unter dem Bau von ae Äußeren Einflüssen - und von Autos.');
+		$is = $this->TextAnalysis->wordCount(array('min_char'=>3, 'sort'=>'DESC', 'limit'=>5));
+		//pr($is);
+		$this->assertTrue(!empty($is) && is_array($is) && count($is) === 5);
+
+	}
+
+/** Start **/
+
+	public function testOccurances() {
+		$this->TextAnalysis = new TextAnalysisLib('Hochhaus');
+		$is = $this->TextAnalysis->occurrences();
+		//pr($is);
+		$this->assertTrue(!empty($is) && is_array($is) && count($is) === 6);
+
+		$is = $this->TextAnalysis->occurrences(null, true);
+		//pr($is);
+		$this->assertTrue(!empty($is) && is_array($is) && count($is) === 7);
+
+		$is = $this->TextAnalysis->occurrences('h');
+		//pr($is);
+		$expected = 3;
+		$this->assertEquals($is, $expected);
+
+		$is = $this->TextAnalysis->occurrences('h', true);
+		//pr($is);
+		$expected = 2;
+		$this->assertEquals($is, $expected);
+	}
+
+	public function testMaxOccurances() {
+		$is = $this->TextAnalysis->maxOccurrences();
+		//pr($is);
+		$this->assertTrue(!empty($is) && is_array($is) && count($is) === 1);
+
+		$this->TextAnalysis = new TextAnalysisLib('Radfahren');
+		$is = $this->TextAnalysis->maxOccurrences();
+		//pr($is);
+		$this->assertTrue(!empty($is) && is_array($is) && count($is) === 2);
+
+	}
+
+	//TODO: rest of the test functions
+
+
+/*
+//give it the text
+$text = new TextParse(
+"PHP:Hypertext Preprocessor is a widely used, general-purpose scripting language that was originally designed for web development to produce dynamic web pages... .. .. For this purpose,PHP code is embedded into the HTML source document and interpreted by a web server with a PHP processor module, which generates the web page document.
+
+
+
+
+As a general-purpose programming language, PHP code(PHP CODE)is processed by an interpreter application in command-line mode performing desired operating system operations and producing program output on its standard output channel.It may also function as a graphical application...... PHP is available as a processor for most modern web servers and as standalone interpreter on most operating systems and computing platforms."
+);
+
+echo "Lenght:".		$text->getLenght()		."\n";	//the Lenght
+
+echo "Character:".	$text->getCharacter()	."\n";	//Character count
+
+echo "Letter:".		$text->getLetter()		."\n";	//Letter count
+
+echo "Space:".		$text->getSpace()		."\n";	//Space count
+
+echo "Symbol:".		$text->getSymbol()		."\n";	//Symbol count(non letter / space / \n / \r)
+
+echo "Word:".		$text->getWord()		."\n";	//Word count
+echo "The Words:";
+print_r($text->getWord(1));	//the Words
+echo "\n";
+
+echo "Sentence:".		$text->getSentence()		."\n";	//Sentence count
+echo "The Sentences:";
+print_r($text->getSentence(1));	//the Sentences
+echo "\n";
+
+echo "Paragraph:".		$text->getParagraph()		."\n";	//Paragraph count
+echo "The Paragraphs:";
+print_r($text->getParagraph(1));	//the Paragraphs
+echo "\n";
+
+echo "Beautified Text:\n".	$text->beautify(80);	//beautify the text, wordwrap=80
+*/
+
+}

+ 4 - 109
Test/Case/Lib/Utility/TextLibTest.php

@@ -6,28 +6,14 @@ App::uses('TextLib', 'Tools.Utility');
  */
 class TextLibTest extends CakeTestCase {
 
-	public function setUp() {
-		$this->TextLib = new TextLib(null);
-	}
+	public $TextLib;
 
-	public function testScreamFont() {
-		$strings = array(
-			'Some Äext' => false,
-			'SOME ÄEXT' => true,
-			'ST' => true,
-			'SOme TExt' => true,
-			'SOme Text' => false,
-		);
+	public function setUp() {
+		parent::setUp();
 
-		foreach ($strings as $string => $expected) {
-			$this->TextLib = new TextLib($string);
-			$is = $this->TextLib->isScreamFont();
-			//pr($is);
-			$this->assertSame($expected, $is);
-		}
+		$this->TextLib = new TextLib();
 	}
 
-
 	public function testConvertToOrd() {
 		$this->TextLib = new TextLib('h H');
 		$is = $this->TextLib->convertToOrd();
@@ -57,95 +43,4 @@ class TextLibTest extends CakeTestCase {
 
 	}
 
-	public function testWordCount() {
-		$this->TextLib = new TextLib('Hochhaus, Unter dem Bau von ae Äußeren Einflüssen - und von Autos.');
-		$is = $this->TextLib->wordCount(array('min_char'=>3));
-		//pr($is);
-		$this->assertTrue(!empty($is) && is_array($is) && count($is) === 9);
-
-
-		$this->TextLib = new TextLib('Hochhaus, Unter dem Bau von ae Äußeren Einflüssen - und von Autos.');
-		$is = $this->TextLib->wordCount(array('min_char'=>3, 'sort'=>'DESC', 'limit'=>5));
-		//pr($is);
-		$this->assertTrue(!empty($is) && is_array($is) && count($is) === 5);
-
-	}
-
-/** Start **/
-
-	public function testOccurances() {
-		$this->TextLib = new TextLib('Hochhaus');
-		$is = $this->TextLib->occurrences();
-		//pr($is);
-		$this->assertTrue(!empty($is) && is_array($is) && count($is) === 6);
-
-		$is = $this->TextLib->occurrences(null, true);
-		//pr($is);
-		$this->assertTrue(!empty($is) && is_array($is) && count($is) === 7);
-
-		$is = $this->TextLib->occurrences('h');
-		//pr($is);
-		$expected = 3;
-		$this->assertEquals($is, $expected);
-
-		$is = $this->TextLib->occurrences('h', true);
-		//pr($is);
-		$expected = 2;
-		$this->assertEquals($is, $expected);
-	}
-
-	public function testMaxOccurances() {
-		$is = $this->TextLib->maxOccurrences();
-		//pr($is);
-		$this->assertTrue(!empty($is) && is_array($is) && count($is) === 1);
-
-		$this->TextLib = new TextLib('Radfahren');
-		$is = $this->TextLib->maxOccurrences();
-		//pr($is);
-		$this->assertTrue(!empty($is) && is_array($is) && count($is) === 2);
-
-	}
-
-	//TODO: rest of the test functions
-
-
-/*
-//give it the text
-$text = new TextParse(
-"PHP:Hypertext Preprocessor is a widely used, general-purpose scripting language that was originally designed for web development to produce dynamic web pages... .. .. For this purpose,PHP code is embedded into the HTML source document and interpreted by a web server with a PHP processor module, which generates the web page document.
-
-
-
-
-As a general-purpose programming language, PHP code(PHP CODE)is processed by an interpreter application in command-line mode performing desired operating system operations and producing program output on its standard output channel.It may also function as a graphical application...... PHP is available as a processor for most modern web servers and as standalone interpreter on most operating systems and computing platforms."
-);
-
-echo "Lenght:".		$text->getLenght()		."\n";	//the Lenght
-
-echo "Character:".	$text->getCharacter()	."\n";	//Character count
-
-echo "Letter:".		$text->getLetter()		."\n";	//Letter count
-
-echo "Space:".		$text->getSpace()		."\n";	//Space count
-
-echo "Symbol:".		$text->getSymbol()		."\n";	//Symbol count(non letter / space / \n / \r)
-
-echo "Word:".		$text->getWord()		."\n";	//Word count
-echo "The Words:";
-print_r($text->getWord(1));	//the Words
-echo "\n";
-
-echo "Sentence:".		$text->getSentence()		."\n";	//Sentence count
-echo "The Sentences:";
-print_r($text->getSentence(1));	//the Sentences
-echo "\n";
-
-echo "Paragraph:".		$text->getParagraph()		."\n";	//Paragraph count
-echo "The Paragraphs:";
-print_r($text->getParagraph(1));	//the Paragraphs
-echo "\n";
-
-echo "Beautified Text:\n".	$text->beautify(80);	//beautify the text, wordwrap=80
-*/
-
 }

+ 0 - 1
Test/Fixture/LogFixture.php

@@ -1,5 +1,4 @@
 <?php
-/* Log Fixture generated on: 2011-11-20 21:59:10 : 1321822750 */
 
 /**
  * LogFixture

+ 24 - 7
TestSuite/MyCakeTestCase.php

@@ -67,28 +67,45 @@ abstract class MyCakeTestCase extends CakeTestCase {
 
 /*** Helper Functions **/
 
-
 	/**
 	 * outputs debug information during a web tester (browser) test case
 	 * since PHPUnit>=3.6 swallowes all output by default
 	 * this is a convenience output handler since debug() or pr() have no effect
 	 * @param mixed $data
-	 * @param bool $pre should a pre tag be enclosed around the output
+	 * @param bool $force Should the output be flushed (forced)
 	 * @return void
 	 * 2011-12-04 ms
 	 */
-	public static function out($data, $pre = true) {
+	public static function debug($data, $force = false) {
 		if (php_sapi_name() === 'cli') {
 			return;
 		}
+		debug($data, null, false);
+		if (!$force) {
+			return;
+		}
+		ob_flush();
+	}
 
-		if ($pre) {
+	/**
+	 * outputs debug information during a web tester (browser) test case
+	 * since PHPUnit>=3.6 swallowes all output by default
+	 * this is a convenience output handler
+	 * @param mixed $data
+	 * @param bool $force Should the output be flushed (forced)
+	 * @return void
+	 * 2011-12-04 ms
+	 */
+	public static function out($data, $plain = false, $force = false) {
+		if (php_sapi_name() === 'cli') {
+			return;
+		}
+		if (!$plain|| is_array($data)) {
 			pr($data);
 		} else {
-			echo $data;
+			echo '<div>' . $data . '</div>';
 		}
-		if (empty($_SERVER['HTTP_HOST'])) {
-			# cli mode / shell access: use the --debug modifier if you are using the CLI interface
+		if (!$force) {
 			return;
 		}
 		ob_flush();