=============================================================================
Copyright 2003 INCOGEN, Inc.

This program is distributed under the terms of the BSD License (see the
license.txt file that was distributed along with this file for details).

INCOGEN, Inc. asks that credit be given when this code is used, and if
bug fixes or other beneficial changes are made to the code, that unified
diff patches (diff -uNr original-tree new-tree) be submitted. Please
submit patches to opensource@incogen.com.

BugPort 1.X BugPort Developer Information
Please consult the system documentation for more general information

Douglas Q. Hawkins (2003/12/04): 1.001
=============================================================================

This document is intended for use by developers wishing to extend BugPort.

Developers will probably find it useful to consult file-structure.txt before
reading this document.

=============================================================================

Importation System
   BugPort uses it own custom class imporation system.  The following
   functions are exposed by the imporation system...

   All files in the top-level of php_classes/Common are loaded automatically
   and do NOT need to explicitly loaded.

   importClass( 'Foo.Bar' )
      will 'require()' the PHP file php_classes/Foo/Bar.php will also load
      php_classes/Foo/CONSTANTS.php if it exists (before the class is loaded)

   importConstants( 'Foo' ) will 'require()' the PHP file php_classes/CONSTANTS.php

   importLibrary( 'foo' ) will 'require()' the PHP file
      php_classes/Libraries/fooLibrary.php
      For all intents and purposes, all files in php_classes/Libraries are
      already loaded, so it should not be necessary to invoke this method.


Class coding conventions
   Almost all abstract classes are prefixed with A.  For example: AView
   Any new abstract classes should be prefixed with A.

   All interfaces which are documented concepts with no implementation
   are prefixed with I.  For example: IIterator

   All class must directly or indirectly inherit from Common.Object because
   certain aspects of the system are dependent on additional features
   provided by the Object class.

   All classes must load (importClass) their parent classes
     (The exception is Object which is auto-imported).

   Whenever a class is instantiated, the class should be imported immediately
   before it is instantiated.
   For Example:
   importClass( 'Foo.Bar' );
   $bar =& new Bar();
   ...

   Whenever a static method of a class is invoked, the class should be
   imported immediately before it is accessed.
   For Example:
   importClass( 'Foo.Singleton' );
   $instance =& Singleton::getInstance();

   Optional arguments are given a default value in the argument list
   of UNSPECIFIED, so that clients may selectively include optional arguments
   by passing UNSPECIFIED for arguments for which they wish to use the default.

   For Example:
      //Definition
      function foo( $bar = UNSPECIFIED, $baz = UNSPECIFIED )
      {
         ...
      }
      //Invocation
      foo( UNSPECIFIED, 3 );


Basic Flow
   The one PHP script php/index.php drives the flow of BugPort.  It should
   NEVER be necessary to alter php/index.php or add files to the php
   directory.  php/index.php simply initializes the class loader and
   then loads a Controller class and defers all browser requests to
   the Controller for processing.

   The Controller examines the GET parameters provided to determine
   which BugUI.AView, BugUI.AForm, or BugUI.AOperation
   class to instantiate.  It then invokes the appropriate methods on the
   created object and then returns the HTML of the current AView by
   invoking AView->getHTML.

   All concrete extensions of AView, AForm (AForm extends AView) must be
   placed in BugUI.Views.

   All concrete extensions of AOperation must be placed in BugUI.Operations.


HTML Generation
   All HTML in BugPort is generated through a series of HTMLComponents.
   HTMLComponents are conrete classes derived from
   HTMLComponents.AHTMLComponent.

   The HTMLComponents package provides a series of classes for building
   common HTML elements.

   HTMLComponents of general value are ...
      HTMLComponents.Text
      HTMLComponents.LongText
      HTMLComponents.LongTextBox2
      HTMLCompoennts.CompositeHTMLComponent
      HTMLComponents.Table
      HTMLComponents.TwoColumnTable
      HTMLComponents.FourColumnTable
      HTMLComponents.Links.ExternalLink
      HTMLComponents.Images.AImage (and its children)
      HTMLComponents.LightForms.Text
      HTMLComponents.LightForms.TextComponent
      HTMLComponents.LightForms.SelectComponent

