<?php
/** 
 * Project:     CiviCRM: Constituent Relationship Management for NP's
 * File:        civicrm.module 
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 */ 

/**
 * Drupal module file.
 *
 * @package CRM
 * @copyright CiviCRM LLC (c) 2004-2006
 * $Id$
 *
 */

/**
 * Provides a link to the CSS stylesheet associated with this module.
 * and the javascript files needed by this module
 *
 * @return a &lt;style&gt; tag that indicates what file browsers should import
 */
function civicrm_html_head()
{
    if ( ! civicrm_initialize( ) ) {
        return;
    }

    require_once 'CRM/Core/Config.php';
    $config =& CRM_Core_Config::singleton();

    $head  = "<style type=\"text/css\">@import url({$config->resourceBase}css/civicrm.css);</style>\n";

    // include the below files ONLY if needed, since they are heavy weight
    if ( arg(0) == 'civicrm' ) {
        // do not include this in contribution and profile pages
        if ( arg(1) == 'profile' ||
             ( arg(1) == 'contribute' ) && arg(2) == 'transact' ) {
            // skip, do nothing
            $config->includeDojo = 0;
        } else {
            $head .= "<style type=\"text/css\">@import url({$config->resourceBase}css/skins/aqua/theme.css);</style>\n";
            $head .= "<script type=\"text/javascript\">var djConfig = { isDebug: false };</script>";
            $head .= "<script type=\"text/javascript\" src=\"{$config->resourceBase}packages/dojo/dojo.js\"></script>";
            $head .= "<script type=\"text/javascript\" src=\"{$config->resourceBase}js/calendar.js\"></script>";
            $head .= "<script type=\"text/javascript\" src=\"{$config->resourceBase}js/lang/calendar-lang.php\"></script>";
            $head .= "<script type=\"text/javascript\" src=\"{$config->resourceBase}js/calendar-setup.js\"></script>";
        }
    } else {
        $config->includeDojo = 0;
    }

    return $head;
    
}

/**
 * @file
 * This is an example outlining how a module can be used to display a
 * custom page at a given URL.
 */

/**
 * Implementation of hook_help().
 *
 * Throughout Drupal, hook_help() is used to display help text at the top of
 * pages. Some other parts of Drupal pages get explanatory text from these hooks
 * as well. We use it here to provide a description of the module on the
 * module administration page. This example also illustrates how to add help
 * text to the pages your module defines.
 */
