- <modulename>
+
- configs/
+
- application.ini
+
- controllers/
+
- helpers/
+
- forms/
+
- layouts/
+
- filters/
+
- helpers/
+
- scripts/
+
- models/
+
- services/
+
- views/
+
- filters/
+
- helpers/
+
- scripts/
+
- Bootstrap.php
From 06f945f27840b53e57795dadbc38e76f7e11ab1c Mon Sep 17 00:00:00 2001 From: Horus3 Date: Mon, 24 Feb 2014 16:42:14 +0100 Subject: init --- .../core/en/coding-standard.coding-style.html | 843 ++ .../manual/core/en/coding-standard.html | 119 + .../en/coding-standard.naming-conventions.html | 371 + .../manual/core/en/coding-standard.overview.html | 155 + .../en/coding-standard.php-file-formatting.html | 152 + zend/documentation/manual/core/en/copyrights.html | 114 + .../core/en/doc-standard.file-formatting.html | 599 ++ .../documentation/manual/core/en/doc-standard.html | 116 + .../manual/core/en/doc-standard.overview.html | 125 + .../core/en/doc-standard.recommendations.html | 185 + .../documentation/manual/core/en/introduction.html | 111 + .../manual/core/en/introduction.installation.html | 196 + .../manual/core/en/introduction.overview.html | 138 + .../manual/core/en/learning.autoloading.html | 120 + .../manual/core/en/learning.form.decorators.html | 123 + zend/documentation/manual/core/en/learning.html | 134 + .../manual/core/en/learning.layout.html | 114 + .../manual/core/en/learning.lucene.html | 126 + .../manual/core/en/learning.multiuser.html | 117 + .../manual/core/en/learning.paginator.html | 117 + .../manual/core/en/learning.plugins.html | 114 + .../manual/core/en/learning.quickstart.html | 123 + .../manual/core/en/learning.view.placeholders.html | 117 + zend/documentation/manual/core/en/manual.html | 106 + .../documentation/manual/core/en/migration.06.html | 354 + .../documentation/manual/core/en/migration.08.html | 197 + .../documentation/manual/core/en/migration.09.html | 154 + .../documentation/manual/core/en/migration.10.html | 389 + .../manual/core/en/migration.110.html | 502 ++ .../manual/core/en/migration.112.html | 187 + .../documentation/manual/core/en/migration.15.html | 235 + .../documentation/manual/core/en/migration.16.html | 209 + .../documentation/manual/core/en/migration.17.html | 702 ++ .../documentation/manual/core/en/migration.18.html | 157 + .../documentation/manual/core/en/migration.19.html | 545 ++ zend/documentation/manual/core/en/migration.html | 129 + .../manual/core/en/performance.classloading.html | 441 + .../manual/core/en/performance.database.html | 202 + zend/documentation/manual/core/en/performance.html | 117 + .../manual/core/en/performance.introduction.html | 108 + .../manual/core/en/performance.localization.html | 222 + .../manual/core/en/performance.view.html | 454 + .../core/en/project-structure.filesystem.html | 129 + .../manual/core/en/project-structure.html | 119 + .../manual/core/en/project-structure.overview.html | 126 + .../manual/core/en/project-structure.project.html | 302 + .../manual/core/en/project-structure.rewrite.html | 215 + zend/documentation/manual/core/en/reference.html | 332 + .../documentation/manual/core/en/requirements.html | 110 + .../manual/core/en/requirements.introduction.html | 9066 ++++++++++++++++++++ zend/documentation/manual/core/en/zend.acl.html | 177 + zend/documentation/manual/core/en/zend.amf.html | 174 + .../manual/core/en/zend.application.html | 186 + zend/documentation/manual/core/en/zend.auth.html | 186 + .../documentation/manual/core/en/zend.barcode.html | 180 + zend/documentation/manual/core/en/zend.cache.html | 183 + .../documentation/manual/core/en/zend.captcha.html | 177 + zend/documentation/manual/core/en/zend.cloud.html | 184 + .../manual/core/en/zend.codegenerator.html | 177 + zend/documentation/manual/core/en/zend.config.html | 186 + .../manual/core/en/zend.config.writer.html | 171 + .../manual/core/en/zend.console.getopt.html | 180 + .../manual/core/en/zend.controller.html | 204 + .../manual/core/en/zend.currency.html | 198 + zend/documentation/manual/core/en/zend.date.html | 189 + zend/documentation/manual/core/en/zend.db.html | 195 + zend/documentation/manual/core/en/zend.debug.html | 171 + zend/documentation/manual/core/en/zend.dojo.html | 183 + zend/documentation/manual/core/en/zend.dom.html | 174 + .../manual/core/en/zend.event-manager.html | 171 + .../manual/core/en/zend.exception.html | 177 + zend/documentation/manual/core/en/zend.feed.html | 201 + zend/documentation/manual/core/en/zend.file.html | 177 + zend/documentation/manual/core/en/zend.filter.html | 186 + zend/documentation/manual/core/en/zend.form.html | 195 + .../manual/core/en/zend.gdata.analytics.html | 176 + .../manual/core/en/zend.gdata.authsub.html | 253 + .../manual/core/en/zend.gdata.books.html | 600 ++ .../manual/core/en/zend.gdata.calendar.html | 956 +++ .../manual/core/en/zend.gdata.clientlogin.html | 218 + .../manual/core/en/zend.gdata.docs.html | 266 + .../manual/core/en/zend.gdata.exception.html | 206 + .../manual/core/en/zend.gdata.gapps.html | 1287 +++ zend/documentation/manual/core/en/zend.gdata.html | 195 + .../manual/core/en/zend.gdata.photos.html | 959 +++ .../manual/core/en/zend.gdata.spreadsheets.html | 480 ++ .../manual/core/en/zend.gdata.youtube.html | 758 ++ zend/documentation/manual/core/en/zend.http.html | 207 + .../manual/core/en/zend.infocard.html | 171 + zend/documentation/manual/core/en/zend.json.html | 183 + zend/documentation/manual/core/en/zend.layout.html | 180 + zend/documentation/manual/core/en/zend.ldap.html | 189 + zend/documentation/manual/core/en/zend.loader.html | 195 + zend/documentation/manual/core/en/zend.locale.html | 183 + zend/documentation/manual/core/en/zend.log.html | 183 + zend/documentation/manual/core/en/zend.mail.html | 210 + zend/documentation/manual/core/en/zend.markup.html | 180 + .../documentation/manual/core/en/zend.measure.html | 183 + zend/documentation/manual/core/en/zend.memory.html | 177 + zend/documentation/manual/core/en/zend.mime.html | 177 + .../manual/core/en/zend.mobile.push.html | 180 + .../manual/core/en/zend.navigation.html | 177 + zend/documentation/manual/core/en/zend.oauth.html | 171 + zend/documentation/manual/core/en/zend.openid.html | 177 + .../manual/core/en/zend.paginator.html | 180 + zend/documentation/manual/core/en/zend.pdf.html | 192 + .../manual/core/en/zend.progressbar.html | 171 + zend/documentation/manual/core/en/zend.queue.html | 186 + .../manual/core/en/zend.reflection.html | 177 + .../manual/core/en/zend.registry.html | 171 + zend/documentation/manual/core/en/zend.rest.html | 177 + .../manual/core/en/zend.search.lucene.html | 198 + .../manual/core/en/zend.serializer.html | 175 + zend/documentation/manual/core/en/zend.server.html | 174 + .../documentation/manual/core/en/zend.service.html | 291 + .../documentation/manual/core/en/zend.session.html | 183 + zend/documentation/manual/core/en/zend.soap.html | 180 + zend/documentation/manual/core/en/zend.tag.html | 174 + zend/documentation/manual/core/en/zend.test.html | 177 + zend/documentation/manual/core/en/zend.text.html | 174 + .../manual/core/en/zend.timesync.html | 174 + .../manual/core/en/zend.tool.framework.html | 186 + zend/documentation/manual/core/en/zend.tool.html | 174 + .../manual/core/en/zend.tool.project.html | 180 + .../manual/core/en/zend.translate.html | 186 + zend/documentation/manual/core/en/zend.uri.html | 171 + .../manual/core/en/zend.validate.html | 183 + .../documentation/manual/core/en/zend.version.html | 171 + zend/documentation/manual/core/en/zend.view.html | 183 + .../manual/core/en/zend.wildfire.html | 171 + zend/documentation/manual/core/en/zend.xmlrpc.html | 177 + .../manual/core/en/zendx.console.process.unix.html | 169 + .../documentation/manual/core/en/zendx.jquery.html | 171 + 133 files changed, 39573 insertions(+) create mode 100644 zend/documentation/manual/core/en/coding-standard.coding-style.html create mode 100644 zend/documentation/manual/core/en/coding-standard.html create mode 100644 zend/documentation/manual/core/en/coding-standard.naming-conventions.html create mode 100644 zend/documentation/manual/core/en/coding-standard.overview.html create mode 100644 zend/documentation/manual/core/en/coding-standard.php-file-formatting.html create mode 100644 zend/documentation/manual/core/en/copyrights.html create mode 100644 zend/documentation/manual/core/en/doc-standard.file-formatting.html create mode 100644 zend/documentation/manual/core/en/doc-standard.html create mode 100644 zend/documentation/manual/core/en/doc-standard.overview.html create mode 100644 zend/documentation/manual/core/en/doc-standard.recommendations.html create mode 100644 zend/documentation/manual/core/en/introduction.html create mode 100644 zend/documentation/manual/core/en/introduction.installation.html create mode 100644 zend/documentation/manual/core/en/introduction.overview.html create mode 100644 zend/documentation/manual/core/en/learning.autoloading.html create mode 100644 zend/documentation/manual/core/en/learning.form.decorators.html create mode 100644 zend/documentation/manual/core/en/learning.html create mode 100644 zend/documentation/manual/core/en/learning.layout.html create mode 100644 zend/documentation/manual/core/en/learning.lucene.html create mode 100644 zend/documentation/manual/core/en/learning.multiuser.html create mode 100644 zend/documentation/manual/core/en/learning.paginator.html create mode 100644 zend/documentation/manual/core/en/learning.plugins.html create mode 100644 zend/documentation/manual/core/en/learning.quickstart.html create mode 100644 zend/documentation/manual/core/en/learning.view.placeholders.html create mode 100644 zend/documentation/manual/core/en/manual.html create mode 100644 zend/documentation/manual/core/en/migration.06.html create mode 100644 zend/documentation/manual/core/en/migration.08.html create mode 100644 zend/documentation/manual/core/en/migration.09.html create mode 100644 zend/documentation/manual/core/en/migration.10.html create mode 100644 zend/documentation/manual/core/en/migration.110.html create mode 100644 zend/documentation/manual/core/en/migration.112.html create mode 100644 zend/documentation/manual/core/en/migration.15.html create mode 100644 zend/documentation/manual/core/en/migration.16.html create mode 100644 zend/documentation/manual/core/en/migration.17.html create mode 100644 zend/documentation/manual/core/en/migration.18.html create mode 100644 zend/documentation/manual/core/en/migration.19.html create mode 100644 zend/documentation/manual/core/en/migration.html create mode 100644 zend/documentation/manual/core/en/performance.classloading.html create mode 100644 zend/documentation/manual/core/en/performance.database.html create mode 100644 zend/documentation/manual/core/en/performance.html create mode 100644 zend/documentation/manual/core/en/performance.introduction.html create mode 100644 zend/documentation/manual/core/en/performance.localization.html create mode 100644 zend/documentation/manual/core/en/performance.view.html create mode 100644 zend/documentation/manual/core/en/project-structure.filesystem.html create mode 100644 zend/documentation/manual/core/en/project-structure.html create mode 100644 zend/documentation/manual/core/en/project-structure.overview.html create mode 100644 zend/documentation/manual/core/en/project-structure.project.html create mode 100644 zend/documentation/manual/core/en/project-structure.rewrite.html create mode 100644 zend/documentation/manual/core/en/reference.html create mode 100644 zend/documentation/manual/core/en/requirements.html create mode 100644 zend/documentation/manual/core/en/requirements.introduction.html create mode 100644 zend/documentation/manual/core/en/zend.acl.html create mode 100644 zend/documentation/manual/core/en/zend.amf.html create mode 100644 zend/documentation/manual/core/en/zend.application.html create mode 100644 zend/documentation/manual/core/en/zend.auth.html create mode 100644 zend/documentation/manual/core/en/zend.barcode.html create mode 100644 zend/documentation/manual/core/en/zend.cache.html create mode 100644 zend/documentation/manual/core/en/zend.captcha.html create mode 100644 zend/documentation/manual/core/en/zend.cloud.html create mode 100644 zend/documentation/manual/core/en/zend.codegenerator.html create mode 100644 zend/documentation/manual/core/en/zend.config.html create mode 100644 zend/documentation/manual/core/en/zend.config.writer.html create mode 100644 zend/documentation/manual/core/en/zend.console.getopt.html create mode 100644 zend/documentation/manual/core/en/zend.controller.html create mode 100644 zend/documentation/manual/core/en/zend.currency.html create mode 100644 zend/documentation/manual/core/en/zend.date.html create mode 100644 zend/documentation/manual/core/en/zend.db.html create mode 100644 zend/documentation/manual/core/en/zend.debug.html create mode 100644 zend/documentation/manual/core/en/zend.dojo.html create mode 100644 zend/documentation/manual/core/en/zend.dom.html create mode 100644 zend/documentation/manual/core/en/zend.event-manager.html create mode 100644 zend/documentation/manual/core/en/zend.exception.html create mode 100644 zend/documentation/manual/core/en/zend.feed.html create mode 100644 zend/documentation/manual/core/en/zend.file.html create mode 100644 zend/documentation/manual/core/en/zend.filter.html create mode 100644 zend/documentation/manual/core/en/zend.form.html create mode 100644 zend/documentation/manual/core/en/zend.gdata.analytics.html create mode 100644 zend/documentation/manual/core/en/zend.gdata.authsub.html create mode 100644 zend/documentation/manual/core/en/zend.gdata.books.html create mode 100644 zend/documentation/manual/core/en/zend.gdata.calendar.html create mode 100644 zend/documentation/manual/core/en/zend.gdata.clientlogin.html create mode 100644 zend/documentation/manual/core/en/zend.gdata.docs.html create mode 100644 zend/documentation/manual/core/en/zend.gdata.exception.html create mode 100644 zend/documentation/manual/core/en/zend.gdata.gapps.html create mode 100644 zend/documentation/manual/core/en/zend.gdata.html create mode 100644 zend/documentation/manual/core/en/zend.gdata.photos.html create mode 100644 zend/documentation/manual/core/en/zend.gdata.spreadsheets.html create mode 100644 zend/documentation/manual/core/en/zend.gdata.youtube.html create mode 100644 zend/documentation/manual/core/en/zend.http.html create mode 100644 zend/documentation/manual/core/en/zend.infocard.html create mode 100644 zend/documentation/manual/core/en/zend.json.html create mode 100644 zend/documentation/manual/core/en/zend.layout.html create mode 100644 zend/documentation/manual/core/en/zend.ldap.html create mode 100644 zend/documentation/manual/core/en/zend.loader.html create mode 100644 zend/documentation/manual/core/en/zend.locale.html create mode 100644 zend/documentation/manual/core/en/zend.log.html create mode 100644 zend/documentation/manual/core/en/zend.mail.html create mode 100644 zend/documentation/manual/core/en/zend.markup.html create mode 100644 zend/documentation/manual/core/en/zend.measure.html create mode 100644 zend/documentation/manual/core/en/zend.memory.html create mode 100644 zend/documentation/manual/core/en/zend.mime.html create mode 100644 zend/documentation/manual/core/en/zend.mobile.push.html create mode 100644 zend/documentation/manual/core/en/zend.navigation.html create mode 100644 zend/documentation/manual/core/en/zend.oauth.html create mode 100644 zend/documentation/manual/core/en/zend.openid.html create mode 100644 zend/documentation/manual/core/en/zend.paginator.html create mode 100644 zend/documentation/manual/core/en/zend.pdf.html create mode 100644 zend/documentation/manual/core/en/zend.progressbar.html create mode 100644 zend/documentation/manual/core/en/zend.queue.html create mode 100644 zend/documentation/manual/core/en/zend.reflection.html create mode 100644 zend/documentation/manual/core/en/zend.registry.html create mode 100644 zend/documentation/manual/core/en/zend.rest.html create mode 100644 zend/documentation/manual/core/en/zend.search.lucene.html create mode 100644 zend/documentation/manual/core/en/zend.serializer.html create mode 100644 zend/documentation/manual/core/en/zend.server.html create mode 100644 zend/documentation/manual/core/en/zend.service.html create mode 100644 zend/documentation/manual/core/en/zend.session.html create mode 100644 zend/documentation/manual/core/en/zend.soap.html create mode 100644 zend/documentation/manual/core/en/zend.tag.html create mode 100644 zend/documentation/manual/core/en/zend.test.html create mode 100644 zend/documentation/manual/core/en/zend.text.html create mode 100644 zend/documentation/manual/core/en/zend.timesync.html create mode 100644 zend/documentation/manual/core/en/zend.tool.framework.html create mode 100644 zend/documentation/manual/core/en/zend.tool.html create mode 100644 zend/documentation/manual/core/en/zend.tool.project.html create mode 100644 zend/documentation/manual/core/en/zend.translate.html create mode 100644 zend/documentation/manual/core/en/zend.uri.html create mode 100644 zend/documentation/manual/core/en/zend.validate.html create mode 100644 zend/documentation/manual/core/en/zend.version.html create mode 100644 zend/documentation/manual/core/en/zend.view.html create mode 100644 zend/documentation/manual/core/en/zend.wildfire.html create mode 100644 zend/documentation/manual/core/en/zend.xmlrpc.html create mode 100644 zend/documentation/manual/core/en/zendx.console.process.unix.html create mode 100644 zend/documentation/manual/core/en/zendx.jquery.html (limited to 'zend/documentation/manual/core/en') diff --git a/zend/documentation/manual/core/en/coding-standard.coding-style.html b/zend/documentation/manual/core/en/coding-standard.coding-style.html new file mode 100644 index 0000000..bbf6cca --- /dev/null +++ b/zend/documentation/manual/core/en/coding-standard.coding-style.html @@ -0,0 +1,843 @@ + + +
+ +
+
+ Coding StylePHP Code Demarcation+ PHP code must always be delimited by the full-form, standard + PHP tags: + + +
+ Short tags are never allowed. For files containing only PHP + code, the closing tag must always be omitted (See General standards). + +StringsString Literals+ When a string is literal (contains no variable substitutions), the apostrophe or + "single quote" should always be used to demarcate the string: + + +
String Literals Containing Apostrophes+ When a literal string itself contains apostrophes, it is permitted to demarcate + the string with quotation marks or "double quotes". This is especially useful + for SQL statements: + + +
+ This syntax is preferred over escaping apostrophes as it is much easier to read. + +Variable Substitution+ Variable substitution is permitted using either of these forms: + + +
+ For consistency, this form is not permitted: + + +
String Concatenation+ Strings must be concatenated using the "." operator. A space must always + be added before and after the "." operator to improve readability: + + +
+ When concatenating strings with the "." operator, it is encouraged to + break the statement into multiple lines to improve readability. In these + cases, each successive line should be padded with white space such that the + "."; operator is aligned under the "=" operator: + + +
ArraysNumerically Indexed ArraysNegative numbers are not permitted as indices. + ++ An indexed array may start with any non-negative number, however + all base indices besides 0 are discouraged. + + ++ When declaring indexed arrays with the Array function, a trailing + space must be added after each comma delimiter to improve readability: + + ++ It is permitted to declare multi-line indexed arrays using the "array" + construct. In this case, each successive line must be padded with spaces such + that beginning of each line is aligned: + + +
+ Alternately, the initial array item may begin on the following line. If so, + it should be padded at one indentation level greater than the line containing + the array declaration, and all successive lines should have the same + indentation; the closing paren should be on a line by itself at the same + indentation level as the line containing the array declaration: + + +
+ When using this latter declaration, we encourage using a trailing comma for + the last item in the array; this minimizes the impact of adding new items on + successive lines, and helps to ensure no parse errors occur due to a missing + comma. + +Associative Arrays+ When declaring associative arrays with the Array construct, + breaking the statement into multiple lines is encouraged. In this case, each + successive line must be padded with white space such that both the keys and the + values are aligned: + + +
+ Alternately, the initial array item may begin on the following line. If so, + it should be padded at one indentation level greater than the line containing + the array declaration, and all successive lines should have the same + indentation; the closing paren should be on a line by itself at the same + indentation level as the line containing the array declaration. For + readability, the various "=>" assignment operators should be padded such that + they align. + + +
+ When using this latter declaration, we encourage using a trailing comma for + the last item in the array; this minimizes the impact of adding new items on + successive lines, and helps to ensure no parse errors occur due to a missing + comma. + +ClassesClass Declaration+ Classes must be named according to Zend Framework's naming conventions. + + ++ The brace should always be written on the line underneath the class name. + + ++ Every class must have a documentation block that conforms to the PHPDocumentor + standard. + + ++ All code in a class must be indented with four spaces. + + ++ Only one class is permitted in each PHP file. + + ++ Placing additional code in class files is permitted but discouraged. + In such files, two blank lines must separate the class from any additional + PHP code in the class file. + + ++ The following is an example of an acceptable class declaration: + + +
+ Classes that extend other classes or which implement interfaces should + declare their dependencies on the same line when possible. + + +
+ If as a result of such declarations, the line length exceeds the maximum line + length, break the line before the "extends" and/or "implements" + keywords, and pad those lines by one indentation level. + + +
+ If the class implements multiple interfaces and the declaration exceeds the + maximum line length, break after each comma separating the interfaces, and + indent the interface names such that they align. + + +
Class Member Variables+ Member variables must be named according to Zend Framework's variable naming + conventions. + + ++ Any variables declared in a class must be listed at the top of the class, above + the declaration of any methods. + + ++ The var construct is not permitted. Member variables always + declare their visibility by using one of the private, + protected, or public modifiers. Giving + access to member variables directly by declaring them as public is permitted but + discouraged in favor of accessor methods (set & get). + +Functions and MethodsFunction and Method Declaration+ Functions must be named according to Zend Framework's function naming + conventions. + + ++ Methods inside classes must always declare their visibility by using + one of the private, protected, + or public modifiers. + + ++ As with classes, the brace should always be written on the line underneath the + function name. Space between the function name and the opening parenthesis for + the arguments is not permitted. + + ++ Functions in the global scope are strongly discouraged. + + ++ The following is an example of an acceptable function declaration in a class: + + +
+ In cases where the argument list exceeds the maximum line + length, you may introduce line breaks. Additional arguments to the + function or method must be indented one additional level beyond the function + or method declaration. A line break should then occur before the closing + argument paren, which should then be placed on the same line as the opening + brace of the function or method with one space separating the two, and at the + same indentation level as the function or method declaration. The following is + an example of one such situation: + + +
+ +
+ Call-time pass-by-reference is strictly prohibited. + + ++ The return value must not be enclosed in parentheses. This can hinder + readability, in additional to breaking code if a method is later changed to + return by reference. + + +
Function and Method Usage+ Function arguments should be separated by a single trailing space after the + comma delimiter. The following is an example of an acceptable invocation of a + function that takes three arguments: + + +
+ Call-time pass-by-reference is strictly prohibited. See the function + declarations section for the proper way to pass function arguments by-reference. + + ++ In passing arrays as arguments to a function, the function call may include the + "array" hint and may be split into multiple lines to improve readability. In + such cases, the normal guidelines for writing arrays still apply: + + + + +Control StatementsIf/Else/Elseif+ Control statements based on the if and + elseif constructs must have a single space before the + opening parenthesis of the conditional and a single space after the closing + parenthesis. + + ++ Within the conditional statements between the parentheses, operators must be + separated by spaces for readability. Inner parentheses are encouraged to improve + logical grouping for larger conditional expressions. + + ++ The opening brace is written on the same line as the conditional statement. The + closing brace is always written on its own line. Any content within the braces + must be indented using four spaces. + + +
+ If the conditional statement causes the line length to exceed the maximum line + length and has several clauses, you may break the conditional into + multiple lines. In such a case, break the line prior to a logic operator, and + pad the line such that it aligns under the first character of the conditional + clause. The closing paren in the conditional will then be placed on a line with + the opening brace, with one space separating the two, at an indentation level + equivalent to the opening control statement. + + +
+ The intention of this latter declaration format is to prevent issues when + adding or removing clauses from the conditional during later revisions. + + ++ For "if" statements that include "elseif" or "else", the formatting conventions + are similar to the "if" construct. The following examples demonstrate proper + formatting for "if" statements with "else" and/or "elseif" constructs: + + +
+ PHP allows statements to be written without braces in some + circumstances. This coding standard makes no differentiation- all "if", + "elseif" or "else" statements must use braces. + +Switch+ Control statements written with the "switch" statement must have a single space + before the opening parenthesis of the conditional statement and after the + closing parenthesis. + + ++ All content within the "switch" statement must be indented using four spaces. + Content under each "case" statement must be indented using an additional four + spaces. + + +
+ The construct default should never be omitted from a + switch statement. + + ++ Inline DocumentationDocumentation Format+ All documentation blocks ("docblocks") must be compatible with the phpDocumentor + format. Describing the phpDocumentor format is beyond the scope of this + document. For more information, visit: » http://phpdoc.org/ + + ++ All class files must contain a "file-level" docblock at the top of each file and + a "class-level" docblock immediately above each class. Examples of such + docblocks can be found below. + +Files+ Every file that contains PHP code must have a docblock at + the top of the file that contains these phpDocumentor tags at a minimum: + + +
+ The @category annotation must have a value of "Zend". + + ++ The @package annotation must be assigned, and should be + equivalent to the component name of the class contained in the file; typically, + this will only have two segments, the "Zend" prefix, and the component name. + + ++ The @subpackage annotation is optional. If provided, it + should be the subcomponent name, minus the class prefix. In the example above, + the assumption is that the class in the file is either + "Zend_Magic_Wand", or uses that classname as part of its + prefix. + +Classes+ Every class must have a docblock that contains these phpDocumentor tags at a + minimum: + + +
+ The @category annotation must have a value of "Zend". + + ++ The @package annotation must be assigned, and should be + equivalent to the component to which the class belongs; typically, this will + only have two segments, the "Zend" prefix, and the component name. + + ++ The @subpackage annotation is optional. If provided, it + should be the subcomponent name, minus the class prefix. In the example above, + the assumption is that the class described is either + "Zend_Magic_Wand", or uses that classname as part of its + prefix. + +Functions+ Every function, including object methods, must have a docblock that contains at + a minimum: + + +
+ It is not necessary to use the "@access" tag because the access level is already + known from the "public", "private", or "protected" modifier used to declare the + function. + + ++ If a function or method may throw an exception, use @throws for all known + exception classes: + + +
+ +
|
+ + + | +
+
+ Zend Framework Coding Standard for PHPTable of Contents ++ +
|
+
+
|
+
+
+ Naming ConventionsClasses+ Zend Framework standardizes on a class naming convention whereby the names of the + classes directly map to the directories in which they are stored. The root level + directory of Zend Framework's standard library is the "Zend/" directory, whereas + the root level directory of Zend Framework's extras library is the "ZendX/" + directory. All Zend Framework classes are stored hierarchically under these root + directories.. + + ++ Class names may only contain alphanumeric characters. Numbers are permitted + in class names but are discouraged in most cases. Underscores are only permitted in + place of the path separator; the filename "Zend/Db/Table.php" + must map to the class name "Zend_Db_Table". + + ++ If a class name is comprised of more than one word, the first letter of each new + word must be capitalized. Successive capitalized letters are not allowed, e.g. + a class "Zend_PDF" is not allowed while "Zend_Pdf" is + acceptable. + + ++ These conventions define a pseudo-namespace mechanism for Zend Framework. Zend + Framework will adopt the PHP namespace feature when it becomes + available and is feasible for our developers to use in their applications. + + ++ See the class names in the standard and extras libraries for examples of this + classname convention. + + ++ Abstract Classes+ In general, abstract classes follow the same conventions as classes, + with one additional rule: abstract class names must end in the term, "Abstract", + and that term must not be preceded by an underscore. As an example, + Zend_Controller_Plugin_Abstract is considered an + invalid name, but Zend_Controller_PluginAbstract or + Zend_Controller_Plugin_PluginAbstract would be valid + names. + + ++ Interfaces+ In general, interfaces follow the same conventions as classes, + with one additional rule: interface names may optionally end in the term, + "Interface", but that term must not be preceded by an underscore. As an example, + Zend_Controller_Plugin_Interface is considered an + invalid name, but Zend_Controller_PluginInterface or + Zend_Controller_Plugin_PluginInterface would be valid + names. + + ++ While this rule is not required, it is strongly recommended, as it provides a + good visual cue to developers as to which files contain interfaces rather than + classes. + + ++ Filenames+ For all other files, only alphanumeric characters, underscores, and the dash + character ("-") are permitted. Spaces are strictly prohibited. + + ++ Any file that contains PHP code should end with the extension + ".php", with the notable exception of view scripts. The + following examples show acceptable filenames for Zend Framework classes: + + +
+ File names must map to class names as described above. + +Functions and Methods+ Function names may only contain alphanumeric characters. Underscores are not + permitted. Numbers are permitted in function names but are discouraged in most + cases. + + ++ Function names must always start with a lowercase letter. When a function name + consists of more than one word, the first letter of each new word must be + capitalized. This is commonly called "camelCase" formatting. + + ++ Verbosity is generally encouraged. Function names should be as verbose as is + practical to fully describe their purpose and behavior. + + ++ These are examples of acceptable names for functions: + + +
+ For object-oriented programming, accessors for instance or static variables should + always be prefixed with "get" or "set". In implementing design patterns, such as the + singleton or factory patterns, the name of the method should contain the pattern + name where practical to more thoroughly describe behavior. + + ++ For methods on objects that are declared with the "private" or "protected" modifier, + the first character of the method name must be an underscore. This is the only + acceptable application of an underscore in a method name. Methods declared "public" + should never contain an underscore. + + ++ Functions in the global scope (a.k.a "floating functions") are permitted but + discouraged in most cases. Consider wrapping these functions in a static class. + +Variables+ Variable names may only contain alphanumeric characters. Underscores are not + permitted. Numbers are permitted in variable names but are discouraged in most + cases. + + ++ For instance variables that are declared with the "private" or "protected" modifier, + the first character of the variable name must be a single underscore. This is the + only acceptable application of an underscore in a variable name. Member variables + declared "public" should never start with an underscore. + + ++ As with function names (see section 3.3) variable names must always start with a + lowercase letter and follow the "camelCaps" capitalization convention. + + ++ Verbosity is generally encouraged. Variables should always be as verbose as + practical to describe the data that the developer intends to store in them. Terse + variable names such as "$i" and "$n" are + discouraged for all but the smallest loop contexts. If a loop contains more than + 20 lines of code, the index variables should have more descriptive names. + +Constants+ Constants may contain both alphanumeric characters and underscores. Numbers are + permitted in constant names. + + ++ All letters used in a constant name must be capitalized, while all words in a + constant name must be separated by underscore characters. + + ++ For example, EMBED_SUPPRESS_EMBED_EXCEPTION is permitted but + EMBED_SUPPRESSEMBEDEXCEPTION is not. + + ++ Constants must be defined as class members with the "const" modifier. Defining + constants in the global scope with the "define" function is permitted but strongly + discouraged. + ++ +
|
+ + + | +
+
+ OverviewScope+ This document provides guidelines for code formatting and documentation to + individuals and teams contributing to Zend Framework. Many developers using Zend + Framework have also found these coding standards useful because their code's style + remains consistent with all Zend Framework code. It is also worth noting that it + requires significant effort to fully specify coding standards. + + ++ + + Topics covered in Zend Framework's coding standards include: + + +
Goals+ Coding standards are important in any development project, but they are particularly + important when many developers are working on the same project. Coding standards + help ensure that the code is high quality, has fewer bugs, and can be easily + maintained. + ++ +
|
+ + + | +
+
+ PHP File FormattingGeneral+ For files that contain only PHP code, the closing tag ("?>") is + never permitted. It is not required by PHP, and omitting it´ + prevents the accidental injection of trailing white space into the response. + + ++ IndentationIndentation should consist of 4 spaces. Tabs are not allowed. +Maximum Line Length+ The target line length is 80 characters. That is to say, Zend Framework developers + should strive keep each line of their code under 80 characters where possible and + practical. However, longer lines are acceptable in some circumstances. The maximum + length of any line of PHP code is 120 characters. + +Line Termination+ Line termination follows the Unix text file convention. Lines must end with a + single linefeed (LF) character. Linefeed characters are represented as ordinal 10, + or hexadecimal 0x0A. + + ++ Note: Do not use carriage returns (CR) as is the convention in Apple OS's (0x0D) or + the carriage return - linefeed combination (CRLF) as is standard + for the Windows OS (0x0D, 0x0A). + ++ +
|
+ + + | +
+
+ Copyright Information+ The following copyrights are applicable to portions of Zend Framework. + + ++ Copyright © 2005- Zend Technologies Inc. + (http://www.zend.com) + ++ +
|
+
+
|
+
+
+ Documentation File FormattingXML Tags+ Each manual file must include the following XML declarations at + the top of the file: + + +
+ XML files from translated languages must also include a revision + tag containing the revision of the corresponding English-language file the + translation was based on. + + +
Maximum Line Length+ The maximum line length, including tags, attributes, and indentation, is not to + exceed 100 characters. There is only one exception to this rule: attribute and value + pairs are allowed to exceed the 100 chars as they are not allowed to be separated. + +IndentationIndentation should consist of 4 spaces. Tabs are not allowed. +Tags which are at the same level must have the same indentation. + +
+ Tags which are one level under the previous tag must be indented with 4 additional + spaces. + + +
+ Multiple block tags within the same line are not allowed; multiple inline tags are + allowed, however. + + +
Line Termination+ Line termination follows the Unix text file convention. Lines must end with a + single linefeed (LF) character. Linefeed characters are represented as ordinal 10, + or hexadecimal 0x0A. + + ++ Note: Do not use carriage returns (CR) as is the convention in + Apple OS's (0x0D) or the carriage return - linefeed combination + (CRLF) as is standard for the Windows OS (0x0D, 0x0A). + +Empty tags+ Empty tags are not allowed; all tags must contain text or child tags. + + +
Usage of whitespace within documentsWhitespace within tags+ Opening block tags should have no whitespace immediately following them other + than line breaks (and indentation on the following line). + + +
+ Opening inline tags should have no whitespace immediately following them. + + +
+ Closing block tags may be preceded by whitespace equivalent to the current + indentation level, but no more than that amount. + + +
+ Closing inline tags must not be preceded by any whitespace. + + +
Multiple line breaks+ Multiple line breaks within or between tags are not allowed. + + +
Separation between tags+ Tags at the same level must be separated by an empty line to improve + readability. + + +
+ The first child tag should open directly below its parent, with no empty line + between them; the last child tag should close directly before the closing tag of + its parent. + + +
Program Listings+ The opening <programlisting> tag must indicate the + appropriate "language" attribute and be indented at the same level as its sibling + blocks. + + +
+ CDATA should be used around all program listings. + + ++ <programlisting> sections must not add linebreaks or + whitespace at the beginning or end of the section, as these are then represented in + the final output. + + +
+ Ending CDATA and <programlisting> + tags should be on the same line, without any indentation. + + +
+ The <programlisting> tag should contain the "language" + attribute with a value appropriate to the contents of the program listing. Typical + values include "css", "html", "ini", "javascript", "php", "text", and "xml". + + +
+ For program listings containing only PHP code, + PHP tags (e.g., "<?php", "?>") are not required, and + should not be used. They simply clutter the narrative, and are implied by the use + of the <programlisting> tag. + + +
+ Line lengths within program listings should follow the coding standards + recommendations. + + ++ Refrain from using require_once(), + require(), include_once(), and + include() calls within PHP listings. + They simply clutter the narrative, and are largely obviated when using an + autoloader. Use them only when they are essential to the example. + + ++ Notes on specific inline tagsclassname+ The tag <classname> must be used each time a class + name is represented by itself; it should not be used when combined with a + method name, variable name, or constant, and no other content is allowed within + the tag. + + +
varname+ Variables must be wrapped in the <varname> tag. + Variables must be written using the "$" sigil. No other content is allowed + within this tag, unless a class name is used, which indicates a class variable. + + +
methodname+ Methods must be wrapped in the <methodname> tag. + Methods must either include the full method signature or at the least a pair of + closing parentheses (e.g., "()"). No other content is allowed within this tag, + unless a class name is used, which indicates a class method. + + +
constant+ Use the <constant> tag when denoting constants. + Constants must be written in UPPERCASE. No other content is + allowed within this tag, unless a class name is used, which indicates a class + constant. + + +
filename+ Filenames and paths must be wrapped in the + <filename> tag. No other content is allowed in this + tag. + + +
command+ Commands, shell scripts, and program calls must be wrapped in the + <command> tag. If the command includes arguments, + these should also be included within the tag. + + +
code+ Usage of the <code> tag is discouraged, in favor of + the other inline tasks discussed previously. + +Notes on specific block tagstitle+ The <title> tag is not allowed to hold other tags. + + +
+ +
|
+ + + | +
+
+ Zend Framework Documentation StandardTable of Contents ++ +
|
+
+
|
+
+
+ OverviewScope+ This document provides guidelines for creation of the end-user + documentation found within Zend Framework. It is intended as a + guide to Zend Framework contributors, who must write + documentation as part of component contributions, as well as to + documentation translators. The standards contained herein are + intended to ease translation of documentation, minimize + visual and stylistic differences between different documentation + files, and make finding changes in documentation easier with + diff tools. + + ++ You may adopt and/or modify these standards in accordance with the terms of our + » license. + + ++ Topics covered in Zend Framework's documentation standards include documentation + file formatting and recommendations for documentation quality. + ++ +
|
+ + + | +
+
+ RecommendationsUse editors without autoformatting+ For editing the documentation, typically you should not use formal + XML editors. Such editors normally autoformat existing documents + to fit their own standards and/or do not strictly follow the docbook standard. As + examples, we have seen them erase the CDATA tags, change 4 space + separation to tabs or 2 spaces, etc. + + ++ The style guidelines were written in large part to assist translators in recognizing + the lines that have changed using normal diff tools. + Autoformatting makes this process more difficult. + +Use Images+ Good images and diagrams can improve readability and comprehension. Use them + whenever they will assist in these goals. Images should be placed in the + documentation/manual/en/figures/ directory, and be named after + the section identifier in which they occur. + +Use Case Examples+ Look for good use cases submitted by the community, especially those posted in + proposal comments or on one of the mailing lists. Examples often illustrate usage + far better than the narrative does. + + ++ When writing your examples for inclusion in the manual, follow + all coding standards and documentation standards. + +Avoid Replicating phpdoc Contents+ The manual is intended to be a reference guide for end-user usage. Replicating + the phpdoc documentation for internal-use components and classes is not wanted, and + the narrative should be focussed on usage, not the internal workings. In any case, + at this time, we would like the documentation teams to focus on translating the + English manual, not the phpdoc comments. + +Use Links+ Link to other sections of the manual or to external sources + instead of recreating documentation. + + ++ Linking to other sections of the manual may be done using the + <link> tag (to which you must provide link text). + + +
+ To link to an external resource, use <ulink>: + + +
+ +
|
+ + + | +
+
+
+
+ Introduction to Zend GdataTable of Contents
+ +
|
+
+
|
+
+
+ Installation+ See the requirements appendix for a detailed list of + requirements for Zend Framework. + + ++ Installing Zend Framework is extremely simple. Once you have downloaded and extracted the + framework, you should add the /library folder in the distribution to + the beginning of your include path. You may also want to move the library folder + to another – possibly shared – location on your file system. + + +
+ Once you have a copy of Zend Framework available, your application needs to be able to + access the framework classes. Though there are + » + several ways to achieve this, your PHP + » include_path + needs to contain the path to Zend Framework's library. + + ++ Zend provides a » QuickStart + to get you up and running as quickly as possible. This is an excellent way to begin + learning about the framework with an emphasis on real world examples that you can build + upon. + + ++ Since Zend Framework components are loosely coupled, you may use a somewhat unique + combination of them in your own applications. The following chapters provide a + comprehensive reference to Zend Framework on a component-by-component basis. + ++ +
|
+ + + | +
+
+ Overview+ Zend Framework is an open source framework for developing web applications and services + with PHP 5. Zend Framework is implemented using 100% object-oriented + code. The component structure of Zend Framework is somewhat unique; each component is + designed with few dependencies on other components. This loosely coupled architecture allows + developers to use components individually. We often call this a "use-at-will" design. + + ++ While they can be used separately, Zend Framework components in the standard library form a + powerful and extensible web application framework when combined. Zend Framework offers a + robust, high performance MVC implementation, a database abstraction that + is simple to use, and a forms component that implements HTML form + rendering, validation, and filtering so that developers can consolidate all of these + operations using one easy-to-use, object oriented interface. Other components, such as + Zend_Auth and Zend_Acl, provide user + authentication and authorization against all common credential stores. Still others + implement client libraries to simply access to the most popular web services available. + Whatever your application needs are, you're likely to find a Zend Framework component that + can be used to dramatically reduce development time with a thoroughly tested foundation. + + ++ The principal sponsor of the project 'Zend Framework' is » + Zend Technologies, but many companies have contributed components or significant + features to the framework. Companies such as Google, Microsoft, and StrikeIron have + partnered with Zend to provide interfaces to web services and other technologies that they + wish to make available to Zend Framework developers. + + ++ Zend Framework could not deliver and support all of these features without the help of the + vibrant Zend Framework community. Community members, including contributors, make + themselves available on » mailing + lists, » IRC channels, and other + forums. Whatever question you have about Zend Framework, the community is always available + to address it. + ++ +
|
+ + + | +
+
+
+
+ Autoloading in Zend Gdata+ + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Understanding and Using Zend Form Decorators+ + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Learning Zend GdataTable of Contents
+ +
|
+
+
|
+
+
+
+
+ Getting Started with Zend_Layout+ + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Getting Started with Zend_Search_Lucene+ + + + + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Getting Started with Zend_Session, Zend_Auth, and Zend_Acl+ + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Getting Started with Zend_Paginator+ + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Plugins in Zend Gdata+ + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend Gdata Quick Start+ + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Getting Started Zend_View Placeholders+ + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+Table of Contents
+
+ +
|
+ + + | +
+
+ Zend Framework 0.6+ When upgrading from a previous release to Zend Framework 0.6 or higher you + should note the following migration notes. + + +Zend_Controller+ The most basic usage of the MVC components has not changed; you can + still do each of the following: + + +
+ We encourage use of the Response object to aggregate content and + headers. This will allow for more flexible output format switching + (for instance, JSON or XML instead of + XHTML) in your applications. + By default, dispatch() will render the response, sending both + headers and rendering any content. You may also have the front + controller return the response using returnResponse(), + and then render the response using your own logic. A future version + of the front controller may enforce use of the response object via + output buffering. + + ++ There are many additional features that extend the existing API, + and these are noted in the documentation. + + ++ The main changes you will need to be aware of will be found when + subclassing the various components. Key amongst these are: + + +
+ +
|
+
+
|
+
+
+ Zend Framework 0.8+ When upgrading from a previous release to Zend Framework 0.8 or higher you + should note the following migration notes. + + +Zend_Controller+ Per previous changes, the most basic usage of the MVC components + remains the same: + + +
+ However, the directory structure underwent an overhaul, several + components were removed, and several others either renamed or added. + Changes include: + + +
+ +
|
+
+
|
+
+
+ Zend Framework 0.9+ When upgrading from a previous release to Zend Framework 0.9 or higher you + should note the following migration notes. + + +Zend_Controller+ 0.9.3 introduces action helpers. + As part of this change, the following methods have been removed as + they are now encapsulated in the redirector + action helper: + + +
+ Read the action + helpers documentation for more information on how to + retrieve and manipulate helper objects, and the redirector + helper documentation for more information on setting + redirect options (as well as alternate methods for redirecting). + ++ +
|
+
+
|
+
+
+ Zend Framework 1.0+ When upgrading from a previous release to Zend Framework 1.0 or higher you + should note the following migration notes. + + +Zend_Controller+ The principal changes introduced in 1.0.0RC1 are the introduction of + and default enabling of the + ErrorHandler + plugin and the ViewRenderer + action helper. Please read the documentation to each thoroughly to + see how they work and what effect they may have on your + applications. + + ++ The ErrorHandler plugin runs during + postDispatch() checking for exceptions, and forwarding + to a specified error handler controller. You should include such a + controller in your application. You may disable it by setting the + front controller parameter noErrorHandler: + + +
+ The ViewRenderer action helper automates view injection + into action controllers as well as autorendering of view scripts + based on the current action. The primary issue you may encounter is + if you have actions that do not render view scripts and neither + forward or redirect, as the ViewRenderer will attempt + to render a view script based on the action name. + + ++ There are several strategies you can take to update your code. In + the short term, you can globally disable the + ViewRenderer in your front controller bootstrap prior + to dispatching: + + +
+ However, this is not a good long term strategy, as it means most + likely you'll be writing more code. + + ++ When you're ready to start using the ViewRenderer + functionality, there are several things to look for in your + controller code. First, look at your action methods (the methods + ending in 'Action'), and determine what each is doing. If none of + the following is happening, you'll need to make changes: + + +
+ The easiest change is to disable auto-rendering for that method: + + +
+ If you find that none of your action methods are rendering, + forwarding, or redirecting, you will likely want to put the above + line in your preDispatch() or init() + methods: + + +
+ If you are calling render(), and you're using the Conventional Modular + directory structure, you'll want to change your code to + make use of autorendering: + + +
+ If you're not using the conventional modular directory structure, + there are a variety of methods for setting the view base path and + script path specifications so that you can make use of the + ViewRenderer. Please read the ViewRenderer + documentation for information on these methods. + + ++ If you're using a view object from the registry, or customizing your + view object, or using a different view implementation, you'll want + to inject the ViewRenderer with this object. This can + be done easily at any time. + + +
+ There are many ways to modify the ViewRenderer, + including setting a different view script to render, specifying + replacements for all replaceable elements of a view script path + (including the suffix), choosing a response named segment to + utilize, and more. If you aren't using the conventional modular + directory structure, you can even associate different path + specifications with the ViewRenderer. + + ++ We encourage you to adapt your code to use the + ErrorHandler and ViewRenderer as they are + now core functionality. + +Zend_Currency+ Creating an object of Zend_Currency has become simpler. + You no longer have to give a script or set it to NULL. The optional + script parameter is now an option which can be set through the + setFormat() method. + + +
+ The setFormat() method takes now an array of options. These + options are set permanently and override all previously set values. Also a new option + 'precision' has been added. The following options have been refactored: + + +
+ The toCurrency() method no longer supports the optional + 'script' and 'locale' parameters. Instead it takes an options array which + can contain the same keys as for the setFormat() method. + + ++ The methods getSymbol(), + getShortName(), getName(), + getRegionList() and + getCurrencyList() are no longer static and can be called + from within the object. They return the set values of the object if no + parameter has been set. + ++ +
|
+
+
|
+
+
+ Zend Framework 1.10+ When upgrading from a previous release to Zend Framework 1.10 or higher you + should note the following migration notes. + + +Zend_Controller_Front+ A wrong behaviour was fixed, when there was no module route and no route + matched the given request. Previously, the router returned an unmodified + request object, so the front controller just displayed the default controller + and action. Since Zend Framework 1.10, the router will correctly as noted + in the router interface, throw an exception if no route matches. The error + plugin will then catch that exception and forward to the error controller. + You can then test for that specific error with the constant + Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE: + + +
Zend_Feed_Reader+ With the introduction of Zend Framework 1.10, Zend_Feed_Reader's + handling of retrieving Authors and Contributors was changed, introducing + a break in backwards compatibility. This change was an effort to harmonise + the treatment of such data across the RSS and Atom classes of the component + and enable the return of Author and Contributor data in more accessible, + usable and detailed form. It also rectifies an error in that it was assumed + any author element referred to a name. In RSS this is incorrect as an + author element is actually only required to provide an email address. + In addition, the original implementation applied its RSS limits to Atom + feeds significantly reducing the usefulness of the parser with that format. + + ++ The change means that methods like getAuthors() + and getContributors no longer return a simple array + of strings parsed from the relevant RSS and Atom elements. Instead, the return + value is an ArrayObject subclass called + Zend_Feed_Reader_Collection_Author which simulates + an iterable multidimensional array of Authors. Each member of this object + will be a simple array with three potential keys (as the source data permits). + These include: name, email and uri. + + ++ The original behaviour of such methods would have returned a simple + array of strings, each string attempting to present a single name, but + in reality this was unreliable since there is no rule governing the format + of RSS Author strings. + + ++ The simplest method of simulating the original behaviour of these + methods is to use the Zend_Feed_Reader_Collection_Author's + getValues() which also returns a simple array of strings + representing the "most relevant data", for authors presumed to be their name. + Each value in the resulting array is derived from the "name" value + attached to each Author (if present). In most cases this simple change is + easy to apply as demonstrated below. + + +
Zend_File_TransferSecurity change+ For security reasons Zend_File_Transfer does no longer store + the original mimetype and filesize which is given from the requesting client into + its internal storage. Instead the real values will be detected at initiation. + + ++ Additionally the original values within $_FILES will be + overridden within the real values at initiation. This makes also + $_FILES secure. + + ++ When you are in need of the original values you can either store them before + initiating Zend_File_Transfer or use the + disableInfos option at initiation. Note that this option is + useless when its given after initiation. + +Count validation+ Before release 1.10 the MimeType validator used a wrong + naming. For consistency the following constants have been changed: + + +
+ When you are translating these messages within your code then use the new constants. + As benefit you don't need to translate the original string anymore to get a correct + spelling. + +Zend_Filter_HtmlEntities+ In order to default to a more secure character encoding, + Zend_Filter_HtmlEntities now defaults to UTF-8 + instead of ISO-8859-1. + + ++ Additionally, because the actual mechanism is dealing with character encodings and not + character sets, two new methods have been added, setEncoding() + and getEncoding(). The previous methods + setCharSet() and setCharSet() are now + deprecated and proxy to the new methods. Finally, instead of using the protected members + directly within the filter() method, these members are + retrieved by their explicit accessors. If you were extending the filter in the past, + please check your code and unit tests to ensure everything still continues to work. + +Zend_Filter_StripTags+ Zend_Filter_StripTags contains a flag, + commentsAllowed, that, in previous versions, allowed you to + optionally whitelist HTML comments in HTML text + filtered by the class. However, this opens code enabling the flag to + XSS attacks, particularly in Internet Explorer (which allows + specifying conditional functionality via HTML comments). Starting + in version 1.9.7 (and backported to versions 1.8.5 and 1.7.9), the + commentsAllowed flag no longer has any meaning, and all + HTML comments, including those containing other + HTML tags or nested commments, will be stripped from the final output + of the filter. + +Zend_TranslateXliff adapter+ In past the Xliff adapter used the source string as message Id. According to the + Xliff standard the trans-unit Id should be used. This behaviour was corrected with + Zend Framework 1.10. Now the trans-unit Id is used as message Id per default. + + ++ But you can still get the incorrect and old behaviour by setting the + useId option to FALSE. + + +
Zend_ValidateSelf written validators+ When setting returning a error from within a self written validator you have to + call the _error() method. Before Zend Framework 1.10 you + were able to call this method without giving a parameter. It used then the first + found message template. + + ++ This behaviour is problematic when you have validators with more than one different + message to be returned. Also when you extend an existing validator you can get + unexpected results. This could lead to the problem that your user get not the + message you expected. + + +
+ To prevent this problem the _error() method is no longer + allowed to be called without giving a parameter. + + +
Simplification in date validator+ Before Zend Framework 1.10 2 identical messages were thrown within the date + validator. These were NOT_YYYY_MM_DD and + FALSEFORMAT. As of Zend Framework 1.10 only the + FALSEFORMAT message will be returned when the given date + does not match the set format. + +Fixes in Alpha, Alnum and Barcode validator+ Before Zend Framework 1.10 the messages within the 2 barcode adapters, the Alpha + and the Alnum validator were identical. This introduced problems when using custom + messages, translations or multiple instances of these validators. + + ++ As with Zend Framework 1.10 the values of the constants were changed to + be unique. When you used the constants as proposed in the manual there is + no change for you. But when you used the content of the constants in your code + then you will have to change them. The following table shows you the changed values: + + +
+ +
|
+
+
|
+
+
+ Zend Framework 1.12+ When upgrading from a previous release to Zend Framework 1.12 or higher you + should note the following migration notes. + + + ++ +
|
+
+
|
+
+
+ Zend Framework 1.5+ When upgrading from a previous release to Zend Framework 1.5 or higher you + should note the following migration notes. + + +Zend_Controller+ Though most basic functionality remains the same, and all documented + functionality remains the same, there is one particular + undocumented "feature" that has changed. + + ++ When writing URLs, the documented way to write camelCased action + names is to use a word separator; these are '.' or '-' by default, + but may be configured in the dispatcher. The dispatcher internally + lowercases the action name, and uses these word separators to + re-assemble the action method using camelCasing. However, because PHP + functions are not case sensitive, you could + still write URLs using camelCasing, and the dispatcher would resolve + these to the same location. For example, 'camel-cased' would become + 'camelCasedAction' by the dispatcher, whereas 'camelCased' would + become 'camelcasedAction'; however, due to the case insensitivity of + PHP, both will execute the same method. + + ++ This causes issues with the ViewRenderer when resolving view + scripts. The canonical, documented way is that all word separators + are converted to dashes, and the words lowercased. This creates + a semantic tie between the actions and view scripts, and the + normalization ensures that the scripts can be found. However, if the + action 'camelCased' is called and actually resolves, the word + separator is no longer present, and the ViewRenderer attempts to + resolve to a different location -- camelcased.phtml instead of + camel-cased.phtml. + + ++ Some developers relied on this "feature", which was never intended. + Several changes in the 1.5.0 tree, however, made it so that the + ViewRenderer no longer resolves these paths; the semantic tie is now + enforced. First among these, the dispatcher now enforces case + sensitivity in action names. What this means is that referring to + your actions on the url using camelCasing will no longer resolve to + the same method as using word separators (i.e., 'camel-casing'). + This leads to the ViewRenderer now only honoring the word-separated + actions when resolving view scripts. + + ++ If you find that you were relying on this "feature", you have several + options: + + +
+ +
|
+
+
|
+
+
+ Zend Framework 1.6+ When upgrading from a previous release to Zend Framework 1.6 or higher you + should note the following migration notes. + + +Zend_ControllerDispatcher Interface Changes+ Users brought to our attention the fact that + Zend_Controller_Front and + Zend_Controller_Router_Route_Module were each + using methods of the dispatcher that were not in the dispatcher + interface. We have now added the following three methods to + ensure that custom dispatchers will continue to work with the + shipped implementations: + + +
Zend_File_TransferChanges when using validators+ As noted by users, the validators from Zend_File_Transfer + do not work the same way like the default ones from + Zend_Form. Zend_Form allows the usage + of a $breakChainOnFailure parameter which breaks the validation + for all further validators when an validation error has occurred. + + ++ So we added this parameter also to all existing validators from + Zend_File_Transfer. + + +
+ To migrate your scripts to the new API, simply add a + FALSE after defining the wished validator. + + +Example #1 How to change your file validators from 1.6.1 to 1.6.2
+ +
|
+
+
|
+
+
+ Zend Framework 1.7+ When upgrading from a previous release to Zend Framework 1.7 or higher you + should note the following migration notes. + + +Zend_ControllerDispatcher Interface Changes+ Users brought to our attention the fact that + Zend_Controller_Action_Helper_ViewRenderer were + using a method of the dispatcher abstract class that was not in + the dispatcher interface. We have now added the following method to + ensure that custom dispatchers will continue to work with the + shipped implementations: + + +
Zend_File_TransferChanges when using filters and validators+ As noted by users, the validators from Zend_File_Transfer + do not work in conjunction with Zend_Config due to the fact + that they have not used named arrays. + + ++ Therefor, all filters and validators for Zend_File_Transfer + have been reworked. While the old signatures continue to work, + they have been marked as deprecated, and will emit a PHP notice + asking you to fix them. + + ++ The following list shows you the changes you will have to do for proper + usage of the parameters. + + +Filter: Rename
Example #1 Changes for the rename filter from 1.6 to 1.7
Validator: Count
Example #2 Changes for the count validator from 1.6 to 1.7 Validator:Extension
Example #3 Changes for the extension validator from 1.6 to 1.7
Validator: FilesSize
+ Additionally, the useByteString() method + signature has changed. It can only be used to test if the + validator is expecting to use byte strings in generated + messages. To set the value of the flag, use the + setUseByteString() method. + + +Example #4 Changes for the filessize validator from 1.6 to 1.7
Validator: Hash
Example #5 Changes for the hash validator from 1.6 to 1.7 Validator: ImageSize
Example #6 Changes for the imagesize validator from 1.6 to 1.7
Validator: Size
Example #7 Changes for the size validator from 1.6 to 1.7
Zend_LocaleChanges when using isLocale()+ According to the coding standards isLocale() had to be + changed to return a boolean. In previous releases a string was returned on success. + For release 1.7 a compatibility mode has been added which allows to use the + old behaviour of a returned string, but it triggers a user warning to + mention you to change to the new behaviour. The rerouting which the old + behaviour of isLocale() could have done is no longer + neccessary as all I18n will now process a rerouting themself. + + ++ To migrate your scripts to the new API, simply use the method as + shown below. + + +Example #8 How to change isLocale() from 1.6 to 1.7
+ Note that you can use the second parameter to see if the locale is correct + without processing a rerouting. +
Changes when using getDefault()+ The meaning of the getDefault() method has been change due + to the fact that we integrated a framework locale which can be set with + setDefault(). It does no longer return the locale chain + but only the set framework locale. + + ++ To migrate your scripts to the new API, simply use the method as + shown below. + + +Example #9 How to change getDefault() from 1.6 to 1.7
+ Note that the second parameter of the old getDefault() + implementation is not available anymore, but the returned values are the same. + + Zend_TranslateSetting languages+ When using automatic detection of languages, or setting languages manually + to Zend_Translate you may have mentioned that from time to + time a notice is thrown about not added or empty translations. In some previous + release also an exception was raised in some cases. + + ++ The reason is, that when a user requests a non existing language, you + have no simple way to detect what's going wrong. So we added those + notices which show up in your log and tell you that the user requested + a language which you do not support. Note that the code, even when + we trigger such an notice, keeps working without problems. + + ++ But when you use a own error or exception handler, like xdebug, you + will get all notices returned, even if this was not your intention. + This is due to the fact that these handlers override all settings + from within PHP. + + ++ To get rid of these notices you can simply set the new option + 'disableNotices' to TRUE. It defaults to + FALSE. + + +Example #10 Setting languages without getting notices + Let's assume that we have 'en' available and our user requests + 'fr' which is not in our portfolio of translated languages. +
+ In this case we will get an notice about a not available language 'fr'. + Simply add the option and the notices will be disabled. +
Zend_View+ + + Prior to the 1.7.5 release, the Zend Framework team was notified of + a potential Local File Inclusion (LFI) vulnerability in the + Zend_View::render() method. Prior to 1.7.5, the method + allowed, by default, the ability to specify view scripts that + included parent directory notation (e.g., "../" or "..\"). This + opens the possibility for an LFI attack if unfiltered user input is + passed to the render() method: + + +
+ Zend_View now by default raises an exception when such + a view script is requested. + + +Disabling LFI protection for the render() method+ Since a number of developers reported that they were using such + notation within their applications that was not + the result of user input, a special flag was created to allow + disabling the default protection. You have two methods for doing so: + by passing the 'lfiProtectionOn' key to the constructor options, or + by explicitly calling the setLfiProtection() method. + + +
+ +
|
+
+
|
+
+
+ Zend Framework 1.8+ When upgrading from a previous release to Zend Framework 1.8 or higher you + should note the following migration notes. + + +Zend_ControllerStandard Route Changes+ As translated segments were introduced into the new standard + route, the '@' character is now a special character + in the beginning of a route segment. To be able to use it in a + static segment, you must escape it by prefixing it with second + '@' character. The same rule now applies for the + ':' character. + +Zend_LocaleDefault caching+ As with Zend Framework 1.8 a default caching was added. The reason behind this + change was, that most users had performance problems but did not add caching at + all. As the I18n core is a bottleneck when no caching is used we decided to add + a default caching when no cache has been set to Zend_Locale. + + ++ Sometimes it is still wanted to prevent caching at all even if this decreases + performance. To do so you can simply disable caching by using the + disableCache() method. + + +Example #1 Disabling default caching
+ +
|
+
+
|
+
+
+ Zend Framework 1.9+ When upgrading from a release of Zend Framework earlier than 1.9.0 to any 1.9 release, you + should note the following migration notes. + + +Zend_File_TransferMimeType validation+ For security reasons we had to turn off the default fallback mechanism of the + MimeType, ExcludeMimeType, + IsCompressed and IsImage validators. + This means, that if the fileInfo or + magicMime extensions can not be found, the validation will + always fail. + + ++ If you are in need of validation by using the HTTP fields which + are provided by the user then you can turn on this feature by using the + enableHeaderCheck() method. + + ++ + Example #1 Allow the usage of the HTTP fields
Zend_Filter+ Prior to the 1.9 release, Zend_Filter allowed + the usage of the static get() method. As with + release 1.9 this method has been renamed to + filterStatic() to be more descriptive. The + old get() method is marked as deprecated. + +Zend_Http_ClientChanges to internal uploaded file information storage+ In version 1.9 of Zend Framework, there has been a change in the way + Zend_Http_Client internally stores information about + files to be uploaded, set using the + Zend_Http_Client::setFileUpload() method. + + ++ This change was introduced in order to allow multiple files to be uploaded + with the same form name, as an array of files. More information about this issue + can be found in » this bug report. + + +Example #2 Internal storage of uploaded file information
+ As you can see, this change permits the usage of the same form element name with + more than one file - however, it introduces a subtle backwards-compatibility change + and as such should be noted. + +Deprecation of Zend_Http_Client::_getParametersRecursive()+ Starting from version 1.9, the protected method + _getParametersRecursive() is no longer used by + Zend_Http_Client and is deprecated. Using it will cause an + E_NOTICE message to be emitted by PHP. + + ++ If you subclass Zend_Http_Client and call this method, you + should look into using the + Zend_Http_Client::_flattenParametersArray() static method + instead. + + ++ Again, since this _getParametersRecursive() is a protected + method, this change will only affect users who subclass + Zend_Http_Client. + +Zend_LocaleDeprecated methods+ Some specialized translation methods have been deprecated because they duplicate + existing behaviour. Note that the old methods will still work, but a user notice is + triggered which describes the new call. The methods will be erased with 2.0. + See the following list for old and new method call. + + +
Security fixes as with 1.9.7+ Additionally, users of the 1.9 series may be affected by other changes starting in + version 1.9.7. These are all security fixes that also have potential backwards + compatibility implications. + + +Zend_Dojo_View_Helper_Editor+ A slight change was made in the 1.9 series to modify the default usage of the Editor + dijit to use div tags instead of a textarea + tag; the latter usage has » security + implications, and usage of div tags is recommended by the + Dojo project. + + ++ In order to still allow graceful degradation, a new degrade + option was added to the view helper; this would allow developers to optionally use a + textarea instead. However, this opens applications developed with + that usage to XSS vectors. In 1.9.7, we have removed this option. + Graceful degradation is still supported, however, via a noscript + tag that embeds a textarea. This solution addressess all security + concerns. + + ++ The takeaway is that if you were using the degrade flag, it will + simply be ignored at this time. + +Zend_Filter_HtmlEntities+ In order to default to a more secure character encoding, + Zend_Filter_HtmlEntities now defaults to + UTF-8 instead of ISO-8859-1. + + ++ Additionally, because the actual mechanism is dealing with character encodings and + not character sets, two new methods have been added, + setEncoding() and getEncoding(). + The previous methods setCharSet() and + setCharSet() are now deprecated and proxy to the new + methods. Finally, instead of using the protected members directly within the + filter() method, these members are retrieved by their + explicit accessors. If you were extending the filter in the past, please check your + code and unit tests to ensure everything still continues to work. + +Zend_Filter_StripTags+ Zend_Filter_StripTags contains a flag, + commentsAllowed, that, in previous versions, allowed you to + optionally whitelist HTML comments in HTML + text filtered by the class. However, this opens code enabling the flag to + XSS attacks, particularly in Internet Explorer (which allows + specifying conditional functionality via HTML comments). Starting + in version 1.9.7 (and backported to versions 1.8.5 and 1.7.9), the + commentsAllowed flag no longer has any meaning, and all + HTML comments, including those containing other + HTML tags or nested commments, will be stripped from the final + output of the filter. + ++ +
|
+
+
|
+
+
+
+
+ Zend Gdata Migration NotesTable of Contents + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+ Class Loading+ Anyone who ever performs profiling of a Zend Framework application will + immediately recognize that class loading is relatively expensive in Zend + Framework. Between the sheer number of class files that need to be + loaded for many components, to the use of plugins that do not have a 1:1 + relationship between their class name and the file system, the various + calls to include_once() and + require_once() can be problematic. This chapter intends to provide + some concrete solutions to these issues. + + +How can I optimize my include_path?+ One trivial optimization you can do to increase the speed of class + loading is to pay careful attention to your include_path. In + particular, you should do four things: use absolute paths (or paths + relative to absolute paths), reduce the number of include paths you + define, have your Zend Framework include_path as early as possible, + and only include the current directory path at the end of your + include_path. + + +Use absolute paths+ While this may seem a micro-optimization, the fact is that if + you don't, you'll get very little benefit from PHP's realpath + cache, and as a result, opcode caching will not perform nearly + as you may expect. + + ++ There are two easy ways to ensure this. First, you can hardcode + the paths in your php.ini, httpd.conf, + or .htaccess. Second, you + can use PHP's realpath() function when + setting your include_path: + + +
+ You can use relative paths -- so long as + they are relative to an absolute path: + + +
+
+
+ + However, even so, it's typically a trivial task to simply pass + the path to realpath(). + +Reduce the number of include paths you define+ Include paths are scanned in the order in which they appear in + the include_path. Obviously, this means that you'll get a result + faster if the file is found on the first scan rather than the + last. Thus, a rather obvious enhancement is to simply reduce the + number of paths in your include_path to only what you need. Look + through each include_path you've defined, and determine if you + actually have any functionality in that path that is used in + your application; if not, remove it. + + ++ Another optimization is to combine paths. For instance, Zend + Framework follows PEAR naming conventions; thus, if you are + using PEAR libraries (or libraries from another framework or + component library that follows PEAR CS), try to put all of these + libraries on the same include_path. This can often be achieved + by something as simple as symlinking one or more libraries into + a common directory. + +Define your Zend Framework include_path as early as possible+ Continuing from the previous suggestion, another obvious + optimization is to define your Zend Framework include_path as + early as possible in your include_path. In most cases, it should + be the first path in the list. This ensures that files included + from Zend Framework are found on the first scan. + +Define the current directory last, or not at all+ Most include_path examples show using the current directory, or + '.'. This is convenient for ensuring that scripts in the same + directory as the file requiring them can be loaded. However, + these same examples typically show this path item as the first + item in the include_path -- which means that the current + directory tree is always scanned first. In most cases, with Zend + Framework applications, this is not desired, and the path may be + safely pushed to the last item in the list. + + +Example #1 Example: Optimized include_path + Let's put all of these suggestions together. Our assumption will be that you + are using one or more PEAR libraries in conjunction with + Zend Framework -- perhaps the PHPUnit and Archive_Tar + libraries -- and that you occasionally need to include + files relative to the current file. + + First, we'll create a library directory in our project. Inside that + directory, we'll symlink our Zend Framework's library/Zend + directory, as well as the necessary directories from our PEAR + installation: +
+ This allows us to add our own library code if necessary, while + keeping shared libraries intact. + + Next, we'll opt to create our include_path programmatically + within our public/index.php file. This allows us to move + our code around on the file system, without needing to edit the + include_path every time. + + We'll borrow ideas from each of the suggestions above: we'll use + absolute paths, as determined using realpath(); + we'll include Zend Framework's include path early; we've + already consolidated include_paths; and we'll put the current + directory as the last path. In fact, we're doing really well + here -- we're going to end up with only two paths. +
How can I eliminate unnecessary require_once statements?+ Lazy loading is an optimization technique designed to push the + expensive operation of loading a class file until the last possible + moment -- i.e., when instantiating an object of that class, calling + a static class method, or referencing a class constant or static + property. PHP supports this via autoloading, which allows you to + define one or more callbacks to execute in order to map a class name + to a file. + + ++ However, most benefits you may reap from autoloading are negated if + your library code is still performing require_once() calls -- + which is precisely the case with Zend Framework. So, the question is: how can + you eliminate those require_once() calls in order to maximize + autoloader performance? + + +Strip require_once calls with find and sed+ An easy way to strip require_once() calls is to use the + UNIX utilities 'find' and 'sed' in conjunction to comment out + each call. Try executing the following statements (where '%' + indicates the shell prompt): + + +
+ This one-liner (broken into two lines for readability) iterates + through each PHP file and tells it to replace each instance of + 'require_once' with '// require_once', effectively commenting + out each such statement. (It selectively keeps + require_once() calls within + Zend_Application and + Zend_Loader_Autoloader, as these classes will fail without + them.) + + ++ This command could be added to an automated build or release + process trivially, helping boost performance in your production + application. It should be noted, however, that if you use this + technique, you must utilize autoloading; + you can do that from your "public/index.php" file with the + following code: + + +
How can I speed up plugin loading?+ Many components have plugins, which allow you to create your own + classes to utilize with the component, as well as to override + existing, standard plugins shipped with Zend Framework. This + provides important flexibility to the framework, but at a price: + plugin loading is a fairly expensive task. + + ++ The plugin loader allows you to register class prefix / path pairs, + allowing you to specify class files in non-standard paths. Each + prefix can have multiple paths associated with it. + Internally, the plugin loader loops through each prefix, and then + through each path attached to it, testing to see if the file exists + and is readable on that path. It then loads it, and tests to see + that the class it is looking for is available. As you might imagine, + this can lead to many stat calls on the file system. + + ++ Multiply this by the number of components that use the PluginLoader, + and you get an idea of the scope of this issue. At the time of this + writing, the following components made use of the PluginLoader: + + +
+ How can you reduce the number of such calls made? + + +Use the PluginLoader include file cache+ Zend Framework 1.7.0 adds an include file cache to the + PluginLoader. This functionality writes " include_once()" + calls to a file, which you can then include in your bootstrap. While this + introduces extra include_once() calls to your code, it + also ensures that the PluginLoader returns as early as possible. + + ++ The PluginLoader documentation includes + a complete example of its use. + ++ +
|
+ + + | +
+
+ Zend_Db Performance+ Zend_Db is a database abstraction layer, and is intended to + provide a common API for SQL operations. + Zend_Db_Table is a + Table Data Gateway, intended to abstract common table-level database + operations. Due to their abstract nature and the "magic" they do under + the hood to perform their operations, they can sometimes introduce + performance overhead. + + +How can I reduce overhead introduced by Zend_Db_Table for + retrieving table metadata?+ In order to keep usage as simple as possible, and also to support + constantly changing schemas during development, + Zend_Db_Table does some magic under the hood: on + first use, it fetches the table schema and stores it within object + members. This operation is typically expensive, regardless of the + database -- which can contribute to bottlenecks in production. + + ++ Fortunately, there are techniques for improving the situation. + + +Use the metadata cache+ Zend_Db_Table can optionally utilize + Zend_Cache to cache table metadata. This is + typically faster to access and less expensive than fetching the + metadata from the database itself. + + ++ The Zend_Db_Table + documentation includes information on metadata caching. + +Hardcode your metadata in the table definition+ As of 1.7.0, Zend_Db_Table also provides support + for hardcoding metadata in the table definition. This is + an advanced use case, and should only be used when you know the + table schema is unlikely to change, or that you're able to keep + the definitions up-to-date. + ++ SQL generated with Zend_Db_Select s not hitting my indexes; how can I make it better? ++ Zend_Db_Select is relatively good at its job. However, + if you are performing complex queries requiring joins or + sub-selects, it can often be fairly naive. + + +Write your own tuned SQL+ The only real answer is to write your own SQL; + Zend_Db does not require the usage of + Zend_Db_Select, so providing your own, tuned + SQL select statements is a perfectly legitimate approach, + + ++ Run EXPLAIN on your queries, and test a variety of + approaches until you can reliably hit your indices in the most + performant way -- and then hardcode the SQL as a class property + or constant. + + ++ If the SQL requires variable arguments, provide placeholders in + the SQL, and utilize a combination of + vsprintf() and array_map() to + inject the values into the SQL: + + + + ++ +
|
+ + + | +
+
+
+
+ Zend Gdata Performance GuideTable of Contents + + + + + + ++ +
|
+
+
|
+
+
+ Introduction+ The purpose of this appendix is to provide some concrete strategies for + improving the performance of your Zend Framework applications. The guide + is presented in a "Question and Answer" format, and broken into areas of + concern. + ++ +
|
+ + + | +
+
+ Internationalization (i18n) and Localization (l10n)+ Internationalizing and localizing a site are fantastic ways to expand + your audience and ensure that all visitors can get to the information + they need. However, it often comes with a performance penalty. Below + are some strategies you can employ to reduce the overhead of i18n and + l10n. + + +Which translation adapter should I use?+ Not all translation adapters are made equal. Some have more + features than others, and some perform better than others. + Additionally, you may have business requirements that force you to + use a particular adapter. However, if you have a choice, which + adapters are fastest? + + +Use non-XML translation adapters for greatest speed+ Zend Framework ships with a variety of translation adapters. + Fully half of them utilize an XML format, incurring memory and + performance overhead. Fortunately, there are several adapters + that utilize other formats that can be parsed much more + quickly. In order of speed, from fastest to slowest, they are: + + +
+ If high performance is one of your concerns, we suggest + utilizing one of the above adapters. + +How can I make translation and localization even faster?+ Maybe, for business reasons, you're limited to an XML-based + translation adapter. Or perhaps you'd like to speed things up even + more. Or perhaps you want to make l10n operations faster. How can + you do this? + + +Use translation and localization caches+ Both Zend_Translate and Zend_Locale + implement caching functionality that can greatly affect + performance. In the case of each, the major bottleneck is + typically reading the files, not the actual lookups; using a + cache eliminates the need to read the translation and/or + localization files. + + ++ You can read about caching of translation and localization + strings in the following locations: + + +
+ +
|
+ + + | +
+
+ View Rendering+ When using Zend Framework's MVC layer, chances are you will be using + Zend_View. Zend_View is performs well + compared to other view or templating engines; since view scripts + are written in PHP, you do not incur the overhead of compiling custom + markup to PHP, nor do you need to worry that the compiled + PHP is not optimized. However, Zend_View presents + its own issues: extension is done via overloading (view helpers), and a number of view + helpers, while carrying out key functionality do so with a performance + cost. + + +How can I speed up resolution of view helpers?+ Most Zend_View "methods" are actually provided via + overloading to the helper system. This provides important flexibility to + Zend_View; instead of needing to extend + Zend_View and provide all the helper methods you may + utilize in your application, you can define your helper methods in separate + classes and consume them at will as if they were direct methods of + Zend_View. This keeps the view object itself relatively + thin, and ensures that objects are created only when needed. + + ++ Internally, Zend_View uses the PluginLoader to look + up helper classes. This means that for each helper you call, + Zend_View needs to pass the helper name to the + PluginLoader, which then needs to determine the class name, load the + class file if necessary, and then return the class name so it may be + instantiated. Subsequent uses of the helper are much faster, as + Zend_View keeps an internal registry of loaded helpers, + but if you use many helpers, the calls add up. + + ++ The question, then, is: how can you speed up helper resolution? + + +Use the PluginLoader include file cache+ The simplest, cheapest solution is the same as for general + PluginLoader performance: use + the PluginLoader include file cache. Anecdotal + evidence has shown this technique to provide a 25-30% + performance gain on systems without an opcode cache, and a + 40-65% gain on systems with an opcode cache. + +Extend Zend_View to provide often used helper methods+ Another solution for those seeking to tune performance even + further is to extend Zend_View to manually add the + helper methods they most use in their application. Such helper + methods may simply manually instantiate the appropriate helper + class and proxy to it, or stuff the full helper implementation + into the method. + + +
+ Either way, this technique will substantially reduce the + overhead of the helper system by avoiding calls to the + PluginLoader entirely, and either benefiting from autoloading or + bypassing it altogether. + +How can I speed up view partials?+ Those who use partials heavily and who profile their applications + will often immediately notice that the partial() view + helper incurs a lot of overhead, due to the need to clone the view + object. Is it possible to speed this up? + + +Use partial() only when really necessary+ The partial() view helper accepts three arguments: + + +
+ The power and use of partial() come from the second + and third arguments. The $module argument allows + partial() to temporarily add a script path for the + given module so that the partial view script will resolve to + that module; the $model argument allows you to + explicitly pass variables for use with the partial view. + If you're not passing either argument, use + render() instead! + + ++ Basically, unless you are actually passing variables to the + partial and need the clean variable scope, or rendering a view + script from another MVC module, there is no reason to incur the + overhead of partial(); instead, use + Zend_View's built-in render() + method to render the view script. + +How can I speed up calls to the action() view helper?+ Version 1.5.0 introduced the action() view helper, + which allows you to dispatch an MVC action and capture its rendered + content. This provides an important step towards the DRY principle, + and promotes code reuse. However, as those who profile their + applications will quickly realize, it, too, is an expensive + operation. Internally, the action() view helper needs + to clone new request and response objects, invoke the dispatcher, + invoke the requested controller and action, etc. + + ++ How can you speed it up? + + +Use the ActionStack when possible+ Introduced at the same time as the action() view + helper, the ActionStack + consists of an action helper and a front controller plugin. + Together, they allow you to push additional actions to invoke + during the dispatch cycle onto a stack. If you are calling + action() from your layout view scripts, you may + want to instead use the ActionStack, and render your views to + discrete response segments. As an example, you could write a + dispatchLoopStartup() plugin like the following to + add a login form box to each page: + + +
+ The UserController::indexAction() method might then + use the $responseSegment parameter to indicate which + response segment to render to. In the layout script, you would + then simply render that response segment: + + +
+ While the ActionStack still requires a dispatch cycle, this is + still cheaper than the action() view helper as it + does not need to clone objects and reset internal state. + Additionally, it ensures that all pre and post dispatch plugins are + invoked, which may be of particular concern if you are using + front controller plugins for handling ACL's to particular + actions. + +Favor helpers that query the model over action()+ In most cases, using action() is simply overkill. + If you have most business logic nested in your models and are + simply querying the model and passing the results to a view + script, it will typically be faster and cleaner to simply write + a view helper that pulls the model, queries it, and does + something with that information. + + ++ As an example, consider the following controller action and view + script: + + +
+ Using action(), you would then invoke it with the + following: + + +
+ This could be refactored to a view helper that looks like the + following: + + +
+ You would then invoke the helper as follows: + + +
+ This has two benefits: it no longer incurs the overhead of the + action() view helper, and also presents a more + semantically understandable API. + ++ +
|
+ + + | +
+
+ Module Structure+ The directory structure for modules should mimic that of the + application/ directory in the recommended project structure: + + +
+ The purpose of these directories remains exactly the same as for the recommended + project directory structure. + ++ +
|
+ + + | +
+
+ Recommended Project Structure for Zend Framework MVC ApplicationsTable of Contents ++ +
|
+
+
|
+
+
+ Overview+ Many developers seek guidance on the best project structure for a Zend Framework project + in a relatively flexible environment. A "flexible" environment is one in which the + developer can manipulate their file systems and web server configurations as needed to + achieve the most ideal project structure to run and secure their application. The + default project structure will assume that the developer has such flexibility at their + disposal. + + ++ The following directory structure is designed to be maximally extensible for complex + projects, while providing a simple subset of folder and files for project with simpler + requirements. This structure also works without alteration for both modular and + non-modular Zend Framework applications. The .htaccess files + require URL rewrite functionality in the web server as described in + the Rewrite Configuration Guide, also + included in this appendix. + + ++ It is not the intention that this project structure will support all possible Zend + Framework project requirements. The default project profile used by + Zend_Tool reflect this project structure, but applications with + requirements not supported by this structure should use a custom project profile. + ++ +
|
+ + + | +
+
+ Recommended Project Directory Structure
+ The following describes the use cases for each directory as listed. + + +
+ +
|
+ + + | +
+
+ Rewrite Configuration Guide+ URL rewriting is a common function of HTTP + servers. However, the rules and configuration differ widely between them. Below are + some common approaches across a variety of popular web servers available at the time of + writing. + + +Apache HTTP Server+ All examples that follow use mod_rewrite, an official + module that comes bundled with Apache. To use it, + mod_rewrite must either be included at compile time or + enabled as a Dynamic Shared Object (DSO). Please consult the + » Apache documentation for your + version for more information. + + +Rewriting inside a VirtualHost+ Here is a very basic virtual host definition. These rules direct all requests + to index.php, except when a matching file is found under + the document_root. + + +
+ Note the slash ("/") prefixing index.php; the rules for + .htaccess differ in this regard. + +Rewriting within a .htaccess file+ Below is a sample .htaccess file that utilizes + mod_rewrite. It is similar to the virtual host + configuration, except that it specifies only the rewrite rules, and the leading + slash is omitted from index.php. + + +
+ There are many ways to configure mod_rewrite; if you + would like more information, see Jayson Minard's » Blueprint for PHP Applications: + Bootstrapping. + +Microsoft Internet Information Server+ As of version 7.0, IIS now ships with a standard rewrite engine. + You may use the following configuration to create the appropriate rewrite rules. + + +
+ +
|
+ + + | +
+
+ Zend Framework RequirementsTable of Contents
+ +
|
+
+
|
+
+
+ Introduction+ Zend Framework requires a PHP 5 interpreter with a web server + configured to handle PHP scripts correctly. Some features require + additional extensions or web server features; in most cases the framework can be used + without them, although performance may suffer or ancillary features may not be fully + functional. An example of such a dependency is mod_rewrite in an Apache environment, + which can be used to implement "pretty URL's" like + "http://www.example.com/user/edit". If mod_rewrite is not enabled, + Zend Framework can be configured to support URL's such as + "http://www.example.com?controller=user&action=edit". Pretty + URL's may be used to shorten URL's for textual + representation or search engine optimization (SEO), but they do not + directly affect the functionality of the application. + + +PHP Version+ Zend recommends the most current release of PHP for critical + security and performance enhancements, and currently supports + PHP 5.2.11 or later. + + ++ Zend Framework has an extensive collection of unit tests, which you can run using + PHPUnit 3.4.15 or later. + +PHP Extensions+ You will find a table listing all extensions typically found in + PHP and how they are used in Zend Framework below. You should + verify that the extensions on which Zend Framework components you'll be using in + your application are available in your PHP environments. Many + applications will not require every extension listed below. + + ++ A dependency of type "hard" indicates that the components or classes + cannot function properly if the respective extension is not available, + while a dependency of type "soft" indicates that the component may use + the extension if it is available but will function properly if it is not. + Many components will automatically use certain extensions if they are available + to optimize performance but will execute code with similar functionality in the + component itself if the extensions are unavailable. + + +
Zend Framework Components+ Below is a table that lists all available Zend Framework Components + and which PHP extension they need. This can help guide you + to know which extensions are required for your application. + Not all extensions used by Zend Framework are required for every + application. + + ++ A dependency of type "hard" indicates that the components or classes + cannot function properly if the respective extension is not available, + while a dependency of type "soft" indicates that the component may use + the extension if it is available but will function properly if it is not. + Many components will automatically use certain extensions if they are available + to optimize performance but will execute code with similar functionality in the + component itself if the extensions are unavailable. + + +
Zend Framework Dependencies+ Below you can find a table listing Zend Framework Components + and their dependencies to other Zend Framework Components. This + can help you if you need to have only single components instead + of the complete Zend Framework. + + ++ A dependency of type "hard" indicates that the components or classes + cannot function properly if the respective dependent component is not available, + while a dependency of type "soft" indicates that the component may need + the dependent component in special situations or with special adapters. + At last a dependency of type "fix" indicated that these components or classes are + in any case used by subcomponents, and a dependency of type "sub" indicates that + these components can be used by subcomponents in special situations or with special + adapters. + + ++ +
+ +
|
+ + + | +
+
+
+
+ Zend_Acl+ + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Amf+ + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Application+ + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Auth+ + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Barcode+ + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Cache+ + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Captcha+ + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ SimpleCloud API: Zend_Cloud+ + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_CodeGenerator+ + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Config+ + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Config_Writer+ + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Console_Getopt+ + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Controller+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Currency+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Date+ + + + + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Db+ + + + + + + + + + + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Debug+ + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Dojo+ + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Dom+ + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_EventManager+ + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Exception+ + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Feed+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_File+ + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Filter+ + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Form+ + + + + + + + + + + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+ Using Google Analytics+ The Google Analytics API allows client applications to + request data, saved in the analytics accounts. + + ++ See » http://code.google.com/apis/analytics/docs/gdata/v2/gdataOverview.html + for more information about the Google Analytics API. + + +Retrieving account data+ Using the account feed, you are able to retrieve a list of all the accounts available to a specified user. + + +
+ The $analytics->getAccountFeed() call, results in a + Zend_Gdata_Analytics_AccountFeed object that contains + Zend_Gdata_Analytics_AccountEntry objects. Each of this + objects represent a google analytics account. + +Retrieving report data+ Besides the account feed, google offers a data feed, to retrieve report data using + the Google Analytics API. To easily request for these reports, + Zend_Gdata_Analytics offers a simple query construction interface. You can use all + the » metrics + and dimensions specified by the API. Additionaly you can apply some » filters + to retrieve some » common + data or even complex results. + + +
+ +
|
+
+
|
+
+
+ Authenticating with AuthSub+ The AuthSub mechanism enables you to write web applications + that acquire authenticated access Google Data services, + without having to write code that handles user credentials. + + ++ See » http://code.google.com/apis/accounts/AuthForWebApps.html + for more information about Google Data AuthSub authentication. + + ++ The Google documentation says the ClientLogin mechanism is appropriate + for "installed applications" whereas the AuthSub mechanism is + for "web applications." The difference is that AuthSub requires + interaction from the user, and a browser interface that can react + to redirection requests. The ClientLogin solution uses PHP code to + supply the account credentials; the user is not required to enter her + credentials interactively. + + ++ The account credentials supplied via the AuthSub mechanism are + entered by the user of the web application. Therefore they must be + account credentials that are known to that user. + + ++ + Creating an AuthSub authenticated Http Client+ Your PHP application should provide a hyperlink to the + Google URL that performs authentication. The static function + Zend_Gdata_AuthSub::getAuthSubTokenUri() + provides the correct URL. The arguments to this function include + the URL to your PHP application so that Google can + redirect the user's browser back to your application after the user's + credentials have been verified. + + ++ After Google's authentication server redirects the user's browser + back to the current application, a GET request parameter is set, + called token. The value of this parameter is a single-use token + that can be used for authenticated access. This token can be converted into a multi-use + token and stored in your session. + + ++ Then use the token value in a call to + Zend_Gdata_AuthSub::getHttpClient(). + This function returns an instance of Zend_Http_Client, + with appropriate headers set so that subsequent requests your + application submits using that HTTP Client are also authenticated. + + ++ Below is an example of PHP code for a web application + to acquire authentication to use the Google Calendar service + and create a Zend_Gdata client object using that authenticated + HTTP Client. + + +
Revoking AuthSub authentication+ To terminate the authenticated status of a given token, use the + Zend_Gdata_AuthSub::AuthSubRevokeToken() + static function. Otherwise, the token is still valid for + some time. + + +
+ + +
|
+
+
|
+
+
+ Using the Book Search Data API+ The Google Book Search Data API allows client applications to view + and update Book Search content in the form of Google Data API feeds. + + ++ Your client application can use the Book Search Data API to issue + full-text searches for books and to retrieve standard book information, + ratings, and reviews. You can also access individual users' + » library collections and + public reviews. Finally, your application can submit authenticated requests + to enable users to create and modify library collections, ratings, labels, + reviews, and other account-specific entities. + + ++ For more information on the Book Search Data API, please refer to the + official » PHP + Developer's Guide on code.google.com. + + +Authenticating to the Book Search service+ You can access both public and private feeds using the Book Search + Data API. Public feeds don't require any authentication, but they are + read-only. If you want to modify user libraries, submit reviews or + ratings, or add labels, then your client needs to authenticate before + requesting private feeds. It can authenticate using either of two + approaches: AuthSub proxy authentication or ClientLogin username/password + authentication. Please refer to the » Authentication + section in the PHP Developer's Guide for more detail. + +Searching for books+ The Book Search Data API provides a number of feeds that list + collections of books. + + ++ The most common action is to retrieve a list of books that match a + search query. To do so you create a VolumeQuery object + and pass it to the Books::getVolumeFeed() method. + + ++ For example, to perform a keyword query, with a filter on + viewability to restrict the results to partial or full view books, use + the setMinViewability() and setQuery() + methods of the VolumeQuery object. The following code snippet + prints the title and viewability of all volumes whose metadata or text matches + the query term "domino": + + +
+ The Query class, and subclasses like + VolumeQuery, are responsible for constructing feed + URLs. The VolumeQuery shown above constructs a URL + equivalent to the following: + + +
+ Note: Since Book Search results are + public, you can issue a Book Search query without authentication. + + ++ Here are some of the most common VolumeQuery + methods for setting search parameters: + + ++ setQuery(): Specifies a search + query term. Book Search searches all book metadata and full text for + books matching the term. Book metadata includes titles, keywords, + descriptions, author names, and subjects. + Note that any spaces, quotes or other punctuation in the parameter + value must be URL-escaped (Use a plus (+) for a + space). To search for an exact phrase, enclose the phrase in quotation marks. + For example, to search for books matching the phrase "spy plane", set + the q parameter to %22spy+plane%22. + You can also use any of the » + advanced search operators supported by Book Search. For example, + jane+austen+-inauthor:austen returns matches that mention + (but are not authored by) Jane Austen. + + ++ setStartIndex(): Specifies + the index of the first matching result that should be included in the + result set. This parameter uses a one-based index, meaning the first + result is 1, the second result is 2 and so forth. This parameter works + in conjunction with the max-results + parameter to determine which results to return. For example, to + request the third set of 10 results—results 21-30—set + the start-index parameter to 21 and the + max-results parameter to 10. + Note: This isn't a general cursoring + mechanism. If you first send a query with + ?start-index=1&max-results=10 and then send another + query with ?start-index=11&max-results=10, the + service cannot guarantee that the results are equivalent to + ?start-index=1&max-results=20, because insertions and + deletions could have taken place in between the two queries. + + ++ setMaxResults(): + Specifies the maximum number of results that should be included + in the result set. This parameter works in conjunction with the + start-index parameter to determine which + results to return. The default value of this parameter is + 10 and the maximum value is 20. + + ++ setMinViewability(): Allows you to filter the results according + to the books' » viewability + status. This parameter accepts one of three values: + 'none' (the default, returning all matching books regardless of + viewability), 'partial_view' (returning only books + that the user can preview or view in their entirety), or + 'full_view' (returning only books that the user can + view in their entirety). + + +Partner Co-Branded Search+ Google Book Search provides » Co-Branded + Search, which lets content partners provide full-text search of + their books from their own websites. + + ++ If you are a partner who wants to do Co-Branded Search using the + Book Search Data API, you may do so by modifying the feed + URL above to point to your Co-Branded Search implementation. if, + for example, a Co-Branded Search is available at the following + URL: + + +
+ then you can obtain the same results using the Book Search Data + API at the following URL: + + +
+ To specify an alternate URL when querying a volume feed, you can + provide an extra parameter to newVolumeQuery() + + +
+ For additional information or support, visit our + » Partner help center. + +Using community featuresAdding a rating+ A user can add a rating to a book. Book Search uses a 1-5 + rating system in which 1 is the lowest rating. Users cannot + update or delete ratings. + + ++ To add a rating, add a Rating object to a + VolumeEntry and post it to the annotation feed. In the + example below, we start from an empty VolumeEntry object. + + +
Reviews+ In addition to ratings, authenticated users can submit reviews or + edit their reviews. For information on how to request previously + submitted reviews, see » Retrieving annotations. + + +Adding a review+ To add a review, add a Review object to a + VolumeEntry and post it to the annotation + feed. In the example below, we start from an existing + VolumeEntry object. + + +
Editing a review+ To update an existing review, first you retrieve the + review you want to update, then you modify it, and + then you submit it to the annotation feed. + + +
Labels+ You can use the Book Search Data API to label volumes with + keywords. A user can submit, retrieve and modify labels. See + » Retrieving + annotations for how to read previously submitted labels. + + +Submitting a set of labels+ To submit labels, add a Category object + with the scheme LABELS_SCHEME to a + VolumeEntry and post it to the annotation feed. + + +
Retrieving annotations: reviews, ratings, and labels+ You can use the Book Search Data API to retrieve annotations + submitted by a given user. Annotations include reviews, ratings, and + labels. To retrieve any user's annotations, you can send an + unauthenticated request that includes the user's user ID. To retrieve the + authenticated user's annotations, use the value me as the user + ID. + + +
+ For a list of the supported query parameters, see the + » query parameters + section. + +Deleting Annotations+ If you retrieved an annotation entry containing ratings, + reviews, and/or labels, you can remove all annotations + by calling deleteVolume() on that entry. + + +
Book collections and My Library+ Google Book Search provides a number of user-specific + book collections, each of which has its own feed. + + ++ The most important collection is the user's My Library, which + represents the books the user would like to remember, organize, and + share with others. This is the collection the user sees when accessing + his or her » My Library + page. + + +Retrieving books in a user's library+ The following sections describe how to retrieve a list + of books from a user's library, with or without query + parameters. + + ++ You can query a Book Search public feed without authentication. + + +Retrieving all books in a user's library+ To retrieve the user's books, send a query to the + My Library feed. To get the library of the authenticated + user, use me in place of USER_ID. + + +
+ Note: The feed may not contain all of the user's books, because + there's a default limit on the number of results returned. For + more information, see the max-results query parameter in + » Searching for books. + +Searching for books in a user's library+ Just as you can » search across all books, + you can do a full-text search over just the books in a + user's library. To do this, just set the appropriate + paramters on the VolumeQuery object. + + ++ For example, the following query returns all the books in + your library that contain the word "bear": + + +
+ For a list of the supported query parameters, see the + » query parameters + section. In addition, you can search for books that have been + » labeled by the user: + + +
Updating books in a user's library+ You can use the Book Search Data API to add a book to, or remove + a book from, a user's library. Ratings, reviews, and labels are valid + across all the collections of a user, and are thus edited using the + annotation feed (see » Using community features). + + +Adding a book to a library+ After authenticating, you can add books to the current user's library. + + ++ You can either create an entry from scratch if you + know the volume ID, or insert an entry read from any feed. + + ++ The following example creates a new entry and adds it to the library: + + +
+ The following example adds an existing + VolumeEntry object to the library: + + +
Removing a book from a library+ To remove a book from a user's library, call + deleteVolume() on the + VolumeEntry object. + + +
+ +
|
+
+
|
+
+
+ Using Google Calendar+ You can use the + Zend_Gdata_Calendar + class to view, create, update, and delete events in the online Google Calendar service. + + ++ See » + http://code.google.com/apis/calendar/overview.html + for more information about the Google Calendar API. + + +Connecting To The Calendar Service+ The Google Calendar API, like all GData APIs, is + based off of the Atom Publishing Protocol (APP), an XML based format + for managing web-based resources. Traffic between a client and the Google Calendar + servers occurs over HTTP and allows for both authenticated and + unauthenticated connections. + + ++ Before any transactions can occur, this connection needs to be made. Creating a + connection to the calendar servers involves two steps: creating an + HTTP client and binding a Zend_Gdata_Calendar + service instance to that client. + + +Authentication+ The Google Calendar API allows access to both public and private + calendar feeds. Public feeds do not require authentication, but are read-only and + offer reduced functionality. Private feeds offers the most complete functionality + but requires an authenticated connection to the calendar servers. There are three + authentication schemes that are supported by Google Calendar: + + +
+ The Zend_Gdata + library provides support for all three authentication schemes. + The rest of this chapter will assume that you are familiar the + authentication schemes available and how to create an + appropriate authenticated connection. For more information, + please see section the Authentication section + of this manual or the » Authentication Overview in the + Google Data API Developer's Guide. + +Creating A Service Instance+ In order to interact with Google Calendar, this library provides the + Zend_Gdata_Calendar service class. This class provides a + common interface to the Google Data and Atom Publishing Protocol models and assists + in marshaling requests to and from the calendar servers. + + ++ Once deciding on an authentication scheme, the next step is to create an instance + of Zend_Gdata_Calendar. The class constructor takes an + instance of Zend_Http_Client as a single argument. This + provides an interface for AuthSub and ClientAuth authentication, as both of these + require creation of a special authenticated HTTP client. If no + arguments are provided, an unauthenticated instance of + Zend_Http_Client will be automatically created. + + ++ The example below shows how to create a Calendar service class using ClientAuth + authentication: + + +
+ A Calendar service using AuthSub can be created in a similar, though slightly more + lengthy fashion: + + +
+ Finally, an unauthenticated server can be created for use with either public feeds + or MagicCookie authentication: + + +
+ Note that MagicCookie authentication is not supplied with the + HTTP connection, but is instead specified along with the desired + visibility when submitting queries. See the section on retrieving events below for + an example. + +Retrieving A Calendar List+ The calendar service supports retrieving a list of calendars for the authenticated + user. This is the same list of calendars which are displayed in the Google Calendar + UI, except those marked as "hidden" are also available. + + ++ The calendar list is always private and must be accessed over an authenticated + connection. It is not possible to retrieve another user's calendar list and it cannot + be accessed using MagicCookie authentication. Attempting to access a calendar list + without holding appropriate credentials will fail and result in a 401 (Authentication + Required) status code. + + +
+ Calling getCalendarListFeed() creates a new instance of + Zend_Gdata_Calendar_ListFeed containing each available calendar + as an instance of Zend_Gdata_Calendar_ListEntry. After retrieving + the feed, you can use the iterator and accessors contained within the feed to inspect + the enclosed calendars. + + + + +Retrieving Events+ Like the list of calendars, events are also retrieved using the + Zend_Gdata_Calendar service class. The event list returned is of + type Zend_Gdata_Calendar_EventFeed and contains each event as an + instance of Zend_Gdata_Calendar_EventEntry. As before, the + iterator and accessors contained within the event feed instance allow inspection of + individual events. + + +Queries+ When retrieving events using the Calendar API, specially + constructed query URLs are used to describe what events should be + returned. The Zend_Gdata_Calendar_EventQuery class simplifies + this task by automatically constructing a query URL based on + provided parameters. A full list of these parameters is available at the » Queries section + of the Google Data APIs Protocol Reference. However, + there are three parameters that are worth special attention: + + +
Retrieving Events In Order Of Start Time+ The example below illustrates the use of the Zend_Gdata_Query + class and specifies the private visibility feed, which requires that an + authenticated connection is available to the calendar servers. If a MagicCookie is + being used for authentication, the visibility should be instead set to + "private-magicCookieValue", where magicCookieValue is the + random string obtained when viewing the private XML address in + the Google Calendar UI. Events are requested chronologically by start time and only + events occurring in the future are returned. + + +
+ Additional properties such as ID, author, when, event status, visibility, web + content, and content, among others are available within + Zend_Gdata_Calendar_EventEntry. Refer to the + » Zend Framework + API Documentation and the + » Calendar Protocol + Reference for a complete list. + +Retrieving Events In A Specified Date Range+ To print out all events within a certain range, for example from December 1, + 2006 through December 15, 2007, add the following two lines to the previous sample. + Take care to remove "$query->setFutureevents('true')", since + futureevents will override startMin and + startMax. + + +
+ Note that startMin is inclusive whereas + startMax is exclusive. As a result, only events through + 2006-12-15 23:59:59 will be returned. + +Retrieving Events By Fulltext Query+ To print out all events which contain a specific word, for example "dogfood", use + the setQuery() method when creating the query. + + +
Retrieving Individual Events+ Individual events can be retrieved by specifying their event ID as part of the + query. Instead of calling getCalendarEventFeed(), + getCalendarEventEntry() should be called instead. + + +
+ In a similar fashion, if the event URL is known, it can be passed + directly into getCalendarEntry() to retrieve a specific + event. In this case, no query object is required since the event + URL contains all the necessary information to retrieve the event. + + +
Creating EventsCreating Single-Occurrence Events+ Events are added to a calendar by creating an instance of + Zend_Gdata_EventEntry and populating it with the appropriate + data. The calendar service instance (Zend_Gdata_Calendar) is + then used to used to transparently covert the event into XML and + POST it to the calendar server. Creating events requires either an AuthSub or + ClientAuth authenticated connection to the calendar server. + + +At a minimum, the following attributes should be set: + +
Other useful attributes that may optionally set include: + +
+ For a complete list of event attributes, refer to the » Zend Framework + API Documentation and the » Calendar Protocol + Reference. Attributes that can contain multiple values, such as where, + are implemented as arrays and need to be created accordingly. Be aware that all of + these attributes require objects as parameters. Trying instead to populate them + using strings or primitives will result in errors during conversion to + XML. + + ++ Once the event has been populated, it can be uploaded to the calendar server by + passing it as an argument to the calendar service's + insertEvent() function. + + +
Event Schedules and Reminders+ An event's starting time and duration are determined by the value of its + when property, which contains the properties + startTime, endTime, and + valueString. StartTime and + EndTime control the duration of the + event, while the valueString property is currently unused. + + ++ All-day events can be scheduled by specifying only the date omitting the time when + setting startTime and endTime. Likewise, + zero-duration events can be specified by omitting the endTime. + In all cases, date and time values should be provided in + » RFC3339 format. + + +
+ The when attribute also controls when reminders are sent to a + user. Reminders are stored in an array and each event may have up to find reminders + associated with it. + + ++ For a reminder to be valid, it needs to have two attributes + set: method and a time. Method can accept + one of the following strings: "alert", "email", or "sms". The time should be entered + as an integer and can be set with either the property minutes, + hours, days, or + absoluteTime. However, a valid request may only have one of + these attributes set. If a mixed time is desired, convert to the most precise unit + available. For example, 1 hour and 30 minutes should be entered as 90 minutes. + + +
Creating Recurring Events+ Recurring events are created the same way as single-occurrence events, except a + recurrence attribute should be provided instead of a where attribute. The + recurrence attribute should hold a string describing the event's recurrence pattern + using properties defined in the iCalendar standard (» RFC 2445). + + ++ Exceptions to the recurrence pattern will usually be specified by a distinct + recurrenceException attribute. However, the iCalendar standard + provides a secondary format for defining recurrences, and the possibility that + either may be used must be accounted for. + + ++ Due to the complexity of parsing recurrence patterns, further information on this + them is outside the scope of this document. However, more information can be found + in the » Common + Elements section of the Google Data APIs Developer + Guide, as well as in RFC 2445. + + +
Using QuickAdd+ QuickAdd is a feature which allows events to be created using free-form text entry. + For example, the string "Dinner at Joe's Diner on Thursday" would create an event + with the title "Dinner", location "Joe's Diner", and date "Thursday". To take + advantage of QuickAdd, create a new QuickAdd property set to + TRUE and store the freeform text as a + content property. + + +
Modifying Events+ Once an instance of an event has been obtained, the event's attributes can be locally + modified in the same way as when creating an event. Once all modifications are + complete, calling the event's save() method will upload the + changes to the calendar server and return a copy of the event as it was created on the + server. + + ++ In the event another user has modified the event since the local copy was retrieved, + save() will fail and the server will return a 409 (Conflict) + status code. To resolve this a fresh copy of the event must be retrieved from the server + before attempting to resubmit any modifications. + + +
Deleting Events+ Calendar events can be deleted either by calling the calendar service's + delete() method and providing the edit URL + of an event or by calling an existing event's own delete() + method. + + ++ In either case, the deleted event will still show up on a user's private event feed if + an updateMin query parameter is provided. Deleted events can be + distinguished from regular events because they will have their + eventStatus property set to + "http://schemas.google.com/g/2005#event.canceled". + + +
Accessing Event Comments+ When using the full event view, comments are not directly stored within an entry. + Instead, each event contains a URL to its associated comment feed + which must be manually requested. + + ++ Working with comments is fundamentally similar to working with events, with the only + significant difference being that a different feed and event class should be used and + that the additional meta-data for events such as where and when does not exist for + comments. Specifically, the comment's author is stored in the + author property, and the comment text is stored in the + content property. + + +
+ +
|
+
+
|
+
+
+ Authenticating with ClientLogin+ The ClientLogin mechanism enables you to write PHP application + that acquire authenticated access to Google Services, + specifying a user's credentials in the HTTP Client. + + ++ See » http://code.google.com/apis/accounts/AuthForInstalledApps.html + for more information about Google Data ClientLogin authentication. + + ++ The Google documentation says the ClientLogin mechanism is appropriate + for "installed applications" whereas the AuthSub mechanism is + for "web applications." The difference is that AuthSub requires + interaction from the user, and a browser interface that can react + to redirection requests. The ClientLogin solution uses PHP code to + supply the account credentials; the user is not required to enter her + credentials interactively. + + ++ The account credentials supplied via the ClientLogin mechanism must + be valid credentials for Google services, but they are not required + to be those of the user who is using the PHP application. + + +Creating a ClientLogin authenticated Http Client+ The process of creating an authenticated HTTP client using + the ClientLogin mechanism is to call the static function + Zend_Gdata_ClientLogin::getHttpClient() + and pass the Google account credentials in plain text. + The return value of this function is an object of class + Zend_Http_Client. + + ++ The optional third parameter is the name of the Google Data + service. For instance, this can be 'cl' for Google Calendar. + The default is "xapi", which is recognized by Google Data + servers as a generic service name. + + ++ The optional fourth parameter is an instance of Zend_Http_Client. + This allows you to set options in the client, such as proxy + server settings. If you pass NULL for this + parameter, a generic Zend_Http_Client object is created. + + ++ The optional fifth parameter is a short string that Google Data + servers use to identify the client application for logging + purposes. By default this is string "Zend-ZendFramework"; + + +
+ The optional sixth parameter is a string ID for a
+
+ The optional seventh parameter is a user's response to a
+ + Below is an example of PHP code for a web application + to acquire authentication to use the Google Calendar service + and create a Zend_Gdata client object using that authenticated + Zend_Http_Client. + + +
Terminating a ClientLogin authenticated Http Client+ There is no method to revoke ClientLogin authentication as there + is in the AuthSub token-based solution. The credentials used + in the ClientLogin authentication are the login and password + to a Google account, and therefore these can be used repeatedly + in the future. + ++ +
|
+
+
|
+
+
+ Using Google Documents List Data API+ The Google Documents List Data API allows client applications to + upload documents to Google Documents and list them in the form of + Google Data API ("GData") feeds. Your client application can request + a list of a user's documents, and query the content in an existing + document. + + ++ See » http://code.google.com/apis/documents/overview.html + for more information about the Google Documents List API. + + +Get a List of Documents+ You can get a list of the Google Documents for a particular user by using + the getDocumentListFeed() method of the docs + service. The service will return a + Zend_Gdata_Docs_DocumentListFeed object + containing a list of documents associated with the authenticated + user. + + +
+ The resulting Zend_Gdata_Docs_DocumentListFeed object + represents the response from the server. This feed contains a list of + Zend_Gdata_Docs_DocumentListEntry objects + ($feed->entries), each of which represents a single + Google Document. + +Upload a Document+ You can create a new Google Document by uploading a word + processing document, spreadsheet, or presentation. This example + is from the interactive Docs.php sample which comes with the + library. It demonstrates uploading a file and printing + information about the result from the server. + + +
Searching the documents feed+ You can search the Document List using some of the » standard + Google Data API query parameters. Categories are used to + restrict the + type of document (word processor document, spreadsheet) returned. + The full-text query string is used to search the content of all + the documents. More detailed information on parameters specific + to the Documents List can be found in the » Documents List + Data API Reference Guide. + + +Get a List of Word Processing Documents+ You can also request a feed containing all of your documents of a specific type. For + example, to see a list of your work processing documents, you would perform a + category query as follows. + + +
Get a List of Spreadsheets+ To request a list of your Google Spreadsheets, use the following category query: + + +
Performing a text query+ You can search the content of documents by using a + Zend_Gdata_Docs_Query in your request. A Query object + can be used to construct the query URI, with the search term + being passed in as a parameter. Here is an example method which queries + the documents list for documents which contain the search string: + + +
+ +
|
+
+
|
+
+
+ Catching Gdata Exceptions+ The Zend_Gdata_App_Exception class is a base class + for exceptions thrown by Zend_Gdata. You can catch any exception + thrown by Zend_Gdata by catching + Zend_Gdata_App_Exception. + + +
+ The following exception subclasses are used by Zend_Gdata: + +
+ You can use these exception subclasses to handle specific exceptions + differently. See the API documentation for information on which + exception subclasses are thrown by which methods in Zend_Gdata. + + +
+ +
|
+
+
|
+
+
+ Using Google Apps Provisioning+ Google Apps is a service which allows domain administrators to offer + their users managed access to Google services such as Mail, Calendar, + and Docs & Spreadsheets. The Provisioning API offers a programmatic + interface to configure this service. Specifically, this API allows + administrators the ability to create, retrieve, update, and delete + user accounts, nicknames, groups, and email lists. + + ++ This library implements version 2.0 of the Provisioning API. Access to + your account via the Provisioning API must be manually enabled for + each domain using the Google Apps control panel. Only certain + account types are able to enable this feature. + + ++ For more information on the Google Apps Provisioning API, including + instructions for enabling API access, refer to the » Provisioning + API V2.0 Reference. + + ++ + Setting the current domain+ In order to use the Provisioning API, the domain being + administered needs to be specified in all request URIs. In order + to ease development, this information is stored within both the + Gapps service and query classes to use when constructing + requests. + + +Setting the domain for the service class+ To set the domain for requests made by the service class, + either call setDomain() or specify the domain + when instantiating the service class. For example: + + +
Setting the domain for query classes+ Setting the domain for requests made by query classes is + similar to setting it for the service class-either call + setDomain() or specify the domain when creating + the query. For example: + + +
+ When using a service class factory method to create a query, + the service class will automatically set the query's domain to + match its own domain. As a result, it is not necessary to + specify the domain as part of the constructor arguments. + + +
Interacting with users+ Each user account on a Google Apps hosted domain is represented as + an instance of Zend_Gdata_Gapps_UserEntry. This class provides + access to all account properties including name, username, + password, access rights, and current quota. + + +Creating a user account+ User accounts can be created by calling the + createUser() convenience method: + + +
+ Users can also be created by instantiating UserEntry, + providing a username, given name, family name, and password, + then calling insertUser() on a service object to + upload the entry to the server. + + +
+ The user's password should normally be provided as cleartext. + Optionally, the password can be provided as an SHA-1 digest if + login->passwordHashFunction is set to + 'SHA-1'. + +Retrieving a user account+ Individual user accounts can be retrieved by calling the + retrieveUser() convenience method. If the user is + not found, NULL will be returned. + + ++ Users can also be retrieved by creating an + instance of Zend_Gdata_Gapps_UserQuery, setting its username + property to equal the username of the user that is to be + retrieved, and calling getUserEntry() on a + service object with that query. + + ++ If the specified user cannot be located a ServiceException + will be thrown with an error code of + Zend_Gdata_Gapps_Error::ENTITY_DOES_NOT_EXIST. + ServiceExceptions will be covered in the exceptions chapter. + +Retrieving all users in a domain+ To retrieve all users in a domain, call the + retrieveAllUsers() convenience method. + + +
+ This will create a Zend_Gdata_Gapps_UserFeed object which + holds each user on the domain. + + ++ Alternatively, call getUserFeed() with no + options. Keep in mind that on larger + domains this feed may be paged by the server. For more + information on paging, see the paging chapter. + + +
Updating a user account+ The easiest way to update a user account is to retrieve the + user as described in the previous sections, make any desired + changes, then call save() on that user. Any + changes made will be propagated to the server. + + +
Resetting a user's password+ A user's password can be reset to a new value by updating + the login->password property. + + +
+ Note that it is not possible to recover a password in this + manner as stored passwords are not made available via the + Provisioning API for security reasons. + +Forcing a user to change their password+ A user can be forced to change their password at their + next login by setting the + login->changePasswordAtNextLogin property to + TRUE. + + +
+ Similarly, this can be undone by setting the + login->changePasswordAtNextLogin property to + FALSE. + +Suspending a user account+ Users can be restricted from logging in without deleting + their user account by instead + suspending their user account. + Accounts can be suspended or restored by using the + suspendUser() and + restoreUser() convenience methods: + + +
+ Alternatively, you can set the UserEntry's + login->suspended property to + TRUE. + + +
+ To restore the user's access, set the + login->suspended property to + FALSE. + +Granting administrative rights+ Users can be granted the ability to administer your domain + by setting their login->admin property to + TRUE. + + +
+ And as expected, setting a user's login->admin + property to FALSE revokes their + administrative rights. + +Deleting user accounts+ Deleting a user account to which you already hold a UserEntry + is a simple as calling delete() on that + entry. + + +
+ If you do not have access to a UserEntry object for an + account, use the deleteUser() convenience method. + + +
Interacting with nicknames+ Nicknames serve as email aliases for existing users. Each nickname + contains precisely two key properties: its name and its owner. Any + email addressed to a nickname is forwarded to the user who owns + that nickname. + + ++ Nicknames are represented as an instances of + Zend_Gdata_Gapps_NicknameEntry. + + +Creating a nickname+ Nicknames can be created by calling the + createNickname() convenience method: + + +
+ Nicknames can also be created by instantiating NicknameEntry, + providing the nickname with a name and an owner, then calling + insertNickname() on a service object to upload + the entry to the server. + + +
Retrieving a nickname+ Nicknames can be retrieved by calling the + retrieveNickname() convenience method. This will + return NULL if a user is not found. + + +
+
+
+ + Individual nicknames can also be retrieved by creating an + instance of Zend_Gdata_Gapps_NicknameQuery, setting its + nickname property to equal the nickname that is to be + retrieved, and calling getNicknameEntry() on a + service object with that query. + + +
+
+
+ + As with users, if no corresponding nickname is found a + ServiceException will be thrown with an error code of + Zend_Gdata_Gapps_Error::ENTITY_DOES_NOT_EXIST. Again, these + will be discussed in the exceptions chapter. + +Retrieving all nicknames for a user+ To retrieve all nicknames associated with a given user, call + the convenience method retrieveNicknames(). + + +
+ This will create a Zend_Gdata_Gapps_NicknameFeed object which + holds each nickname associated with the specified user. + + ++ Alternatively, create a new Zend_Gdata_Gapps_NicknameQuery, + set its username property to the desired user, and submit the + query by calling getNicknameFeed() on a service + object. + + +
Retrieving all nicknames in a domain+ To retrieve all nicknames in a feed, simply call the + convenience method retrieveAllNicknames() + + +
+ This will create a Zend_Gdata_Gapps_NicknameFeed object which + holds each nickname on the domain. + + ++ Alternatively, call getNicknameFeed() on a + service object with no arguments. + + +
Deleting a nickname+ Deleting a nickname to which you already hold a NicknameEntry + for is a simple as calling delete() on that + entry. + + +
+ For nicknames which you do not hold a NicknameEntry for, use + the deleteNickname() convenience method. + + +
Interacting with groups+ Google Groups allows people to post messages like an email list. Google + is depreciating the Email List API. Google Groups provides some neat + features like nested groups and group owners. If you want to start + a new email lst, it is advisable to use Google Groups instead. + Google's Email List is not compatible with Google Groups. So if you + create an email list, it will not show up as a group. The opposite is + true as well. + + ++ Each group on a domain is represented as an instance of + Zend_Gdata_Gapps_GroupEntry. + + +Creating a group+ Groups can be created by calling the + createGroup() convenience method: + + +
+ Groups can also be created by instantiating + GroupEntry, providing a group id and name for the group, + then calling insertGroup() on a service + object to upload the entry to the server. + + +
Retrieving an individual group+ To retrieve an individual group, call the + retrieveGroup() convenience method: + + +
+
+
+ + This will create a Zend_Gdata_Gapps_GroupEntry + object which holds the properties about the group. + + ++ Alternatively, create a new Zend_Gdata_Gapps_GroupQuery, + set its groupId property to the desired group id, and + submit the query by calling getGroupEntry() + on a service object. + + + + +Retrieving all groups in a domain+ To retrieve all groups in a domain, call the convenience + method retrieveAllGroups(). + + +
+
+
+ + This will create a Zend_Gdata_Gapps_GroupFeed + object which holds each group on the domain. + + ++ Alternatively, call getGroupFeed() on a + service object with no arguments. + + + + +Deleting a group+ To delete a group, call the deleteGroup() convenience + method: + + +
Updating a group+ Groups can be updated by calling the + updateGroup() convenience method: + + +
+ The first parameter is required. The second, third and fourth parameter, + representing the group name, group descscription, and email permission, + respectively are optional. Setting any of these optional parameters + to null will not update that item. + +Retrieving all groups to which a person is a member+ To retrieve all groups to which a particular person is a + member, call the retrieveGroups() + convenience method: + + +
+
+
+ + This will create a Zend_Gdata_Gapps_GroupFeed + object which holds each group associated with the specified member. + + ++ Alternatively, create a new Zend_Gdata_Gapps_GroupQuery, + set its member property to the desired email address, and + submit the query by calling getGroupFeed() + on a service object. + + + + +Interacting with group members+ Each member subscribed to a group is represented by an + instance of Zend_Gdata_Gapps_MemberEntry. + Through this class, individual recipients can be added and removed + from groups. + + +Adding a member to a group+ To add a member to a group, simply call the + addMemberToGroup() convenience method: + + +
Check to see if member belongs to group+ To check to see if member belongs to group, simply call the + isMember() convenience method: + + +
+ The method returns a boolean value. If the member belongs to the + group specified, the method returns true, else it returns false. + +Removing a member from a group+ To remove a member from a group, call the + removeMemberFromGroup() convenience + method: + + +
Retrieving the list of members to a group+ The convenience method retrieveAllMembers() + can be used to retrieve the list of members of a group: + + +
+
+
+ + Alternatively, construct a new MemberQuery, set its groupId + property to match the desired group id, and call + getMemberFeed() on a service object. + + +
+
+
+ + This will create a Zend_Gdata_Gapps_MemberFeed + object which holds each member for the selected group. + +Interacting with group owners+ Each owner associated with a group is represented by an + instance of Zend_Gdata_Gapps_OwnerEntry. + Through this class, individual owners can be added and removed + from groups. + + +Adding an owner to a group+ To add an owner to a group, simply call the + addOwnerToGroup() convenience method: + + +
Retrieving the list of the owner of a group+ The convenience method retrieveGroupOwners() + can be used to retrieve the list of the owners of a group: + + +
+
+
+ + Alternatively, construct a new OwnerQuery, set its groupId + property to match the desired group id, and call + getOwnerFeed() on a service object. + + +
+
+
+ + This will create a Zend_Gdata_Gapps_OwnerFeed + object which holds each member for the selected group. + +Check to see if an email is the owner of a group+ To check to see if an email is the owner of a group, simply call + the isOwner() convenience method: + + +
+ The method returns a boolean value. If the email is the owner of + the group specified, the method returns true, else it returns false. + +Removing an owner from a group+ To remove an owner from a group, call the + removeOwnerFromGroup() convenience + method: + + +
Interacting with email lists+ Email lists allow several users to retrieve email addressed to a + single email address. Users do not need to be a + member of this domain in order to subscribe to an email list + provided their complete email address (including domain) is used. + + ++ Each email list on a domain is represented as an instance of + Zend_Gdata_Gapps_EmailListEntry. + + +Creating an email list+ Email lists can be created by calling the + createEmailList() convenience method: + + +
+ Email lists can also be created by instantiating + EmailListEntry, providing a name for the list, then calling + insertEmailList() on a service object to upload + the entry to the server. + + +
Retrieving all email lists to which a recipient is subscribed+ To retrieve all email lists to which a particular recipient is + subscribed, call the retrieveEmailLists() + convenience method: + + +
+ This will create a Zend_Gdata_Gapps_EmailListFeed object + which holds each email list associated with the specified recipient. + + ++ Alternatively, create a new Zend_Gdata_Gapps_EmailListQuery, + set its recipient property to the desired email address, and + submit the query by calling getEmailListFeed() on + a service object. + + +
Retrieving all email lists in a domain+ To retrieve all email lists in a domain, call the convenience + method retrieveAllEmailLists(). + + +
+ This will create a Zend_Gdata_Gapps_EmailListFeed object + which holds each email list on the domain. + + ++ Alternatively, call getEmailListFeed() on a + service object with no arguments. + + +
Deleting an email list+ To delete an email list, call the deleteEmailList() + convenience method: + + +
Interacting with email list recipients+ Each recipient subscribed to an email list is represented by an + instance of Zend_Gdata_Gapps_EmailListRecipient. Through this + class, individual recipients can be added and removed from email + lists. + + +Adding a recipient to an email list+ To add a recipient to an email list, simply call the + addRecipientToEmailList() convenience method: + + +
Retrieving the list of subscribers to an email list+ The convenience method retrieveAllRecipients() + can be used to retrieve the list of subscribers to an email list: + + +
+ Alternatively, construct a new EmailListRecipientQuery, set + its emailListName property to match the desired email list, + and call getEmailListRecipientFeed() on a service + object. + + +
+ This will create a Zend_Gdata_Gapps_EmailListRecipientFeed + object which holds each recipient for the selected email list. + +Removing a recipient from an email list+ To remove a recipient from an email list, call the + removeRecipientFromEmailList() convenience + method: + + +
Handling errors+ In addition to the standard suite of exceptions thrown by + Zend_Gdata, requests using the Provisioning + API may also throw a + Zend_Gdata_Gapps_ServiceException. These exceptions + indicate that a API specific error occurred which prevents the + request from completing. + + ++ Each ServiceException instance may hold one or more Error objects. + Each of these objects contains an error code, reason, and + (optionally) the input which triggered the exception. A complete + list of known error codes is provided in Zend Framework's API + documentation under Zend_Gdata_Gapps_Error. Additionally, the + authoritative error list is available online at » Google + Apps Provisioning API V2.0 Reference: Appendix D. + + ++ While the complete list of errors received is available within + ServiceException as an array by calling getErrors(), + often it is convenient to know if one specific error occurred. For + these cases the presence of an error can be determined by calling + hasError(). + + ++ The following example demonstrates how to detect if a requested + resource doesn't exist and handle the fault gracefully: + + +
+ +
|
+
+
|
+
+
+
+
+ Zend_GdataTable of Contents
+ +
|
+
+
|
+
+
+ Using Picasa Web Albums+ Picasa Web Albums is a service which allows users to maintain albums of + their own pictures, and browse the albums and pictures of others. + The API offers a programmatic interface to this service, allowing + users to add to, update, and remove from their albums, as well as + providing the ability to tag and comment on photos. + + ++ Access to public albums and photos is not restricted by account, + however, a user must be logged in for non-read-only access. + + ++ For more information on the API, including + instructions for enabling API access, refer to the » Picasa + Web Albums Data API Overview. + + ++ + Connecting To The Service+ The Picasa Web Albums API, like all GData APIs, is + based off of the Atom Publishing Protocol (APP), an XML based format + for managing web-based resources. Traffic between a client and the servers occurs over + HTTP and allows for both authenticated and unauthenticated + connections. + + ++ Before any transactions can occur, this connection needs to be made. Creating a + connection to the Picasa servers involves two steps: creating an HTTP + client and binding a Zend_Gdata_Photos + service instance to that client. + + +Authentication+ The Google Picasa API allows access to both public and private + photo feeds. Public feeds do not require authentication, but are read-only and offer + reduced functionality. Private feeds offers the most complete functionality but + requires an authenticated connection to the Picasa servers. There are three + authentication schemes that are supported by Google Picasa : + + +
+ The + Zend_Gdata + library provides support for both authentication schemes. + The rest of this chapter will assume that you are familiar the + authentication schemes available and how to create an + appropriate authenticated connection. For more information, + please see section the + Authentication section + of this manual or the » Authentication Overview in the + Google Data API Developer's Guide. + +Creating A Service Instance+ In order to interact with the servers, this library provides the + Zend_Gdata_Photos service class. This class provides a common + interface to the Google Data and Atom Publishing Protocol models and assists in + marshaling requests to and from the servers. + + ++ Once deciding on an authentication scheme, the next step is to create an instance of + Zend_Gdata_Photos. The class constructor takes an instance of + Zend_Http_Client as a single argument. This provides an + interface for AuthSub and ClientAuth authentication, as both of these require + creation of a special authenticated HTTP client. If no arguments + are provided, an unauthenticated instance of Zend_Http_Client + will be automatically created. + + ++ The example below shows how to create a service class using ClientAuth + authentication: + + +
+ A service instance using AuthSub can be created in a similar, though slightly more + lengthy fashion: + + +
+ Finally, an unauthenticated server can be created for use with public feeds: + + +
Understanding and Constructing Queries+ The primary method to request data from the service is by constructing a query. There + are query classes for each of the following types: + + +
A new UserQuery can be constructed as followed: + +
+ for each query, a number of parameters limiting the search can be requested, or + specified, with get(Parameter) and set(Parameter), respectively. They are as follows: + + +
Retrieving Feeds And Entries+ The service has functions to retrieve a feed, or individual entries, for users, albums, + and individual photos. + + +Retrieving A User+ The service supports retrieving a user feed and list of the user's content. If the + requested user is also the authenticated user, entries marked as + "hidden" will also be returned. + + ++ The user feed can be accessed by passing the username to the + getUserFeed() method: + + +
Or, the feed can be accessed by constructing a query, first: + +
+ Constructing a query also provides the ability to request a user entry object: + + +
Retrieving An Album+ The service supports retrieving an album feed and a list of the album's content. + + ++ The album feed is accessed by constructing a query object and passing it to + getAlbumFeed(): + + +
+ Alternatively, the query object can be given an album name with + setAlbumName(). Setting the album name is mutually + exclusive with setting the album id, and setting one will unset the other. + + ++ Constructing a query also provides the ability to request an album entry object: + + +
Retrieving A Photo+ The service supports retrieving a photo feed and a list of associated comments and + tags. + + ++ The photo feed is accessed by constructing a query object and passing it to + getPhotoFeed(): + + +
+ Constructing a query also provides the ability to request a photo entry object: + + +
Retrieving A Comment+ The service supports retrieving comments from a feed of a different type. By setting + a query to return a kind of "comment", a feed request can return comments associated + with a specific user, album, or photo. + + ++ Performing an action on each of the comments on a given photo can be accomplished + as follows: + + +
Retrieving A Tag+ The service supports retrieving tags from a feed of a different type. By setting a + query to return a kind of "tag", a feed request can return tags associated with a + specific photo. + + ++ Performing an action on each of the tags on a given photo can be accomplished as + follows: + + +
Creating EntriesThe service has functions to create albums, photos, comments, and tags. + +Creating An AlbumThe service supports creating a new album for an authenticated user: + +
Creating A PhotoThe service supports creating a new photo for an authenticated user: + +
Creating A CommentThe service supports creating a new comment for a photo: + +
Creating A TagThe service supports creating a new tag for a photo: + +
Deleting EntriesThe service has functions to delete albums, photos, comments, and tags. + +Deleting An AlbumThe service supports deleting an album for an authenticated user: + +
Deleting A PhotoThe service supports deleting a photo for an authenticated user: + +
Deleting A CommentThe service supports deleting a comment for an authenticated user: + +
Deleting A TagThe service supports deleting a tag for an authenticated user: + +
Optimistic Concurrency (Notes On Deletion)+ GData feeds, including those of the Picasa Web Albums service, implement optimistic + concurrency, a versioning system that prevents users from overwriting changes, + inadvertently. When deleting a entry through the service class, if the entry has + been modified since it was last fetched, an exception will be thrown, unless + explicitly set otherwise (in which case the deletion is retried on the updated + entry). + + ++ An example of how to handle versioning during a deletion is shown by + deleteAlbumEntry(): + + +
+ +
|
+
+
|
+
+
+ Using Google Spreadsheets+ The Google Spreadsheets data API allows client applications to view + and update Spreadsheets content in the form of Google data API feeds. + Your client application can request a list of a user's spreadsheets, + edit or delete content in an existing Spreadsheets worksheet, and + query the content in an existing Spreadsheets worksheet. + + ++ See » http://code.google.com/apis/spreadsheets/overview.html + for more information about the Google Spreadsheets API. + + +Create a Spreadsheet+ The Spreadsheets data API does not currently provide a way to + programmatically create or delete a spreadsheet. + +Get a List of Spreadsheets+ You can get a list of spreadsheets for a particular user by using + the getSpreadsheetFeed() method of the Spreadsheets + service. The service will return a + Zend_Gdata_Spreadsheets_SpreadsheetFeed object + containing a list of spreadsheets associated with the authenticated + user. + + +
Get a List of Worksheets+ A given spreadsheet may contain multiple worksheets. For each + spreadsheet, there's a worksheets metafeed listing all the + worksheets in that spreadsheet. + + ++ Given the spreadsheet key from the <id> of a + Zend_Gdata_Spreadsheets_SpreadsheetEntry + object you've already retrieved, you can fetch a feed + containing a list of worksheets associated with that spreadsheet. + + +
+ The resulting Zend_Gdata_Spreadsheets_WorksheetFeed + object feed represents the response from the server. Among other + things, this feed contains a list of + Zend_Gdata_Spreadsheets_WorksheetEntry + objects ($feed->entries), each of which represents a + single worksheet. + +Interacting With List-based Feeds+ A given worksheet generally contains multiple rows, each + containing multiple cells. You can request data from the + worksheet either as a list-based feed, in which each entry + represents a row, or as a cell-based feed, in which each + entry represents a single cell. For information on cell-based feeds, see Interacting with cell-based + feeds. + + ++ The following sections describe how to get a list-based feed, + add a row to a worksheet, and send queries with various query + parameters. + + ++ The list feed makes some assumptions about how the data is laid + out in the spreadsheet. + + ++ In particular, the list feed treats the first row of the + worksheet as a header row; Spreadsheets dynamically creates + XML elements named after the contents of header-row cells. + Users who want to provide Gdata feeds should not put any data + other than column headers in the first row of a worksheet. + + ++ The list feed contains all rows after the first row up to the + first blank row. The first blank row terminates the data set. + If expected data isn't appearing in a feed, check the worksheet + manually to see whether there's an unexpected blank row in the + middle of the data. In particular, if the second row of the + spreadsheet is blank, then the list feed will contain no data. + + ++ A row in a list feed is as many columns wide as the worksheet itself. + + +Get a List-based Feed+ To retrieve a worksheet's list feed, use the + getListFeed() method of the Spreadsheets service. + + +
+ The resulting Zend_Gdata_Spreadsheets_ListFeed + object $listfeed represents a response from the + server. Among other things, this feed contains an array of + Zend_Gdata_Spreadsheets_ListEntry objects + ($listFeed->entries), each of which represents + a single row in a worksheet. + + ++ Each Zend_Gdata_Spreadsheets_ListEntry contains an + array, custom, which contains the data for that + row. You can extract and display this array: + + +
+ An alternate version of this array, customByName, + allows direct access to an entry's cells by name. This is + convenient when trying to access a specific header: + + +
Reverse-sort Rows+ By default, rows in the feed appear in the same order as the + corresponding rows in the GUI; that is, they're in order by + row number. To get rows in reverse order, set the reverse + properties of the Zend_Gdata_Spreadsheets_ListQuery + object to TRUE: + + +
+ Note that if you want to order (or reverse sort) by a + particular column, rather than by position in the worksheet, + you can set the orderby value of the + Zend_Gdata_Spreadsheets_ListQuery object to + column:<the header of that column>. + +Send a Structured Query+ You can set a Zend_Gdata_Spreadsheets_ListQuery's + sq value to produce a feed with entries that meet + the specified criteria. For example, suppose you have a worksheet + containing personnel data, in which each row represents + information about a single person. You wish to retrieve all rows + in which the person's name is "John" and the person's age is over + 25. To do so, you would set sq as follows: + + +
Add a Row+ Rows can be added to a spreadsheet by using the + insertRow() method of the Spreadsheet service. + + +
+ The $rowData parameter contains an array of column + keys to data values. The method returns a + Zend_Gdata_Spreadsheets_SpreadsheetsEntry object + which represents the inserted row. + + ++ Spreadsheets inserts the new row immediately after the last row + that appears in the list-based feed, which is to say + immediately before the first entirely blank row. + +Edit a Row+ Once a Zend_Gdata_Spreadsheets_ListEntry object + is fetched, its rows can be updated by using the + updateRow() method of the Spreadsheet service. + + +
+ The $oldListEntry parameter contains the list entry + to be updated. $newRowData contains an array of + column keys to data values, to be used as the new row data. + The method returns a + Zend_Gdata_Spreadsheets_SpreadsheetsEntry object + which represents the updated row. + +Delete a Row+ To delete a row, simply invoke deleteRow() on the + Zend_Gdata_Spreadsheets object with the existing + entry to be deleted: + + +
+ Alternatively, you can call the delete() method of + the entry itself: + + +
Interacting With Cell-based Feeds+ In a cell-based feed, each entry represents a single cell. + + ++ Note that we don't recommend interacting with both a cell-based + feed and a list-based feed for the same worksheet at the same time. + + +Get a Cell-based Feed+ To retrieve a worksheet's cell feed, use the + getCellFeed() method of the Spreadsheets service. + + +
+ The resulting Zend_Gdata_Spreadsheets_CellFeed + object $cellFeed represents a response from the + server. Among other things, this feed contains an array of + Zend_Gdata_Spreadsheets_CellEntry objects + ($cellFeed>entries), each of which represents + a single cell in a worksheet. You can display this information: + + +
Send a Cell Range Query+ Suppose you wanted to retrieve the cells in the first column + of a worksheet. You can request a cell feed containing only + this column as follows: + + +
+ This requests all the data in column 1, starting with row 2. + +Change Contents of a Cell+ To modify the contents of a cell, call + updateCell() with the row, column, + and new value of the cell. + + +
+ The new data is placed in the specified cell in the worksheet. + If the specified cell contains data already, it will be + overwritten. Note: Use updateCell() to change + the data in a cell, even if the cell is empty. + ++ +
|
+
+
|
+
+
+ Using the YouTube Data API+ The YouTube Data API offers read and write access to YouTube's content. + Users can perform unauthenticated requests to Google Data feeds to + retrieve feeds of popular videos, comments, public information about + YouTube user profiles, user playlists, favorites, subscriptions and so on. + + ++ For more information on the YouTube Data API, please refer + to the official » PHP + Developer's Guide on code.google.com. + + +Authentication+ The YouTube Data API allows read-only access to public data, which + does not require authentication. For any write requests, a user + needs to authenticate either using ClientLogin or AuthSub authentication. Please refer + to the » Authentication + section in the PHP Developer's Guide for more detail. + +Developer Keys and Client ID+ A developer key identifies the YouTube developer that is submitting + an API request. A client ID identifies your application for logging + and debugging purposes. Please visit » http://code.google.com/apis/youtube/dashboard/ + to obtain a developer key and client ID. The example below demonstrates how to pass the + developer key and client ID to the » Zend_Gdata_YouTube + service object. + + +Example #1 Passing a Developer Key and ClientID to Zend_Gdata_YouTube
Retrieving public video feeds+ The YouTube Data API provides numerous feeds that return a list of + videos, such as standard feeds, related videos, video responses, + user's uploads, and user's favorites. For example, the + user's uploads feed returns all videos uploaded by a specific user. See the » YouTube + API reference guide for a detailed list of available + feeds. + + +Searching for videos by metadata+ You can retrieve a list of videos that match specified + search criteria, using the YouTubeQuery class. The following query + looks for videos which contain the word "cat" in their + metadata, starting with the 10th video and displaying 20 + videos per page, ordered by the view count. + + +Example #2 Searching for videos
+ For more details on the different query parameters, please refer to the » + Reference Guide. The available helper functions in » Zend_Gdata_YouTube_VideoQuery + for each of these parameters are described in more detail in the » PHP + Developer's Guide. + +Searching for videos by categories and tags/keywords+ Searching for videos in specific categories is done by generating a » specially + formatted URL. For example, to search for + comedy videos which contain the keyword dog: + + +Example #3 Searching for videos in specific categories
Retrieving standard feeds+ The YouTube Data API has a number of » standard + feeds. These standard feeds can be retrieved as » Zend_Gdata_YouTube_VideoFeed + objects using the specified URLs, using the predefined constants + within the » Zend_Gdata_YouTube + class (Zend_Gdata_YouTube::STANDARD_TOP_RATED_URI for example) or + using the predefined helper methods (see code listing below). + + ++ To retrieve the top rated videos using the helper method: + + +Example #4 Retrieving a standard video feed
+ There are also query parameters to specify the time period + over which the standard feed is computed. + + ++ For example, to retrieve the top rated videos for today: + + +Example #5 Using a Zend_Gdata_YouTube_VideoQuery to Retrieve Videos
+ Alternatively, you could just retrieve the feed using the + URL: + + +Example #6 Retrieving a video feed by URL
Retrieving videos uploaded by a user+ You can retrieve a list of videos uploaded by a particular user + using a simple helper method. This example retrieves videos + uploaded by the user 'liz'. + + +Example #7 Retrieving videos uploaded by a specific user
Retrieving videos favorited by a user+ You can retrieve a list of a user's favorite videos + using a simple helper method. This example retrieves videos + favorited by the user 'liz'. + + +Example #8 Retrieving a user's favorite videos
Retrieving video responses for a video+ You can retrieve a list of a video's video responses + using a simple helper method. This example retrieves video + response for a video with the ID 'abc123813abc'. + + +Example #9 Retrieving a feed of video responses
Retrieving video comments+ The comments for each YouTube video can be retrieved in + several ways. To retrieve the comments for the video with + the ID 'abc123813abc', use the following code: + + +Example #10 Retrieving a feed of video comments from a video ID + Comments can also be retrieved for a video if you have a copy of the » Zend_Gdata_YouTube_VideoEntry + object: + + +Example #11 Retrieving a Feed of Video Comments from a Zend_Gdata_YouTube_VideoEntry
Retrieving playlist feeds+ The YouTube Data API provides information about users, including + profiles, playlists, subscriptions, and more. + + +Retrieving the playlists of a user+ The library provides a helper method to retrieve + the playlists associated with a given user. To retrieve the + playlists for the user 'liz': + + +Example #12 Retrieving the playlists of a user Retrieving a specific playlist+ The library provides a helper method to retrieve + the videos associated with a given playlist. To retrieve the + playlists for a specific playlist entry: + + +Example #13 Retrieving a specific playlist
Retrieving a list of a user's subscriptions+ A user can have several types of subscriptions: channel + subscription, tag subscription, or favorites subscription. A » Zend_Gdata_YouTube_SubscriptionEntry + is used to represent individual subscriptions. + + ++ To retrieve all subscriptions for the user 'liz': + + +Example #14 Retrieving all subscriptions for a user
Retrieving a user's profile+ You can retrieve the public profile information + for any YouTube user. To retrieve the profile + for the user 'liz': + + + +Uploading Videos to YouTube+ Please make sure to review the diagrams in the » protocol + guide on code.google.com for a high-level + overview of the upload process. Uploading videos can be done in one of + two ways: either by uploading the video directly or by sending just the video + meta-data and having a user upload the video through an HTML form. + + ++ In order to upload a video directly, you must first construct a new » Zend_Gdata_YouTube_VideoEntry + object and specify some required meta-data. The following example shows uploading the + Quicktime video "mytestmovie.mov" to YouTube with the following properties: + + +
+ The code below creates a blank » Zend_Gdata_YouTube_VideoEntry + to be uploaded. A » Zend_Gdata_App_MediaFileSource + object is then used to hold the actual video file. Under the hood, the » Zend_Gdata_YouTube_Extension_MediaGroup + object is used to hold all of the video's meta-data. Our helper methods detailed below + allow you to just set the video meta-data without having to worry about the media group + object. The $uploadUrl is the location where the new entry gets posted to. + This can be specified either with the $userName of the + currently authenticated user, or, alternatively, you can simply use the + string 'default' to refer to the currently authenticated user. + + +Example #16 Uploading a video
+ To upload a video as private, simply use: $myVideoEntry->setVideoPrivate(); prior to + performing the upload. $videoEntry->isVideoPrivate() can be used to check whether a + video entry is private or not. + +Browser-based upload+ Browser-based uploading is performed almost identically to direct uploading, + except that you do not attach a » Zend_Gdata_App_MediaFileSource + object to the » Zend_Gdata_YouTube_VideoEntry + you are constructing. Instead you simply submit all of your video's meta-data to receive + back a token element which can be used to construct an HTML upload + form. + + +Example #17 Browser-based upload
+ The above code prints out a link and a token that is used to construct an + HTML form to display in the user's browser. A simple example form is + shown below with $tokenValue representing the content of the returned token element, + as shown being retrieved from $myVideoEntry above. In order for the user + to be redirected to your website after submitting the form, make sure to + append a $nextUrl parameter to the $postUrl above, which functions in the + same way as the $next parameter of an AuthSub link. The only difference is + that here, instead of a single-use token, a status and an id variable are + returned in the URL. + + +Example #18 Browser-based upload: Creating the HTML form
Checking upload status+ After uploading a video, it will immediately be visible in an + authenticated user's uploads feed. However, it will not be public on + the site until it has been processed. Videos that have been rejected or + failed to upload successfully will also only be in the authenticated + user's uploads feed. The following code checks the status of a » Zend_Gdata_YouTube_VideoEntry + to see if it is not live yet or if it has been rejected. + + +Example #19 Checking video upload status
Other Functions+ In addition to the functionality described above, the YouTube API + contains many other functions that allow you to modify video meta-data, + delete video entries and use the full range of community features on the site. Some of + the community features that can be modified through the API include: + ratings, comments, playlists, subscriptions, user profiles, contacts and messages. + ++ Please refer to the full documentation available in the » PHP Developer's + Guide on code.google.com. + ++ +
|
+
+
|
+
+
+
+
+ Zend_Http+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_InfoCard+ + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Json+ + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Layout+ + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Ldap+ + + + + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Loader+ + + + + + + + + + + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Locale+ + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Log+ + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Mail+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Markup+ + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Measure+ + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Memory+ + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Mime+ + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Mobile_Push+ + + + + + + + + + + + ++ +
|
+
+
|
+
+
+ + + +
|
+
+
|
+
+
+
+
+ Zend_Oauth+ + + ++ +
|
+
+
|
+
+
+
+
+ Zend_OpenId+ + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Paginator+ + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Pdf+ + + + + + + + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_ProgressBar+ + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Queue+ + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Reflection+ + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Registry+ + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Rest+ + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Search_Lucene+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Serializer+ + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Server+ + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Service+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Session+ + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Soap+ + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Tag+ + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Test+ + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Text+ + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_TimeSync+ + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Tool_Framework+ + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Tool+ + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Tool_Project+ + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Translate+ + + + + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Uri+ + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Validate+ + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Version+ + + ++ +
|
+
+
|
+
+
+
+
+ Zend_View+ + + + + + + + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ Zend_Wildfire+ + + ++ +
|
+
+
|
+
+
+
+
+ Zend_XmlRpc+ + + + + + + + + ++ +
|
+
+
|
+
+
+
+
+ ZendX_Console_Process_Unix+ ++ +
|
+
+
|
+
+
+
+
+ ZendX_JQuery+ + + ++ +
|
+
+
|
+