wiki:phpgwapi/how_does_API_work

Version 6 (modified by rodsouza, 14 years ago) (diff)

--

Tendo como base uma requisição inicial para o script /index.php

A primeira verificação é a existência do script /header.inc.php, caso não exista então há um redirecionamento para /setup/index.php.

    if ( ! file_exists('header.inc.php' ) )
    {
        Header( 'Location: setup/index.php' );
        exit;
    }

Caso exista o script /header.inc.php o próximo passo é obter o id da sesssão. Caso não exista então há um redirecionamento para /login.php.

    if ( ! $GLOBALS[ 'sessionid' ] )
    {   
        Header( 'Location: login.php'.
            ( isset( $_SERVER[ 'QUERY_STRING' ] ) && ! empty( $_SERVER[ 'QUERY_STRING' ] ) ?
                '?phpgw_forward=' . urlencode( '/index.php?' . $_SERVER[ 'QUERY_STRING' ] ) : '' ) );
        exit;
    }

A seguir é realizada a verificação se a existe a opção menuaction. Caso a opção exista ela deve estar no formato APP.CLASS.METHOD.

    if ( isset( $_GET[ 'menuaction'] ) )
    {
        list( $app, $class, $method ) = explode( '.', @$_GET[ 'menuaction' ] );
        if ( ! $app || ! $class || ! $method )
        {
            $invalid_data = true;
        }
    }

Se a opção não existir então assume-se que a requisição deve ser redirecionada para o script home.php. O mesmo ocorre se a opção existir porém a parte APP referencie-se a phpgwapi.

    else
    {
        $app = 'home';
        $invalid_data = true;
    }

    if ( $app == 'phpgwapi' )
    {
        $app = 'home';
        $api_requested = true;
    }

Após é configurada algumas variáveis globais e é incluido o script /header.inc.php.

    $GLOBALS[ 'phpgw_info' ][ 'flags' ] = array(
        'noheader'   => true,
        'nonavbar'   => true,
        'currentapp' => $app
    );

    include('./header.inc.php');

O script /header.inc.php começa definindo o path do ExpressoLivre?, o nome do usuário com permissão para realizar alterações na configuração básica e a senha do mesmo no formato md5.

    define( 'PHPGW_SERVER_ROOT', '/var/www/expresso' );
    define( 'PHPGW_INCLUDE_ROOT', '/var/www/expresso' );
    $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'header_admin_user' ] = 'expresso-admin';
    $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'header_admin_password' ] = 'e8d95a51f3af4a3b134bf6bb680a213a';
    $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'setup_acl' ] = '';

Após algumas outras variáveis são populadas.

    // Opcoes exclusivas a partir da versão 2.0 :: Configurar via setup/header
    $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'captcha' ] = 0;
    $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'num_badlogin' ] = 0;
    $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'atributoexpiracao' ] = '';
    $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'atributousuarios' ] = '';
    $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'certificado' ] = 0;
    $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'use_assinar_criptografar' ] = 0;
    $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'num_max_certs_to_cipher' ] = 0;

    // Opcoes exlusivas para o Expresso Livre
    $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'use_https' ] = 0;
    $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'sugestoes_email_to' ] = '';
    $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'domain_name' ] = '';
    $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'use_prefix_organization' ] = false;

Posteriormente existe as informações referentes à base de dados.

    $GLOBALS['phpgw_domain']['default'] = array(
        'db_host' => 'localhost',
        'db_port' => '5432',
        'db_name' => 'expresso',
        'db_user' => 'postgres',
        'db_pass' => '',
        'db_type' => 'pgsql',
    );

Em seguida é definido o diretório das classes da API e incluido o script /phpgwapi/setup/setup.inc.php.

    define( 'PHPGW_API_INC', PHPGW_INCLUDE_ROOT . '/phpgwapi/inc' );
    include( PHPGW_SERVER_ROOT . '/phpgwapi/setup/setup.inc.php' );