function civicrm_help($section)
{	
    switch ($section) {
    case 'admin/help#civicrm':
      $output = '<p>'. t('The CiviCRM module stores information on the universe of people associated with a community and on their interactions such as emails, donations, petitions, events, etc. It can act as a stand alone contact management system or it can be integrated with mass mailer, volunteer management, petition, and event finding. CiviCRM enables organizations to maintain all these activities in a single database, creating efficiencies and new opportunities for communities to better communicate and benefit from relationships with their community members.') .'</p>';
      $output .= '<p>'. t('The CiviCRM module allows you to create contacts, or import them from other sources. You can record relationships between contacts, such as indicating they live in the same household. There are two types of groups of contacts. You can create static groups which have a set list of contacts. You can also create dynamic (smart) groups based on characteristics that contacts have in common. For example, you could create a group of all contacts who live in California AND who have volunteered for your organization within the past year. The CiviCRM module also allows for tagging for less formal categorization of contacts or groups. You can easily extend CiviCRM to record community member information which is specific to your community or organization using custom fields. For example, you can create a set of fields to track volunteer skills and preferences. CiviCRM profile gives you a way to allow community members (\'users\') to update their own information, as well as share some of that information with others. Finally, you can configure custom activity types such as volunteering or attending events.') .'</p>';
      $output .= '<p>' . t('You can:') . '</p>';
      $output .= '<ul>';
      $output .= '<li>' . t('read the <a href="!1">CiviCRM Administrator Guide</a>.', array('!1' => 'http://wiki.civicrm.org/confluence//x/0Cc')) . '</li>';
      $output .= '<li>' . t('enable CiviCRM blocks at <a href="!1">Administer &raquo; Site Building &raquo; Blocks</a>.', array('!1' => url('admin/build/block'))) . '</li>';
      $output .= '<li>' . t('read about <a href="!1">CiviCRM access permissions</a> and set access permissions at <a href="!2">Administer CiviCRM &raquo; Access Control</a>.', array('!1' => 'http://wiki.civicrm.org/confluence//x/SyU', '!2' => url('civicrm/admin/access'))) . '</li>';
      $output .= '<li>' . t('find contacts by name, email address, group membership and or tagging at <a href="!1">Find Contacts</a>.', array('!1' => url('civicrm/contact/search/basic'))) . '</li>';
      $output .= '<li>' . t('do complex searches based on tags, group membership, location, activities and custom fields at <a href="!1">Advanced Search</a>.', array('!1' => url('civicrm/contact/search/advanced'))) . '</li>';
      $output .= '<li>' . t('create or manage groups at <a href="!1">Manage Groups</a>.', array('!1' => url('civicrm/group'))) . '</li>';
      $output .= '<li>' . t('import contacts from other sources at <a href="!1">Import Contacts</a>.', array('!1' => url('civicrm/import'))) . '</li>';
      $output .= '<li>' . t('create or administer tags (e.g. organizer, foundation, environment...) at <a href="!1">CiviCRM &raquo; Administer &raquo; Tags</a>.', array('!1' => url('civicrm/admin/tag'))) . '</li>';
      $output .= '<li>' . t('create or administer relationship types (e.g. household member, board member, spouse...) <a href="!1">CiviCRM &raquo; Administer &raquo; Relationship Types</a>.', array('!1' => url('civicrm/admin/reltype'))) . '</li>';
      $output .= '<li>' . t('create or administer location types (e.g. home, work, school...) <a href="!1">CiviCRM &raquo; Administer &raquo; Location Types</a>.', array('!1' => url('civicrm/admin/locationType'))) . '</li>';
      $output .= '<li>' . t('create or administer activity types (e.g. house meeting, intake interview...) at <a href="!1">CiviCRM &raquo; Administer &raquo; Activity Types</a>.', array('!1' => url('civicrm/admin/options', 'group=activity_type&reset=1'))) . '</li>';
      $output .= '<li>' . t('create or administer custom data fields (e.g. volunteer skills, emergency contact info...) <a href="!1">CiviCRM &raquo; Administer &raquo; Custom Data</a>.', array('!1' => url('civicrm/admin/custom/group'))) . '</li>';
      $output .= '<li>' . t('create or administer CiviCRM profiles (i.e. what contact data is collected during user registration and included in My Account) at <a href="!1">CiviCRM &raquo; Administer &raquo; CiviCRM Profiles</a>.', array('!1' => url('civicrm/admin/uf/group'))) . '</li>';
      $output .= '</ul>';
      $output .= '<p>'. t('For more information please refer to the <a href="!1">CiviCRM web-site</a> which includes project information, documentation and support resources and more.', array('!1' => 'http://civicrm.org')) .'</p>';
      return $output;
     case 'admin/modules#description':
         // This description is shown in the listing at admin/modules.
         return t('Constituent Relationship Management (CiviCRM !1). Allows sites to manage contacts, relationships and groups, and track contact activities, contributions, memberships and events. For more information please refer to the <a href="!2">CiviCRM web-site</a> which includes project information, documentation and support resources and more.', array('!1' => '1.9', '!2' => 'http://civicrm.org/'));
    }
}

/**
 * Implementation of hook_perm().
 *
 * Since the access to our new custom pages will be granted based on
 * special permissions, we need to define what those permissions are here.
 * This ensures that they are available to enable on the user role
 * administration pages.
 */
function civicrm_perm()
{
    // make sure the system is initialized
    if ( ! civicrm_initialize( ) ) {
        return;
    }

    $config =& CRM_Core_Config::singleton();

    // static permissions
    $cPerm = array('add contacts', 'view all contacts', 'edit all contacts', 'import contacts',
                   'edit groups', 'administer CiviCRM', 
                   'access uploaded files',
                   'profile listings and forms',
                   'access all custom data',
                   'access CiviCRM', 'access Contact Dashboard' );
                   
    // permissions for components which are conditionally enabled via config file setting
    require_once 'CRM/Core/Component.php';
    foreach ( $config->enableComponents as $comp ) {
        $perm = CRM_Core_Component::get( $comp, 'perm' );
        if ( $perm ) {
            $cPerm = array_merge( $cPerm, $perm );
        }
    }
	return $cPerm;
}

