<?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
 * @author Donald A. Lobo <lobo@yahoo.com>
 * @copyright Donald A. Lobo 01/15/2005
 * $Id$
 *
 */

include_once 'config.inc.php';

/**
 * Provides a link to the CSS stylesheet associated with this module.
 *
 * @return a &lt;style&gt; tag that indicates what file browsers should import
 */
function civicrm_html_head()
{
    require_once 'CRM/Core/Config.php';
    $config =& CRM_Core_Config::singleton();
    return '<style type="text/css">@import url(' . $config->resourceBase . 'css/civicrm.css);</style>';
}

/**
 * @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/modules#description':
        // This description is shown in the listing at admin/modules.
        return t('Constituent Relationship Management (CRM). Allows sites to manage contacts, relationships and groups, and track contact activities.');
        
    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><li>'. t('enable CiviCRM blocks at %1.', array('%1' => l(t('administer') . ' >> ' . t('blocks'), 'admin/blocks'))) . '</li>';

        $output .= '<li>' . t('set access permissions at %1.', array('%1' => l(t('administer') . ' >> ' . t('access control'), 'admin/access'))) . '</li>';

        $output .= '<li>' . t('find contacts by name, email address, group membership and/or tagging at %1.', array('%1' => l(t('find contacts'), 'civicrm/contact/search/basic'))) . '</li>';

        $output .= '<li>' . t('do complex searches based on tags, group membership, location, activities and custom fields at %1.', array('%1' => l(t('advanced search'), 'civicrm/contact/search/advanced'))) . '</li>';

        $output .= '<li>' . t('reuse a saved search at %1.', array('%1' => l(t('saved searches'), 'civicrm/contact/search/saved'))) . '</li>';

        $output .= '<li>' . t('create or manage groups at %1.', array('%1' => l(t('manage groups'), 'civicrm/group'))) . '</li>';

        $output .= '<li>' . t('import contacts from other sources at %1.', array('%1' => l(t('import contacts'), 'civicrm/import'))) . '</li>';

        $output .= '<li>' . t('create or administer tags (e.g. organizer, foundation, environment...) at %1.', array('%1' => l(t('civicrm') . ' >> ' . t('admin') . ' >> ' . t('tags'), 'civicrm/admin/tag'))) . '</li>';

        $output .= '<li>' . t('create or administer relationship types (e.g. household member, board member, spouse...) at %1.', array('%1' => l(t('civicrm') . ' >> ' . t('admin') . ' >> ' . t('relationship types'), 'civicrm/admin/reltype'))) . '</li>';

        $output .= '<li>' . t('create or administer location types (e.g. home, work, school...) at %1.', array('%1' => l(t('civicrm') . ' >> ' . t('admin') . ' >> ' . t('location types'), 'civicrm/admin/locationType'))) . '</li>';

        $output .= '<li>' . t('create or administer activity types (e.g. house meeting, intake interview...) at %1.', array('%1' => l(t('civicrm') . ' >> ' . t('admin') . ' >> ' . t('activity types'), 'civicrm/admin/civicrm/admin/activityType'))) . '</li>';

        $output .= '<li>' . t('create or administer custom data fields (e.g. volunteer skills, emergency contact info...) at %1.', array('%1-admin-custom-group' => l(t('civicrm') . ' >> ' . t('admin') . ' >> ' . t('custom data'), 'civicrm/admin/custom/group'))) . '</li>';

        $output .= '<li>' . t('create or administer civicrm profile (i.e. what contact data is collected during user registration) at %1.', array('%1' => l(t('civicrm') . ' >> ' . t('admin') . ' >> ' . t('civicrm profile'), 'civicrm/admin/uf/group'))) . '</li></ul>';

        $output .= '<p>'. t('For more information please read the <a href="%1">configuration and customization handbook CiviCRM page</a>.', array('%1' => 'http://www.drupal.org/handbook/modules/civicrm/')) .'</p>';

        return $output;
    }
}

/**
 * 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
    civicrm_initialize( );

    // static permissions
    $cPerm = array('add contacts', 'view all contacts', 'edit all contacts',
                   'edit groups', 'administer CiviCRM', 
                   'access CiviCRM Profile Listings',
                   'access CiviCRM' );

    // dynamic permissions - access by group (title)
    require_once 'CRM/Core/PseudoConstant.php';
    require_once 'CRM/Core/Permission.php';

    $groups =& CRM_Core_PseudoConstant::allGroup();
    foreach ( $groups as $title ) {
        $cPerm[] = t( CRM_Core_Permission::VIEW_GROUPS . '%1', array('%1' => $title));
        $cPerm[] = t( CRM_Core_Permission::EDIT_GROUPS . '%1', array('%1' => $title));
    }

    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' ) || ( ! user_access( 'access CiviCRM' ) ) ) {
        return;
    }

    // The $op parameter determines what piece of information is being requested.
    global $user;
    if ($user->uid) {
        require_once 'CRM/Core/Block.php';

        $menu_arr = civicrm_menu(true);
        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 ( $may_cache ) {
        require_once 'CRM/Utils/Menu.php';
        $items = CRM_Utils_Menu::items( );
        return $items;
    } else {
        return array( );
    }
}

/**
 * Initialize CivicRM. Call this function from other modules too if 
 * they use the CivicRM API.
 *
 */