O script /phpgwapi/setup/setup.inc.php define dados sobre a API, além das tabelas utiliadas.

    /* Basic information about this app */
    $setup_info[ 'phpgwapi' ][ 'name' ] = 'phpgwapi';
    $setup_info[ 'phpgwapi' ][ 'title' ] = 'phpgwapi';
    $setup_info[ 'phpgwapi' ][ 'version' ] = '2.2.000';
    $setup_info[ 'phpgwapi' ][ 'versions' ][ 'current_header' ] = '2.0';
    $setup_info[ 'phpgwapi' ][ 'enable' ] = 3;
    $setup_info[ 'phpgwapi' ][ 'app_order' ] = 1;

    /* The tables this app creates */
    $setup_info[ 'phpgwapi' ][ 'tables' ][ ] = 'phpgw_config';
    $setup_info[ 'phpgwapi' ][ 'tables' ][ ] = 'phpgw_applications';
    $setup_info[ 'phpgwapi' ][ 'tables' ][ ] = 'phpgw_acl';
    $setup_info[ 'phpgwapi' ][ 'tables' ][ ] = 'phpgw_accounts';
    $setup_info[ 'phpgwapi' ][ 'tables' ][ ] = 'phpgw_preferences';
    $setup_info[ 'phpgwapi' ][ 'tables' ][ ] = 'phpgw_sessions';
    $setup_info[ 'phpgwapi' ][ 'tables' ][ ] = 'phpgw_app_sessions';
    $setup_info[ 'phpgwapi' ][ 'tables' ][ ] = 'phpgw_access_log';
    $setup_info[ 'phpgwapi' ][ 'tables' ][ ] = 'phpgw_hooks';
    $setup_info[ 'phpgwapi' ][ 'tables' ][ ] = 'phpgw_languages';
    $setup_info[ 'phpgwapi' ][ 'tables' ][ ] = 'phpgw_lang';
    $setup_info[ 'phpgwapi' ][ 'tables' ][ ] = 'phpgw_nextid';
    $setup_info[ 'phpgwapi' ][ 'tables' ][ ] = 'phpgw_categories';
    $setup_info[ 'phpgwapi' ][ 'tables' ][ ] = 'phpgw_log';
    $setup_info[ 'phpgwapi' ][ 'tables' ][ ] = 'phpgw_log_msg';
    $setup_info[ 'phpgwapi' ][ 'tables' ][ ] = 'phpgw_vfs';
    $setup_info[ 'phpgwapi' ][ 'tables' ][ ] = 'phpgw_history_log';
    $setup_info[ 'phpgwapi' ][ 'tables' ][ ] = 'phpgw_async';

Caso a variável $GLOBALS[ 'phpgw_info' ][ 'flags' ][ 'noapi' ] não tenha o valor true então é realizada a inclusão dos scripts a seguir, todos localizados no diretório de classes da API.

    if ( ! isset( $GLOBALS[ 'phpgw_info' ][ 'flags' ][ 'noapi' ] ) || ! $GLOBALS[ 'phpgw_info' ][ 'flags' ][ 'noapi' ] == true )
    {
        include( PHPGW_API_INC . '/functions.inc.php' );
        include( PHPGW_API_INC . '/xml_functions.inc.php' );
        include( PHPGW_API_INC . '/soap_functions.inc.php' );
    }

O script /phpgwapi/inc/functions.inc.php inicia incluindo o script /phpgwapi/inc/common_functions.inc.php. Após algumas variáveis são populas caso o ExpressoLivre? esteja utilizando o formato multi-domínios.

Em seguida as classes phpgw e db são instanciadas.

    $GLOBALS[ 'phpgw' ] = CreateObject( 'phpgwapi.phpgw' );
    $GLOBALS[ 'phpgw' ]->db = CreateObject( 'phpgwapi.db' );

Com a instância da classe referente à base de dados uma tentativa de conexão com à base é realizada.

    if (!
    $GLOBALS['phpgw']->db->connect(
        $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'db_name' ],
        $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'db_host' ],
        $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'db_port' ],
        $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'db_user' ],
        $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'db_pass' ],
        $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'db_type' ]
    ) )

Caso não seja possível conectar-se então o famigerado erro Código 001 é exibido.

A etapa seguinte é popular informações sobre o servidor proveniente da base de dados em $GLOBALS[ 'phpgw_info' ][ 'server' ].

    $GLOBALS[ 'phpgw' ]->db->query( "SELECT * from phpgw_config WHERE config_app='phpgwapi'", __LINE__, __FILE__ );
    while ( $GLOBALS[ 'phpgw' ]->db->next_record( ) )
    {
        $GLOBALS[ 'phpgw_info' ][ 'server' ][ $GLOBALS[ 'phpgw' ]->db->f( 'config_name' ) ] = stripslashes( $GLOBALS[ 'phpgw' ]->db->f( 'config_value' ) );
    }

