svn commit: r578051 [16/31] - in /lenya/branches/revolution/1.3.x/src: java/org/apache/lenya/cms/content/flat/ webapp/lenya/modules/xinha/ webapp/lenya/modules/xinha/contrib/ webapp/lenya/modules/xinha/examples/ webapp/lenya/modules/xinha/images/ webap...

[email protected]
Newsgroups gmane.comp.cms.lenya.cvs
Message-ID <[email protected]>
Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HorizontalRule/popups/edit_horizontal_rule.html
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HorizontalRule/popups/edit_horizontal_rule.html?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HorizontalRule/popups/edit_horizontal_rule.html (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HorizontalRule/popups/edit_horizontal_rule.html Fri Sep 21 03:36:30 2007
@@ -0,0 +1,141 @@
+<!DOCTYPE html
+     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+  <title>Insert/Edit Horizontal Rule</title>
+  <link rel="stylesheet" type="text/css" href="../../../popups/popup.css" />
+  <script type="text/javascript" src="../../../popups/popup.js"></script>
+  <script type="text/javascript" src="../../../modules/ColorPicker/ColorPicker.js"></script>
+<script type="text/javascript">
+editor = window.opener.editor;
+
+function Init() {
+	__dlg_translate("HorizontalRule");
+	__dlg_init(null,{width:320,height:290});
+	var params = window.dialogArguments;
+	if(params) {
+		document.getElementById("f_size").value = params.f_size;
+		document.getElementById("f_width").value = params.f_width;
+		document.getElementById("f_widthUnit").value = params.f_widthUnit;
+		document.getElementById("f_align").value = params.f_align;
+		document.getElementById("f_color").value = params.f_color;
+		document.getElementById("hrpv").style.backgroundColor = params.f_color;
+		document.getElementById("f_noshade").checked = params.f_noshade;
+	}
+	
+	var colpick = document.getElementById('hrpv');
+	var f_color = document.getElementById('f_color');
+	var colPicker = new Xinha.colorPicker({cellsize:'5px',callback:selectColor});
+	colpick.onclick = function() { colPicker.open('top,left',colpick, f_color.value ); }
+	
+	document.getElementById("f_width").focus();
+}
+
+function onOK() {
+  var fields = ["f_size", "f_width", "f_widthUnit", "f_align", "f_color", "f_noshade"];
+  var param = {};
+  for (var i in fields) {
+    var id = fields[i];
+	var el = document.getElementById(id);
+    param[id] = (el.type == "checkbox") ? el.checked : el.value;
+  }
+  __dlg_close(param);
+  return false;
+}
+
+function onCancel() {
+  __dlg_close(null);
+  return false;
+}
+
+function selectColor(color) {
+	document.getElementById('hrpv').style.backgroundColor = color;
+	document.getElementById('f_color').value = color;
+}
+window.onload = Init;
+</script>
+
+<style type="text/css">
+.buttonColor {
+  padding: 1px;
+  cursor: default;
+  border: 1px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+
+.buttonColor-hilite {
+  border-color: #000;
+}
+
+.buttonColor .chooser {
+  height: 0.6em;
+  border: 1px solid;
+  padding: 0px 1em;
+  border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+}
+
+.buttonColor .nocolor {
+  padding: 0px;
+  height: 0.6em;
+  border: 1px solid;
+  border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+}
+.buttonColor .nocolor-hilite { background-color: #fff; color: #f00; }
+</style>
+
+</head>
+
+<body class="dialog">
+<div class="title">Horizontal Rule</div>
+<form action="" method="get">
+  <fieldset>
+  <legend>Layout</legend>
+    <div class="fr">Width:</div>
+    <input style="margin-right: 0.5em;" name="f_width" id="f_width" size="5" type="text" />
+    <select style="margin-right: 0.5em;" name="f_widthUnit" id="f_widthUnit">
+      <option value="%">percent</option>
+      <option value="px">pixels</option>
+    </select>
+	<br />
+    <div class="fr">Height:</div>
+    <input style="margin-right: 0.5em;" name="f_size" id="f_size" size="5" type="text" /> <span>pixels</span>
+	<br />
+    <div class="fr">Alignment:</div>
+    <select name="f_align" id="f_align">
+      <option value="left">Left</option>
+      <option value="center">Center</option>
+      <option value="right">Right</option>
+    </select>
+
+  </fieldset>
+  <fieldset>
+  <legend>Style</legend>
+    <div class="fr">Color:</div>
+    <table cellpadding="2" cellspacing="0" id="hrbtn" class="buttonColor">
+    <tr>
+      <td class="chooser" id="hrpv"
+          onmouseover="document.getElementById('hrbtn').style.borderColor='black'"
+          onmouseout="document.getElementById('hrbtn').style.borderColor='ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight'"
+          >&nbsp;</td>
+      <td class="nocolor" id="hrclr"
+          onmouseover="document.getElementById('hrclr').style.color='#f00'"
+          onmouseout="document.getElementById('hrclr').style.color='#000'"
+          onclick="document.getElementById('f_color').value='';	document.getElementById('hrpv').style.backgroundColor=''">&#x00d7;</td>
+    </tr>
+    </table>
+    <br />
+    <div class="fr"> </div>
+    <input type="hidden" name="f_color" id="f_color" />
+    <input type="checkbox" name="f_noshade" id="f_noshade" value="noshade" />
+    <span>No shading</span>
+    <br />
+  </fieldset>
+<div id="buttons">
+  <button type="submit" name="ok" onclick="return onOK();">OK</button>
+  <button type="button" name="cancel" onclick="return onCancel();">Cancel</button>
+</div>
+</form>
+</body>
+</html>
\ No newline at end of file

Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlEntities/Entities.js
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlEntities/Entities.js?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlEntities/Entities.js (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlEntities/Entities.js Fri Sep 21 03:36:30 2007
@@ -0,0 +1,204 @@
+{
+"&iexcl;" : "¡",
+"&cent;" : "¢",
+"&pound;" : "£",
+"&curren;" : "¤",
+"&yen;" : "Â¥",
+"&brvbar;" : "¦",
+"&sect;" : "§",
+"&uml;" : "¨",
+"&copy;" : "©",
+"&ordf;" : "ª",
+"&laquo;" : "«",
+"&not;" : "¬",
+"&reg;" : "®",
+"&macr;" : "¯",
+"&deg;" : "°",
+"&plusmn;" : "±",
+"&sup2;" : "²",
+"&sup3;" : "³",
+"&acute;" : "´",
+"&micro;" : "µ",
+"&para;" : "¶",
+"&middot;" : "·",
+"&cedil;" : "¸",
+"&sup1;" : "¹",
+"&ordm;" : "º",
+"&raquo;" : "»",
+"&frac14;" : "¼",
+"&frac12;" : "½",
+"&frac34;" : "¾",
+"&iquest;" : "¿",
+"&Agrave;" : "À",
+"&Aacute;" : "Á",
+"&Acirc;" : "Â",
+"&Atilde;" : "Ã",
+"&Auml;" : "Ä",
+"&Aring;" : "Å",
+"&AElig;" : "Æ",
+"&Ccedil;" : "Ç",
+"&Egrave;" : "È",
+"&Eacute;" : "É",
+"&Ecirc;" : "Ê",
+"&Euml;" : "Ë",
+"&Igrave;" : "Ì",
+"&Iacute;" : "Í",
+"&Icirc;" : "Î",
+"&Iuml;" : "Ï",
+"&ETH;" : "Ð",
+"&Ntilde;" : "Ñ",
+"&Ograve;" : "Ò",
+"&Oacute;" : "Ó",
+"&Ocirc;" : "Ô",
+"&Otilde;" : "Õ",
+"&Ouml;" : "Ö",
+"&times;" : "×",
+"&Oslash;" : "Ø",
+"&Ugrave;" : "Ù",
+"&Uacute;" : "Ú",
+"&Ucirc;" : "Û",
+"&Uuml;" : "Ü",
+"&Yacute;" : "Ý",
+"&THORN;" : "Þ",
+"&szlig;" : "ß",
+"&agrave;" : "à",
+"&aacute;" : "á",
+"&acirc;" : "â",
+"&atilde;" : "ã",
+"&auml;" : "ä",
+"&aring;" : "Ã¥",
+"&aelig;" : "æ",
+"&ccedil;" : "ç",
+"&egrave;" : "è",
+"&eacute;" : "é",
+"&ecirc;" : "ê",
+"&euml;" : "ë",
+"&igrave;" : "ì",
+"&iacute;" : "í",
+"&icirc;" : "î",
+"&iuml;" : "ï",
+"&eth;" : "ð",
+"&ntilde;" : "ñ",
+"&ograve;" : "ò",
+"&oacute;" : "ó",
+"&oacute;" : "ó",
+"&ocirc;" : "ô",
+"&otilde;" : "õ",
+"&ouml;" : "ö",
+"&divide;" : "÷",
+"&oslash;" : "ø",
+"&ugrave;" : "ù",
+"&uacute;" : "ú",
+"&ucirc;" : "û",
+"&uuml;" : "ü",
+"&yacute;" : "ý",
+"&thorn;" : "þ",
+"&yuml;" : "ÿ",
+"&fnof;" : "ƒ",
+"&Alpha;" : "Α",
+"&Beta;" : "Β",
+"&Gamma;" : "Γ",
+"&Delta;" : "Δ",
+"&Epsilon;" : "Ε",
+"&Zeta;" : "Ζ",
+"&Eta;" : "Η",
+"&Theta;" : "Θ",
+"&Iota;" : "Ι",
+"&Kappa;" : "Κ",
+"&Lambda;" : "Λ",
+"&Mu;" : "Μ",
+"&Nu;" : "Ν",
+"&Xi;" : "Ξ",
+"&Omicron;" : "Ο ",
+"&Pi;" : "Π",
+"&Rho;" : "Ρ",
+"&Sigma;" : "Σ",
+"&Tau;" : "Τ",
+"&Upsilon;" : "Î¥",
+"&Phi;" : "Φ",
+"&Chi;" : "Χ",
+"&Psi;" : "Ψ",
+"&Omega;" : "Ω",
+"&alpha;" : "α",
+"&beta;" : "β",
+"&gamma;" : "γ",
+"&delta;" : "δ",
+"&epsilon;" : "ε",
+"&zeta;" : "ζ",
+"&eta;" : "η",
+"&theta;" : "θ",
+"&iota;" : "ι",
+"&kappa;" : "κ",
+"&lambda;" : "λ",
+"&mu;" : "μ",
+"&nu;" : "ν",
+"&xi;" : "ξ",
+"&omicron;" : "ο",
+"&pi;" : "π",
+"&rho;" : "ρ",
+"&sigmaf;" : "ς",
+"&sigma;" : "σ",
+"&tau;" : "τ",
+"&upsilon;" : "υ",
+"&phi;" : "φ",
+"&omega;" : "ω",
+"&bull;" : "•",
+"&hellip;" : "…",
+"&prime;" : "′",
+"&Prime;" : "″",
+"&oline;" : "‾",
+"&frasl;" : "⁄",
+"&trade;" : "™",
+"&larr;" : "←",
+"&uarr;" : "↑",
+"&rarr;" : "→",
+"&darr;" : "↓",
+"&harr;" : "↔",
+"&rArr;" : "⇒",
+"&part;" : "∂",
+"&prod;" : "∏",
+"&sum;" : "∑",
+"&minus;" : "−",
+"&radic;" : "√",
+"&infin;" : "∞",
+"&cap;" : "∩",
+"&int;" : "∫",
+"&asymp;" : "≈",
+"&ne;" : "≠",
+"&equiv;" : "≡",
+"&le;" : "≤",
+"&ge;" : "≥",
+"&loz;" : "◊",
+"&spades;" : "♠",
+"&clubs;" : "♣",
+"&hearts;" : "♥",
+"&diams;" : "♦",
+"&OElig;" : "Œ",
+"&oelig;" : "œ",
+"&Scaron;" : "Å ",
+"&scaron;" : "Å¡",
+"&Yuml;" : "Ÿ",
+"&circ;" : "ˆ",
+"&tilde;" : "˜",
+"&ndash;" : "–",
+"&mdash;" : "—",
+"&lsquo;" : "‘",
+"&rsquo;" : "’",
+"&sbquo;" : "‚",
+"&ldquo;" : "“",
+"&rdquo;" : "”",
+"&bdquo;" : "„",
+"&dagger;" : "†",
+"&Dagger;" : "‡",
+"&permil;" : "‰",
+"&lsaquo;" : "‹",
+"&rsaquo;" : "›",
+"&euro;" : "€",
+
+	// \x22 means '"' -- we use hex reprezentation so that we don't disturb
+	// JS compressors (well, at least mine fails.. ;)
+	
+	"&nbsp;" : "\xA0",
+	"&#8804;" : String.fromCharCode(0x2264), 
+	"&#8805;" : String.fromCharCode(0x2265)
+}

Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlEntities/html-entities.js
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlEntities/html-entities.js?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlEntities/html-entities.js (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlEntities/html-entities.js Fri Sep 21 03:36:30 2007
@@ -0,0 +1,51 @@
+/*------------------------------------------*\
+HtmlEntities for Xinha
+____________________
+
+Intended to faciliate the use of special characters with ISO 8 bit encodings.
+
+Using the conversion map provided by mharrisonline in ticket #127
+
+If you want to adjust the list, e.g. to except the characters that are available in the used charset,
+edit Entities.js. 
+You may save it under a different name using the xinha_config.HtmlEntities.EntitiesFile variable
+
+ISO-8859-1 preset is default, set
+  
+  xinha_config.HtmlEntities.Encoding = null;
+
+if you want all special characters to be converted or want to load a custom file 
+\*------------------------------------------*/
+
+function HtmlEntities(editor) {
+	this.editor = editor;
+}
+
+HtmlEntities._pluginInfo = {
+  name          : "HtmlEntities",
+  version       : "1.0",
+  developer     : "Raimund Meyer",
+  developer_url : "http://rheinauf.de",
+  c_owner       : "Xinha community",
+  sponsor       : "",
+  sponsor_url   : "",
+  license       : "Creative Commons Attribution-ShareAlike License"
+}
+Xinha.Config.prototype.HtmlEntities =
+{
+	Encoding     : 'iso-8859-1',
+	EntitiesFile : _editor_url + "plugins/HtmlEntities/Entities.js"
+}
+HtmlEntities.prototype.onGenerate = function() {
+    var e = this.editor;
+    var url = (e.config.HtmlEntities.Encoding) ?  _editor_url + "plugins/HtmlEntities/"+e.config.HtmlEntities.Encoding+".js" : e.config.HtmlEntities.EntitiesFile;
+    var callback = function (getback) {
+    	var specialReplacements = e.config.specialReplacements;
+    	eval("var replacements =" + getback);
+    	for (var i in  replacements)
+		{
+			specialReplacements[i] =  replacements[i];	
+		}
+    }
+    Xinha._getback(url,callback);
+}

Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlEntities/iso-8859-1.js
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlEntities/iso-8859-1.js?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlEntities/iso-8859-1.js (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlEntities/iso-8859-1.js Fri Sep 21 03:36:30 2007
@@ -0,0 +1,109 @@
+{
+"&fnof;" : "ƒ",
+"&Alpha;" : "Α",
+"&Beta;" : "Β",
+"&Gamma;" : "Γ",
+"&Delta;" : "Δ",
+"&Epsilon;" : "Ε",
+"&Zeta;" : "Ζ",
+"&Eta;" : "Η",
+"&Theta;" : "Θ",
+"&Iota;" : "Ι",
+"&Kappa;" : "Κ",
+"&Lambda;" : "Λ",
+"&Mu;" : "Μ",
+"&Nu;" : "Ν",
+"&Xi;" : "Ξ",
+"&Omicron;" : "Ο ",
+"&Pi;" : "Π",
+"&Rho;" : "Ρ",
+"&Sigma;" : "Σ",
+"&Tau;" : "Τ",
+"&Upsilon;" : "Î¥",
+"&Phi;" : "Φ",
+"&Chi;" : "Χ",
+"&Psi;" : "Ψ",
+"&Omega;" : "Ω",
+"&alpha;" : "α",
+"&beta;" : "β",
+"&gamma;" : "γ",
+"&delta;" : "δ",
+"&epsilon;" : "ε",
+"&zeta;" : "ζ",
+"&eta;" : "η",
+"&theta;" : "θ",
+"&iota;" : "ι",
+"&kappa;" : "κ",
+"&lambda;" : "λ",
+"&mu;" : "μ",
+"&nu;" : "ν",
+"&xi;" : "ξ",
+"&omicron;" : "ο",
+"&pi;" : "π",
+"&rho;" : "ρ",
+"&sigmaf;" : "ς",
+"&sigma;" : "σ",
+"&tau;" : "τ",
+"&upsilon;" : "υ",
+"&phi;" : "φ",
+"&omega;" : "ω",
+"&bull;" : "•",
+"&hellip;" : "…",
+"&prime;" : "′",
+"&Prime;" : "″",
+"&oline;" : "‾",
+"&frasl;" : "⁄",
+"&trade;" : "™",
+"&larr;" : "←",
+"&uarr;" : "↑",
+"&rarr;" : "→",
+"&darr;" : "↓",
+"&harr;" : "↔",
+"&rArr;" : "⇒",
+"&part;" : "∂",
+"&prod;" : "∏",
+"&sum;" : "∑",
+"&minus;" : "−",
+"&radic;" : "√",
+"&infin;" : "∞",
+"&cap;" : "∩",
+"&int;" : "∫",
+"&asymp;" : "≈",
+"&ne;" : "≠",
+"&equiv;" : "≡",
+"&le;" : "≤",
+"&ge;" : "≥",
+"&loz;" : "◊",
+"&spades;" : "♠",
+"&clubs;" : "♣",
+"&hearts;" : "♥",
+"&diams;" : "♦",
+"&OElig;" : "Œ",
+"&oelig;" : "œ",
+"&Scaron;" : "Å ",
+"&scaron;" : "Å¡",
+"&Yuml;" : "Ÿ",
+"&circ;" : "ˆ",
+"&tilde;" : "˜",
+"&ndash;" : "–",
+"&mdash;" : "—",
+"&lsquo;" : "‘",
+"&rsquo;" : "’",
+"&sbquo;" : "‚",
+"&ldquo;" : "“",
+"&rdquo;" : "”",
+"&bdquo;" : "„",
+"&dagger;" : "†",
+"&Dagger;" : "‡",
+"&permil;" : "‰",
+"&lsaquo;" : "‹",
+"&rsaquo;" : "›",
+"&euro;" : "€",
+
+	// \x22 means '"' -- we use hex reprezentation so that we don't disturb
+	// JS compressors (well, at least mine fails.. ;)
+	
+	"&nbsp;" : "\xA0",
+	"&#8804;" : String.fromCharCode(0x2264), 
+	"&#8805;" : String.fromCharCode(0x2265)
+}

Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/README
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/README?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/README (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/README Fri Sep 21 03:36:30 2007
@@ -0,0 +1,104 @@
+// Plugin for htmlArea to run code through the server's HTML Tidy
+// By Adam Wright, for The University of Western Australia
+//
+//   Email:      [email protected]
+//   Homepage:   http://blog.hipikat.org/
+//
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+//
+// Version: 0.5
+// Released to the outside world: 04/03/04
+
+
+HtmlTidy is a plugin for the popular cross-browser TTY WYSIWYG editor,
+htmlArea (http://www.interactivetools.com/products/htmlarea/). HtmlTidy
+basically queries HTML Tidy (http://tidy.sourceforge.net/) on the
+server side, getting it to make-html-nice, instead of relying on masses
+of javascript, which the client would have to download.
+
+Hi, this is a quick explanation of how to install HtmlTidy. Much better
+documentation is probably required, and you're welcome to write it :)
+
+
+* The HtmlTidy directory you should have found this file in should
+  include the following:
+
+  - README
+        This file, providing help installing the plugin.
+
+  - html-tidy-config.cfg
+        This file contains the configuration options HTML Tidy uses to
+        clean html, and can be modified to suit your organizations
+        requirements.
+
+  - html-tidy-logic.php
+        This is the php script, which is queried with dirty html and is
+        responsible for invoking HTML Tidy, getting nice new html and
+        returning it to the client.
+
+  - html-tidy.js
+        The main htmlArea plugin, providing functionality to tidy html
+        through the htmlArea interface.
+
+  - htmlarea.js.onmode_event.diff
+        At the time of publishing, an extra event handler was required
+        inside the main htmlarea.js file. htmlarea.js may be patched
+        against this file to make the changes reuquired, but be aware
+        that the event handler may either now be in the core or
+        htmlarea.js may have changed enough to invalidate the patch.
+	
+	UPDATE: now it exists in the official htmlarea.js; applying
+	this patch is thus no longer necessary.
+
+  - img/html-tidy.gif
+        The HtmlTidy icon, for the htmlArea toolbar. Created by Dan
+        Petty for The University of Western Australia.
+
+  - lang/en.js
+        English language file. Add your own language files here and
+        please contribute back into the htmlArea community!
+
+  The HtmlArea directory should be extracted to your htmlarea/plugins/
+  directory.
+
+
+* Make sure the onMode event handler mentioned above, regarding
+  htmlarea.js.onmode_event.diff, exists in your htmlarea.js
+
+
+* html-tidy-logic.php should be executable, and your web server should
+  be configured to execute php scripts in the directory
+  html-tidy-logic.php exists in.
+
+
+* HTML Tidy needs to be installed on your server, and 'tidy' should be
+  an alias to it, lying in the PATH known to the user executing such
+  web scripts.
+
+
+* In your htmlArea configuration, do something like this:
+
+    HTMLArea.loadPlugin("HtmlTidy");
+
+    editor = new HTMLArea("doc");
+    editor.registerPlugin("HtmlTidy");
+
+
+* Then, in your htmlArea toolbar configuration, use:
+
+    - "HT-html-tidy"
+        This will create the 'tidy broom' icon on the toolbar, which
+        will attempt to tidy html source when clicked, and;
+
+    - "HT-auto-tidy"
+        This will create an "Auto Tidy" / "Don't Tidy" dropdown, to
+        select whether the source should be tidied automatically when
+        entering source view. On by default, if you'd like it otherwise
+        you can do so programatically after generating the toolbar :)
+        (Or just hack it to be otherwise...)
+    
+
+Thank you.
+
+Any bugs you find can be emailed to [email protected]

Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/html-tidy-config.cfg
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/html-tidy-config.cfg?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/html-tidy-config.cfg (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/html-tidy-config.cfg Fri Sep 21 03:36:30 2007
@@ -0,0 +1,29 @@
+// Default configuration file for the htmlArea, HtmlTidy plugin
+// By Adam Wright, for The University of Western Australia
+//
+// Evertything you always wanted to know about HTML Tidy *
+// can be found at http://tidy.sourceforge.net/, and a
+// quick reference to the configuration options exists at
+// http://tidy.sourceforge.net/docs/quickref.html
+//
+// * But were afraid to ask
+//
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+
+word-2000: yes
+clean: yes
+drop-font-tags: no
+doctype: auto
+drop-empty-paras: yes
+drop-proprietary-attributes: yes
+enclose-block-text: yes
+enclose-text: yes
+escape-cdata: yes
+logical-emphasis: yes
+indent: auto
+indent-spaces: 2
+break-before-br: yes
+output-xhtml: yes
+
+force-output: yes

Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/html-tidy-logic.php
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/html-tidy-logic.php?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/html-tidy-logic.php (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/html-tidy-logic.php Fri Sep 21 03:36:30 2007
@@ -0,0 +1,79 @@
+<?php 
+##
+##  Plugin for htmlArea, to run code through the server's HTML Tidy
+##   By Adam Wright, for The University of Western Australia
+##    This is the server-side script, which dirty code is run through.
+##
+##  Distributed under the same terms as HTMLArea itself.
+##  This notice MUST stay intact for use (see license.txt).
+##
+
+	// Get the original source
+	$source = $_POST['htisource_name'];
+	$source = stripslashes($source);
+  $cwd = str_replace("\\","/",getcwd())."/";
+  
+	// Open a tidy process - I hope it's installed!
+	$descriptorspec = array(
+		0 => array("pipe", "r"),
+		1 => array("pipe", "w")
+	);
+	$process = @proc_open("tidy -utf8 -config {$cwd}html-tidy-config.cfg", $descriptorspec, $pipes);
+
+
+	// Make sure the program started and we got the hooks...
+	// Either way, get some source code into $source
+	if (is_resource($process)) {
+
+		// Feed untidy source into the stdin
+		fwrite($pipes[0], $source);
+		fclose($pipes[0]);
+
+		// Read clean source out to the browser
+		while (!feof($pipes[1])) {
+			//echo fgets($pipes[1], 1024);
+			$newsrc .= fgets($pipes[1], 1024);
+		}
+		fclose($pipes[1]);
+
+		// Clean up after ourselves
+		proc_close($process);
+
+	} else {
+    /* Use tidy if it's available from PECL */
+    if( function_exists('tidy_parse_string') )
+    {
+      $tempsrc = tidy_parse_string($source);
+      tidy_clean_repair();
+      $newsrc = tidy_get_output();
+    }
+    else
+    {
+      // Better give them back what they came with, so they don't lose it all...
+      $newsrc = "<body>\n" .$source. "\n</body>";
+    }
+	}
+
+	// Split our source into an array by lines
+	$srcLines = preg_split("/\n/",$newsrc,-1,PREG_SPLIT_NO_EMPTY);
+
+	// Get only the lines between the body tags
+	$startLn = 0;
+	while ( strpos( $srcLines[$startLn++], '<body' ) === false && $startLn < sizeof($srcLines) );
+	$endLn = $startLn;
+	while ( strpos( $srcLines[$endLn++], '</body' ) === false && $endLn < sizeof($srcLines) );
+
+	$srcLines = array_slice( $srcLines, $startLn, ($endLn - $startLn - 1) );
+
+	// Create a set of javascript code to compile a new source string
+	foreach ($srcLines as $line) {
+		$jsMakeSrc .= "\tns += '" . str_replace("'","\'",$line) . "\\n';\n";
+	}
+if(!sizeof($srcLines)) {
+    echo "alert(HTMLArea._lc('Tidy failed.  Check your HTML for syntax errors.', 'HtmlTidy'));\n";
+} else {
+?>
+var ns="";
+<?php echo $jsMakeSrc; ?>
+editor.setHTML(ns);
+<? } ?>
\ No newline at end of file

Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/html-tidy.js
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/html-tidy.js?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/html-tidy.js (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/html-tidy.js Fri Sep 21 03:36:30 2007
@@ -0,0 +1,105 @@
+// Plugin for htmlArea to run code through the server's HTML Tidy
+// By Adam Wright, for The University of Western Australia
+//
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+
+function HtmlTidy(editor) {
+	this.editor = editor;
+
+	var cfg = editor.config;
+	var bl = HtmlTidy.btnList;
+	var self = this;
+
+	this.onMode = this.__onMode;
+
+	// register the toolbar buttons provided by this plugin
+	var toolbar = [];
+	for (var i = 0; i < bl.length; ++i) {
+		var btn = bl[i];
+		if (btn == "html-tidy") {
+			var id = "HT-html-tidy";
+			cfg.registerButton(id, this._lc("HTML Tidy"), editor.imgURL(btn[0] + ".gif", "HtmlTidy"), true,
+					   function(editor, id) {
+						   // dispatch button press event
+						   self.buttonPress(editor, id);
+					   }, btn[1]);
+			toolbar.push(id);
+		} else if (btn == "html-auto-tidy") {
+            var btnTxt = [this._lc("Auto-Tidy"), this._lc("Don't Tidy")];
+            var optionItems = new Object();
+            optionItems[btnTxt[0]] = "auto";
+            optionItems[btnTxt[1]] = "noauto";
+			var ht_class = {
+				id	: "HT-auto-tidy",
+				options	: optionItems,
+				action	: function (editor) { self.__onSelect(editor, this); },
+				refresh	: function (editor) { },
+				context	: "body"
+			};
+			cfg.registerDropdown(ht_class);
+		}
+	}
+
+	for (var i in toolbar) {
+		cfg.toolbar[0].push(toolbar[i]);
+	}
+}
+
+HtmlTidy._pluginInfo = {
+	name          : "HtmlTidy",
+	version       : "1.0",
+	developer     : "Adam Wright",
+	developer_url : "http://blog.hipikat.org/",
+	sponsor       : "The University of Western Australia",
+	sponsor_url   : "http://www.uwa.edu.au/",
+	license       : "htmlArea"
+};
+
+HtmlTidy.prototype._lc = function(string) {
+    return HTMLArea._lc(string, 'HtmlTidy');
+};
+
+HtmlTidy.prototype.__onSelect = function(editor, obj) {
+	// Get the toolbar element object
+	var elem = editor._toolbarObjects[obj.id].element;
+
+	// Set our onMode event appropriately
+	if (elem.value == "auto")
+		this.onMode = this.__onMode;
+	else
+		this.onMode = null;
+};
+
+HtmlTidy.prototype.__onMode = function(mode) {
+	if ( mode == "textmode" ) {
+		this.buttonPress(this.editor, "HT-html-tidy");
+	}
+};
+
+HtmlTidy.btnList = [
+		    null, // separator
+		    ["html-tidy"],
+		    ["html-auto-tidy"]
+];
+
+HtmlTidy.prototype.buttonPress = function(editor, id) {
+
+	switch (id)
+  {
+    case "HT-html-tidy":
+    {
+      var oldhtml = editor.getHTML();
+      if(oldhtml=="") break; //don't clean empty text
+      // Ask the server for some nice new html, based on the old...
+      HTMLArea._postback(_editor_url + 'plugins/HtmlTidy/html-tidy-logic.php', {'htisource_name' : oldhtml},
+                            function(javascriptResponse) { eval(javascriptResponse) });
+    }
+		break;
+	}
+};
+
+HtmlTidy.prototype.processTidied = function(newSrc) {
+	editor = this.editor;
+	editor.setHTML(newSrc);
+};
\ No newline at end of file

Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/img/html-tidy.gif
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/img/html-tidy.gif?rev=578051&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/img/html-tidy.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/de.js
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/de.js?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/de.js (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/de.js Fri Sep 21 03:36:30 2007
@@ -0,0 +1,7 @@
+// I18N constants
+// LANG: "de", ENCODING: UTF-8
+// Author: Raimund Meyer [email protected]
+{
+  "HTML Tidy": "HTML Tidy",
+	"Tidy failed.  Check your HTML for syntax errors.": "Tidy fehlgeschlagen. Prüfen Sie den HTML Code nach Syntax-Fehlern."  
+};

Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/fr.js
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/fr.js?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/fr.js (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/fr.js Fri Sep 21 03:36:30 2007
@@ -0,0 +1,8 @@
+// I18N constants
+// LANG: "fr", ENCODING: UTF-8
+{
+  "HTML Tidy": "HTML Tidy",
+  "Auto-Tidy": "Tidy automatique",
+  "Don't Tidy": "Tidy non utilisé",
+  "Tidy failed.  Check your HTML for syntax errors.": "Tidy a échoué. Vérifiez votre HTML for des erreurs de syntaxe"
+};
\ No newline at end of file

Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/ja.js
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/ja.js?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/ja.js (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/ja.js Fri Sep 21 03:36:30 2007
@@ -0,0 +1,8 @@
+// I18N constants
+// LANG: "ja", ENCODING: UTF-8
+{
+  "HTML Tidy": "HTML Tidy",
+  "Auto-Tidy": "自動適正化",
+  "Don't Tidy": "適正化しない",
+  "Tidy failed.  Check your HTML for syntax errors.":"適正化に失敗しました。HTMLの文法エラーを確認してください。"
+};
\ No newline at end of file

Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/nb.js
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/nb.js?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/nb.js (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/nb.js Fri Sep 21 03:36:30 2007
@@ -0,0 +1,7 @@
+// I18N constants
+// LANG: "nb", ENCODING: UTF-8
+// translated: Kim Steinhaug, http://www.steinhaug.com/, [email protected]
+{
+  "HTML Tidy": "HTML Tidy",
+  "Tidy failed.  Check your HTML for syntax errors.": "Tidy feilet. Sjekk HTML koden for syntaksfeil."
+};
\ No newline at end of file

Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/nl.js
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/nl.js?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/nl.js (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/HtmlTidy/lang/nl.js Fri Sep 21 03:36:30 2007
@@ -0,0 +1,5 @@
+// I18N constants
+// LANG: "nl", ENCODING: UTF-8
+{
+  "HT-html-tidy": "HTML opschonen"
+};
\ No newline at end of file

Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/Files.php
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/Files.php?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/Files.php (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/Files.php Fri Sep 21 03:36:30 2007
@@ -0,0 +1,333 @@
+<?php
+/**
+ * File Utilities.
+ * @author $Author: ray $
+ * @version $Id: Files.php 709 2007-01-30 23:22:04Z ray $
+ * @package ImageManager
+ */
+
+define('FILE_ERROR_NO_SOURCE', 100);
+define('FILE_ERROR_COPY_FAILED', 101);
+define('FILE_ERROR_DST_DIR_FAILED', 102);
+define('FILE_COPY_OK', 103);
+define('FILE_ERROR_DST_DIR_EXIST', 104);
+
+/**
+ * File Utilities
+ * @author $Author: ray $
+ * @version $Id: Files.php 709 2007-01-30 23:22:04Z ray $
+ * @package ImageManager
+ * @subpackage files
+ */
+class Files 
+{
+	
+	/**
+	 * Copy a file from source to destination. If unique == true, then if
+	 * the destination exists, it will be renamed by appending an increamenting 
+	 * counting number.
+	 * @param string $source where the file is from, full path to the files required
+	 * @param string $destination_file name of the new file, just the filename
+	 * @param string $destination_dir where the files, just the destination dir,
+	 * e.g., /www/html/gallery/
+	 * @param boolean $unique create unique destination file if true.
+	 * @return string the new copied filename, else error if anything goes bad.
+	 */
+	function copyFile($source, $destination_dir, $destination_file, $unique=true) 
+	{
+		if(!(file_exists($source) && is_file($source))) 
+			return FILE_ERROR_NO_SOURCE;
+
+		$destination_dir = Files::fixPath($destination_dir);
+
+		if(!is_dir($destination_dir)) 
+			Return FILE_ERROR_DST_DIR_FAILED;
+
+		$filename = Files::escape($destination_file);
+
+		if($unique) 
+		{
+			$dotIndex = strrpos($destination_file, '.');
+			$ext = '';
+			if(is_int($dotIndex)) 
+			{
+				$ext = substr($destination_file, $dotIndex);
+				$base = substr($destination_file, 0, $dotIndex);
+			}
+			$counter = 0;
+			while(is_file($destination_dir.$filename)) 
+			{
+				$counter++;
+				$filename = $base.'_'.$counter.$ext;
+			}
+		}
+
+		if (!copy($source, $destination_dir.$filename))
+			return FILE_ERROR_COPY_FAILED;
+		
+		//verify that it copied, new file must exists
+		if (is_file($destination_dir.$filename))
+			Return $filename;
+		else
+			return FILE_ERROR_COPY_FAILED;
+	}
+
+	/**
+	 * Create a new folder.
+	 * @param string $newFolder specifiy the full path of the new folder.
+	 * @return boolean true if the new folder is created, false otherwise.
+	 */
+	function createFolder($newFolder) 
+	{
+		mkdir ($newFolder, 0777);
+		return chmod($newFolder, 0777);
+	}
+
+
+	/**
+	 * Escape the filenames, any non-word characters will be
+	 * replaced by an underscore.
+	 * @param string $filename the orginal filename
+	 * @return string the escaped safe filename
+	 */
+	function escape($filename)
+	{
+		Return preg_replace('/[^\w\._]/', '_', $filename);
+	}
+
+	/**
+	 * Delete a file.
+	 * @param string $file file to be deleted
+	 * @return boolean true if deleted, false otherwise.
+	 */
+	function delFile($file) 
+	{
+		if(is_file($file)) 
+			Return unlink($file);
+		else
+			Return false;
+	}
+
+	/**
+	 * Delete folder(s), can delete recursively.
+	 * @param string $folder the folder to be deleted.
+	 * @param boolean $recursive if true, all files and sub-directories
+	 * are delete. If false, tries to delete the folder, can throw
+	 * error if the directory is not empty.
+	 * @return boolean true if deleted.
+	 */
+	function delFolder($folder, $recursive=false) 
+	{
+		$deleted = true;
+		if($recursive) 
+		{
+			$d = dir($folder);
+			while (false !== ($entry = $d->read())) 
+			{
+				if ($entry != '.' && $entry != '..')
+				{
+					$obj = Files::fixPath($folder).$entry;
+					//var_dump($obj);
+					if (is_file($obj))
+					{
+						$deleted &= Files::delFile($obj);					
+					}
+					else if(is_dir($obj))
+					{
+						$deleted &= Files::delFolder($obj, $recursive);
+					}
+					
+				}
+			}
+			$d->close();
+
+		}
+
+		//$folder= $folder.'/thumbs';
+		//var_dump($folder);
+		if(is_dir($folder)) 
+			$deleted &= rmdir($folder);
+		else
+			$deleted &= false;
+
+		Return $deleted;
+	}
+
+	/**
+	 * Append a / to the path if required.
+	 * @param string $path the path
+	 * @return string path with trailing /
+	 */
+	function fixPath($path) 
+	{
+		//append a slash to the path if it doesn't exists.
+		if(!(substr($path,-1) == '/'))
+			$path .= '/';
+		Return $path;
+	}
+
+	/**
+	 * Concat two paths together. Basically $pathA+$pathB
+	 * @param string $pathA path one
+	 * @param string $pathB path two
+	 * @return string a trailing slash combinded path.
+	 */
+	function makePath($pathA, $pathB) 
+	{
+		$pathA = Files::fixPath($pathA);
+		if(substr($pathB,0,1)=='/')
+			$pathB = substr($pathB,1);
+		Return Files::fixPath($pathA.$pathB);
+	}
+
+	/**
+	 * Similar to makePath, but the second parameter
+	 * is not only a path, it may contain say a file ending.
+	 * @param string $pathA the leading path
+	 * @param string $pathB the ending path with file
+	 * @return string combined file path.
+	 */
+	function makeFile($pathA, $pathB) 
+	{		
+		$pathA = Files::fixPath($pathA);
+		if(substr($pathB,0,1)=='/')
+			$pathB = substr($pathB,1);
+		
+		Return $pathA.$pathB;
+	}
+
+	
+	/**
+	 * Format the file size, limits to Mb.
+	 * @param int $size the raw filesize
+	 * @return string formated file size.
+	 */
+	function formatSize($size) 
+	{
+		if($size < 1024) 
+			return $size.' bytes';	
+		else if($size >= 1024 && $size < 1024*1024) 
+			return sprintf('%01.2f',$size/1024.0).' KB';
+		else
+			return sprintf('%01.2f',$size/(1024.0*1024)).' MB';
+	}
+
+	/**
+	 * Returns size of a directory, with all file & subdirectory
+	 * sizes added up
+	 * @param string dir path
+	 * @return int
+	 */
+	function dirSize($dirName = '.')
+	{
+		$dir  = dir($dirName);
+		$size = 0;
+
+		while ($file = $dir->read()) {
+			if ($file != '.' && $file != '..')
+			{
+				if (is_dir("$dirName$file"))
+				{
+					$size += Files::dirSize($dirName . '/' . $file);
+				}
+				else
+				{
+					$size += filesize($dirName . '/' . $file);
+				}
+			}
+		}
+		$dir->close();
+		return $size;
+	}
+	
+	/**
+	 * Renames file, preserving its directory and extension
+	 * @param string $oldPath path to the old existing file
+	 * @param string new filename (just the name, without path or extension)
+	 * @author Krzysztof Kotowicz <[email protected]>
+	 */
+	function renameFile($oldPath, $newName) {
+
+		if(!(file_exists($oldPath) && is_file($oldPath)))
+			return FILE_ERROR_NO_SOURCE;
+
+		$oldFileParts = pathinfo($oldPath);
+
+		$newPath = $oldFileParts['dirname'] . '/'
+				   . $newName
+				   . (!empty($oldFileParts['extension']) ? '.' . $oldFileParts['extension'] : '');
+
+		if (file_exists($newPath))
+			return false;
+
+		if (!rename($oldPath, $newPath))
+			return FILE_ERROR_COPY_FAILED;
+
+	}
+	
+	function rename ($oldPath,$newPath)
+	{
+		if(!(is_dir($oldPath) || is_file($oldPath)))
+			return FILE_ERROR_NO_SOURCE;
+		
+		if (file_exists($newPath))
+			return FILE_ERROR_DST_DIR_EXIST;
+
+		$ret = rename($oldPath, $newPath);
+		if (!$ret)
+			return FILE_ERROR_COPY_FAILED;
+		else return FILE_COPY_OK;
+	}
+	
+		/**
+	 * copy a directory and all subdirectories and files (recursive)
+	 * @author SBoisvert at Don'tSpamMe dot Bryxal dot ca (adapted from php.net)
+	 * @author Raimund Meyer
+	 * @param string base path
+	 * @param string source directory
+	 * @param string destination directory
+	 * @param bool   overwrite existing files
+	 *  
+	 * @return mixed bool true on pass, number on fail
+	 */
+  	function copyDir($basePath, $source, $dest, $overwrite = false)
+	{
+		if(!is_dir($basePath . $dest))
+		{
+			if (!@mkdir($basePath . $dest)) return FILE_ERROR_DST_DIR_FAILED;	
+		}
+		if($handle = opendir($basePath . $source))
+		{        // if the folder exploration is sucsessful, continue
+			while( ($file = readdir($handle)) !== false)
+			{ // as long as storing the next file to $file is successful, continue
+				if($file != '.' && $file != '..')
+				{
+					$path = $source . '/' . $file;
+					if(is_file($basePath . $path))
+					{
+						/*if(!is_file($basePath . $dest . '/' . $file) || $overwrite)
+						{
+							if(!@copy($basePath . $path, $basePath . $dest . '/' . $file))
+							{
+							  return FILE_ERROR_COPY_FAILED;
+							}
+						}*/
+						Files::copyFile($basePath . $path, $basePath . $dest . '/', $file, true);
+					} 
+					elseif(is_dir($basePath . $path))
+					{
+						if(!is_dir($basePath . $dest . '/' . $file))
+						{
+							mkdir($basePath . $dest . '/' . $file); // make subdirectory before subdirectory is copied
+							Files::copyDir($basePath, $path, $dest . '/' . $file, $overwrite); //recurse!
+						}
+					}
+				}
+			}
+			closedir($handle);
+		}
+		return true;
+	}
+}
+
+?>

Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/GD.php
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/GD.php?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/GD.php (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/GD.php Fri Sep 21 03:36:30 2007
@@ -0,0 +1,503 @@
+<?php
+/***********************************************************************
+** Title.........:  GD Driver
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <[email protected]>
+** Filename......:  GD.php
+** Last changed..:  30 Aug 2003 
+** Notes.........:  Orginal is from PEAR
+**/
+// +----------------------------------------------------------------------+
+// | PHP Version 4                                                        |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group                                |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license,      |
+// | that is bundled with this package in the file LICENSE, and is        |
+// | available at through the world-wide-web at                           |
+// | http://www.php.net/license/2_02.txt.                                 |
+// | If you did not receive a copy of the PHP license and are unable to   |
+// | obtain it through the world-wide-web, please send a note to          |
+// | [email protected] so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <[email protected]>                      |
+// |          Alan Knowles <[email protected]>                            |
+// +----------------------------------------------------------------------+
+//
+//    Usage :
+//    $img    = new Image_Transform_GD();
+//    $angle  = -78;
+//    $img->load('magick.png');
+//
+//    if($img->rotate($angle,array('autoresize'=>true,'color_mask'=>array(255,0,0)))){
+//        $img->addText(array('text'=>"Rotation $angle",'x'=>0,'y'=>100,'font'=>'/usr/share/fonts/default/TrueType/cogb____.ttf'));
+//        $img->display();
+//    } else {
+//        echo "Error";
+//    }
+//
+//
+// $Id: GD.php 709 2007-01-30 23:22:04Z ray $
+//
+// Image Transformation interface using the GD library
+//
+
+require_once "../ImageManager/Classes/Transform.php";
+
+Class Image_Transform_Driver_GD extends Image_Transform
+{
+    /**
+     * Holds the image file for manipulation
+     */
+    var $imageHandle = '';
+
+    /**
+     * Holds the original image file
+     */
+    var $old_image = '';
+
+    /**
+     * Check settings
+     *
+     * @return mixed true or  or a PEAR error object on error
+     *
+     * @see PEAR::isError()
+     */
+    function Image_Transform_GD()
+    {
+        return;
+    } // End function Image
+
+    /**
+     * Load image
+     *
+     * @param string filename
+     *
+     * @return mixed none or a PEAR error object on error
+     * @see PEAR::isError()
+     */
+    function load($image)
+    {
+        $this->uid = md5($_SERVER['REMOTE_ADDR']);
+        $this->image = $image;
+        $this->_get_image_details($image);
+        $functionName = 'ImageCreateFrom' . $this->type;
+		if(function_exists($functionName))
+		{
+			$this->imageHandle = $functionName($this->image);
+		}
+    } // End load
+
+    /**
+     * addText
+     *
+     * @param   array   options     Array contains options
+     *                              array(
+     *                                  'text'  The string to draw
+     *                                  'x'     Horizontal position
+     *                                  'y'     Vertical Position
+     *                                  'Color' Font color
+     *                                  'font'  Font to be used
+     *                                  'size'  Size of the fonts in pixel
+     *                                  'resize_first'  Tell if the image has to be resized
+     *                                                  before drawing the text
+     *                              )
+     *
+     * @return none
+     * @see PEAR::isError()
+     */
+    function addText($params)
+    {
+        $default_params = array(
+                                'text' => 'This is Text',
+                                'x' => 10,
+                                'y' => 20,
+                                'color' => array(255,0,0),
+                                'font' => 'Arial.ttf',
+                                'size' => '12',
+                                'angle' => 0,
+                                'resize_first' => false // Carry out the scaling of the image before annotation?  Not used for GD
+                                );
+        $params = array_merge($default_params, $params);
+        extract($params);
+
+        if( !is_array($color) ){
+            if ($color[0]=='#'){
+                $this->colorhex2colorarray( $color );
+            } else {
+                include_once('Image/Transform/Driver/ColorsDefs.php');
+                $color = isset($colornames[$color])?$colornames[$color]:false;
+            }
+        }
+
+        $c = imagecolorresolve ($this->imageHandle, $color[0], $color[1], $color[2]);
+
+        if ('ttf' == substr($font, -3)) {
+            ImageTTFText($this->imageHandle, $size, $angle, $x, $y, $c, $font, $text);
+        } else {
+            ImagePSText($this->imageHandle, $size, $angle, $x, $y, $c, $font, $text);
+        }
+        return true;
+    } // End addText
+
+
+    /**
+     * Rotate image by the given angle
+     * Uses a fast rotation algorythm for custom angles
+     * or lines copy for multiple of 90 degrees
+     *
+     * @param int       $angle      Rotation angle
+     * @param array     $options    array(  'autoresize'=>true|false,
+     *                                      'color_mask'=>array(r,g,b), named color or #rrggbb
+     *                                   )
+     * @author Pierre-Alain Joye
+     * @return mixed none or a PEAR error object on error
+     * @see PEAR::isError()
+     */
+    function rotate($angle, $options=null)
+    {
+        if(function_exists('imagerotate')) {
+            $white = imagecolorallocate ($this->imageHandle, 255, 255, 255);
+			$this->imageHandle = imagerotate($this->imageHandle, $angle, $white);
+            return true;
+        }
+
+        if ( $options==null ){
+            $autoresize = true;
+            $color_mask = array(255,255,0);
+        } else {
+            extract( $options );
+        }
+
+        while ($angle <= -45) {
+            $angle  += 360;
+        }
+        while ($angle > 270) {
+            $angle  -= 360;
+        }
+
+        $t      = deg2rad($angle);
+
+        if( !is_array($color_mask) ){
+            if ($color[0]=='#'){
+                $this->colorhex2colorarray( $color_mask );
+            } else {
+                include_once('Image/Transform/Driver/ColorDefs.php');
+                $color = isset($colornames[$color_mask])?$colornames[$color_mask]:false;
+            }
+        }
+
+        // Do not round it, too much lost of quality
+        $cosT   = cos($t);
+        $sinT   = sin($t);
+
+        $img    =& $this->imageHandle;
+
+        $width  = $max_x  = $this->img_x;
+        $height = $max_y  = $this->img_y;
+        $min_y  = 0;
+        $min_x  = 0;
+
+        $x1     = round($max_x/2,0);
+        $y1     = round($max_y/2,0);
+
+        if ( $autoresize ){
+            $t      = abs($t);
+            $a      = round($angle,0);
+            switch((int)($angle)){
+                case 0:
+                        $width2     = $width;
+                        $height2    = $height;
+                    break;
+                case 90:
+                        $width2     = $height;
+                        $height2    = $width;
+                    break;
+                case 180:
+                        $width2     = $width;
+                        $height2    = $height;
+                    break;
+                case 270:
+                        $width2     = $height;
+                        $height2    = $width;
+                    break;
+                default:
+                    $width2     = (int)(abs(sin($t) * $height + cos($t) * $width));
+                    $height2    = (int)(abs(cos($t) * $height+sin($t) * $width));
+            }
+
+            $width2     -= $width2%2;
+            $height2    -= $height2%2;
+
+            $d_width    = abs($width - $width2);
+            $d_height   = abs($height - $height2);
+            $x_offset   = $d_width/2;
+            $y_offset   = $d_height/2;
+            $min_x2     = -abs($x_offset);
+            $min_y2     = -abs($y_offset);
+            $max_x2     = $width2;
+            $max_y2     = $height2;
+        }
+
+        $img2   = @imagecreate($width2,$height2);
+
+        if ( !is_resource($img2) ){
+            return false;/*PEAR::raiseError('Cannot create buffer for the rotataion.',
+                                null, PEAR_ERROR_TRIGGER, E_USER_NOTICE);*/
+        }
+
+        $this->img_x = $width2;
+        $this->img_y = $height2;
+
+
+        imagepalettecopy($img2,$img);
+
+        $mask   = imagecolorresolve($img2,$color_mask[0],$color_mask[1],$color_mask[2]);
+
+        // use simple lines copy for axes angles
+        switch((int)($angle)){
+            case 0:
+                imagefill ($img2, 0, 0,$mask);
+                for ($y=0; $y < $max_y; $y++) {
+                    for ($x = $min_x; $x < $max_x; $x++){
+                        $c  = @imagecolorat ( $img, $x, $y);
+                        imagesetpixel($img2,$x+$x_offset,$y+$y_offset,$c);
+                    }
+                }
+                break;
+            case 90:
+                imagefill ($img2, 0, 0,$mask);
+                for ($x = $min_x; $x < $max_x; $x++){
+                    for ($y=$min_y; $y < $max_y; $y++) {
+                        $c  = imagecolorat ( $img, $x, $y);
+                        imagesetpixel($img2,$max_y-$y-1,$x,$c);
+                    }
+                }
+                break;
+            case 180:
+                imagefill ($img2, 0, 0,$mask);
+                for ($y=0; $y < $max_y; $y++) {
+                    for ($x = $min_x; $x < $max_x; $x++){
+                        $c  = @imagecolorat ( $img, $x, $y);
+                        imagesetpixel($img2, $max_x2-$x-1, $max_y2-$y-1, $c);
+                    }
+                }
+                break;
+            case 270:
+                imagefill ($img2, 0, 0,$mask);
+                for ($y=0; $y < $max_y; $y++) {
+                    for ($x = $max_x; $x >= $min_x; $x--){
+                        $c  = @imagecolorat ( $img, $x, $y);
+                        imagesetpixel($img2,$y,$max_x-$x-1,$c);
+                    }
+                }
+                break;
+            // simple reverse rotation algo
+            default:
+                $i=0;
+                for ($y = $min_y2; $y < $max_y2; $y++){
+
+                    // Algebra :)
+                    $x2 = round((($min_x2-$x1) * $cosT) + (($y-$y1) * $sinT + $x1),0);
+                    $y2 = round((($y-$y1) * $cosT - ($min_x2-$x1) * $sinT + $y1),0);
+
+                    for ($x = $min_x2; $x < $max_x2; $x++){
+
+                        // Check if we are out of original bounces, if we are
+                        // use the default color mask
+                        if ( $x2>=0 && $x2<$max_x && $y2>=0 && $y2<$max_y ){
+                            $c  = imagecolorat ( $img, $x2, $y2);
+                        } else {
+                            $c  = $mask;
+                        }
+                        imagesetpixel($img2,$x+$x_offset,$y+$y_offset,$c);
+
+                        // round verboten!
+                        $x2  += $cosT;
+                        $y2  -= $sinT;
+                    }
+                }
+                break;
+        }
+        $this->old_image    = $this->imageHandle;
+        $this->imageHandle  =  $img2;
+        return true;
+    }
+
+
+   /**
+    * Resize Action
+    *
+    * For GD 2.01+ the new copyresampled function is used
+    * It uses a bicubic interpolation algorithm to get far
+    * better result.
+    *
+    * @param int  $new_x new width
+    * @param int  $new_y new height
+    *
+    * @return true on success or pear error
+    * @see PEAR::isError()
+    */
+    function _resize($new_x, $new_y) {
+        if ($this->resized === true) {
+            return false; /*PEAR::raiseError('You have already resized the image without saving it.  Your previous resizing will be overwritten', null, PEAR_ERROR_TRIGGER, E_USER_NOTICE);*/
+        }
+        if(function_exists('ImageCreateTrueColor')){
+            $new_img =ImageCreateTrueColor($new_x,$new_y);
+        } else {
+            $new_img =ImageCreate($new_x,$new_y);
+        }
+        if(function_exists('ImageCopyResampled')){
+            ImageCopyResampled($new_img, $this->imageHandle, 0, 0, 0, 0, $new_x, $new_y, $this->img_x, $this->img_y);
+        } else {
+            ImageCopyResized($new_img, $this->imageHandle, 0, 0, 0, 0, $new_x, $new_y, $this->img_x, $this->img_y);
+        }
+        $this->old_image = $this->imageHandle;
+        $this->imageHandle = $new_img;
+        $this->resized = true;
+
+        $this->new_x = $new_x;
+        $this->new_y = $new_y;
+        return true;
+    }
+
+    /**
+     * Crop the image
+     *
+     * @param int $crop_x left column of the image
+     * @param int $crop_y top row of the image
+     * @param int $crop_width new cropped image width
+     * @param int $crop_height new cropped image height
+     */
+    function crop($new_x, $new_y, $new_width, $new_height) 
+    {
+        if(function_exists('ImageCreateTrueColor')){
+            $new_img =ImageCreateTrueColor($new_width,$new_height);
+        } else {
+            $new_img =ImageCreate($new_width,$new_height);
+        }
+        if(function_exists('ImageCopyResampled')){
+            ImageCopyResampled($new_img, $this->imageHandle, 0, 0, $new_x, $new_y,$new_width,$new_height,$new_width,$new_height);
+        } else {
+            ImageCopyResized($new_img, $this->imageHandle, 0, 0, $new_x, $new_y, $new_width,$new_height,$new_width,$new_height);
+        }
+        $this->old_image = $this->imageHandle;
+        $this->imageHandle = $new_img;
+        $this->resized = true;
+
+        $this->new_x = $new_x;
+        $this->new_y = $new_y;
+        return true;
+    }
+   
+    /**
+     * Flip the image horizontally or vertically
+     *
+     * @param boolean $horizontal true if horizontal flip, vertical otherwise
+     */
+    function flip($horizontal)
+    {
+        if(!$horizontal) {
+            $this->rotate(180);
+        }
+
+        $width = imagesx($this->imageHandle); 
+        $height = imagesy($this->imageHandle); 
+
+        for ($j = 0; $j < $height; $j++) { 
+                $left = 0; 
+                $right = $width-1; 
+
+
+                while ($left < $right) { 
+                    //echo " j:".$j." l:".$left." r:".$right."\n<br>";
+                    $t = imagecolorat($this->imageHandle, $left, $j); 
+                    imagesetpixel($this->imageHandle, $left, $j, imagecolorat($this->imageHandle, $right, $j)); 
+                    imagesetpixel($this->imageHandle, $right, $j, $t); 
+                    $left++; $right--; 
+                } 
+            
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Adjust the image gamma
+     *
+     * @param float $outputgamma
+     *
+     * @return none
+     */
+    function gamma($outputgamma=1.0) {
+        ImageGammaCorrect($this->imageHandle, 1.0, $outputgamma);
+    }
+
+    /**
+     * Save the image file
+     *
+     * @param string  $filename the name of the file to write to
+     * @param int     $quality  output DPI, default is 85
+     * @param string  $types    define the output format, default
+     *                          is the current used format
+     *
+     * @return none
+     */
+    function save($filename, $type = '', $quality = 85)
+    {
+		$type           = $type==''? $this->type : $type;
+		$functionName   = 'image' . $type;
+
+		if(function_exists($functionName))
+		{
+			$this->old_image = $this->imageHandle;
+			if($type=='jpeg')
+				$functionName($this->imageHandle, $filename, $quality);
+			else
+				$functionName($this->imageHandle, $filename);
+			$this->imageHandle = $this->old_image;
+			$this->resized = false;
+		}
+    } // End save
+
+
+    /**
+     * Display image without saving and lose changes
+     *
+     * @param string type (JPG,PNG...);
+     * @param int quality 75
+     *
+     * @return none
+     */
+    function display($type = '', $quality = 75)
+    {
+        if ($type != '') {
+            $this->type = $type;
+        }
+        $functionName = 'Image' . $this->type;
+		if(function_exists($functionName))
+		{
+			header('Content-type: image/' . strtolower($this->type));
+			$functionName($this->imageHandle, '', $quality);
+			$this->imageHandle = $this->old_image;
+			$this->resized = false;
+			ImageDestroy($this->old_image);
+			$this->free();
+		}
+    }
+
+    /**
+     * Destroy image handle
+     *
+     * @return none
+     */
+    function free()
+    {
+        if ($this->imageHandle){
+            ImageDestroy($this->imageHandle);
+        }
+    }
+
+} // End class ImageGD
+?>

Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/IM.php
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/IM.php?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/IM.php (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/IM.php Fri Sep 21 03:36:30 2007
@@ -0,0 +1,235 @@
+<?php
+
+/***********************************************************************
+** Title.........:  ImageMagick Driver
+** Version.......:  1.0
+** Author........:  Xiang Wei ZHUO <[email protected]>
+** Filename......:  IM.php
+** Last changed..:  30 Aug 2003 
+** Notes.........:  Orginal is from PEAR
+**/
+
+// +----------------------------------------------------------------------+
+// | PHP Version 4                                                        |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group                                |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license,      |
+// | that is bundled with this package in the file LICENSE, and is        |
+// | available at through the world-wide-web at                           |
+// | http://www.php.net/license/2_02.txt.                                 |
+// | If you did not receive a copy of the PHP license and are unable to   |
+// | obtain it through the world-wide-web, please send a note to          |
+// | [email protected] so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <[email protected]>                      |
+// +----------------------------------------------------------------------+
+//
+// $Id: IM.php 709 2007-01-30 23:22:04Z ray $
+//
+// Image Transformation interface using command line ImageMagick
+//
+
+require_once "../ImageManager/Classes/Transform.php";
+
+Class Image_Transform_Driver_IM extends Image_Transform
+{
+    /**
+     * associative array commands to be executed
+     * @var array
+     */
+    var $command = array();
+
+    /**
+     *
+     *
+     */
+    function Image_Transform_Driver_IM()
+    {
+        return true;
+    } // End Image_IM
+
+    /**
+     * Load image
+     *
+     * @param string filename
+     *
+     * @return mixed none or a PEAR error object on error
+     * @see PEAR::isError()
+     */
+    function load($image)
+    {
+
+        $this->uid = md5($_SERVER['REMOTE_ADDR']);
+        /*if (!file_exists($image)) {
+            return PEAR::raiseError('The image file ' . $image . ' does\'t exist', true);
+        }*/
+        $this->image = $image;
+        $this->_get_image_details($image);
+    } // End load
+
+    /**
+     * Resize Action
+     *
+     * @param int   new_x   new width
+     * @param int   new_y   new height
+     *
+     * @return none
+     * @see PEAR::isError()
+     */
+    function _resize($new_x, $new_y)
+    {
+        /*if (isset($this->command['resize'])) {
+            return PEAR::raiseError("You cannot scale or resize an image more than once without calling save or display", true);
+        }*/
+        $this->command['resize'] = "-geometry ${new_x}x${new_y}!";
+
+        $this->new_x = $new_x;
+        $this->new_y = $new_y;
+    } // End resize
+
+    /**
+     * Crop the image
+     *
+     * @param int $crop_x left column of the image
+     * @param int $crop_y top row of the image
+     * @param int $crop_width new cropped image width
+     * @param int $crop_height new cropped image height
+     */
+    function crop($crop_x, $crop_y, $crop_width, $crop_height) 
+    {
+        $this->command['crop'] = "-crop {$crop_width}x{$crop_height}+{$crop_x}+{$crop_y}";
+    }
+
+    /**
+     * Flip the image horizontally or vertically
+     *
+     * @param boolean $horizontal true if horizontal flip, vertical otherwise
+     */
+    function flip($horizontal) 
+    {
+        if($horizontal)
+            $this->command['flop'] = "-flop";
+        else
+            $this->command['flip'] = "-flip";
+    }
+    /**
+     * rotate
+     *
+     * @param   int     angle   rotation angle
+     * @param   array   options no option allowed
+     *
+     */
+    function rotate($angle, $options=null)
+    {
+        if ('-' == $angle{0}) {
+            $angle = 360 - substr($angle, 1);
+        }
+         $this->command['rotate'] = "-rotate $angle";
+    } // End rotate
+
+    /**
+     * addText
+     *
+     * @param   array   options     Array contains options
+     *                              array(
+     *                                  'text'  The string to draw
+     *                                  'x'     Horizontal position
+     *                                  'y'     Vertical Position
+     *                                  'Color' Font color
+     *                                  'font'  Font to be used
+     *                                  'size'  Size of the fonts in pixel
+     *                                  'resize_first'  Tell if the image has to be resized
+     *                                                  before drawing the text
+     *                              )
+     *
+     * @return none
+     * @see PEAR::isError()
+     */
+    function addText($params)
+    {
+        $default_params = array(
+                                'text' => 'This is Text',
+                                'x' => 10,
+                                'y' => 20,
+                                'color' => 'red',
+                                'font' => 'Arial.ttf',
+                                'resize_first' => false // Carry out the scaling of the image before annotation?
+                                );
+         $params = array_merge($default_params, $params);
+         extract($params);
+         if (true === $resize_first) {
+             // Set the key so that this will be the last item in the array
+            $key = 'ztext';
+         } else {
+            $key = 'text';
+         }
+         $this->command[$key] = "-font $font -fill $color -draw 'text $x,$y \"$text\"'";
+         // Producing error: gs: not found gs: not found convert: Postscript delegate failed [No such file or directory].
+    } // End addText
+
+    /**
+     * Adjust the image gamma
+     *
+     * @param float $outputgamma
+     *
+     * @return none
+     */
+    function gamma($outputgamma=1.0) {
+        $this->command['gamma'] = "-gamma $outputgamma";
+    }
+
+    /**
+     * Save the image file
+     *
+     * @param string  $filename the name of the file to write to
+     * @param quality $quality  image dpi, default=75
+     * @param string  $type     (JPG,PNG...)
+     *
+     * @return none
+     */
+    function save($filename, $type='', $quality = 85)
+    {
+        $type == '' ? $this->type : $type;
+        $cmd = '' . IMAGE_TRANSFORM_LIB_PATH . 'convert ';
+		$cmd .= implode(' ', $this->command) . " -quality $quality ";
+		$cmd .= '"'.($this->image) . '" "' . ($filename) . '"';
+        
+        //$cmd = str_replace('/', '\\', $cmd);
+		//echo($cmd.'<br>');
+        exec($cmd,$retval);
+		//error_log('IM '.print_r($retval,true));
+    } // End save
+
+    /**
+     * Display image without saving and lose changes
+     *
+     * @param string type (JPG,PNG...);
+     * @param int quality 75
+     *
+     * @return none
+     */
+    function display($type = '', $quality = 75)
+    {
+        if ($type == '') {
+            header('Content-type: image/' . $this->type);
+            passthru(IMAGE_TRANSFORM_LIB_PATH . 'convert ' . implode(' ', $this->command) . " -quality $quality "  . escapeshellarg($this->image) . ' ' . strtoupper($this->type) . ":-");
+        } else {
+            header('Content-type: image/' . $type);
+            passthru(IMAGE_TRANSFORM_LIB_PATH . 'convert ' . implode(' ', $this->command) . " -quality $quality "  . escapeshellarg($this->image) . ' ' . strtoupper($type) . ":-");
+        }
+    }
+
+
+    /**
+     * Destroy image handle
+     *
+     * @return none
+     */
+    function free()
+    {
+        return true;
+    }
+
+} // End class ImageIM
+?>

Added: lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/ImageEditor.php
URL: http://svn.apache.org/viewvc/lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/ImageEditor.php?rev=578051&view=auto
==============================================================================
--- lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/ImageEditor.php (added)
+++ lenya/branches/revolution/1.3.x/src/webapp/lenya/modules/xinha/plugins/ImageManager/Classes/ImageEditor.php Fri Sep 21 03:36:30 2007
@@ -0,0 +1,449 @@
+<?php
+/**
+ * Image Editor. Editing tools, crop, rotate, scale and save.
+ * @author $Author: ray $
+ * @version $Id: ImageEditor.php 709 2007-01-30 23:22:04Z ray $
+ * @package ImageManager
+ */
+
+require_once('../ImageManager/Classes/Transform.php');
+
+/**
+ * Handles the basic image editing capbabilities.
+ * @author $Author: ray $
+ * @version $Id: ImageEditor.php 709 2007-01-30 23:22:04Z ray $
+ * @package ImageManager
+ * @subpackage Editor
+ */
+class ImageEditor 
+{
+	/**
+	 * ImageManager instance.
+	 */
+	var $manager;
+
+	/**
+	 * user based on IP address
+	 */
+	var $_uid;
+
+	/**
+	 * tmp file storage time.
+	 */
+	var $lapse_time =900; //15 mins
+
+	var $filesaved = 0;
+
+	/**
+	 * Create a new ImageEditor instance. Editing requires a 
+	 * tmp file, which is saved in the current directory where the
+	 * image is edited. The tmp file is assigned by md5 hash of the
+	 * user IP address. This hashed is used as an ID for cleaning up
+	 * the tmp files. In addition, any tmp files older than the
+	 * the specified period will be deleted.
+	 * @param ImageManager $manager the image manager, we need this
+	 * for some file and path handling functions.
+	 */
+	function ImageEditor($manager) 
+	{
+		$this->manager = $manager;
+		$this->_uid = md5($_SERVER['REMOTE_ADDR']);
+	}
+	
+	/**
+	 * Did we save a file?
+	 * @return int 1 if the file was saved sucessfully, 
+	 * 0 no save operation, -1 file save error.
+	 */
+	function isFileSaved() 
+	{
+		Return $this->filesaved;
+	}
+
+	/**
+	 * Process the image, if not action, just display the image.
+	 * @return array with image information, empty array if not an image.
+	 * <code>array('src'=>'url of the image', 'dimensions'=>'width="xx" height="yy"',
+	 * 'file'=>'image file, relative', 'fullpath'=>'full path to the image');</code>
+	 */
+	function processImage() 
+	{
+		if(isset($_GET['img']))
+			$relative = rawurldecode($_GET['img']);
+		else
+			Return array();
+		
+		//$relative = '/Series2004NoteFront.jpg';
+
+		$imgURL = $this->manager->getFileURL($relative);
+		$fullpath = $this->manager->getFullPath($relative);
+		
+		$imgInfo = @getImageSize($fullpath);
+		if(!is_array($imgInfo))
+			Return array();
+
+		$action = $this->getAction();
+
+		if(!is_null($action))
+		{
+			$image = $this->processAction($action, $relative, $fullpath);
+		}
+		else
+		{
+			$image['src'] = $imgURL;
+			$image['dimensions'] = $imgInfo[3];
+			$image['file'] = $relative;
+			$image['fullpath'] = $fullpath;
+		}
+
+		Return $image;
+	}
+
+	/**
+	 * Process the actions, crop, scale(resize), rotate, flip, and save.
+	 * When ever an action is performed, the result is save into a
+	 * temporary image file, see createUnique on the filename specs.
+	 * It does not return the saved file, alway returning the tmp file.
+	 * @param string $action, should be 'crop', 'scale', 'rotate','flip', or 'save'
+	 * @param string $relative the relative image filename
+	 * @param string $fullpath the fullpath to the image file
+	 * @return array with image information
+	 * <code>array('src'=>'url of the image', 'dimensions'=>'width="xx" height="yy"',
+	 * 'file'=>'image file, relative', 'fullpath'=>'full path to the image');</code>
+	 */
+	function processAction($action, $relative, $fullpath) 
+	{
+		$params = '';
+		
+		if(isset($_GET['params']))
+			$params = $_GET['params'];
+
+		$values =  explode(',',$params,4);
+		$saveFile = $this->getSaveFileName($values[0]);
+
+		$img = Image_Transform::factory(IMAGE_CLASS);
+		$img->load($fullpath);
+
+		switch ($action) 
+		{
+			case 'crop':
+				$img->crop(intval($values[0]),intval($values[1]),
+							intval($values[2]),intval($values[3]));
+			break;
+			case 'scale':
+				$img->resize(intval($values[0]),intval($values[1]));
+				break;
+			case 'rotate':
+				$img->rotate(floatval($values[0]));
+				break;
+			case 'flip':
+				if ($values[0] == 'hoz')
+					$img->flip(true);
+				else if($values[0] == 'ver') 
+					$img->flip(false);
+				break;
+			case 'save':
+				if(!is_null($saveFile))
+				{
+					$quality = intval($values[1]);
+		            if($quality <0) $quality = 85;
+					$newSaveFile = $this->makeRelative($relative, $saveFile);
+					$newSaveFile = $this->getUniqueFilename($newSaveFile);
+					
+					//get unique filename just returns the filename, so
+					//we need to make the relative path once more.
+					$newSaveFile = $this->makeRelative($relative, $newSaveFile);
+          $image['saveFile'] = $newSaveFile;
+					$newSaveFullpath = $this->manager->getFullPath($newSaveFile);
+					$img->save($newSaveFullpath, $values[0], $quality);
+					if(is_file($newSaveFullpath))
+						$this->filesaved = 1;
+					else
+						$this->filesaved = -1;
+				}
+				break;
+		}
+		
+		//create the tmp image file
+		$filename = $this->createUnique($fullpath);
+		$newRelative = $this->makeRelative($relative, $filename);
+		$newFullpath = $this->manager->getFullPath($newRelative);
+		$newURL = $this->manager->getFileURL($newRelative);
+		
+		//save the file.
+		$img->save($newFullpath);
+		$img->free();
+
+		//get the image information
+		$imgInfo = @getimagesize($newFullpath);
+
+		$image['src'] = $newURL;
+    $image['width'] = $imgInfo[0];
+    $image['height'] = $imgInfo[1];
+		$image['dimensions'] = $imgInfo[3];
+		$image['file'] = $newRelative;
+		$image['fullpath'] = $newFullpath;
+
+		Return $image;
+	
+	}
+
+	/**
+	 * Get the file name base on the save name
+	 * and the save type.
+	 * @param string $type image type, 'jpeg', 'png', or 'gif'
+	 * @return string the filename according to save type
+	 */
+	function getSaveFileName($type) 
+	{
+		if(!isset($_GET['file']))
+			Return null;
+
+		$filename = Files::escape(rawurldecode($_GET['file']));
+		$index = strrpos($filename,'.');
+		$base = substr($filename,0,$index);
+		$ext = strtolower(substr($filename,$index+1,strlen($filename)));
+
+		if($type == 'jpeg' && !($ext=='jpeg' || $ext=='jpg'))
+		{
+			Return $base.'.jpeg';
+		}
+		if($type=='png' && $ext != 'png')
+			Return $base.'.png';
+		if($type=='gif' && $ext != 'gif')
+			Return $base.'.gif';
+
+		Return $filename;
+	}
+
+	/**
+	 * Get the default save file name, used by editor.php.
+	 * @return string a suggestive filename, this should be unique
+	 */
+	function getDefaultSaveFile() 
+	{
+		if(isset($_GET['img']))
+			$relative = rawurldecode($_GET['img']);
+		else
+			Return null;
+
+		Return $this->getUniqueFilename($relative);
+	}
+
+	/**
+	 * Get a unique filename. If the file exists, the filename
+	 * base is appended with an increasing integer.
+	 * @param string $relative the relative filename to the base_dir
+	 * @return string a unique filename in the current path
+	 */
+	function getUniqueFilename($relative) 
+	{
+		$fullpath = $this->manager->getFullPath($relative);
+		
+		$pathinfo = pathinfo($fullpath);
+
+		$path = Files::fixPath($pathinfo['dirname']);
+		$file = Files::escape($pathinfo['basename']);
+		
+		$filename = $file;
+
+		$dotIndex = strrpos($file, '.');
+		$ext = '';
+
+		if(is_int($dotIndex)) 
+		{
+			$ext = substr($file, $dotIndex);
+			$base = substr($file, 0, $dotIndex);
+		}
+
+		$counter = 0;
+		while(is_file($path.$filename)) 
+		{
+			$counter++;
+			$filename = $base.'_'.$counter.$ext;
+		}
+		
+		Return $filename;
+		
+	}
+
+	/**
+	 * Specifiy the original relative path, a new filename
+	 * and return the new filename with relative path.
+	 * i.e. $pathA (-filename) + $file
+	 * @param string $pathA the relative file
+	 * @param string $file the new filename
+	 * @return string relative path with the new filename
+	 */
+	function makeRelative($pathA, $file) 
+	{
+		$index = strrpos($pathA,'/');
+		if(!is_int($index))
+			Return $file;
+
+		$path = substr($pathA, 0, $index);
+		Return Files::fixPath($path).$file;
+	}
+
+	/**
+	 * Get the action GET parameter
+	 * @return string action parameter
+	 */
+	function getAction() 
+	{
+		$action = null;
+		if(isset($_GET['action']))
+			$action = $_GET['action'];
+		Return $action;
+	}
+
+	/**
+	 * Generate a unique string based on md5(microtime()).
+	 * Well not so uniqe, as it is limited to 6 characters
+	 * @return string unique string.
+	 */
+    function uniqueStr()
+    {
+      return substr(md5(microtime()),0,6);
+    }
+
+	/**
+	 * Create unique tmp image file name.
+	 * The filename is based on the tmp file prefix
+	 * specified in config.inc.php plus 
+	 * the UID (basically a md5 of the remote IP)
+	 * and some random 6 character string.
+	 * This function also calls to clean up the tmp files.
+	 * @param string $file the fullpath to a file
+	 * @return string a unique filename for that path
+	 * NOTE: it only returns the filename, path no included.
+	 */
+	function createUnique($file) 
+	{
+		$pathinfo = pathinfo($file);
+		$path = Files::fixPath($pathinfo['dirname']);
+		$imgType = $this->getImageType($file);
+
+		$unique_str = $this->manager->getTmpPrefix().$this->_uid.'_'.$this->uniqueStr().".".$imgType;
+
+	   //make sure the the unique temp file does not exists
+        while (file_exists($path.$unique_str))
+        {
+            $unique_str = $this->manager->getTmpPrefix().$this->_uid.'_'.$this->uniqueStr().".".$imgType;
+        }
+
+		$this->cleanUp($path,$pathinfo['basename']);
+
+		Return $unique_str;
+	}
+
+	/**
+	 * Delete any tmp image files.
+	 * @param string $path the full path 
+	 * where the clean should take place.
+	 */
+	function cleanUp($path,$file) 
+	{
+		$path = Files::fixPath($path);
+
+		if(!is_dir($path))
+			Return false;
+
+		$d = @dir($path);
+		
+		$tmp = $this->manager->getTmpPrefix();
+		$tmpLen = strlen($tmp);
+
+		$prefix = $tmp.$this->_uid;
+		$len = strlen($prefix);
+
+		while (false !== ($entry = $d->read())) 
+		{
+			//echo $entry."<br>";
+			if(is_file($path.$entry) && $this->manager->isTmpFile($entry))
+			{
+				if(substr($entry,0,$len)==$prefix && $entry != $file)
+					Files::delFile($path.$entry);
+				else if(substr($entry,0,$tmpLen)==$tmp && $entry != $file)
+				{
+					if(filemtime($path.$entry)+$this->lapse_time < time())
+						Files::delFile($path.$entry);
+				}
+			}
+		}
+		$d->close();
+	}
+
+	/**
+	 * Get the image type base on an image file.
+	 * @param string $file the full path to the image file.
+	 * @return string of either 'gif', 'jpeg', 'png' or 'bmp'
+	 * otherwise it will return null.
+	 */
+	function getImageType($file) 
+	{
+		$imageInfo = @getImageSize($file);
+
+		if(!is_array($imageInfo))
+			Return null;
+
+		switch($imageInfo[2]) 
+		{
+			case 1:
+				Return 'gif';
+			case 2:
+				Return 'jpeg';
+			case 3:
+				Return 'png';
+			case 6:
+				Return 'bmp';
+		}
+
+		Return null;
+	}
+
+	/**
+	 * Check if the specified image can be edit by GD
+	 * mainly to check that GD can read and save GIFs
+	 * @return int 0 if it is not a GIF file, 1 is GIF is editable, -1 if not editable.
+	 */
+	function isGDEditable() 
+	{
+		if(isset($_GET['img']))
+			$relative = rawurldecode($_GET['img']);
+		else
+			Return 0;
+		if(IMAGE_CLASS != 'GD')
+			Return 0;
+
+		$fullpath = $this->manager->getFullPath($relative);
+
+		$type = $this->getImageType($fullpath);
+		if($type != 'gif')
+			Return 0;
+
+		if(function_exists('ImageCreateFrom'+$type)
+			&& function_exists('image'+$type))
+			Return 1;
+		else
+			Return -1;
+	}
+
+	/**
+	 * Check if GIF can be edit by GD.
+	 * @return int 0 if it is not using the GD library, 1 is GIF is editable, -1 if not editable.
+	 */
+	function isGDGIFAble() 
+	{
+		if(IMAGE_CLASS != 'GD')
+			Return 0;
+
+		if(function_exists('ImageCreateFromGif')
+			&& function_exists('imagegif'))
+			Return 1;
+		else
+			Return -1;
+	}
+}
+
+?>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.