/**
 * Implementation of hook_block().
 *
 * This hook both declares to Drupal what blocks are provided by the module, and
 * generates the contents of the blocks themselves.
 */

function civicrm_block($op='list', $delta='0')
{
    if ( ( arg(0) != 'civicrm' && arg(0) != 'admin' ) ||
         ( $op == 'configure' ) ) {
        return;
    }

    if ( ! civicrm_initialize( ) ) {
        return;
    }

    // The $op parameter determines what piece of information is being requested.
    require_once 'CRM/Core/Block.php';

    if ($op == 'list') {
        $block = CRM_Core_Block::getInfo();
    } else {
        $block = CRM_Core_Block::getContent ($delta);
    }
    return $block;
}

/**
 * Implementation of hook_menu().
 *
 * You must implement hook_menu() to emit items to place in the main menu.
 * This is a required step for modules wishing to display their own pages,
 * because the process of creating the links also tells Drupal what
 * callback function to use for a given URL. The menu items returned
 * here provide this information to the menu system.
 *
 * With the below menu definitions, URLs will be interpreted as follows:
 *
 * If the user accesses http://example.com/?q=foo, then the menu system
 * will first look for a menu item with that path. In this case it will
 * find a match, and execute civicrm_foo().
 *
 */
function civicrm_menu($may_cache)
{
    if ( ! civicrm_initialize( ) ) {
        return;
    }

    require_once 'CRM/Core/Menu.php';
    if ( $may_cache ) {
        return CRM_Core_Menu::permissionedItems( );
    } else {
        return CRM_Core_Menu::items( );
    }
}

/**
 * Initialize CiviCRM. Call this function from other modules too if 
 * they use the CiviCRM API.
 *
 * @param boolean $requireAPI should we also load the civicrm api functions
 *
 */
function civicrm_initialize( $requireAPI = false ) 
{
    static $initialized    = null;
    static $initializedAPI = null;
    static $failure        = false;

    if ( $failure ) {
        return false;
    }

    if ( ! $initialized ) {
        if ( function_exists( 'conf_path' ) ) {
            $settingsFile = conf_path( ) . '/civicrm.settings.php';
        } else {
            $settingsFile = conf_init( ) . '/civicrm.settings.php';
        }
        $error = include_once( $settingsFile );
        if ( $error == false ) {
            $failure = true;
            drupal_set_message( "<strong><p class='error'>Oops! - The CiviCRM settings file (civicrm.settings.php) was not found in the expected location (" . $settingsFile . "). Please review the <a href='http://wiki.civicrm.org/confluence//x/mQ8'>Installation Instructions</a>, <a href='http://wiki.civicrm.org/confluence/display/CRMDOC/FAQ#FAQ-install'>Installation FAQs</a>, and <a href='http://wiki.civicrm.org/confluence//x/7ho'>Trouble-shooting</a> documentation for assistance.</strong></p>" );
            return false;
        }
        
        // this does pretty much all of the civicrm initialization
        $error = include_once( 'CRM/Core/Config.php' );
        if ( $error == false ) {
            $failure = true;
            drupal_set_message( "<strong><p class='error'>Oops! - The path for including CiviCRM code files is not set properly. Most likely there is an error in the <em>civicrm_root</em> setting in your CiviCRM settings file ($settingsFile).</p><p> &raquo; civicrm_root is currently set to: <em>$civicrm_root</em>.</p><p>Please review the <a href='http://wiki.civicrm.org/confluence//x/mQ8'>Installation Instructions</a>, <a href='http://wiki.civicrm.org/confluence/display/CRMDOC/FAQ#FAQ-install'>Installation FAQs</a>, and <a href='http://wiki.civicrm.org/confluence//x/7ho'>Trouble-shooting</a> documentation for assistance.</strong></p>" );
            return false;
        }

        $initialized = true;
        $config =& CRM_Core_Config::singleton();
        
        // Add module-specific header elements
        drupal_set_html_head(civicrm_html_head());

        return true;
    }

    if ( $requireAPI && ! $initializedAPI ) {
        $initializedAPI = true;
        require_once 'api/crm.php';
    }

    return true;
}

