You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 13 Next »

Work In Progress

This Coding Guide is a work in progress. Furthermore, existing code may not meet these guidelines. However, all new code must, including any refactoring of existing code.

Background

A common coding style ensures consistency of the look and feel of the code, regardless of who wrote a given portion. This, in turn, increases readability, makes the code easier to understand, and makes the project look more polished and professional.

Many of the style decisions here are arbitrary. The purpose of this document is not to answer the general question "What is the proper number of spaces to indent code?" but the specific question "What number of spaces is code indented in the COmanage codebase?" (The answer is 2, described below.)

For examples of other coding style guides, see The Zend Framework (PHP), Apache (C), and Google (various).


General

  • Use the most compact notation that is still easy to understand.
  • Follow CakePHP guidelines, such as for file names.
  • If there's a reason to have an exception to these guidelines in the code, then there's a reason to update this document.

Correct Case

Methods

Camel case with lower initial:

$this->bindModel();
$this->initializeParentCou();

Variables

Camel case with lower initial:

$cou = 'whatever';
$couAllowed = array();
$isInCou = false;

Avoid very short names except in very compact contexts, such as for loops.


Quotes

Single Quotes

Single quotes are used when using a string as an index.

$foo['this']['that'];

Double Quotes

Double quotes are used when quoting a string in other contexts.

$txt = "This is some text.";

Whitespace

Indentation

Indentation is in increments of two (2) spaces. Tabs are not used.

function foo($i)
{
  $j = $i + 1;

  if($j > 1)
    bar($j);
}

Separation of Characters

In general, whitespace is omitted where it is not necessary. For example:

function foo($a);

$a = $b['foo'];

And not:

function foo ( $a );

$a = $b['foo'];

The exceptions are where extra whitespace dramatically increases readability:

// Argument lists, arrays, etc
passingArguments($first, $second, $third);

// Nested array references
$a = $b[ $c['foo'] ];

// If-then-else shorthand
return($a ? $a : $b);

Separation of Statements

In general, all statements, procedures, functions, etc are separated by a blank line. However, "like" statements (such as blocks of variable declarations or calculations performed as part of an operation) are grouped together without an intermediate blank line.

  part of previous function;
  end of previous function;

  return(foo);
}

function textFunction()
{
  $var = 0;
  $othervar = 1;

  beginning of next function;

End of File

One or more newlines at the end of a file may cause errors (the page does not render) on some systems, including MAMP and Ubuntu, and so must be avoided.


Alignment

Curly Braces

Curly braces ({,}) are placed on new lines. Curly braces may be omitted only when each contained clause is one line:

OK:

if($a > 0)
{
  return(true);
}
elseif($b > 0)
{
  return(false);
}

if($a > 0)
  return(true);
elseif($b > 0)
  return(false);

Not:

if($a > 0)
{
  $a++;
  $foo = bar;
}
else
  return(false);

Parentheses

Parentheses are used even when considered optional. The exception is return statements, since return is a language construct and not a function.

OK:

print ($a ? $a : $b);

return false;

Not:

print $a ? $a : $b;

return(false);

When creating a list within parentheses, such as when constructing an array or passing parameters to a function, if the entire list is not readable on one line, indent one level and begin on the next line:

$v = array('small');
$w = array(
  "the beginning of a longer list",
  "the continuation of a longer list",
  "the conclusion of a longer list"
);

Hashes and Arrays

When constructing a hash, align on the => as much as possible:

$h = array(
  'A'  => "Option A",
  'B'  => "Option B",
  'YZ' => "Option YZ"
);

When constructing an array, align on the = as much as possible:

$args['foo']['bar']        = "Sushi";
$args['foo']['restaurant'] = "Hibachi";

Conditionals

if statements with complex conditionals should have each conditional on a new line, aligned with the previous conditional. Nested conditionals should be further indented.  Exceptions are made for those that are easy to read and fit on one line.

if(($a == $b)
   || (($a == $c)
       && ($d == $e))

Comments

Comment Delimiters

Comments are exclusively delimited with double slashes (//). The exceptions are the top of file comment, and that code may be temporarily commented with C-style comments (/* */).

Top of File

The top of each file must include the following header:

/*
 * COmanage Registry Foo Bar
 * Optional Brief Description
 *
 * Version: $Revision$
 * Date: $Date$
 *
 * Copyright (C) 2012 University Corporation for Advanced Internet Development, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under
 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 */

Note that $Revision and $Date are SVN keywords that must be set on a per-file basis. (They will not be updated automatically otherwise.) Don't add a new file with the revision and date copy and pasted from a different file.

Function Descriptions

Functions must have a comment block of the following form:

function view($id)
{
  // Retrieve a Standard Object
  //
  // Parameters:
  // - id: Object identifier (eg: cm_co_groups:id) representing object to be retrieved
  //
  // Preconditions:
  // (1) <id> must exist
  //
  // Postconditions:
  // (1) $<object>s set (with one member) if found
  // (2) HTTP status returned (REST)
  // (3) Session flash message updated (HTML) on suitable error
  //
  // Returns:
  //   Nothing

Comments and descriptions are written in normal English, except periods are omitted if there is only one sentence.

Parameters and Returns are simple lists, prefixed with a hyphen and space ({{- }}). Lists are in the order passed. If there are no parameters, indicate None with two leading spaces. If the function returns nothing, use Nothing with two leading spaces.

Preconditions and Postconditions are numbered lists, prefixed (#). If there are no preconditions or postconditions, use None with four leading spaces.

At some point, this format may change to an auto doc format.

Inline Comments

Comments should be included where it isn't patently obvious what is going on. Comments should be written in normal English using normal grammar and syntax.

  // We need to figure out what the person's name is as asserted by
  // the home organization, so pull it from the Org Identity.

When a code block relates to a detailed JIRA issue (eg: a bug or a specific change), link to the issue in the comment. Do not link to JIRA for big feature requests (those that encompass more than a small block of code).

  // This change is for CO-90210. Don't undo it!
  // https://bugs.internet2.edu/jira/browse/CO-90210

PHP-isms

No Short Tags

The full PHP tag must be used.

<?php some stuff; ?>

print, not echo

echo is a language construct, not a function, and so it's use within COmanage is deprecated to avoid unexpected behavior. (print is also a language construct, but behaves like a function.)


CakePHP-isms

Arrays as Arguments

Where an array is required as an argument (used very commonly in CakePHP), define the array first and then pass it.

Preferred:

$args['fields'][] = "MAX(ordr)+1 as m";
$args['order'][] = "m";

$o = $this->CoEnrollmentAttribute->find('first', $args);

Not Preferred:

$o = $this->CoEnrollmentAttribute->find('first',
                                        array('fields' =>
                                              array("MAX(ordr)+1 as m")),
                                        array('order' =>
                                              array("m")));

SQL Query Optimization

In general, use Containable Behavior to constrain what Cake is pulling from the database. Cake will usually try to pull a bunch of associated data, which may or may not match what you actually need in a given context. You can use Containable to specify exactly which associated data you want returned.

Don't return anything but CoPerson:

$this->CoPerson->contain();

Obtain OrgIdentity and Name:

$this->OrgIdentity->contain('Name');

Obtain OrgIdentity, Name, CO, and CO Groups the Org Identity is a member of:

$args['contain'][] = 'Name';
$args['contain']['CoOrgIdentityLink']['CoPerson'][0] = 'Co';
$args['contain']['CoOrgIdentityLink']['CoPerson']['CoGroupMember'] = 'CoGroup';
$orgIdentities = $this->OrgIdentity->find('all', $args);
  • No labels