AView and AForm

   Brief introduction
      AView classes (which are themselves) HTMLComponents assemble a series
      of HTMLComponents into a composite AHTMLComponent (like
      CompositeHTMLComponent, Table, TwoColumnTable, or FourColumnTable)
      and then return the getHTML of the composite when they are to
      be rendered.

      A link to display a given AView may be obtained by constructing an
      instance of the AView and requesting its displayOperation by invoking
      AView->getDisplayOperation.  The AOperation returned is an
      AHTMLComponent that produces a link to the original AView.

      AForm is an extension of AView which adds additionally capabilities
      for producing pages containing a form.  The Controller facilitates the
      flow of AForm classes reducing the burden implementing a form.

   Extending AView
      A concrete AView class may be created by...
      1 - Creating a new file in BugUI.Views.AView that extends BugUI.AView
      2 - Adding the method getHTML to the class.
          getHTML produces the HTML contents of this page.
          The produced string should not contain <html>, <body>, <title>,
          or headers and footers those are added automatically by
          the Controller.
      3 - Adding the method getTitle to the class.  getTitle must return
          a user-presentable title for the view.
      4 - Overriding getParameters with additional information needed to
          reconstuct this AView.
      5 - Optionally, overriding isEnabled if there are restrictions on
          who may access or when this AView is enabled.
      Additional capabilities are also available please consult header comments
      in the source.

   Extending AForm
      A concrete AForm class may be created by...
      1 - Creating a new file in BugUI.Views.AView that extends BugUI.AForm
      2 - Adding the method _getBodyHTML to the class.
          _getBodyHTML produces the HTML contents that go inside of
          the produced <form> tag without the submit button.
      3 - Following steps 3-5 of Extending AView
      4 - Adding the method _loadData to load any data from the
          $_REQUEST into $this
      5 - Optionally, overriding _isValid if further validation is needed
          (Please consult the header docs in the source)
          If _isValid was overridden then _getErrors will also need to
          be overridden.
      6 - Adding the method _execute to actually process the form input
          information which is now stored in $this.
      7 - Adding the method &_getNextView to return the View to display
          after this form has been executed.
      Additional capabilities are also available please consult header comments
      in the source.

Business Objects
   For simplicitly, BugPort does not draw a distinction between the
   business object class and its persister.  So, the class and/or its
   prototypical instance act as Factories for instances of the class which
   map to actual database rows.

   BugPort manages all data through a series of business objects.  These
   objects hide the complexities of database table manipulation and
   cache management from the UI code.

   All business objects are derived from the abstract class Database.ADatabaseItem
   which provides basic database persistence facilities.  All ADatabaseItems
   support the following methods ...

      public String getIdentifyingString()
         This method provides a user-presentable String to that
         identifies this ADatabaseItem.

      public boolean isNew()
         This method indicates if this ADatabaseItem is "new" which
         means that it has NOT been persisted to the database.

      public boolean isNull()
         indicates that this ADatabaseItem represents a dummy instance or
         an unmatched ID in the database

      public int getPrimaryID()
         provides the integer that represents the ID for this ADatabaseItem or
         returns NON_EXISTENT_ID if this ADatabaseItem isNew or isNull

      public Collections.IIterator doSearch(
         [whereClause], [binds], [orderBy], [join] )
         provides an IIterator that contains the elements matched by the
         specified database query.

      public store()
         Persists any changes that have been made to this ADatabaseItem
         to the persistent store.  If this ADatabaseItem isNew, it will
         be inserted; otherwise, its corresponding row will be updated.
         store is NOT usually called directly.  It is called at needed
         by business logic methods.

   Additionally, each ADatabaseItem class supports...
      public static <thisClass> getPrototype()
         which returns a prototypical instance of this ADatabaseItem class.
         The prototypical instance may then be used to make queries against
         the database.

   The following ADatabaseItem classes exist in BugPort...
      Shared.Project
      Shared.User
      Shared.UserType
      Bugs.ADevelopmentItem which has the concrete children...
         Bugs.Defect
         Bugs.Feature
         Bugs.Task
      Bugs.Attachment
      Bugs.Category
      Bugs.ClientType
      Bugs.Comment
      Bugs.CommentType
      Bugs.Frequency
      Bugs.Platform
      Bugs.Priority
      Bugs.ReportType
      Bugs.ServerInstance
      Bugs.Severity
      Bugs.State
      Bugs.Subproject
      Bugs.Version

      Each of these classes defines additional methods for manipulating
      the business object in question.