/**
 * Function to get the contact type
 * @param string $default contact type
 *
 * @return $ctype contact type
 */
function civicrm_get_ctype( $default = null ) 
{
    // here we are creating a new contact
    // get the contact type from the POST variables if any

    if ( isset( $_REQUEST['ctype'] ) ) {
        $ctype = $_REQUEST['ctype'];
    } else if ( isset( $_REQUEST['edit'] ) &&
                isset( $_REQUEST['edit']['ctype'] ) ) {
        $ctype = $_REQUEST['edit']['ctype'];
    } else {
        $ctype = $default;
    }

    if ( $ctype != 'Individual'   &&
         $ctype != 'Organization' &&
         $ctype != 'Household' ) {
        $ctype = $default;
    }
    return $ctype; 
}

/**
 * This is the main function that is called on any civicrm click
 *
 */
function civicrm_invoke( )
{
    // make sure the system is initialized
    if ( ! civicrm_initialize( ) ) {
        return drupal_not_found( );
    }
    
    require_once 'CRM/Core/Error.php';
    
    // synchronize the drupal uid with the contacts db
    global $user;
    require_once 'CRM/Core/BAO/UFMatch.php';
    CRM_Core_BAO_UFMatch::synchronize( $user, false, 'Drupal',
                                       civicrm_get_ctype( 'Individual' ) );

    $args = explode( '/', $_GET['q'] );

	if ( $args[1] == 'quickreg' ) {
        civicrm_quickreg( );
    } else {
        require_once 'CRM/Core/Invoke.php';
        $ret  = CRM_Core_Invoke::invoke( $args );
    }
    return $ret;
}

function civicrm_quickreg( ) 
{
    if ( ! civicrm_initialize( ) ) {
        return;
    }

    $names  = array( 'first_name', 'last_name', 'email', 'postal_code' ); 
    $params = array( ); 
    foreach ( $names as $name ) { 
        if ( isset( $_POST[ $name ] ) && ! empty( $_POST[ $name ] ) ) { 
            $params[$name] = $_POST[ $name ];  
        } 
    } 

    require_once 'api/Contact.php';
    $contact = crm_create_contact( $params, 'Individual' ); 
    if ( isset( $_SERVER['HTTP_REFERER'] ) ) {
        $url = $_SERVER['HTTP_REFERER'];
    } else {
        $config =& CRM_Core_Config::singleton( );
        $url = $config->userFrameworkBaseURL;
    }
    CRM_Utils_System::redirect( $url );
}

/**
 * User hook for civicrm module
 *
 * Note that we ignore the edit field and do not follow the drupal protocol
 * of extracting values from the edit field. We extract the fields directly
 * from $_POST. This is because the underlying form package that we use
 * (HTML_QuickForm) does the form value extraction and validation.
 *
 * @param string $type     Type of operation being performed
 * @param array  $edit     The array of form values submitted by the user.
 * @param object $user     The user object on which the operation is being performed.
 * @param object $category The active category of user information being edited.
 *
 * @return mixed           depends on the operation being performed
 */
function civicrm_user( $type, &$edit, &$user, $category = NULL ) 
{
	if ( $type == 'load' ) {
        return;
    }			

    if ( ! civicrm_initialize( ) ) {
        return;
    }

    switch ( $type ) {

    case 'login':
        require_once 'CRM/Core/BAO/UFMatch.php';
        return CRM_Core_BAO_UFMatch::synchronize( $user, false, 'Drupal',
                                                  civicrm_get_ctype( 'Individual' ) );
    case 'register':
        $config =& CRM_Core_Config::singleton( );
        if ( $config->inCiviCRM ) {
            return;
        }
 
        if ( empty( $_POST ) || $config->userFrameworkVersion < 4.7 ) {
            return civicrm_register_data($edit, $user, $category, true, false );
        } else {
            return civicrm_register_data( $edit, $user, $category, false, true );
        }
        return;

    case 'insert':
        $config =& CRM_Core_Config::singleton( );
        if ( $config->inCiviCRM ) {
            return;
        }
 
        return civicrm_register_data($edit, $user, $category, false);

    case 'view':
        return civicrm_view_data($user);

    case 'update':
        return civicrm_form_data($edit, $user, $category, false, false );

    case 'form':
        $config =& CRM_Core_Config::singleton( );
        if ( empty( $_POST ) || $config->userFrameworkVersion < 4.7 ) {
            return civicrm_form_data($edit, $user, $category, true, false );
        } else {
            return civicrm_form_data($edit, $user, $category, true, true );
        }
        return;

    case 'validate':
        return civicrm_validate_data($edit, $user, $category);

    case 'categories':
        return civicrm_categories($user);

	case 'delete':
        require_once 'CRM/Core/BAO/UFMatch.php';
        return CRM_Core_BAO_UFMatch::deleteUser( $user->uid );
    }

}

