Community wiki

Community wiki

draft coding rules

a) documentation: at least public methods (purpose, params, return-value) need to be documented with phpDoc (unless we agree in some other doc-format). New API classes are only permitted if they are fully documented: inline docs and a document in the wiki's developer docs explaining the purpose of the app and giving some examples.

b) 3-tier: UI > BO > SO !!!
All database stuff should be in (an) own class(es), never calling a higher layer and operating on server-time. The business logic should be an own layer never calling the UI layer and also serving xmlrpc and other apps. The BO layer should (at least by default) operate on user-time. The UI layer should create the UI by using some kind of templates and it has to be called again by the form (NOT BO direct!).
The lower layers can be instanciated in class-vars or extended by a higher layer (better performance).
knecke: xmlrpc should not be served direct by BO, as xmlrpc required special handling of input params and make the BO class therefor more complicated.

c) use references whenever possible: It gives a far better performance with big variables (objects, arrays, strings), specialy when using new $class() or CreateObject($app.'.'.$class), eg. $bo =& CreateObject('myapp.mybo');

d) indention with tabs

e) if and brackets: there are two permitted forms:
if ($x) $y = $z;    // in one line only !
if ($x)
    $y = $z;
elseif ($c)
    $a = $b;
Same applies to while and foreach

f) unix lineends

g) the app need to be able to run with register_globals off AND register_long_vars off. You need to use $_GET, $_POST, $_REQUEST, $_SERVER and $_COOKIE not just global $var or $GLOBALS['var'] or the old forms like $HTTP_GET_VARS['var'] or $GLOBALS['HTTP_POST_VARS']['var']. NEVER TRUST THE VALUE OF ANY OF THESE, THEY CAN ALWAYS BE TEMPERED BY MALICIOUS USERS.

h) XSS (cross site scripting): all html output has to be run through htmlspecialchars or better html::htmlspecialchars, which has some fixes for some multibyte languages. This includes attributes in html-tags! An easy way to do that is by using the html class in the api or a template engine doing that with all output automatically.

i) SQL injuntion: all values send to the database need to be run through db::quote($var,$type=false) or the new methods db::select, db::insert, db::update, db::delete, db::expression have to be used! Column-names (eg. in ORDER BY) need to be checked too, if they are passed via $_GET OR $_POST (post variables can be easyly tempered too).

j) use single quotes in strings, they have a far better performance then double quotes (evtl. containing variables). Also important for the performance use single quotes for keys in arrays, eg. $arr['name'], not $arr["name"] or $arr[name].

h) use foreach:
foreach([(array)]$arr as [$key =>] $val)
instead of
while(list([$key],$val) = [@]each($arr))
It has better performance and is less error-prone (not reset array-pointers, caused some trouble in the past).

i) all column-names used should have a short unique prefix for the table, an underscore and then it's actual name. Reason: You get nearly endlist list of reserved word if you merge them from all database types. This was/is the biggest pain if you port eGW to a new database-type. Exception: Foreign keys should use the prefix of the table they are pointing too (have the same name as in the table they belong to). It also simplifies joins because the column-names of the result-set are still unique, beside the identical foreign keys.

No rule without exceptions: apps ported into eGW or complete classes (eg. ADOdb) should be left as is whenever possible, to allow an easier upgrade! They can be called by a wrapper extending or instanciating them in an eGW way if necessary.

Feel free to add further rules if you think they are necessary and comment, as suggest by Lars, on the core-list (egroupware-core AT lists DOT sf DOT net) or here in the text (marked with your name).


Coding Rules:

1. All Code must be documented with PHPDoc. (Rule One Rationale)?
1.1 Patchs must include all class documentation.
1.2 All commiters must run the documentation script, after the commit.

2. All Code must be Objected Oriented. (Rule Two Rationale)?
2.1. The Code must respect and preserve the SO/BO/UI struture.
2.2. Specific Classes must be inherited from a generic class not the oposite.
2.3. Do not use Bo Layer to define protocol interfaces.