function civicrm_initialize() {
    static $initialized = false;

    if ( $initialized ) {
        return;
    }

    $initialized = true;

    // this does pretty much all of the civicrm initialization
    require_once 'CRM/Core/Config.php';
    $config =& CRM_Core_Config::singleton();

    // Add module-specific stylesheet to page header
    drupal_set_html_head(civicrm_html_head());

    if(arg(0) == 'civicrm') {
        // this is just for ease of use. once the code is solid, we no longer need this
        // menu_rebuild();
    }
}

function civicrm_invoke()
{
    // make sure the system is initialized
    civicrm_initialize( );

    // 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' );

    $args = explode( '/', $_GET['q'] );
    require_once 'CRM/Core/Invoke.php';
    $ret  = CRM_Core_Invoke::invoke( $args );
    
    return $ret;
}

/**
 * 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;
    }

    // make sure the system is initialized
    civicrm_initialize( );

    // CRM_Core_Error::debug( $type, $edit );

    switch ( $type ) {

    case 'login':
        require_once 'CRM/Core/BAO/UFMatch.php';
        return CRM_Core_BAO_UFMatch::synchronize( $user, false, 'Drupal' );

    case 'register':
        return civicrm_register_data($edit, $user, $category, true);

    case 'insert':
        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);

    case 'form':
        return civicrm_form_data($edit, $user, $category, true);

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

    case 'categories':
        return civicrm_categories();
    }

}

function civicrm_categories( ) {
    require_once 'CRM/Core/BAO/UFGroup.php';
	$group =& new CRM_Core_DAO_UFGroup( );
    $group->is_active = 1;
    $group->orderBy( 'weight', 'title' );
    $group->find( );

    while ( $group->fetch( ) ) {
        $data[] = array( 'name'   => $group->title,
                         'title'  => $group->title,
                         'weight' => $group->weight );
    }
    return $data;
}

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

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

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

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

    $output = array( );
    if ( $html ) {
        $output[] = array( 'title' => null, 'data' => $html, weight => 0 );
    }

    return $output;
}

function civicrm_form_data($edit, &$user, $category, $reset) {
    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 ) {
        CRM_Core_BAO_UFMatch::synchronize( $user, false, 'Drupal' );
        $userID = CRM_Core_BAO_UFMatch::getContactId( $user->uid );
    }

    // at this point we better have a valid userID
    // else we hopefully aborted earlier

    // get all the data for this specific category
    $html = CRM_Core_BAO_UFGroup::getEditHTML( $userID, $category, null, false, $reset );
    if ( $html ) {
        $output[] = array( 'title' => $category, 'data' => $html, weight => 0 );
    }
    
    return $output;
}

function civicrm_view_data($user ) {
    require_once 'CRM/Core/PseudoConstant.php';
    $ufGroups =& CRM_Core_PseudoConstant::ufGroup( );

    $data = array( );

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

    $userID = CRM_Core_BAO_UFMatch::getContactId( $user->uid );
    if ( $userID ) {
        require_once 'CRM/Profile/Page/Dynamic.php';
        foreach ( $ufGroups as $id => $title ) {
            $page =& new CRM_Profile_Page_Dynamic( $userID, $id );
            $data[$title] = $page->run( );
        }
    }

    return $data;
}

function civicrm_validate_data($edit, &$user, $title) {
    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;
    }

    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 );
    if ( ! CRM_Core_BAO_UFGroup::isValid( $userID, $title, $register ) ) {
        if ( $register ) {
            form_set_error( 'error', 'Please correct the errors indicated below...' );
        } else {
            form_set_error( 'error', "Please complete and save required values in the tab $title" );
        }
    }
    return;
}

?>