function civicrm_categories( &$user ) 
{
    if ( ! civicrm_initialize( ) ) {
        return;
    }

    require_once 'CRM/Core/BAO/UFMatch.php';
    $userID = CRM_Core_BAO_UFMatch::getContactId( $user->uid );
    if ( ! $userID ) {
        return null;
    }

    $config =& CRM_Core_Config::singleton( ); 

    $ctype = CRM_Core_DAO::getFieldValue( 'CRM_Contact_DAO_Contact', $userID, 'contact_type' );

    require_once 'CRM/Core/BAO/UFGroup.php';
    require_once 'CRM/Core/BAO/UFField.php';

    $allUFGroups =& CRM_Core_BAO_UFGroup::getModuleUFGroup('User Account');
    $ufGroups = array( );

    //check if there are any fields in this group
    foreach ($allUFGroups as $key => $value) {
        $fieldType = CRM_Core_BAO_UFField::getProfileType( $key );
        if ( $fieldType != $ctype ) {
            continue;
        }
        $ufGroups[$key] = $value;
    }
    return $ufGroups;
}

function civicrm_register_data($edit, &$user, $category, $reset, $doNotProcess = false ) 
{
    require_once 'CRM/Core/BAO/UFMatch.php';
    require_once 'CRM/Core/BAO/UFGroup.php';
    require_once 'CRM/Core/Action.php';

    $ctype = civicrm_get_ctype( 'Individual' );
    if ( $user->uid ) {
        CRM_Core_BAO_UFMatch::synchronize( $user, true, 'Drupal', $ctype );
    }

    $userID = CRM_Core_BAO_UFMatch::getContactId( $user->uid );

    if ( $userID ) {
        $html = CRM_Core_BAO_UFGroup::getEditHTML( $userID, '',
                                                   CRM_Core_Action::UPDATE, true,
                                                   $reset, null,
                                                   $doNotProcess, $ctype );
    } else {
        $html = CRM_Core_BAO_UFGroup::getEditHTML( $userID, '',
                                                   CRM_Core_Action::ADD, true,
                                                   $reset, null,
                                                   $doNotProcess, $ctype );
    }

    $output = array( );
    if ( $html ) {
        $config =& CRM_Core_Config::singleton( );
        if ( $config->userFrameworkVersion >= 4.7 ) {
            $index = empty( $category ) ? 'civicrm-profile-register' : $category;
            $output[$index] = array( '#title' => $category,
                                     '#value' => $html,
                                     '#weight' => 1 );
        } else {
            $output[] = array( 'title' => null, 'data' => $html, 'weight' => 0 );
        }
    }

    return $output;
}

function civicrm_form_data($edit, &$user, $category, $reset, $doNotProcess = false) 
{
    require_once 'CRM/Core/BAO/UFMatch.php';
    require_once 'CRM/Core/BAO/UFGroup.php';

    $output = array( );

    $userID = CRM_Core_BAO_UFMatch::getContactId( $user->uid );
    if ( ! $userID ) {
        $ctype = civicrm_get_ctype( 'Individual' );
        CRM_Core_BAO_UFMatch::synchronize( $user, false, 'Drupal', $ctype );
        $userID = CRM_Core_BAO_UFMatch::getContactId( $user->uid );
    }

    // at this point we better have a valid userID
	if ( ! $userID ) {
        // we get into this scenario if we do not like the email address supplied by the user
        return;
    }

    $ctype = CRM_Core_DAO::getFieldValue( 'CRM_Contact_DAO_Contact', $userID, 'contact_type' );

    // get all the data for this specific category
    $html = CRM_Core_BAO_UFGroup::getEditHTML( $userID, $category, null, false, $reset, null, $doNotProcess, $ctype );
    
    if ( $html ) {
        $config =& CRM_Core_Config::singleton( );
        if ( $config->userFrameworkVersion >= 4.7 ) {
            $index = empty( $category ) ? 'civicrm-profile-my-account' : $category;
            $output[$index] = array( '#title' => $category,
                                     '#value' => $html,
                                     '#weight' => 1 );
        } else {
            $output[] = array( 'title' => $category, 'data' => $html, 'weight' => 0 );
        }
    }

    return $output;
}