3. Use PHP References to all objects. (Rule Three Rationale)?
3.1.Use PHP References as first option to other situations.

4. All code must be idented with tab.

5. There are only one form to use brackets in conditional operators. Follow the example bellow.
if ($x)
    $y = $z;
elseif ($c)
    $a = $b;

6. Use only unix type linefeeds.

7. All applications must be able to run using register_globals off (Rule Seven Rationale)?
7.1 Use $_GET['var'], not $HTTP_GET_VARS['var'] or $GLOBALS['HTTP_POST_VARS']['var'].

8. Use the HTML Class in api. (Rule eight rationale)?

9. Use only the ADOdb object to access the data base. (Rule Nine Rationale)?

10. Use only foreach (Rule Ten Rationale)?

11. Use a three letters prefix followed by one underscore caracter to all column-names in db tables. (Rule Ten Rationale)?

12. Do not modify libs from external projects. (Rule 12 Rationale)?
12.1 If they need adaptations use a warper classes.
12.2 If they need improvements do it in the original project.

[Sebastian Ebling]
I like the PEAR coding standards and most of the following is from this document:

This means in short
a) Indenting and Line Length
- Ident of 4 spaces in K&R style. Different to PEAR we can also use tabs, afaik most eGroupWare developers like them.
- It is recommended to keep lines at approximately 75-85 characters long for better code readability.

b) Control Structures
- One space between control keyword and opening parenthesis to distinguish them from function calls.
- Use curly braces even in situataions where they are technicalli optional to increase readability

c) Function Calls
- NO spaces between the function name, the opening parenthesis and the first parameter. Spaces between commas and each parameter and no spaces between the last parameter, the closing parenthesis and the semicolon.
- In the case of a block of related assignments, more spaces may be inserted to promote readability

d) Function Definitions
- Function declarations follow the "BSD/Allman style"

e) Quoting
- use single quotes where possible

f) Comments
- Inline documentations follow the rules of phpDocumentor.
- C style comments (/* */) and standard C++ comments (//) are both fine.
- Use of Perl/shell style comments (#) is discouraged.

g) Including Code
- Anywhere you are unconditionally including a class file, use require_once
- Anywhere you are conditionally including a class file (for example factory methods) use include_once.

h) PHP Code Tags
- Always use <?php ?> to delimit PHP code, not the <? ?> shorthand.

i) Header Comment Blocks
- All source code files shall contain a "page-level" docblock at the top of each file and a "class-level" docblock immediately above each class.
- Required Tags that have variable content: @license, @author, @since, @deprecated
- Order and spaces should follow the JavaDoc? standard

j) SVN
- Include the $Id$ keyword in each file. (and enable this feature to our SVN)

k) Example URLs
- Use, and for all example URLs and email addresses, per RFC 2606

l) Naming Conventions
- Class names should always begin with an uppercase letter. Each letter that starts a new "word" is capitalized. We should think of an prefix to avoid name collisions
- Functions and methods should always begin with an lowercase letter. Each letter that starts a new "word" is capitalized. We should think of an prefix to avoid name collisions
- Constants should always be all-uppercase, with underscores to separate words. Prefix constant names with the uppercased name of the class/package they are used in.
- Global variables should start with a single underscore

m) File Formats
- ASCII text
- ISO-8859-1 character encoding
- Unix formatted (Lines must end only with a line feed (LF))
- There should be one line feed after the closing PHP tag (?>). This means that when the cursor is at the very end of the file, it should be one line below the closing PHP tag.

n) E_STRICT-compatible code
- The code must be E_STRICT-compatible. This means that it must not produce any warnings or errors when PHP's error reporting level is set to E_STRICT.

o) Error Handling Guidelines (PHP5, eGroupWare 2.0?)
- Use exceptions
- Include @throws to the inline documentation

That's it for the moment.
Stay tuned, as I will provide a sample file in short.
You are here