Segue um exemplo de $GLOBALS[ 'phpgw_info' ][ 'server' ] populada.

    [server] => Array
        (
            [header_admin_user] => expresso-admin
            [header_admin_password] => e8d95a51f3af4a3b134bf6bb680a213a
            [setup_acl] => 
            [captcha] => 0
            [num_badlogin] => 0
            [atributoexpiracao] => 
            [atributousuarios] => 
            [certificado] => 0
            [use_assinar_criptografar] => 0
            [num_max_certs_to_cipher] => 0
            [use_https] => 0
            [sugestoes_email_to] => 
            [domain_name] => 
            [use_prefix_organization] => 
            [show_domain_selectbox] => 
            [db_persistent] => 
            [sessions_type] => php4
            [mcrypt_enabled] => 
            [versions] => Array
                (
                    [mcrypt] => 
                    [phpgwapi] => 2.2.000
                    [current_header] => 2.0
                    [header] => 2.0
                )

            [mcrypt_iv] => iwktq671fBY9ZZu1GNpCL8FrzIq4Y
            [default_domain] => default
            [db_host] => localhost
            [db_port] => 5432
            [db_name] => expresso
            [db_user] => postgres
            [db_pass] => 
            [db_type] => pgsql
            [site_title] => Expresso Livre
            [max_access_log_age] => 20
            [block_time] => 1
            [num_unsuccessful_id] => 50
            [num_unsuccessful_ip] => 500
            [disable_autoload_langfiles] => True
            [showpoweredbyon] => bottom
            [holidays_url_path] => localhost
            [usecookies] => True
            [install_id] => eb6dc5e478cafcab4286441bec7a1e5b
            [ldap_root_pw] => senha
            [cal_expressoMail] => 1.2
            [image_type] => 1
            [useframes] => never
            [sessions_app_timeout] => 1
            [deny_user_grants_access] => True
            [cal_type_tree_participants] => 3
            [auto_search] => True
            [temp_dir] => /tmp
            [files_dir] => /home/projetos/expresso
            [webserver_url] => /expresso
            [hostname] => 127.0.0.1
            [auth_type] => ldap
            [account_repository] => ldap
            [sql_encryption_type] => md5
            [account_min_id] => 1000
            [account_max_id] => 1000000
            [name_jabber] => 127.0.0.1
            [resource_jabber] => celepar
            [port_jabber] => 8888
            [server_webjabber] => 127.0.0.1
            [server_ldap_jabber] => 127.0.0.1
            [context_ldap_jabber] => dc=ecelepar10631
            [user_ldap_jabber] => cn=admin
            [password_ldap_jabber] => senha
            [server_ldap_jabberit] => localhost
            [context_ldap_jabberit] => dc=ecelepar10631
            [user_ldap_jabberit] => uid=expresso-admin,ou=celepar,dc=ecelepar10631
            [password_ldap_jabberit] => senha
            [auto_create_expire] => never
            [acl_default] => deny
            [ldap_host] => 127.0.0.1
            [ldap_context] => dc=ecelepar10631
            [ldap_group_context] => dc=ecelepar10631
            [ldap_root_dn] => cn=admin,dc=ecelepar10631
            [ldap_encryption_type] => md5
            [ldap_version3] => True
            [mcrypt_algo] => tripledes
            [mcrypt_mode] => cbc
            [file_repository] => sql
            [file_store_contents] => filesystem
            [tz_offset] => -2
            [asyncservice] => off
            [lang_ctimes] => a:3:{s:2:"en";a:2:{s:5:"admin";i:1268134511;s:11:"preferences";i:1268134514;}s:5:"es-es";a:2:{s:5:"admin";i:1268134511;s:11:"preferences";i:1268134514;}s:5:"pt-br";a:2:{s:5:"admin";i:1268134511;s:11:"preferences";i:1268134514;}}
            [name_jabberit] => im.pr.gov.br
            [port_jabberit] => 5223
            [resource_jabberit] => ECELEPAR10631
            [use_ssl_jabberit] => true
            [use_proxy_java] => false
            [name_company_applet_jabberit] => Celepar
            [mail_server] => localhost
            [mail_port] => 143
            [sessions_timeout] => 14400
        )

Seguindo o fluxo existe uma verificação da obrigatoriedade da utilização de conexão segura.

    if( @isset( $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'enforce_ssl' ] ) && ! $_SERVER[ 'HTTPS' ] )
    {
        Header( 'Location: https://' . $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'hostname' ] . $GLOBALS[ 'phpgw_info' ][ 'server' ][ 'webserver_url' ] . $_SERVER[' REQUEST_URI' ] );
        exit;
    }

Se for obrigatório o uso de conexão segura então todo o processo descrito até o momento será novamente executado.

O passo seguinte é instânciar as classes errorlog, translation, common, hooks, auth, accounts, acl, sessions, preferences, applications.

    $GLOBALS['phpgw']->log          = CreateObject('phpgwapi.errorlog');
    $GLOBALS['phpgw']->translation  = CreateObject('phpgwapi.translation');
    $GLOBALS['phpgw']->common       = CreateObject('phpgwapi.common');
    $GLOBALS['phpgw']->hooks        = CreateObject('phpgwapi.hooks');
    $GLOBALS['phpgw']->auth         = CreateObject('phpgwapi.auth');
    $GLOBALS['phpgw']->accounts     = CreateObject('phpgwapi.accounts');
    $GLOBALS['phpgw']->acl          = CreateObject('phpgwapi.acl');
    $GLOBALS['phpgw']->session      = CreateObject('phpgwapi.sessions');
    $GLOBALS['phpgw']->preferences  = CreateObject('phpgwapi.preferences');
    $GLOBALS['phpgw']->applications = CreateObject('phpgwapi.applications');

Caso a variável $GLOBALS[ 'phpgw_info' ][ 'flags' ][ 'included_classes' ][ 'error' ] esteja habilitada então é incluido a classe error.

    if ( ! isset( $GLOBALS[ 'phpgw_info' ][ 'flags' ][ 'included_classes' ][ 'error' ] ) || ! $GLOBALS[ 'phpgw_info' ][ 'flags' ][ 'included_classes' ][ 'error' ] )
    {
        include_once( PHPGW_INCLUDE_ROOT . '/phpgwapi/inc/class.error.inc.php' );
        $GLOBALS[ 'phpgw_info' ][ 'flags' ][ 'included_classes' ][ 'error' ] = true;
    }

Após todas as classes instanciadas então é registrado o método phpgw_final da classe common para ser executada ao final da execução da requisição.