function civicrm_view_data($user ) 
{
    $data = array( );

    require_once 'CRM/Core/BAO/UFMatch.php';
    $userID = CRM_Core_BAO_UFMatch::getContactId( $user->uid );
    if ( $userID ) {
        $config =& CRM_Core_Config::singleton( ); 

        // make sure user has permission to view the record
        require_once 'CRM/Contact/BAO/Contact.php';
        $contactURL = null;
        if ( CRM_Contact_BAO_Contact::permissionedContact( $userID ) ) {
            $url = CRM_Utils_System::url( 'civicrm/contact/view', "reset=1&cid=$userID" );
            $contactURL = '<a href="' .$url. '">&raquo; ' .t("View Contact Record") . '</a>';
            if ( CRM_Core_Permission::check( 'access Contact Dashboard' ) ) {
                $url = CRM_Utils_System::url( 'civicrm/user', "reset=1&id=$userID" );
                $contactURL .= '<br/><a href="' .$url. '">&raquo; ' .t("View Contact Dashboard") . '</a>';
            }
        }

        require_once 'CRM/Profile/Page/Dynamic.php';
        require_once 'CRM/Core/BAO/UFGroup.php';
        require_once 'CRM/Core/BAO/UFField.php';

        $ctype = CRM_Core_DAO::getFieldValue( 'CRM_Contact_DAO_Contact', $userID, 'contact_type' );

        $ufGroups =& CRM_Core_BAO_UFGroup::getModuleUFGroup('User Account');
        $setLink = 0 ;        
        foreach ( $ufGroups as $id => $title ) {
            
            $fieldType = CRM_Core_BAO_UFField::getProfileType( $id );
            if ( $fieldType != $ctype ) {
                continue;
            }
            $page =& new CRM_Profile_Page_Dynamic( $userID, $id, null, true );
            $pageContent = $page->run( );
            
            if ( $pageContent ) {
                if ( $config->userFrameworkVersion >= 4.7 ) {
                    $item = array( 'value' => $pageContent );
                    $data[$title['title']][] = $item;
                } else {
                    $data[$title['title']] = $pageContent;
                }
                $setLink++;
            }
        }
        
        if ($setLink  && CRM_Core_Permission::check( 'access CiviCRM' )) {
            if ( $config->userFrameworkVersion >= 4.7 ) { 
                $item = array( 'title' => '',
                               'value' => $contactURL );
                $data[''][] = $item;
                
            } else {
                $data[''] = $contactURL;
            }
        }
    }
    return $data;
}

function civicrm_validate_data($edit, &$user, $title) 
{
    static $validated = false;

    if ( $validated ) {
        return;
    }

    $validated = true;

    require_once 'CRM/Utils/Array.php';

    // if this is an admin creator, dont validate
    if ( ( $_GET['q'] == 'admin/user/create' ) ||
         ! CRM_Utils_Array::value( '_qf_default', $_POST ) ) {
        return true;
    }

    require_once 'CRM/Core/BAO/UFMatch.php';
    require_once 'CRM/Core/BAO/UFGroup.php';

    $register = ( arg(1) == 'register' ) ? true : false;
    $userID = CRM_Core_BAO_UFMatch::getContactId( $user->uid );
	$errors = CRM_Core_BAO_UFGroup::isValid( $userID, $title, $register );
    if ( is_array( $errors ) ) {
        if ( $register ) {
            foreach ( $errors as $name => $error ) {
                form_set_error( $name, $error );
            }
        } else {
            form_set_error( 'error', "Please complete and save required values in the tab $title" );
        }
        return false;
    }
    return true;
}

?>
