string(19) "ViewArticleOrg.html" Project Coding Standards : roojs.org - open source
 These are general notes applied to Projects that I work on, the main intent is to try and make the code maintainable over a long period of time.

PHP Code

  • Follow PEAR Standards Which are (with slight additions):
    • Indenting
      • 4 spaces (Not tabs)
      • Do not over indent
      • Try and keep within 80 chars wide
        Bad:
        $ret = $this->callSomething(array('xxx' => 'yyyy',
                                          'zzz' => 'aaaa' ....
         
              
        Good
        $ret = $this->callSomething(array(
              'xxx' => 'yyyy',
              'zzz' => 'aaaa' ....
        ));
              
    • Control Structures
      • If / else
        • No short ifs (eg. always use brackets)
        • do not use else if you have returned or used break; within a block.
          if ((condition) || (condition2)) {
              statement;
              statement;
          } else { 
              statement;
          }
           
          if ((condition) || (condition2)) {
              statement;
              statement;
          } elseif  ((condition) || (condition2)) { 
              statement;
          }
           
          // for long if statements
          if ((condition) 
                  || (condition2)    //8 space indent  
                  || (condition2)
                  || (condition2)
              ) {       // closer and opener 4 space indented
              statement;
              statement;
          }
           
           
          
        • break out or return rather than nesting if statements
          When inside methods or loops, use return or break, rather than have heavily nested if blocks
          for ($i = 0; $i < 100; $i++) {
              if (!$x) {
                  break;
              }
              if ($x < 10) {
          	statement;
          	statement;
                  break;
              }
              ......
          }
           
           
          function get($arg) 
          {
               $do = DB_DataObject:;factory('xxxx');
               if (!(int)$arg || !$do->get($arg)) {
                    return HTML_FlexyFramework::factory('Error/404', array('errors'=> .....);
               }
               .....
                    
          • BAD:
            function get($arg) 
            {
                 $do = DB_DataObject:;factory('xxxx');
                 if ($arg != "") {
                     if ($do->get("id",$arg)) {
                          ... do stuff ...
                     }
                 }
            }
                        
      • Switch Case 
        • indent once for case, and once for statements
        • extra line after break; except on last one.
          switch ($x) {
              case 1:
                  statement;
                  break;
              
              case 2:
                  statement;
                  break;
           
              default:
                  statement;
                  break;
          } 

      • Method Calls
        • No space between method name and ( and first paramenter
        • space after each,
        • avoid more than 2 arguments to a method (use named arguments)
        • dont over indent arguments
        • commas after argument, not before
        • extra space can be added before return assignment to enhance readability

          $ret = $this->callSomething($a, $b);
           
          $ret = $this->callSomething(array(
                      'xxx' => 'yyyy',
                      'zzz' => 'aaaa',
                 ));
           
          $abcdefg = $this->find();
          $xxx     = $this->fetch();
                   
      • Method Definitions
        • first { is on line after definition
        • return from method sooner rather than later

          function callSomething($a, $b)
          { 
              if ($a) {
                  return false;
              }
              statement;
              
          }
          
        • return should not use () brackets around return values
      • Class Definitions
        • first { is on line after definition
          class myclass extends anotherclass
          { 
              function .......()
              {
              }
              
          }
                    



    • Comments
      • Do not commit commented out code
      • Method / Class header Comments use /* */ style comments
      • Class Properties can use docbook comments or // comment after the defintion
        class something
        { 
            var $fred;  // this is fred's var
        }
        
        Longer comments should use /* */ style docbook comments

      • Methods (unless FlexyFramework get()/post()/getAuth()) require standard phpdoc comment definitons (detailing arguments) preferably with simple examples of usage.
      • Comments inside of Methods should use // style comments to enable commenting out blocks of code for debugging using /* */ style comments
          • # bash/perl style comments should not be used.
    • Include  / Require
      • include / require_once etc. should not use ( ) around arguments
      • do not attempt to cope with require_once failing (by hiding it or testing include path) 
        include 'MyClass.php
      • Always use full relative path rather than short path
        require_once 'MyProject/MyClass.php';
        //rather than
        require_once 'MyClass.php'
         
         
        
    • PHP Code tags
      • Do not use short tags (<?)
      • Do not add the closing tag to the end of  files (?>) as it often can break sessions

    • Naming Conventions
        • Classes
          • use Caps_First with _ between names. (exceptions may occur when part of the name relates to an extenal object - eg. a database table)
              • Good: Some_MyProject, Some_Project_Driver
              • Bad: SomeProjectThatWorks, SomeProject_ProjectDriver
          • Underscore  heirachy should relate to extends pattern where feasible
              • Fred_Driver extends Fred
              • Fred_Driver_Postgres extends Fred_Driver
          • Libraries should always use a type prefix (eg. HTML_/Net_/DB_ etc.)
          • Projects should always have a non-generic name, and all classes should extend that (see later)
        • Functions
          • DO NOT USE!
        • Methods / Variables
          • Always use studlyCaps with first letter lower, and latter ones upper case.
              • Good: someMethod(), $this->someVar;
              • Bad: some_method(), SomeMethod(),  $this->some_var
          • Prefix private methods with underscore (these may use _ in names as well.
            • _my_private_method()
            • $this->_my_private_var;
          • Avoid pass-by-reference, unless absolutely necessary.
        • Constants
          • Built in constants should use lower case
            • eg. true, false, null
          • User Defined constants should be associated with a class and all uppercase
            • eg. MYPROJECT_TESTFLAG
        • Global Variables
          • Should always be associated with a class
          • Should not be accessed from outside the owning class.
          • Should be initialized when the class is loaded (in global space)
    • File Formats
      • Should use UNIX line endings (\n) not (\r\n)

  • Class inheritance
    • Avoid to many levels of extends, in general code (above 3 should be extremely rare, and well justified.)

  • Require / Lazy loading
    • Utilize Lazy loading, avoid requiring files at the start of each class/page file.
    • Avoid long lists of require_once's at the top of each file.
    • Avoid assuming that a class is loaded, help the end user out by explicitly saying where some class comes from.

  • Mixing PHP + HTML/Data
    • Avoid embedding large quantities of data in PHP code. Use JSON/INI or simple text files if possible
    • Avoid where possible echo'ing HTML  or text from within classes. Always prefer adding to the Templates any HTML
      • Exceptions may occur when dealing with HTML/XML Trees.
      • Only use "echo", not "print" (as this makes checking for xss vectors simpler)
    • Avoid placing validation messages in the PHP code, (This excludes system failure type messages), as this makes doing translated templates with user error messages easier.

      use
      $this->warning['messagename']= true;
       
      and in the HTML:
       
      <p flexy:if="warning[messagename]">Display the warning / error</p>
  • Method Arguments
    • Maximum of 3, over that, use named arguments array.
    • Prefered Max is 2 arguments.
    • Avoid pass by reference, unless absolutely necessary (it makes code more difficult to follow) - return arrays or associative arrays.
  • XML / HTML
      • use the DOM / SimpleXML extensions rather than XML_Tree/XML_Parser.

  • DataObjects:
    • reusable chunks of  database specific code should go in the DataObjects.
      • Favour moving joinAdd constructs into the DataObject for reuse later or optimization, by manually modifying the $this->_joinAdd variable.
    • DataObjects should be initialized using DB_DataObject::factory(....)
    • DataObjects should not make direct use of input variables (eg. $_REQUEST/$_POST/$_GET etc.)
    • Do not use cachedGet()
    • For frequently called gets/fetches, consider defining a cached() method.
    • return value for $do->get() can be considered to be boolean, and tests should look like this:
      if(!$do->get($id)) {
          $this->error = ....
          return HTML_FlexyFramework::run('Error/404');
      }
            
    • $do->get(), can work out the primary key, so do not use it with $do->get('id',$arg);
    • use $do->find(true) when fetch a single result, (rather than using $do->find() / $do->fetch();
    • user $do->escape($data) on all data going to whereAdd() or similar methods, where the data can not be trusted (eg. user input/reading from a file.)


  • FlexyFramework
    • Implement and use Page base classes
      • A project one (non-authenticated) eg. MyProject extends HTML_FlexyFramework2_Page
      • A authenticated one, eg. MyProject_Authenticated extends MyProject
    • Page Classes should avoid deep directory trees:
      • MyProject_Products_Search_Edit (MyProject/Products/Search/Edit.php) == BAD
      • MyProject_ProductsEdit (MyProject/ProductEdit.php) == GOOD.
    • Page Constructors
      • __construct or class constructors should not be used (it makes the code to difficult to follow)
    • Unused shared base classes (eg. MyProject_SomePage extends MyProject_SomePageBase)
      • Avoid these, merge the code into an existing class (either the project one or a relivant page)
    • Avoid calling parent::get() or parent::post(), make explicite methods for actions, and call them specificily in child classes. (This enables top level get/post to return 404 errors on pages not found)
    • Do not use the modules toolkit - it was a bad idea, and is only ther for Backwards compatibility
      (you should write your own project based loadModules routine, that loads any modules you intend to use)
    • Do not make error handling a module Errors should be handled with flags (or values with context data, not messages) and be part of the page template

  • Emailing
    • Should use standard Email template code, and not hard code Email into PHP. (see Flexy tricks)
    • Be careful of data injection in to Email templates
      From: { t.someemail } <test@xyz>
      Subject: A test
      .....
            
      In the above example ensure that { t.someemail } does not have line breaks comming from user input!

  • Errors
    • Do not use @ to suppress errors unless absolutly necessary.
    • in PHP4
      • use PEAR::raiseError(), lazy loaded.
      • consider outputtting debuging information via trigger_error(E_USER_WARNING) (when debugging is turned on.)
    • in PHP5,
      • trigger_errror() is for programming errors / debug warnings.
      • Exceptions for everything else (Probably PEAR_Exceptions)
        • Try and catch all exceptions where they are thrown. - try and avoid global catchalls.
        • use function arguments to determine if Exceptions should be converted to return values, or run
          HTML_FlexyFramework::run('error',array('errors'=> array('problem_with_xxx'=>true)));

  • Constants
    • Should not be used as configuration variables
    • Normal usage should be to assist in the readability of code, normally in cases where a set of numerical states can be represented by a textural word (eg. SMTP_STATE_READY_TO_SEND = 1)
    • Naming should follow PEAR standards (eg. with class name prefixed - or in PHP5 just use class constants.)

  • Configuration
    • Most configuration is automatically detected by the Framework, however other configuration settings may originate from
      • bootstrap (index.php) hard coded into the Framework constructor
      • bootstrap (index.php) may choose to load a .ini fire to help building the constructor
      • FlexyFramework's ConfigDir is depreciated.
      • If you do use configuration files, load them in the bootloader, and pass them as an argument to the HTML_FlexyFramework::factory() startup, eg.
        $siteconfig = parse_ini_file('/etc/flexyframework/myproject_config.ini');
        HTML_FlexyFramework::factory(array(
        	......
        	MyProject => $siteconfig,
        ));
                
    • Read Access
      • Global configuration is available by:
        $opts = HTML_FlexyFramework::get()->classname;
      • DO NOT write or alter the global configuration.

  • Sessions
    • All sessions should be stored associated with the class they are used in, and try not to access them directly from outside the class.. eg,
      class MyProject_TestPage extends MyProject 
      {
       
           function get()
           { 
               $_SESSION[__CLASS__]['settings'] = .......
      	 

  • Debugging
    • at present the recommendation is to use a debug flag on a class, and trigger_error with E_USER_WARNING. this can be caught by the error handler if neccessary and reformated.

Javascript

  • all js files go in [templatedirectory]/images/js/ (unless using Roo Pman system)
    • This enables the Flexy url-rewriter to fix src locations.
    • Pman Project specific 
      • Files go in module directory, filename matches class name eg. Pman.Tab.XXX goes in Pman.Tab.XXX.js
      • At present Filename/Classnames start with Pman.Tab.* or Pman.Dialog.* depending on what the class deals with
      • Library components still go in images/js/ - usually are extensions of a Roo element.

  • functions should only be used on the page that they are called.
    • Therefore, no functions should appear in .js files

  • Included js files should be classes.
    • Classes are of three types
      • Static classes Eg. for layouts or Dialogs (less so now)
      • Implementations of Roo.Observable, created as follows
        Pman.Dialog.XXX = new Roo.Observable({ 
             xxx : function () { .... },
             yyy : 1
        });
      • Classes which can be extended - these should use Roo.extend() syntax and have a constructor.
    • Code should, in general, follow pear standards (re indentation etc.)
    • Global variables
      • should be avoided where possible - Tie a global resorce to a static class, or class instance
    • Strings
      • Use single Quotes for non-translatable strings
      • Use double Quotes for strings that require translation

  • Class names should use the Project(eg. Pman), Type(eg. Dialog),  Module name (eg. Builder), then the specific name
    • eg. Pman.Dialog.BuilderDatabaseModelView
    • names like Q3, ERM are bad, BuilderQuizType3 is better
    • Avoid generic Class names, eg. 'Util', 
  • Class properties and methods (RooJS library / and calling code)
    • properties should generally be lower case, and use underscore 
    • methods should start with lowercase and use camelCase (uppercase second word start)
  • Should assume availablity of baseURL and rootURL will be provided by
  • <flexy:toJavascript baseURL="baseURL" rootURL="rootURL"/>
  • Javascript included .js files should avoid running code directly, they should be initiated manually by the page.
    • BAD = .js file that modifies the whole layout when it loads
    • GOOD = registering modules with Pman, or implementing the Roo.Document.on('load', ... event)
  • For AJAX transactions with PHP use the Roo.Ajax.request(), or Pman.request()
  • (PHP/Pman project) Use the the method $this->jdata(), $this->jok(), $this->jerr() to send back data
  • avoid using eval(), unless absolutely no good alternative exits (see. Roo.decode())


General Coding (PHP / js)

  • Avoid mapping names (especially databases columns to other names)
    • BAD :  this.tbx0 = document.getElementById('username');
    • GOOD : this.username = document.getElementById('username');
    • EVEN BETTER this.elements.username  = document.getElementById('username');
      • This can then be automated by for[each] loops...



HTML (and Flexy Templates)

  • Indent Code with 2 spaces
  • Try and keep to less than 80 characers per line
  • Layout Tags 1 per line etc.
    • Example:
      <div>
        <table>
          <tr>
            <td>XXXX</td>
          </tr>
        </table>
      </div>
            
  • Prefer CSS over Tables (or keep table usage to a minium) - use class="xxxx" rather that id="xxx" to enable reuse of styles
    • except when really representing tabular information.
  • Generally Avoid usage of absolute positioning of CSS.
    • (this can get messy when reflowing with javascript)
  • Use { baseURL } and { rootURL } in links / post locations
  • Use  the images/ folder for images, so the Template engine can rewrite the url.
  • Break complex pages into two templates and duplicate HTML rather than conditionally displaying large chunks,
    eg. BAD:
    { if:step1 } 
    .........
    { end: }
    { if:step2 } 
    .....
    { end: }
    ........
        

XUL

  • do not use commandset/command, use oncommand with javascript call.

CSS

  • Should not in general be embeded into HTML file.
  • Author / Copyright should be at top of file once, not in multiple places
  • Do not use non-english characters in comments.
  • should be located in [templatedir]/images/css/ and referenced by href="images/css/....." so the url can be rewritten by the template engine.
  • should be indented as follows
    .stylename
    {
    		display: block;
    		font-color: red;
    }
    Note the large indentation on the definitions.
  • Should be split into seperate files depending on their purpose (eg. leftnav.css / topnav.css etc.)
  • Should be carefull when redefining standard HTML elements, it is prefered to use a base style, and refer to subelements: eg.
    .mybody h2 
  • Should generally avoid using #id - prefer classes

SQL 



    Variable names (Stored procedures)

        Input arguements : i_***
        Local Variables  : v_***

        Cursor Variables : c_****
        Records          : r_****
        Cursor Names     : cursor_****


    Indent 
     - 4 spaces
     - Indent the body, eg. everything inside of 'BEGIN'
     - Statements that span more than one line, every subsequent line should be indented

    Alignment
     - a sequence of A = B, A= B... the right hand side should be space apart so that it aligns
      eg.
        invbuy_transdate    = new_inv_buy.transdate,
        invbuy_qty          = new_inv_buy.qty,
        invbuy_totalcost    = new_inv_buy.totalcost,

      variable type alignment- types should be seperated from variable name.
        v_trans_qty         numeric(18, 6);
        v_new_invhist_id    integer;
        
    Case
     - Use uppercase for SQL keywords.

    Line length
     - try and keep it under 80 characters

    WHERE conditions
        one compare per line.
        AND / OR keywords on seperate lines
        () brackets - on there own line 
        Wrap groups of AND/OR with () brackets do not rely on operator precidence


    INSERT VALUES
        max two columns per lines
        add extra line break after each pair of lines
        values should match layout

    Comments
        As much as possible.

    Follow us on