Parcourir la source

Commit extras and externals for ZF 1.12.3

git-svn-id: http://framework.zend.com/svn/framework/standard/tags/release-1.12.3@25291 44c647ce-9c0f-0410-b52a-842ac1e357ba
matthew il y a 13 ans
Parent
commit
3e31137181
100 fichiers modifiés avec 12232 ajouts et 0 suppressions
  1. 105 0
      extras/documentation/manual/en/Makefile.in
  2. 50 0
      extras/documentation/manual/en/README
  3. 87 0
      extras/documentation/manual/en/configure.in
  4. 47 0
      extras/documentation/manual/en/html.xsl.in
  5. 20 0
      extras/documentation/manual/en/manual-lint.xml.in
  6. 48 0
      extras/documentation/manual/en/manual.xml.in
  7. 90 0
      extras/documentation/manual/en/module_specs/ZendX_Console_Process_Unix.xml
  8. 235 0
      extras/documentation/manual/en/module_specs/ZendX_JQuery-Form.xml
  9. 386 0
      extras/documentation/manual/en/module_specs/ZendX_JQuery-View-Helpers.xml
  10. 321 0
      extras/documentation/manual/en/module_specs/ZendX_JQuery-View-JQuery.xml
  11. 20 0
      extras/documentation/manual/en/module_specs/ZendX_JQuery-View.xml
  12. 29 0
      extras/documentation/manual/en/module_specs/ZendX_JQuery.xml
  13. 22 0
      extras/documentation/manual/en/xinclude.mod
  14. 174 0
      extras/library/ZendX/Application/Resource/Jquery.php
  15. 38 0
      extras/library/ZendX/Console/Exception.php
  16. 38 0
      extras/library/ZendX/Console/Process/Exception.php
  17. 658 0
      extras/library/ZendX/Console/Process/Unix.php
  18. 597 0
      extras/library/ZendX/Db/Adapter/Firebird.php
  19. 39 0
      extras/library/ZendX/Db/Adapter/Firebird/Exception.php
  20. 369 0
      extras/library/ZendX/Db/Statement/Firebird.php
  21. 40 0
      extras/library/ZendX/Db/Statement/Firebird/Exception.php
  22. 38 0
      extras/library/ZendX/Exception.php
  23. 157 0
      extras/library/ZendX/JQuery.php
  24. 76 0
      extras/library/ZendX/JQuery/Controller/Action/Helper/AutoComplete.php
  25. 32 0
      extras/library/ZendX/JQuery/Exception.php
  26. 67 0
      extras/library/ZendX/JQuery/Form.php
  27. 39 0
      extras/library/ZendX/JQuery/Form/Decorator/AccordionContainer.php
  28. 39 0
      extras/library/ZendX/JQuery/Form/Decorator/AccordionPane.php
  29. 67 0
      extras/library/ZendX/JQuery/Form/Decorator/DialogContainer.php
  30. 39 0
      extras/library/ZendX/JQuery/Form/Decorator/TabContainer.php
  31. 39 0
      extras/library/ZendX/JQuery/Form/Decorator/TabPane.php
  32. 149 0
      extras/library/ZendX/JQuery/Form/Decorator/UiWidgetContainer.php
  33. 178 0
      extras/library/ZendX/JQuery/Form/Decorator/UiWidgetElement.php
  34. 31 0
      extras/library/ZendX/JQuery/Form/Decorator/UiWidgetElementMarker.php
  35. 157 0
      extras/library/ZendX/JQuery/Form/Decorator/UiWidgetPane.php
  36. 39 0
      extras/library/ZendX/JQuery/Form/Element/AutoComplete.php
  37. 39 0
      extras/library/ZendX/JQuery/Form/Element/ColorPicker.php
  38. 39 0
      extras/library/ZendX/JQuery/Form/Element/DatePicker.php
  39. 39 0
      extras/library/ZendX/JQuery/Form/Element/Slider.php
  40. 39 0
      extras/library/ZendX/JQuery/Form/Element/Spinner.php
  41. 180 0
      extras/library/ZendX/JQuery/Form/Element/UiWidget.php
  42. 11 0
      extras/library/ZendX/JQuery/Form/Exception.php
  43. 32 0
      extras/library/ZendX/JQuery/View/Exception.php
  44. 171 0
      extras/library/ZendX/JQuery/View/Helper/AccordionContainer.php
  45. 80 0
      extras/library/ZendX/JQuery/View/Helper/AccordionPane.php
  46. 308 0
      extras/library/ZendX/JQuery/View/Helper/AjaxLink.php
  47. 89 0
      extras/library/ZendX/JQuery/View/Helper/AutoComplete.php
  48. 73 0
      extras/library/ZendX/JQuery/View/Helper/ColorPicker.php
  49. 135 0
      extras/library/ZendX/JQuery/View/Helper/DatePicker.php
  50. 74 0
      extras/library/ZendX/JQuery/View/Helper/DialogContainer.php
  51. 167 0
      extras/library/ZendX/JQuery/View/Helper/JQuery.php
  52. 862 0
      extras/library/ZendX/JQuery/View/Helper/JQuery/Container.php
  53. 164 0
      extras/library/ZendX/JQuery/View/Helper/Slider.php
  54. 73 0
      extras/library/ZendX/JQuery/View/Helper/Spinner.php
  55. 132 0
      extras/library/ZendX/JQuery/View/Helper/TabContainer.php
  56. 74 0
      extras/library/ZendX/JQuery/View/Helper/TabPane.php
  57. 84 0
      extras/library/ZendX/JQuery/View/Helper/UiWidget.php
  58. 105 0
      extras/library/ZendX/JQuery/View/Helper/UiWidgetPane.php
  59. 61 0
      extras/tests/AllTests.php
  60. 51 0
      extras/tests/TestConfiguration.php.dist
  61. 85 0
      extras/tests/TestHelper.php
  62. 67 0
      extras/tests/ZendX/AllTests.php
  63. 61 0
      extras/tests/ZendX/Application/AllTests.php
  64. 59 0
      extras/tests/ZendX/Application/Resource/AllTests.php
  65. 200 0
      extras/tests/ZendX/Application/Resource/JqueryTest.php
  66. 61 0
      extras/tests/ZendX/Console/AllTests.php
  67. 59 0
      extras/tests/ZendX/Console/Process/AllTests.php
  68. 201 0
      extras/tests/ZendX/Console/Process/UnixTest.php
  69. 220 0
      extras/tests/ZendX/Db/Adapter/FirebirdTest.php
  70. 54 0
      extras/tests/ZendX/Db/Adapter/SkipTests.php
  71. 187 0
      extras/tests/ZendX/Db/AllTests.php
  72. 76 0
      extras/tests/ZendX/Db/Profiler/FirebirdTest.php
  73. 175 0
      extras/tests/ZendX/Db/Select/FirebirdTest.php
  74. 61 0
      extras/tests/ZendX/Db/SkipTests.php
  75. 49 0
      extras/tests/ZendX/Db/Statement/FirebirdTest.php
  76. 63 0
      extras/tests/ZendX/Db/Table/FirebirdTest.php
  77. 128 0
      extras/tests/ZendX/Db/Table/Relationships/FirebirdTest.php
  78. 101 0
      extras/tests/ZendX/Db/Table/Row/FirebirdTest.php
  79. 34 0
      extras/tests/ZendX/Db/Table/Rowset/FirebirdTest.php
  80. 174 0
      extras/tests/ZendX/Db/Table/Select/FirebirdTest.php
  81. 69 0
      extras/tests/ZendX/Db/Table/TestSetup.php
  82. 127 0
      extras/tests/ZendX/Db/TestSetup.php
  83. 218 0
      extras/tests/ZendX/Db/TestUtil/Firebird.php
  84. 63 0
      extras/tests/ZendX/JQuery/AllTests.php
  85. 70 0
      extras/tests/ZendX/JQuery/AutoCompleteActionHelperTest.php
  86. 52 0
      extras/tests/ZendX/JQuery/Form/AllTests.php
  87. 406 0
      extras/tests/ZendX/JQuery/Form/DecoratorTest.php
  88. 239 0
      extras/tests/ZendX/JQuery/Form/ElementTest.php
  89. 13 0
      extras/tests/ZendX/JQuery/Form/_files/expected/uiwidgetcontainer/with_content.html
  90. 138 0
      extras/tests/ZendX/JQuery/JQueryTest.php
  91. 184 0
      extras/tests/ZendX/JQuery/View/AccordionContainerTest.php
  92. 247 0
      extras/tests/ZendX/JQuery/View/AjaxLinkTest.php
  93. 73 0
      extras/tests/ZendX/JQuery/View/AllTests.php
  94. 63 0
      extras/tests/ZendX/JQuery/View/AutoCompleteTest.php
  95. 63 0
      extras/tests/ZendX/JQuery/View/ColorPickerTest.php
  96. 103 0
      extras/tests/ZendX/JQuery/View/DatePickerTest.php
  97. 69 0
      extras/tests/ZendX/JQuery/View/DialogContainerTest.php
  98. 90 0
      extras/tests/ZendX/JQuery/View/SliderTest.php
  99. 59 0
      extras/tests/ZendX/JQuery/View/SpinnerTest.php
  100. 129 0
      extras/tests/ZendX/JQuery/View/TabContainerTest.php

+ 105 - 0
extras/documentation/manual/en/Makefile.in

@@ -0,0 +1,105 @@
+#
+# Zend Framework
+#
+# LICENSE
+#
+# This source file is subject to the new BSD license that is bundled
+# with this package in the file LICENSE.txt.
+# It is also available through the world-wide-web at this URL:
+# http://framework.zend.com/license/new-bsd
+# If you did not receive a copy of the license and are unable to
+# obtain it through the world-wide-web, please send an email
+# to license@zend.com so we can send you a copy immediately.
+#
+# @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+# @license    http://framework.zend.com/license/new-bsd     New BSD License
+#
+
+#
+# Makefile - build Zend Framework product and documentation
+#
+# Main targets:
+#  all - render DocBook manual in HTML.
+#  clean - remove staged files.
+#  check - validate DocBook manual using xmllint.
+#  check1 - validate one DocBook XML file using xmllint.
+#    Requires that you set the XMLFILE variable.
+#
+
+# -- parameters you are likely to want to change --
+
+# XMLFILE is the name of one DocBook XML file that you want to
+#   test with xmllint, using the 'check1' target.
+
+XEP=@XEP@
+XINC=@XINC@
+FOP=@FOP@
+XSLTPROC=@XSLTPROC@
+XMLLINT=@XMLLINT@
+ECSRC=@ECSRC@
+HERE=@HERE@
+
+DOCBOOK_DTD=http://framework.zend.com/docbook/xml/4.5/docbookx.dtd
+DOCBOOK_XSL=http://framework.zend.com/docbook-xsl/htmlhelp/htmlhelp.xsl
+DOCBOOK_FO_XSL=http://framework.zend.com/docbook-xsl/fo/docbook.xsl
+HTML_XSL=html.xsl
+MANUAL_XML=manual.xml
+MANUAL_LINT_XML=manual-lint.xml.in
+MODULE=module_specs
+XMLFILE=
+
+all:	$(MANUAL_XML) html
+
+# Build the docs in HTML format
+
+html: html/index.html
+
+html/index.html: $(MANUAL_XML) $(HTML_XSL)
+	@echo "Rendering the whole manual with $(XSLTPROC)..."
+	$(XSLTPROC) --xinclude --output html/index.html $(HTML_XSL) $(MANUAL_XML)
+	@echo "Copying manual figures (recursively)..."
+	-[ -d figures ] && cp -r figures html/figures
+
+$(MANUAL_XML): $(MANUAL_XML).in
+	sed -e 's!@DOCBOOK_DTD@!$(DOCBOOK_DTD)!' $< > $@
+
+$(HTML_XSL): $(HTML_XSL).in
+	sed -e 's!@DOCBOOK_XSL@!$(DOCBOOK_XSL)!' $< > $@
+
+# Build the docs in PDF format
+
+pdf-xep: $(MANUAL_XML)
+	$(XSLTPROC) --xinclude --output ZendFramework.fo $(DOCBOOK_FO_XSL) $(MANUAL_XML)
+	"$(XEP)" -fo ZendFramework.fo -pdf ZendFramework.pdf
+
+check: $(MANUAL_XML)
+	@echo "Checking the whole manual with $(XMLLINT)..."
+	@$(XMLLINT) --xinclude --output _temp_manual.xml $(MANUAL_XML)
+	@$(XMLLINT) --valid --noout --postvalid _temp_manual.xml \
+	    && echo "OK"
+
+check1: $(MANUAL_LINT_XML)
+	@if [ -n "$(XMLFILE)" ] ; then \
+	    if [ -f "$(MODULE)/$(XMLFILE)" ] ; then \
+		echo "Checking $(XMLFILE) with $(XMLLINT)..." ; \
+		sed -e 's!@XMLFILE@!$(MODULE)/$(XMLFILE)!' -e 's!@DOCBOOK_DTD@!$(DOCBOOK_DTD)!' $(MANUAL_LINT_XML) \
+		| $(XMLLINT) --xinclude --output _temp_$(XMLFILE) - ; \
+		$(XMLLINT) --valid --noout --postvalid _temp_$(XMLFILE) \
+		  && echo "OK" ; \
+	    else  \
+		echo "File $(MODULE)/$(XMLFILE) not found." ; \
+	    fi ; \
+	else \
+	    echo "Please specify a filename, e.g. 'make XMLFILE=filename.xml lint'" ; \
+	fi
+
+clean:
+	-rm -f html/*.html html/HTML.manifest
+	-rm -Rf html/figures
+	-rm -f _temp_*.xml
+
+cleanall: clean
+	-rm -f config.* configure
+	-rm -rf autom4te.cache
+	-rm -f Makefile
+	-rm -f $(HTML_XSL) $(MANUAL_XML)

+ 50 - 0
extras/documentation/manual/en/README

@@ -0,0 +1,50 @@
+Required software:
+
+- autoconf
+- make
+- xsltproc
+- xmllint
+
+On Windows, you should use Cygwin software or another port of GNU 
+development tools.
+
+How to build the DocBook documentation:
+
+- run "autoconf" in this dir
+- run "./configure" in this dir
+- run "make"
+
+The HTML files are rendered in the "html" dir.
+
+When developing content, you can verify your changes by running:
+
+  "make check"
+
+This verifies the XML for the whole manual is valid.
+
+You can verify your changes in a single file by running:
+
+  "make XMLFILE=filename.xml check1"
+
+The filename.xml is relative to the "module_specs" directory.
+
+DocBook resources:
+
+http://www.ibiblio.org/godoy/sgml/docbook/howto/index.html
+http://opensource.bureau-cornavin.com/crash-course/index.html
+http://ds9a.nl/docbook/
+http://www.sagehill.net/docbookxsl/index.html
+http://docbook.org/tdg/en/html/part2.html DocBook tag reference
+
+
+Also a CHM project file is prepared to create CHM help files on the fly.
+You need to install the MsHtmlHelpWorkshop.
+
+To build the CHM file from within the commandshell go to the directory
+where your html files are build by using make as described before.
+Then call:
+ "C:/path/to/workshop/hhc htmlhelp.hhp"
+where "C:/path/to/workshop/" is the path to you installation of MsHtmlHelpWorkshop
+
+This will build a "Zend_Framework_LANGUAGE.chm" file.
+Within the file you will find a index and in future also a table of content.

+ 87 - 0
extras/documentation/manual/en/configure.in

@@ -0,0 +1,87 @@
+AC_INIT(Makefile.in)
+AC_COPYRIGHT([Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)])
+
+XINC=xinc
+XEP=xep
+FOP=fop
+XSLTPROC=xsltproc
+XMLLINT=xmllint
+
+AC_ARG_WITH(xep, [  --with-xep   Where to find RenderX XEP],
+	[
+		if test "x$withval" != "xno"; then
+			XEP="$withval"
+		fi
+	]
+)
+AC_PATH_PROG(XEP,  $XEP)
+
+AC_ARG_WITH(xinc, [  --with-xinc  Where to find lunasil XINC],
+	[
+		if test "x$withval" != "xno"; then
+			XINC="$withval"
+		fi
+	]
+)
+AC_PATH_PROG(XINC, $XINC)
+
+AC_ARG_WITH(fop, [  --with-fop  Where to find Apache FOP],
+	[
+		if test "x$withval" != "xno"; then
+			FOP="$withval"
+		fi
+	]
+)
+AC_PATH_PROG(FOP,  $FOP)
+
+AC_ARG_WITH(xsltproc, [  --with-xsltproc  Where to find xsltproc],
+	[
+		if test "x$withval" != "xno"; then
+			XSLTPROC="$withval"
+		fi
+	]
+)
+AC_PATH_PROG(XSLTPROC,  $XSLTPROC)
+
+AC_ARG_WITH(xmllint, [  --with-xmllint  Where to find xmllint],
+	[
+		if test "x$withval" != "xno"; then
+			XMLLINT="$withval"
+		fi
+	]
+)
+AC_PATH_PROG(XMLLINT,  $XMLLINT)
+
+ECSRC=../trunk
+AC_ARG_WITH(ecsrc, [  --with-ecsrc  Where to find the ecelerity source],
+	[
+		if test "x$withval" != "xno"; then
+			ECSRC="$withval"
+		fi
+	]
+)
+
+AC_SUBST(XINC)
+AC_SUBST(XEP)
+AC_SUBST(FOP)
+AC_SUBST(XSLTPROC)
+AC_SUBST(XMLLINT)
+AC_SUBST(ECSRC)
+HERE=`pwd`
+AC_SUBST(HERE)
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+
+cat > config.nice <<EOT
+#!/bin/sh
+./configure \
+    --with-ecsrc='$ECSRC' \
+    --with-xsltproc='$XSLTPROC' \
+    --with-xmllint='$XMLLINT' \
+    --with-fop='$FOP' \
+    --with-xinc='$XINC' \
+    --with-xep='$XEP'
+
+EOT
+chmod +x config.nice
+

+ 47 - 0
extras/documentation/manual/en/html.xsl.in

@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"   
+				version="1.0">
+
+<xsl:import href="@DOCBOOK_XSL@"/>
+	<xsl:param name="use.extensions">0</xsl:param>
+	<xsl:param name="use.id.as.filename">1</xsl:param>
+	<xsl:param name="base.dir">./</xsl:param>
+	<xsl:param name="chunk.fast">1</xsl:param>
+	<xsl:param name="make.valid.html">1</xsl:param>
+	<xsl:param name="section.autolabel">1</xsl:param>
+	<xsl:param name="generate.index">1</xsl:param>
+	<xsl:param name="section.label.includes.component.label">1</xsl:param>
+	<xsl:param name="chunker.output.indent">yes</xsl:param>
+	<xsl:param name="chunker.output.encoding">UTF-8</xsl:param>
+	<xsl:param name="chunk.first.sections">0</xsl:param>
+	<xsl:param name="chunk.tocs.and.lots">0</xsl:param>
+	<xsl:param name="html.extra.head.links">1</xsl:param>
+	<xsl:param name="generate.manifest">1</xsl:param>
+	<xsl:param name="admon.graphics">1</xsl:param>
+	<xsl:param name="admon.style"></xsl:param>
+	<xsl:param name="html.stylesheet">dbstyle.css</xsl:param>
+	<xsl:param name="header.rule">0</xsl:param>
+	<xsl:param name="footer.rule">0</xsl:param>
+          <xsl:param name="htmlhelp.chm" select="'Zend_Framework_EN.chm'"/>
+          <xsl:param name="htmlhelp.hhc.binary" select="0"/>
+          <xsl:param name="htmlhelp.hhc.folders.instead.books" select="0"/>
+          <xsl:param name="toc.section.depth" select="4"/>
+
+<xsl:template name="user.header.navigation">
+  <!-- stuff put here appears before the top navigation area -->
+</xsl:template>
+
+<xsl:template name="user.footer.navigation">
+  <!-- stuff put here appears after the bottom navigation area -->
+  <xsl:element name="div">
+    <xsl:attribute name="class">revinfo</xsl:attribute>
+    <xsl:value-of select="//pubdate[1]"/>
+  </xsl:element>
+</xsl:template>
+
+
+</xsl:stylesheet>
+<!--
+vim:se ts=2 sw=2 et:
+-->

+ 20 - 0
extras/documentation/manual/en/manual-lint.xml.in

@@ -0,0 +1,20 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+    "@DOCBOOK_DTD@"
+[
+    <!ENTITY % xinclude SYSTEM "xinclude.mod">
+    %xinclude;
+]>
+<book id="manual" lang="en">
+    <chapter>
+        <title>XMLLint</title>
+        <xi:include href="@XMLFILE@">
+            <xi:fallback>
+                Cannot find file "@XMLFILE@"
+            </xi:fallback>
+        </xi:include>
+    </chapter>
+</book>
+<!--
+vim:se ts=4 sw=4 et:
+-->

+ 48 - 0
extras/documentation/manual/en/manual.xml.in

@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+    "@DOCBOOK_DTD@"
+[
+    <!ENTITY % xinclude SYSTEM "xinclude.mod">
+    %xinclude;
+]>
+<book id="manual" lang="en">
+    <bookinfo>
+        <title>Programmer's Reference Guide</title>
+        <subtitle>Zend Framework - Extras Library</subtitle>
+        <edition>Programmer's Reference Guide for Zend Framework</edition>
+        <pubdate><?dbtimestamp format="Y-m-d"?></pubdate>
+        <copyright>
+            <year>2005-<?dbtimestamp format="Y"?></year>
+            <holder>
+                Zend Technologies Inc.
+                (<ulink url="http://www.zend.com" />)
+            </holder>
+        </copyright>
+        <!--
+        A Title page graphic can be included like this
+            <mediaobject>
+              <imageobject>
+                <imagedata fileref="../web/images/foo.jpg"/>
+              </imageobject>
+            </mediaobject>
+        -->
+    </bookinfo>
+
+    <chapter id="zendx.console.process.unix">
+        <title>ZendX_Console_Process_Unix</title>
+        <xi:include href="module_specs/ZendX_Console_Process_Unix.xml" />
+    </chapter>
+
+    <chapter id="zendx.jquery">
+        <title>ZendX_JQuery</title>
+        <xi:include href="module_specs/ZendX_JQuery.xml" />
+        <xi:include href="module_specs/ZendX_JQuery-View.xml" />
+        <xi:include href="module_specs/ZendX_JQuery-Form.xml" />
+    </chapter>
+
+    <index id="the.index" />
+</book>
+<!--
+vim:se ts=4 sw=4 et:
+-->

+ 90 - 0
extras/documentation/manual/en/module_specs/ZendX_Console_Process_Unix.xml

@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zendx.console.process.unix.overview">
+    <title>ZendX_Console_Process_Unix</title>
+
+    <sect2 id="zendx.console.process.unix.introduction">
+        <title>Introduction</title>
+        <para>
+            <classname>ZendX_Console_Process_Unix</classname> allows developers to spawn
+            an object as a new process, and so do multiple tasks in parallel on
+            console environments. Through its specific nature, it is only
+            working on *nix based systems like Linux, Solaris, Mac/OSx and such.
+            Additionally, the <code>shmop_*</code>, <code>pcntl_*</code> and
+            <code>posix_*</code> modules are required for this component to
+            run. If one of the requirements is not met, it will throw an
+            exception after instantiating the component.
+        </para>
+    </sect2>
+
+    <sect2 id="zendx.console.process.unix.basic">
+        <title>Basic usage of ZendX_Console_Process_Unix</title>
+        <para>
+            <classname>ZendX_Console_Process_Unix</classname> is an abstract class, which
+            requires the user to extend it. It has a single abstract method
+            called <methodname>_run()</methodname> which has to be implemented to create a
+            working process. It also comes with multiple methods for checking
+            the alive status and share variables between the parent and the
+            child process.
+        </para>
+
+        <para>
+            The <methodname>_run()</methodname> method and every method which is called
+            by it is executed by the child process. Every other method which is
+            called directly by the parent is executed by the parent process.
+        </para>
+
+        <para>
+            <methodname>setVariable()</methodname> and <methodname>getVariable()</methodname> can be
+            used from both the parent- and the child process to share variables.
+            To observe the alive status, the child process should call
+            <methodname>_setAlive()</methodname> in a frequent interval, so that the parent
+            process can check the last alive time via <methodname>getLastAlive()</methodname>.
+            To get the PID of the child process, the parent can call
+            <methodname>getPid()</methodname>.
+        </para>
+
+        <example id="zendx.console.process.unix.example">
+            <title>Basic example for processing</title>
+            <para>
+                This example illustrates a basic child process
+            </para>
+
+            <programlisting language="php"><![CDATA[
+class MyProcess extends ZendX_Console_Process_Unix
+{
+    protected function _run()
+    {
+        for ($i = 0; $i < 10; $i++) {
+            // Doing something really important which can't wait: sleeping
+            sleep(1);
+        }
+    }
+}
+
+// This part should last about 10 seconds, not 20.
+$process1 = new MyProcess();
+$process1->start();
+
+$process2 = new MyProcess();
+$process2->start();
+
+while ($process1->isRunning() || $process2->isRunning()) {
+    sleep(1);
+}
+
+echo 'All processes completed';
+]]></programlisting>
+
+            <para>
+                In this example a process is forked twice and executed. As every
+                process runs 10 seconds, the parent process will be finished after
+                10 seconds (and not 20).
+            </para>
+        </example>
+
+    </sect2>
+</sect1>
+<!--
+vim:se ts=4 sw=4 et:
+-->

+ 235 - 0
extras/documentation/manual/en/module_specs/ZendX_JQuery-Form.xml

@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zendx.jquery.form">
+    <title>ZendX_JQuery Form Elements and Decorators</title>
+
+    <para>All View Helpers are pressed into Zend_Form elements or decorators also. They can even be
+        easily integrated into your already existing forms. To enable a Form for Zend_JQuery support
+        you can use two ways: Init your form as <code>$form = new ZendX_JQuery_Form();</code> or
+        use the static method <methodname>ZendX_JQuery::enableForm($form)</methodname> to enable jQuery element support.
+    </para>
+
+    <sect2 id="zendx.jquery.form.usage">
+        <title>General Elements and Decorator Usage</title>
+
+        <para>Both elements and decorators of the Zend jQuery Form set can be initialized with
+            the option key <code>jQueryParams</code> to set certain jQuery object related parameters.
+            This jQueryParams array of options matches to the <varname>$params</varname> variable
+            of the corresponding view helpers. For example:</para>
+
+        <programlisting language="php"><![CDATA[
+$element = new ZendX_JQuery_Form_Element_DatePicker(
+                    'dp1',
+                    array('jQueryParams' => array('defaultDate' => '2007/10/10'))
+                );
+// would internally call to:
+$view->datePicker("dp1", "", array('defaultDate' => '2007/10/10'), array());
+]]></programlisting>
+
+        <para>Additionally elements jQuery options can be customized by the following methods:</para>
+
+        <itemizedlist>
+            <listitem><para><methodname>setJQueryParam($name, $value)</methodname>: Set the jQuery option <varname>$name</varname> to
+                    the given value.</para></listitem>
+            <listitem><para><methodname>setJQueryParams($params)</methodname>: Set key value pairs of jQuery options and merge
+                    them with the already set options.</para></listitem>
+            <listitem><para><methodname>getJQueryParam($name)</methodname>: Return the jQuery option with the given name.</para></listitem>
+            <listitem><para><methodname>getJQueryParams()</methodname>: Return an array of all currently set jQuery options.</para></listitem>
+        </itemizedlist>
+
+        <para>Each jQuery related Decorator also owns a <methodname>getJQueryParams()</methodname> method, to set options you have to
+            use the <methodname>setDecorators()</methodname>, <methodname>addDecorator()</methodname> or <methodname>addDecorators()</methodname> functionality
+            of a form element and set the jQueryParams key as option:</para>
+
+        <programlisting language="php"><![CDATA[
+$form->setDecorators(array(
+    'FormElements',
+    array('AccordionContainer', array(
+        'id'          => 'tabContainer',
+        'style'       => 'width: 600px;',
+        'jQueryParams' => array(
+            'alwaysOpen' => false,
+            'animated'   => "easeslide"
+        ),
+    )),
+    'Form'
+));
+]]></programlisting>
+    </sect2>
+
+    <sect2 id="zendx.jquery.form.elements">
+        <title>Form Elements</title>
+
+        <para>The Zend Framework jQuery Extras Extension comes with the following Form Elements:</para>
+
+        <itemizedlist>
+            <listitem><para><code>ZendX_JQuery_Form_Element_AutoComplete</code>: Proxy to AutoComplete View Helper</para></listitem>
+            <listitem><para><code>ZendX_JQuery_Form_Element_ColorPicker</code>: Proxy to ColorPicker View Helper</para></listitem>
+            <listitem><para><code>ZendX_JQuery_Form_Element_DatePicker</code>: Proxy to DatePicker View Helper</para></listitem>
+            <listitem><para><code>ZendX_JQuery_Form_Element_Slider</code>: Proxy to Slider View Helper</para></listitem>
+            <listitem><para><code>ZendX_JQuery_Form_Element_Spinner</code>: Proxy to Spinner View Helper</para></listitem>
+        </itemizedlist>
+
+        <note id="zendx.jquery.form.elements.markerinterface">
+            <title>jQuery Decorators: Beware the Marker Interface for UiWidgetElements</title>
+
+            <para>By default all the jQuery Form elements use the <code>ZendX_JQuery_Form_Decorator_UiWidgetElement</code> decorator
+                for rendering the jQuery element with its specific view helper. This decorator is inheritly different
+                from the ViewHelper decorator that is used for most of the default form elements in Zend_Form.
+                To ensure that rendering works correctly for jQuery form elements at least one decorator has to
+                implement the <code>ZendX_JQuery_Form_Decorator_UiWidgetElementMarker</code> interface, which
+                the default decorator does. If no marker interface is found an exception is thrown. Use the marker
+                interface if you want to implement your own decorator for the jQuery form element specific rendering.
+            </para>
+        </note>
+    </sect2>
+
+    <sect2 id="zendx.jquery.form.decorators">
+        <title>Form Decorators</title>
+
+        <para>The following Decorators come with the Zend Framework jQuery Extension:</para>
+
+        <itemizedlist>
+            <listitem><para><code>ZendX_JQuery_Form_Decorator_AccordionContainer</code>: Proxy to AccordionContainer View Helper</para></listitem>
+            <listitem><para><code>ZendX_JQuery_Form_Decorator_AccordionPane</code>: Proxy to AccordionPane View Helper</para></listitem>
+            <listitem><para><code>ZendX_JQuery_Form_Decorator_DialogContainer</code>: Proxy to DialogContainer View Helper</para></listitem>
+            <listitem><para><code>ZendX_JQuery_Form_Decorator_TabContainer</code>: Proxy to TabContainer View Helper</para></listitem>
+            <listitem><para><code>ZendX_JQuery_Form_Decorator_TabPane</code>: Proxy to TabPane View Helper</para></listitem>
+            <listitem><para><code>ZendX_JQuery_Form_Decorator_UiWidgetElement</code>: Decorator to Display jQuery Form Elements</para></listitem>
+        </itemizedlist>
+
+        <para>Utilizing the Container elements is a bit more complicated, the following example builds a Form with 2 SubForms in a TabContainer:</para>
+
+        <example id="zendx.jquery.form.decorators.tabexample">
+            <title>SubForms with TabContainer Decorator</title>
+
+            <para>The following example makes use of all Form elements and wraps them into 2 subforms that are decorated with a tab container. First
+                we build the basic <code>ZendX_JQuery_Form</code>:</para>
+
+            <programlisting language="php"><![CDATA[
+$form = new ZendX_JQuery_Form();
+$form->setAction('formdemo.php');
+$form->setAttrib('id', 'mainForm');
+$form->setAttrib('class', 'flora');
+
+$form->setDecorators(array(
+    'FormElements',
+    array('TabContainer', array(
+        'id'          => 'tabContainer',
+        'style'       => 'width: 600px;',
+    )),
+    'Form',
+));
+]]></programlisting>
+
+            <para>Setting the Form Id (in this case to 'mainForm') is an important step for the TabContainer. It is needed that the subforms can relate
+                to the Container Id in a later form building stage. We now initialize two SubForms that will be decorated with the <code>TabPane</code>
+                decorators:</para>
+
+            <programlisting language="php"><![CDATA[
+$subForm1 = new ZendX_JQuery_Form();
+$subForm1->setDecorators(array(
+    'FormElements',
+    array('HtmlTag',
+          array('tag' => 'dl')),
+    array('TabPane',
+          array('jQueryParams' => array('containerId' => 'mainForm',
+                                        'title' => 'DatePicker and Slider')))
+));
+
+$subForm2 = new ZendX_JQuery_Form();
+$subForm2->setDecorators(array(
+   'FormElements',
+   array('HtmlTag',
+         array('tag' => 'dl')),
+   array('TabPane',
+         array('jQueryParams' => array('containerId' => 'mainForm',
+                                       'title' => 'AutoComplete and Spinner')))
+));
+]]></programlisting>
+
+            <para>In this stage it is important that the <code>'containerId'</code> option is set in each SubForm TabPane, or the subforms
+                cannot relate back to the tab Container and would not be displayed. To enforce this setting, an exception of the type <code>ZendX_JQuery_Exception</code>
+                is thrown if the option is not set. We can now add all the desired elements to the subforms:</para>
+
+            <programlisting language="php"><![CDATA[
+// Add Element Date Picker
+$elem = new ZendX_JQuery_Form_Element_DatePicker(
+                "datePicker1", array("label" => "Date Picker:")
+            );
+$elem->setJQueryParam('dateFormat', 'dd.mm.yy');
+$subForm1->addElement($elem);
+
+// Add Element Spinner
+$elem = new ZendX_JQuery_Form_Element_Spinner(
+                "spinner1", array('label' => 'Spinner:')
+            );
+$elem->setJQueryParams(array('min' => 0, 'max' => 1000, 'start' => 100));
+$subForm1->addElement($elem);
+
+// Add Slider Element
+$elem = new ZendX_JQuery_Form_Element_Slider(
+                "slider1", array('label' => 'Slider:')
+            );
+$elem->setJQueryParams(array('defaultValue' => '75'));
+$subForm2->addElement($elem);
+
+// Add Autocomplete Element
+$elem = new ZendX_JQuery_Form_Element_AutoComplete(
+                "ac1", array('label' => 'Autocomplete:')
+            );
+$elem->setJQueryParams(array('source' => array('New York',
+                                             'Berlin',
+                                             'Bern',
+                                             'Boston')));
+$subForm2->addElement($elem);
+
+// Submit Button
+$elem = new Zend_Form_Element_Submit("btn1", array('value' => 'Submit'));
+$subForm1->addElement($elem);
+]]></programlisting>
+
+            <para>Three additional lines are missing to put it all together and we have a jQuery animated form:</para>
+
+            <programlisting language="php"><![CDATA[
+$form->addSubForm($subForm1, 'subform1');
+$form->addSubForm($subForm2, 'subform2');
+
+$formString = $form->render($view);
+]]></programlisting>
+        </example>
+
+        <example id="zendx.jquery.form.decorators.dialogexample">
+            <title>Wrapping a Form into the Dialog Container</title>
+
+            <para>The only use for the Dialog Container in Zend Form context is to wrap itself around a form and
+            display it in a dialog. Its important to remember that the order of the decorators has to be different than in the Accordion and
+            Tab Container examples.</para>
+
+            <programlisting language="php"><![CDATA[
+// Create new jQuery Form
+$form = new ZendX_JQuery_Form();
+$form->setAction('formdemo.php');
+
+// Wrap the complete form inside a Dialog box
+$form->setDecorators(array(
+    'FormElements',
+    'Form',
+    array('DialogContainer', array(
+        'id'          => 'tabContainer',
+        'style'       => 'width: 600px;',
+        'jQueryParams' => array(
+            'tabPosition' => 'top'
+        ),
+    )),
+));
+
+// Add Element Spinner
+$elem = new ZendX_JQuery_Form_Element_Spinner("spinner1", array('label' => 'Spinner:', 'attribs' => array('class' => 'flora')));
+$elem->setJQueryParams(array('min' => 0, 'max' => 1000, 'start' => 100));
+
+$form->addElement($elem);
+]]></programlisting>
+        </example>
+    </sect2>
+</sect1>

+ 386 - 0
extras/documentation/manual/en/module_specs/ZendX_JQuery-View-Helpers.xml

@@ -0,0 +1,386 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect2 id="zendx.jquery.view.helpers">
+    <title>JQuery Helpers</title>
+
+    <sect3 id="zendx.jquery.view.helpers.ajaxlink">
+        <title>AjaxLink Helper</title>
+
+        <para>The AjaxLink helper uses jQuery's ajax capabilities to offer the creation of links that do ajax requests and
+            inject the response into a chosen DOM element. It also offers the possibility to append simple jQuery effects
+            to both the link and the response DOM element. A simple example introduces its functionality:</para>
+
+        <programlisting language="php"><![CDATA[
+<!-- Inside your View Object -->
+<div id="container"></div>
+<?php echo $this->view->ajaxLink("Link Name",
+                          "url.php",
+                          array('update' => '#container')); ?>
+]]></programlisting>
+
+        <para>This example creates a link with the label "Link Name" that fires an ajax request to url.php
+            upon click and renders the response into the div container "#container". The function header
+            for the ajaxLink is as follows: <code>function ajaxLink($label, $url, $options, $params);</code>
+            The options array is very powerful and offers you lots of functionality to customize your
+            ajax requests.</para>
+
+        <para>Available options are:</para>
+
+        <table id="zendx.jquery.view.helpers.ajaxlink.table">
+            <title>AjaxLink options</title>
+            <tgroup cols="4">
+                <thead>
+                    <row>
+                        <entry>Option</entry>
+                        <entry>Data Type</entry>
+                        <entry>Default Value</entry>
+                        <entry>Description</entry>
+                    </row>
+                </thead>
+                <tbody>
+                    <row>
+                        <entry><code>update</code></entry>
+                        <entry><code>string</code></entry>
+                        <entry><code>false</code></entry>
+                        <entry>
+                            Container to inject response content into, use jQuery CSS Selector syntax, ie. "#container" or ".box"
+                        </entry>
+                    </row>
+                    <row>
+                        <entry><code>method</code></entry>
+                        <entry><code>string</code></entry>
+                        <entry><code>Implicit GET or POST</code></entry>
+                        <entry>Request method, is implicitly chosen as GET when no parameters given and POST when parameters given.</entry>
+                    </row>
+                    <row>
+                        <entry><code>complete</code></entry>
+                        <entry><code>string</code></entry>
+                        <entry><code>false</code></entry>
+                        <entry>Javascript callback executed, when ajax request is complete. This option allows for shortcut effects, see next section.</entry>
+                    </row>
+                    <row>
+                        <entry><code>beforeSend</code></entry>
+                        <entry><code>string</code></entry>
+                        <entry><code>false</code></entry>
+                        <entry>Javascript callback executed right before ajax request is started. This option allows for shortcut effects, see next section.</entry>
+                    </row>
+                    <row>
+                        <entry><code>noscript</code></entry>
+                        <entry><code>boolean</code></entry>
+                        <entry><code>true</code></entry>
+                        <entry>If true the link generated will contain a href attribute to the given link for non-javascript enabled browsers. If false href will resolve to "#".</entry>
+                    </row>
+                    <row>
+                        <entry><code>dataType</code></entry>
+                        <entry><code>string</code></entry>
+                        <entry><code>html</code></entry>
+                        <entry>What type of data is the Ajax Response of? Possible are Html, Text, Json. Processing Json responses has to be done with custom "complete" callback functions.</entry>
+                    </row>
+                    <row>
+                        <entry><code>attribs</code></entry>
+                        <entry><code>array</code></entry>
+                        <entry><code>null</code></entry>
+                        <entry>Additional HTML attributes the ajaxable link should have.</entry>
+                    </row>
+                    <row>
+                        <entry><code>title, id, class</code></entry>
+                        <entry><code>string</code></entry>
+                        <entry><code>false</code></entry>
+                        <entry>Convenience shortcuts for HTML Attributes.</entry>
+                    </row>
+                    <row>
+                        <entry><code>inline</code></entry>
+                        <entry><code>boolean</code></entry>
+                        <entry><code>false</code></entry>
+                        <entry>Although far from best practice, you can set javascript for this link inline in "onclick" attribute.</entry>
+                    </row>
+                  </tbody>
+              </tgroup>
+          </table>
+
+          <para>To enlighten the usage of this helper it is best to show another bunch of more complex examples. This
+            example assumes that you have only one view object that you want to display and don't care a lot about
+            html best practices, since we have to output the jQuery environment just before the closing body tag.</para>
+
+          <programlisting language="php"><![CDATA[
+<html>
+    <head>
+        <title>Zend Framework jQuery AjaxLink Example</title>
+        <script language="javascript"
+                type="text/javascript"
+                src="myCallbackFuncs.js"></script>
+    </head>
+
+    <body>
+        <!-- without echoing jQuery this following -->
+        <!-- list only prints a list of for links -->
+        <ul>
+            <li>
+                <?php echo $this->ajaxLink("Example 1",
+                                           "/ctrl/action1",
+                                           array('update' => '#content',
+                                                 'noscript' => false,
+                                                 'method' => 'POST')); ?>
+            </li>
+            <li>
+                <?php echo $this->ajaxLink("Example 2",
+                                           "/ctrl/action2",
+                                           array('update' => '#content',
+                                                 'class' => 'someLink'),
+                                           array('param1' => 'value1',
+                                                 'param2' => 'value2')); ?>
+            </li>
+            <li><?php echo $this->ajaxLink("Example 3",
+                                           "/ctrl/action3",
+                                           array('dataType' => 'json',
+                                                 'complete' =>
+                                                    'alert(data)')); ?>
+            </li>
+            <li><?php echo $this->ajaxLink("Example 4",
+                                           "/ctrl/action4",
+                                           array('beforeSend' => 'hide',
+                                                 'complete' => 'show')); ?>
+            </li>
+            <li>
+                <?php echo $this->ajaxLink("Example 5",
+                                           "/ctrl/action5",
+                                           array(
+                                            'beforeSend' =>
+                                             'myBeforeSendCallbackJsFunc();',
+                                            'complete' =>
+                                             'myCompleteCallbackJsFunc(data);')
+                                           ); ?>
+            </li>
+        </ul>
+
+        <!-- only at this point the javascript is printed to sreen -->
+        <?php echo $this->jQuery(); ?>
+    </body>
+</html>
+]]></programlisting>
+
+          <para>You might have already seen that the 'update', 'complete', and 'beforeSend' options have to be executed in specific order and syntax so that you cannot
+              use those callbacks and override their behaviour completely when you are using <methodname>ajaxLink()</methodname>. For larger use cases you will probably want to
+              write the request via jQuery on your own. The primary use case for the callbacks is effect usage, other uses may very well become hard to maintain.
+              As shown in Example Link 5, you can also forward the beforeSend/complete Callbacks to your own javascript functions.</para>
+
+          <sect4 id="zendx.jquery.view.helpers.ajaxlink.effects">
+            <title>Shortcut Effects</title>
+
+            <para>You can use shortcut effect names to make your links actions more fancy. For example the Container that will contain
+                the ajax response may very well be invisible in the first place. Additionally you can use shortcut effects on the link
+                to hide it after clicking. The following effects can be used for callbacks:</para>
+
+            <itemizedlist>
+                <listitem><para><code>complete</code> callback: 'show', 'showslow', 'shownormal', 'showfast', 'fadein', 'fadeinslow',
+                'fadeinfast', 'slidedown', 'slidedownslow', 'slidedownfast'. These all correspond to the jQuery effects
+                fadeIn(), show() and slideDown() and will be executed on the container specified in <code>update</code>.</para></listitem>
+
+                <listitem><para><code>beforeSend</code> callback: 'fadeout', 'fadeoutslow', 'fadeoutfast', 'hide',
+                'hideslow', 'hidefast', 'slideup'. These correspond to the jQuery effects fadeOut(), hide(), slideUp() and
+                are executed on the clicked link.</para></listitem>
+            </itemizedlist>
+
+            <programlisting language="php"><![CDATA[
+<?php echo $this->ajaxLink("Example 6",
+                           "/ctrl/action6",
+                           array('beforeSend' => 'hide',
+                                 'complete' => 'show')); ?>
+]]></programlisting>
+          </sect4>
+    </sect3>
+
+    <sect3 id="zendx.jquery.view.helpers.ui">
+        <title>jQuery UI Library Helpers</title>
+
+        <para>The jQuery UI Library offers a range of layout and form specific widgets that are integrated into the
+            Zend Framework via View Helpers. The form-elements are easy to handle and will be described first, whereas
+            the layout specific widgets are a bit more complex to use.</para>
+
+        <sect4 id="zendx.jquery.view.helpers.ui.form">
+            <title>jQuery UI Form Helpers</title>
+
+            <para>The method signature for all form view helpers closely resembles the Dojo View helpers signature,
+                <methodname>helper($id, $value, $params, $attribs)</methodname>. A description of the parameters follows:</para>
+
+            <itemizedlist>
+                <listitem><para><varname>$id</varname>: Will act as the identifier name for the helper element inside a form. If in the attributes
+                        no id element is given, this will also become the form element id, that has to be unique across
+                        the DOM.</para></listitem>
+                <listitem><para><varname>$value</varname>: Default value of the element.</para></listitem>
+                <listitem><para><varname>$params</varname>: Widget specific parameters that customize the look and feel
+                        of the widget. These options are unique to each widget and <ulink url="http://docs.jquery.com/UI">
+                        described in the jQuery UI documentation</ulink>. The data is casted to JSON, so make sure
+                        to use the <classname>Zend_Json_Expr</classname> class to mark executable javascript as safe.</para></listitem>
+                <listitem><para><varname>$attribs</varname>: HTML Attributes of the Form Helper</para></listitem>
+            </itemizedlist>
+
+            <para>The following UI widgets are available as form view helpers. Make sure you use the correct
+                version of jQuery UI library to be able to use them. The Google CDN always offers you the latest
+                released version.</para>
+
+            <itemizedlist>
+                <listitem><para><methodname>autoComplete($id, $value, $params, $attribs)</methodname>: The AutoComplete View helper
+                    is part of jQuery UI since version 1.8 and creates a text field and registeres
+                    it to have auto complete functionality. The completion data source has to be given as jQuery
+                    related parameters 'url' or 'data' as described in the jQuery UI manual.
+                </para></listitem>
+                <listitem><para><methodname>colorPicker($id, $value, $params, $attribs)</methodname>: ColorPicker is still
+                a ZendX_JQuery element for legacy reason, but was removed from jQuery UI completly.
+                </para></listitem>
+                <listitem><para><methodname>datePicker($id, $value, $params, $attribs)</methodname>: Create a DatePicker
+                    inside a text field. This widget is available since jQuery UI 1.5 and can therefore currently be used
+                    with the Google CDN. Using the 'handles' option to create multiple handles overwrites the default set value
+                    and the jQuery parameter 'startValue' internally inside the view helper.</para></listitem>
+                <listitem><para><methodname>slider($id, $value, $params, $attribs)</methodname>: Create a Sliding element
+                    that updates its value into a hidden form field. Available since jQuery UI 1.5.</para></listitem>
+                <listitem><para><methodname>spinner($id, $value, $params, $attribs)</methodname>: Create a Spinner element
+                    that can spin through numeric values in a specified range. This element was removed from
+                    the 1.6 jQuery UI release and has not been re-released yet.</para></listitem>
+            </itemizedlist>
+
+            <example id="zendx.jquery.view.helpers.form.example">
+                <title>Showing jQuery Form View Helper Usage</title>
+
+                <para>In this example we want to simulate a fictional web application that offers auctions
+                    on travel locations. A user may specify a city to travel, a start and end date, and a
+                    maximum amount of money he is willing to pay. Therefore we need an autoComplete field
+                    for all the currently known travel locations, a date picker for start and end dates
+                    and a spinner to specify the amount.</para>
+
+                <programlisting language="php"><![CDATA[
+<form method="post" action="bid.php">
+    <label for="locaction">Where do you want to travel?</label>
+    <?php echo $this->autoComplete("location",
+                                   "",
+                                   array('source' => array('New York',
+                                                         'Mexico City',
+                                                         'Sydney',
+                                                         'Ruegen',
+                                                         'Baden Baden'))); ?>
+    <br />
+
+    <label for="startDate">Travel Start Date:</label>
+    <?php echo $this->datePicker("startDate", '',
+             array(
+                'defaultDate' => '+7',
+                'minDate' => '+7',
+                'onClose' => new Zend_Json_Expr('myJsonFuncCechkingValidity'))); ?>
+    <br />
+
+    <label for="startDate">Travel End Date:</label>
+    <?php echo $this->datePicker("endDate", '',
+             array(
+                'defaultDate' => '+14',
+                'minDate' => '+7',
+                'onClose' => new Zend_Json_Expr('myJsonFuncCechkingValidity'))); ?>
+    <br />
+
+    <label for="bid">Your Bid:</label>
+    <?php echo $this->spinner("bid",
+                              "",
+                              array('min' => 1205.50,
+                                    'max' => 10000,
+                                    'start' => 1205.50,
+                                    'currency' => '€')); ?>
+    <br />
+
+    <input type="submit" value="Bid!" />
+</form>
+]]></programlisting>
+
+                <para>You can see the use of jQuery UI Widget specific parameters. These all correspond to those given in the jQuery UI docs
+                    and are converted to JSON and handed through to the view script.</para>
+            </example>
+        </sect4>
+
+        <sect4 id="zendx.jquery.view.helpers.ui.actionhelper">
+            <title>Using an Action Helper to Send Data to AutoComplete</title>
+
+            <para>The jQuery UI Autocomplete Widget can load data from a remote location
+                rather than from an javascript array, making its usage really useful. Zend
+                Framework currently providers a bunch of server-side AutoComplete
+                Helpers and there is one for jQuery too. You register the helper
+                to the controller helper broker and it takes care of disabling layouts
+                and renders an array of data correctly to be read by the AutoComplete field.
+                To use the Action Helper you have to put this rather long statement into
+                your bootstrap or Controller initialization function:
+            </para>
+
+            <programlisting language="php"><![CDATA[
+Zend_Controller_Action_HelperBroker::addHelper(
+    new ZendX_JQuery_Controller_Action_Helper_AutoComplete()
+);
+]]></programlisting>
+
+            <para>You can then directly call the helper to render AutoComplete Output in
+            your Controller</para>
+
+            <programlisting language="php"><![CDATA[
+class MyIndexController extends Zend_Controller_Action
+{
+    public function autocompleteAction()
+    {
+        // The data sent via the ajax call is inside $_GET['q']
+        $filter = $_GET['q'];
+
+        // Disable Layout and stuff, just displaying AutoComplete Information.
+        $this->_helper->autoComplete(array("New York", "Bonn", "Tokio"));
+    }
+}
+]]></programlisting>
+        </sect4>
+
+        <sect4 id="zendx.jquery.view.helpers.ui.layout">
+            <title>jQuery UI Layout Helpers</title>
+
+            <para>There is a wide range of Layout helpers that the UI library offers. The ones covered by Zend Framework view helpers are
+                Accordion, Dialog, Tabs. Dialog is the most simple one, whereas Accordion and Tab extend a common abstract class and
+                offer a secondary view helper for pane generation. The following view helpers exist in the jQuery view helpers collection,
+                an example accompanies them to show their usage.</para>
+
+            <itemizedlist>
+                <listitem><para><methodname>dialogContainer($id, $content, $params, $attribs)</methodname>: Create a Dialog Box that is rendered with
+                        the given content.on startup. If the option 'autoOpen' set to false is specified the box will not be displayed
+                        on load but can be shown with the additional <methodname>dialog("open")</methodname> javascript function. See UI docs
+                        for details.</para></listitem>
+                <listitem><para><methodname>tabPane($id, $content, $options)</methodname>: Add a new pane to a tab container with the given <varname>$id</varname>.
+                        The given <varname>$content</varname> is shown in this tab pane. To set the title use <varname>$options['title']</varname>.
+                        If <varname>$options['contentUrl']</varname> is set, the content of the tab is requested via ajax on tab activation.
+                    </para></listitem>
+                <listitem><para><methodname>tabContainer($id, $params, $attribs)</methodname>: Render a tab container with all the currently registered
+                        panes. This view helper also offers to add panes with the following syntax:
+                        <code>$this->tabContainer()->addPane($id, $label, $content, $options)</code>.
+                    </para></listitem>
+                <listitem><para><methodname>accordionPane($id, $content, $options)</methodname>: Add a new pane to the accordion container with the given <varname>$id</varname>.
+                        The given <varname>$content</varname> is shown in this tab pane. To set the title use <varname>$options['title']</varname>.
+                    </para></listitem>
+                <listitem><para><methodname>accordionContainer($id, $params, $attribs)</methodname>: Render an accordion container with all the currently registered
+                        panes. This view helper also offers to add panes with the following syntax:
+                        <code>$this->accordionContainer()->addPane($id, $label, $content, $options)</code>.
+                    </para></listitem>
+            </itemizedlist>
+
+            <example id="zendx.jquery.view.helpers.ui.layout.example">
+                <title>Showing the latest news in a Tab Container</title>
+
+                <para>For this example we assume the developer already wrote the controller and model side of the script and assigned
+                    an array of news items to the view script. This array contains at most 5 news elements, so we don't have to care
+                    about the tab container getting to many tabs.</para>
+
+                <programlisting language="php"><![CDATA[
+<?php foreach($this->news AS $article): ?>
+<?php $this->tabPane("newstab",
+                     $article->body,
+                     array('title' => $article->title)); ?>
+<?php endforeach; ?>
+
+<h2>Latest News</h2>
+<?php echo $this->tabContainer("newstab",
+                               array(),
+                               array('class' => 'flora')); ?>
+]]></programlisting>
+            </example>
+        </sect4>
+    </sect3>
+</sect2>

+ 321 - 0
extras/documentation/manual/en/module_specs/ZendX_JQuery-View-JQuery.xml

@@ -0,0 +1,321 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect2 id="zendx.jquery.view.jquery">
+    <title>jQuery() View Helper</title>
+
+    <para>
+        The <methodname>jQuery()</methodname> view helper simplifies setup of your jQuery environment
+        in your application. It takes care of loading the core and ui library dependencies if necessary
+        and acts as a stack for all the registered onLoad javascript statements. All jQuery view helpers
+        put their javascript code onto this stack. It acts as a collector for everything jQuery in your
+        application with the following responsibilities:
+    </para>
+
+    <itemizedlist>
+        <listitem><para>Handling deployment of CDN or a local path jQuery Core
+                and UI libraries.</para></listitem>
+        <listitem><para>Handling <ulink url="http://api.jquery.com/ready">$(document).ready()</ulink> events.</para></listitem>
+        <listitem><para>Specifying additional stylesheet themes to use.</para></listitem>
+    </itemizedlist>
+
+    <para>
+        The <methodname>jQuery()</methodname> view helper implementation, like its <methodname>dojo()</methodname> pendant,
+        follows the placeholder architecture implementation; the data set in it persists between view
+        objects, and may be directly echo'd from your layout script. Since views specified in a Zend_Layout
+        script file are rendered before the layout itself, the <methodname>jQuery()</methodname> helper can act as a
+        stack for jQuery statements and render them into the head segment of the html page.
+    </para>
+
+    <para>Contrary to Dojo, themes cannot be loaded from a CDN for the jQuery UI widgets and have to be implemented
+        in your pages stylesheet file or loaded from an extra stylesheet file. A default theme called Flora can be
+        obtained from the jQuery UI downloadable file.</para>
+
+    <example id="zend.jquery.view.jquery.usage">
+        <title>jQuery() View Helper Example</title>
+
+        <para>
+            In this example a jQuery environment using the core and UI libraries will be needed. UI Widgets should
+            be rendered with the Flora thema that is installed in 'public/styles/flora.all.css'. The jQuery libraries
+            are both loaded from local paths.
+        </para>
+
+        <para>
+            To register the jQuery functionality inside the view object, you have to add the appropriate helpers
+            to the view helper path. There are many ways of accomplishing this, based on the requirements that the
+            jQuery helpers have. If you need them in one specific view only, you can use the addHelperPath method
+            on initialization of this view, or right before rendering:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$view->addHelperPath('ZendX/JQuery/View/Helper/', 'ZendX_JQuery_View_Helper');
+]]></programlisting>
+
+        <para>If you need them throughout your application, you can register them in your bootstrap
+            file using access to the Controller Plugin ViewRenderer:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$view = new Zend_View();
+$view->addHelperPath('ZendX/JQuery/View/Helper/', 'ZendX_JQuery_View_Helper');
+
+$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
+$viewRenderer->setView($view);
+Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
+]]></programlisting>
+
+        <para>Now in the view script we want to display a Date Picker and an Ajax based Link.</para>
+
+        <programlisting language="php"><![CDATA[
+<?php echo $this->ajaxLink("Show me something",
+                    "/hello/world",
+                    array('update' => '#content'));?>
+
+<div id="content"></div>
+
+<form method="post" action="/hello/world">
+Pick your Date: <?php echo $this->datePicker("dp1",
+                                             '',
+                                             array(
+                                                'defaultDate' =>
+                                                    date('Y/m/d', time())));?>
+<input type="submit" value="Submit" />
+</form>
+]]></programlisting>
+
+        <para>Both helpers now stacked some javascript statements on the jQuery helper and printed a link and
+            a form element respectively. To access the javascript we have to utilize the jQuery()
+            functionality. Both helpers already activated their dependencies that is they have called
+            <methodname>jQuery()->enable()</methodname> and <methodname>jQuery()->uiEnable()</methodname>. We only have to print
+            the jQuery() environment, and we choose to do so in the layout script's head segment:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+<html>
+    <head>
+        <title>A jQuery View Helper Example</title>
+        <?php echo $this->jQuery(); ?>
+    </head>
+
+    <body>
+        <?php echo $this->layout()->content; ?>
+    </body>
+</html>
+]]></programlisting>
+
+        <para>Although <code>$this->layout()->content;</code> is printed behind the <code>$this->jQuery()</code> statement,
+            the content of the view script is rendered before. This way all the javascript onLoad code has already been put
+            on the onLoad stack and can be printed within the head segment of the html document.
+        </para>
+    </example>
+
+    <sect3 id="zendx.jquery.view.jquery.noconflict">
+        <title>jQuery NoConflict Mode</title>
+
+        <para>jQuery offers a noConflict mode that allows the library to be run side by side with other javascript libraries
+            that operate in the global namespace, Prototype for example. The Zend Framework jQuery View Helper makes usage of
+            the noConflict mode very easy. If you want to run Prototype and jQuery side by side you can call
+            <code>ZendX_JQuery_View_Helper_JQuery::enableNoConflictMode();</code> and all jQuery helpers will operate in the No Conflict
+            Mode.</para>
+
+        <example id="zend.jquery.view.jquery.noconflict">
+            <title>Building your own Helper with No Conflict Mode</title>
+
+            <para>To make use of the NoConflict Mode in your own jQuery helper, you only have to use the static method
+                <methodname>ZendX_JQuery_View_Helper_JQuery::getJQueryHandler()</methodname> method. It returns the variable jQuery is operating
+                in at the moment, either <code>$</code> or <varname>$j</varname>
+            </para>
+
+            <programlisting language="php"><![CDATA[
+class MyHelper_SomeHelper extends Zend_View_Helper_Abstract
+{
+    public function someHelper()
+    {
+        $jquery = $this->view->jQuery();
+        $jquery->enable(); // enable jQuery Core Library
+
+        // get current jQuery handler based on noConflict settings
+        $jqHandler = ZendX_JQuery_View_Helper_JQuery::getJQueryHandler();
+
+        $function = '("#element").click(function() '
+                  . '{ alert("noConflict Mode Save Helper!"); }'
+                  . ')';
+        $jquery->addOnload($jqHandler . $function);
+        return '';
+    }
+}
+]]></programlisting>
+        </example>
+    </sect3>
+
+    <sect3 id="zendx.jquery.view.jquery.themes">
+        <title>jQuery UI Themes</title>
+
+        <para>Since there are no online available themes to use out of the box, the implementation of the UI library themes
+            is a bit more complex than with the Dojo helper. The jQuery UI documentation describes for each component
+            what stylesheet information is needed and the Default and Flora Themes from the downloadable archive give hints
+            on the usage of stylesheets. The jQuery helper offers the function <code>jQuery()->addStylesheet($path);</code>
+            function to include the dependant stylesheets whenever the helper is enabled and rendered. You can optionally
+            merge the required stylesheet information in your main stylesheet file.
+        </para>
+    </sect3>
+
+    <sect3 id="zendx.jquery.view.jquery.methods">
+        <title>Methods Available</title>
+
+        <para>
+            The <methodname>jQuery()</methodname> view helper always returns an instance of
+            the jQuery placeholder container. That container object has the
+            following methods available:
+        </para>
+
+        <sect4 id="zendx.jquery.view.jquery.methods.core">
+            <title>jQuery Core Library methods</title>
+            <itemizedlist>
+                <listitem><para><methodname>enable()</methodname>: explicitly enable jQuery
+                        integration.</para></listitem>
+                <listitem><para><methodname>disable()</methodname>: disable jQuery
+                        integration.</para></listitem>
+                <listitem><para><methodname>isEnabled()</methodname>: determine whether or not
+                        jQuery integration is enabled.</para></listitem>
+                <listitem><para><methodname>setVersion()</methodname>: set the jQuery version
+                        that is used. This also decides on the library loaded
+                        from the Google Ajax Library CDN</para></listitem>
+                <listitem><para><methodname>getVersion()</methodname>: get the current jQuery
+                        that is used. This also decides on the library loaded
+                        from the Google Ajax Library CDN</para></listitem>
+                <listitem><para><methodname>useCdn()</methodname>: Return true, if CDN usage is
+                        currently enabled</para></listitem>
+                <listitem><para><methodname>useLocalPath()</methodname>: Return true, if local usage
+                        is currently enabled</para></listitem>
+                <listitem><para><methodname>setLocalPath()</methodname>: Set the local path to the
+                        jQuery Core library</para></listitem>
+                <listitem><para><methodname>getLocalPath()</methodname>: If set, return the local path to the
+                        jQuery Core library</para></listitem>
+            </itemizedlist>
+        </sect4>
+
+        <sect4 id="zendx.jquery.view.jquery.methods.ui">
+            <title>jQuery UI Library methods</title>
+
+            <itemizedlist>
+                <listitem><para><methodname>uiEnable()</methodname>: explicitly enable jQuery UI
+                        integration.</para></listitem>
+                <listitem><para><methodname>uiDisable()</methodname>: disable jQuery UI
+                        integration.</para></listitem>
+                <listitem><para><methodname>uiIsEnabled()</methodname>: determine whether or not
+                        jQuery UI integration is enabled.</para></listitem>
+                <listitem><para><methodname>setUiVersion()</methodname>: set the jQuery UI version
+                        that is used. This also decides on the library loaded
+                        from the Google Ajax Library CDN</para></listitem>
+                <listitem><para><methodname>getUiVersion()</methodname>: get the current jQuery UI
+                        that is used. This also decides on the library loaded
+                        from the Google Ajax Library CDN</para></listitem>
+                <listitem><para><methodname>useUiCdn()</methodname>: Return true, if CDN usage is
+                        currently enabled for jQuery UI</para></listitem>
+                <listitem><para><methodname>useUiLocal()</methodname>: Return true, if local usage
+                        is currently enabled for jQuery UI</para></listitem>
+                <listitem><para><methodname>setUiLocalPath()</methodname>: Set the local path to the
+                        jQuery UI library</para></listitem>
+                <listitem><para><methodname>getUiLocalPath()</methodname>: If set, get the local path
+                        to the jQuery UI library</para></listitem>
+            </itemizedlist>
+        </sect4>
+
+        <sect4 id="zendx.jquery.view.jquery.methods.other">
+            <title>jQuery Helper Utility methods</title>
+
+            <itemizedlist>
+                <listitem><para><methodname>setView(Zend_View_Interface $view)</methodname>: set
+                        a view instance in the container.</para></listitem>
+                <listitem><para><methodname>onLoadCaptureStart()</methodname>: Start capturing javascript code
+                        for jQuery onLoad execution.</para></listitem>
+                <listitem><para><methodname>onLoadCaptureEnd()</methodname>: Stop capturing</para></listitem>
+                <listitem><para><methodname>javascriptCaptureStart()</methodname>: Start capturing javascript code
+                        that has to be rendered after the inclusion of either jQuery Core or UI libraries.</para></listitem>
+                <listitem><para><methodname>javascriptCaptureEnd()</methodname>: Stop capturing.</para></listitem>
+                <listitem><para><methodname>addJavascriptFile($path)</methodname>: Add javascript file to be included after
+                                jQuery Core or UI library.</para></listitem>
+                <listitem><para><methodname>getJavascriptFiles()</methodname>: Return all currently registered
+                        additional javascript files.</para></listitem>
+                <listitem><para><methodname>clearJavascriptFiles()</methodname>: Clear the javascript files</para></listitem>
+                <listitem><para><methodname>addJavascript($statement)</methodname>: Add javascript statement to be included
+                        after jQuery Core or UI library.</para></listitem>
+                <listitem><para><methodname>getJavascript()</methodname>: Return all currently registered
+                        additional javascript statements.</para></listitem>
+                <listitem><para><methodname>clearJavascript()</methodname>: Clear the javascript statements.</para></listitem>
+                <listitem><para><methodname>addStylesheet($path)</methodname>: Add a stylesheet file that is needed
+                        for a jQuery view helper to display correctly.</para></listitem>
+                <listitem><para><methodname>getStylesheets()</methodname>: Get all currently registered
+                        additional stylesheets.</para></listitem>
+                <listitem><para><methodname>addOnLoad($statement)</methodname>: Add javascript statement that should
+                        be executed on document loading.</para></listitem>
+                <listitem><para><methodname>getOnLoadActions()</methodname>: Return all currently registered
+                        onLoad statements.</para></listitem>
+                <listitem><para><methodname>setRenderMode($mask)</methodname>: Render only a specific subset of the
+                        jQuery environment via ZendX_JQuery::RENDER_ constants. Rendering all elements
+                        is the default behaviour.</para></listitem>
+                <listitem><para><methodname>getRenderMode()</methodname>: Return the current
+                        jQuery environment rendering mode.</para></listitem>
+                <listitem><para><methodname>setCdnSsl($bool)</methodname>: Set if the CDN Google Ajax Library should be loaded
+                        from an SSL or a Non-SSL location.</para></listitem>
+            </itemizedlist>
+
+            <para>These are quite a number of methods, but many of them are used for internally by all the
+                additional view helpers and during the printing of the jQuery environment. Unless you
+                want to build your own jQuery helper or have a complex use-case, you will probably only
+                get in contact with a few methods of these.</para>
+        </sect4>
+
+    </sect3>
+
+    <sect3 id="zendx.jquery.view.jquery.refactor">
+        <title>Refactoring jQuery environment with setRenderMode()</title>
+
+        <para>Using the current setup that was described, each page of your website would show
+            a different subset of jQuery code that would be needed to keep the current jQuery related
+            items running. Also different files or stylesheets may be included depending on which
+            helpers you implemented in your application. In production stage you might want to centralize
+            all the javascript your application generated into a single file, or disable stylesheet
+            rendering because you have merged all the stylesheets into a single file and include it statically
+            in your layout. To allow a smooth refactoring you can enable or disable the rendering
+            of certain jQuery environment blocks with help of the following constants and the
+        <methodname>jQuery()->setRenderMode($bitmask)</methodname> function.</para>
+
+        <itemizedlist>
+            <listitem><para><code>ZendX_JQuery::RENDER_LIBRARY</code>: Renders jQuery Core and UI library</para></listitem>
+            <listitem><para><code>ZendX_JQuery::RENDER_SOURCES</code>: Renders additional javascript files</para></listitem>
+            <listitem><para><code>ZendX_JQuery::RENDER_STYLESHEETS</code>: Renders jQuery related stylesheets</para></listitem>
+            <listitem><para><code>ZendX_JQuery::RENDER_JAVASCRIPT</code>: Render additional javascript statements</para></listitem>
+            <listitem><para><code>ZendX_JQuery::RENDER_JQUERY_ON_LOAD</code>: Render jQuery onLoad statements</para></listitem>
+            <listitem><para><code>ZendX_JQuery::RENDER_ALL</code>: Render all previously mentioned blocks, this is default behaviour.</para></listitem>
+        </itemizedlist>
+
+        <para>
+            For an example, if you would have merged jQuery Core and UI libraries as well as other files into a single large file
+            as well as merged stylesheets to keep HTTP requests low on your production application.
+            You could disallow the jQuery helper to render those parts, but render all the other stuff
+            with the following statement in your view:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$view->jQuery()
+     ->setRenderMode(ZendX_JQuery::RENDER_JAVASCRIPT |
+                     ZendX_JQuery::RENDER_JQUERY_ON_LOAD);
+]]></programlisting>
+
+        <para>This statement makes sure only the required javascript statements and onLoad blocks of the current page are rendered by the jQuery helper.</para>
+    </sect3>
+
+    <sect3 id="zendx.jquery.view.jquery.migrations">
+        <title>Migrations</title>
+
+        <para>Prior to 1.8 the methods <methodname>setCdnVersion()</methodname>, <methodname>setLocalPath()</methodname>
+            <methodname>setUiCdnVersion()</methodname> and <methodname>setUiLocalPath()</methodname> all enabled the view
+            helper upon calling, which is considered a bug from the following perspective: If
+            you want to use the any non-default library option, you would have to manually disable the
+            jQuery helper aftwards if you only require it to be loaded in some scenarios. With version
+            1.8 the jQuery helper does only enable itsself, when <methodname>enable()</methodname> is called,
+            which all internal jQuery View helpers do upon being called.
+        </para>
+    </sect3>
+</sect2>

+ 20 - 0
extras/documentation/manual/en/module_specs/ZendX_JQuery-View.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zendx.jquery.view" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <title>ZendX_JQuery View Helpers</title>
+
+    <para>
+        Zend Framework provides jQuery related View Helpers through its Extras Library.
+        These can be enabled in two ways, adding jQuery to the view helper path:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$view->addHelperPath("ZendX/JQuery/View/Helper", "ZendX_JQuery_View_Helper");
+]]></programlisting>
+
+    <para>Or using the <methodname>ZendX_JQuery::enableView(Zend_View_Interface $view)</methodname> method
+        that does the same for you.</para>
+
+    <xi:include href="ZendX_JQuery-View-JQuery.xml" />
+    <xi:include href="ZendX_JQuery-View-Helpers.xml" />
+</sect1>

+ 29 - 0
extras/documentation/manual/en/module_specs/ZendX_JQuery.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zendx.jquery.introduction">
+    <title>Introduction</title>
+
+    <para>
+        As of version 1.7, Zend Framework integrates <ulink
+            url="http://jquery.com">jQuery</ulink> view and form helpers through
+        its extras library. The jQuery support is meant as an alternative
+         to the already existing Dojo library integration. Currently jQuery can
+         be integrated into your Zend Framework applications in the following ways:
+    </para>
+
+    <itemizedlist>
+        <listitem><para>View helper to help setup the jQuery (Core and UI) environment</para></listitem>
+        <listitem><para>jQuery UI specific Zend_View helpers</para></listitem>
+        <listitem><para>jQuery UI specific Zend_Form elements and decorators</para></listitem>
+    </itemizedlist>
+
+    <para>
+        By default the jQuery javascript dependencies are loaded from the Google Ajax Library
+        Content Distribution Network. The CDN offers both jQuery Core and jQuery UI access points and
+        the view helpers therefore can already offer you most the dependencies out of the box. Currently
+        the Google CDN offers jQuery UI support up to version 1.5.2, but the jQuery view and form helpers
+        already make use of the UI library 1.6 version (AutoComplete, ColorPicker, Spinner, Slider).
+        To make use of these great additions you have to download the release candidate version of the
+        <ulink url="http://ui.jquery.com">jQuery UI library</ulink> from its website.
+    </para>
+</sect1>

+ 22 - 0
extras/documentation/manual/en/xinclude.mod

@@ -0,0 +1,22 @@
+<!-- $Id: $ -->
+<!ELEMENT xi:include (xi:fallback?) >
+<!ATTLIST xi:include
+    xmlns:xi   CDATA       #FIXED    "http://www.w3.org/2001/XInclude"
+    href       CDATA       #REQUIRED
+    parse      (xml|text)  "xml"
+    encoding   CDATA       #IMPLIED >
+
+<!ELEMENT xi:fallback ANY>
+<!ATTLIST xi:fallback
+    xmlns:xi   CDATA   #FIXED   "http://www.w3.org/2001/XInclude" >
+
+<!ATTLIST sect1
+    xmlns:xi   CDATA   #FIXED   "http://www.w3.org/2001/XInclude" >
+    
+<!-- inside chapter or section elements -->
+<!ENTITY % local.divcomponent.mix "| xi:include">
+<!-- inside para, programlisting, literallayout, etc. -->   
+<!ENTITY % local.para.char.mix "| xi:include">
+<!-- inside bookinfo, chapterinfo, etc. -->      
+<!ENTITY % local.info.class "| xi:include"> 
+<!ENTITY % local.chapter.class "| xi:include">

+ 174 - 0
extras/library/ZendX/Application/Resource/Jquery.php

@@ -0,0 +1,174 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Application
+ * @subpackage Resource
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: Jquery.php 20240 2010-01-13 04:51:56Z matthew $
+ */
+
+/**
+ * JQuery application resource
+ *
+ * Example configuration:
+ * <pre>
+ *   resources.Jquery.noconflictmode = false        ; default
+ *   resources.Jquery.version = 1.7.1               ; <null>
+ *   resources.Jquery.localpath = "/foo/bar"
+ *   resources.Jquery.enable = true
+ *   resources.Jquery.uienable = true;
+ *   resources.Jquery.ui_enable = true;
+ *   resources.Jquery.uiversion = 0.7.7;
+ *   resources.Jquery.ui_version = 0.7.7;
+ *   resources.Jquery.uilocalpath = "/bar/foo";
+ *   resources.Jquery.ui_localpath = "/bar/foo";
+ *   resources.Jquery.cdn_ssl = false
+ *   resources.Jquery.render_mode = 255 ; default
+ *   resources.Jquery.rendermode = 255 ; default
+ *
+ *   resources.Jquery.javascriptfile = "/some/file.js"
+ *   resources.Jquery.javascriptfiles.0 = "/some/file.js"
+ *   resources.Jquery.stylesheet = "/some/file.css"
+ *   resources.Jquery.stylesheets.0 = "/some/file.css"
+ * </pre>
+ *
+ * Resource for settings JQuery options
+ *
+ * @uses       Zend_Application_Resource_ResourceAbstract
+ * @category   ZendX
+ * @package    ZendX_Application
+ * @subpackage Resource
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_Application_Resource_Jquery
+    extends Zend_Application_Resource_ResourceAbstract
+{
+    /**
+     * @var ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    protected $_jquery;
+
+    /**
+     * @var Zend_View
+     */
+    protected $_view;
+
+    /**
+     * Defined by Zend_Application_Resource_Resource
+     *
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function init()
+    {
+        return $this->getJquery();
+    }
+
+    /**
+     * Retrieve JQuery View Helper
+     *
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function getJquery()
+    {
+        if (null === $this->_jquery) {
+            $this->getBootstrap()->bootstrap('view');
+            $this->_view = $this->getBootstrap()->view;
+
+            ZendX_JQuery::enableView($this->_view);
+            $this->_parseOptions($this->getOptions());
+
+            $this->_jquery = $this->_view->jQuery();
+        }
+
+        return $this->_jquery;
+    }
+
+    /**
+     * Parse options to find those pertinent to jquery helper and invoke them
+     *
+     * @param  array $options
+     * @return void
+     */
+    protected function _parseOptions(array $options)
+    {
+        foreach ($options as $key => $value) {
+            switch(strtolower($key)) {
+                case 'noconflictmode':
+                    if (!(bool)$value) {
+                        ZendX_JQuery_View_Helper_JQuery::disableNoConflictMode();
+                    } else {
+                        ZendX_JQuery_View_Helper_JQuery::enableNoConflictMode();
+                    }
+                    break;
+                case 'version':
+                    $this->_view->JQuery()->setVersion($value);
+                    break;
+                case 'localpath':
+                    $this->_view->JQuery()->setLocalPath($value);
+                    break;
+                case 'uiversion':
+                case 'ui_version':
+                    $this->_view->JQuery()->setUiVersion($value);
+                    break;
+                case 'uilocalpath':
+                case 'ui_localpath':
+                    $this->_view->JQuery()->setUiLocalPath($value);
+                    break;
+                case 'cdn_ssl':
+                    $this->_view->JQuery()->setCdnSsl($value);
+                    break;
+                case 'render_mode':
+                case 'rendermode':
+                    $this->_view->JQuery()->setRenderMode($value);
+                    break;
+                case 'javascriptfile':
+                    $this->_view->JQuery()->addJavascriptFile($value);
+                    break;
+                case 'javascriptfiles':
+                    foreach($options['javascriptfiles'] as $file) {
+                        $this->_view->JQuery()->addJavascriptFile($file);
+                    }
+                    break;
+                case 'stylesheet':
+                    $this->_view->JQuery()->addStylesheet($value);
+                    break;
+                case 'stylesheets':
+                    foreach ($value as $stylesheet) {
+                        $this->_view->JQuery()->addStylesheet($stylesheet);
+                    }
+                    break;
+            }
+        }
+
+        if ((isset($options['uienable']) && (bool) $options['uienable'])
+            || (isset($options['ui_enable']) && (bool) $options['ui_enable'])
+            || (!isset($options['ui_enable']) && !isset($options['uienable'])))
+        {
+            $this->_view->JQuery()->uiEnable();
+        } else {
+            $this->_view->JQuery()->uiDisable();
+        }
+
+        if ((isset($options['enable']) && (bool) $options['enable'])
+           || !isset($options['enable']))
+        {
+            $this->_view->JQuery()->enable();
+        } else {
+            $this->_view->JQuery()->disable();
+        }
+    }
+}

+ 38 - 0
extras/library/ZendX/Console/Exception.php

@@ -0,0 +1,38 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category  ZendX
+ * @package   ZendX_Whois
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd     New BSD License
+ * @version   $Id$
+ */
+
+/**
+ * @see ZendX_Exception
+ */
+require_once 'ZendX/Exception.php';
+
+/**
+ * Exception class for ZendX_Console
+ *
+ * @category  ZendX
+ * @package   ZendX_Console
+ * @uses      Zend_Exception
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_Console_Exception extends ZendX_Exception
+{
+}

+ 38 - 0
extras/library/ZendX/Console/Process/Exception.php

@@ -0,0 +1,38 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category  ZendX
+ * @package   ZendX_Console
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd     New BSD License
+ * @version   $Id$
+ */
+
+/**
+ * @see ZendX_Console_Exception
+ */
+require_once 'ZendX/Console/Exception.php';
+
+/**
+ * Exception class for ZendX_Console_Process
+ *
+ * @category  ZendX
+ * @package   ZendX_Console
+ * @uses      ZendX_Console_Exception
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_Console_Process_Exception extends ZendX_Console_Exception
+{
+}

+ 658 - 0
extras/library/ZendX/Console/Process/Unix.php

@@ -0,0 +1,658 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category  ZendX
+ * @package   ZendX_Console
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd     New BSD License
+ * @version   $Id$
+ */
+
+
+/**
+ * ZendX_Console_Process_Unix allows you to spawn a class as a separated process
+ *
+ * @category  ZendX
+ * @package   ZendX_Console
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class ZendX_Console_Process_Unix
+{
+    /**
+     * Void method
+     */
+    const VOID_METHOD = 'void_method';
+
+    /**
+     * Return method
+     */
+    const RETURN_METHOD = 'void_method';
+    
+    /**
+     * Unique thread name
+     *
+     * @var string
+     */
+    private $_name;
+
+    /**
+     * PID of the child process
+     *
+     * @var integer
+     */
+    private $_pid = null;
+
+    /**
+     * UID of the child process owner
+     *
+     * @var integer
+     */
+    private $_puid = null;
+
+    /**
+     * GUID of the child process owner
+     *
+     * @var integer
+     */
+    private $_guid = null;
+
+    /**
+     * Whether the process is yet forked or not
+     *
+     * @var boolean
+     */
+    private $_isRunning = false;
+
+    /**
+     * Wether we are into child process or not
+     *
+     * @var boolean
+     */
+    private $_isChild = false;
+
+    /**
+     * A data structure to hold data for Inter Process Communications
+     *
+     * @var array
+     */
+    private $_internalIpcData = array();
+
+    /**
+     * Key to access to Shared Memory Area.
+     *
+     * @var integer
+     */
+    private $_internalIpcKey;
+
+    /**
+     * Key to access to Sync Semaphore.
+     *
+     * @var integer
+     */
+    private $_internalSemKey;
+
+    /**
+     * Is Shared Memory Area OK? If not, the start() method will block.
+     * Otherwise we'll have a running child without any communication channel.
+     *
+     * @var boolean
+     */
+    private $_ipcIsOkay;
+
+    /**
+     * Filename of the IPC segment file
+     *
+     * @var string
+     */
+    private $_ipcSegFile;
+
+    /**
+     * Filename of the semaphor file
+     *
+     * @var string
+     */
+    private $_ipcSemFile;
+
+    /**
+     * Constructor method
+     *
+     * Allocates a new pseudo-thread object. Optionally, set a PUID, a GUID and
+     * a UMASK for the child process. This also initialize Shared Memory
+     * Segments for process communications.
+     *
+     * @param  integer $puid
+     * @param  integer $guid
+     * @param  integer $umask
+     * @throws ZendX_Console_Process_Exception When running on windows
+     * @throws ZendX_Console_Process_Exception When running in web enviroment
+     * @throws ZendX_Console_Process_Exception When shmop_* functions don't exist
+     * @throws ZendX_Console_Process_Exception When pcntl_* functions don't exist
+     * @throws ZendX_Console_Process_Exception When posix_* functions don't exist
+     */
+    public function __construct($puid = null, $guid = null, $umask = null)
+    {
+        if (substr(PHP_OS, 0, 3) === 'WIN') {
+            require_once 'ZendX/Console/Process/Exception.php';
+            throw new ZendX_Console_Process_Exception('Cannot run on windows');
+        } else if (!in_array(substr(PHP_SAPI, 0, 3), array('cli', 'cgi'))) {
+            require_once 'ZendX/Console/Process/Exception.php';
+            throw new ZendX_Console_Process_Exception('Can only run on CLI or CGI enviroment');
+        } else if (!function_exists('shmop_open')) {
+            require_once 'ZendX/Console/Process/Exception.php';
+            throw new ZendX_Console_Process_Exception('shmop_* functions are required');
+        } else if (!function_exists('pcntl_fork')) {
+            require_once 'ZendX/Console/Process/Exception.php';
+            throw new ZendX_Console_Process_Exception('pcntl_* functions are required');
+        } else if (!function_exists('posix_kill')) {
+            require_once 'ZendX/Console/Process/Exception.php';
+            throw new ZendX_Console_Process_Exception('posix_* functions are required');
+        }
+    
+        $this->_isRunning = false;
+
+        $this->_name = md5(uniqid(rand()));
+        $this->_guid = $guid;
+        $this->_puid = $puid;
+
+        if ($umask !== null) {
+            umask($umask);
+        }
+
+        // Try to create the shared memory segment. The variable
+        // $this->_ipcIsOkay contains the return code of this operation and must
+        // be checked before forking
+        if ($this->_createIpcSegment() && $this->_createIpcSemaphore()) {
+            $this->_ipcIsOkay = true;
+        } else {
+            $this->_ipcIsOkay = false;
+        }
+    }
+    
+    /**
+     * Stop the child on destruction
+     */
+    public function __destruct()
+    {
+        if ($this->isRunning()) {
+            $this->stop();
+        }
+    }
+    
+    /**
+     * Causes this pseudo-thread to begin parallel execution.
+     *
+     * This method first checks of all the Shared Memory Segment. If okay, it
+     * forks the child process, attaches signal handler and returns immediatly.
+     * The status is set to running, and a PID is assigned. The result is that
+     * two pseudo-threads are running concurrently: the current thread (which
+     * returns from the call to the start() method) and the other thread (which
+     * executes its run() method).
+     * 
+     * @throws ZendX_Console_Process_Exception When SHM segments can't be created
+     * @throws ZendX_Console_Process_Exception When process forking fails
+     * @return void
+     */
+    public function start()
+    {
+        if (!$this->_ipcIsOkay) {
+            require_once 'ZendX/Console/Process/Exception.php';
+            throw new ZendX_Console_Process_Exception('Unable to create SHM segments for process communications');
+        }
+
+        // @see http://www.php.net/manual/en/function.pcntl-fork.php#41150
+        @ob_end_flush();
+        
+        pcntl_signal(SIGCHLD, SIG_IGN);
+
+        $pid = @pcntl_fork();
+        if ($pid === -1) {
+            require_once 'ZendX/Console/Process/Exception.php';
+            throw new ZendX_Console_Process_Exception('Forking process failed');
+        } else if ($pid === 0) {
+            // This is the child
+            $this->_isChild = true;
+           
+            // Sleep a second to avoid problems
+            sleep(1);
+            
+            // Install the signal handler
+            pcntl_signal(SIGUSR1, array($this, '_sigHandler'));
+
+            // If requested, change process identity
+            if ($this->_guid !== null) {
+                posix_setgid($this->_guid);
+            }
+
+            if ($this->_puid !== null) {
+                posix_setuid($this->_puid);
+            }
+
+            // Run the child
+            try {
+                $this->_run();
+            } catch (Exception $e) {
+                // We have to catch any exceptions and clean up the process,
+                // else we will have a memory leak.
+            }
+
+            // Destroy the child after _run() execution. Required to avoid
+            // unuseful child processes after execution
+            exit(0);
+        } else {
+            // Else this is the parent
+            $this->_isChild   = false;
+            $this->_isRunning = true;
+            $this->_pid       = $pid;
+        }
+    }
+    
+    /**
+     * Causes the current thread to die.
+     *
+     * The relative process is killed and disappears immediately from the
+     * processes list.
+     *
+     * @return boolean
+     */
+    public function stop()
+    {
+        $success = false;
+
+        if ($this->_pid > 0) {
+            $status = 0;
+            
+            posix_kill($this->_pid, 9);
+            pcntl_waitpid($this->_pid, $status, WNOHANG);
+            $success = pcntl_wifexited($status);
+            $this->_cleanProcessContext();
+        }
+
+        return $success;
+    }
+
+    /**
+     * Test if the pseudo-thread is already started.
+     *
+     * @return boolean
+     */
+    public function isRunning()
+    {       
+        return $this->_isRunning;
+    }
+
+    /**
+     * Set a variable into the shared memory segment, so that it can accessed
+     * both from the parent and from the child process. Variable names 
+     * beginning with underlines are only permitted to interal functions.
+     *
+     * @param  string $name
+     * @param  mixed  $value
+     * @throws ZendX_Console_Process_Exception When an invalid variable name is supplied
+     * @return void
+     */
+    public function setVariable($name, $value)
+    {
+        if ($name[0] === '_') {
+            require_once 'ZendX/Console/Process/Exception.php';
+            throw new ZendX_Console_Process_Exception('Only internal functions may use underline (_) as variable prefix');
+        }
+
+        $this->_writeVariable($name, $value);
+    }
+
+    /**
+     * Get a variable from the shared memory segment. Returns NULL if the
+     * variable doesn't exist.
+     *
+     * @param  string $name
+     * @return mixed
+     */
+    public function getVariable($name)
+    {
+        $this->_readFromIpcSegment();
+
+        if (isset($this->_internalIpcData[$name])) {
+            return $this->_internalIpcData[$name];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Read the time elapsed since the last child setAlive() call.
+     *
+     * This method is useful because often we have a pseudo-thread pool and we
+     * need to know each pseudo-thread status. If the child executes the
+     * setAlive() method, the parent with getLastAlive() can know that child is
+     * alive.
+     *
+     * @return integer
+     */
+    public function getLastAlive()
+    {
+        $pingTime = $this->getVariable('_pingTime');
+
+        return ($pingTime === null ? 0 : (time() - $pingTime));
+    }
+
+    /**
+     * Returns the PID of the current pseudo-thread.
+     *
+     * @return integer
+     */
+    public function getPid()
+    {
+        return $this->_pid;
+    }
+    
+    /**
+     * Set a pseudo-thread property that can be read from parent process
+     * in order to know the child activity.
+     *
+     * Practical usage requires that child process calls this method at regular
+     * time intervals; parent will use the getLastAlive() method to know
+     * the elapsed time since the last pseudo-thread life signals...
+     * 
+     * @return void
+     */
+    protected function _setAlive()
+    {
+        $this->_writeVariable('_pingTime', time());
+    }
+    
+
+    /**
+     * This is called from within the parent; all the communication stuff
+     * is done here.
+     *
+     * @param  string $methodName
+     * @param  array  $argList
+     * @param  string $type
+     * @return mixed
+     */
+    protected function _callCallbackMethod($methodName, array $argList = array(), $type = self::VOID_METHOD)
+    {
+        // This is the parent, so we really cannot execute the method. Check
+        // arguments passed to the method.
+        if ($type === self::RETURN_METHOD) {
+            $this->_internalIpcData['_callType'] = self::RETURN_METHOD;
+        } else {
+            $this->_internalIpcData['_callType'] = self::VOID_METHOD;
+        }
+
+        // These setting are common to both the calling types
+        $this->_internalIpcData['_callMethod'] = $methodName;
+        $this->_internalIpcData['_callInput']  = $argList;
+
+        // Write the IPC data to the shared segment
+        $this->_writeToIpcSegment();
+
+        // Now we need to differentiate a bit.
+        switch ($this->_internalIpcData['_callType']) {
+            case VOID_METHOD:
+                // Notify the child so it can process the request
+                $this->_sendSigUsr1();
+                break;
+
+            case RETURN_METHOD:
+                // Set the semaphorew
+                shmop_write($this->_internalSemKey, 1, 0);
+
+                // Notify the child so it can process the request
+                $this->_sendSigUsr1();
+
+                // Block until the child process return
+                $this->_waitForIpcSemaphore();
+
+                // Read from the SHM segment. The result is stored into
+                // $this->_internalIpcData['_callOutput']
+                $this->_readFromIpcSegment();
+
+                // Data are returned. Now we can reset the semaphore
+                shmop_write($this->_internalSemKey, 0, 1);
+
+                // Return the result. Hence no break required here
+                return $this->_internalIpcData['_callOutput'];
+        }
+    }
+    
+    /**
+     * This method actually implements the pseudo-thread logic.
+     * 
+     * @return void
+     */
+    abstract protected function _run();
+    
+    /**
+     * Sends signal to the child process
+     * 
+     * @return void
+     */
+    private function _sendSigUsr1()
+    {
+        if ($this->_pid > 0) {
+            posix_kill($this->_pid, SIGUSR1);
+        }
+    }
+    
+    /**
+     * Acutally Write a variable to the shared memory segment
+     *
+     * @param  string $name
+     * @param  mixed  $value
+     * @return void
+     */
+    private function _writeVariable($name, $value)
+    {
+        $this->_internalIpcData[$name] = $value;
+        $this->_writeToIpcSegment();
+    }
+
+    /**
+     * Destroy thread context and free relative resources.
+     * 
+     * @return void
+     */
+    private function _cleanProcessContext()
+    {
+        shmop_delete($this->_internalIpcKey);
+        shmop_delete($this->_internalSemKey);
+
+        shmop_close($this->_internalIpcKey);
+        shmop_close($this->_internalSemKey);
+
+        @unlink($this->_ipcSegFile);
+        @unlink($this->_ipcSemFile);
+
+        $this->_isRunning = false;
+        $this->_pid       = null;
+    }
+
+    /**
+     * This is the signal handler that makes the communications between client
+     * and server possible.
+     *
+     * @param  integer $signo
+     * @return void
+     */
+    private function _sigHandler($signo)
+    {
+        switch ($signo) {
+            case SIGTERM:
+                // Handle shutdown tasks. Hence no break is require
+                exit;
+
+            case SIGUSR1:
+                // This is the User-defined signal we'll use. Read the SHM segment
+                $this->_readFromIpcSegment();
+
+                if (isset($this->_internalIpcData['_callType'])) {
+                    $method = $this->_internalIpcData['_callMethod'];
+                    $params = $this->_internalIpcData['_callInput'];
+
+                    switch ($this->_internalIpcData['_callType']) {
+                        case self::VOID_METHOD:
+                            // Simple call the (void) method and return immediatly
+                            // no semaphore is placed into parent, so the processing
+                            // is async
+                            call_user_func(array($this, $method), $params);
+                            break;
+
+                        case self::RETURN_METHOD:
+                            // Process the request
+                            $this->_internalIpcData['_callOutput'] = call_user_func(array($this, $method), $params);
+
+                            // Write the result into IPC segment
+                            $this->_writeToIPCsegment();
+
+                            // Unlock the semaphore but block _writeToIpcSegment()
+                            shmop_write($this->_internalSemKey, 0, 0);
+                            shmop_write($this->_internalSemKey, 1, 1);
+                            break;
+                    }
+                }
+                break;
+                
+            default:
+                // Ignore all other singals
+                break;
+        }
+    }
+
+    /**
+     * Wait for IPC Semaphore
+     * 
+     * @return void
+     */
+    private function _waitForIpcSemaphore()
+    {
+        while (true) {
+            $okay = shmop_read($this->_internalSemKey, 0, 1);
+
+            if ($okay === 0) {
+                break;
+            }
+
+            usleep(10);
+        }
+    }
+
+    /**
+     * Read data from IPC segment
+     * 
+     * @throws ZendX_Console_Process_Exception When writing of SHM segment fails
+     * @return void
+     */
+    private function _readFromIpcSegment()
+    {
+        $serializedIpcData = shmop_read($this->_internalIpcKey,
+                                        0,
+                                        shmop_size($this->_internalIpcKey));
+
+        if ($serializedIpcData === false) {
+            require_once 'ZendX/Console/Process/Exception.php';
+            throw new ZendX_Console_Process_Exception('Fatal error while reading SHM segment');
+        }
+
+        $data = @unserialize($serializedIpcData);
+        
+        if ($data !== false) {
+            $this->_internalIpcData = $data;
+        }
+    }
+
+    /**
+     * Write data to IPC segment
+     * 
+     * @throws ZendX_Console_Process_Exception When writing of SHM segment fails
+     * @return void
+     */
+    private function _writeToIpcSegment()
+    {
+        // Read the transaction bit (2 bit of _internalSemKey segment). If it's
+        // value is 1, we're into the execution of a PHP_FORK_RETURN_METHOD, so
+        // we must not write to segment (data corruption)
+        if (shmop_read($this->_internalSemKey, 1, 1) === 1) {
+            return;
+        }
+
+        $serializedIpcData = serialize($this->_internalIpcData);
+
+        // Set the exchange array (IPC) into the shared segment
+        $shmBytesWritten = shmop_write($this->_internalIpcKey,
+                                       $serializedIpcData,
+                                       0);
+
+        // Check if lenght of SHM segment is enougth to contain data
+        if ($shmBytesWritten !== strlen($serializedIpcData)) {
+            require_once 'ZendX/Console/Process/Exception.php';
+            throw new ZendX_Console_Process_Exception('Fatal error while writing to SHM segment');
+        }
+    }
+
+    /**
+     * Create an IPC segment
+     *
+     * @throws ZendX_Console_Process_Exception When SHM segment can't be created
+     * @return boolean
+     */
+    private function _createIpcSegment()
+    {
+        $this->_ipcSegFile = realpath(sys_get_temp_dir()) . '/' . rand() . $this->_name . '.shm';
+        touch($this->_ipcSegFile);
+
+        $shmKey = ftok($this->_ipcSegFile, 't');
+        if ($shmKey === -1) {
+            require_once 'ZendX/Console/Process/Exception.php';
+            throw new ZendX_Console_Process_Exception('Could not create SHM segment');
+        }
+
+        $this->_internalIpcKey = @shmop_open($shmKey, 'c', 0644, 10240);
+
+        if (!$this->_internalIpcKey) {
+            @unlink($this->_ipcSegFile);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Create IPC semaphore
+     *
+     * @throws ZendX_Console_Process_Exception When semaphore can't be created
+     * @return boolean
+     */
+    private function _createIpcSemaphore()
+    {
+        $this->_ipcSemFile = realpath(sys_get_temp_dir()) . '/' . rand() . $this->_name . '.sem';
+        touch($this->_ipcSemFile);
+
+        $semKey = ftok($this->_ipcSemFile, 't');
+        if ($semKey === -1) {
+            require_once 'ZendX/Console/Process/Exception.php';
+            throw new ZendX_Console_Process_Exception('Could not create semaphore');
+        }
+
+        $this->_internalSemKey = @shmop_open($semKey, 'c', 0644, 10);
+
+        if (!$this->_internalSemKey) {
+            @unlink($this->_ipcSemFile);
+            return false;
+        }
+
+        return true;
+    }
+}

+ 597 - 0
extras/library/ZendX/Db/Adapter/Firebird.php

@@ -0,0 +1,597 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage Adapter
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: $
+ */
+
+/**
+ * @see Zend_Db_Adapter_Abstract
+ */
+require_once 'Zend/Db/Adapter/Abstract.php';
+
+/**
+ * @see Zend_Db_Profiler
+ */
+require_once 'Zend/Db/Profiler.php';
+
+/**
+ * @see Zend_Db_Select
+ */
+require_once 'Zend/Db/Select.php';
+
+/**
+ * @see Zend_Db_Statement_Firebird
+ */
+require_once 'ZendX/Db/Statement/Firebird.php';
+
+
+/**
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage Adapter
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_Db_Adapter_Firebird extends Zend_Db_Adapter_Abstract
+{
+    /**
+     * Specifies whether the adapter automatically quotes identifiers.
+     * If true, most SQL generated by Zend_Db classes applies
+     * identifier quoting automatically.
+     * If false, developer must quote identifiers themselves
+     * by calling quoteIdentifier().
+     *
+     * @var bool
+     */
+    protected $_autoQuoteIdentifiers = true;
+
+    /**
+     * The transaction resource.
+     *
+     * @var transaction
+     */
+    protected $_transResource = null;
+
+    /**
+     * Return the status of current transaction.
+     * @return bool
+     */
+
+    public function getTransaction()
+    {
+        return (is_resource($this->_transResource) ? $this->_transResource : null);
+    }
+
+    /**
+     * Keys are UPPERCASE SQL datatypes or the constants
+     * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
+     *
+     * Values are:
+     * 0 = 32-bit integer
+     * 1 = 64-bit integer
+     * 2 = float or decimal
+     *
+     * @var array Associative array of datatypes to values 0, 1, or 2.
+     */
+    protected $_numericDataTypes = array(
+        Zend_Db::INT_TYPE    => Zend_Db::INT_TYPE,
+        Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
+        Zend_Db::FLOAT_TYPE  => Zend_Db::FLOAT_TYPE,
+        'SMALLINT'           => Zend_Db::INT_TYPE,
+        'INT'                => Zend_Db::INT_TYPE,
+        'INTEGER'            => Zend_Db::INT_TYPE,
+        'BIGINT'             => Zend_Db::BIGINT_TYPE,
+        'INT64'              => Zend_Db::BIGINT_TYPE,
+        'DECIMAL'            => Zend_Db::FLOAT_TYPE,
+        'DOUBLE PRECISION'   => Zend_Db::FLOAT_TYPE,
+        'DOUBLE'             => Zend_Db::FLOAT_TYPE,
+        'NUMERIC'            => Zend_Db::FLOAT_TYPE,
+        'FLOAT'              => Zend_Db::FLOAT_TYPE
+    );
+
+    /**
+     * Quote a raw string.
+     *
+     * @param string $value     Raw string
+     * @return string           Quoted string
+     */
+    protected function _quote($value)
+    {
+        if (is_int($value) || is_float($value)) {
+            return $value;
+        }
+        $value = str_replace("'", "''", $value);
+        return "'" . $value . "'";
+    }
+
+    /**
+     * Returns a list of the tables in the database.
+     *
+     * @return array
+     */
+    public function listTables()
+    {
+        $data = $this->fetchCol('SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$SYSTEM_FLAG = 0');
+        foreach($data as &$v)
+            $v = trim($v);
+        return $data;
+    }
+
+    /**
+     * Returns the column descriptions for a table.
+     *
+     * The return value is an associative array keyed by the column name,
+     * as returned by the RDBMS.
+     *
+     * The value of each array element is an associative array
+     * with the following keys:
+     *
+     * SCHEMA_NAME      => string; name of database or schema
+     * TABLE_NAME       => string;
+     * COLUMN_NAME      => string; column name
+     * COLUMN_POSITION  => number; ordinal position of column in table
+     * DATA_TYPE        => string; SQL datatype name of column
+     * DEFAULT          => string; default expression of column, null if none
+     * NULLABLE         => boolean; true if column can have nulls
+     * LENGTH           => number; length of CHAR/VARCHAR
+     * SCALE            => number; scale of NUMERIC/DECIMAL
+     * PRECISION        => number; precision of NUMERIC/DECIMAL
+     * UNSIGNED         => boolean; unsigned property of an integer type
+     * PRIMARY          => boolean; true if column is part of the primary key
+     * PRIMARY_POSITION => integer; position of column in primary key
+     * IDENTITY         => integer; true if column is auto-generated with unique values
+     *
+     * @param string $tableName
+     * @param string $schemaName OPTIONAL
+     * @return array
+     */
+    public function describeTable($tableName, $schemaName = null)
+    {
+        $fieldMaps = array(
+            'TEXT'      => 'CHAR',
+            'VARYING'   => 'VARCHAR',
+            'SHORT'     => 'SMALLINT',
+            'LONG'      => 'INTEGER',
+            'FLOAT'     => 'FLOAT',
+            'INT64'     => array(0 => 'BIGINT', 'NUMERIC', 'DECIMAL'),
+            'DATE'      => 'DATE',
+            'TIME'      => 'TIME',
+            'BLOB'      => 'BLOB',
+            'DOUBLE'    => 'DOUBLE PRECISION',
+            'TIMESTAMP' => 'TIMESTAMP'
+        );
+
+        $sql = 'select
+                    RF.RDB$RELATION_NAME, \'\', RF.RDB$FIELD_NAME, T.RDB$TYPE_NAME,
+                    RF.RDB$DEFAULT_VALUE, RF.RDB$NULL_FLAG, RF.RDB$FIELD_POSITION,
+                    F.RDB$CHARACTER_LENGTH, F.RDB$FIELD_SCALE, F.RDB$FIELD_PRECISION,
+                    IXS.RDB$FIELD_POSITION, IXS.RDB$FIELD_POSITION, F.RDB$FIELD_SUB_TYPE
+                from RDB$RELATION_FIELDS RF
+                left join RDB$RELATION_CONSTRAINTS RC
+                    on (RF.RDB$RELATION_NAME = RC.RDB$RELATION_NAME and RC.RDB$CONSTRAINT_TYPE = \'PRIMARY KEY\')
+                left join RDB$INDEX_SEGMENTS IXS
+                    on (IXS.RDB$FIELD_NAME = RF.RDB$FIELD_NAME and RC.RDB$INDEX_NAME = IXS.RDB$INDEX_NAME)
+                inner join RDB$FIELDS F on (RF.RDB$FIELD_SOURCE = F.RDB$FIELD_NAME)
+                inner join RDB$TYPES T on (T.RDB$TYPE = F.RDB$FIELD_TYPE and T.RDB$FIELD_NAME = \'RDB$FIELD_TYPE\')
+                where ' . $this->quoteInto('(UPPER(RF.RDB$RELATION_NAME) = UPPER(?)) ', $tableName) . '
+                order by RF.RDB$FIELD_POSITION';
+
+        $stmt = $this->query($sql);
+
+        /**
+         * Use FETCH_NUM so we are not dependent on the CASE attribute of the PDO connection
+         */
+        $result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
+
+        $table_name      = 0;
+        $owner           = 1;
+        $column_name     = 2;
+        $data_type       = 3;
+        $data_default    = 4;
+        $nullable        = 5;
+        $column_id       = 6;
+        $data_length     = 7;
+        $data_scale      = 8;
+        $data_precision  = 9;
+        $constraint_type = 10;
+        $position        = 11;
+        $sub_type        = 12;
+
+        $desc = array();
+        foreach ($result as $key => $row) {
+            list ($primary, $primaryPosition, $identity) = array(false, null, false);
+            if (strlen($row[$constraint_type])) {
+                $primary = true;
+                $primaryPosition = $row[$position];
+                /**
+                 * Firebird does not support auto-increment keys.
+                 */
+                $identity = false;
+            }
+
+            $dataType = trim($row[$data_type]);
+            $newType = $fieldMaps[$dataType];
+            if (is_array($newType) && $dataType == 'INT64')
+                $newType = $newType[$row[$sub_type]];
+            $row[$data_type] = $newType;
+
+            $desc[trim($row[$column_name])] = array(
+                'SCHEMA_NAME'      => '',
+                'TABLE_NAME'       => trim($row[$table_name]),
+                'COLUMN_NAME'      => trim($row[$column_name]),
+                'COLUMN_POSITION'  => $row[$column_id] +1,
+                'DATA_TYPE'        => $row[$data_type],
+                'DEFAULT'          => $row[$data_default],
+                'NULLABLE'         => (bool) ($row[$nullable] != '1'),
+                'LENGTH'           => $row[$data_length],
+                'SCALE'            => ($row[$data_scale] == 0 ? null : $row[$data_scale]),
+                'PRECISION'        => ($row[$data_precision] == 0 ? null : $row[$data_precision]),
+                'UNSIGNED'         => false,
+                'PRIMARY'          => $primary,
+                'PRIMARY_POSITION' => ($primary ? $primaryPosition+1 : null),
+                'IDENTITY'         => $identity
+            );
+        }
+        return $desc;
+    }
+
+
+    /**
+     * Format a connection string to connect to database
+     *
+     * @return void
+     */
+    protected function _formatDbConnString($host, $port, $dbname)
+    {
+        if (is_numeric($port))
+            $port = '/' . (integer) $port;
+        if ($dbname)
+            $dbname = ':' . $dbname;
+
+        return $host . $port . $dbname;
+
+    }
+
+    /**
+     * Creates a connection to the database.
+     *
+     * @return void
+     * @throws ZendX_Db_Adapter_Firebird_Exception
+     */
+    protected function _connect()
+    {
+        if (isset($this->_connection) && is_resource($this->_connection)) {
+            return;
+        }
+
+        if (!extension_loaded('interbase')) {
+            /**
+             * @see ZendX_Db_Adapter_Firebird_Exception
+             */
+            require_once 'ZendX/Db/Adapter/Firebird/Exception.php';
+            throw new ZendX_Db_Adapter_Firebird_Exception('The Interbase extension is required for this adapter but the extension is not loaded');
+        }
+
+
+        // Suppress connection warnings here.
+        // Throw an exception instead.
+        $this->_connection = @ibase_connect(
+                                $this->_formatDbConnString($this->_config['host'],$this->_config['port'] ,$this->_config['dbname']),
+                                $this->_config['username'],
+                                $this->_config['password'],
+                                $this->_config['charset'],
+                                $this->_config['buffers'],
+                                $this->_config['dialect'],
+                                $this->_config['role']
+                              );
+
+        if ($this->_connection === false) {
+            /**
+             * @see ZendX_Db_Adapter_Firebird_Exception
+             */
+            require_once 'ZendX/Db/Adapter/Firebird/Exception.php';
+            throw new ZendX_Db_Adapter_Firebird_Exception(ibase_errmsg());
+        }
+    }
+
+    /**
+     * Force the connection to close.
+     *
+     * @return void
+     */
+    public function closeConnection()
+    {
+        if (is_resource($this->_transResource)) {
+            ibase_rollback($this->_transResource);
+        }
+        $this->_transResource = null;
+
+        if (is_resource($this->_connection)) {
+            unset($this->_connection);
+        }
+        //$this->_connection = false;
+    }
+
+    /**
+     * Prepare a statement and return a Statement resource.
+     *
+     * @param  string  $sql  SQL query
+     * @return ZendX_Db_Statement_Firebird
+     */
+    public function prepare($sql)
+    {
+        $this->_connect();
+
+        $stmt = new ZendX_Db_Statement_Firebird($this, $sql);
+        if ($stmt === false) {
+            return false;
+        }
+        $stmt->setFetchMode($this->_fetchMode);
+        return $stmt;
+    }
+
+    /**
+     * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
+     *
+     * As a convention, on RDBMS brands that support sequences
+     * (e.g. Firebird, Oracle, PostgreSQL, DB2), this method forms the name of a sequence
+     * from the arguments and returns the last id generated by that sequence.
+     * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
+     * returns the last value generated for such a column, and the table name
+     * argument is disregarded.
+     *
+     * Firebird does not support IDENTITY columns, so if the sequence is not
+     * specified, this method returns null.
+     *
+     * @param string $tableName   OPTIONAL Name of table.
+     * @param string $primaryKey  OPTIONAL Name of primary key column.
+     * @return string
+     * @throws ZendX_Db_Adapter_Firebird_Exception
+     */
+    public function lastInsertId($tableName = null, $primaryKey = null)
+    {
+        if ($tableName !== null) {
+            $sequenceName = $tableName;
+            if ($primaryKey) {
+                $sequenceName .= "_$primaryKey";
+            }
+            $sequenceName .= '_seq';
+            return $this->lastSequenceId($sequenceName);
+        }
+
+        // No support for IDENTITY columns; return null
+        return null;
+    }
+
+    /**
+     * Begin a transaction.
+     *
+     * @return void
+     */
+    protected function _beginTransaction()
+    {
+        $this->_connect();
+        if (is_resource($this->_transResource)){
+            return;
+        }
+
+        $this->_transResource = ibase_trans(IBASE_DEFAULT, $this->_connection);
+    }
+
+    /**
+     * Commit a transaction.
+     *
+     * @return void
+     */
+    protected function _commit()
+    {
+        if (false === ibase_commit(is_resource($this->_transResource) ? $this->_transResource : $this->_connection)) {
+            /**
+             * @see ZendX_Db_Adapter_Firebird_Exception
+             */
+            require_once 'ZendX/Db/Adapter/Firebird/Exception.php';
+            throw new ZendX_Db_Adapter_Firebird_Exception(ibase_errmsg());
+        }
+        $this->_transResource = null;
+    }
+
+    /**
+     * Roll-back a transaction.
+     *
+     * @return void
+     */
+    protected function _rollBack()
+    {
+        if (false === ibase_rollback(is_resource($this->_transResource) ? $this->_transResource : $this->_connection)) {
+            /**
+             * @see ZendX_Db_Adapter_Firebird_Exception
+             */
+            require_once 'ZendX/Db/Adapter/Firebird/Exception.php';
+            throw new ZendX_Db_Adapter_Firebird_Exception(ibase_errmsg());
+        }
+        $this->_transResource = null;
+    }
+
+    /**
+     * Set the fetch mode.
+     *
+     * @param int $mode
+     * @return void
+     */
+    public function setFetchMode($mode)
+    {
+        switch ($mode) {
+            case Zend_Db::FETCH_LAZY:
+            case Zend_Db::FETCH_ASSOC:
+            case Zend_Db::FETCH_NUM:
+            case Zend_Db::FETCH_BOTH:
+            case Zend_Db::FETCH_NAMED:
+            case Zend_Db::FETCH_OBJ:
+            case Zend_Db::FETCH_BOUND: // bound to PHP variable
+                $this->_fetchMode = $mode;
+                break;
+            default:
+                /**
+                 * @see ZendX_Db_Adapter_Firebird_Exception
+                 */
+                require_once 'ZendX/Db/Adapter/Firebird/Exception.php';
+                throw new ZendX_Db_Adapter_Firebird_Exception("Invalid fetch mode '$mode' specified");
+        }
+    }
+
+    /**
+     * Adds an adapter-specific LIMIT clause to the SELECT statement.
+     *
+     * @param string $sql
+     * @param integer $count
+     * @param integer $offset
+     * @throws Zend_Db_Adapter_Exception
+     * @return string
+     */
+    public function limit($sql, $count, $offset = 0)
+    {
+        $count = intval($count);
+        if ($count <= 0) {
+            /**
+             * @see ZendX_Db_Adapter_Firebird_Exception
+             */
+            require_once 'ZendX/Db/Adapter/Firebird/Exception.php';
+            throw new ZendX_Db_Adapter_Firebird_Exception("LIMIT argument count=$count is not valid");
+        }
+
+        $offset = intval($offset);
+        if ($offset < 0) {
+            /**
+             * @see ZendX_Db_Adapter_Firebird_Exception
+             */
+            require_once 'ZendX/Db/Adapter/Firebird/Exception.php';
+            throw new ZendX_Db_Adapter_Firebird_Exception("LIMIT argument offset=$offset is not valid");
+        }
+
+        if (trim($sql) == ''){
+            //Only compatible with FB 2.0 or newer
+            //ZF 1.5.0 don't support limit sql syntax that don't only append texto to sql, fixed in 1.5.1
+            $sql .= " rows $count";
+            if ($offset > 0)
+                $sql .= " to $offset";
+        }
+        else
+            $sql = substr_replace($sql, "select first $count skip $offset ", stripos($sql, 'select'), 6);
+
+        return $sql;
+    }
+
+        /**
+     * Quote a table identifier and alias.
+     *
+     * @param string|array|Zend_Db_Expr $ident The identifier or expression.
+     * @param string $alias An alias for the table.
+     * @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option.
+     * @return string The quoted identifier and alias.
+     */
+    public function quoteTableAs($ident, $alias = null, $auto=false)
+    {
+        // Firebird doesn't allow the 'AS' keyword between the table identifier/expression and alias.
+        return $this->_quoteIdentifierAs($ident, $alias, $auto, ' ');
+    }
+
+    /**
+     * Return the most recent value from the specified sequence in the database.
+     * This is supported only on RDBMS brands that support sequences
+     * (e.g. Firebird, Oracle, PostgreSQL, DB2).  Other RDBMS brands return null.
+     *
+     * @param string $sequenceName
+     * @return string
+     */
+    public function lastSequenceId($sequenceName)
+    {
+        $this->_connect();
+        $sql = 'SELECT GEN_ID('.$this->quoteIdentifier($sequenceName).', 0) FROM RDB$DATABASE';
+        $value = $this->fetchOne($sql);
+        return $value;
+    }
+
+    /**
+     * Generate a new value from the specified sequence in the database, and return it.
+     * This is supported only on RDBMS brands that support sequences
+     * (e.g. Firebird, Oracle, PostgreSQL, DB2).  Other RDBMS brands return null.
+     *
+     * @param string $sequenceName
+     * @return integer
+     */
+    public function nextSequenceId($sequenceName)
+    {
+        $this->_connect();
+        $sql = 'SELECT GEN_ID('.$this->quoteIdentifier($sequenceName).', 1) FROM RDB$DATABASE';
+        $value = $this->fetchOne($sql);
+        return $value;
+    }
+
+    /**
+     * Check if the adapter supports real SQL parameters.
+     *
+     * @param string $type 'positional' or 'named'
+     * @return bool
+     */
+    public function supportsParameters($type)
+    {
+        switch ($type) {
+            case 'positional':
+                return true;
+            case 'named':
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Test if a connection is active
+     *
+     * @return boolean
+     */
+    public function isConnected()
+    {
+        return ((bool) (is_resource($this->_connection)
+                     && get_resource_type($this->_connection) == 'Firebird/InterBase link'));
+    }
+
+    /**
+     * Retrieve server version in PHP style
+     *
+     * @return string
+     */
+    public function getServerVersion()
+    {
+        $this->_connect();
+        $service = ibase_service_attach($this->_formatDbConnString($this->_config['host'], $this->_config['port'], ''), $this->_config['username'], $this->_config['password']);
+
+        if ($service != FALSE) {
+            $server_info  = ibase_server_info($service, IBASE_SVC_SERVER_VERSION);
+            ibase_service_detach($service);
+            $matches = null;
+            if (preg_match('/((?:[0-9]{1,2}\.){1,3}[0-9]{1,2})/', $server_info, $matches)) {
+                return $matches[1];
+            } else {
+                return null;
+            }
+        } else {
+            return null;
+        }
+    }
+}

+ 39 - 0
extras/library/ZendX/Db/Adapter/Firebird/Exception.php

@@ -0,0 +1,39 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    ZendX_Db
+ * @subpackage Adapter
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: $
+ */
+
+/**
+ * @see Zend_Db_Adapter_Exception
+ */
+require_once 'Zend/Db/Adapter/Exception.php';
+
+/**
+ * ZendX_Db_Adapter_Firebird_Exception
+ *
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage Adapter
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_Db_Adapter_Firebird_Exception extends Zend_Db_Adapter_Exception
+{
+}

+ 369 - 0
extras/library/ZendX/Db/Statement/Firebird.php

@@ -0,0 +1,369 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage Statement
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: $
+ */
+
+/**
+ * @see Zend_Db_Statement
+ */
+require_once 'Zend/Db/Statement.php';
+
+/**
+ * Extends for Firebird
+ *
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage Statement
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_Db_Statement_Firebird extends Zend_Db_Statement
+{
+
+    /**
+     * The firebird_stmtPrepared resource.
+     *
+     * @var firebird_stmtPrepared
+     */
+    protected $_stmtPrepared = null;
+
+    /**
+     * The firebird_stmtResult resource.
+     *
+     * @var firebird_result
+     */
+    protected $_stmtResult = null;
+
+    /**
+     * The firebird_stmtResult resource.
+     *
+     * @var firebird_result
+     */
+    protected $_stmtRowCount = 0;
+
+    /**
+     * The firebird_stmtResult resource.
+     *
+     * @var firebird_result
+     */
+    protected $_stmtColumnCount = 0;
+
+    /**
+     * Column names.
+     *
+     * @var array
+     */
+    protected $_keys = array();
+
+    /**
+     * Fetched result values.
+     *
+     * @var array
+     */
+    protected $_values = array();
+
+    /**
+     * @var array
+     */
+    protected $_meta = null;
+
+    /**
+     * @param  string $sql
+     * @return void
+     * @throws ZendX_Db_Statement_Firebird_Exception
+     */
+    public function _prepare($sql)
+    {
+        $this->_stmtRowCount = 0;
+        $this->_stmtColumnCount = 0;
+
+        $connection = $this->_adapter->getConnection();
+
+        if ($trans = $this->_adapter->getTransaction())
+            $this->_stmtPrepared = @ibase_prepare($connection, $trans, $sql);
+        else
+            $this->_stmtPrepared = @ibase_prepare($connection, $sql);
+
+        if ($this->_stmtPrepared === false) {
+            /**
+             * @see ZendX_Db_Statement_Firebird_Exception
+             */
+            require_once 'ZendX/Db/Statement/Firebird/Exception.php';
+            throw new ZendX_Db_Statement_Firebird_Exception("Firebird prepare error: " . ibase_errmsg());
+        }
+    }
+
+    /**
+     * Binds a parameter to the specified variable name.
+     *
+     * @param mixed $parameter Name the parameter, either integer or string.
+     * @param mixed $variable  Reference to PHP variable containing the value.
+     * @param mixed $type      OPTIONAL Datatype of SQL parameter.
+     * @param mixed $length    OPTIONAL Length of SQL parameter.
+     * @param mixed $options   OPTIONAL Other options.
+     * @return bool
+     * @throws ZendX_Db_Statement_Firebird_Exception
+     */
+    protected function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null)
+    {
+        return true;
+    }
+
+    /**
+     * Closes the cursor and the statement.
+     *
+     * @return bool
+     */
+    public function close()
+    {
+        if ($stmt = $this->_stmtResult) {
+            @ibase_free_result($this->_stmtResult);
+            $this->_stmtResult = null;
+        }
+
+        if ($this->_stmtPrepared) {
+            $r = @ibase_free_query($this->_stmtPrepared);
+            $this->_stmtPrepared = null;
+            return $r;
+        }
+        return false;
+    }
+
+    /**
+     * Closes the cursor, allowing the statement to be executed again.
+     *
+     * @return bool
+     */
+    public function closeCursor()
+    {
+        if ($stmt = $this->_stmtResult) {
+            return @ibase_free_result($this->_stmtResult);
+        }
+        return false;
+    }
+
+    /**
+     * Returns the number of columns in the result set.
+     * Returns null if the statement has no result set metadata.
+     *
+     * @return int The number of columns.
+     */
+    public function columnCount()
+    {
+        return $this->_stmtColumnCount ? $this->_stmtColumnCount : 0;
+    }
+
+    /**
+     * Retrieves the error code, if any, associated with the last operation on
+     * the statement handle.
+     *
+     * @return string error code.
+     */
+    public function errorCode()
+    {
+        if ($this->_stmtPrepared || $this->_stmtResult) {
+            return ibase_errcode();
+        }
+        return false;        
+    }
+
+    /**
+     * Retrieves an array of error information, if any, associated with the
+     * last operation on the statement handle.
+     *
+     * @return array
+     */
+    public function errorInfo()
+    {
+        if (!$this->_stmtPrepared) {
+            return false;
+        }
+        return array(
+            ibase_errcode(),
+            ibase_errmsg()
+        );
+    }
+
+    /**
+     * Executes a prepared statement.
+     *
+     * @param array $params OPTIONAL Values to bind to parameter placeholders.
+     * @return bool
+     * @throws ZendX_Db_Statement_Firebird_Exception
+     */
+    public function _execute(array $params = null)
+    {
+        if (!$this->_stmtPrepared) {
+            return false;
+        }
+
+        // if no params were given as an argument to execute(),
+        // then default to the _bindParam array
+        if ($params === null) {
+            $params = $this->_bindParam;
+        }
+        // send $params as input parameters to the statement
+        if ($params) {
+            array_unshift($params, $this->_stmtPrepared);
+            $retval = @call_user_func_array(
+                'ibase_execute',
+                $params
+            );
+        } else
+            // execute the statement
+            $retval = @ibase_execute($this->_stmtPrepared);
+        $this->_stmtResult = $retval;
+
+        if ($retval === false) {
+            $last_error = ibase_errmsg();
+            $this->_stmtRowCount = 0;
+        }        
+        
+        //Firebird php ibase extension, auto-commit is not after each call, but at
+        //end of script. Disabled when transaction is active
+        if (!$this->_adapter->getTransaction())
+            ibase_commit_ret();
+            
+        if ($retval === false) {
+            /**
+             * @see ZendX_Db_Statement_Firebird_Exception
+             */
+            require_once 'ZendX/Db/Statement/Firebird/Exception.php';
+            throw new ZendX_Db_Statement_Firebird_Exception("Firebird statement execute error : " . $last_error);
+        }               
+
+        // statements that have no result set do not return metadata
+        if (is_resource($this->_stmtResult)) {
+
+            // get the column names that will result
+            $this->_keys = array();
+            $coln = ibase_num_fields($this->_stmtResult);
+            $this->_stmtColumnCount = $coln;
+            for ($i = 0; $i < $coln; $i++) {
+                $col_info = ibase_field_info($this->_stmtResult, $i);
+                $this->_keys[] = $this->_adapter->foldCase($col_info['name']);
+            }
+
+            // set up a binding space for result variables
+            $this->_values = array_fill(0, count($this->_keys), null);
+
+            // set up references to the result binding space.
+            // just passing $this->_values in the call_user_func_array()
+            // below won't work, you need references.
+            $refs = array();
+            foreach ($this->_values as $i => &$f) {
+                $refs[$i] = &$f;
+            }
+        }
+
+        if ($trans = $this->_adapter->getTransaction())
+            $this->_stmtRowCount = ibase_affected_rows($trans);
+        else
+            $this->_stmtRowCount = ibase_affected_rows($this->_adapter->getConnection());
+        return true;
+    }
+
+    /**
+     * Fetches a row from the result set.
+     *
+     * @param int $style  OPTIONAL Fetch mode for this fetch operation.
+     * @param int $cursor OPTIONAL Absolute, relative, or other.
+     * @param int $offset OPTIONAL Number for absolute or relative cursors.
+     * @return mixed Array, object, or scalar depending on fetch mode.
+     * @throws Zend_Db_Statement_Exception
+     */
+    public function fetch($style = null, $cursor = null, $offset = null)
+    {
+        if (!$this->_stmtResult) {
+            return false;
+        }
+
+        if ($style === null) {
+            $style = $this->_fetchMode;
+        }
+        
+        switch ($style) {
+            case Zend_Db::FETCH_NUM:
+                $row = ibase_fetch_row($this->_stmtResult, IBASE_TEXT);
+                break;
+            case Zend_Db::FETCH_ASSOC:
+                $row = ibase_fetch_assoc($this->_stmtResult, IBASE_TEXT);
+                break;
+            case Zend_Db::FETCH_BOTH:
+                $row = ibase_fetch_assoc($this->_stmtResult, IBASE_TEXT);
+                if ($row !== false)
+                    $row = array_merge($row, array_values($row));
+                break;
+            case Zend_Db::FETCH_OBJ:
+                $row = ibase_fetch_object($this->_stmtResult, IBASE_TEXT);
+                break;
+            case Zend_Db::FETCH_BOUND:
+                $row = ibase_fetch_assoc($this->_stmtResult, IBASE_TEXT);
+                if ($row !== false){
+                    $row = array_merge($row, array_values($row));
+                    $row = $this->_fetchBound($row);
+                }
+                break;
+            default:
+                /**
+                 * @see ZendX_Db_Adapter_Firebird_Exception
+                 */
+                require_once 'ZendX/Db/Statement/Firebird/Exception.php';
+                throw new ZendX_Db_Statement_Firebird_Exception(
+                    "Invalid fetch mode '$style' specified"
+                );
+                break;
+        }
+
+
+        return $row;
+    }
+
+    /**
+     * Retrieves the next rowset (result set) for a SQL statement that has
+     * multiple result sets.  An example is a stored procedure that returns
+     * the results of multiple queries.
+     *
+     * @return bool
+     * @throws ZendX_Db_Statement_Firebird_Exception
+     */
+    public function nextRowset()
+    {
+        /**
+         * @see ZendX_Db_Statement_Firebird_Exception
+         */
+        require_once 'ZendX/Db/Statement/Firebird/Exception.php';
+        throw new ZendX_Db_Statement_Firebird_Exception(__FUNCTION__.'() is not implemented');
+    }
+
+    /**
+     * Returns the number of rows affected by the execution of the
+     * last INSERT, DELETE, or UPDATE statement executed by this
+     * statement object.
+     *
+     * @return int     The number of rows affected.
+     * @throws Zend_Db_Statement_Exception
+     */
+    public function rowCount()
+    {
+        return $this->_stmtRowCount ? $this->_stmtRowCount : 0;
+    }
+
+}

+ 40 - 0
extras/library/ZendX/Db/Statement/Firebird/Exception.php

@@ -0,0 +1,40 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    ZendX_Db
+ * @subpackage Statement
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: $
+ */
+
+/**
+ * @see Zend_Db_Statement_Exception
+ */
+require_once 'Zend/Db/Statement/Exception.php';
+
+/**
+ * ZendX_Db_Adapter_Firebird_Exception
+ *
+ * @category   ZendX 
+ * @package    ZendX_Db
+ * @subpackage Statement
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_Db_Statement_Firebird_Exception extends Zend_Db_Statement_Exception
+{
+}
+

+ 38 - 0
extras/library/ZendX/Exception.php

@@ -0,0 +1,38 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category  ZendX
+ * @package   ZendX_Whois
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd     New BSD License
+ * @version   $Id$
+ */
+
+/**
+ * @see Zend_Exception
+ */
+require_once 'Zend/Exception.php';
+
+/**
+ * Exception class for ZendX
+ *
+ * @category  ZendX
+ * @package   ZendX
+ * @uses      Zend_Exception
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_Exception extends Zend_Exception
+{
+}

+ 157 - 0
extras/library/ZendX/JQuery.php

@@ -0,0 +1,157 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see Zend_Json
+ */
+require_once "Zend/Json.php";
+
+/**
+ * jQuery Global Class holding constants and static convienience methods.
+ *
+ * @todo       Offer convenience methods to add a tab or accordion container/pane combination.
+ * @package    ZendX_JQuery
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+  */
+class ZendX_JQuery
+{
+    /**
+     * Current default supported jQuery library version with ZendX_JQuery
+     * 
+     * @const string
+     */
+    const DEFAULT_JQUERY_VERSION = "1.3.2";
+
+    /**
+     * Currently supported jQuery UI library version with ZendX_JQuery
+     *
+     * @const string
+     */
+    const DEFAULT_UI_VERSION = "1.7.1";
+
+    /**
+     * @see http://code.google.com/apis/ajaxlibs/documentation/index.html#jquery
+     * @const string Base path to CDN
+     */
+    const CDN_BASE_GOOGLE = 'http://ajax.googleapis.com/ajax/libs/';
+
+    /**
+     * @see http://code.google.com/apis/ajaxlibs/documentation/index.html#jquery
+     * @const string Base path to CDN
+     */
+    const CDN_BASE_GOOGLE_SSL = 'https://ajax.googleapis.com/ajax/libs/';
+
+    /**
+     * @const string
+     */
+    const CDN_SUBFOLDER_JQUERY = 'jquery/';
+
+    /**
+     * @const string
+     */
+    const CDN_SUBFOLDER_JQUERYUI = 'jqueryui/';
+
+    /**
+     * Always uses compressed version, because this is assumed to be the use case
+     * in production enviroment. An uncompressed version has to included manually.
+     *
+     * @see http://code.google.com/apis/ajaxlibs/documentation/index.html#jquery
+     * @const string File path after base and version
+     */
+    const CDN_JQUERY_PATH_GOOGLE = '/jquery.min.js';
+
+    /**
+     * Which parts of the the jQuery library should be rendered on echo'ing
+     * the jQuery library to the View. The constants act as bit-mask. This
+     * way the jQuery autogenerated code can be refactored based on personal needs.
+     *
+     * @see ZendX_JQuery_Helper_JQuery::setRenderMode
+     * @const Integer
+     */
+    const RENDER_LIBRARY         = 1;
+    const RENDER_SOURCES         = 2;
+    const RENDER_STYLESHEETS     = 4;
+    const RENDER_JAVASCRIPT      = 8;
+    const RENDER_JQUERY_ON_LOAD  = 16;
+    const RENDER_ALL             = 255;
+
+    /**
+     * jQuery-enable a view instance
+     *
+     * @param  Zend_View_Interface $view
+     * @return void
+     */
+    public static function enableView(Zend_View_Interface $view)
+    {
+        if (false === $view->getPluginLoader('helper')->getPaths('ZendX_JQuery_View_Helper')) {
+            $view->addHelperPath('ZendX/JQuery/View/Helper', 'ZendX_JQuery_View_Helper');
+        }
+    }
+
+    /**
+     * jQuery-enable a form instance
+     *
+     * @param  Zend_Form $form
+     * @return void
+     */
+    public static function enableForm(Zend_Form $form)
+    {
+        $form->addPrefixPath('ZendX_JQuery_Form_Decorator', 'ZendX/JQuery/Form/Decorator', 'decorator')
+             ->addPrefixPath('ZendX_JQuery_Form_Element', 'ZendX/JQuery/Form/Element', 'element')
+             ->addElementPrefixPath('ZendX_JQuery_Form_Decorator', 'ZendX/JQuery/Form/Decorator', 'decorator')
+             ->addDisplayGroupPrefixPath('ZendX_JQuery_Form_Decorator', 'ZendX/JQuery/Form/Decorator');
+
+        foreach ($form->getSubForms() as $subForm) {
+            self::enableForm($subForm);
+        }
+
+        if (null !== ($view = $form->getView())) {
+            self::enableView($view);
+        }
+    }
+
+    /**
+     * Encode Json that may include javascript expressions.
+     *
+     * Take care of using the Zend_Json_Encoder to alleviate problems with the json_encode
+     * magic key mechanism as of now.
+     *
+     * @see Zend_Json::encode
+     * @param  mixed $value
+     * @return mixed
+     */
+    public static function encodeJson($value)
+    {
+        if (is_array($value) && count($value) == 0) {
+            return '{}';
+        }
+
+        if(!class_exists('Zend_Json')) {
+            /**
+             * @see Zend_Json
+             */
+            require_once "Zend/Json.php";
+        }
+        return Zend_Json::encode($value, false, array('enableJsonExprFinder' => true));
+    }
+}

+ 76 - 0
extras/library/ZendX/JQuery/Controller/Action/Helper/AutoComplete.php

@@ -0,0 +1,76 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once "Zend/Controller/Action/Helper/AutoComplete/Abstract.php";
+
+class ZendX_JQuery_Controller_Action_Helper_AutoComplete
+extends Zend_Controller_Action_Helper_AutoComplete_Abstract
+{
+    /**
+     * Validate autocompletion data
+     *
+     * @param  mixed $data
+     * @return boolean
+     */
+    public function validateData($data)
+    {
+        if (!is_array($data)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Prepare autocompletion data
+     *
+     * @param  mixed   $data
+     * @param  boolean $keepLayouts
+     * @return mixed
+     */
+    public function prepareAutoCompletion($data, $keepLayouts = false)
+    {
+        if (!$this->validateData($data)) {
+            /**
+             * @see Zend_Controller_Action_Exception
+             */
+            require_once 'Zend/Controller/Action/Exception.php';
+            throw new Zend_Controller_Action_Exception('Invalid data passed for autocompletion');
+        }
+
+        $data = (array) $data;
+        $output = "";
+        foreach($data AS $k => $v) {
+            if(is_numeric($k)) {
+                $output .= $v."\n";
+            } else {
+                $output .= $k."|".$v."\n";
+            }
+        }
+
+        if (!$keepLayouts) {
+            $this->disableLayouts();
+        }
+
+        return $output;
+    }
+}

+ 32 - 0
extras/library/ZendX/JQuery/Exception.php

@@ -0,0 +1,32 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once "Zend/Exception.php";
+
+/**
+ * jQuery Exception
+ *
+ * @package    ZendX_JQuery
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+  */
+class ZendX_JQuery_Exception extends Zend_Exception { }

+ 67 - 0
extras/library/ZendX/JQuery/Form.php

@@ -0,0 +1,67 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once "Zend/Form.php";
+
+/**
+ * Form Wrapper for jQuery-enabled forms
+ *
+ * @package    ZendX_JQuery
+ * @subpackage Form
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+  */
+class ZendX_JQuery_Form extends Zend_Form
+{
+    /**
+     * Constructor
+     *
+     * @param  array|Zend_Config|null $options
+     * @return void
+     */
+    public function __construct($options = null)
+    {
+        $this->addPrefixPath('ZendX_JQuery_Form_Decorator', 'ZendX/JQuery/Form/Decorator', 'decorator')
+             ->addPrefixPath('ZendX_JQuery_Form_Element', 'ZendX/JQuery/Form/Element', 'element')
+             ->addElementPrefixPath('ZendX_JQuery_Form_Decorator', 'ZendX/JQuery/Form/Decorator', 'decorator')
+             ->addDisplayGroupPrefixPath('ZendX_JQuery_Form_Decorator', 'ZendX/JQuery/Form/Decorator');
+        parent::__construct($options);
+    }
+
+    /**
+     * Set the view object
+     *
+     * Ensures that the view object has the jQuery view helper path set.
+     *
+     * @param  Zend_View_Interface $view
+     * @return ZendX_JQuery_Form
+     */
+    public function setView(Zend_View_Interface $view = null)
+    {
+        if (null !== $view) {
+            if (false === $view->getPluginLoader('helper')->getPaths('ZendX_JQuery_View_Helper')) {
+                $view->addHelperPath('ZendX/JQuery/View/Helper', 'ZendX_JQuery_View_Helper');
+            }
+        }
+        return parent::setView($view);
+    }
+}

+ 39 - 0
extras/library/ZendX/JQuery/Form/Decorator/AccordionContainer.php

@@ -0,0 +1,39 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_Form_Decorator_UiWidgetContainer
+ */
+require_once "UiWidgetContainer.php";
+
+/**
+ * Form Decorator for jQuery Accordion View Helper
+ *
+ * @package    ZendX_JQuery
+ * @subpackage Form
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_JQuery_Form_Decorator_AccordionContainer extends ZendX_JQuery_Form_Decorator_UiWidgetContainer
+{
+    protected $_helper = "accordionContainer";
+}

+ 39 - 0
extras/library/ZendX/JQuery/Form/Decorator/AccordionPane.php

@@ -0,0 +1,39 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_Form_Decorator_UiWidgetContainer
+ */
+require_once "UiWidgetPane.php";
+
+/**
+ * Form Decorator for jQuery Accordion Pane View Helper
+ *
+ * @package    ZendX_JQuery
+ * @subpackage Form
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_JQuery_Form_Decorator_AccordionPane extends ZendX_JQuery_Form_Decorator_UiWidgetPane
+{
+    protected $_helper = "accordionPane";
+}

+ 67 - 0
extras/library/ZendX/JQuery/Form/Decorator/DialogContainer.php

@@ -0,0 +1,67 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_Form_Decorator_UiWidgetContainer
+ */
+require_once "UiWidgetContainer.php";
+
+/**
+ * Form Decorator for jQuery Dialog View Helper
+ *
+ * @package    ZendX_JQuery
+ * @subpackage Form
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_JQuery_Form_Decorator_DialogContainer extends ZendX_JQuery_Form_Decorator_UiWidgetContainer
+{
+    protected $_helper = "dialogContainer";
+
+    /**
+     * Render an jQuery UI Widget element using its associated view helper
+     *
+     * Determine view helper from 'helper' option, or, if none set, from
+     * the element type. Then call as
+     * helper($element->getName(), $element->getValue(), $element->getAttribs())
+     *
+     * @param  string $content
+     * @return string
+     * @throws Zend_Form_Decorator_Exception if element or view are not registered
+     */
+    public function render($content)
+    {
+        $element = $this->getElement();
+        $view    = $element->getView();
+        if (null === $view) {
+            return $content;
+        }
+
+        $jQueryParams = $this->getJQueryParams();
+        $attribs     = $this->getOptions();
+
+        $helper      = $this->getHelper();
+        $id          = $element->getId() . '-container';
+
+        return $view->$helper($id, $content, $jQueryParams, $attribs);
+    }
+}

+ 39 - 0
extras/library/ZendX/JQuery/Form/Decorator/TabContainer.php

@@ -0,0 +1,39 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_Form_Decorator_UiWidgetContainer
+ */
+require_once "UiWidgetContainer.php";
+
+/**
+ * Form Decorator for jQuery Tabs View Helper
+ *
+ * @package    ZendX_JQuery
+ * @subpackage Form
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_JQuery_Form_Decorator_TabContainer extends ZendX_JQuery_Form_Decorator_UiWidgetContainer
+{
+    protected $_helper = "tabContainer";
+}

+ 39 - 0
extras/library/ZendX/JQuery/Form/Decorator/TabPane.php

@@ -0,0 +1,39 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_Form_Decorator_UiWidgetContainer
+ */
+require_once "UiWidgetPane.php";
+
+/**
+ * Form Decorator for jQuery Tab Pane View Helper
+ *
+ * @package    ZendX_JQuery
+ * @subpackage Form
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_JQuery_Form_Decorator_TabPane extends ZendX_JQuery_Form_Decorator_UiWidgetPane
+{
+    protected $_helper = "tabPane";
+}

+ 149 - 0
extras/library/ZendX/JQuery/Form/Decorator/UiWidgetContainer.php

@@ -0,0 +1,149 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once "Zend/Form/Decorator/Abstract.php";
+
+/**
+ * Abstract Form Decorator for all jQuery UI Widget Containers
+ *
+ * @package    ZendX_JQuery
+ * @subpackage Form
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class ZendX_JQuery_Form_Decorator_UiWidgetContainer extends Zend_Form_Decorator_Abstract
+{
+    /**
+     * View helper
+     * @var string
+     */
+    protected $_helper;
+
+    /**
+     * Element attributes
+     * @var array
+     */
+    protected $_attribs;
+
+    /**
+     * jQuery option parameters
+     * @var array
+     */
+    protected $_jQueryParams;
+
+    /**
+     * Get view helper for rendering container
+     *
+     * @return string
+     */
+    public function getHelper()
+    {
+        if (null === $this->_helper) {
+            require_once 'Zend/Form/Decorator/Exception.php';
+            throw new Zend_Form_Decorator_Exception('No view helper specified fo DijitContainer decorator');
+        }
+        return $this->_helper;
+    }
+
+    /**
+     * Get element attributes
+     *
+     * @return array
+     */
+    public function getAttribs()
+    {
+        if (null === $this->_attribs) {
+            $attribs = $this->getElement()->getAttribs();
+            if (array_key_exists('jQueryParams', $attribs)) {
+                $this->getJQueryParams();
+                unset($attribs['jQueryParams']);
+            }
+            $this->_attribs = $attribs;
+        }
+        return $this->_attribs;
+    }
+
+    /**
+     * Get jQuery option parameters
+     *
+     * @return array
+     */
+    public function getJQueryParams()
+    {
+        if (null === $this->_jQueryParams) {
+            $this->_jQueryParams = array();
+            if($attribs = $this->getElement()->getAttribs()) {
+                if (array_key_exists('jQueryParams', $attribs)) {
+                    $this->_jQueryParams = $attribs['jQueryParams'];
+                }
+            }
+
+            if($options = $this->getOptions()) {
+                if (array_key_exists('jQueryParams', $options)) {
+                    $this->_jQueryParams = array_merge($this->_jQueryParams, $options['jQueryParams']);
+                    $this->removeOption('jQueryParams');
+                }
+            }
+        }
+
+        return $this->_jQueryParams;
+    }
+
+    /**
+     * Render an jQuery UI Widget element using its associated view helper
+     *
+     * Determine view helper from 'helper' option, or, if none set, from
+     * the element type. Then call as
+     * helper($element->getName(), $element->getValue(), $element->getAttribs())
+     *
+     * @param  string $content
+     * @return string
+     * @throws Zend_Form_Decorator_Exception if element or view are not registered
+     */
+    public function render($content)
+    {
+        $element = $this->getElement();
+        $view    = $element->getView();
+        if (null === $view) {
+            return $content;
+        }
+
+        $placement = $this->getPlacement();
+        $separator = $this->getSeparator();
+
+        $jQueryParams = $this->getJQueryParams();
+        $attribs      = $this->getOptions();
+
+        $helper      = $this->getHelper();
+        $id          = $element->getId() . '-container';
+
+        $tabs = $view->$helper($id, $jQueryParams, $attribs);
+
+        switch ($placement) {
+            case self::PREPEND:
+                return $tabs . $separator . $content;
+
+            case self::APPEND:
+                return $content . $separator . $tabs;
+        }
+    }
+}

+ 178 - 0
extras/library/ZendX/JQuery/Form/Decorator/UiWidgetElement.php

@@ -0,0 +1,178 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see Zend_Form_Decorator_ViewHelper
+ */
+require_once "Zend/Form/Decorator/ViewHelper.php";
+
+/**
+ * @see ZendX_JQuery_Form_Decorator_UiWidgetElementMarker
+ */
+require_once "ZendX/JQuery/Form/Decorator/UiWidgetElementMarker.php";
+
+/**
+ * Abstract Form Decorator for all jQuery UI Form Elements
+ *
+ * @package    ZendX_JQuery
+ * @subpackage Form
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_JQuery_Form_Decorator_UiWidgetElement
+    extends Zend_Form_Decorator_ViewHelper
+    implements ZendX_JQuery_Form_Decorator_UiWidgetElementMarker
+{
+    /**
+     * Element attributes
+     *
+     * @var array
+     */
+    protected $_attribs;
+
+    /**
+     * jQuery UI View Helper
+     *
+     * @var ZendX_JQuery_View_Helper_UiWidget
+     */
+    public $helper;
+
+    /**
+     * jQuery related attributes/options
+     *
+     * @var array
+     */
+    protected $_jQueryParams = array();
+
+    /**
+     * Get element attributes
+     *
+     * @return array
+     */
+    public function getElementAttribs()
+    {
+        if (null === $this->_attribs) {
+            if($this->_attribs = parent::getElementAttribs()) {
+                if (array_key_exists('jQueryParams', $this->_attribs)) {
+                    $this->setJQueryParams($this->_attribs['jQueryParams']);
+                    unset($this->_attribs['jQueryParams']);
+                }
+            }
+        }
+
+        return $this->_attribs;
+    }
+
+    /**
+     * Set a single jQuery option parameter
+     *
+     * @param  string $key
+     * @param  mixed $value
+     * @return ZendX_JQuery_Form_Decorator_UiWidgetElement
+     */
+    public function setJQueryParam($key, $value)
+    {
+        $this->_jQueryParams[(string) $key] = $value;
+        return $this;
+    }
+
+    /**
+     * Set jQuery option parameters
+     *
+     * @param  array $params
+     * @return ZendX_JQuery_Form_Decorator_UiWidgetElement
+     */
+    public function setJQueryParams(array $params)
+    {
+        $this->_jQueryParams = array_merge($this->_jQueryParams, $params);
+        return $this;
+    }
+
+    /**
+     * Retrieve a single jQuery option parameter
+     *
+     * @param  string $key
+     * @return mixed|null
+     */
+    public function getJQueryParam($key)
+    {
+        $this->getElementAttribs();
+        $key = (string) $key;
+        if (array_key_exists($key, $this->_jQueryParams)) {
+            return $this->_jQueryParams[$key];
+        }
+
+        return null;
+    }
+
+    /**
+     * Get jQuery option parameters
+     *
+     * @return array
+     */
+    public function getJQueryParams()
+    {
+        $this->getElementAttribs();
+        return $this->_jQueryParams;
+    }
+
+    /**
+     * Render an jQuery UI Widget element using its associated view helper
+     *
+     * @param  string $content
+     * @return string
+     * @throws Zend_Form_Decorator_Exception if element or view are not registered
+     */
+    public function render($content)
+    {
+        $element = $this->getElement();
+        $view = $element->getView();
+        if (null === $view) {
+            require_once 'Zend/Form/Decorator/Exception.php';
+            throw new Zend_Form_Decorator_Exception('UiWidgetElement decorator cannot render without a registered view object');
+        }
+
+        if(method_exists($element, 'getJQueryParams')) {
+            $this->setJQueryParams($element->getJQueryParams());
+        }
+        $jQueryParams = $this->getJQueryParams();
+
+        $helper    = $this->getHelper();
+        $separator = $this->getSeparator();
+        $value     = $this->getValue($element);
+        $attribs   = $this->getElementAttribs();
+        $name      = $element->getFullyQualifiedName();
+
+        $id = $element->getId();
+        $attribs['id'] = $id;
+
+        $elementContent = $view->$helper($name, $value, $jQueryParams, $attribs);
+        switch ($this->getPlacement()) {
+            case self::APPEND:
+                return $content . $separator . $elementContent;
+            case self::PREPEND:
+                return $elementContent . $separator . $content;
+            default:
+                return $elementContent;
+        }
+    }
+}

+ 31 - 0
extras/library/ZendX/JQuery/Form/Decorator/UiWidgetElementMarker.php

@@ -0,0 +1,31 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * Marking UiWidgetElement rendering decorator.
+ *
+ * Marker Interface to make sure that programmer using ZendX_JQuery is not
+ * switching ZendX_JQuery_Form_Decorator_UiWidgetElement with Zend_Form_Decorator_ViewHelper
+ * without noticing that this is not possible.
+ */
+interface ZendX_JQuery_Form_Decorator_UiWidgetElementMarker {
+}

+ 157 - 0
extras/library/ZendX/JQuery/Form/Decorator/UiWidgetPane.php

@@ -0,0 +1,157 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once "Zend/Form/Decorator/Abstract.php";
+
+/**
+ * Abstract Form Decorator for all jQuery UI Pane View Helpers
+ *
+ * @package    ZendX_JQuery
+ * @subpackage Form
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class ZendX_JQuery_Form_Decorator_UiWidgetPane extends Zend_Form_Decorator_Abstract
+{
+    /**
+     * View helper
+     * @var string
+     */
+    protected $_helper;
+
+    /**
+     * Element attributes
+     * @var array
+     */
+    protected $_attribs;
+
+    /**
+     * jQuery option parameters
+     * @var array
+     */
+    protected $_jQueryParams;
+
+    /**
+     * Container title
+     * @var string
+     */
+    protected $_title;
+
+    /**
+     * Get view helper for rendering container
+     *
+     * @return string
+     */
+    public function getHelper()
+    {
+        if (null === $this->_helper) {
+            require_once 'Zend/Form/Decorator/Exception.php';
+            throw new Zend_Form_Decorator_Exception('No view helper specified fo UiWidgetContainer decorator');
+        }
+        return $this->_helper;
+    }
+
+    /**
+     * Get element attributes
+     *
+     * @return array
+     */
+    public function getAttribs()
+    {
+        if (null === $this->_attribs) {
+            $attribs = $this->getElement()->getAttribs();
+            if (array_key_exists('jQueryParams', $attribs)) {
+                $this->getJQueryParams();
+                unset($attribs['jQueryParams']);
+            }
+            $this->_attribs = $attribs;
+        }
+        return $this->_attribs;
+    }
+
+    /**
+     * Get jQuery option parameters
+     *
+     * @return array
+     */
+    public function getJQueryParams()
+    {
+        if (null === $this->_jQueryParams) {
+            $attribs = $this->getElement()->getAttribs();
+            $this->_jQueryParams = array();
+            if (array_key_exists('jQueryParams', $attribs)) {
+                $this->_jQueryParams = $attribs['jQueryParams'];
+            }
+
+            $options = $this->getOptions();
+            if (array_key_exists('jQueryParams', $options)) {
+                $this->_jQueryParams = array_merge($this->_jQueryParams, $options['jQueryParams']);
+                $this->removeOption('jQueryParams');
+            }
+        }
+
+        // Ensure we have a title param
+        if (!array_key_exists('title', $this->_jQueryParams)) {
+            require_once "Zend/Form/Decorator/Exception.php";
+            throw new Zend_Form_Decorator_Exception("UiWidgetPane Decorators have to have a jQueryParam 'title' to render. This title can been set via setJQueryParam('title') on the parent element.");
+        }
+
+        return $this->_jQueryParams;
+    }
+
+    /**
+     * Render an jQuery UI Widget Pane using its associated view helper
+     *
+     * @throws Zend_Form_Decorator_Exception
+     * @param  string $content
+     * @return string
+     * @throws Zend_Form_Decorator_Exception if element or view are not registered
+     */
+    public function render($content)
+    {
+        $element = $this->getElement();
+        $view    = $element->getView();
+        if (null === $view) {
+            return $content;
+        }
+
+        $jQueryParams = $this->getJQueryParams();
+        $attribs     = array_merge($this->getAttribs(), $this->getOptions());
+
+        if(isset($jQueryParams['title']) && !empty($jQueryParams['title'])) {
+            if (null !== ($translator = $element->getTranslator())) {
+                $jQueryParams['title'] = $translator->translate($jQueryParams['title']);
+            }
+        }
+
+        if(isset($jQueryParams['containerId'])) {
+            $id = $jQueryParams['containerId']."-container";
+        } else {
+            require_once "Zend/Form/Decorator/Exception.php";
+            throw new Zend_Form_Decorator_Exception("UiWidgetPane Decorators have to have a jQueryParam 'containerId', to point at their parent container. This containerId has been set via setAttrib('id') on the parent element.");
+        }
+
+        $helper = $this->getHelper();
+
+        return $view->$helper($id, $content, $jQueryParams, $attribs);
+    }
+}

+ 39 - 0
extras/library/ZendX/JQuery/Form/Element/AutoComplete.php

@@ -0,0 +1,39 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_Form_Element_UiWidget
+ */
+require_once "UiWidget.php";
+
+/**
+ * Form Element for jQuery Autocomplete View Helper
+ *
+ * @package    ZendX_JQuery
+ * @subpackage Form
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+  */
+class ZendX_JQuery_Form_Element_AutoComplete extends ZendX_JQuery_Form_Element_UiWidget
+{
+    public $helper = "autoComplete";
+}

+ 39 - 0
extras/library/ZendX/JQuery/Form/Element/ColorPicker.php

@@ -0,0 +1,39 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_Form_Element_UiWidget
+ */
+require_once "UiWidget.php";
+
+/**
+ * Form Element for jQuery ColorPicker View Helper
+ *
+ * @package    ZendX_JQuery
+ * @subpackage Form
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+  */
+class ZendX_JQuery_Form_Element_ColorPicker extends ZendX_JQuery_Form_Element_UiWidget
+{
+    public $helper = "colorPicker";
+}

+ 39 - 0
extras/library/ZendX/JQuery/Form/Element/DatePicker.php

@@ -0,0 +1,39 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_Form_Element_UiWidget
+ */
+require_once "UiWidget.php";
+
+/**
+ * Form Element for jQuery DatePicker View Helper
+ *
+ * @package    ZendX_JQuery
+ * @subpackage Form
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+  */
+class ZendX_JQuery_Form_Element_DatePicker extends ZendX_JQuery_Form_Element_UiWidget
+{
+    public $helper = "datePicker";
+}

+ 39 - 0
extras/library/ZendX/JQuery/Form/Element/Slider.php

@@ -0,0 +1,39 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_Form_Element_UiWidget
+ */
+require_once "UiWidget.php";
+
+/**
+ * Form Element for jQuery Slider View Helper
+ *
+ * @package    ZendX_JQuery
+ * @subpackage Form
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+  */
+class ZendX_JQuery_Form_Element_Slider extends ZendX_JQuery_Form_Element_UiWidget
+{
+    public $helper = "slider";
+}

+ 39 - 0
extras/library/ZendX/JQuery/Form/Element/Spinner.php

@@ -0,0 +1,39 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_Form_Element_UiWidget
+ */
+require_once "UiWidget.php";
+
+/**
+ * Form Element for jQuery Spinner View Helper
+ *
+ * @package    ZendX_JQuery
+ * @subpackage Form
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+  */
+class ZendX_JQuery_Form_Element_Spinner extends ZendX_JQuery_Form_Element_UiWidget
+{
+    public $helper = "spinner";
+}

+ 180 - 0
extras/library/ZendX/JQuery/Form/Element/UiWidget.php

@@ -0,0 +1,180 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once "Zend/Form/Element.php";
+
+/**
+ * Base Form Element for jQuery View Helpers
+ *
+ * @package    ZendX_JQuery
+ * @subpackage Form
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_JQuery_Form_Element_UiWidget extends Zend_Form_Element
+{
+    /**
+     * jQuery related parameters of this form element.
+     *
+     * @var array
+     */
+    public $jQueryParams = array();
+
+    /**
+     * Just here to prevent errors.
+     *
+     * @var array
+     */
+    public $options = array();
+
+    /**
+     * Constructor
+     *
+     * @param  mixed $spec
+     * @param  mixed $options
+     * @return void
+     */
+    public function __construct($spec, $options = null)
+    {
+        $this->addPrefixPath('ZendX_JQuery_Form_Decorator', 'ZendX/JQuery/Form/Decorator', 'decorator');
+        parent::__construct($spec, $options);
+    }
+
+    /**
+     * Get jQuery related parameter of this form element
+     *
+     * @param  string $key
+     * @return string
+     */
+    public function getJQueryParam($key)
+    {
+        $key = (string) $key;
+        return $this->jQueryParams[$key];
+    }
+
+    /**
+     * Get all currently known jQuery related parameters of this element
+     *
+     * @return array
+     */
+    public function getJQueryParams()
+    {
+        return $this->jQueryParams;
+    }
+
+    /**
+     * Set a jQuery related parameter of this form element.
+     *
+     * @param  string $key
+     * @param  string $value
+     * @return ZendX_JQuery_Form_Element_UiWidget
+     */
+    public function setJQueryParam($key, $value)
+    {
+        $key = (string) $key;
+        $this->jQueryParams[$key] = $value;
+        return $this;
+    }
+
+    /**
+     * Set an array of jQuery related options for this element (merging with old options).
+     *
+     * @param  Array $params
+     * @return ZendX_JQuery_Form_Element_UiWidget
+     */
+    public function setJQueryParams($params)
+    {
+        $this->jQueryParams = array_merge($this->jQueryParams, $params);
+        return $this;
+    }
+
+    /**
+     * Load default decorators
+     *
+     * @return void
+     */
+    public function loadDefaultDecorators()
+    {
+        if ($this->loadDefaultDecoratorsIsDisabled()) {
+            return;
+        }
+
+        $decorators = $this->getDecorators();
+        if (empty($decorators)) {
+            $this->addDecorator('UiWidgetElement')
+                 ->addDecorator('Errors')
+                 ->addDecorator('Description', array('tag' => 'p', 'class' => 'description'))
+                 ->addDecorator('HtmlTag', array('tag' => 'dd'))
+                 ->addDecorator('Label', array('tag' => 'dt'));
+        }
+    }
+
+    /**
+     * Set the view object
+     *
+     * Ensures that the view object has the jQuery view helper path set.
+     *
+     * @param  Zend_View_Interface $view
+     * @return ZendX_JQuery_Form_Element_UiWidget
+     */
+    public function setView(Zend_View_Interface $view = null)
+    {
+        if (null !== $view) {
+            if (false === $view->getPluginLoader('helper')->getPaths('ZendX_JQuery_View_Helper')) {
+                $view->addHelperPath('ZendX/JQuery/View/Helper', 'ZendX_JQuery_View_Helper');
+            }
+        }
+        return parent::setView($view);
+    }
+
+    /**
+     * Retrieve all decorators
+     *
+     * @throws ZendX_JQuery_Form_Exception
+     * @return array
+     */
+    public function getDecorators()
+    {
+        $decorators = parent::getDecorators();
+        if(count($decorators) > 0) {
+            // Only check this if there are decorators present, otherwise it could
+            // be that the decorators have not been initialized yet.
+            $foundUiWidgetElementMarker = false;
+            foreach($decorators AS $decorator) {
+                if($decorator instanceof ZendX_JQuery_Form_Decorator_UiWidgetElementMarker) {
+                    $foundUiWidgetElementMarker = true;
+                }
+            }
+            if($foundUiWidgetElementMarker === false) {
+                require_once "ZendX/JQuery/Form/Exception.php";
+                throw new ZendX_JQuery_Form_Exception(
+                    "Cannot render jQuery form element without at least one decorator ".
+                    "implementing the 'ZendX_JQuery_Form_Decorator_UiWidgetElementMarker' interface. ".
+                    "Default decorator for this marker interface is the 'ZendX_JQuery_Form_Decorator_UiWidgetElement'. ".
+                    "Hint: The ViewHelper decorator does not render jQuery elements correctly."
+                );
+            }
+        }
+
+        return $decorators;
+    }
+}

+ 11 - 0
extras/library/ZendX/JQuery/Form/Exception.php

@@ -0,0 +1,11 @@
+<?php
+
+/**
+ * @see ZendX_JQuery_Exception
+ */
+require_once "ZendX/JQuery/Exception.php";
+
+class ZendX_JQuery_Form_Exception extends ZendX_JQuery_Exception
+{
+
+}

+ 32 - 0
extras/library/ZendX/JQuery/View/Exception.php

@@ -0,0 +1,32 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id: Exception.php 11941 2008-10-13 19:41:38Z matthew $
+ */
+
+require_once "ZendX/JQuery/Exception.php";
+
+/**
+ * jQuery Exception
+ *
+ * @package    ZendX_JQuery
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+  */
+class ZendX_JQuery_View_Exception extends ZendX_JQuery_Exception { }

+ 171 - 0
extras/library/ZendX/JQuery/View/Helper/AccordionContainer.php

@@ -0,0 +1,171 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_View_Helper_UiWidget
+ */
+require_once "ZendX/JQuery/View/Helper/UiWidget.php";
+
+/**
+ * jQuery Accordion View Helper
+ *
+ * @uses 	   Zend_Json
+ * @package    ZendX_JQuery
+ * @subpackage View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+  */
+class ZendX_JQuery_View_Helper_AccordionContainer extends ZendX_JQuery_View_Helper_UiWidget
+{
+    /**
+     * @var array
+     */
+    protected $_panes = array();
+
+    /**
+     * @var string
+     */
+    protected $_elementHtmlTemplate = null;
+
+    /**
+     * Add Accordion Pane for the Accordion-Id
+     *
+     * @param  string $id
+     * @param  string $name
+     * @param  string $content
+     * @return ZendX_JQuery_View_Helper_AccordionContainer
+     */
+    public function addPane($id, $name, $content, array $options=array())
+    {
+        if(!isset($this->_panes[$id])) {
+            $this->_panes[$id] = array();
+        }
+        if(strlen($name) == 0 && isset($options['title'])) {
+            $name = $options['title'];
+        }
+        $this->_panes[$id][] = array('name' => $name, 'content' => $content, 'options' => $options);
+        return $this;
+    }
+
+    /**
+     * Render Accordion with the currently registered elements.
+     *
+     * If no arguments are given, the accordion object is returned so that
+     * chaining the {@link addPane()} function allows to register new elements
+     * for an accordion.
+     *
+     * @link   http://docs.jquery.com/UI/Accordion
+     * @param  string $id
+     * @param  array  $params
+     * @param  array  $attribs
+     * @return string|ZendX_JQuery_View_Helper_AccordionContainer
+     */
+    public function accordionContainer($id=null, array $params=array(), array $attribs=array())
+    {
+        if(0 === func_num_args()) {
+            return $this;
+        }
+
+        if(!isset($attribs['id'])) {
+            $attribs['id'] = $id;
+        }
+
+        $html = "";
+        if(isset($this->_panes[$id])) {
+            foreach($this->_panes[$id] AS $element) {
+                $html .= sprintf($this->getElementHtmlTemplate(), $element['name'], $element['content']).PHP_EOL;
+            }
+
+            if(count($params) > 0) {
+                $params = ZendX_JQuery::encodeJson($params);
+            } else {
+                $params = "{}";
+            }
+
+            $js = sprintf('%s("#%s").accordion(%s);',
+                ZendX_JQuery_View_Helper_JQuery::getJQueryHandler(),
+                $attribs['id'],
+                $params
+            );
+            $this->jquery->addOnLoad($js);
+
+            $html = $this->getAccordionTemplate($attribs, $html);
+        }
+        return $html;
+    }
+
+    /**
+     * @param  array $attribs
+     * @param  string $html
+     * @return string
+     */
+    protected function getAccordionTemplate($attribs, $html)
+    {
+        if(version_compare($this->jquery->getUiVersion(), "1.7.0") >= 0) {
+            $html = '<div'
+                  . $this->_htmlAttribs($attribs)
+                  . '>'.PHP_EOL
+                  . $html
+                  . '</div>'.PHP_EOL;
+        } else {
+            $html = '<ul'
+                  . $this->_htmlAttribs($attribs)
+                  . '>'.PHP_EOL
+                  . $html
+                  . '</ul>'.PHP_EOL;
+        }
+        return $html;
+    }
+
+    /**
+     * @return string
+     */
+    protected function getElementHtmlTemplate()
+    {
+        if($this->_elementHtmlTemplate == null) {
+            if(version_compare($this->jquery->getUiVersion(), "1.7.0") >= 0) {
+                $this->_elementHtmlTemplate = '<h3><a href="#">%s</a></h3><div>%s</div>';
+            } else {
+                $this->_elementHtmlTemplate = '<li class="ui-accordion-group"><a href="#" class="ui-accordion-header">%s</a><div class="ui-accordion-content">%s</div></li>';
+            }
+        }
+        return $this->_elementHtmlTemplate;
+    }
+
+    /**
+     * Set the accordion element template
+     *
+     * @param  string $htmlTemplate
+     * @return ZendX_JQuery_View_Helper_AccordionContainer
+     */
+    public function setElementHtmlTemplate($htmlTemplate)
+    {
+        if(substr_count($htmlTemplate, '%s') != 2) {
+            require_once "ZendX/JQuery/View/Exception.php";
+            throw new ZendX_JQuery_View_Exception(
+                "Accordion Container HTML Template requires two sprintf() string replace markers '%s'."
+            );
+        }
+        $this->_elementHtmlTemplate = $htmlTemplate;
+        return $this;
+    }
+}

+ 80 - 0
extras/library/ZendX/JQuery/View/Helper/AccordionPane.php

@@ -0,0 +1,80 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_View_Helper_UiWidgetPane
+ */
+require_once "UiWidgetPane.php";
+
+/**
+ * jQuery Accordion Pane, goes with Accordion Container
+ *
+ * @uses 	   ZendX_JQuery_View_Helper_AccordionContainer
+ * @package    ZendX_JQuery
+ * @subpackage View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+  */
+class ZendX_JQuery_View_Helper_AccordionPane extends ZendX_JQuery_View_Helper_UiWidgetPane
+{
+    /**
+     * Add accordion pane to the accordion with $id
+     *
+     * Directly add an additional pane to the accordion with $id. The title
+     * is to be given in the $options array as 'title' key. Additionally when
+     * specified with no arguments, the helper returns itsself as object making
+     * it possible to use {@link captureStart()} and {@link captureEnd()} methods.
+     *
+     * @param  string $id
+     * @param  string $content
+     * @param  array  $options
+     * @return string|ZendX_JQuery_View_Helper_AccordionPane
+     */
+    public function accordionPane($id=null, $content='', array $options=array())
+    {
+        if(0 === func_num_args()) {
+            return $this;
+        }
+
+        $name = '';
+        if(isset($options['title'])) {
+            $name = $options['title'];
+            unset($options['title']);
+        }
+
+        $this->_addPane($id, $name, $content, $options);
+        return '';
+    }
+
+    /**
+     * Method hooks into Accordion Container and registeres new pane
+     *
+     * @param string $id
+     * @param string $name
+     * @param string $content
+     * @param array  $options
+     */
+    protected function _addPane($id, $name, $content, array $options=array())
+    {
+        $this->view->accordionContainer()->addPane($id, $name, $content, $options);
+    }
+}

+ 308 - 0
extras/library/ZendX/JQuery/View/Helper/AjaxLink.php

@@ -0,0 +1,308 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see Zend_View_Helper_HtmlElement
+ */
+include_once "Zend/View/Helper/HtmlElement.php";
+
+/**
+ * jQuery Accordion Pane, goes with Accordion Container
+ *
+ * @uses 	   Zend_Json
+ * @package    ZendX_JQuery
+ * @subpackage View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_JQuery_View_Helper_AjaxLink extends Zend_View_Helper_HtmlElement
+{
+    /**
+     * Static because multiple instances accross views of AjaxLink could reset the counter and a
+     * subcontainer because of this single private class variable seems too much overhead.
+     *
+     * @staticvar Integer
+     */
+    private static $currentLinkCallbackId = 1;
+
+    /**
+     * Create an anchor that enables ajax-based requests and handling of the response.
+     *
+     * This helper creates links that make XmlHttpRequests to the server. It allows to
+     * inject the response into the DOM. Fancy effects going with the links can be enabled
+     * via simple callback shortnames. The functionality is mostly controlled by the $options
+     * array:
+     *
+     * $options
+     *  Key				Behaviour
+     *  =================================================================================
+     *  'update'        Update a container with the content fetched from $url
+     *  'method'        Explicit Requesting method mimicing the jQuery functionality: GET, POST
+     *  'inline'        True or false, wheater to inline the javascript in onClick=""
+     * 					atttribute or append it to jQuery onLoad Stack.
+     *  'complete'      String specifies javascript called after successful request or a
+     * 					shortname of a jQuery effect that should be applied to the 'update' element.
+     *  'beforeSend'	String specifies javascript called before the request is sent, or a
+     * 					shortname of a jQuery effect that should be applied to the link clicked.
+     *  'noscript'		True/false, include a noscript variant that directly requests
+     * 					the given $url (make sure to check $request->isXmlHttpRequest())
+     *  'dataType'		What type of data is the response returning? text, html, json?
+     *  'title'			HTML Attribute title of the Anchor
+     *  'class'			HTML Attribute class of the Anchor
+     *  'id'			HTML Attribute id of the Anchor
+     *  'attribs'		Array of Key-Value pairs with HTML Attribute names and their content.
+     *
+     * BeforeSend Callback:
+     * Can include shortcuts as a string assignment to fire of effects before sending of request.
+     * Possible shortcuts are 'fadeOut', 'fadeOutSlow', 'hide', 'hideSlow', 'slideUp', 'flash',
+     * @example $options = array('beforeSend' => 'hideSlow', 'complete' => 'show');
+     *
+     * @link   http://docs.jquery.com/Ajax
+     * @param  String $label Urls Title
+     * @param  String $url Link to Point to
+     * @param  Array $options
+     * @param  Array $params Key Value Pairs of GET/POST Parameters
+     * @return String
+     */
+    public function ajaxLink($label, $url, $options=null, $params=null)
+    {
+        $jquery = $this->view->jQuery();
+        $jquery->enable();
+
+        $jqHandler = (ZendX_JQuery_View_Helper_JQuery::getNoConflictMode()==true)?'$j':'$';
+
+        $attribs = array();
+        if(isset($options['attribs']) && is_array($options['attribs'])) {
+            $attribs = $options['attribs'];
+        }
+
+        //
+        // The next following 4 conditions check for html attributes that the link might need
+        //
+        if(empty($options['noscript']) || $options['noscript'] == false) {
+            $attribs['href'] = "#";
+        } else {
+            $attribs['href'] = $url;
+        }
+
+        if(!empty($options['title'])) {
+            $attribs['title'] = $options['title'];
+        }
+
+        // class value is an array because the jQuery CSS selector
+        // click event needs its own classname later on
+        if(!isset($attribs['class'])) {
+            $attribs['class'] = array();
+        } elseif(is_string($attribs['class'])) {
+            $attribs['class'] = explode(" ", $attribs['class']);
+        }
+        if(!empty($options['class'])) {
+            $attribs['class'][] = $options['class'];
+        }
+
+        if(!empty($options['id'])) {
+            $attribs['id'] = $options['id'];
+        }
+
+        //
+        // Execute Javascript inline?
+        //
+        $inline = false;
+        if(!empty($options['inline']) && $options['inline'] == true) {
+            $inline = true;
+        }
+
+        //
+        // Detect the callbacks:
+        // Just those two callbacks, beforeSend and complete can be defined for the $.get and $.post options.
+        // Pick all the defined callbacks and put them on their respective stacks.
+        //
+        $callbacks = array('beforeSend' => null, 'complete' => null);
+        if(isset($options['beforeSend'])) {
+            $callbacks['beforeSend'] = $options['beforeSend'];
+        }
+        if(isset($options['complete'])) {
+            $callbacks['complete'] = $options['complete'];
+        }
+
+        $updateContainer = false;
+        if(!empty($options['update']) && is_string($options['update'])) {
+            $updateContainer = $options['update'];
+
+            // Additionally check if there is a callback complete that is a shortcut to be executed
+            // on the specified update container
+            if(!empty($callbacks['complete'])) {
+                switch(strtolower($callbacks['complete'])) {
+                    case 'show':
+                        $callbacks['complete'] = sprintf('%s("%s").show();', $jqHandler, $updateContainer);
+                        break;
+                    case 'showslow':
+                        $callbacks['complete'] = sprintf('%s("%s").show("slow");', $jqHandler, $updateContainer);
+                        break;
+                    case 'shownormal':
+                        $callbacks['complete'] = sprintf('%s("%s").show("normal");', $jqHandler, $updateContainer);
+                        break;
+                    case 'showfast':
+                        $callbacks['complete'] = sprintf('%s("%s").show("fast");', $jqHandler, $updateContainer);
+                        break;
+                    case 'fadein':
+                        $callbacks['complete'] = sprintf('%s("%s").fadeIn("normal");', $jqHandler, $updateContainer);
+                        break;
+                    case 'fadeinslow':
+                        $callbacks['complete'] = sprintf('%s("%s").fadeIn("slow");', $jqHandler, $updateContainer);
+                        break;
+                    case 'fadeinfast':
+                        $callbacks['complete'] = sprintf('%s("%s").fadeIn("fast");', $jqHandler, $updateContainer);
+                        break;
+                    case 'slidedown':
+                        $callbacks['complete'] = sprintf('%s("%s").slideDown("normal");', $jqHandler, $updateContainer);
+                        break;
+                    case 'slidedownslow':
+                        $callbacks['complete'] = sprintf('%s("%s").slideDown("slow");', $jqHandler, $updateContainer);
+                        break;
+                    case 'slidedownfast':
+                        $callbacks['complete'] = sprintf('%s("%s").slideDown("fast");', $jqHandler, $updateContainer);
+                        break;
+                }
+            }
+        }
+
+        if(empty($options['dataType'])) {
+            $options['dataType'] = "html";
+        }
+
+        $requestHandler = $this->_determineRequestHandler($options, (count($params)>0)?true:false);
+
+        $callbackCompleteJs = array();
+        if($updateContainer != false) {
+            if($options['dataType'] == "text") {
+                $callbackCompleteJs[] = sprintf('%s("%s").text(data);', $jqHandler, $updateContainer);
+            } else {
+                $callbackCompleteJs[] = sprintf('%s("%s").html(data);', $jqHandler, $updateContainer);
+            }
+        }
+        if($callbacks['complete'] != null) {
+            $callbackCompleteJs[] = $callbacks['complete'];
+        }
+
+        if(isset($params) && count($params) > 0) {
+            $params = ZendX_JQuery::encodeJson($params);
+        } else {
+            $params = '{}';
+        }
+
+        $js = array();
+        if($callbacks['beforeSend'] != null) {
+            switch(strtolower($callbacks['beforeSend'])) {
+                case 'fadeout':
+                    $js[] = sprintf('%s(this).fadeOut();', $jqHandler);
+                    break;
+                case 'fadeoutslow':
+                    $js[] = sprintf('%s(this).fadeOut("slow");', $jqHandler);
+                    break;
+                case 'fadeoutfast':
+                    $js[] = sprintf('%s(this).fadeOut("fast");', $jqHandler);
+                    break;
+                case 'hide':
+                    $js[] = sprintf('%s(this).hide();', $jqHandler);
+                    break;
+                case 'hideslow':
+                    $js[] = sprintf('%s(this).hide("slow");', $jqHandler);
+                    break;
+                case 'hidefast':
+                    $js[] = sprintf('%s(this).hide("fast");', $jqHandler);
+                    break;
+                case 'slideup':
+                    $js[] = sprintf('%s(this).slideUp(1000);', $jqHandler);
+                    break;
+                default:
+                    $js[] = $callbacks['beforeSend'];
+                    break;
+            }
+        }
+
+        switch($requestHandler) {
+            case 'GET':
+                $js[] = sprintf('%s.get("%s", %s, function(data, textStatus) { %s }, "%s");return false;',
+                    $jqHandler, $url, $params, implode(' ', $callbackCompleteJs), $options['dataType']);
+                break;
+            case 'POST':
+                $js[] = sprintf('%s.post("%s", %s, function(data, textStatus) { %s }, "%s");return false;',
+                    $jqHandler, $url, $params, implode(' ', $callbackCompleteJs), $options['dataType']);
+                break;
+        }
+
+        $js = implode($js);
+
+        if($inline == true) {
+            $attribs['onclick'] = $js;
+        } else {
+            if(!isset($attribs['id'])) {
+                $clickClass = sprintf("ajaxLink%d", ZendX_JQuery_View_Helper_AjaxLink::$currentLinkCallbackId);
+                ZendX_JQuery_View_Helper_AjaxLink::$currentLinkCallbackId++;
+
+                $attribs['class'][] = $clickClass;
+                $onLoad = sprintf('%s("a.%s").click(function() { %s });', $jqHandler, $clickClass, $js);
+            } else {
+                $onLoad = sprintf('%s("a#%s").click(function() { %s });', $jqHandler, $attribs['id'], $js);
+            }
+
+            $jquery->addOnLoad($onLoad);
+        }
+
+        if(count($attribs['class']) > 0) {
+            $attribs['class'] = implode(" ", $attribs['class']);
+        } else {
+            unset($attribs['class']);
+        }
+
+        $html = '<a'
+            . $this->_htmlAttribs($attribs)
+            . '>'
+            . $label
+            . '</a>';
+        return $html;
+    }
+
+    /**
+     * Determine which request method (GET or POST) should be used.
+     *
+     * Normally the request method is determined implicitly by the rule,
+     * if addiotional params are sent, POST, if not GET. You can overwrite
+     * this behaviiour by implicitly setting $options['method'] = "POST|GET";
+     *
+     * @param  Array   $options
+     * @param  Boolean $hasParams
+     * @return String
+     */
+    protected function _determineRequestHandler($options, $hasParams)
+    {
+        if(isset($options['method']) && in_array(strtoupper($options['method']), array('GET', 'POST'))) {
+            return strtoupper($options['method']);
+        }
+        $requestHandler = "GET";
+        if($hasParams == true) {
+            $requestHandler = "POST";
+        }
+        return $requestHandler;
+    }
+}

+ 89 - 0
extras/library/ZendX/JQuery/View/Helper/AutoComplete.php

@@ -0,0 +1,89 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_View_Helper_UiWidget
+ */
+require_once "ZendX/JQuery/View/Helper/UiWidget.php";
+
+/**
+ * jQuery Autocomplete View Helper
+ *
+ * @uses 	   Zend_Json, Zend_View_Helper_FormText
+ * @package    ZendX_JQuery
+ * @subpackage View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_JQuery_View_Helper_AutoComplete extends ZendX_JQuery_View_Helper_UiWidget
+{
+    /**
+     * Builds an AutoComplete ready input field.
+     *
+     * This view helper builds an input field with the {@link Zend_View_Helper_FormText} FormText
+     * Helper and adds additional javascript to the jQuery stack to initialize an AutoComplete
+     * field. Make sure you have set one out of the two following options: $params['data'] or
+     * $params['url']. The first one accepts an array as data input to the autoComplete, the
+     * second accepts an url, where the autoComplete content is returned from. For the format
+     * see jQuery documentation.
+     *
+     * @link   http://docs.jquery.com/UI/Autocomplete
+     * @throws ZendX_JQuery_Exception
+     * @param  String $id
+     * @param  String $value
+     * @param  array $params
+     * @param  array $attribs
+     * @return String
+     */
+    public function autoComplete($id, $value = null, array $params = array(), array $attribs = array())
+    {
+        $attribs = $this->_prepareAttributes($id, $value, $attribs);
+
+        if (!isset($params['source'])) {
+            if (isset($params['url'])) {
+                $params['source'] = $params['url'];
+                unset($params['url']);
+            } else if (isset($params['data'])) {
+                $params['source'] = $params['data'];
+                unset($params['data']);
+            } else {
+                require_once "ZendX/JQuery/Exception.php";
+                throw new ZendX_JQuery_Exception(
+                    "Cannot construct AutoComplete field without specifying 'source' field, ".
+                    "either an url or an array of elements."
+                );
+            }
+        }
+
+        $params = ZendX_JQuery::encodeJson($params);
+
+        $js = sprintf('%s("#%s").autocomplete(%s);',
+                ZendX_JQuery_View_Helper_JQuery::getJQueryHandler(),
+                $attribs['id'],
+                $params
+        );
+
+        $this->jquery->addOnLoad($js);
+
+        return $this->view->formText($id, $value, $attribs);
+    }
+}

+ 73 - 0
extras/library/ZendX/JQuery/View/Helper/ColorPicker.php

@@ -0,0 +1,73 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_View_Helper_UiWidget
+ */
+require_once "ZendX/JQuery/View/Helper/UiWidget.php";
+
+/**
+ * jQuery Color Picker View Helper
+ *
+ * @uses 	   Zend_View_Helper_FormText
+ * @package    ZendX_JQuery
+ * @subpackage View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_JQuery_View_Helper_ColorPicker extends ZendX_JQuery_View_Helper_UiWidget
+{
+	/**
+	 * Render a Color Picker in an FormText field.
+	 *
+	 * @link   http://docs.jquery.com/UI/ColorPicker
+	 * @param  string $id
+	 * @param  string $value
+	 * @param  array  $params
+	 * @param  array  $attribs
+	 * @return string
+	 */
+    public function colorPicker($id, $value='', array $params=array(), array $attribs=array())
+    {
+	    $attribs = $this->_prepareAttributes($id, $value, $attribs);
+
+	    if(strlen($value) >= 6) {
+	        $params['color'] = $value;
+	    }
+
+	    if(count($params) > 0) {
+            $params = ZendX_JQuery::encodeJson($params);
+	    } else {
+	        $params = "{}";
+	    }
+
+        $js = sprintf('%s("#%s").colorpicker(%s);',
+            ZendX_JQuery_View_Helper_JQuery::getJQueryHandler(),
+            $attribs['id'],
+            $params
+        );
+
+        $this->jquery->addOnLoad($js);
+
+	    return $this->view->formText($id, $value, $attribs);
+    }
+}

+ 135 - 0
extras/library/ZendX/JQuery/View/Helper/DatePicker.php

@@ -0,0 +1,135 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see Zend_Registry
+ */
+require_once "Zend/Registry.php";
+
+/**
+ * @see ZendX_JQuery_View_Helper_UiWidget
+ */
+require_once "ZendX/JQuery/View/Helper/UiWidget.php";
+
+/**
+ * jQuery Date Picker View Helper
+ *
+ * @uses 	   Zend_View_Helper_FormText
+ * @package    ZendX_JQuery
+ * @subpackage View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_JQuery_View_Helper_DatePicker extends ZendX_JQuery_View_Helper_UiWidget
+{
+    /**
+     * Create a jQuery UI Widget Date Picker
+     *
+     * @link   http://docs.jquery.com/UI/Datepicker
+     * @param  string $id
+     * @param  string $value
+     * @param  array  $params jQuery Widget Parameters
+     * @param  array  $attribs HTML Element Attributes
+     * @return string
+     */
+    public function datePicker($id, $value = null, array $params = array(), array $attribs = array())
+    {
+        $attribs = $this->_prepareAttributes($id, $value, $attribs);
+
+        if(!isset($params['dateFormat']) && Zend_Registry::isRegistered('Zend_Locale')) {
+            $params['dateFormat'] = self::resolveZendLocaleToDatePickerFormat();
+        }
+
+        // TODO: Allow translation of DatePicker Text Values to get this action from client to server
+        $params = ZendX_JQuery::encodeJson($params);
+
+        $js = sprintf('%s("#%s").datepicker(%s);',
+                ZendX_JQuery_View_Helper_JQuery::getJQueryHandler(),
+                $attribs['id'],
+                $params
+        );
+
+        $this->jquery->addOnLoad($js);
+
+        return $this->view->formText($id, $value, $attribs);
+    }
+
+    /**
+     * A Check for Zend_Locale existance has already been done in {@link datePicker()}
+     * this function only resolves the default format from Zend Locale to
+     * a jQuery Date Picker readable format. This function can be potentially buggy
+     * because of its easy nature and is therefore stripped from the core functionality
+     * to be easily overriden.
+     *
+     * @return string
+     */
+    public static function resolveZendLocaleToDatePickerFormat($format=null)
+    {
+        if($format == null) {
+            $locale = Zend_Registry::get('Zend_Locale');
+            if( !($locale instanceof Zend_Locale) ) {
+                require_once "ZendX/JQuery/Exception.php";
+                throw new ZendX_JQuery_Exception("Cannot resolve Zend Locale format by default, no application wide locale is set.");
+            }
+            /**
+             * @see Zend_Locale_Format
+             */
+            require_once "Zend/Locale/Format.php";
+            $format = Zend_Locale_Format::getDateFormat($locale);
+        }
+
+        $dateFormat = array(
+            'EEEEE' => 'D', 'EEEE' => 'DD', 'EEE' => 'D', 'EE' => 'D', 'E' => 'D',
+            'MMMM' => 'MM', 'MMM' => 'M', 'MM' => 'mm', 'M' => 'm',
+            'YYYYY' => 'yy', 'YYYY' => 'yy', 'YYY' => 'yy', 'YY' => 'y', 'Y' => 'yy',
+            'yyyyy' => 'yy', 'yyyy' => 'yy', 'yyy' => 'yy', 'yy' => 'y', 'y' => 'yy',
+            'G' => '', 'e' => '', 'a' => '', 'h' => '', 'H' => '', 'm' => '',
+            's' => '', 'S' => '', 'z' => '', 'Z' => '', 'A' => '',
+        );
+
+        $newFormat = "";
+        $isText = false;
+        $i = 0;
+        while($i < strlen($format)) {
+            $chr = $format[$i];
+            if($chr == '"' || $chr == "'") {
+                $isText = !$isText;
+            }
+            $replaced = false;
+            if($isText == false) {
+                foreach($dateFormat AS $zl => $jql) {
+                    if(substr($format, $i, strlen($zl)) == $zl) {
+                        $chr = $jql;
+                        $i += strlen($zl);
+                        $replaced = true;
+                    }
+                }
+            }
+            if($replaced == false) {
+                $i++;
+            }
+            $newFormat .= $chr;
+        }
+
+        return $newFormat;
+    }
+}

+ 74 - 0
extras/library/ZendX/JQuery/View/Helper/DialogContainer.php

@@ -0,0 +1,74 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_View_Helper_UiWidget
+ */
+require_once "ZendX/JQuery/View/Helper/UiWidget.php";
+
+/**
+ * jQuery Dialog View Helper
+ *
+ * @package    ZendX_JQuery
+ * @subpackage View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_JQuery_View_Helper_DialogContainer extends ZendX_JQuery_View_Helper_UiWidget
+{
+    /**
+     * Create a jQuery UI Dialog filled with the given content
+     *
+     * @link   http://docs.jquery.com/UI/Dialog
+     * @param  string $id
+     * @param  string $content
+     * @param  array $params
+     * @param  array $attribs
+     * @return string
+     */
+    public function dialogContainer($id, $content, $params=array(), $attribs=array())
+    {
+        if (!array_key_exists('id', $attribs)) {
+            $attribs['id'] = $id;
+        }
+
+        if(count($params) > 0) {
+            $params = ZendX_JQuery::encodeJson($params);
+        } else {
+            $params = "{}";
+        }
+
+        $js = sprintf('%s("#%s").dialog(%s);',
+                ZendX_JQuery_View_Helper_JQuery::getJQueryHandler(),
+                $attribs['id'],
+                $params
+        );
+        $this->jquery->addOnLoad($js);
+
+        $html = '<div'
+                . $this->_htmlAttribs($attribs)
+                . '>'
+                . $content
+                . '</div>';
+        return $html;
+    }
+}

+ 167 - 0
extras/library/ZendX/JQuery/View/Helper/JQuery.php

@@ -0,0 +1,167 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery
+ */
+require_once "ZendX/JQuery.php";
+
+/**
+ * @see Zend_Registry
+ */
+require_once 'Zend/Registry.php';
+
+/**
+ * @see Zend_View_Helper_Abstract
+ */
+require_once 'Zend/View/Helper/Abstract.php';
+
+/**
+ * @see ZendX_JQuery_View_Helper_JQuery_Container
+ */
+require_once "ZendX/JQuery/View/Helper/JQuery/Container.php";
+
+/**
+ * jQuery Helper. Functions as a stack for code and loads all jQuery dependencies.
+ *
+ * @uses 	   Zend_Json
+ * @package    ZendX_JQuery
+ * @subpackage View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_JQuery_View_Helper_JQuery extends Zend_View_Helper_Abstract
+{
+    /**
+     * @var Zend_View_Interface
+     */
+    public $view;
+
+	/**
+	 * jQuery no Conflict Mode
+	 *
+	 * @see	      http://docs.jquery.com/Using_jQuery_with_Other_Libraries
+	 * @staticvar Boolean Status of noConflict Mode
+	 */
+    private static $noConflictMode = false;
+
+   /**
+     * Initialize helper
+     *
+     * Retrieve container from registry or create new container and store in
+     * registry.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        $registry = Zend_Registry::getInstance();
+        if (!isset($registry[__CLASS__])) {
+            require_once 'ZendX/JQuery/View/Helper/JQuery/Container.php';
+            $container = new ZendX_JQuery_View_Helper_JQuery_Container();
+            $registry[__CLASS__] = $container;
+        }
+        $this->_container = $registry[__CLASS__];
+    }
+
+	/**
+	 * Return jQuery View Helper class, to execute jQuery library related functions.
+	 *
+	 * @return ZendX_JQuery_View_Helper_JQuery_Container
+	 */
+    public function jQuery()
+    {
+        return $this->_container;
+    }
+
+    /**
+     * Set view object
+     *
+     * @param  Zend_View_Interface $view
+     * @return void
+     */
+    public function setView(Zend_View_Interface $view)
+    {
+        $this->view = $view;
+        $this->_container->setView($view);
+    }
+
+    /**
+     * Proxy to container methods
+     *
+     * @param  string $method
+     * @param  array  $args
+     * @return mixed
+     * @throws Zend_View_Exception For invalid method calls
+     */
+    public function __call($method, $args)
+    {
+        if (!method_exists($this->_container, $method)) {
+            require_once 'Zend/View/Exception.php';
+            throw new Zend_View_Exception(sprintf('Invalid method "%s" called on jQuery view helper', $method));
+        }
+
+        return call_user_func_array(array($this->_container, $method), $args);
+    }
+
+	/**
+	 * Enable the jQuery internal noConflict Mode to work with
+	 * other Javascript libraries. Will setup jQuery in the variable
+	 * $j instead of $ to overcome conflicts.
+	 *
+	 * @link http://docs.jquery.com/Using_jQuery_with_Other_Libraries
+	 */
+    public static function enableNoConflictMode()
+    {
+    	self::$noConflictMode = true;
+    }
+
+	/**
+	 * Disable noConflict Mode of jQuery if this was previously enabled.
+	 *
+	 * @return void
+	 */
+    public static function disableNoConflictMode()
+    {
+    	self::$noConflictMode = false;
+    }
+
+	/**
+	 * Return current status of the jQuery no Conflict Mode
+	 *
+	 * @return Boolean
+	 */
+    public static function getNoConflictMode()
+    {
+    	return self::$noConflictMode;
+    }
+
+    /**
+     * Return current jQuery handler based on noConflict mode settings.
+     *
+     * @return String
+     */
+    public static function getJQueryHandler()
+    {
+        return ((self::getNoConflictMode()==true)?'$j':'$');
+    }
+}

+ 862 - 0
extras/library/ZendX/JQuery/View/Helper/JQuery/Container.php

@@ -0,0 +1,862 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright   Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery
+ */
+require_once 'ZendX/JQuery.php';
+
+/**
+ * jQuery View Helper. Transports all jQuery stack and render information across all views.
+ *
+ * @uses       ZendX_JQuery_View_Helper_JQuery_Container
+ * @package    ZendX_JQuery
+ * @subpackage View
+ * @copyright  Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_JQuery_View_Helper_JQuery_Container
+{
+    /**
+     * Path to local webserver jQuery library
+     *
+     * @var String
+     */
+    protected $_jqueryLibraryPath = null;
+
+    /**
+     * Additional javascript files that for jQuery Helper components.
+     *
+     * @var Array
+     */
+    protected $_javascriptSources = array();
+
+    /**
+     * Indicates wheater the jQuery View Helper is enabled.
+     *
+     * @var Boolean
+     */
+    protected $_enabled = false;
+
+    /**
+     * Indicates if a capture start method for javascript or onLoad has been called.
+     *
+     * @var Boolean
+     */
+    protected $_captureLock = false;
+
+    /**
+     * Additional javascript statements that need to be executed after jQuery lib.
+     *
+     * @var Array
+     */
+    protected $_javascriptStatements = array();
+
+    /**
+     * Additional stylesheet files for jQuery related components.
+     *
+     * @var Array
+     */
+    protected $_stylesheets = array();
+
+    /**
+     * jQuery onLoad statements Stack
+     *
+     * @var Array
+     */
+    protected $_onLoadActions = array();
+
+    /**
+     * View is rendered in XHTML or not.
+     *
+     * @var Boolean
+     */
+    protected $_isXhtml = false;
+
+    /**
+     * Default CDN jQuery Library version
+     *
+     * @var String
+     */
+    protected $_version = ZendX_JQuery::DEFAULT_JQUERY_VERSION;
+
+    /**
+     * Default Render Mode (all parts)
+     *
+     * @var Integer
+     */
+    protected $_renderMode = ZendX_JQuery::RENDER_ALL;
+
+    /**
+     * jQuery UI Library Enabled
+     *
+     * @var Boolean
+     */
+    protected $_uiEnabled = false;
+
+    /**
+     * Local jQuery UI Path. Use Google CDN if
+     * variable is null
+     *
+     * @var String
+     */
+    protected $_uiPath = null;
+
+    /**
+     * jQuery UI Google CDN Version
+     *
+     * @var String
+     */
+    protected $_uiVersion = ZendX_JQuery::DEFAULT_UI_VERSION;
+
+    /**
+     * Load CDN Path from SSL or Non-SSL?
+     *
+     * @var boolean
+     */
+    protected $_loadSslCdnPath = false;
+
+    /**
+     * View Instance
+     *
+     * @var Zend_View_Interface
+     */
+    public $view = null;
+
+    /**
+     * Set view object
+     *
+     * @param  Zend_View_Interface $view
+     * @return void
+     */
+    public function setView(Zend_View_Interface $view)
+    {
+        $this->view = $view;
+    }
+
+    /**
+     * Enable jQuery
+     *
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function enable()
+    {
+        $this->_enabled = true;
+        return $this;
+    }
+
+    /**
+     * Disable jQuery
+     *
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function disable()
+    {
+        $this->uiDisable();
+        $this->_enabled = false;
+        return $this;
+    }
+
+    /**
+     * Is jQuery enabled?
+     *
+     * @return boolean
+     */
+    public function isEnabled()
+    {
+        return $this->_enabled;
+    }
+
+    /**
+     * Set the version of the jQuery library used.
+     *
+     * @param string $version
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function setVersion($version)
+    {
+        $this->_version = $version;
+        return $this;
+    }
+
+    /**
+     * Get the version used with the jQuery library
+     *
+     * @return string
+     */
+    public function getVersion()
+    {
+        return $this->_version;
+    }
+
+    /**
+     * Use CDN, using version specified. Currently supported
+     * by Googles Ajax Library API are: 1.2.3, 1.2.6
+     *
+     * @deprecated As of version 1.8, use {@link setVersion()} instead.
+     * @param  string $version
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function setCdnVersion($version = null)
+    {
+        return $this->setVersion($version);
+    }
+
+    /**
+     * Get CDN version
+     *
+     * @deprecated As of version 1.8, use {@link getVersion()} instead.
+     * @return string
+     */
+    public function getCdnVersion()
+    {
+        return $this->getVersion();
+    }
+
+    /**
+     * Set Use SSL on CDN Flag
+     *
+     * @param bool $flag
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function setCdnSsl($flag)
+    {
+        $this->_loadSslCdnPath = (boolean) $flag;
+        return $this;
+    }
+
+    /**
+     * Get Flag of SSL on CDN
+     *
+     * @return boolean True if SSL is used on CDN
+     */
+    public function getCdnSsl()
+    {
+        return $this->_loadSslCdnPath;
+    }
+
+    /**
+     * Are we using the CDN?
+     *
+     * @return boolean
+     */
+    public function useCdn()
+    {
+        return !$this->useLocalPath();
+    }
+
+    /**
+     * Set path to local jQuery library
+     *
+     * @param  string $path
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function setLocalPath($path)
+    {
+        $this->_jqueryLibraryPath = (string) $path;
+        return $this;
+    }
+
+    /**
+     * Enable jQuery UI Library Rendering
+     *
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function uiEnable()
+    {
+        $this->enable();
+        $this->_uiEnabled = true;
+        return $this;
+    }
+
+    /**
+     * Disable jQuery UI Library Rendering
+     *
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function uiDisable()
+    {
+        $this->_uiEnabled = false;
+        return $this;
+    }
+
+    /**
+     * Check wheater currently the jQuery UI library is enabled.
+     *
+     * @return boolean
+     */
+    public function uiIsEnabled()
+    {
+         return $this->_uiEnabled;
+    }
+
+    /**
+     * Set jQuery UI version used.
+     * 
+     * @param  string $version
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function setUiVersion($version)
+    {
+        $this->_uiVersion = $version;
+        return $this;
+    }
+
+    /**
+     * Get jQuery UI Version used.
+     *
+     * @return string
+     */
+    public function getUiVersion()
+    {
+        return $this->_uiVersion;
+    }
+
+    /**
+     * Set jQuery UI CDN Version
+     *
+     * @deprecated As of 1.8 use {@link setUiVersion()}
+     *
+     * @param string $version
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function setUiCdnVersion($version = '1.5.2')
+    {
+        return $this->setUiVersion($version);
+    }
+
+    /**
+     * Return jQuery UI CDN Version
+     *
+     * @deprecated As of 1.8 use {@link getUiVersion()}
+     *
+     * @return String
+     */
+    public function getUiCdnVersion()
+    {
+        return $this->getUiVersion();
+    }
+
+    /**
+     * Set local path to jQuery UI library
+     *
+     * @param String $path
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function setUiLocalPath($path)
+    {
+        $this->_uiPath = (string) $path;
+        return $this;
+    }
+
+    /**
+     * Return the local jQuery UI Path if set.
+     *
+     * @return string
+     */
+    public function getUiPath()
+    {
+        return $this->_uiPath;
+    }
+
+    /**
+     * Proxies to getUiPath() for consistency in function naming.
+     *
+     * @return string
+     */
+    public function getUiLocalPath()
+    {
+        return $this->getUiPath();
+    }
+
+    /**
+     * Is the jQuery Ui loaded from local scope?
+     *
+     * @return boolean
+     */
+    public function useUiLocal()
+    {
+        return (null === $this->_uiPath) ? false : true;
+    }
+
+    /**
+     * Is the jQuery Ui enabled and loaded from CDN?
+     *
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function useUiCdn()
+    {
+        return !$this->useUiLocal();
+    }
+
+    /**
+     * Get local path to jQuery
+     *
+     * @return string
+     */
+    public function getLocalPath()
+    {
+        return $this->_jqueryLibraryPath;
+    }
+
+    /**
+     * Are we using a local path?
+     *
+     * @return boolean
+     */
+    public function useLocalPath()
+    {
+        return (null === $this->_jqueryLibraryPath) ? false : true;
+    }
+
+    /**
+     * Start capturing routines to run onLoad
+     *
+     * @return boolean
+     * @throws Zend_Exception
+     */
+    public function onLoadCaptureStart()
+    {
+        if ($this->_captureLock) {
+            require_once 'Zend/Exception.php';
+            throw new Zend_Exception('Cannot nest onLoad captures');
+        }
+
+        $this->_captureLock = true;
+        return ob_start();
+    }
+
+    /**
+     * Stop capturing routines to run onLoad
+     *
+     * @return boolean
+     */
+    public function onLoadCaptureEnd()
+    {
+        $data               = ob_get_clean();
+        $this->_captureLock = false;
+
+        $this->addOnLoad($data);
+        return true;
+    }
+
+    /**
+     * Capture arbitrary javascript to include in jQuery script
+     *
+     * @return boolean
+     * @throws Zend_Exception
+     */
+    public function javascriptCaptureStart()
+    {
+        if ($this->_captureLock) {
+            require_once 'Zend/Exception.php';
+            throw new Zend_Exception('Cannot nest captures');
+        }
+
+        $this->_captureLock = true;
+        return ob_start();
+    }
+
+    /**
+     * Finish capturing arbitrary javascript to include in jQuery script
+     *
+     * @return boolean
+     */
+    public function javascriptCaptureEnd()
+    {
+        $data               = ob_get_clean();
+        $this->_captureLock = false;
+
+        $this->addJavascript($data);
+        return true;
+    }
+
+    /**
+     * Add a Javascript File to the include stack.
+     *
+     * @param string $path
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function addJavascriptFile($path)
+    {
+        $path = (string) $path;
+        if (!in_array($path, $this->_javascriptSources)) {
+            $this->_javascriptSources[] = $path;
+        }
+        return $this;
+    }
+
+    /**
+     * Return all currently registered Javascript files.
+     *
+     * This does not include the jQuery library, which is handled by another retrieval
+     * strategy.
+     *
+     * @return array
+     */
+    public function getJavascriptFiles()
+    {
+        return $this->_javascriptSources;
+    }
+
+    /**
+     * Clear all currently registered Javascript files.
+     *
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function clearJavascriptFiles()
+    {
+        $this->_javascriptSources = array();
+        return $this;
+    }
+
+    /**
+     * Add arbitrary javascript to execute in jQuery JS container
+     *
+     * @param  string $js
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function addJavascript($js)
+    {
+        $this->_javascriptStatements[] = $js;
+        $this->enable();
+        return $this;
+    }
+
+    /**
+     * Return all registered javascript statements
+     *
+     * @return array
+     */
+    public function getJavascript()
+    {
+        return $this->_javascriptStatements;
+    }
+
+    /**
+     * Clear arbitrary javascript stack
+     *
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function clearJavascript()
+    {
+        $this->_javascriptStatements = array();
+        return $this;
+    }
+
+    /**
+     * Add a stylesheet
+     *
+     * @param  string $path
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function addStylesheet($path)
+    {
+        $path = (string) $path;
+        if (!in_array($path, $this->_stylesheets)) {
+            $this->_stylesheets[] = (string) $path;
+        }
+        return $this;
+    }
+
+    /**
+     * Retrieve registered stylesheets
+     *
+     * @return array
+     */
+    public function getStylesheets()
+    {
+        return $this->_stylesheets;
+    }
+
+    /**
+     * Clear all currently registered stylesheets files
+     *
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function clearStylesheets()
+    {
+        $this->_stylesheets = array();
+        return $this;
+    }
+
+    /**
+     * Add a script to execute onLoad
+     *
+     * @param  string $callback Lambda
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function addOnLoad($callback)
+    {
+        if (!in_array($callback, $this->_onLoadActions, true)) {
+            $this->_onLoadActions[] = $callback;
+        }
+        $this->enable();
+        return $this;
+    }
+
+    /**
+     * Retrieve all registered onLoad actions
+     *
+     * @return array
+     */
+    public function getOnLoadActions()
+    {
+        return $this->_onLoadActions;
+    }
+
+    /**
+     * Clear the onLoadActions stack.
+     *
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function clearOnLoadActions()
+    {
+        $this->_onLoadActions = array();
+        return $this;
+    }
+
+    /**
+     * Set which parts of the jQuery enviroment should be rendered.
+     *
+     * This function allows for a gradual refactoring of the jQuery code
+     * rendered by calling __toString(). Use ZendX_JQuery::RENDER_*
+     * constants. By default all parts of the enviroment are rendered.
+     *
+     * @see    ZendX_JQuery::RENDER_ALL
+     * @param  integer $mask
+     * @return ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    public function setRenderMode($mask)
+    {
+        $this->_renderMode = $mask;
+        return $this;
+    }
+
+    /**
+     * Return bitmask of the current Render Mode
+     * @return integer
+     */
+    public function getRenderMode()
+    {
+        return $this->_renderMode;
+    }
+
+    /**
+     * String representation of jQuery environment
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        if (!$this->isEnabled()) {
+            return '';
+        }
+
+        $this->_isXhtml = $this->view->doctype()->isXhtml();
+
+        $html  = $this->_renderStylesheets() . PHP_EOL
+               . $this->_renderScriptTags() . PHP_EOL
+               . $this->_renderExtras();
+        return $html;
+    }
+
+    /**
+     * Render jQuery stylesheets
+     *
+     * @return string
+     */
+    protected function _renderStylesheets()
+    {
+        if(0 == ($this->getRenderMode() & ZendX_JQuery::RENDER_STYLESHEETS)) {
+            return '';
+        }
+
+        foreach ($this->getStylesheets() as $stylesheet) {
+            $stylesheets[] = $stylesheet;
+        }
+
+        if (empty($stylesheets)) {
+            return '';
+        }
+
+        array_reverse($stylesheets);
+        $style = '';
+        foreach($stylesheets AS $stylesheet) {
+            if ($this->view instanceof Zend_View_Abstract) {
+                $closingBracket = ($this->view->doctype()->isXhtml()) ? ' />' : '>';
+            } else {
+                $closingBracket = ' />';
+            }
+
+            $style .= '<link rel="stylesheet" href="'.$stylesheet.'" '.
+                      'type="text/css" media="screen"' . $closingBracket . PHP_EOL;
+        }
+
+        return $style;
+    }
+
+    /**
+     * Renders all javascript file related stuff of the jQuery enviroment.
+     *
+     * @return string
+     */
+    protected function _renderScriptTags()
+    {
+        $scriptTags = '';
+        if( ($this->getRenderMode() & ZendX_JQuery::RENDER_LIBRARY) > 0) {
+            $source = $this->_getJQueryLibraryPath();
+
+            $scriptTags .= '<script type="text/javascript" src="' . $source . '"></script>' . PHP_EOL;
+
+            if($this->uiIsEnabled()) {
+                $uiPath = $this->_getJQueryUiLibraryPath();
+                $scriptTags .= '<script type="text/javascript" src="'.$uiPath.'"></script>' . PHP_EOL;
+            }
+
+            if(ZendX_JQuery_View_Helper_JQuery::getNoConflictMode() == true) {
+                $scriptTags .= '<script type="text/javascript">var $j = jQuery.noConflict();</script>' . PHP_EOL;
+            }
+        }
+
+        if( ($this->getRenderMode() & ZendX_JQuery::RENDER_SOURCES) > 0) {
+            foreach($this->getJavascriptFiles() AS $javascriptFile) {
+                $scriptTags .= '<script type="text/javascript" src="' . $javascriptFile . '"></script>' . PHP_EOL;
+            }
+        }
+
+        return $scriptTags;
+    }
+
+    /**
+     * Renders all javascript code related stuff of the jQuery enviroment.
+     *
+     * @return string
+     */
+    protected function _renderExtras()
+    {
+        $onLoadActions = array();
+        if( ($this->getRenderMode() & ZendX_JQuery::RENDER_JQUERY_ON_LOAD) > 0) {
+            foreach ($this->getOnLoadActions() as $callback) {
+                $onLoadActions[] = $callback;
+            }
+        }
+
+        $javascript = '';
+        if( ($this->getRenderMode() & ZendX_JQuery::RENDER_JAVASCRIPT) > 0) {
+            $javascript = implode("\n    ", $this->getJavascript());
+        }
+
+        $content = '';
+
+        if (!empty($onLoadActions)) {
+            if(true === ZendX_JQuery_View_Helper_JQuery::getNoConflictMode()) {
+                $content .= '$j(document).ready(function() {'."\n    ";
+            } else {
+                $content .= '$(document).ready(function() {'."\n    ";
+            }
+            $content .= implode("\n    ", $onLoadActions) . "\n";
+            $content .= '});'."\n";
+        }
+
+        if (!empty($javascript)) {
+            $content .= $javascript . "\n";
+        }
+
+        if (preg_match('/^\s*$/s', $content)) {
+            return '';
+        }
+
+        $html = '<script type="text/javascript">' . PHP_EOL
+              . (($this->_isXhtml) ? '//<![CDATA[' : '//<!--') . PHP_EOL
+              . $content
+              . (($this->_isXhtml) ? '//]]>' : '//-->') . PHP_EOL
+              . PHP_EOL . '</script>';
+        return $html;
+    }
+
+    /**
+     * @return string
+     */
+    protected function _getJQueryLibraryBaseCdnUri()
+    {
+        if($this->_loadSslCdnPath == true) {
+            $baseUri = ZendX_JQuery::CDN_BASE_GOOGLE_SSL;
+        } else {
+            $baseUri = ZendX_JQuery::CDN_BASE_GOOGLE;
+        }
+        return $baseUri;
+    }
+
+    /**
+     * @return string
+     */
+    protected function _getJQueryUiLibraryBaseCdnUri()
+    {
+        if($this->_loadSslCdnPath == true) {
+            $baseUri = ZendX_JQuery::CDN_BASE_GOOGLE_SSL;
+        } else {
+            $baseUri = ZendX_JQuery::CDN_BASE_GOOGLE;
+        }
+        return $baseUri;
+    }
+
+    /**
+     * Internal function that constructs the include path of the jQuery library.
+     *
+     * @return string
+     */
+    protected function _getJQueryLibraryPath()
+    {
+        if($this->_jqueryLibraryPath != null) {
+            $source = $this->_jqueryLibraryPath;
+        } else {
+            $baseUri = $this->_getJQueryLibraryBaseCdnUri();
+            $source  = $baseUri
+                     . ZendX_JQuery::CDN_SUBFOLDER_JQUERY
+                     . $this->getVersion()
+                     . ZendX_JQuery::CDN_JQUERY_PATH_GOOGLE;
+        }
+
+        return $source;
+    }
+
+    /**
+     * Internal function that constructs the include path of the jQueryUI library.
+     *
+     * @return string
+     */
+    protected function _getJQueryUiLibraryPath()
+    {
+        if($this->useUiCdn()) {
+            $baseUri = $this->_getJQueryLibraryBaseCdnUri();
+            $uiPath  = $baseUri
+                     . ZendX_JQuery::CDN_SUBFOLDER_JQUERYUI
+                     . $this->getUiVersion()
+                     . '/jquery-ui.min.js';
+        } else if($this->useUiLocal()) {
+            $uiPath = $this->getUiPath();
+        }
+
+        return $uiPath;
+    }
+}

+ 164 - 0
extras/library/ZendX/JQuery/View/Helper/Slider.php

@@ -0,0 +1,164 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_View_Helper_UiWidget
+ */
+require_once "ZendX/JQuery/View/Helper/UiWidget.php";
+
+/**
+ * jQuery Slider View Helper
+ *
+ * @uses 	   Zend_Json
+ * @package    ZendX_JQuery
+ * @subpackage View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_JQuery_View_Helper_Slider extends ZendX_JQuery_View_Helper_UiWidget
+{
+    /**
+     * Create jQuery slider that updates its values into a hidden form input field.
+     *
+     * @link   http://docs.jquery.com/UI/Slider
+     * @param  string $id
+     * @param  string $value
+     * @param  array  $params
+     * @param  array  $attribs
+     * @return string
+     */
+    public function slider($id, $value = null, array $params = array(), array $attribs = array())
+    {
+        if(!isset($attribs['id'])) {
+            $attribs['id'] = $id;
+        }
+
+        $jqh = ZendX_JQuery_View_Helper_JQuery::getJQueryHandler();
+
+        $params = $this->initializeStartingValues($value, $params);
+        $handleCount = $this->getHandleCount($params);
+
+        // Build the Change/Update functionality of the Slider via javascript, updating hidden fields. aswell as hidden fields
+        $hidden = "";
+        if(!isset($params['change'])) {
+            $sliderUpdateFn = 'function(e, ui) {'.PHP_EOL;
+            for($i = 0; $i < $handleCount; $i++) {
+                // Js Func
+                if($i === 0) {
+                    $sliderHiddenId = $attribs['id'];
+                } else {
+                    $sliderHiddenId = $attribs['id']."-".$i;
+                }
+                $sliderUpdateFn .= $this->getChangeCallback($jqh, $sliderHiddenId, $attribs['id'], $i);
+
+                // Hidden Fields
+                $startValue = $this->getHandleValue($i, $params);
+                $hiddenAttribs = array('type' => 'hidden', 'id' => $sliderHiddenId, 'name' => $sliderHiddenId, 'value' => $startValue);
+                $hidden .= '<input' . $this->_htmlAttribs($hiddenAttribs) . $this->getClosingBracket(). PHP_EOL;
+            }
+            $sliderUpdateFn .= "}".PHP_EOL;
+            $params['change'] = new Zend_Json_Expr($sliderUpdateFn);
+        }
+
+        $attribs['id'] .= "-slider";
+
+        if(count($params) > 0) {
+            $params = ZendX_JQuery::encodeJson($params);
+        } else {
+            $params = '{}';
+        }
+
+        $js = sprintf('%s("#%s").slider(%s);', $jqh, $attribs['id'], $params);
+        $this->jquery->addOnLoad($js);
+
+        $html = '<div' . $this->_htmlAttribs($attribs) . '>';
+        for($i = 0; $i < $handleCount; $i++) {
+            $html .= '<div class="ui-slider-handle"></div>';
+        }
+        $html .= '</div>';
+
+        return $hidden.$html;
+    }
+
+    protected function getChangeCallback($jqh, $sliderHiddenId, $elementId, $handlerNum)
+    {
+        if(version_compare($this->jquery->getUiVersion(), "1.7.0") >= 0) {
+            return sprintf('    %s("#%s").attr("value", %s("#%s-slider").slider("values", %d));'.PHP_EOL,
+                $jqh, $sliderHiddenId, $jqh, $elementId, $handlerNum
+            );
+        } else {
+            return sprintf('    %s("#%s").attr("value", %s("#%s-slider").slider("value", %d));'.PHP_EOL,
+                $jqh, $sliderHiddenId, $jqh, $elementId, $handlerNum
+            );
+        }
+    }
+
+    protected function getHandleCount($params)
+    {
+        if(version_compare($this->jquery->getUiVersion(), "1.7.0") >= 0) {
+            return count($params['values']);
+        } else {
+            return count($params['handles']);
+        }
+    }
+
+    protected function getHandleValue($handleNum, $params)
+    {
+        if(version_compare($this->jquery->getUiVersion(), "1.7.0") >= 0) {
+            return $params['values'][$handleNum];
+        } else {
+            return $params['handles'][$handleNum]['start'];
+        }
+    }
+
+    protected function initializeStartingValues($value, $params)
+    {
+        $values = array();
+        if(isset($params['value'])) {
+            $values[] = $params['value'];
+            unset($params['value']);
+        } else if(isset($params['values'])) {
+            $values = $params['values'];
+            unset($params['values']);
+        } else if(isset($params['handles'])) {
+            for($i = 0; $i < count($params['handles']); $i++) {
+                $values[] = $params['handles'][$i]['start'];
+            }
+            unset($params['handles']);
+        } else if(isset($params['startValue'])) {
+            $values[] = $params['startValue'];
+            unset($params['startValue']);
+        } else if(is_numeric($value)) {
+            $values[] = $value;
+        }
+
+        if(version_compare($this->jquery->getUiVersion(), "1.7.0") >= 0) {
+            $params['values'] = $values;
+        } else {
+            $params['handles'] = array();
+            for($i = 0; $i < count($values); $i++) {
+                $params['handles'][$i]['start'] = $values[$i];
+            }
+        }
+        return $params;
+    }
+}

+ 73 - 0
extras/library/ZendX/JQuery/View/Helper/Spinner.php

@@ -0,0 +1,73 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_View_Helper_UiWidget
+ */
+require_once "ZendX/JQuery/View/Helper/UiWidget.php";
+
+/**
+ * jQuery Spinner View Helper
+ *
+ * @uses 	   Zend_Json
+ * @package    ZendX_JQuery
+ * @subpackage View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_JQuery_View_Helper_Spinner extends ZendX_JQuery_View_Helper_UiWidget
+{
+    /**
+     * Create FormText field for numeric values that can be spinned through its values.
+     *
+     * @link   http://docs.jquery.com/UI/Spinner
+     * @param  string $id
+     * @param  string $value
+     * @param  array  $params
+     * @param  array  $attribs
+     * @return string
+     */
+	public function spinner($id, $value="", array $params=array(), array $attribs=array())
+	{
+	    $attribs = $this->_prepareAttributes($id, $value, $attribs);
+
+	    if(!isset($params['start']) && is_numeric($value)) {
+	        $params['start'] = $value;
+	    }
+
+	    if(count($params)) {
+	        $params = ZendX_JQuery::encodeJson($params);
+	    } else {
+	        $params = '{}';
+	    }
+
+        $js = sprintf('%s("#%s").spinner(%s);',
+            ZendX_JQuery_View_Helper_JQuery::getJQueryHandler(),
+            $attribs['id'],
+            $params
+        );
+
+        $this->jquery->addOnLoad($js);
+
+	    return $this->view->formText($id, $value, $attribs);
+	}
+}

+ 132 - 0
extras/library/ZendX/JQuery/View/Helper/TabContainer.php

@@ -0,0 +1,132 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_View_Helper_UiWidget
+ */
+require_once "ZendX/JQuery/View/Helper/UiWidget.php";
+
+/**
+ * jQuery Tabs Container View Helper
+ *
+ * @uses 	   Zend_Json
+ * @package    ZendX_JQuery
+ * @subpackage View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_JQuery_View_Helper_TabContainer extends ZendX_JQuery_View_Helper_UiWidget
+{
+    /**
+     * Save all the pre-rendered tab panes to each tab container
+     *
+     * @var array
+     */
+    protected $_tabs = array();
+
+    /**
+     * Add Tab to TabsContainer
+     *
+     * @param  string $id
+     * @param  string $name
+     * @param  string $content
+     * @param  array  $options
+     * @return ZendX_JQuery_View_Helper_TabsContainer
+     */
+    public function addPane($id, $name, $content, array $options=array())
+    {
+        if(!isset($this->_tabs[$id])) {
+            $this->_tabs[$id] = array();
+        }
+        if(strlen($name) == 0 && isset($options['title'])) {
+            $name = $options['title'];
+        }
+
+        $this->_tabs[$id][] = array('name' => $name, 'content' => $content, 'options' => $options);
+        return $this;
+    }
+
+    /**
+     * Render TabsContainer with all the currently registered tabs.
+     *
+     * Render all tabs to the given $id. If no arguments are given the
+     * tabsContainer view helper object is returned and can be used
+     * for chaining {@link addPane()} for tab pane adding.
+     *
+     * @link   http://docs.jquery.com/UI/Tabs
+     * @param  string $id
+     * @param  array  $params
+     * @param  array  $attribs
+     * @return string|ZendX_JQuery_View_Helper_TabsContainer
+     */
+    public function tabContainer($id=null, $params=array(), $attribs=array())
+    {
+        if(func_num_args() === 0) {
+            return $this;
+        }
+
+        if(!isset($attribs['id'])) {
+            $attribs['id'] = $id;
+        }
+
+        $content = "";
+        if(isset($this->_tabs[$id])) {
+            $list = '<ul class="ui-tabs-nav">'.PHP_EOL;
+            $html = '';
+            $fragment_counter = 1;
+            foreach($this->_tabs[$id] AS $k => $v) {
+                $frag_name = sprintf('%s-frag-%d', $attribs['id'], $fragment_counter++);
+                $opts = $v['options'];
+                if(isset($opts['contentUrl'])) {
+                    $list .= '<li class="ui-tabs-nav-item"><a href="'.$opts['contentUrl'].'"><span>'.$v['name'].'</span></a></li>'.PHP_EOL;
+                } else {
+                    $list .= '<li class="ui-tabs-nav-item"><a href="#'.$frag_name.'"><span>'.$v['name'].'</span></a></li>'.PHP_EOL;
+                    $html .= '<div id="'.$frag_name.'" class="ui-tabs-panel">'.$v['content'].'</div>'.PHP_EOL;
+                }
+            }
+            $list .= '</ul>'.PHP_EOL;
+
+            $content = $list.$html;
+            unset($this->_tabs[$id]);
+        }
+
+        if(count($params)) {
+            $params = ZendX_JQuery::encodeJson($params);
+        } else {
+            $params = '{}';
+        }
+
+        $js = sprintf('%s("#%s").tabs(%s);',
+            ZendX_JQuery_View_Helper_JQuery::getJQueryHandler(),
+            $attribs['id'],
+            $params
+        );
+        $this->jquery->addOnLoad($js);
+
+        $html = '<div'
+              . $this->_htmlAttribs($attribs)
+              . '>'.PHP_EOL
+              . $content
+              . '</div>'.PHP_EOL;
+        return $html;
+    }
+}

+ 74 - 0
extras/library/ZendX/JQuery/View/Helper/TabPane.php

@@ -0,0 +1,74 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once "UiWidgetPane.php";
+
+/**
+ * jQuery Tabs Pane View Helper, goes with Tab Container
+ *
+ * @uses 	   Zend_Json, ZendX_JQuery_View_Helper_TabContainer
+ * @package    ZendX_JQuery
+ * @subpackage View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_JQuery_View_Helper_TabPane extends ZendX_JQuery_View_Helper_UiWidgetPane
+{
+    /**
+     * Add a tab pane to the tab container with the given $id.
+     *
+     * @param  string $id
+     * @param  string $content
+     * @param  array  $options
+     * @return string always empty
+     */
+    public function tabPane($id=null, $content='', array $options=array())
+    {
+        if(0 === func_num_args()) {
+            return $this;
+        }
+
+        $name = '';
+        if(isset($options['title'])) {
+            $name = $options['title'];
+            unset($options['title']);
+        }
+
+        $this->_addPane($id, $name, $content, $options);
+        return '';
+    }
+
+    /**
+     * Register new tab pane with tabContainer view helper.
+     *
+     * @see    ZendX_JQuery_View_Helper_TabContainer::addPane
+     * @param  string $id
+     * @param  string $name
+     * @param  string $content
+     * @param  array  $options
+     * @return void
+     */
+    protected function _addPane($id, $name, $content, array $options=array())
+    {
+        $this->view->tabContainer()->addPane($id, $name, $content, $options);
+    }
+}

+ 84 - 0
extras/library/ZendX/JQuery/View/Helper/UiWidget.php

@@ -0,0 +1,84 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_View_Helper_UiWidget
+ */
+require_once "Zend/View/Helper/HtmlElement.php";
+
+/**
+ * @see ZendX_JQuery
+ */
+require_once "ZendX/JQuery.php";
+
+/**
+ * jQuery Ui Widget Base class
+ *
+ * @uses 	   ZendX_JQuery_View_Helper_JQuery_Container
+ * @package    ZendX_JQuery
+ * @subpackage View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class ZendX_JQuery_View_Helper_UiWidget extends Zend_View_Helper_HtmlElement
+{
+    /**
+     * Contains reference to the jQuery view helper
+     *
+     * @var ZendX_JQuery_View_Helper_JQuery_Container
+     */
+    protected $jquery;
+
+    /**
+     * Set view and enable jQuery Core and UI libraries
+     *
+     * @param  Zend_View_Interface $view
+     * @return ZendX_JQuery_View_Helper_Widget
+     */
+    public function setView(Zend_View_Interface $view)
+    {
+        parent::setView($view);
+        $this->jquery = $this->view->jQuery();
+        $this->jquery->enable()
+                     ->uiEnable();
+        return $this;
+    }
+
+    /**
+     * Helps with building the correct Attributes Array structure.
+     *
+     * @param String $id
+     * @param String $value
+     * @param Array $attribs
+     * @return Array $attribs
+     */
+	protected function _prepareAttributes($id, $value, $attribs)
+	{
+        if(!isset($attribs['id'])) {
+            $attribs['id'] = $id;
+        }
+        $attribs['name']  = $id;
+        $attribs['value'] = (string) $value;
+
+        return $attribs;
+	}
+}

+ 105 - 0
extras/library/ZendX/JQuery/View/Helper/UiWidgetPane.php

@@ -0,0 +1,105 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+/**
+ * @see ZendX_JQuery_View_Helper_UiWidget
+ */
+require_once "UiWidget.php";
+
+/**
+ * jQuery Pane Base class, adds captureStart/captureEnd functionality for panes.
+ *
+ * @uses 	   ZendX_JQuery_View_Helper_JQuery_Container
+ * @package    ZendX_JQuery
+ * @subpackage View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class ZendX_JQuery_View_Helper_UiWidgetPane extends ZendX_JQuery_View_Helper_UiWidget
+{
+    /**
+     * Capture Lock information
+     *
+     * @var array
+     */
+    protected $_captureLock = array();
+
+    /**
+     * Current capture additional information
+     *
+     * @var array
+     */
+    protected $_captureInfo = array();
+
+    /**
+     * Begin capturing content for layout container
+     *
+     * @param  string $id
+     * @param  string $name
+     * @param  array  $options
+     * @return void
+     */
+    public function captureStart($id, $name, array $options=array())
+    {
+        if (array_key_exists($id, $this->_captureLock)) {
+            require_once 'ZendX/JQuery/View/Exception.php';
+            throw new ZendX_JQuery_View_Exception(sprintf('Lock already exists for id "%s"', $id));
+        }
+
+        $this->_captureLock[$id] = true;
+        $this->_captureInfo[$id] = array(
+            'name'  => $name,
+            'options' => $options,
+        );
+
+        return ob_start();
+    }
+
+    /**
+     * Finish capturing content for layout container
+     *
+     * @param  string $id
+     * @return string
+     */
+    public function captureEnd($id)
+    {
+        if (!array_key_exists($id, $this->_captureLock)) {
+            require_once 'ZendX/JQuery/View/Exception.php';
+            throw new ZendX_JQuery_View_Exception(sprintf('No capture lock exists for id "%s"; nothing to capture', $id));
+        }
+
+        $content = ob_get_clean();
+        extract($this->_captureInfo[$id]);
+        unset($this->_captureLock[$id], $this->_captureInfo[$id]);
+        return $this->_addPane($id, $name, $content, $options);
+    }
+
+    /**
+     * Add an additional pane to the current Widget Container
+     *
+     * @param string $id
+     * @param string $name
+     * @param string $content
+     * @param array  $options
+     */
+    abstract protected function _addPane($id, $name, $content, array $options=array());
+}

+ 61 - 0
extras/tests/AllTests.php

@@ -0,0 +1,61 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'AllTests::main');
+}
+
+/**
+ * @see ZendX_AllTests
+ */
+require_once 'ZendX/AllTests.php';
+
+class AllTests
+{
+    public static function main()
+    {
+        $parameters = array();
+
+        if (TESTS_GENERATE_REPORT && extension_loaded('xdebug')) {
+            $parameters['reportDirectory'] = TESTS_GENERATE_REPORT_TARGET;
+        }
+
+        if (defined('TESTS_ZEND_LOCALE_FORMAT_SETLOCALE') && TESTS_ZEND_LOCALE_FORMAT_SETLOCALE) {
+            // run all tests in a special locale
+            setlocale(LC_ALL, TESTS_ZEND_LOCALE_FORMAT_SETLOCALE);
+        }
+
+        PHPUnit_TextUI_TestRunner::run(self::suite(), $parameters);
+    }
+
+    public static function suite()
+    {
+        $suite = new PHPUnit_Framework_TestSuite('Zend Framework Extras');
+
+        $suite->addTest(ZendX_AllTests::suite());
+
+        return $suite;
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'AllTests::main') {
+    AllTests::main();
+}

+ 51 - 0
extras/tests/TestConfiguration.php.dist

@@ -0,0 +1,51 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/**
+ * This file defines configuration for running the unit tests for the Zend
+ * Framework.  Some tests have dependencies to PHP extensions or databases
+ * which may not necessary installed on the target system.  For these cases,
+ * the ability to disable or configure testing is provided below.  Tests for
+ * components which should run universally are always run by the master
+ * suite and cannot be disabled.
+ *
+ * Do not edit this file. Instead, copy this file to TestConfiguration.php,
+ * and edit the new file. Never commit plaintext passwords to the source
+ * code repository.
+ */
+
+/**
+ * ZendX_Db_Adapter_Firebird
+ */
+define('TESTS_ZEND_DB_ADAPTER_FIREBIRD_ENABLED',  false);
+define('TESTS_ZEND_DB_ADAPTER_FIREBIRD_HOSTNAME', '');
+define('TESTS_ZEND_DB_ADAPTER_FIREBIRD_PORT', 3050);
+define('TESTS_ZEND_DB_ADAPTER_FIREBIRD_USERNAME', 'sysdba');
+define('TESTS_ZEND_DB_ADAPTER_FIREBIRD_PASSWORD', 'masterkey');
+define('TESTS_ZEND_DB_ADAPTER_FIREBIRD_DATABASE', 'C:\fbtest.fdb'); //must be DOS name
+define('TESTS_ZEND_DB_ADAPTER_FIREBIRD_BINPATH', 'C:/Program Files/Firebird/Firebird_2_1/bin/'); //don't forget last slash
+
+/**
+ * PHPUnit Code Coverage / Test Report
+ */
+define('TESTS_GENERATE_REPORT', false);
+define('TESTS_GENERATE_REPORT_TARGET', '/path/to/target');

+ 85 - 0
extras/tests/TestHelper.php

@@ -0,0 +1,85 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/**
+ * Include PHPUnit dependencies
+ */
+require_once 'PHPUnit/Runner/Version.php';
+
+$phpunitVersion = PHPUnit_Runner_Version::id();
+if ($phpunitVersion == '@package_version@' || version_compare($phpunitVersion, '3.5.5', '>=')) {
+    if (version_compare($phpunitVersion, '3.6.0', '>=')) {
+        echo 'This verison of PHPUnit is not supported in Zend Framework 1.x unit tests.';
+        exit(1);
+    }
+    require_once 'PHPUnit/Autoload.php'; // >= PHPUnit 3.5.5
+} else {
+    require_once 'PHPUnit/Framework.php'; // < PHPUnit 3.5.5
+}
+
+/*
+ * Set error reporting to the level to which Zend Framework code must comply.
+ */
+error_reporting(E_ALL | E_STRICT);
+
+/*
+ * Determine the root, library, and tests directories of the framework
+ * distribution.
+ */
+$zfRoot        = realpath(dirname(dirname(__FILE__)));
+$zfCoreLibrary = "$zfRoot/library";
+$zfCoreTests   = "$zfRoot/tests";
+
+/*
+ * Prepend the Zend Framework library/ and tests/ directories to the
+ * include_path. This allows the tests to run out of the box and helps prevent
+ * loading other copies of the framework code and tests that would supersede
+ * this copy.
+ */
+$path = array(
+    $zfCoreLibrary,
+    $zfCoreTests,
+    get_include_path()
+    );
+set_include_path(implode(PATH_SEPARATOR, $path));
+
+/*
+ * Load the user-defined test configuration file, if it exists; otherwise, load
+ * the default configuration.
+ */
+if (is_readable($zfCoreTests . DIRECTORY_SEPARATOR . 'TestConfiguration.php')) {
+    require_once $zfCoreTests . DIRECTORY_SEPARATOR . 'TestConfiguration.php';
+} else {
+    require_once $zfCoreTests . DIRECTORY_SEPARATOR . 'TestConfiguration.php.dist';
+}
+
+/**
+ * Start output buffering, if enabled
+ */
+if (defined('TESTS_ZEND_OB_ENABLED') && constant('TESTS_ZEND_OB_ENABLED')) {
+    ob_start();
+}
+
+/*
+ * Unset global variables that are no longer needed.
+ */
+unset($zfRoot, $zfCoreLibrary, $zfCoreTests, $path);

+ 67 - 0
extras/tests/ZendX/AllTests.php

@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/**
+ * Test helper
+ */
+require_once dirname(__FILE__) . '/../TestHelper.php';
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'ZendX_AllTests::main');
+}
+
+require_once 'ZendX/Application/AllTests.php';
+require_once 'ZendX/Console/AllTests.php';
+require_once 'ZendX/JQuery/AllTests.php';
+require_once 'ZendX/Db/AllTests.php';
+
+/**
+ * @category   ZendX
+ * @package    ZendX
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_AllTests
+{
+    public static function main()
+    {
+        PHPUnit_TextUI_TestRunner::run(self::suite());
+    }
+
+    public static function suite()
+    {
+        $suite = new PHPUnit_Framework_TestSuite('Zend Framework Extras - ZendX');
+
+        $suite->addTestSuite('ZendX_Application_AllTests');
+        $suite->addTestSuite('ZendX_Console_AllTests');
+        $suite->addTestSuite('ZendX_JQuery_AllTests');
+        $suite->addTestSuite('ZendX_Db_AllTests');
+
+        return $suite;
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'ZendX_AllTests::main') {
+    Zend_AllTests::main();
+}

+ 61 - 0
extras/tests/ZendX/Application/AllTests.php

@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Application
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: AllTests.php 12231 2008-10-31 23:55:11Z dasprid $
+ */
+
+/**
+ * Test helper
+ */
+require_once dirname(__FILE__) . '/../../TestHelper.php';
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'ZendX_Application_AllTests::main');
+}
+
+require_once 'ZendX/Application/Resource/AllTests.php';
+
+/**
+ * @category   ZendX
+ * @package    ZendX_Application
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_Application_AllTests
+{
+    public static function main()
+    {
+        PHPUnit_TextUI_TestRunner::run(self::suite());
+    }
+
+    public static function suite()
+    {
+        $suite = new PHPUnit_Framework_TestSuite('Zend Framework - ZendX_Application');
+
+        $suite->addTest(ZendX_Application_Resource_AllTests::suite());
+
+        return $suite;
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'ZendX_Application_AllTests::main') {
+    ZendX_Console_AllTests::main();
+}

+ 59 - 0
extras/tests/ZendX/Application/Resource/AllTests.php

@@ -0,0 +1,59 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    ZendX_Console
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: AllTests.php 12231 2008-10-31 23:55:11Z dasprid $
+ */
+
+/**
+ * Test helper
+ */
+require_once dirname(__FILE__) . '/../../../TestHelper.php';
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'ZendX_Application_Resource_AllTests::main');
+}
+
+require_once 'ZendX/Application/Resource/JqueryTest.php';
+
+/**
+ * @category   Zend
+ * @package    ZendX_Applicatoin
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_Application_Resource_AllTests
+{
+    public static function main()
+    {
+        PHPUnit_TextUI_TestRunner::run(self::suite());
+    }
+
+    public static function suite()
+    {
+        $suite = new PHPUnit_Framework_TestSuite('Zend Framework - ZendX_Application_Resource');
+        $suite->addTestSuite('ZendX_Application_Resource_JQueryTest');
+
+        return $suite;
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'ZendX_Application_Resource_AllTests::main') {
+    ZendX_Application_Resource_AllTests::main();
+}

+ 200 - 0
extras/tests/ZendX/Application/Resource/JqueryTest.php

@@ -0,0 +1,200 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    ZendX_Application
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'ZendX_Application_Resource_JqueryTest::main');
+}
+
+/**
+ * Test helper
+ */
+require_once dirname(__FILE__) . '/../../../TestHelper.php';
+
+/**
+ * Zend_Loader_Autoloader
+ */
+require_once 'Zend/Loader/Autoloader.php';
+
+/**
+ * @category   Zend
+ * @package    ZendX_Application
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @group      Zend_Application
+ */
+class ZendX_Application_Resource_JqueryTest extends PHPUnit_Framework_TestCase
+{
+    public static function main()
+    {
+        $suite  = new PHPUnit_Framework_TestSuite(__CLASS__);
+        $result = PHPUnit_TextUI_TestRunner::run($suite);
+    }
+
+    public function setUp()
+    {
+        // Store original autoloaders
+        $this->loaders = spl_autoload_functions();
+        if (!is_array($this->loaders)) {
+            // spl_autoload_functions does not return empty array when no
+            // autoloaders registered...
+            $this->loaders = array();
+        }
+
+        Zend_Loader_Autoloader::resetInstance();
+        $this->autoloader = Zend_Loader_Autoloader::getInstance();
+
+        $this->application = new Zend_Application('testing');
+
+        $this->bootstrap = new Zend_Application_Bootstrap_Bootstrap($this->application);
+
+        Zend_Registry::_unsetInstance();
+        ZendX_JQuery_View_Helper_JQuery::disableNoConflictMode();
+    }
+
+    public function tearDown()
+    {
+        // Restore original autoloaders
+        $loaders = spl_autoload_functions();
+        foreach ($loaders as $loader) {
+            spl_autoload_unregister($loader);
+        }
+
+        foreach ($this->loaders as $loader) {
+            spl_autoload_register($loader);
+        }
+
+        // Reset autoloader instance so it doesn't affect other tests
+        Zend_Loader_Autoloader::resetInstance();
+        ZendX_JQuery_View_Helper_JQuery::disableNoConflictMode();
+    }
+
+    public function testInitializationInitializesJqueryObject()
+    {
+        $this->bootstrap->registerPluginResource('view');
+        $resource = new ZendX_Application_Resource_Jquery(array());
+        $resource->setBootstrap($this->bootstrap);
+
+        $res = $resource->init();
+        $this->assertTrue($res instanceof ZendX_JQuery_View_Helper_JQuery_Container);
+        $this->assertSame($res, $resource->getJquery());
+    }
+
+    public function testOptionsArePassedOn()
+    {
+        $options = array(
+            'noconflictmode'  => true,
+            'version'         => '1.2.3',
+            'localpath'       => '/foo/bar/',
+            'ui_version'      => '2.3.4',
+            'uilocalpath'     => '/bar/foo/',
+            'cdn_ssl'         => true,
+            'rendermode'      => 192,
+            'javascriptfile'  => '/fooBar.js',
+            'javascriptfiles' => array('johndoe.js','janedoe.js'),
+            'stylesheet'      => '/fooBar.css',
+            'stylesheets'     => array('johndoe.css','janedoe.css'),
+        );
+
+        $this->bootstrap->registerPluginResource('view');
+        $resource = new ZendX_Application_Resource_Jquery(array());
+        $resource->setBootstrap($this->bootstrap);
+        $resource->setOptions($options);
+
+        $res = $resource->init();
+
+        $this->assertTrue(ZendX_JQuery_View_Helper_JQuery::getNoConflictMode());
+        $this->assertEquals('1.2.3', $res->getVersion());
+        $this->assertEquals('/foo/bar/', $res->getLocalPath());
+        $this->assertEquals('2.3.4', $res->getUiVersion());
+        $this->assertEquals('/bar/foo/', $res->getUiLocalPath());
+        $this->assertTrue($res->getCdnSsl());
+        $this->assertEquals(192, $res->getRenderMode());
+        $this->assertEquals(array('/fooBar.css', 'johndoe.css', 'janedoe.css'),
+                            $res->getStylesheets());
+        $this->assertEquals(array('/fooBar.js', 'johndoe.js', 'janedoe.js'),
+                            $res->getJavascriptFiles());
+    }
+
+    public function testAliasOptionsArePassedOn()
+    {
+        $options = array(
+            'uiversion'    => '3.4.5',
+            'ui_localpath' => '/f00/b4r/',
+            'render_mode'  => 187,
+        );
+
+        $this->bootstrap->registerPluginResource('view');
+        $resource = new ZendX_Application_Resource_Jquery(array());
+        $resource->setBootstrap($this->bootstrap);
+        $resource->setOptions($options);
+
+        $res = $resource->init();
+
+        $this->assertEquals('3.4.5', $res->getUiVersion());
+        $this->assertEquals('/f00/b4r/', $res->getUiLocalPath());
+        $this->assertEquals(187, $res->getRenderMode());
+    }
+
+    /**
+     * @group ZF-10254
+     */
+    public function testIfUiDisableEnableViewHelperJquery()
+    {
+        $options = array(
+            'uienable'    => false,
+            'enable'      => true
+        );
+
+        $this->bootstrap->registerPluginResource('view');
+        $resource = new ZendX_Application_Resource_Jquery(array());
+        $resource->setBootstrap($this->bootstrap);
+        $resource->setOptions($options);
+        $res = $resource->init();
+        $this->assertTrue($res->isEnabled());
+        $this->assertFalse($res->uiIsEnabled());
+
+        $resource = new ZendX_Application_Resource_Jquery(array());
+        $resource->setBootstrap($this->bootstrap);
+        $res = $resource->init();
+        $this->assertTrue($res->isEnabled());
+        $this->assertTrue($res->uiIsEnabled());
+
+        $resource = new ZendX_Application_Resource_Jquery(array());
+        $resource->setBootstrap($this->bootstrap);
+        $resource->setOptions(array('uienable' => false));
+        $res = $resource->init();
+        $this->assertTrue($res->isEnabled());
+        $this->assertFalse($res->uiIsEnabled());
+
+        $resource = new ZendX_Application_Resource_Jquery(array());
+        $resource->setBootstrap($this->bootstrap);
+        $resource->setOptions(array('enable' => false));
+        $res = $resource->init();
+        $this->assertFalse($res->isEnabled());
+        $this->assertFalse($res->uiIsEnabled());
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'Zend_Application_Resource_LocaleTest::main') {
+    Zend_Application_Resource_LocaleTest::main();
+}

+ 61 - 0
extras/tests/ZendX/Console/AllTests.php

@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Console
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/**
+ * Test helper
+ */
+require_once dirname(__FILE__) . '/../../TestHelper.php';
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'ZendX_Console_AllTests::main');
+}
+
+require_once 'ZendX/Console/Process/AllTests.php';
+
+/**
+ * @category   ZendX
+ * @package    ZendX_Console
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_Console_AllTests
+{
+    public static function main()
+    {
+        PHPUnit_TextUI_TestRunner::run(self::suite());
+    }
+
+    public static function suite()
+    {
+        $suite = new PHPUnit_Framework_TestSuite('Zend Framework - ZendX_Console');
+
+        $suite->addTest(ZendX_Console_Process_AllTests::suite());
+        
+        return $suite;
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'ZendX_Console_AllTests::main') {
+    ZendX_Console_AllTests::main();
+}

+ 59 - 0
extras/tests/ZendX/Console/Process/AllTests.php

@@ -0,0 +1,59 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    ZendX_Console
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/**
+ * Test helper
+ */
+require_once dirname(__FILE__) . '/../../../TestHelper.php';
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'ZendX_Console_Process_AllTests::main');
+}
+
+require_once 'ZendX/Console/Process/UnixTest.php';
+
+/**
+ * @category   Zend
+ * @package    ZendX_Console
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_Console_Process_AllTests
+{
+    public static function main()
+    {
+        PHPUnit_TextUI_TestRunner::run(self::suite());
+    }
+
+    public static function suite()
+    {
+        $suite = new PHPUnit_Framework_TestSuite('Zend Framework - ZendX_Console_Process');
+        $suite->addTestSuite('ZendX_Console_Process_UnixTest');
+        
+        return $suite;
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'ZendX_Console_Process_AllTests::main') {
+    ZendX_Console_Process_AllTests::main();
+}

+ 201 - 0
extras/tests/ZendX/Console/Process/UnixTest.php

@@ -0,0 +1,201 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    ZendX_Console
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+// Call Zend_ProgressBar_Adapter_ConsoleTest::main() if this source file is executed directly.
+if (!defined("PHPUnit_MAIN_METHOD")) {
+    define("PHPUnit_MAIN_METHOD", "ZendX_Console_Process_UnixTest::main");
+}
+
+/**
+ * Test helper
+ */
+require_once dirname(__FILE__) . '/../../../TestHelper.php';
+
+/**
+ * ZendX_Console_Process_Unix
+ */
+require_once 'ZendX/Console/Process/Unix.php';
+
+/**
+ * @category   Zend
+ * @package    ZendX_Console
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_Console_Process_UnixTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Runs the test methods of this class.
+     *
+     * @return void
+     */
+    public static function main()
+    {
+        $suite  = new PHPUnit_Framework_TestSuite("ZendX_Console_Process_UnixTest");
+        $result = PHPUnit_TextUI_TestRunner::run($suite);
+    }
+    
+    public function setUp()
+    {
+        if (substr(PHP_OS, 0, 3) === 'WIN') {
+            $this->markTestSkipped('Cannot run on Windows');
+        } else if (!in_array(substr(PHP_SAPI, 0, 3), array('cli', 'cgi'))) {
+            $this->markTestSkipped('Can only run on CLI or CGI enviroment');
+        } else if (!function_exists('shmop_open')) {
+            $this->markTestSkipped('shmop_* functions are required');
+        } else if (!function_exists('pcntl_fork')) {
+            $this->markTestSkipped('pcntl_* functions are required');
+        } else if (!function_exists('posix_kill')) {
+            $this->markTestSkipped('posix_* functions are required');
+        }
+    }
+    
+    public function testStop()
+    {
+        $startTime = microtime(true);
+        
+        $process = new sleepingProcess();
+        
+        $process->start();
+        $process->stop();
+
+        $diffTime = round(microtime(true) - $startTime);
+        
+        $this->assertEquals(0, $diffTime);
+    }
+    
+    public function testAutomaticEnding()
+    {
+        $startTime = microtime(true);
+        
+        $process = new simpleProcess();
+        
+        $process->start();
+
+        do {
+            usleep(10);
+            $diffTime = round(microtime(true) - $startTime);
+        } while ($process->isRunning() && $diffTime < 2);
+        
+        $process->stop();
+        
+        $this->assertEquals(1, $diffTime);
+    }
+    
+    public function testParallel()
+    {
+        $startTime = microtime(true);
+        
+        $process1 = new sleepingProcess();
+        $process2 = new sleepingProcess();
+        
+        $process1->start();
+        $process2->start();
+
+        do {
+            usleep(10);
+            $diffTime = round(microtime(true) - $startTime);
+        } while (($process1->isRunning() || $process2->isRunning()) && $diffTime < 3);
+        
+        $process1->stop();
+        $process2->stop();
+        
+        $this->assertEquals(2, $diffTime);
+    }
+    
+    public function testVariables()
+    {
+        $startTime = microtime(true);
+        
+        $process = new variableProcess();
+        
+        $process->start();
+        $process->setVariable('request', true);
+
+        do {
+            usleep(10);
+            $diffTime = round(microtime(true) - $startTime);
+            $response = $process->getVariable('response');
+        } while ($response === null && $diffTime < 3);
+        
+        $process->stop();
+        
+        $this->assertTrue($response);
+    }
+    
+    public function testAlive()
+    {
+        $startTime = microtime(true);
+        
+        $process = new aliveProcess();
+        
+        $process->start();
+        
+        sleep(2);
+
+        $this->assertEquals(1, $process->getLastAlive());
+        
+        $process->stop();
+    }
+}
+
+class simpleProcess extends ZendX_Console_Process_Unix
+{
+    protected function _run()
+    {
+    }
+}
+
+class sleepingProcess extends ZendX_Console_Process_Unix
+{
+    protected function _run()
+    {
+        sleep(1);
+    }
+}
+
+class variableProcess extends ZendX_Console_Process_Unix
+{
+    protected function _run()
+    {
+        $var = null;
+        do {
+            $var = $this->getVariable('request');
+        } while ($var === NULL);
+        
+        $this->setVariable('response', true);
+    }
+}
+
+class aliveProcess extends ZendX_Console_Process_Unix
+{
+    protected function _run()
+    {
+        $this->_setAlive();
+    }
+}
+
+// Call ZendX_Console_Process_UnixTest::main() if this source file is executed directly.
+if (PHPUnit_MAIN_METHOD == "ZendX_Console_Process_UnixTest::main") {
+    ZendX_Console_Process_UnixTest::main();
+}

+ 220 - 0
extras/tests/ZendX/Db/Adapter/FirebirdTest.php

@@ -0,0 +1,220 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * @see Zend_Db_Adapter_TestCommon
+ */
+require_once 'Zend/Db/Adapter/TestCommon.php';
+
+/**
+ * @see Zend_Db_Adapter_Firebird
+ */
+require_once 'ZendX/Db/Adapter/Firebird.php';
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__);
+
+class ZendX_Db_Adapter_FirebirdTest extends Zend_Db_Adapter_TestCommon
+{
+
+    protected $_numericDataTypes = array(
+        Zend_Db::INT_TYPE    => Zend_Db::INT_TYPE,
+        Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
+        Zend_Db::FLOAT_TYPE  => Zend_Db::FLOAT_TYPE,
+        'INT'                => Zend_Db::INT_TYPE,
+        'INTEGER'            => Zend_Db::INT_TYPE,
+        'SMALLINT'           => Zend_Db::INT_TYPE,
+        'BIGINT'             => Zend_Db::BIGINT_TYPE,
+        'INT64'              => Zend_Db::BIGINT_TYPE,
+        'DECIMAL'            => Zend_Db::FLOAT_TYPE,
+        'DOUBLE'             => Zend_Db::FLOAT_TYPE,
+        'DOUBLE PRECISION'   => Zend_Db::FLOAT_TYPE,
+        'NUMERIC'            => Zend_Db::FLOAT_TYPE,
+        'FLOAT'              => Zend_Db::FLOAT_TYPE
+    );
+
+
+    public function testAdapterDescribeTablePrimaryAuto()
+    {
+        $this->markTestSkipped($this->getDriver() . ' does not support auto-increment');
+    }
+
+    public function testAdapterInsert()
+    {
+        $row = array (
+            'product_id'   => $this->_db->nextSequenceId('zfproducts_seq'),
+            'product_name' => 'Solaris',
+        );
+        $rowsAffected = $this->_db->insert('zfproducts', $row);
+        $this->assertEquals(1, $rowsAffected);
+        $lastInsertId = $this->_db->lastInsertId('zfproducts', null); // implies 'zfproducts_seq'
+        $lastSequenceId = $this->_db->lastSequenceId('zfproducts_seq');
+        $this->assertEquals('4', (string) $lastInsertId, 'Expected new id to be 4');
+        $this->assertEquals('4', (string) $lastSequenceId, 'Expected new id to be 4');
+    }
+
+    /**
+     * test that quote() escapes a single-quote
+     * character in a string.
+     */
+    public function testAdapterQuoteSingleQuote()
+    {
+        $string = "St John's Wort";
+        $value = $this->_db->quote($string);
+        $this->assertEquals("'St John''s Wort'", $value);
+    }
+
+    /**
+     * test that quoteTableAs() accepts a string and an alias,
+     * and returns each as delimited identifiers.
+     * Oracle does not want the 'AS' in between.
+     */
+    public function testAdapterQuoteTableAs()
+    {
+        $string = "foo";
+        $alias = "bar";
+        $value = $this->_db->quoteTableAs($string, $alias);
+        $this->assertEquals('"foo" "bar"', $value);
+    }
+
+    /**
+     * test that quote() escapes a double-quote
+     * character in a string.
+     */
+    public function testAdapterQuoteDoubleQuote()
+    {
+        $value = $this->_db->quote('St John"s Wort');
+        $this->assertEquals("'St John\"s Wort'", $value);
+    }
+
+    /**
+     * Test that quote() takes an array and returns
+     * an imploded string of comma-separated, quoted elements.
+     */
+    public function testAdapterQuoteArray()
+    {
+        $array = array("it's", 'all', 'right!');
+        $value = $this->_db->quote($array);
+        $this->assertEquals("'it''s', 'all', 'right!'", $value);
+    }
+
+    /**
+     * test that quoteInto() escapes a single-quote
+     * character in a string.
+     */
+    public function testAdapterQuoteIntoSingleQuote()
+    {
+        $value = $this->_db->quoteInto('id = ?', 'St John\'s Wort');
+        $this->assertEquals("id = 'St John''s Wort'", $value);
+    }
+
+	/**
+     * test that quoteInto() escapes a double-quote
+     * character in a string.
+     */
+    public function testAdapterQuoteIntoDoubleQuote()
+    {
+        $value = $this->_db->quoteInto('id=?', 'St John"s Wort');
+        $this->assertEquals("id='St John\"s Wort'", $value);
+    }
+
+    public function testZF2059()
+    {
+		$this->markTestSkipped($this->getDriver() . ' not affected by ZF-2059');
+    }
+
+
+	// Deffers from others RDBMS, Firebird always is in a transaction, and for Zend_Db the default
+	// transaction Isolation is snapshot, changes made by other transaction is only visible with new
+    // transaction, commiting retaining or rollback retaining
+    public function testAdapterTransactionCommit()
+    {
+        $bugs = $this->_db->quoteIdentifier('zfbugs');
+        $bug_id = $this->_db->quoteIdentifier('bug_id');
+
+        // use our default connection as the Connection1
+        $dbConnection1 = $this->_db;
+
+        // create a second connection to the same database
+        $dbConnection2 = Zend_Db::factory($this->getDriver(), $this->_util->getParams());
+        $dbConnection2->getConnection();
+
+        // notice the number of rows in connection 2
+        $count = $dbConnection2->fetchOne("SELECT COUNT(*) FROM $bugs");
+        $this->assertEquals(4, $count, 'Expecting to see 4 rows in bugs table (step 1)');
+
+        // start an explicit transaction in connection 1
+        $dbConnection1->beginTransaction();
+
+        // delete a row in connection 1
+        $rowsAffected = $dbConnection1->delete(
+            'zfbugs',
+            "$bug_id = 1"
+        );
+        $this->assertEquals(1, $rowsAffected);
+
+        // we should still see all rows in connection 2
+        // because the DELETE has not been committed yet
+        $count = $dbConnection2->fetchOne("SELECT COUNT(*) FROM $bugs");
+        $this->assertEquals(4, $count, 'Expecting to still see 4 rows in bugs table (step 2); perhaps Adapter is still in autocommit mode?');
+
+        // commit the DELETE
+        $dbConnection1->commit();
+
+        // now we should see one fewer rows in connection 2
+		
+		$dbConnection2->commit();
+        $count = $dbConnection2->fetchOne("SELECT COUNT(*) FROM $bugs");
+        $this->assertEquals(3, $count, 'Expecting to see 3 rows in bugs table after DELETE (step 3)');
+
+        // delete another row in connection 1
+        $rowsAffected = $dbConnection1->delete(
+            'zfbugs',
+            "$bug_id = 2"
+        );
+        $this->assertEquals(1, $rowsAffected);
+
+        // we should see results immediately, because
+        // the db connection returns to auto-commit mode
+        $count = $dbConnection2->fetchOne("SELECT COUNT(*) FROM $bugs");
+        $this->assertEquals(2, $count);
+    }
+
+    /**
+     * Used by _testAdapterOptionCaseFoldingNatural()
+     * DB2, Oracle and Firebird return identifiers in uppercase naturally,
+     * so those test suites will override this method.
+     */
+    protected function _testAdapterOptionCaseFoldingNaturalIdentifier()
+    {
+        return 'CASE_FOLDED_IDENTIFIER';
+    }
+
+    public function testAdapterOptionCaseFoldingLower()
+    {
+        $this->markTestSkipped($this->getDriver() . ' always return UPPERCASE Natural Identifiers');
+    }
+
+    public function getDriver()
+    {
+        return 'Firebird';
+    }
+
+}

+ 54 - 0
extras/tests/ZendX/Db/Adapter/SkipTests.php

@@ -0,0 +1,54 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * PHPUnit test case
+ */
+require_once 'PHPUnit/Framework/TestCase.php';
+
+
+/**
+ * @package    Zend_Db
+ * @subpackage UnitTests
+ */
+abstract class ZendX_Db_Adapter_Skip_CommonTest extends PHPUnit_Framework_TestCase
+{
+    abstract public function getDriver();
+
+    public function setUp()
+    {
+        $driver = $this->getDriver();
+        $this->markTestSkipped("Testing ZendX_Db_Adapter_$driver is not enabled in TestConfiguration.php");
+    }
+
+    public function testAdapter()
+    {
+        // this is here only so we have at least one test
+    }
+}
+
+class ZendX_Db_Adapter_Skip_FirebirdTest extends Zend_Db_Adapter_Skip_CommonTest
+{
+    public function getDriver()
+    {
+        return 'Firebird';
+    }
+}

+ 187 - 0
extras/tests/ZendX/Db/AllTests.php

@@ -0,0 +1,187 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: $
+ */
+
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'ZendX_Db_AllTests::main');
+}
+
+
+/**
+ * Test helper
+ */
+require_once dirname(__FILE__) . '/../../TestHelper.php';
+
+/**
+ * PHPUnit_Framework_TestSuite
+ */
+require_once 'PHPUnit/Framework/TestSuite.php';
+
+/**
+ * PHPUnit_TextUI_TestRunner
+ */
+require_once 'PHPUnit/TextUI/TestRunner.php';
+
+/**
+ * @see Zend_Loader
+ */
+require_once 'Zend/Loader.php';
+
+/**
+ * @see Zend_Db_SkipTests
+ */
+require_once 'ZendX/Db/SkipTests.php';
+
+/**
+ * @see ZendX_Db_Profiler_AllTests
+ */
+require_once 'Zend/Db/Profiler/AllTests.php';
+
+/**
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_Db_AllTests
+{
+
+    protected static $_skipTestSuite = null;
+
+    public static function main()
+    {
+        PHPUnit_TextUI_TestRunner::run(self::suite());
+    }
+
+    public static function suite()
+    {
+        $suite = new PHPUnit_Framework_TestSuite('Zend Framework - ZendX_Db');
+
+        /**
+         * Static tests should always be enabled,
+         * but if they're not, don't throw an error.
+         */
+        if (!defined('TESTS_ZENDX_DB_ADAPTER_STATIC_ENABLED')) {
+            define('TESTS_ZENDX_DB_ADAPTER_STATIC_ENABLED', false);
+        }
+
+        self::_addDbTestSuites($suite, 'Firebird');
+
+        /**
+         * @todo  self::_addDbTestSuites($suite, 'Odbc');
+         */
+
+        if (self::$_skipTestSuite !== null) {
+            $suite->addTest(self::$_skipTestSuite);
+        }
+
+        $suite->addTest(Zend_Db_Profiler_AllTests::suite());
+
+        return $suite;
+    }
+
+    protected static function _addDbTestSuites($suite, $driver)
+    {
+        $DRIVER = strtoupper($driver);
+        $enabledConst = "TESTS_ZEND_DB_ADAPTER_{$DRIVER}_ENABLED";
+        if (!defined($enabledConst) || constant($enabledConst) != true) {
+            self::_skipTestSuite($driver, "this Adapter is not enabled in TestConfiguration.php");
+            return;
+        }
+
+        $ext = array(
+            'Firebird' => 'interbase',
+            /**
+             * @todo  'Odbc'
+             */
+        );
+
+        if (isset($ext[$driver]) && !extension_loaded($ext[$driver])) {
+            self::_skipTestSuite($driver, "extension '{$ext[$driver]}' is not loaded");
+            return;
+        }
+
+        if (preg_match('/^pdo_(.*)/i', $driver, $matches)) {
+            // check for PDO extension
+            if (!extension_loaded('pdo')) {
+                self::_skipTestSuite($driver, "extension 'PDO' is not loaded");
+                return;
+            }
+
+            // check the PDO driver is available
+            $pdo_driver = strtolower($matches[1]);
+            if (!in_array($pdo_driver, PDO::getAvailableDrivers())) {
+                self::_skipTestSuite($driver, "PDO driver '{$pdo_driver}' is not available");
+                return;
+            }
+        }
+
+        try {
+
+            Zend_Loader::loadClass("ZendX_Db_Adapter_{$driver}Test");
+            Zend_Loader::loadClass("ZendX_Db_Profiler_{$driver}Test");
+            Zend_Loader::loadClass("ZendX_Db_Statement_{$driver}Test");
+            Zend_Loader::loadClass("ZendX_Db_Select_{$driver}Test");
+            Zend_Loader::loadClass("ZendX_Db_Table_{$driver}Test");
+            Zend_Loader::loadClass("ZendX_Db_Table_Select_{$driver}Test");
+            Zend_Loader::loadClass("ZendX_Db_Table_Rowset_{$driver}Test");
+            Zend_Loader::loadClass("ZendX_Db_Table_Row_{$driver}Test");
+            Zend_Loader::loadClass("ZendX_Db_Table_Relationships_{$driver}Test");
+
+            // if we get this far, there have been no exceptions loading classes
+            // so we can add them as test suites
+
+            $suite->addTestSuite("ZendX_Db_Adapter_{$driver}Test");
+            $suite->addTestSuite("ZendX_Db_Profiler_{$driver}Test");
+            $suite->addTestSuite("ZendX_Db_Statement_{$driver}Test");
+            $suite->addTestSuite("ZendX_Db_Select_{$driver}Test");
+            $suite->addTestSuite("ZendX_Db_Table_{$driver}Test");
+            $suite->addTestSuite("Zendx_Db_Table_Select_{$driver}Test");
+            $suite->addTestSuite("ZendX_Db_Table_Rowset_{$driver}Test");
+            $suite->addTestSuite("ZendX_Db_Table_Row_{$driver}Test");
+            $suite->addTestSuite("ZendX_Db_Table_Relationships_{$driver}Test");
+
+        } catch (Zend_Exception $e) {
+            self::_skipTestSuite($driver, "cannot load test classes: " . $e->getMessage());
+        }
+    }
+
+    protected static function _skipTestSuite($driver, $message = '')
+    {
+        $skipTestClass = "ZendX_Db_Skip_{$driver}Test";
+        $skipTest = new $skipTestClass();
+        $skipTest->message = $message;
+
+        if (self::$_skipTestSuite === null) {
+            self::$_skipTestSuite = new PHPUnit_Framework_TestSuite('ZendX_Db skipped test suites');
+        }
+
+        self::$_skipTestSuite->addTest($skipTest);
+    }
+
+}
+
+if (PHPUnit_MAIN_METHOD == 'Zend_DbX_AllTests::main') {
+    Zend_Db_AllTests::main();
+}

+ 76 - 0
extras/tests/ZendX/Db/Profiler/FirebirdTest.php

@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: StaticTest.php 4700 2007-05-04 04:25:11Z bkarwin $
+ */
+
+
+/**
+ * @see Zend_Db_Profiler_TestCommon
+ */
+require_once 'Zend/Db/Profiler/TestCommon.php';
+
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__);
+
+
+/**
+ * @category   Zend
+ * @package    Zend_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class ZendX_Db_Profiler_FirebirdTest extends Zend_Db_Profiler_TestCommon
+{
+
+    protected function _testProfilerSetFilterQueryTypeCommon($queryType)
+    {
+        $bugs = $this->_db->quoteIdentifier('zfbugs', true);
+        $bug_status = $this->_db->quoteIdentifier('bug_status', true);
+        $bug_id = $this->_db->quoteIdentifier('bug_id', true);
+
+        $prof = $this->_db->getProfiler();
+        $prof->setEnabled(true);
+
+        $this->assertSame($prof->setFilterQueryType($queryType), $prof);
+        $this->assertEquals($queryType, $prof->getFilterQueryType());
+
+        $this->_db->query("SELECT * FROM $bugs");
+        $this->_db->query("INSERT INTO $bugs ($bug_id, $bug_status) VALUES (GEN_ID(\"zfbugs_seq\", 1), ?)", array('NEW'));
+        $this->_db->query("DELETE FROM $bugs");
+        $this->_db->query("UPDATE $bugs SET $bug_status = ?", array('FIXED'));
+
+        $qps = $prof->getQueryProfiles();
+        $this->assertType('array', $qps, 'Expecting some query profiles, got none');
+        foreach ($qps as $qp) {
+            $qtype = $qp->getQueryType();
+            $this->assertEquals($queryType, $qtype,
+                "Found query type $qtype, which should have been filtered out");
+        }
+
+        $prof->setEnabled(false);
+    }
+
+    public function getDriver()
+    {
+        return 'Firebird';
+    }
+}

+ 175 - 0
extras/tests/ZendX/Db/Select/FirebirdTest.php

@@ -0,0 +1,175 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+require_once 'Zend/Db/Select/TestCommon.php';
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__);
+
+class ZendX_Db_Select_FirebirdTest extends Zend_Db_Select_TestCommon
+{
+
+    public function testSelectWhereWithTypeFloat()
+    {
+        $this->markTestIncomplete($this->getDriver() . ' (setlocale bugging subsequent tests)');
+    }
+
+    protected function _selectOrderByAutoExpr()
+    {
+        $products = $this->_db->quoteIdentifier('zfproducts');
+        $product_id = $this->_db->quoteIdentifier('product_id');
+
+        $select = $this->_db->select()
+            ->from('zfproducts')
+            ->order("UPPER($products.$product_id)");
+        return $select;
+    }
+
+    protected function _selectColumnWithColonQuotedParameter()
+    {
+        $product_id = $this->_db->quoteIdentifier('product_id');
+
+        $select = $this->_db->select()
+            ->from('zfproducts')
+            ->where("'as''as:xX'" . ' = ?', $this->_db->quote("as'as:x"));
+        return $select;
+    }
+
+    public function testSelectFromSelectObject ()
+    {
+        $select = $this->_selectFromSelectObject();
+        $query = $select->assemble();
+        $cmp = 'SELECT ' . $this->_db->quoteIdentifier('t') . '.* FROM (SELECT '
+                         . $this->_db->quoteIdentifier('subqueryTable') . '.* FROM '
+                         . $this->_db->quoteIdentifier('subqueryTable') . ') '
+                         . $this->_db->quoteIdentifier('t');
+        $this->assertEquals($query, $cmp);
+    }
+
+    protected function _selectGroupByAutoExpr()
+    {
+        $thecount = $this->_db->quoteIdentifier('thecount');
+        $bugs_products = $this->_db->quoteIdentifier('zfbugs_products');
+        $bug_id = $this->_db->quoteIdentifier('bug_id');
+
+        $select = $this->_db->select()
+            ->from('zfbugs_products', array('bug_id'=>"UPPER($bugs_products.$bug_id)", new Zend_Db_Expr("COUNT(*) AS $thecount")))
+            ->group("UPPER($bugs_products.$bug_id)")
+            ->order("UPPER($bugs_products.$bug_id)");
+        return $select;
+    }
+
+    /**
+     * Test the UNION statement for a Zend_Db_Select object.
+     */
+    protected function _selectUnionString()
+    {
+        $bugs = $this->_db->quoteIdentifier('zfbugs');
+        $bug_id = $this->_db->quoteIdentifier('bug_id');
+        $bug_status = $this->_db->quoteIdentifier('bug_status');
+        $products = $this->_db->quoteIdentifier('zfproducts');
+        $product_id = $this->_db->quoteIdentifier('product_id');
+        $product_name = $this->_db->quoteIdentifier('product_name');
+        $id = $this->_db->quoteIdentifier('id');
+        $name = $this->_db->quoteIdentifier('name');
+        $sql1 = "SELECT $bug_id AS $id, $bug_status AS $name FROM $bugs";
+        $sql2 = "SELECT $product_id AS $id, $product_name AS $name FROM $products";
+
+        $select = $this->_db->select()
+            ->union(array($sql1, $sql2))
+            ->order(new Zend_Db_Expr('1'));
+        return $select;
+    }
+
+    public function testSelectFromQualified()
+    {
+        $this->markTestSkipped($this->getDriver() . ' does not report its schema as we expect.');
+    }
+
+    public function testSelectJoinQualified()
+    {
+        $this->markTestSkipped($this->getDriver() . ' does not report its schema as we expect.');
+    }
+
+    public function testSelectJoin()
+    {
+        $select = $this->_selectJoin();
+        $stmt = $this->_db->query($select);
+        $result = $stmt->fetchAll();
+        $this->assertEquals(6, count($result));
+        $this->assertEquals(4, count($result[0]));
+    }
+
+    public function testSelectJoinInner()
+    {
+        $select = $this->_selectJoinInner();
+        $stmt = $this->_db->query($select);
+        $result = $stmt->fetchAll();
+        $this->assertEquals(6, count($result));
+        $this->assertEquals(4, count($result[0]));
+    }
+
+    public function testSelectJoinRight()
+    {
+        $select = $this->_selectJoinRight();
+        $stmt = $this->_db->query($select);
+        $result = $stmt->fetchAll();
+        $this->assertEquals(7, count($result));
+        $this->assertEquals(10, count($result[0]));
+        $this->assertEquals(3, $result[3]['product_id']);
+        $this->assertNull($result[6]['product_id']);
+    }
+
+    public function testSelectJoinLeft()
+    {
+        $select = $this->_selectJoinLeft();
+        $stmt = $this->_db->query($select);
+        $result = $stmt->fetchAll();
+        $this->assertEquals(7, count($result));
+        $this->assertEquals(10, count($result[0]));
+        $this->assertEquals(3, $result[3]['product_id']);
+        $this->assertNull($result[6]['product_id']);
+    }
+
+    public function testSelectJoinCross()
+    {
+        $select = $this->_selectJoinCross();
+        $stmt = $this->_db->query($select);
+        $result = $stmt->fetchAll();
+        $this->assertEquals(18, count($result));
+        $this->assertEquals(4, count($result[0]));
+    }
+
+    public function testSelectJoinWithCorrelationName()
+    {
+        $select = $this->_selectJoinWithCorrelationName();
+        $stmt = $this->_db->query($select);
+        $result = $stmt->fetchAll();
+        $this->assertEquals(1, count($result));
+        $this->assertEquals(4, count($result[0]));
+    }
+
+
+    public function getDriver()
+    {
+        return 'Firebird';
+    }
+
+}

+ 61 - 0
extras/tests/ZendX/Db/SkipTests.php

@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: $
+ */
+
+require_once 'PHPUnit/Framework/TestCase.php';
+
+/**
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class ZendX_Db_Skip_CommonTest extends PHPUnit_Framework_TestCase
+{
+    public $message = null;
+
+    abstract public function getDriver();
+
+    public function setUp()
+    {
+        $driver = $this->getDriver();
+        $message = 'Skipping ' . $this->getDriver();
+        if ($this->message) {
+            $message .= ': ' . $this->message;
+        }
+        $this->markTestSkipped($message);
+    }
+
+    public function testDb()
+    {
+        // this is here only so we have at least one test
+    }
+}
+
+class ZendX_Db_Skip_FirebirdTest extends ZendX_Db_Skip_CommonTest
+{
+    public function getDriver()
+    {
+        return 'Firebird';
+    }
+}

+ 49 - 0
extras/tests/ZendX/Db/Statement/FirebirdTest.php

@@ -0,0 +1,49 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+require_once 'Zend/Db/Statement/TestCommon.php';
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__);
+
+class ZendX_Db_Statement_FirebirdTest extends Zend_Db_Statement_TestCommon
+{
+
+    public function testStatementBindParamByName()
+    {
+        $this->markTestSkipped($this->getDriver() . ' don\' suport Param by Name');
+    }
+
+    public function testStatementBindValueByName()
+    {
+        $this->markTestSkipped($this->getDriver() . ' don\'t suport Param by Name');
+    }
+
+    public function testStatementGetColumnMeta()
+    {
+        $this->markTestIncomplete($this->getDriver() . ' has not implemented getColumnMeta() yet [ZF-1424]');
+    }
+
+    public function getDriver()
+    {
+        return 'Firebird';
+    }
+
+}

+ 63 - 0
extras/tests/ZendX/Db/Table/FirebirdTest.php

@@ -0,0 +1,63 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+require_once 'Zend/Db/Table/TestCommon.php';
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__);
+
+class ZendX_Db_Table_FirebirdTest extends Zend_Db_Table_TestCommon
+{
+
+    public function testTableInsert()
+    {
+        $this->markTestSkipped($this->getDriver().' does not support auto-increment columns.');
+    }
+	
+    public function testTableInsertWithSchema()
+    {
+        $this->markTestSkipped($this->getDriver() . ' does not report its schema as we expect.');	
+	}
+	
+    public function testTableCascadeDelete()
+    {
+        $table = $this->_table['products'];
+        $row1 = $table->find(2)->current();
+        $row1->delete();
+
+        // Test for 'false' value in cascade config
+        $table = $this->_table['bugs'];
+        $row2 = $table->find(1)->current();
+        $row2->delete();
+
+        $table = $this->_table['bugs_products'];
+        $select = $table->select()
+            ->where('"product_id" = ?', 2);
+
+        $rows = $table->fetchAll($select);
+        $this->assertEquals(0, count($rows));
+    }	
+
+    public function getDriver()
+    {
+        return 'Firebird';
+    }
+
+}

+ 128 - 0
extras/tests/ZendX/Db/Table/Relationships/FirebirdTest.php

@@ -0,0 +1,128 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+require_once 'Zend/Db/Table/Relationships/TestCommon.php';
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__);
+
+class ZendX_Db_Table_Relationships_FirebirdTest extends Zend_Db_Table_Relationships_TestCommon
+{
+
+    public function testTableRelationshipFindParentRowSelect()
+    {
+        $bug_id = $this->_db->quoteIdentifier('bug_id', true);
+        $account_name = $this->_db->foldCase('account_name');
+
+        $table = $this->_table['bugs'];
+        $select = $table->select()->where('"account_name" = ?', 'goofy');
+
+        $childRows = $table->fetchAll("$bug_id = 1");
+        $this->assertType('Zend_Db_Table_Rowset_Abstract', $childRows,
+            'Expecting object of type Zend_Db_Table_Rowset_Abstract, got '.get_class($childRows));
+
+        $childRow1 = $childRows->current();
+        $this->assertType('Zend_Db_Table_Row_Abstract', $childRow1,
+            'Expecting object of type Zend_Db_Table_Row_Abstract, got '.get_class($childRow1));
+
+        $parentRow = $childRow1->findParentRow('Zend_Db_Table_TableAccounts', null, $select);
+        $this->assertType('Zend_Db_Table_Row_Abstract', $parentRow,
+            'Expecting object of type Zend_Db_Table_Row_Abstract, got '.get_class($parentRow));
+
+        $this->assertEquals('goofy', $parentRow->$account_name);
+    }
+
+    public function testTableRelationshipMagicFindParentRowSelect()
+    {
+        $bug_id = $this->_db->quoteIdentifier('bug_id', true);
+        $account_name = $this->_db->foldCase('account_name');
+
+        $table = $this->_table['bugs'];
+        $select = $table->select()->where('"account_name" = ?', 'goofy');
+
+        $childRows = $table->fetchAll("$bug_id = 1");
+        $this->assertType('Zend_Db_Table_Rowset_Abstract', $childRows,
+            'Expecting object of type Zend_Db_Table_Rowset_Abstract, got '.get_class($childRows));
+
+        $childRow1 = $childRows->current();
+        $this->assertType('Zend_Db_Table_Row_Abstract', $childRow1,
+            'Expecting object of type Zend_Db_Table_Row_Abstract, got '.get_class($childRow1));
+
+        $parentRow = $childRow1->findParentZend_Db_Table_TableAccounts($select);
+        $this->assertType('Zend_Db_Table_Row_Abstract', $parentRow,
+            'Expecting object of type Zend_Db_Table_Row_Abstract, got '.get_class($parentRow));
+
+        $this->assertEquals('goofy', $parentRow->$account_name);
+    }
+	
+    public function testTableRelationshipFindManyToManyRowsetSelect()
+    {
+        $product_name = $this->_db->foldCase('product_name');
+        $bug_id = $this->_db->foldCase('"bug_id"');
+
+        $table = $this->_table['bugs'];
+        $select = $table->select()->where($bug_id . ' = ?', 1)
+                                  ->limit(2)
+                                  ->order($product_name . ' ASC');
+
+        $originRows = $table->find(1);
+        $originRow1 = $originRows->current();
+
+        $destRows = $originRow1->findManyToManyRowset('Zend_Db_Table_TableProducts', 'Zend_Db_Table_TableBugsProducts', 
+                                                      null, null, $select);
+        $this->assertType('Zend_Db_Table_Rowset_Abstract', $destRows,
+            'Expecting object of type Zend_Db_Table_Rowset_Abstract, got '.get_class($destRows));
+
+        $this->assertEquals(2, $destRows->count());
+
+        $childRow = $destRows->current();
+        $this->assertEquals('Linux', $childRow->$product_name);
+    }
+
+    public function testTableRelationshipMagicFindManyToManyRowsetSelect()
+    {
+        $product_name = $this->_db->foldCase('product_name');
+        $bug_id = $this->_db->foldCase('"bug_id"');
+
+        $table = $this->_table['bugs'];
+        $select = $table->select()->where($bug_id . ' = ?', 1)
+                                  ->limit(2)
+                                  ->order($product_name . ' ASC');
+
+        $originRows = $table->find(1);
+        $originRow1 = $originRows->current();
+
+        $destRows = $originRow1->findZend_Db_Table_TableProductsViaZend_Db_Table_TableBugsProducts($select);
+        $this->assertType('Zend_Db_Table_Rowset_Abstract', $destRows,
+            'Expecting object of type Zend_Db_Table_Rowset_Abstract, got '.get_class($destRows));
+
+        $this->assertEquals(2, $destRows->count());
+
+        $childRow = $destRows->current();
+        $this->assertEquals('Linux', $childRow->$product_name);
+    }	
+
+
+    public function getDriver()
+    {
+        return 'Firebird';
+    }
+
+}

+ 101 - 0
extras/tests/ZendX/Db/Table/Row/FirebirdTest.php

@@ -0,0 +1,101 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+require_once 'Zend/Db/Table/Row/TestCommon.php';
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__);
+
+class ZendX_Db_Table_Row_FirebirdTest extends Zend_Db_Table_Row_TestCommon
+{
+
+    public function testTableRowSetReadOnly()
+    {
+        $table = $this->_table['bugs'];
+        $bug_status = $this->_db->foldCase('bug_status');
+
+        $rowset = $table->find(1);
+        $row1 = $rowset->current();
+
+        $row1->setReadOnly(true);
+        $this->assertTrue($row1->isReadOnly());
+
+        $data = array(
+            'bug_id'          => $this->_db->nextSequenceId('zfbugs_seq'),
+            'bug_description' => 'New Description',
+            'bug_status'      => 'INVALID'
+        );
+
+        $row2 = $table->createRow($data);
+        $row2->setReadOnly(true);
+        try {
+            $row2->save();
+            $this->fail('Expected to catch Zend_Db_Table_Row_Exception');
+        } catch (Zend_Exception $e) {
+            $this->assertType('Zend_Db_Table_Row_Exception', $e,
+                'Expecting object of type Zend_Db_Table_Row_Exception, got '.get_class($e));
+            $this->assertEquals('This row has been marked read-only', $e->getMessage());
+        }
+
+        $row2->setReadOnly(false);
+        $row2->save();
+
+        $row2->$bug_status = 'VALID';
+        $row2->setReadOnly(true);
+
+        try {
+            $row2->save();
+            $this->fail('Expected to catch Zend_Db_Table_Row_Exception');
+        } catch (Zend_Exception $e) {
+            $this->assertType('Zend_Db_Table_Row_Exception', $e,
+                'Expecting object of type Zend_Db_Table_Row_Exception, got '.get_class($e));
+            $this->assertEquals('This row has been marked read-only', $e->getMessage());
+        }
+
+        $row2->setReadOnly(false);
+        $row2->save();
+    }
+
+    public function testTableRowSaveInsert()
+    {
+        $table = $this->_table['bugs'];
+        $data = array(
+            'bug_description' => 'New Description',
+            'bug_status'      => 'INVALID'
+        );
+        try {
+            $row3 = $table->createRow($data);
+            $this->assertNull($row3->bug_id);
+            $row3->bug_id = $this->_db->nextSequenceId('zfbugs_seq');
+            $row3->save();
+            $this->assertEquals(5, $row3->bug_id);
+            $this->assertEquals($data['bug_description'], $row3->bug_description);
+            $this->assertEquals($data['bug_status'], $row3->bug_status);
+        } catch (Zend_Exception $e) {
+            $this->fail("Caught exception of type \"".get_class($e)."\" where no exception was expected.  Exception message: \"".$e->getMessage()."\"\n");
+        }
+    }
+
+    public function getDriver()
+    {
+        return 'Firebird';
+    }
+
+}

+ 34 - 0
extras/tests/ZendX/Db/Table/Rowset/FirebirdTest.php

@@ -0,0 +1,34 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+require_once 'Zend/Db/Table/Rowset/TestCommon.php';
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__);
+
+class ZendX_Db_Table_Rowset_FirebirdTest extends Zend_Db_Table_Rowset_TestCommon
+{
+
+    public function getDriver()
+    {
+        return 'Firebird';
+    }
+
+}

+ 174 - 0
extras/tests/ZendX/Db/Table/Select/FirebirdTest.php

@@ -0,0 +1,174 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+require_once 'Zend/Db/Table/Select/TestCommon.php';
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__);
+
+class ZendX_Db_Table_Select_FirebirdTest extends Zend_Db_Table_Select_TestCommon
+{
+
+    public function testSelectWhereWithTypeFloat()
+    {
+        $this->markTestIncomplete($this->getDriver() . ' (setlocale bugging subsequent tests)');
+    }
+
+    public function testSelectFromSelectObject ()
+    {
+        $select = $this->_selectFromSelectObject();
+        $query = $select->assemble();
+        $cmp = 'SELECT ' . $this->_db->quoteIdentifier('t') . '.* FROM (SELECT '
+                         . $this->_db->quoteIdentifier('subqueryTable') . '.* FROM '
+                         . $this->_db->quoteIdentifier('subqueryTable') . ') '
+                         . $this->_db->quoteIdentifier('t');
+        $this->assertEquals($query, $cmp);
+    }
+
+    /**
+     * Test the UNION statement for a Zend_Db_Select object.
+     */
+    protected function _selectUnionString()
+    {
+        $bugs = $this->_db->quoteIdentifier('zfbugs');
+        $bug_id = $this->_db->quoteIdentifier('bug_id');
+        $bug_status = $this->_db->quoteIdentifier('bug_status');
+        $products = $this->_db->quoteIdentifier('zfproducts');
+        $product_id = $this->_db->quoteIdentifier('product_id');
+        $product_name = $this->_db->quoteIdentifier('product_name');
+        $id = $this->_db->quoteIdentifier('id');
+        $name = $this->_db->quoteIdentifier('name');
+        $sql1 = "SELECT $bug_id AS $id, $bug_status AS $name FROM $bugs";
+        $sql2 = "SELECT $product_id AS $id, $product_name AS $name FROM $products";
+
+        $select = $this->_db->select()
+            ->union(array($sql1, $sql2))
+            ->order(new Zend_Db_Expr('1'));
+        return $select;
+    }
+
+    protected function _selectColumnWithColonQuotedParameter()
+    {
+        $product_id = $this->_db->quoteIdentifier('product_id');
+
+        $select = $this->_db->select()
+            ->from('zfproducts')
+            ->where("'as''as:xX'" . ' = ?', $this->_db->quote("as'as:x"));
+        return $select;
+    }
+
+    protected function _selectOrderByAutoExpr()
+    {
+        $products = $this->_db->quoteIdentifier('zfproducts');
+        $product_id = $this->_db->quoteIdentifier('product_id');
+
+        $select = $this->_db->select()
+            ->from('zfproducts')
+            ->order("UPPER($products.$product_id)");
+        return $select;
+    }
+
+    protected function _selectGroupByAutoExpr()
+    {
+        $thecount = $this->_db->quoteIdentifier('thecount');
+        $bugs_products = $this->_db->quoteIdentifier('zfbugs_products');
+        $bug_id = $this->_db->quoteIdentifier('bug_id');
+
+        $select = $this->_db->select()
+            ->from('zfbugs_products', array('bug_id'=>"UPPER($bugs_products.$bug_id)", new Zend_Db_Expr("COUNT(*) AS $thecount")))
+            ->group("UPPER($bugs_products.$bug_id)")
+            ->order("UPPER($bugs_products.$bug_id)");
+        return $select;
+    }
+
+    public function testSelectFromQualified()
+    {
+        $this->markTestSkipped($this->getDriver() . ' does not report its schema as we expect.');
+    }
+
+    public function testSelectJoinQualified()
+    {
+        $this->markTestSkipped($this->getDriver() . ' does not report its schema as we expect.');
+    }
+
+    public function testSelectJoin()
+    {
+        $select = $this->_selectJoin();
+        $stmt = $this->_db->query($select);
+        $result = $stmt->fetchAll();
+        $this->assertEquals(6, count($result));
+        $this->assertEquals(4, count($result[0]));
+    }
+
+    public function testSelectJoinInner()
+    {
+        $select = $this->_selectJoinInner();
+        $stmt = $this->_db->query($select);
+        $result = $stmt->fetchAll();
+        $this->assertEquals(6, count($result));
+        $this->assertEquals(4, count($result[0]));
+    }
+
+    public function testSelectJoinRight()
+    {
+        $select = $this->_selectJoinRight();
+        $stmt = $this->_db->query($select);
+        $result = $stmt->fetchAll();
+        $this->assertEquals(7, count($result));
+        $this->assertEquals(10, count($result[0]));
+        $this->assertEquals(3, $result[3]['product_id']);
+        $this->assertNull($result[6]['product_id']);
+    }
+
+    public function testSelectJoinLeft()
+    {
+        $select = $this->_selectJoinLeft();
+        $stmt = $this->_db->query($select);
+        $result = $stmt->fetchAll();
+        $this->assertEquals(7, count($result));
+        $this->assertEquals(10, count($result[0]));
+        $this->assertEquals(3, $result[3]['product_id']);
+        $this->assertNull($result[6]['product_id']);
+    }
+
+    public function testSelectJoinCross()
+    {
+        $select = $this->_selectJoinCross();
+        $stmt = $this->_db->query($select);
+        $result = $stmt->fetchAll();
+        $this->assertEquals(18, count($result));
+        $this->assertEquals(4, count($result[0]));
+    }
+
+    public function testSelectJoinWithCorrelationName()
+    {
+        $select = $this->_selectJoinWithCorrelationName();
+        $stmt = $this->_db->query($select);
+        $result = $stmt->fetchAll();
+        $this->assertEquals(1, count($result));
+        $this->assertEquals(4, count($result[0]));
+    }
+
+    public function getDriver()
+    {
+        return 'Firebird';
+    }
+
+}

+ 69 - 0
extras/tests/ZendX/Db/Table/TestSetup.php

@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: TestSetup.php 4791 2007-05-12 23:54:20Z bkarwin $
+ */
+
+
+/**
+ * @see ZendX_Db_TestSetup
+ */
+require_once 'ZendX/Db/TestSetup.php';
+
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__);
+
+
+/**
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class ZendX_Db_Table_TestSetup extends Zend_Db_TestSetup
+{
+
+    /**
+     * @var array of Zend_Db_Table_Abstract
+     */
+    protected $_table = array();
+
+    public function setUp()
+    {
+        parent::setUp();
+
+        $this->_table['accounts']      = $this->_getTable('Zend_Db_Table_TableAccounts');
+        $this->_table['bugs']          = $this->_getTable('Zend_Db_Table_TableBugs');
+        $this->_table['bugs_products'] = $this->_getTable('Zend_Db_Table_TableBugsProducts');
+        $this->_table['products']      = $this->_getTable('Zend_Db_Table_TableProducts');
+    }
+
+    protected function _getTable($tableClass, $options = array())
+    {
+        if (is_array($options) && !isset($options['db'])) {
+            $options['db'] = $this->_db;
+        }
+        Zend_Loader::loadClass($tableClass);
+        $table = new $tableClass($options);
+        return $table;
+    }
+
+}

+ 127 - 0
extras/tests/ZendX/Db/TestSetup.php

@@ -0,0 +1,127 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: $
+ */
+
+
+/**
+ * Test helper
+ */
+
+
+require_once dirname(__FILE__) . '/../../TestHelper.php';
+
+/**
+ * @see Zend_Loader
+ */
+require_once 'Zend/Loader.php';
+
+/**
+ * @see Zend_Db
+ */
+require_once 'Zend/Db.php';
+
+/**
+ * PHPUnit_Framework_TestCase
+ */
+require_once 'PHPUnit/Framework/TestCase.php';
+
+/**
+ * PHPUnit_Util_Filter
+ */
+require_once 'PHPUnit/Util/Filter.php';
+
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__);
+
+
+/**
+ * @category   ZendX
+ * @package    ZendX_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class ZendX_Db_TestSetup extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var ZendX_Db_TestUtil
+     */
+    protected $_util = null;
+
+    /**
+     * @var Zend_Db_Adapter_Abstract
+     */
+    protected $_db = null;
+
+    public abstract function getDriver();
+
+    /**
+     * Subclasses should call parent::setUp() before
+     * doing their own logic, e.g. creating metadata.
+     */
+    public function setUp()
+    {
+        $this->_setUpTestUtil();
+        $this->_setUpAdapter();
+        $this->_util->setUp($this->_db);
+    }
+
+    /**
+     * Get a TestUtil class for the current RDBMS brand.
+     */
+    protected function _setUpTestUtil()
+    {
+        $driver = $this->getDriver();
+        $utilClass = "ZendX_Db_TestUtil_{$driver}";
+        Zend_Loader::loadClass($utilClass);
+        $this->_util = new $utilClass();
+    }
+
+    /**
+     * Open a new database connection
+     */
+    protected function _setUpAdapter()
+    {
+        $params = $this->_util->getParams();
+        $params['adapterNamespace'] = 'ZendX_Db_Adapter';
+        $this->_db = Zend_Db::factory($this->getDriver(), $params);
+        try {
+            $conn = $this->_db->getConnection();
+        } catch (Zend_Exception $e) {
+            $this->_db = null;
+            $this->assertType('Zend_Db_Adapter_Exception', $e,
+                'Expecting Zend_Db_Adapter_Exception, got ' . get_class($e));
+            $this->markTestSkipped($e->getMessage());
+        }
+    }
+
+    /**
+     * Subclasses should call parent::tearDown() after
+     * doing their own logic, e.g. deleting metadata.
+     */
+    public function tearDown()
+    {
+        $this->_util->tearDown();
+        $this->_db = null;
+    }
+
+}

+ 218 - 0
extras/tests/ZendX/Db/TestUtil/Firebird.php

@@ -0,0 +1,218 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Db
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: Firebird.php 6847 2007-11-18 05:24:21Z peptolab $
+ */
+
+
+/**
+ * @see Zend_Db_TestUtil_Common
+ */
+require_once 'Zend/Db/TestUtil/Common.php';
+
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__);
+
+
+/**
+ * @category   Zend
+ * @package    Zend_Db
+ * @subpackage Table
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Db_TestUtil_Firebird extends Zend_Db_TestUtil_Common
+{
+    public function tearDown()
+    {
+        $this->_setUpDatabase(false);
+    }
+
+
+    private function _getConnString()
+    {
+        return  '"' .
+                TESTS_ZEND_DB_ADAPTER_FIREBIRD_HOSTNAME .
+                ( TESTS_ZEND_DB_ADAPTER_FIREBIRD_PORT ? '/' . TESTS_ZEND_DB_ADAPTER_FIREBIRD_PORT : '' ) .
+                TESTS_ZEND_DB_ADAPTER_FIREBIRD_DATABASE .
+                '" USER "' .
+                TESTS_ZEND_DB_ADAPTER_FIREBIRD_USERNAME .
+                '" PASSWORD "' .
+                TESTS_ZEND_DB_ADAPTER_FIREBIRD_PASSWORD .
+                '";';
+
+    }
+
+    private function _setUpDatabase($create = true)
+    {
+        $temp_file = tempnam(sys_get_temp_dir(), 'fbtest.sql');
+        $cmd = 'CONNECT ' . $this->_getConnString() .
+               'DROP DATABASE;' .
+               ( $create ? 'CREATE DATABASE ' . $this->_getConnString() : '');
+
+        file_put_contents($temp_file, $cmd);
+        exec('"TESTS_ZEND_DB_ADAPTER_FIREBIRD_BINPATH" -i ' . $temp_file, $output, $return_var);
+        unlink($temp_file);    
+    }
+
+    public function setUp(Zend_Db_Adapter_Abstract $db)
+    {
+        $this->_setUpDatabase();
+
+        parent::setUp($db);
+
+
+        $this->createSequence('zfbugs_seq');
+        $this->createSequence('zfproducts_seq');
+
+		$zfbugs_seq = $this->_db->quoteIdentifier('zfbugs_seq');
+		$zfproducts_seq = $this->_db->quoteIdentifier('zfproducts_seq');
+
+        $this->_rawQuery("SET GENERATOR $zfbugs_seq TO 4");
+        $this->_rawQuery("SET GENERATOR $zfproducts_seq TO 3");
+    }
+
+    protected function _getDataProducts()
+    {
+        return array(
+            array('product_id' => 1, 'product_name' => 'Windows'),
+            array('product_id' => 2, 'product_name' => 'Linux'),
+            array('product_id' => 3, 'product_name' => 'OS X'),
+        );
+    }
+
+    protected function _getColumnsBugs()
+    {
+        return array(
+            'bug_id'          => 'IDENTITY',
+            'bug_description' => 'VARCHAR(100)',
+            'bug_status'      => 'VARCHAR(20)',
+            'created_on'      => 'TIMESTAMP',
+            'updated_on'      => 'TIMESTAMP',
+            'reported_by'     => 'VARCHAR(100)',
+            'assigned_to'     => 'VARCHAR(100)',
+            'verified_by'     => 'VARCHAR(100)'
+        );
+    }
+
+    protected function _getDataBugs()
+    {
+        return array(
+            array(
+				'bug_id'		  => 1,
+                'bug_description' => 'System needs electricity to run',
+                'bug_status'      => 'NEW',
+                'created_on'      => '2007-04-01',
+                'updated_on'      => '2007-04-01',
+                'reported_by'     => 'goofy',
+                'assigned_to'     => 'mmouse',
+                'verified_by'     => 'dduck'
+            ),
+            array(
+				'bug_id'		  => 2,
+                'bug_description' => 'Implement Do What I Mean function',
+                'bug_status'      => 'VERIFIED',
+                'created_on'      => '2007-04-02',
+                'updated_on'      => '2007-04-02',
+                'reported_by'     => 'goofy',
+                'assigned_to'     => 'mmouse',
+                'verified_by'     => 'dduck'
+            ),
+            array(
+				'bug_id'		  => 3,
+                'bug_description' => 'Where are my keys?',
+                'bug_status'      => 'FIXED',
+                'created_on'      => '2007-04-03',
+                'updated_on'      => '2007-04-03',
+                'reported_by'     => 'dduck',
+                'assigned_to'     => 'mmouse',
+                'verified_by'     => 'dduck'
+            ),
+            array(
+				'bug_id'		  => 4,
+                'bug_description' => 'Bug no product',
+                'bug_status'      => 'INCOMPLETE',
+                'created_on'      => '2007-04-04',
+                'updated_on'      => '2007-04-04',
+                'reported_by'     => 'mmouse',
+                'assigned_to'     => 'goofy',
+                'verified_by'     => 'dduck'
+            )
+        );
+    }
+
+    protected function _getColumnsDocuments()
+    {
+        return array(
+            'doc_id'       => 'INTEGER NOT NULL',
+            'doc_clob'     => 'BLOB',
+            'doc_blob'     => 'BLOB',
+            'PRIMARY KEY'  => 'doc_id'
+            );
+    }
+
+    public function getParams(array $constants = array())
+    {
+        $constants = array(
+            'host'     => 'TESTS_ZEND_DB_ADAPTER_FIREBIRD_HOSTNAME',
+            'username' => 'TESTS_ZEND_DB_ADAPTER_FIREBIRD_USERNAME',
+            'password' => 'TESTS_ZEND_DB_ADAPTER_FIREBIRD_PASSWORD',
+            'dbname'   => 'TESTS_ZEND_DB_ADAPTER_FIREBIRD_DATABASE',
+			'port' 	   => 'TESTS_ZEND_DB_ADAPTER_FIREBIRD_PORT'
+        );
+        return parent::getParams($constants);
+    }
+
+    public function getSqlType($type)
+    {
+        if ($type == 'IDENTITY') {
+            return 'INTEGER NOT NULL PRIMARY KEY';
+        }
+        return $type;
+    }
+
+    protected function _getSqlCreateSequence($sequenceName)
+    {
+		$sequenceName = $this->_db->quoteIdentifier($sequenceName);
+        return "CREATE GENERATOR $sequenceName";
+    }
+
+    protected function _getSqlDropSequence($sequenceName)
+    {
+		$sequenceName = $this->_db->quoteIdentifier($sequenceName);
+        return "DROP GENERATOR $sequenceName";
+    }
+
+    protected function _rawQuery($sql)
+    {
+        $conn = $this->_db->getConnection();
+        try {
+		  ibase_query($conn, $sql);
+		  ibase_commit($conn);
+		} catch (Exception $e) {
+			if (!stripos(' '.$sql, 'drop')){
+				$e = ibase_errmsg();
+				require_once 'Zend/Db/Exception.php';
+				throw new Zend_Db_Exception("SQL parse error for \"$sql\": ".$e);
+			}
+        }
+    }
+
+}

+ 63 - 0
extras/tests/ZendX/JQuery/AllTests.php

@@ -0,0 +1,63 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once dirname(__FILE__)."/../../TestHelper.php";
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'ZendX_JQuery_View_AllTests::main');
+}
+
+require_once "Zend/Registry.php";
+require_once "Zend/View.php";
+require_once "ZendX/JQuery.php";
+require_once "ZendX/JQuery/View/Helper/JQuery.php";
+
+require_once "ZendX/JQuery/JQueryTest.php";
+require_once "ZendX/JQuery/AutoCompleteActionHelperTest.php";
+require_once "ZendX/JQuery/View/AllTests.php";
+require_once "ZendX/JQuery/Form/AllTests.php";
+
+class ZendX_JQuery_AllTests
+{
+    public static function main()
+    {
+        PHPUnit_TextUI_TestRunner::run(self::suite());
+    }
+
+    public static function suite()
+    {
+        $suite = new PHPUnit_Framework_TestSuite('Zend Framework - ZendX_JQuery');
+
+        $suite->addTestSuite('ZendX_JQuery_JQueryTest');
+        $suite->addTestSuite('ZendX_JQuery_View_AllTests');
+        $suite->addTestSuite('ZendX_JQuery_Form_AllTests');
+        $suite->addTestSuite('ZendX_JQuery_AutoCompleteActionHelperTest');
+
+        return $suite;
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'ZendX_JQuery_AllTests::main') {
+    ZendX_JQuery_AllTests::main();
+}
+
+?>

+ 70 - 0
extras/tests/ZendX/JQuery/AutoCompleteActionHelperTest.php

@@ -0,0 +1,70 @@
+<?php
+
+require_once dirname(__FILE__)."/../../TestHelper.php";
+
+require_once "Zend/Controller/Front.php";
+require_once "Zend/Controller/Request/Simple.php";
+require_once "Zend/Controller/Response/Cli.php";
+require_once "ZendX/JQuery/Controller/Action/Helper/AutoComplete.php";
+
+class ZendX_JQuery_AutoCompleteActionHelperTest extends PHPUnit_Framework_TestCase
+{
+    protected $_front = null;
+
+    public function setUp()
+    {
+        $this->_front = Zend_Controller_Front::getInstance();
+        $this->_front->resetInstance();
+
+        $request = new Zend_Controller_Request_Simple();
+        $this->_front->setRequest($request);
+
+        $response = new Zend_Controller_Response_Cli();
+        $this->_front->setResponse($response);
+    }
+
+    public function testCallDirectMethodOnHelperSimpleStructure()
+    {
+        $helper = new ZendX_JQuery_Controller_Action_Helper_AutoComplete();
+        $autoCompleteOutput = $helper->direct(
+            array("New York", "Bonn", "Tokio"),
+            false
+        );
+        $this->assertEquals("New York\nBonn\nTokio\n", $autoCompleteOutput);
+    }
+
+    public function testCallDirectMethodOnHelperKeyValueStructure()
+    {
+        $helper = new ZendX_JQuery_Controller_Action_Helper_AutoComplete();
+        $autoCompleteOutput = $helper->direct(
+            array(
+                "United States" => "Washington",
+                "Germany"       => "Berlin",
+                "Japan"         => "Tokio"
+            ),
+            false
+        );
+        $this->assertEquals(
+            "United States|Washington\nGermany|Berlin\nJapan|Tokio\n",
+            $autoCompleteOutput
+        );
+    }
+
+    public function testCallWithInvalidData()
+    {
+        $helper = new ZendX_JQuery_Controller_Action_Helper_AutoComplete();
+        try {
+            $helper->direct("invaliddata", false);
+            $this->fail();
+        } catch(Zend_Controller_Action_Exception $e) {
+        
+        }
+    }
+
+    public function testValidateData()
+    {
+        $helper = new ZendX_JQuery_Controller_Action_Helper_AutoComplete();
+        $this->assertTrue($helper->validateData(array("New York")));
+        $this->assertFalse($helper->validateData("stringinvalid"));
+    }
+}

+ 52 - 0
extras/tests/ZendX/JQuery/Form/AllTests.php

@@ -0,0 +1,52 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id: AllTests.php 11232 2008-09-05 08:16:33Z beberlei $
+ */
+
+require_once dirname(__FILE__)."/../../../TestHelper.php";
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'ZendX_JQuery_Form_AllTests::main');
+}
+
+require_once "DecoratorTest.php";
+require_once "ElementTest.php";
+
+class ZendX_JQuery_Form_AllTests
+{
+    public static function main()
+    {
+        PHPUnit_TextUI_TestRunner::run(self::suite());
+    }
+
+    public static function suite()
+    {
+        $suite = new PHPUnit_Framework_TestSuite('Zend Framework - ZendX_JQuery - Forms');
+
+        $suite->addTestSuite('ZendX_JQuery_Form_DecoratorTest');
+        $suite->addTestSuite('ZendX_JQuery_Form_ElementTest');
+
+        return $suite;
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'ZendX_JQuery_Form_AllTests::main') {
+    ZendX_JQuery_Form_AllTests::main();
+}

+ 406 - 0
extras/tests/ZendX/JQuery/Form/DecoratorTest.php

@@ -0,0 +1,406 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id: AllTests.php 11232 2008-09-05 08:16:33Z beberlei $
+ */
+
+require_once dirname(__FILE__)."/../../../TestHelper.php";
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'ZendX_JQuery_View_DecoratorTest::main');
+}
+
+require_once "Zend/Registry.php";
+require_once "Zend/View.php";
+require_once "ZendX/JQuery.php";
+require_once "ZendX/JQuery/View/Helper/JQuery.php";
+
+require_once "ZendX/JQuery/Form.php";
+require_once "ZendX/JQuery/Form/Element/Spinner.php";
+require_once "Zend/Form/Decorator/ViewHelper.php";
+require_once "ZendX/JQuery/Form/Decorator/UiWidgetElement.php";
+require_once "ZendX/JQuery/Form/Decorator/TabContainer.php";
+require_once "ZendX/JQuery/Form/Decorator/TabPane.php";
+
+class ZendX_JQuery_Form_DecoratorTest extends PHPUnit_Framework_TestCase
+{
+    public function setUp()
+    {
+        Zend_Registry::_unsetInstance();
+    }
+
+    /**
+     * Returns the contens of the exepcted $file
+     *
+     * @param  string $file
+     * @return string
+     */
+    protected function _getExpected($file)
+    {
+        return file_get_contents(dirname(__FILE__) . '/_files/expected/' . $file);
+    }
+
+    public function testUiWidgetElementDecoratorRender()
+    {
+        $ac = new ZendX_JQuery_Form_Element_Spinner("ac1");
+        // Remove all non jQUery related decorators
+        $ac->removeDecorator('Errors');
+        $ac->removeDecorator('HtmlTag');
+        $ac->removeDecorator('Label');
+
+        try {
+            $ac->render();
+            $this->fail();
+        } catch(Zend_Form_Decorator_Exception $e) {
+
+        } catch(Zend_Exception $e) {
+            $this->fail();
+        }
+
+        $view = new Zend_View();
+        ZendX_JQuery::enableView($view);
+
+        $ac->setView($view);
+        $output = $ac->render();
+
+        $this->assertContains("ac1", $output);
+    }
+
+    public function testUiWidgetElementJQueryParams()
+    {
+        $spinner = new ZendX_JQuery_Form_Element_Spinner("ac1");
+        $uiWidget = $spinner->getDecorator('UiWidgetElement');
+
+        $uiWidget->setJQueryParam("foo", "bar");
+        $this->assertEquals(array("foo" => "bar"), $uiWidget->getJQueryParams());
+
+        $uiWidget->setJQueryParams(array("bar" => "baz"));
+        $this->assertEquals(array("foo" => "bar", "bar" => "baz"), $uiWidget->getJQueryParams());
+
+        $this->assertEquals("bar", $uiWidget->getJQueryParam("foo"));
+        $this->assertEquals("baz", $uiWidget->getJQueryParam("bar"));
+        $this->assertNull($uiWidget->getJQueryParam("unknownParam"));
+    }
+
+    public function testUiWidgetElementRendersElementJQueryParams()
+    {
+        $view = new Zend_View();
+        ZendX_JQuery::enableView($view);
+
+        $spinner = new ZendX_JQuery_Form_Element_Spinner("ac1");
+        $spinner->setJQueryParam('min', 100);
+        $spinner->setView($view);
+        $output = $spinner->render();
+        $this->assertEquals(array('$("#ac1").spinner({"min":100});'), $view->jQuery()->getOnLoadActions());
+    }
+
+    public function testUiWidgetContainerGetHelper()
+    {
+        $container = new ZendX_JQuery_Form_Decorator_TabContainer();
+        $this->assertEquals("tabContainer", $container->getHelper());
+    }
+
+    public function testUiWidgetContainerGetAttribs()
+    {
+        $container = new ZendX_JQuery_Form_Decorator_TabContainer();
+        $ac = new ZendX_JQuery_Form_Element_Spinner("ac1");
+        $container->setElement($ac);
+
+        $this->assertEquals(array("helper" => "spinner", "options" => array()), $container->getAttribs());
+    }
+
+    public function testUiWidgetContainerGetJQueryParams()
+    {
+        $container = new ZendX_JQuery_Form_Decorator_TabContainer();
+        $ac = new ZendX_JQuery_Form_Element_Spinner("spinner");
+        $ac->setJQueryParams(array("foo" => "bar", "baz" => "baz"));
+        $container->setElement($ac);
+
+        $this->assertEquals(array("foo" => "bar", "baz" => "baz"), $container->getJQueryParams());
+    }
+
+    public function testUiWidgetPaneRenderingThrowsExceptionWithoutContainerIdOption()
+    {
+        $spinner = new ZendX_JQuery_Form_Element_Spinner("spinner1");
+        $spinner->setView(new Zend_View());
+        $spinner->setJQueryParam("title", "Title");
+
+        $pane = new ZendX_JQuery_Form_Decorator_TabPane();
+        $pane->setElement($spinner);
+
+        try {
+            $pane->render("");
+            $this->fail();
+        } catch(Zend_Form_Decorator_Exception $e) {
+
+        }
+    }
+
+    public function testUiWidgetPaneRenderingThrowsExceptionWithoutTitleOption()
+    {
+        $spinner = new ZendX_JQuery_Form_Element_Spinner("spinner1");
+        $spinner->setView(new Zend_View());
+        $spinner->setJQueryParam("containerId", "xyzId");
+
+        $pane = new ZendX_JQuery_Form_Decorator_TabPane();
+        $pane->setElement($spinner);
+
+        try {
+            $pane->render("");
+            $this->fail();
+        } catch(Zend_Form_Decorator_Exception $e) {
+
+        }
+    }
+
+    public function testUiWidgetPaneRenderingNoPaneWhenElementHasNoView()
+    {
+        $spinner = new ZendX_JQuery_Form_Element_Spinner("spinner1");
+
+        $pane = new ZendX_JQuery_Form_Decorator_TabPane();
+        $pane->setElement($spinner);
+
+        $this->assertEquals("justthis", $pane->render("justthis"));
+    }
+
+    public function testUiWidgetContainerRender()
+    {
+        $view = new Zend_View();
+        ZendX_JQuery::enableView($view);
+
+        // Create new jQuery Form
+        $form = new ZendX_JQuery_Form();
+        $form->setView($view);
+        $form->setAction('formdemo.php');
+        $form->setAttrib('id', 'mainForm');
+
+        // Use a TabContainer for your form:
+        $form->setDecorators(array(
+            'FormElements',
+            array('TabContainer', array(
+                'id'          => 'tabContainer',
+                'style'       => 'width: 600px;',
+                'jQueryParams' => array(
+                    'tabPosition' => 'top'
+                ),
+            )),
+            'Form',
+        ));
+
+        $subForm1 = new ZendX_JQuery_Form('subform1');
+        $subForm1->setView($view);
+
+        // Add Element Spinner
+        $elem = new ZendX_JQuery_Form_Element_Spinner("spinner1", array('label' => 'Spinner:', 'attribs' => array('class' => 'flora')));
+        $elem->setJQueryParams(array('min' => 0, 'max' => 1000, 'start' => 100));
+
+        $subForm1->addElement($elem);
+
+        $subForm1->setDecorators(array(
+            'FormElements',
+            array('HtmlTag', array('tag' => 'dl')),
+            array('TabPane', array('jQueryParams' => array('containerId' => 'mainForm', 'title' => 'Slider'))),
+        ));
+
+        $form->addSubForm($subForm1, "form1");
+
+        $output = $form->render($view);
+        $this->assertContains('id="tabContainer"', $output);
+        $this->assertContains('href="#tabContainer-frag-1"', $output);
+        $this->assertContains('id="tabContainer-frag-1"', $output);
+    }
+
+    /**
+     * @group ZF-12175
+     */
+    public function testUiWidgetContainerRenderWithContent()
+    {
+        // Setup view
+        $view = new Zend_View();
+        ZendX_JQuery::enableView($view);
+
+        // Create jQuery Form
+        $form = new ZendX_JQuery_Form(
+            array(
+                 'method'     => Zend_Form::METHOD_GET,
+                 'attribs'    => array(
+                     'id' => 'mainForm',
+                 ),
+                 'decorators' => array(
+                     'FormElements',
+                     array(
+                         'HtmlTag',
+                         array(
+                             'tag' => 'dl',
+                         ),
+                     ),
+                     array(
+                         'TabContainer',
+                         array(
+                             'id'        => 'tabContainer',
+                             'placement' => 'prepend',
+                             'separator' => '',
+                         ),
+                     ),
+                     'Form',
+                 )
+            )
+        );
+
+        // Add sub form
+        $subForm = new ZendX_JQuery_Form(
+            array(
+                 'decorators' => array(
+                     'FormElements',
+                     array(
+                         'HtmlTag',
+                         array(
+                             'tag' => 'dl',
+                         ),
+                     ),
+                     array(
+                         'TabPane',
+                         array(
+                             'jQueryParams' => array(
+                                 'containerId' => 'mainForm',
+                                 'title'       => 'Slider',
+                             ),
+                         ),
+                     ),
+                 )
+            )
+        );
+        $form->addSubForm($subForm, 'subform');
+
+        // Add spinner element to subform
+        $subForm->addElement(
+            'spinner',
+            'spinner',
+            array(
+                 'label'   => 'Spinner:',
+                 'attribs' => array(
+                     'class' => 'flora',
+                 ),
+                 'jQueryParams' => array(
+                     'min'   => 0,
+                      'max'   => 1000,
+                      'start' => 100,
+                 ),
+            )
+        );
+
+        // Add submit button to main form
+        $form->addElement(
+            'submit',
+            'submit',
+            array(
+                 'label' => 'Send',
+            )
+        );
+
+        $this->assertSame(
+            $this->_getExpected('uiwidgetcontainer/with_content.html'),
+            $form->render($view)
+        );
+    }
+
+    /**
+     * @group ZF-8055
+     */
+    public function testUiWidgetDialogContainerRenderBug()
+    {
+        $view = new Zend_View();
+        ZendX_JQuery::enableView($view);
+
+        // Create new jQuery Form
+        $form = new ZendX_JQuery_Form();
+        $form->setView($view);
+        $form->setAction('formdemo.php');
+        $form->setAttrib('id', 'mainForm');
+
+        // Use a TabContainer for your form:
+        $form->setDecorators(array(
+            'FormElements',
+            'Form',
+            array('DialogContainer', array(
+                'id'          => 'tabContainer',
+                'style'       => 'width: 600px;',
+                'jQueryParams' => array(
+                    'tabPosition' => 'top'
+                ),
+            )),
+        ));
+
+        $subForm1 = new ZendX_JQuery_Form('subform1');
+        $subForm1->setView($view);
+
+        // Add Element Spinner
+        $elem = new ZendX_JQuery_Form_Element_Spinner("spinner1", array('label' => 'Spinner:', 'attribs' => array('class' => 'flora')));
+        $elem->setJQueryParams(array('min' => 0, 'max' => 1000, 'start' => 100));
+
+        $subForm1->addElement($elem);
+
+        $subForm1->setDecorators(array(
+            'FormElements',
+            array('HtmlTag', array('tag' => 'dl')),
+        ));
+
+        $form->addSubForm($subForm1, "form1");
+
+        $output = $form->render($view);
+
+        $this->assertContains('<div id="tabContainer" style="width: 600px;"><form', $output);
+    }
+
+    public function testRenderWidgetElementShouldEnableJQueryHelper()
+    {
+        $view = new Zend_View();
+
+        $widget = new ZendX_JQuery_Form_Element_Spinner("spinner1", array("label" => "Spinner"));
+        $widget->setView($view);
+
+        $view->jQuery()->disable();
+        $view->jQuery()->uiDisable();
+
+        $widget->render();
+
+        $this->assertTrue($view->jQuery()->isEnabled());
+        $this->assertTrue($view->jQuery()->uiIsEnabled());
+    }
+
+    public function testSettingWidgetPlacement()
+    {
+        $view = new Zend_View();
+        $widget = new ZendX_JQuery_Form_Element_Spinner("spinner1");
+        $widget->setView($view);
+        $widget->getDecorator('UiWidgetElement')->setOption('separator', '[SEP]');
+
+        $widget->getDecorator('UiWidgetElement')->setOption('placement', 'APPEND');
+        $html = $widget->render();
+        $this->assertContains('[SEP]<input type="text" name="spinner1" id="spinner1" value="">', $html);
+
+        $widget->getDecorator('UiWidgetElement')->setOption('placement', 'PREPEND');
+        $html = $widget->render();
+        $this->assertContains('<input type="text" name="spinner1" id="spinner1" value="">[SEP]', $html);
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'ZendX_JQuery_Form_DecoratorTest::main') {
+    ZendX_JQuery_Form_DecoratorTest::main();
+}

+ 239 - 0
extras/tests/ZendX/JQuery/Form/ElementTest.php

@@ -0,0 +1,239 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id: AllTests.php 11232 2008-09-05 08:16:33Z beberlei $
+ */
+
+require_once dirname(__FILE__)."/../../../TestHelper.php";
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'ZendX_JQuery_Form_ElementTest::main');
+}
+
+require_once "Zend/Registry.php";
+require_once "Zend/View.php";
+require_once "Zend/Form/Element.php";
+require_once "Zend/Form/SubForm.php";
+require_once "Zend/Form/Decorator/Description.php";
+require_once "Zend/Json.php";
+require_once "ZendX/JQuery.php";
+require_once "ZendX/JQuery/Form.php";
+require_once "ZendX/JQuery/View/Helper/JQuery.php";
+
+require_once "ZendX/JQuery/Form/Element/Spinner.php";
+require_once "ZendX/JQuery/Form/Element/Slider.php";
+require_once "ZendX/JQuery/Form/Element/ColorPicker.php";
+require_once "ZendX/JQuery/Form/Element/DatePicker.php";
+require_once "ZendX/JQuery/Form/Element/AutoComplete.php";
+
+require_once "Zend/Form/Decorator/ViewHelper.php";
+require_once "ZendX/JQuery/Form/Decorator/UiWidgetElement.php";
+
+
+class ZendX_JQuery_Form_ElementTest extends PHPUnit_Framework_TestCase
+{
+    public function setUp()
+    {
+        Zend_Registry::_unsetInstance();
+    }
+
+    public function testElementSetGetJQueryParam()
+    {
+        $spinner = new ZendX_JQuery_Form_Element_Spinner('spinnerElem');
+        $spinner->setJQueryParam("foo", "baz");
+        $this->assertEquals("baz", $spinner->getJQueryParam("foo"));
+
+        $spinner->setJQueryParam("foo", "bar");
+        $spinner->setJQueryParam("bar", array());
+        $this->assertEquals("bar", $spinner->getJQueryParam("foo"));
+        $this->assertEquals(array(), $spinner->getJQueryParam("bar"));
+    }
+
+    public function testElementSetGetMassJQueryParams()
+    {
+        $spinner = new ZendX_JQuery_Form_Element_Spinner('spinnerElem');
+
+        $spinner->setJQueryParams(array("foo" => "baz", "bar" => "baz"));
+        $this->assertEquals(array("foo" => "baz", "bar" => "baz"), $spinner->getJQueryParams());
+
+        $spinner->setJQueryParams(array("foo" => "bar"));
+        $this->assertEquals(array("foo" => "bar", "bar" => "baz"), $spinner->getJQueryParams());
+    }
+
+    public function testElementsHaveUiWidgetDecorator()
+    {
+        $spinner = new ZendX_JQuery_Form_Element_Spinner('spinnerElem');
+        $this->assertTrue($spinner->getDecorator('UiWidgetElement') !== false);
+
+        $slider = new ZendX_JQuery_Form_Element_Slider('sliderElem');
+        $this->assertTrue($slider->getDecorator('UiWidgetElement') !== false);
+
+        $cp = new ZendX_JQuery_Form_Element_ColorPicker('cpElem');
+        $this->assertTrue($cp->getDecorator('UiWidgetElement') !== false);
+
+        $dp = new ZendX_JQuery_Form_Element_DatePicker('dpElem');
+        $this->assertTrue($dp->getDecorator('UiWidgetElement') !== false);
+
+        $ac = new ZendX_JQuery_Form_Element_AutoComplete('acElem');
+        $this->assertTrue($ac->getDecorator('UiWidgetElement') !== false);
+    }
+
+    public function testElementsEnableJQueryViewPath()
+    {
+        $view = new Zend_View();
+        $spinner = new ZendX_JQuery_Form_Element_Spinner("spinner1");
+
+        $this->assertFalse( false !== $view->getPluginLoader('helper')->getPaths('ZendX_JQuery_View_Helper'));
+        $spinner->setView($view);
+        $this->assertTrue( false !== $view->getPluginLoader('helper')->getPaths('ZendX_JQuery_View_Helper'));
+    }
+
+    /**
+     * @group ZF-4694
+     */
+    public function testJQueryElementWithOnlyViewHelperIsNotAllowedToDieZf4694()
+    {
+        $view = new Zend_View();
+
+        $spinner = new ZendX_JQuery_Form_Element_Spinner("spinner1");
+        $spinner->setDecorators(array('ViewHelper'));
+        $spinner->setView($view);
+
+        try {
+            $spinner->render();
+            $this->fail();
+        } catch(ZendX_JQuery_Form_Exception $e) {
+            // success here
+        } catch(Exception $e) {
+            $this->fail();
+        }
+    }
+
+    /**
+     * @group ZF-5125
+     */
+    public function testJQueryElementHasToImplementMarkerInterface()
+    {
+        $view = new Zend_View();
+
+        $spinner = new ZendX_JQuery_Form_Element_Spinner("spinner1");
+        $spinner->setDecorators(array('ViewHelper'));
+        $spinner->setView($view);
+
+        try {
+            $spinner->render();
+            $this->fail();
+        } catch(ZendX_JQuery_Form_Exception $e) {
+            // success here
+        }
+
+        $spinner->setDecorators(array('UiWidgetElement'));
+        try {
+            $spinner->render();
+            // success here
+        } catch(ZendX_JQuery_Form_Exception $e) {
+            $this->fail();
+        }
+    }
+
+    /**
+     * @group ZF-4859
+     */
+    public function testAutocompleteDoesNotDoubleArrayEncodeDataJsonField()
+    {
+        $view = new Zend_View();
+        $form = new  ZendX_JQuery_Form();
+
+        $dataSource = array(0 => 'John Doe');
+
+        $lastname = new ZendX_JQuery_Form_Element_AutoComplete("Lastname", array('label' => 'Lastname'));
+        $form->addElement($lastname);
+        $form->Lastname->setJQueryParam('source', $dataSource);
+
+        Zend_Json::$useBuiltinEncoderDecoder = true;
+        $output = $form->render($view);
+
+        $this->assertEquals(
+            array('$("#Lastname").autocomplete({"source":["John Doe"]});'),
+            $view->jQuery()->getOnLoadActions()
+        );
+
+        Zend_Json::$useBuiltinEncoderDecoder = false;
+        $output = $form->render($view);
+        $this->assertEquals(
+            array('$("#Lastname").autocomplete({"source":["John Doe"]});'),
+            $view->jQuery()->getOnLoadActions()
+        );
+    }
+
+    /**
+     * @group ZF-5043
+     */
+    public function testFormWithoutIdButSubformsProducesArrayNotationWhichWontWork()
+    {
+        $view = new Zend_View();
+        $form = new ZendX_JQuery_Form();
+
+        $datePicker = new ZendX_JQuery_Form_Element_DatePicker("dp1");
+
+        $subform = new Zend_Form_SubForm();
+        $subform->addElement($datePicker);
+
+        $form->addSubForm($subform, "sf1");
+        $form->setIsArray(true);
+
+        $form   = $form->render($view);
+        $jquery = $view->jQuery()->__toString();
+        $this->assertContains('sf1[dp1]', $form);
+        $this->assertNotContains('$("#sf1[dp1]")', $jquery);
+    }
+    
+    /**
+     * @group ZF-6979
+     */
+    public function testDatePickerWithDescriptionDecorator()
+    {
+        $view = new Zend_View();
+
+        $datePicker = new ZendX_JQuery_Form_Element_DatePicker("dp1");
+        $datePicker->addDecorator(new Zend_Form_Decorator_Description());
+        $datePicker->setDescription("foo");
+
+        $html = $datePicker->render($view);
+
+        $this->assertContains('<p class="description">foo</p>', $html);
+    }
+
+    public function testGetDefaultDecorators()
+    {
+        $widget = new ZendX_JQuery_Form_Element_DatePicker("dp1");;
+        $decorators = $widget->getDecorators();
+        $this->assertEquals(5, count($decorators));
+
+        $this->assertType('ZendX_JQuery_Form_Decorator_UiWidgetElement', $decorators['ZendX_JQuery_Form_Decorator_UiWidgetElement']);
+        $this->assertType('Zend_Form_Decorator_Errors',                  $decorators['Zend_Form_Decorator_Errors']);
+        $this->assertType('Zend_Form_Decorator_Description',             $decorators['Zend_Form_Decorator_Description']);
+        $this->assertType('Zend_Form_Decorator_HtmlTag',                 $decorators['Zend_Form_Decorator_HtmlTag']);
+        $this->assertType('Zend_Form_Decorator_Label',                   $decorators['Zend_Form_Decorator_Label']);
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'ZendX_JQuery_Form_ElementTest::main') {
+    ZendX_JQuery_Form_ElementTest::main();
+}

+ 13 - 0
extras/tests/ZendX/JQuery/Form/_files/expected/uiwidgetcontainer/with_content.html

@@ -0,0 +1,13 @@
+<form id="mainForm" method="get" action=""><div id="tabContainer">
+<ul class="ui-tabs-nav">
+<li class="ui-tabs-nav-item"><a href="#tabContainer-frag-1"><span>Slider</span></a></li>
+</ul>
+<div id="tabContainer-frag-1" class="ui-tabs-panel"><dl>
+<dt id="spinner-label"><label for="spinner" class="optional">Spinner:</label></dt>
+<dd>
+<input type="text" name="spinner" id="spinner" value="" class="flora"></dd></dl></div>
+</div>
+<dl>
+
+<dt id="submit-label">&#160;</dt><dd id="submit-element">
+<input type="submit" name="submit" id="submit" value="Send"></dd></dl></form>

+ 138 - 0
extras/tests/ZendX/JQuery/JQueryTest.php

@@ -0,0 +1,138 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once dirname(__FILE__)."/../../TestHelper.php";
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'ZendX_JQuery_View_DatePickerTest::main');
+}
+
+require_once "Zend/Registry.php";
+require_once "Zend/View.php";
+require_once "Zend/Form.php";
+require_once "ZendX/JQuery.php";
+require_once "ZendX/JQuery/Form.php";
+require_once "Zend/Form/Element.php";
+require_once "ZendX/JQuery/Form/Element/Spinner.php";
+
+class ZendX_JQuery_JQueryTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Runs the test methods of this class.
+     *
+     * @return void
+     */
+    public static function main()
+    {
+        $suite  = new PHPUnit_Framework_TestSuite("ZendX_JQuery_JQueryTest");
+        $result = PHPUnit_TextUI_TestRunner::run($suite);
+    }
+
+    public function testShouldAllowEnableView()
+    {
+        $view = new Zend_View();
+        ZendX_JQuery::enableView($view);
+
+        $this->assertTrue( false !== ($view->getPluginLoader('helper')->getPaths('ZendX_JQuery_View_Helper')) );
+    }
+
+    public function testShouldAllowEnableForm()
+    {
+        $form = new Zend_Form();
+
+        $this->assertFalse( false !== ($form->getPluginLoader('element')->getPaths('ZendX_JQuery_Form_Element')) );
+        $this->assertFalse( false !== ($form->getPluginLoader('decorator')->getPaths('ZendX_JQuery_Form_Decorator')) );
+
+        ZendX_JQuery::enableForm($form);
+
+        $this->assertTrue( false !== ($form->getPluginLoader('element')->getPaths('ZendX_JQuery_Form_Element')) );
+        $this->assertTrue( false !== ($form->getPluginLoader('decorator')->getPaths('ZendX_JQuery_Form_Decorator')) );
+    }
+
+    public function testFormShouldEnableView()
+    {
+        $form = new Zend_Form();
+        $view = new Zend_View();
+        $form->setView($view);
+
+        $this->assertFalse( false !== ($form->getView()->getPluginLoader('helper')->getPaths('ZendX_JQuery_View_Helper')) );
+
+        ZendX_JQuery::enableForm($form);
+
+        $this->assertTrue( false !== ($form->getView()->getPluginLoader('helper')->getPaths('ZendX_JQuery_View_Helper')) );
+    }
+
+    public function testFormEnableShouldIncludeSubforms()
+    {
+        $form = new Zend_Form();
+        $subform = new Zend_Form();
+        $form->addSubForm($subform, "subform1");
+
+        $this->assertFalse( false !== ($form->getPluginLoader('element')->getPaths('ZendX_JQuery_Form_Element')) );
+        $this->assertFalse( false !== ($form->getPluginLoader('decorator')->getPaths('ZendX_JQuery_Form_Decorator')) );
+
+        ZendX_JQuery::enableForm($form);
+
+        $this->assertTrue( false !== ($form->getPluginLoader('element')->getPaths('ZendX_JQuery_Form_Element')) );
+        $this->assertTrue( false !== ($form->getPluginLoader('decorator')->getPaths('ZendX_JQuery_Form_Decorator')) );
+    }
+
+    public function testFormEnableShouldIncludeElementsOnRender()
+    {
+        $view = new Zend_View();
+        $form = new Zend_Form();
+        $element = new ZendX_JQuery_Form_Element_Spinner("spinner1");
+        $form->setView($view);
+        $form->addElement($element);
+
+        ZendX_JQuery::enableForm($form);
+
+        $this->assertFalse($form->getElement('spinner1')->getView() instanceof Zend_View);
+
+        $form->render();
+        $this->assertTrue($form->getElement('spinner1')->getView() instanceof Zend_View);
+        $this->assertTrue( false !== ($form->getElement('spinner1')->getView()->getPluginLoader('helper')->getPaths('ZendX_JQuery_View_Helper')) );
+    }
+
+    public function testJQueryFormShouldHaveHelperPath()
+    {
+        $form = new ZendX_JQuery_Form();
+        $this->assertTrue( false !== ($form->getPluginLoader('element')->getPaths('ZendX_JQuery_Form_Element')) );
+        $this->assertTrue( false !== ($form->getPluginLoader('decorator')->getPaths('ZendX_JQuery_Form_Decorator')) );
+    }
+
+    public function testJQueryFormShouldAutomaticallyEnableView()
+    {
+        $form = new ZendX_JQuery_Form();
+
+        $view = new Zend_View();
+        $this->assertFalse( false !== ($view->getPluginLoader('helper')->getPaths('ZendX_JQuery_View_Helper')) );
+
+        $form->setView($view);
+
+        $this->assertTrue( false !== ($form->getView()->getPluginLoader('helper')->getPaths('ZendX_JQuery_View_Helper')) );
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'ZendX_JQuery_JQueryTest::main') {
+    ZendX_JQuery_JQUeryTest::main();
+}

+ 184 - 0
extras/tests/ZendX/JQuery/View/AccordionContainerTest.php

@@ -0,0 +1,184 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once "jQueryTestCase.php";
+require_once "ZendX/JQuery/View/Helper/AccordionContainer.php";
+
+class ZendX_JQuery_View_AccordionContainerTest extends ZendX_JQuery_View_jQueryTestCase
+{
+    public function testCallingInViewEnablesJQueryHelper()
+    {
+        $element = $this->view->accordionContainer();
+
+        $this->assertTrue($this->jquery->isEnabled());
+        $this->assertTrue($this->jquery->uiIsEnabled());
+        $this->assertTrue($element instanceof ZendX_JQuery_View_Helper_AccordionContainer);
+    }
+
+    public function testShouldAppendToJqueryHelper()
+    {
+        $this->view->accordionContainer()->addPane("elem1", "test1", "test1");
+        $element = $this->view->accordionContainer("elem1", array('option' => 'true'), array());
+
+        $jquery = $this->view->jQuery()->__toString();
+        $this->assertContains('accordion(', $jquery);
+        $this->assertContains('"option":"true"', $jquery);
+    }
+
+    public function testShouldReturnEmptyStringIfEmpty()
+    {
+        $accordion = $this->view->accordionContainer("empty", array(), array());
+
+        $this->assertEquals('', $accordion);
+    }
+
+    public function testShouldAllowAddingTabs()
+    {
+        $accordion = $this->view->accordionContainer()->addPane("container1", "elem1", "Text1")
+                        ->addPane("container1", "elem2", "Text2")
+                        ->accordionContainer("container1", array(), array());
+
+        $this->assertEquals(array('$("#container1").accordion({});'), $this->jquery->getOnLoadActions());
+        $this->assertContains("elem1", $accordion);
+        $this->assertContains("Text1", $accordion);
+        $this->assertContains("elem2", $accordion);
+        $this->assertContains("Text2", $accordion);
+    }
+
+    public function testShouldAllowAddingMultipleTabs()
+    {
+        $this->view->accordionContainer()->addPane("container1", "elem1", "Text1")
+             ->addPane("container2", "elem2", "Text2");
+
+        $accordion = $this->view->accordionContainer("container1", array(), array());
+        $accordion2 = $this->view->accordionContainer("container2", array(), array());
+
+        $this->assertEquals(array('$("#container1").accordion({});', '$("#container2").accordion({});'), $this->jquery->getOnLoadActions());
+        $this->assertNotContains("elem1", $accordion2);
+        $this->assertNotContains("Text1", $accordion2);
+        $this->assertContains("elem1", $accordion);
+        $this->assertContains("Text1", $accordion);
+        $this->assertNotContains("elem2", $accordion);
+        $this->assertNotContains("Text2", $accordion);
+        $this->assertContains("elem2", $accordion2);
+        $this->assertContains("Text2", $accordion2);
+    }
+
+    public function testShouldAllowCaptureTabContent()
+    {
+        $this->view->accordionPane()->captureStart("container1", "elem1");
+        echo "Lorem Ipsum!";
+        $this->view->accordionPane()->captureEnd("container1");
+
+        $this->view->accordionPane()->captureStart("container1", "elem2", array('contentUrl' => 'foo.html'));
+        echo "This is captured and displayed: contentUrl does not exist for Accordion.";
+        $this->view->accordionPane()->captureEnd("container1");
+
+        $accordion = $this->view->accordionContainer("container1", array(), array());
+
+        $this->assertEquals(array('$("#container1").accordion({});'), $this->jquery->getOnLoadActions());
+        $this->assertContains('elem1', $accordion);
+        $this->assertContains('elem2', $accordion);
+        $this->assertContains('Lorem Ipsum!', $accordion);
+        $this->assertNotContains('href="foo.html"', $accordion);
+        $this->assertContains('This is captured and displayed: contentUrl does not exist for Accordion.', $accordion);
+    }
+
+    public function testShouldAllowUsingTabPane()
+    {
+        $this->view->accordionPane("container1", "Lorem Ipsum!", array('title' => 'elem1'));
+        $this->view->accordionPane("container1", 'This is captured and displayed: contentUrl does not exist for Accordion.', array('title' => 'elem2', 'contentUrl' => 'foo.html'));
+        $accordion = $this->view->accordionContainer("container1", array(), array());
+
+        $this->assertEquals(array('$("#container1").accordion({});'), $this->jquery->getOnLoadActions());
+        $this->assertContains('elem1', $accordion);
+        $this->assertContains('elem2', $accordion);
+        $this->assertContains('Lorem Ipsum!', $accordion);
+        $this->assertNotContains('href="foo.html"', $accordion);
+        $this->assertContains('This is captured and displayed: contentUrl does not exist for Accordion.', $accordion);
+    }
+
+    /**
+     * @group ZF-6321
+     */
+    public function testAccordingHtmlRenderingWithUi15()
+    {
+        $this->view->jQuery()->setUiVersion("1.5.3");
+
+        $this->view->accordionPane("container1", "foo", array('title' => 'foo'));
+        $this->view->accordionPane("container1", 'bar', array('title' => 'bar'));
+        $accordion = $this->view->accordionContainer("container1", array(), array());
+
+        $this->assertEquals(
+            '<ul id="container1">
+<li class="ui-accordion-group"><a href="#" class="ui-accordion-header">foo</a><div class="ui-accordion-content">foo</div></li>
+<li class="ui-accordion-group"><a href="#" class="ui-accordion-header">bar</a><div class="ui-accordion-content">bar</div></li>
+</ul>
+',
+            $accordion
+        );
+    }
+
+    /**
+     * @group ZF-6321
+     */
+    public function testAccordingHtmlRenderingWithUi17()
+    {
+        $this->view->jQuery()->setUiVersion("1.7.0");
+
+        $this->view->accordionPane("container1", "foo", array('title' => 'foo'));
+        $this->view->accordionPane("container1", 'bar', array('title' => 'bar'));
+        $accordion = $this->view->accordionContainer("container1", array(), array());
+
+        $this->assertEquals(
+            '<div id="container1">
+<h3><a href="#">foo</a></h3><div>foo</div>
+<h3><a href="#">bar</a></h3><div>bar</div>
+</div>
+',
+            $accordion
+        );
+    }
+
+    public function testAccordionSetWrongHtmlTemplate_ThrowsException()
+    {
+        $this->setExpectedException("ZendX_JQuery_View_Exception");
+
+        $this->view->getHelper('accordionContainer')->setElementHtmlTemplate("foo");
+    }
+
+    public function testAccordionSetHtmlTemplate()
+    {
+        $this->view->getHelper('accordionContainer')->setElementHtmlTemplate("<h3>%s</h3><p>%s</p>");
+
+        $this->view->accordionPane("container1", "foo", array('title' => 'foo'));
+        $accordion = $this->view->accordionContainer("container1", array(), array());
+
+        $this->assertEquals(
+            '<div id="container1">
+<h3>foo</h3><p>foo</p>
+</div>
+',
+            $accordion
+        );
+    }
+}

+ 247 - 0
extras/tests/ZendX/JQuery/View/AjaxLinkTest.php

@@ -0,0 +1,247 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once "jQueryTestCase.php";
+
+require_once "ZendX/JQuery/View/Helper/AjaxLink.php";
+
+class ZendX_JQuery_View_AjaxLinkTest extends ZendX_JQuery_View_jQueryTestCase
+{
+
+    public function testShouldBeCallable() {
+        $link = $this->view->ajaxLink("Link to Inject", "inject.html");
+        $this->assertContains('Link to Inject', $link);
+        $this->assertContains('class="ajaxLink', $link);
+        $this->assertNotContains('inject.html', $link);
+        $this->assertNotContains('$.get', $link);
+
+        $render = $this->jquery->__toString();
+        $this->assertContains('inject.html', $render);
+        $this->assertContains('$.get', $render);
+    }
+
+    public function testShouldBeCallableInline() {
+        $link = $this->view->ajaxLink("Link to Inject", "inject.html", array('inline' => true));
+        $this->assertContains('Link to Inject', $link);
+        $this->assertNotContains('class="ajaxLink', $link);
+        $this->assertContains('inject.html', $link);
+        $this->assertContains('$.get', $link);
+
+        $render = $this->jquery->__toString();
+        $this->assertNotContains('inject.html', $render);
+        $this->assertNotContains('$.get', $render);
+    }
+
+    public function testShouldAllowSendingParamsWithPost() {
+        $link = $this->view->ajaxLink("Link to Inject2", "inject.php", array('update' => '#test', 'class' => 'someClass'), array('key' => 'value'));
+        $this->assertContains('Link to Inject2', $link);
+        $this->assertContains('class="someClass ajaxLink', $link);
+        $this->assertNotContains('inject.php', $link);
+
+        $render = $this->jquery->__toString();
+        $this->assertContains('inject.php', $render);
+        $this->assertContains('$.post', $render);
+        $this->assertContains('#test', $render);
+        $this->assertContains('{"key":"value"}', $render);
+    }
+
+    public function testShouldAllowSendingParamsWithGet() {
+        $link = $this->view->ajaxLink("Link to Inject3", "inject123.php", array('method' => 'get', 'update' => '#test'), array('key' => 'value'));
+        $this->assertContains('Link to Inject3', $link);
+        $this->assertContains('class="ajaxLink', $link);
+        $this->assertNotContains('inject123.php', $link);
+
+        $render = $this->jquery->__toString();
+        $this->assertContains('inject123.php', $render);
+        $this->assertContains('$.get', $render);
+        $this->assertContains('#test', $render);
+        $this->assertContains('{"key":"value"}', $render);
+    }
+
+    public function testShouldAllowSpecifyingDataType() {
+        $link = $this->view->ajaxLink("JSON Response with Callback", "inject.php", array('complete' => 'jsonCallback(data);', 'dataType' => 'json'), array('name' => 'Ludwig von Mises', 'email' => 'mises@vienna.at'));
+        $this->assertContains('JSON Response with Callback', $link);
+        $this->assertContains('class="ajaxLink', $link);
+        $this->assertNotContains('inject.php', $link);
+        $this->assertNotContains('{"name":"Ludwig von Mises","email":"mises@vienna.at"}', $link);
+
+        $render = $this->jquery->__toString();
+        $this->assertContains('inject.php', $render);
+        $this->assertContains('function(data, textStatus) { jsonCallback(data); }', $render);
+        $this->assertContains('"json");', $render);
+        $this->assertContains('{"name":"Ludwig von Mises","email":"mises@vienna.at"}', $render);
+    }
+
+    public function testShouldWorkInNoConflictMode() {
+        ZendX_JQuery_View_Helper_JQuery::enableNoConflictMode();
+        $link = $this->view->ajaxLink("Link to Inject", "inject.html", array('update' => '#test', 'inline' => true, 'beforeSend' => 'hide'));
+
+        $this->assertContains('$j.get', $link);
+        $this->assertContains('$j("#test")', $link);
+        $this->assertContains('$j(this).hide', $link);
+    }
+
+    public function testShouldAllowSwitchUpdateDataFunc() {
+        $link = $this->view->ajaxLink("Link to Inject", "inject.html", array('update' => '#test', 'inline' => true, 'dataType' => 'text'));
+        $this->assertContains('("#test").text(data);', $link);
+    }
+
+    static public function dataBeforeSendEffects()
+    {
+        return array(
+            array('hide', 'hide();'),
+            array('hideslow', 'hide("slow");'),
+            array('hidefast', 'hide("fast");'),
+            array('fadeout', 'fadeOut();'),
+            array('fadeoutslow', 'fadeOut("slow");'),
+            array('fadeoutfast', 'fadeOut("fast");'),
+            array('slideup', 'slideUp(1000);'),
+        );
+    }
+
+    /**
+     * @dataProvider dataBeforeSendEffects
+     * @param string $effect
+     * @param string $js
+     */
+    public function testShouldAllowUsingBeforeSendEffects($effect, $js)
+    {
+        $link = $this->view->ajaxLink("Link to Inject", "inject.html", array('update' => '#test', 'inline' => true, 'beforeSend' => $effect));
+        $this->assertContains(sprintf('$(this).%s', $js), $link);
+
+        ZendX_JQuery_View_Helper_JQuery::enableNoConflictMode();
+
+        $link = $this->view->ajaxLink("Link to Inject", "inject.html", array('update' => '#test', 'inline' => true, 'beforeSend' => $effect));
+        $this->assertContains(sprintf('$j(this).%s', $js), $link);
+    }
+
+    static public function dataCompleteEffects()
+    {
+        return array(
+            array('show', 'show();'),
+            array('showslow', 'show("slow");'),
+            array('showfast', 'show("fast");'),
+            array('shownormal', 'show("normal");'),
+            array('fadein', 'fadeIn("normal");'),
+            array('fadeinslow', 'fadeIn("slow");'),
+            array('fadeinfast', 'fadeIn("fast");'),
+            array('slidedown', 'slideDown("normal");'),
+            array('slidedownslow', 'slideDown("slow");'),
+            array('slidedownfast', 'slideDown("fast");'),
+        );
+    }
+
+    /**
+     * @dataProvider dataCompleteEffects
+     * @param <type> $effect
+     * @param <type> $js
+     */
+    public function testShouldAllowUsingCompleteEffects($effect, $js)
+    {
+        $link = $this->view->ajaxLink("Link to Inject", "inject.html", array('update' => '#test', 'inline' => true, 'complete' => $effect));
+        $this->assertContains(sprintf('$("#test").%s', $js), $link);
+
+        ZendX_JQuery_View_Helper_JQuery::enableNoConflictMode();
+
+        $link = $this->view->ajaxLink("Link to Inject", "inject.html", array('update' => '#test', 'inline' => true, 'complete' => $effect));
+        $this->assertContains(sprintf('$j("#test").%s', $js), $link);
+    }
+
+    public function testOptionsArrayAllowsForSettingAttributes() {
+        $view = $this->getView();
+
+        $html = $view->ajaxLink("Label1", "/some/url", array(
+            'id' => 'ajaxLink1',
+            'title' => 'Label1',
+            'noscript' => true,
+            'attribs' => array('class' => 'test', 'target' => '_blank')
+        ));
+
+        $this->assertContains('id="ajaxLink1"', $html);
+        $this->assertContains('title="Label1"', $html);
+        $this->assertContains('href="/some/url"', $html);
+        $this->assertNotContains('href="#"', $html);
+        $this->assertContains('class="test"', $html);
+        $this->assertContains('target="_blank"', $html);
+    }
+
+    public function testSpecifyingIdDoesNotCreateAutomaticCallbackAndClassAttribute() {
+        $view = $this->getView();
+
+        $html = $view->ajaxLink("Label1", "/some/url", array(
+            'id' => "someId"
+        ));
+
+        $this->assertNotContains('class=', $html);
+        $this->assertContains('id="someId"', $html);
+    }
+
+    /**
+     * @group ZF-5041
+     */
+    public function testXhtmlDoctypeDoesNotMakeAnchorInvalidHtml() {
+        $view = $this->getView();
+        $view->doctype('XHTML1_STRICT');
+
+        $html = $view->ajaxLink("Label1", "/some/url", array('id' => "someId"));
+
+        $this->assertNotContains("/>Label1</a>", $html);
+        $this->assertContains(">Label1</a>", $html);
+   }
+
+   /** @group ZF-9926 */
+   public function testDoNotUseSingleQuotesInJsAsItBreaksInlineLinks()
+   {
+       $view = $this->getView();
+
+       $html = $view->ajaxLink('Label1', '/some/url', array(
+           'method'     => 'post',
+           'dataType'   => 'json',
+           'noscript'   => true,
+           'beforeSend' => 'if(!confirm("Are you sure?")) {return false;}$("#progress-bar").show();',
+           'complete'   => '$("#progress-bar").hide();',
+           'inline'     => true
+       ));
+
+       $this->assertContains('$.post("/some/url"', $html);
+       $this->assertNotContains("'/some/url'", $html);
+       $this->assertNotContains("'json'", $html);
+   }
+   /** @group ZF-9926 */
+   public function testSingleQuotesAreEscapedInJsInlineLinks()
+   {
+       $view = $this->getView();
+
+       $html = $view->ajaxLink('Label1', '/some/url', array(
+           'method'     => 'post',
+           'dataType'   => 'json',
+           'noscript'   => true,
+           'beforeSend' => "if(!confirm('Are you sure?')) {return false;}$('#progress-bar').show();",
+           'complete'   => '$("#progress-bar").hide();',
+           'inline'     => true
+       ));
+
+       $this->assertContains('&#39;Are you sure?&#39;', $html);
+       $this->assertContains('&#39;#progress-bar&#39;', $html);
+       $this->assertContains('"#progress-bar"', $html);
+   }
+}

+ 73 - 0
extras/tests/ZendX/JQuery/View/AllTests.php

@@ -0,0 +1,73 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once dirname(__FILE__)."/../../../TestHelper.php";
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'ZendX_JQuery_View_AllTests::main');
+}
+
+require_once "Zend/Registry.php";
+require_once "Zend/View.php";
+require_once "ZendX/JQuery.php";
+require_once "ZendX/JQuery/View/Helper/JQuery.php";
+
+require_once "AccordionContainerTest.php";
+require_once "AjaxLinkTest.php";
+require_once "AutoCompleteTest.php";
+require_once "ColorPickerTest.php";
+require_once "DatePickerTest.php";
+require_once "DialogContainerTest.php";
+require_once "jQueryTest.php";
+require_once "SliderTest.php";
+require_once "SpinnerTest.php";
+require_once "TabContainerTest.php";
+
+class ZendX_JQuery_View_AllTests
+{
+    public static function main()
+    {
+        PHPUnit_TextUI_TestRunner::run(self::suite());
+    }
+
+    public static function suite()
+    {
+        $suite = new PHPUnit_Framework_TestSuite('Zend Framework - ZendX_JQuery - View Helpers');
+
+        $suite->addTestSuite('ZendX_JQuery_View_jQueryTest');
+        $suite->addTestSuite('ZendX_JQuery_View_AccordionContainerTest');
+        $suite->addTestSuite('ZendX_JQuery_View_AjaxLinkTest');
+        $suite->addTestSuite('ZendX_JQuery_View_AutoCompleteTest');
+        $suite->addTestSuite('ZendX_JQuery_View_ColorPickerTest');
+        $suite->addTestSuite('ZendX_JQuery_View_DatePickerTest');
+        $suite->addTestSuite('ZendX_JQuery_View_DialogContainerTest');
+        $suite->addTestSuite('ZendX_JQuery_View_SliderTest');
+        $suite->addTestSuite('ZendX_JQuery_View_SpinnerTest');
+        $suite->addTestSuite('ZendX_JQuery_View_TabContainerTest');
+
+        return $suite;
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'ZendX_JQuery_View_AllTests::main') {
+    ZendX_JQuery_View_AllTests::main();
+}

+ 63 - 0
extras/tests/ZendX/JQuery/View/AutoCompleteTest.php

@@ -0,0 +1,63 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once "jQueryTestCase.php";
+
+require_once "ZendX/JQuery/View/Helper/AutoComplete.php";
+
+class ZendX_JQuery_View_AutoCompleteTest extends ZendX_JQuery_View_jQueryTestCase
+{
+    public function testCallingInViewEnablesJQueryHelper()
+    {
+        $element = $this->view->autoComplete("element", "", array('data' => array('test')));
+
+        $this->assertTrue($this->jquery->isEnabled());
+        $this->assertTrue($this->jquery->uiIsEnabled());
+    }
+
+    public function testShouldAppendToJqueryHelper()
+    {
+        $element = $this->view->autoComplete("elem1", "Default", array('option' => 'true', 'data' => array('test')), array());
+
+        $jquery = $this->view->jQuery()->__toString();
+        $this->assertContains('autocomplete(', $jquery);
+        $this->assertContains('"option":"true"', $jquery);
+    }
+
+    /**
+     * @expectedException ZendX_JQuery_Exception
+     */
+    public function testShouldAllowAutoCompleteOnlyWithSourceOption()
+    {
+        $element = $this->view->autoComplete("elem1");
+    }
+
+    public function testShouldCreateInputField()
+    {
+        $element = $this->view->autoComplete("elem1", "Default", array('source' => array('Test')));
+
+        $this->assertEquals(array('$("#elem1").autocomplete({"source":["Test"]});'), $this->view->jQuery()->getOnLoadActions());
+        $this->assertContains("<input", $element);
+        $this->assertContains('id="elem1"', $element);
+        $this->assertContains('value="Default"', $element);
+    }
+}

+ 63 - 0
extras/tests/ZendX/JQuery/View/ColorPickerTest.php

@@ -0,0 +1,63 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once "jQueryTestCase.php";
+
+require_once "ZendX/JQuery/View/Helper/ColorPicker.php";
+
+class ZendX_JQuery_View_ColorPickerTest extends ZendX_JQuery_View_jQueryTestCase
+{
+    public function testCallingInViewEnablesJQueryHelper()
+    {
+        $element = $this->view->colorPicker("element", "");
+
+        $this->assertTrue($this->jquery->isEnabled());
+        $this->assertTrue($this->jquery->uiIsEnabled());
+    }
+
+    public function testShouldAppendToJqueryHelper()
+    {
+        $element = $this->view->colorPicker("elem1", "Default", array('option' => 'true'));
+
+        $jquery = $this->view->jQuery()->__toString();
+        $this->assertContains('colorpicker(', $jquery);
+        $this->assertContains('"option":"true"', $jquery);
+    }
+
+    public function testShouldCreateInputField()
+    {
+        $element = $this->view->colorPicker("elem1");
+
+        $this->assertEquals(array('$("#elem1").colorpicker({});'), $this->view->jQuery()->getOnLoadActions());
+        $this->assertContains('<input', $element);
+        $this->assertContains('id="elem1"', $element);
+    }
+
+    public function testShouldDoSomeSemiChecksIfValueCanBeAppliedToColorOption()
+    {
+        $element = $this->view->colorPicker("elem1", "abc");
+        $this->assertEquals(array('$("#elem1").colorpicker({});'), $this->view->jQuery()->getOnLoadActions());
+
+        $element = $this->view->colorPicker("elem1", "#FFFFFF");
+        $this->assertEquals(array('$("#elem1").colorpicker({});', '$("#elem1").colorpicker({"color":"#FFFFFF"});'), $this->view->jQuery()->getOnLoadActions());
+    }
+}

+ 103 - 0
extras/tests/ZendX/JQuery/View/DatePickerTest.php

@@ -0,0 +1,103 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once "jQueryTestCase.php";
+
+require_once "Zend/Locale.php";
+require_once "ZendX/JQuery/View/Helper/DatePicker.php";
+
+class ZendX_JQuery_View_DatePickerTest extends ZendX_JQuery_View_jQueryTestCase
+{
+    public function testCallingInViewEnablesJQueryHelper()
+    {
+        $element = $this->view->datePicker("element", "");
+
+        $this->assertTrue($this->jquery->isEnabled());
+        $this->assertTrue($this->jquery->uiIsEnabled());
+    }
+
+    public function testShouldAppendToJqueryHelper()
+    {
+        $element = $this->view->datePicker("elem1", "", array("option" => "true"));
+
+        $jquery = $this->view->jQuery()->__toString();
+        $this->assertContains('datepicker(', $jquery);
+        $this->assertContains('"option":"true"', $jquery);
+    }
+
+    public function testShouldCreateInputField()
+    {
+        $element = $this->view->datePicker("elem1", "01.01.2007");
+
+        $this->assertEquals(array('$("#elem1").datepicker({});'), $this->view->jQuery()->getOnLoadActions());
+        $this->assertContains("<input", $element);
+        $this->assertContains('id="elem1"', $element);
+        $this->assertContains('value="01.01.2007"', $element);
+    }
+
+    public function testDatePickerSupportsLocaleDe()
+    {
+        $view = $this->getView();
+        $locale = new Zend_Locale('de');
+        Zend_Registry::set('Zend_Locale', $locale);
+        $view->datePicker("dp1");
+
+        $this->assertEquals(array(
+            '$("#dp1").datepicker({"dateFormat":"dd.mm.yy"});',
+        ), $view->jQuery()->getOnLoadActions());
+    }
+
+    public function testDatePickerSupportsLocaleEn()
+    {
+        $view = $this->getView();
+
+        $locale = new Zend_Locale('en');
+        Zend_Registry::set('Zend_Locale', $locale);
+        $view->datePicker("dp2");
+
+        $this->assertEquals(array(
+            '$("#dp2").datepicker({"dateFormat":"M d, yy"});',
+        ), $view->jQuery()->getOnLoadActions());
+    }
+
+    public function testDatePickerSupportsLocaleFr()
+    {
+        $view = $this->getView();
+
+        $locale = new Zend_Locale('fr');
+        Zend_Registry::set('Zend_Locale', $locale);
+        $view->datePicker("dp3");
+
+        $this->assertEquals(array(
+            '$("#dp3").datepicker({"dateFormat":"d M yy"});',
+        ), $view->jQuery()->getOnLoadActions());
+    }
+
+    /**
+     * @group ZF-5615
+     */
+    public function testDatePickerLocalization()
+    {
+        $dpFormat = ZendX_JQuery_View_Helper_DatePicker::resolveZendLocaleToDatePickerFormat("MMM d, yyyy");
+        $this->assertEquals("M d, yy", $dpFormat, "'MMM d, yyyy' has to be converted to 'M d, yy'.");
+    }
+}

+ 69 - 0
extras/tests/ZendX/JQuery/View/DialogContainerTest.php

@@ -0,0 +1,69 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once "jQueryTestCase.php";
+require_once "ZendX/JQuery/View/Helper/DialogContainer.php";
+
+class ZendX_JQuery_View_DialogContainerTest extends ZendX_JQuery_View_jQueryTestCase
+{
+    public function testCallingInViewEnablesJQueryHelper()
+    {
+        $element = $this->view->dialogContainer("element", "");
+
+        $this->assertTrue($this->jquery->isEnabled());
+        $this->assertTrue($this->jquery->uiIsEnabled());
+    }
+
+    public function testShouldAppendToJqueryHelper()
+    {
+        $element = $this->view->dialogContainer("elem1", "", array("option" => "true"));
+
+        $jquery = $this->jquery->__toString();
+        $this->assertContains('dialog(', $jquery);
+        $this->assertContains('"option":"true"', $jquery);
+    }
+
+    public function testShouldCreateDivContainer()
+    {
+        $element = $this->view->dialogContainer("elem1", "", array(), array());
+
+        $this->assertEquals(array('$("#elem1").dialog({});'), $this->jquery->getOnLoadActions());
+        $this->assertContains("<div", $element);
+        $this->assertContains('id="elem1"', $element);
+        $this->assertContains("</div>", $element);
+    }
+
+    /**
+     * @group ZF-4685
+     */
+    public function testUsingJsonExprForResizeShouldBeValidJsCallbackRegression()
+    {
+        $params = array(
+            "resize" => new Zend_Json_Expr("doMyThingAtResize"),
+        );
+
+        $this->view->dialogContainer("dialog1", "Some text", $params);
+
+        $actions = $this->jquery->getOnLoadActions();
+        $this->assertEquals(array('$("#dialog1").dialog({"resize":doMyThingAtResize});'), $actions);
+    }
+}

+ 90 - 0
extras/tests/ZendX/JQuery/View/SliderTest.php

@@ -0,0 +1,90 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once "jQueryTestCase.php";
+
+require_once "ZendX/JQuery/View/Helper/Slider.php";
+
+class ZendX_JQuery_View_SliderTest extends ZendX_JQuery_View_jQueryTestCase
+{
+    public function testCallingInViewEnablesJQueryHelper()
+    {
+        $element = $this->view->slider("element", "");
+
+        $this->assertTrue($this->jquery->isEnabled());
+        $this->assertTrue($this->jquery->uiIsEnabled());
+    }
+
+    public function testShouldAppendToJqueryHelper()
+    {
+        $element = $this->view->slider("elem1", "", array("option" => "true"));
+
+        $jquery = $this->view->jQuery()->__toString();
+        $this->assertContains('slider(', $jquery);
+        $this->assertContains('"option":"true"', $jquery);
+    }
+
+    public function testShouldBuiltSliderElementsWith15API()
+    {
+        $this->view->jQuery()->setUiVersion("1.5.2");
+        $element = $this->view->slider("elem1", "75", array(), array());
+
+        $this->assertEquals(
+            array(
+           		'$("#elem1-slider").slider({"handles":[{"start":"75"}],"change":function(e, ui) {
+    $("#elem1").attr("value", $("#elem1-slider").slider("value", 0));
+}
+});'
+            ), $this->jquery->getOnLoadActions());
+        $this->assertContains("<div", $element);
+        $this->assertContains('<div class="ui-slider-handle"></div>', $element);
+        $this->assertContains('<input', $element);
+        $this->assertContains('type="hidden"', $element);
+        $this->assertContains('id="elem1"', $element);
+        $this->assertContains('id="elem1-slider"', $element);
+    }
+
+    public function testShouldBuiltSliderElementsWith17API()
+    {
+        $this->view->jQuery()->setUiVersion("1.7.2");
+        $element = $this->view->slider("elem1", "75", array(), array());
+
+        $this->assertEquals(
+            array(
+           		'$("#elem1-slider").slider({"values":["75"],"change":function(e, ui) {
+    $("#elem1").attr("value", $("#elem1-slider").slider("values", 0));
+}
+});'
+            ), $this->jquery->getOnLoadActions());
+        $this->assertContains("<div", $element);
+        $this->assertContains('<div class="ui-slider-handle"></div>', $element);
+        $this->assertContains('<input', $element);
+        $this->assertContains('type="hidden"', $element);
+        $this->assertContains('id="elem1"', $element);
+        $this->assertContains('id="elem1-slider"', $element);
+    }
+
+    public function testShouldAllowMultipleSliders()
+    {
+        $element = $this->view->slider("elem1", "0", array('sliderCount' => 3), array());
+    }
+}

+ 59 - 0
extras/tests/ZendX/JQuery/View/SpinnerTest.php

@@ -0,0 +1,59 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once "jQueryTestCase.php";
+require_once "ZendX/JQuery/View/Helper/Spinner.php";
+
+class ZendX_JQuery_View_SpinnerTest extends ZendX_JQuery_View_jQueryTestCase
+{
+    public function testCallingInViewEnablesJQueryHelper()
+    {
+        $element = $this->view->spinner("element", "");
+
+        $this->assertTrue($this->jquery->isEnabled());
+        $this->assertTrue($this->jquery->uiIsEnabled());
+    }
+
+    public function testShouldAppendToJqueryHelper()
+    {
+        $element = $this->view->spinner("elem1", "", array("option" => "true"));
+
+        $jquery = $this->view->jQuery()->__toString();
+        $this->assertContains('spinner(', $jquery);
+        $this->assertContains('"option":"true"', $jquery);
+    }
+
+    public function testShouldCreateInputElement()
+    {
+        $element = $this->view->spinner("elem1");
+
+        $this->assertEquals(array('$("#elem1").spinner({});'), $this->jquery->getOnLoadActions());
+        $this->assertContains('<input', $element);
+        $this->assertContains('id="elem1"', $element);
+    }
+
+    public function testNumericValueShouldBecomeStartOptionParameterIfNoneGiven()
+    {
+        $element = $this->view->spinner("elem1", "100");
+        $this->assertEquals(array('$("#elem1").spinner({"start":"100"});'), $this->jquery->getOnLoadActions());
+    }
+}

+ 129 - 0
extras/tests/ZendX/JQuery/View/TabContainerTest.php

@@ -0,0 +1,129 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category    ZendX
+ * @package     ZendX_JQuery
+ * @subpackage  View
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license     http://framework.zend.com/license/new-bsd     New BSD License
+ * @version     $Id$
+ */
+
+require_once "jQueryTestCase.php";
+require_once "ZendX/JQuery/View/Helper/TabContainer.php";
+
+class ZendX_JQuery_View_TabContainerTest extends ZendX_JQuery_View_jQueryTestCase
+{
+    public function testCallingInViewEnablesJQueryHelper()
+    {
+        $element = $this->view->tabContainer();
+
+        $this->assertTrue($this->jquery->isEnabled());
+        $this->assertTrue($this->jquery->uiIsEnabled());
+    }
+
+    public function testShouldAppendToJqueryHelper()
+    {
+        $this->view->tabContainer()->addPane("elem1", "test1", "test1");
+        $element = $this->view->tabContainer("elem1", array('option' => 'true'), array());
+
+        $jquery = $this->view->jQuery()->__toString();
+        $this->assertContains('tabs(', $jquery);
+        $this->assertContains('"option":"true"', $jquery);
+    }
+
+    public function testShouldAllowAddingTabs()
+    {
+        $tabs = $this->view->tabContainer()->addPane("container1", "elem1", "Text1")
+                        ->addPane("container1", "elem2", "Text2")
+                        ->tabContainer("container1", array(), array());
+
+        $this->assertEquals(array('$("#container1").tabs({});'), $this->jquery->getOnLoadActions());
+        $this->assertContains("elem1", $tabs);
+        $this->assertContains("Text1", $tabs);
+        $this->assertContains("elem2", $tabs);
+        $this->assertContains("Text2", $tabs);
+        $this->assertContains('href="#container1-frag-1"', $tabs);
+        $this->assertContains('href="#container1-frag-2"', $tabs);
+    }
+
+    public function testShoudAllowAddingTabsFromUrls()
+    {
+        $tabs = $this->view->tabContainer()->addPane("container1", "elem1", '', array('contentUrl' => 'blub.html'))
+                        ->addPane("container1", "elem2", '', array('contentUrl' => 'cookie.html'))
+                        ->tabContainer("container1", array(), array());
+
+        $this->assertEquals(array('$("#container1").tabs({});'), $this->jquery->getOnLoadActions());
+        $this->assertContains("elem1", $tabs);
+        $this->assertContains("elem2", $tabs);
+        $this->assertContains('href="blub.html"', $tabs);
+        $this->assertContains('href="cookie.html"', $tabs);
+    }
+
+    public function testShouldAllowCaptureTabContent()
+    {
+        $this->view->tabPane()->captureStart("container1", "elem1");
+        echo "Lorem Ipsum!";
+        $this->view->tabPane()->captureEnd("container1");
+
+        $this->view->tabPane()->captureStart("container1", "elem2", array('contentUrl' => 'foo.html'));
+        echo "This is captured, but not displayed: contentUrl overrides this output.";
+        $this->view->tabPane()->captureEnd("container1");
+
+        $tabs = $this->view->tabContainer("container1", array(), array());
+
+        $this->assertEquals(array('$("#container1").tabs({});'), $this->jquery->getOnLoadActions());
+        $this->assertContains('elem1', $tabs);
+        $this->assertContains('elem2', $tabs);
+        $this->assertContains('Lorem Ipsum!', $tabs);
+        $this->assertContains('href="foo.html"', $tabs);
+        $this->assertNotContains('This is captured, but not displayed: contentUrl overrides this output.', $tabs);
+    }
+
+    public function testShouldAllowUsingTabPane()
+    {
+        $this->view->tabPane("container1", "Lorem Ipsum!", array('title' => 'elem1'));
+        $this->view->tabPane("container1", '', array('title' => 'elem2', 'contentUrl' => 'foo.html'));
+
+        $tabs = $this->view->tabContainer("container1", array(), array());
+
+        $this->assertEquals(array('$("#container1").tabs({});'), $this->jquery->getOnLoadActions());
+        $this->assertContains('elem1', $tabs);
+        $this->assertContains('elem2', $tabs);
+        $this->assertContains('Lorem Ipsum!', $tabs);
+        $this->assertContains('href="foo.html"', $tabs);
+        $this->assertNotContains('This is captured, but not displayed: contentUrl overrides this output.', $tabs);
+    }
+
+    public function testPaneCaptureLockExceptionNoNestingAllowed()
+    {
+        $this->view->tabPane()->captureStart('pane1', 'Label1');
+        try {
+            $this->view->tabPane()->captureStart('pane1', 'Label1');
+            $this->fail();
+        } catch(ZendX_JQuery_View_Exception $e) {
+
+        }
+    }
+
+    public function testPaneCaptureLockExceptionNoEndWithoutStartPossible()
+    {
+        try {
+            $this->view->tabPane()->captureEnd('pane3');
+            $this->fail();
+        } catch(ZendX_JQuery_View_Exception $e) {
+
+        }
+    }
+}

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff