aboutsummaryrefslogtreecommitdiff
path: root/CODING.txt
blob: 35560172062421162a62b8faf0d76ee06cb322d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
*** CODING STANDARDS ***

These are the coding standards for Elgg.  All core development, bundled 
plugins, and tickets attached to Trac are expected to be in this format.

** PHP **

* 	Unix line endings.

* 	Hard tabs, 4 character tab spacing.

* 	No PHP shortcut tags ( <? or <?= or <% ).

* 	PHPDoc comments on functions and classes (all methods; declared properties
	when appropriate).

* 	Mandatory wrapped {}s around any code blocks. 
		Bad:
		if (true) 
			foreach($arr as $elem) 
				echo $elem;
	
		Good:
		if (true) {
			foreach($arr as $elem) {
				echo $elem;
			}
		}

* 	Name standalone functions using underscore_character().

* 	Name classes using CamelCase() and methods using lowerCamelCase().

* 	Name globals and constants in ALL_CAPS (TRUE, NULL, ACCESS_FRIENDS, $CONFIG).

* 	Use underscores / camel case to separate standard English words in
	functions, classes, and methods. (get_default_site(), ElggUser->isLoggedIn()).

* 	Space functions like_this($required, $optional = TRUE).

* 	Space keywords and constructs like this: if (FALSE) { ... }.

* 	Correctly use spaces, quotes, and {}s in strings: 
		Bad (hard to read, misuse of quotes and {}s): 
		echo 'Hello, '.$name."!  How is your {$time_of_day}?";
		
		Good:
		echo "Hello, $name!  How is your $time_of_day?"; 

* 	Line lengths should be reasonable.  If you are writing lines over 100 
	characters on a line, please revise the code.

* 	Use // or /* */ when commenting.

* 	No closing PHP tag (?>) at EOF unless after a heredoc. (Avoids problems with 
	trailing whitespace. Required after heredoc by PHP.)

** CSS **

* 	Use shorthand where possible:
		Bad:
		background-color: #333333;
		background-image:  url(...);
		background-repeat:  repeat-x;
		background-position:  left 10px;
		padding: 2px 9px 2px 9px;
		
		Good:
		background: #333 url(...) repeat-x left 10px;
		padding: 2px 9px;

* 	Use hyphens as separators in classes/ids, not underscores:
		Bad:
		.example_class
		
		Good:
		.example-class
	
* 	One property per line
		Bad:
		color: white;font-size: smaller;
		
		Good:
		color: white;
		font-size: smaller;
	
* 	Property declarations should be spaced like so: `property: value;`
		Bad:
		color:value;
		color :value;
		color : value;
		
		Good:
		color: value;

* 	Group vendor-prefixes for the same property together:
* 	Longest vendor-prefixed version first:
* 	Always include non-vendor-prefixed version:
* 	Put an extra newline between vendor-prefixed groups and other properties:
		Bad:
		-moz-border-radius: 5px;
		border: 1px solid #999999;
		-webkit-border-radius: 5px;
		width: auto;
		
		Good:
		border: 1px solid #999999;
		
		-webkit-border-radius: 5px;
		-moz-border-radius: 5px;
		border-radius: 5px;
	
		width: auto;

* 	Group declarations of subproperties:
		Bad:
		background-color: white;
		color: #0054A7;
		background-position: 2px -257px;
		
		Good:
		background-color: white;
		background-position: 2px -257px;
		color: #0054A7;


*** CODING BEST PRACTICES ***

The following best practices make code easier to read, easier to maintain,
and easier to debug.  Consistent use of these guidelines means less guess
work for developers, which means happier, more productive developers.

* 	Adhere to "Don't Repeat Yourself" (DRY) principles of code design and 
	organization. If you are copy-and-pasting code YOU ARE DOING SOMETHING WRONG.
	If you find a block of code that you want to use multiple times, make a 
	function.  If you find views that are identical except for a single value,
	pull it out into a generic view that takes an option.

* 	Whitespace is free.  Don't be afraid to use it to separate blocks of code. 
	Use a single space to separate function params and string concatenation.

* 	Use self-documenting variable names.  $group_guids is better than $array.

* 	Functions returning an array should return an empty array instead of FALSE
	on no results.

* 	Functions not throwing an exception on error should return FALSE upon 
	failure. 

* 	Functions returning only boolean should be prefaced with is_ or has_ (eg,
	elgg_is_logged_in(), elgg_has_access_to_entity()).

* 	Ternary syntax is acceptable for single-line, non-embedded statements.

* 	Use comments effectively.  Good comments describe the "why."  Good code
	describes the "how."  Ex:
		Not a very useful comment:
	
		// increment $i only when the entity is marked as active.
		foreach($entities as $entity) {
			if ($entity->active == TRUE) {
				$i++;
			}
		}
	
		Useful comment:
	
		// find the next index for inserting a new active entity.
		foreach($entities as $entity) {
			if ($entity->active == TRUE) {
				$i++;
			}
		}

* 	Use commit messages effectively.  Be concise and meaningful. Ex:
		Not meaningful:
		Small fix to groups.
	
		Meaningful:
		Fixes #1234: Added missing ) that caused a WSOD on group profile page
		when logged out.

* 	Commit effectively: Err on the side of atomic commits.  One revision with
	many changes is scary.


*** DEPRECATING APIs ***

Occasionally, functions and classes must be deprecated in favor of newer
replacements.  Since 3rd party plugin authors rely on a consistent API,
backward compatibility must be maintained, but will not be maintained
indefinitely as plugin authors are expected to properly update their
plugins.  In order to maintain backward compatibility, deprecated APIs will
follow these guidelines:

* 	Incompatible API changes cannot occur between bugfix versions 
	(1.6.0 - 1.6.1).

* 	API changes between minor versions (1.6 - 1.7) must maintain backward
	compatibility for at least 2 minor versions.  (1.7 and 1.8. See 
	procedures, below.)

* 	Bugfixes that change the API cannot be included in bugfix versions.

* 	API changes between major versions (1.0 - 2.0) can occur without regard to
	backward compatibility.

The procedure for deprecating an API is as follows:

* 	The first minor version (1.7) with a deprecated API must include a wrapper
	function/class (or otherwise appropriate means) to maintain backward
	compatibility, including any bugs in the original function/class.
	This compatibility layer uses elgg_deprecated_notice('...', 1.7) to log
	that the function is deprecated.

* 	The second minor version (1.8) maintains the backward compatibility
	layer, but elgg_deprecated_notice() will produce a visible warning.

* 	The third minor version (1.9) removes the compatibility layer.  Any use of 
	the deprecated API should be corrected before this.

The general timeline for two minor releases is 8 to 12 months.