------------------------------
-- Class design for cdb.sql --
------------------------------
v.1.8

Written by Patrick Walsh (patrick@phpgroupware.org)


Changelog
---------

v.1.8
	- Added comments to class definitions that note the functions
	  inherited from generic.class.php    

Intro
-----
    This file is intended to compliment the cdb.sql and 
cdb.sql-README.txt files.  It proposes a class structure for the 
phpGroupWare project for interface with the data structure.  This would
be a part of the API.

    The goal is to provide phpGroupWare developers with full access to
all the data in the contact database while also providing an easy-to-use
programming interface.  

    Initially two API's were discussed, the simple API that would always
be available to developers, and the advanced API, which developers would 
need to specifically add before gaining access to the functionality.

    In writing this proposal I'm going to try to combine the simple and
advanced API's into one simple but all powerful API.

    One note: I've turned all properties into get and let functions a la
Microsoft's COM interfaces.  I don't advocate them, but they allow us to
provide read-only properties without confusing properties and functions.
Also, by using functions for the property change functions, we can set
dirty flags and reduce updates.


Requirements
------------
    Preface: this db design allows individual contacts and organization
             contacts as well as associations between organizations and
             individuals.  Since in many respects an individual contact
             and an organization contact function similarly, I will be
             referring to the combined concept of organizations and 
             individual contacts as entities.

                     Entity == Organization || Contact

    1. Mechanism for adding entities.
    2. Mechanism for deleting entities.
    3. Mechanism for searching for an entity by any criteria (any?) and
       returning an array of entities matching the criteria.
    4. Mechanism for editing relationships and properties of any entity.


Class Structure
---------------
    The only meaningful interface to the potential plethora of 
information for any given entity is a class structure.  The design of
this class structure can make or break this app.  I propose a root
entity class.  An entity object contains either an organization or a 
contact.  Both the client and organization objects contain only their
"main" information and use subclasses to handle extended information.
The extended information is only loaded when needed.  The interface
to the classes will be specified below, but the class hierarchy will 
look like this:

    entity.class
       organization.class
           organization.meta.class
           organization.client.class
           organization.location.class
       contact.class
           contact.meta.class
           contact.client.class
           contact.personal.class
               languages.class
           contact.internet.class
           contact.phone.class
               phone.class
           contact.address.class
               address.class
           
    Note that these classes do not line up exactly with the tables.  This
is because the main class will include the Notes and Category 
information.


Class Interfaces
----------------

 - entity.class functions -
     get_type() returns "organization"|"contact"
     let_type(string)
     get_organization_data() returns organization.class
     get_contact_data() returns contact.class

 - organization.class functions -
     id() returns int 
          function used to obtain the org id.  if no org is loaded in
          the class, this returns zero.  This function is inherited, do
          not create it.
     create(string name) returns int
          creates a new org with name name.  on success it returns the 
          new org id, zero on failure
     save() returns boolean
          used to commit changes to the object to the database.  returns 
          true on success, false on failure.
     load(int id) returns boolean
          used to populate the object with the properties from the 
          id record in the database.  returns true if successful and
          false on failure.  failure would happen when the current user
          does not have sufficient read permissions or when there is no
          such id.
     exist(int id) returns boolean
          used to test and see if there is a database entry for the given 
          org id.  returns true if it exists.  this checks the status
          flag in the organization_meta table to make sure the record has
          not been marked for deletion.  This function is inherited, do
          not create it.
     delete() returns boolean
          marks the current org for deletion.  returns true if 
          permissions allow current user to perform the operation and the
          status flag was successfully changed to Deleted.  A cron job,
          or some routine admin function should go through the meta table
          and delete all marked for deletion after a certain time has 
          elapsed.  also needs to remove all references by contacts, if
          any.
     can_read(int id) returns boolean
          tests current user's read permissions on org id.  this function
          is inherited.  do not create.
     can_write(int id) returns boolean
          tests current user's write permissions on org id.  if no id is
          passed, or zero is passed, the currently loaded org, if any, is
          tested for write permissions.  this function is inherited.
     get_client_data() returns organization.client.class
     get_meta_data() returns organization.meta.class
 
     get_name() returns string
     let_name(string)
     get_locations() returns array of strings (location id/location name 
          key/data pairs)
     get_location_data(int id)
          returns the organization.location.class with phone/address
     get_home_page() returns string
     let_home_page(string)
     get_network_name()
     let_network_name(string)
     get_gov_id() returns string
     let_gov_id(string)
     get_categories() returns array of strings
     let_categories(array of strings)
     get_note() returns string
     let_note(string)

 - organization.location.class functions -
     save() returns boolean
          used to commit changes to the object to the database.  returns 
          true on success, false on failure.
     load(int id) returns boolean
          used to populate the object with the properties from the 
          id record in the database.  returns true if successful and
          false on failure.  failure would happen when the current user
          does not have sufficient read permissions or when there is no
          such id.
     create(int type, [string number]) returns int
          creates a new phone number of type type.  on success it 
          returns the new phone id, zero on failure

     get_city() returns string
     let_city(string)
     get_street() returns string
     let_street(string)
     get_country() returns string
     let_country(string)
     get_postalcode() returns string
     let_postalcode(string)
     get_number() returns string
     let_number(string)
          
 - organization.meta.class functions -
     save() returns boolean
          used to commit changes to the object to the database.  returns 
          true on success, false on failure.
     load(int id) returns boolean
          used to populate the object with the properties from the 
          id record in the database.  returns true if successful and
          false on failure.  failure would happen when the current user
          does not have sufficient read permissions or when there is no
          such id.
     date_created() returns date
     date_modified() returns date
     created_by() returns ?  auth user object?  user id?
     version() returns int
        this will be used in the case of changed db formats to facilitate
        smooth transitions of data
 
     get_status() returns string
        one of "active," "pending," or "deleted"
     let_status(string)
     get_file_as() returns string
     let_file_as (string)
        defaults to "last_name, first_name"
     get_followup_status() returns int
     let_followup_status (int)
     get_keywords() returns string
        comma delimited list
     let_keywords(string)
     get_group_access() returns int
        ????  perhaps this should be a string?  controls on access?
     let_group_access(int)
     
 - organization.client.class functions -
     save() returns boolean
          used to commit changes to the object to the database.  returns 
          true on success, false on failure.
     load(int id) returns boolean
          used to populate the object with the properties from the 
          id record in the database.  returns true if successful and
          false on failure.  failure would happen when the current user
          does not have sufficient read permissions or when there is no
          such id.
     get_account() returns string
     let_account(string)
     get_billing_info() returns string
     let_billing_info(string)
     get_referred_by() returns string
     let_referred_by(string)
     get_customer_id() returns string
     let_customer_id(string)

 - contact.class functions -
     id() returns int 
          function used to obtain the contact id.  if no contact is
          loaded in the class, this returns zero.  this function is 
          inherited, do not create it.
     create(string name) returns int
          creates a new contact with name name.  on success it returns 
          the new contact id, zero on failure
     save() returns boolean
          used to commit changes to the object to the database.  returns 
          true on success, false on failure.
     load(int id) returns boolean
          used to populate the object with the properties from the 
          id record in the database.  returns true if successful and
          false on failure.  failure would happen when the current user
          does not have sufficient read permissions or when there is no
          such id.
     exist(int id) returns boolean
          used to test and see if there is a database entry for the given 
          contact id.  returns true if it exists.  this checks the status
          flag in the contact_meta table to make sure the record has not 
          been marked for deletion.  this function is inherited, do not 
          create it.
     delete() returns boolean
          marks the current contact for deletion.  returns true if 
          permissions allow current user to perform the operation and the
          status flag was successfully changed to Deleted.  A cron job,
          or some routine admin function should go through the meta table
          and delete all marked for deletion after a certain time has 
          elapsed.  
     can_read(int id) returns boolean
          tests current user's read permissions on contact id.  this
          function is inherited, do not create.
     can_write(int id) returns boolean
          tests current user's write permissions on contact id.  if no id
          is passed, or zero is passed, the currently loaded contact, if 
          any, is tested for write permissions.  this function is 
          inherited.  do not create it.
     get_client_data() returns contact.client.class
     get_meta_data() returns contact.meta.class
     get_personal_data() returns contact.personal.class
     get_internet_data() returns contact.internet.class
     get_phone_data() returns contact.phone.class
     get_address_data() returns contact.address.class
 
     get_main_organization() returns organization.class
     let_main_organization(organization.class)
     get_first_name() returns string
     let_first_name(string)
     get_middle_name() returns string
     let_middle_name (string)
     get_last_name () returns string
     let_last_name(string)
     get_last_name_prefix () returns string
     let_last_name_prefix(string)
     get_initials () returns string
     let_initials(string)
     get_location () returns string
     let_location(string)
     get_nickname () returns string
     let_nickname(string)
     get_profession() returns string
     let_profession (string)
     get_suffix() returns string
     let_suffix (string)
     get_title () returns string
     let_title(string)

     get_mailing_address() returns string
          this function returns the address as a string, but there is no
          complimentary let_mailing_address.  Addresses should be changed
          via the contact.address.class subclass, but the main page's 
          pointer is changed by the let_mailing_address_selector func.
     get_mailing_address_selector() returns int
     let_mailing_address_selector(int)
          so the int is the ref number and now get_mailing_address will
          return the string of the new num, if the num belongs to the 
          contact.  otherwise it will return a blank string.
     get_web() returns string
     get_web_selector() returns int
     let_web_selector(int)
          above three work just like with mailing address, but for int
          instead of an id number, 1=home, 2=business, 3=other
     get_email() returns string
     get_email_selector() returns int
          again, like an address, a contact can have multiple e-mails and
          one primary e-mail.  this would return the num of the 
          primary e-mail address.  1=home, 2=business, 3=other
     let_email_selector(int)
     get_phonex(int x) returns string
          there are eight primary phone numbers.  only the first four are
          sync'ed with palm pilots.  get_phonex takes a parameter 
          representing x that is a number between 1 and 8.
     get_phonex_selector(int x) returns int
     let_phonex_selector(int x, int ref)
          let_phonex_selector and get_phonex_selector also take an x 
          parameter signifying which phone display slot is being changed.

     get_note() returns string
     let_note(string)    

 - contact.meta.class functions -
     save() returns boolean
          used to commit changes to the object to the database.  returns 
          true on success, false on failure.
     load(int id) returns boolean
          used to populate the object with the properties from the 
          id record in the database.  returns true if successful and
          false on failure.  failure would happen when the current user
          does not have sufficient read permissions or when there is no
          such id.

     date_created() returns date
     date_modified() returns date
     created_by() returns ?  auth user object?  user id?
     version() returns int
        this will be used in the case of changed db formats to facilitate
        smooth transitions of data
 
     get_status() returns string
        one of "active," "pending," or "deleted"
     let_status(string)
     get_file_as() returns string
     let_file_as (string)
        defaults to "last_name, first_name"
     get_followup_status() returns int
     let_followup_status (int)
     get_keywords() returns string
        comma delimited list
     let_keywords(string)
     get_group_access() returns int
        ????  perhaps this should be a string?  controls on access?
     let_group_access(int)
     get_ldap_sync() returns boolean
        determines whether or not to sync with an ldap server
     let_ldap_sync(boolean)
     get_ldap_dn() returns string
        if ldap_sync is true, and this record has already been 
        propogated, then this will return the dn which can directly
        reference the ldap entry.
     let_ldap_dn(string)
     
 - contact.client.class functions -
     save() returns boolean
          used to commit changes to the object to the database.  returns 
          true on success, false on failure.
     load(int id) returns boolean
          used to populate the object with the properties from the 
          id record in the database.  returns true if successful and
          false on failure.  failure would happen when the current user
          does not have sufficient read permissions or when there is no
          such id.
     get_account() returns string
     let_account(string)
     get_billing_info() returns string
     let_billing_info(string)
     get_referred_by() returns string
     let_referred_by(string)
     get_customer_id() returns string
     let_customer_id(string)
 
 - contact.personal.class functions -
     save() returns boolean
          used to commit changes to the object to the database.  returns 
          true on success, false on failure.
     load(int id) returns boolean
          used to populate the object with the properties from the 
          id record in the database.  returns true if successful and
          false on failure.  failure would happen when the current user
          does not have sufficient read permissions or when there is no
          such id.
     get_birthday() returns date
     let_birthday(date)
     get_children() returns string
     let_children(string)
     get_gender() returns "unspecified"|"male"|"female"
     let_gender(string)
     get_gov_id() returns string
     let_gov_id(string)
     get_hobbies() returns string
     let_hobbies(string)
     get_language() returns string
     get_language_id() returns int
     let_language_id(int)
     get_language_data() returns languages.class
           languages.class provides a list of available languages and an
           interface for adding new languages or renaming existing 
           languages
     get_spouse() returns string
     let_spouse(string)
     get_anniversary() returns date
     let_anniversary(date)

 - contact.internet.class functions -
     save() returns boolean
          used to commit changes to the object to the database.  returns 
          true on success, false on failure.
     load(int id) returns boolean
          used to populate the object with the properties from the 
          id record in the database.  returns true if successful and
          false on failure.  failure would happen when the current user
          does not have sufficient read permissions or when there is no
          such id.
     get_email_home() returns string
     let_email_home(string)
     get_email_home_display() returns string
     let_email_home_display(string)
     get_email_business() returns string
     let_email_business(string)
     get_email_business_display() returns string
     let_email_business_display(string)
     get_email_other() returns string
     let_email_other(string)
     get_email_other_display() returns string
     let_email_other_display(string)
     get_ftp() returns string
     let_ftp(string)
     get_freebusy_address() returns string
     let_freebusy_address(string)
     get_homepage_home() returns string
     let_homepage_home(string)
     get_homepage_business() returns string
     let_homepage_business(string)
     get_homepage_other() returns string
     let_homepage_other(string)
     get_icq() returns string
     let_icq(string)
     get_sendasplaintext() as boolean
     let_sendasplaintext(boolean)
 
 - contact.phone.class functions -
     save() returns boolean
          used to commit changes to the object to the database.  returns 
          true on success, false on failure.
     load(int id) returns boolean
          used to populate the object with the properties from the 
          id record in the database.  returns true if successful and
          false on failure.  failure would happen when the current user
          does not have sufficient read permissions or when there is no
          such id.
  
     get_phone_list() returns array of phone.class with id's as keys
 
 - phone.class functions -
     save() returns boolean
          used to commit changes to the object to the database.  returns 
          true on success, false on failure.
     load(int id) returns boolean
          used to populate the object with the properties from the 
          id record in the database.  returns true if successful and
          false on failure.  failure would happen when the current user
          does not have sufficient read permissions or when there is no
          such id.
     create(int type, [string number]) returns int
          creates a new phone number of type type.  on success it 
          returns the new phone id, zero on failure

     get_id() returns int
     get_type_name() returns string
     get_type() returns int
     let_type(int)
     get_type_list() returns array of id/string pairs
     get_number() returns string
     let_number(string)
      
 - contact.address.class functions -
     save() returns boolean
          used to commit changes to the object to the database.  returns 
          true on success, false on failure.
     load(int id) returns boolean
          used to populate the object with the properties from the 
          id record in the database.  returns true if successful and
          false on failure.  failure would happen when the current user
          does not have sufficient read permissions or when there is no
          such id.
     create(int type) returns int
          creates a new address of category type.  on success it returns
          the new address id, on fail it returns zero.
 
     get_address_list() returns array of address.class with id's as keys
 
 - address.class functions -
     save() returns boolean
          used to commit changes to the object to the database.  returns 
          true on success, false on failure.
     load(int id) returns boolean
          used to populate the object with the properties from the 
          id record in the database.  returns true if successful and
          false on failure.  failure would happen when the current user
          does not have sufficient read permissions or when there is no
          such id.
 
     get_city() returns string
     let_city(string)
     get_street() returns string
     let_street(string)
     get_country() returns string
     let_country(string)
     get_postalcode() returns string
     let_postalcode(string)
