Eu comecei este livro com a inteno de trazer um novo lado do SugarCRM a vista. Desde que comecei a trabalhar no SugarCRM, eu vi a flexibilidade e extensibilidade que o aplicativo poderia proporcionar. Eu olhei para a minha posio anterior desenvolvimento de aplicaes internas da empresa, e vendo que muitos dos elementos que acrescentei e questes de design que eu queria se debateu com problemas que SugarCRM j tinha resolvido. A equipe de engenharia da SugarCRM tinha construdo para resolver este problema, mas alguns programadores fora da SugarCRM sabiam realmente o quo potente a plataforma subjacente seria. Eu sabia que eram outros programadores neste mesmo barco, e que se eu pudesse chegar a eles, faria seus trabalhos muito mais fceis. O que uma aplicao de CRM faz ou no faz no totalmente definida; em vez disso, o seu objetivo o de preencher a lacuna em que uma empresa tem em resolver problemas em seus relacionamentos com seus clientes. Por vezes, isto significa manter o acompanhamento de reunies e chamadas de telefone. Outras vezes, isso significa acompanhar o progresso de um projeto em curso. Pode tambm significar gesto dos processos de apoio e de defeitos do produto. No entanto, s vezes um aplicativo no pode cobrir completamente isso. Assim como qualquer empresa ou organizao nica, por isso deve ser o que o CRM vai significar para eles. At SugarCRM, este espao de aplicao foi cheio de jogadores que achavam que tinham o problema de CRM a resolver, e construir aplicaes proprietrias grandes que eram caras para implementar e apoiar alem notoriamente difcil de personalizar para satisfazer as suas necessidades. SugarCRM entrou e mudou esse cenrio, fazendo algo de CRM que barato para implementar, mais fcil de personalizar, e mais acessvel para os usurios finais trabalhar. projetado para ser um CRM que seus usurios no vo odiar, o que a filosofia que os fundadores da SugarCRM definem como seu objetivo primordial. Este livro destina-se a tornar este fcil o uso e a personalizao do aplicativo mostrando o que voc precisa e pode para fazer com ele. O contedo deste livro nicos, como eles vm diretamente da experincia da engenharia da SugarCRM, dando-lhe como o leitor um insight para o aplicativo que voc no consegue encontrar em nenhum outro lugar. O livro possui trs partes distintas: Parte 1: A Plataforma SugarCRM Parte 2: Customizando SugarCRM Out-of-Box Parte 3: Construindo novas funcionalidades em cima do SugarCRM Enquanto este livro destina-se a ser lido do incio ao fim, til tambm como uma referncia geral quanto a desenvolver para SugarCRM. Uma vez que voc tem o conhecimento de como a aplicao funciona internamente, voc pode ir para qualquer parte do livro e pegar qualquer de informao que voc pode precisar. O conjunto das informaes contidas no interior est atualizado com a verso do SugarCRM 5.5 , e a maior parte dos Listagems so construdas sobre a edio de comunidade da SugarCRM. Encorajo-vos a ler atravs do livro para fazer o download e instalar SugarCRM em sua mquina local e experimentar os Listagems, para ver como fcil trabalhar com o SugarCRM. Este livro apenas a ponta do iceberg, o que pode ser feito com SugarCRM. Por conseguinte, encorajo-vos tambm a visitar tambm o Sugar Forums (Fruns http://www.sugarcrm.com/) e o Sugar Developer Zone (http://developers.sugarcrm.com) para mais sobre o que o Sugar pode fazer por voc e onde estamos indo no futuro. A PLATAFORMA SUGARCRM Nesta primeira parte, voc vai aprender tudo sobre SugarCRM; a empresa e a comunidade as diversas funcionalidades da plataforma. Vai ver em profundidade como o MVC e o Framework de metadados juntamente com o CORE da aplicao. Voc tambm ir ver como voc pode integrar SugarCRM com diversas outras aplicaes utilizando a camada de WEBServices, e aprender sobre muitas outras funcionalidades da plataforma do Sugar oferece ao usurio e ao programador. O SUGARCRM? SugarCRM uma aplicao comercial de cdigo aberto. Quando pensamos em software comercial, pensamos proprietrios, software fechado. SugarCRM nico em que ele quebra a expectativa de software comercial, aproveitando o melhor do open-source software onde construdo para criar um produto que tem como foco a usurios finais e desenvolvedores, criando uma experincia positiva para ambos os grupos. Mas tambm tem as vantagens de uma empresa comercial, que inclui suporte de classe mundial, treinamento do usurio final abrangente, e de ponta a ponta teste de controle de qualidade para assegurar alta estabilidade do produto. Vejamos o SugarCRM com poucas perspectivas diferentes: como uma empresa, produto, e comunidade. A EMPRESA SugarCRM foi fundada em 2004 como um projeto de open source sobre no site SourceForge, http://www.sourceforge.net, um dos maiores sites de desenvolvimento open souce da Internet. Trs fundadores da SugarCRM, John Roberts, Clint oram, e Jac Taylor, tem uma experincia combinada de mais de 50 anos construindo Custumer Relationship Management (CRM) como aplicaes proprietrias para empresas do Silicon Valley. Eles cresceram frustrados com a falta de inovao em CRM e as elevadas taxas de insucesso das aplicaes de CRM proprietrias. Os fundadores da SugarCRM tiveram uma abordagem invulgar na construo de uma soluo de CRM. Em vez de escrever o cdigo em segredo e manter o produto proprietrio, os fundadores liberaram o cdigo com uma licena open-source permitido para qualquer parte interessada baixar, modificar, e redistribuir SugarCRM. Em poucos meses, foram transferido 50.000 copias e traduzido para dez lnguas. Em Novembro de 2004, o Sugar Open Source Projeto foi selecionado como projeto do ms pelo SourceForge.net. A popularidade da aplicao permitiu os fundadores do SugarCRM incorporar um negcio em torno do projeto de cdigo-fonte aberto e recebeu 2 milhes de dlares em financiamento de capital de risco da Draper Fisher Jurvetson, capital de uma empresa lder do Vale do Silcio. RPIDO CRESCIMENTO COMO OPEN-SOURCE E SAAS. A popularidade do SugarCRM no site SourceForge e a infuso de capital por investidores do Vale do Silcio permitiu que a empresa fosse se expandindo. SugarCRM estabeleceu uma sede em Cupertino, CA e comeou a construir a sua equipe de engenharia. No incio de 2005, SugarCRM introduziu o Sugar On-Demand , que um "Saas ou software como servio" (software fornecido para um utilizador atravs da nuvem) que permite aos clientes utilizarem o Sugar sem a instalao do software. A tecnologia On-Demand primeiro promove flexibilidade e controle maior sobre como a aplicao implementada, personalizada e utilizada. A inovao da SugarCRM no mercado foi campe em ambas as abordagens. Anteriormente, as empresas tinham oferecido no local ou On-Demand, raramente ambos. Em todos os casos, o cdigo mantinha-se proprietrio que significa que era muito difcil para os clientes compreender o que estavam comprando, e quase impossvel de ser modificado o cdigo sem grandes investimentos em servios profissionais e prazos longos de projeto. O PRODUTO O gerenciamento do relacionamento com o cliente uma indstria bem estabelecida que tem evoludo ao longo das ltimas duas dcadas. Simplesmente, o CRM sobre a utilizao de tecnologia de informao para obter uma melhor compreenso dos clientes e proporcionar uma experincia diferenciada do cliente em toda a relao entre ele e a organizao. Pensar em como transformar seus clientes, dando s empresas uma ferramenta para saber a sua histria as tendncias de compra e interaes, permitindo que voc use este conhecimento para planejar o futuro de suas interaes com eles. Suites de CRM, como, por exemplo a SugarCRM, fornecem ferramentas para todos os empregados que lidam face-a-face com o cliente como: marketing, vendas, suporte, bem como fornecer ferramentas de colaborao para facilitar as comunicaes e a funcionalidade de relatrios, para que os gestores possam entender o que est acontecendo em sua empresa. Suites de CRM tambm oferecem ferramentas de administrao para gerir utilizadores, fluxo de informaes, as personalizaes, e outros "bastidores" das operaes do sistema de CRM. O SugarCRM comeou como uma ferramenta de automao de fora de vendas e rapidamente expandiu para incluir automao de marketing e suporte ao cliente, bem como colaborao e comunicao entre todos os componentes da aplicao. Trata-se de uma aplicao web escritos em sua maioria em linguagem de programao PHP, apoiando verso 5.2.1 e superior como na verso do SugarCRM 5.5.0 , bem como utilizar o ltimo javascript e tcnicas flash para melhorar a experincia do usurio. Ele suporta trabalhar sobre o MySQL, Microsoft SQL Server e os servidores de banco de dados Oracle (Oracle apenas suportado na Enterprise Edition) bem como as implementaes sobre Windows, Linux, Mac OS X e Solaris. Sendo uma aplicao baseada em browser, que permite que os usurios finais possam utilizar o Internet Explorer, Mozilla Firefox, ou browser Safari da Apple. SugarCRM entra em trs edies do produto: Sugar Community Edition contm funcionalidade CRM concebidas para pequenas empresas. Sugar Professional contm a funcionalidade adicional para gerenciar as necessidades de empresas pequenas e mdias. Sugar Enterprise contm os recursos de CRM e suporte para grandes empresas. A seguir discutimos cada edio em: Sugar Community Edition: um Free Open Source Software (FOSS) licenciado sob os termos da Licena Pblica Geral GNU verso 3 (GPLv3). Sugar Community Edition est disponvel para download gratuito no ambiente de desenvolvimento do SugarCRM, http://www.sugarforge.org. Os clientes so livres para baixar, modificar e utilizar Sugar Comunity Edition sem restrio. Sugar Professional: Produto topo da SugarCRM, dirigidas s pequenas e mdias empresas. Ela contm funcionalidades adicionais, tais como a gesto de equipe, controle de acesso, criao de relatrios e acesso sem fios do dispositivo. oferecido sob uma licena comercial. Sugar profissional oferecido em uma subscrio anual. Sugar Enterprise: contm funcionalidades de nvel empresarial para grandes empresas. Ele adiciona funcionalidades adicionais que na grande maioria das implementaes requer suporte Oracle database e Advanced SQL reporting. comercialmente licenciada sob uma subscrio anual, assim como Sugar Professional. FIGURA 1 - MATRIZ DE FUNCIONALIDADES
SugarCRM muito personalizvel, permitindo mltiplas opes de implementao, que permite que at mesmo empresas sem conhecimentos de TI possam usar SugarCRM. Sugar On-Demand: Permite aos utilizadores configurar e executar SugarCRM dentro de minutos, utilizando os Centros de Gesto Dados do SugarCRM. As vantagens incluem disponibilidade e gesto garantida de sua instncia do SugarCRM, que tira toda a preocupaes de upgrade e manuteno do servidor. Sugar On-Site: Permite aos usurios instalar SugarCRM em seu hardware existente. Alm disso, SugarCRM tem um instalador Faststack que concebido para instalar todos os componentes necessrios (Servidor Web, servidor de base de dados, PHP) para SugarCRM. A beleza de possuir opes flexveis de implementao que mesmo os usurios utilizando Sugar On- Demand pode-se personalizar a forma como SugarCRM funciona atravs do poderoso, Mdulo Construtor e a ferramenta Studio muito fcil de usar. (Vamos aprender mais sobre eles nas partes 2 e 3.) Isto permite que qualquer pessoa usando SugarCRM para personaliz-lo s suas necessidades sem ter o nus de apoiar um servidor de aplicao. Alm disso, eles podem alavancar tanto a demanda e opes de implementao no local sem qualquer custo adicional. Isto bastante til para que um sistema possa ser utilizado como um backup do outro, ou pode ser usado como um ambiente de desenvolvimento e outro com produo. O crescimento da SugarCRM continuou ms aps ms desde que foi fundada como um projeto open source em 2004. O SugarCRM foi baixado durante 5,2 milhes de vezes, com mais 55.000 sistemas ativos em cerca de 195 pases apoiam quase meio milho de usurios. Alm disso, SugarCRM tem 4.500 clientes pagadores que utilizam as verses comerciais do produto para a empresa. A COMUNIDADE A chave para o sucesso da SugarCRM reside na grande comunidade de usurios e desenvolvedores em todo o mundo. O seu feedback e contribuies que ajudaram a construir o produto, e tm sido um recurso inestimvel para ajudar SugarCRM crescer. O SugarCRM como uma empresa tem reconhecido isso e construram vrias ferramentas para que a comunidade possa interagir com SugarCRM e outros usurios do SugarCRM por todo o mundo. Vamos ter um olhar para eles. SUGAR FORUMS E WIKIS O lugar mais fcil de interagir com a comunidade de Sugar so os fruns do Sugar (http://www.sugarcrm.com/forums/). Aqui onde os membros da equipe do SugarCRM, usurios finais, parceiros, e os programadores interagem para debater as questes relacionadas com o produto, saber mais sobre as prximas funcionalidades e releases, e aprender como os outros esto usando SugarCRM dentro da sua indstria. Os fruns so conduzidos pelos membros da equipe do SugarCRM e voluntrios da comunidade, e a forma mais fcil de participar da comunidade SugarCRM. O Sugar Wiki (http://www.sugarcrm.com/wiki/) um recurso inestimvel para dicas e truques para trabalhar com SugarCRM. Trata-se de uma wiki principalmente conduzida pela comunidade, mas tambm fornece a documentao oficial do SugarCRM no produto e podcasts de membros da equipe do SugarCRM em uma variedade de tpicos sobre SugarCRM. SUGAREXCHANGE AND SUGARFORGE SugarExchange (http://www.sugarexchange.com/) e o marketplace do SugarCRM onde qualquer usurio do Sugar que pretendam estender funcionalidade central de Sugar pode escolher entre centenas de extenses de mdulos, temas, e pacotes de idioma fornecidos pelos membros e parceiros da comunidade de Sugar. o lugar a onde se deve ir quando voc est procurando uma funcionalidade que pode ser facilmente adicionado ao seu SugarCRM. SugarExchange contm add-ons livres e no-livres para SugarCRM. Enquanto SugarExchange facilitada pelo SugarCRM, todas as transaes e suporte para a add-ons oferecido totalmente independente do SugarCRM, que proporciona um frum para a comunidade de programadores do SugarCRM para add-ons de vitrine para o produto. SugarForge (http://www.sugarforge.org/) o lado do desenvolvedor do SugarExchange, que oferece programao e projectos atividades orientadas e ferramentas para quem desenvolver sobre a plataforma SugarCRM. Isto concebido para oferecer funcionalidades semelhantes no site SourceForge ou Google Code, e oferece fruns, documentao e espao para seu add-ons. Muitas vezes, utilizado em conjunto com SugarExchange, onde SugarExchange utiliza a funo de ajuda add-ons para a comunidade Sugar como um todo. Existem mais de 600 projetos ativos do SugarForge at data, incluindo mais de 80 tradues de idiomas oferecidos para download gratuito. SUGAR DEVELOPER ZONE Se voc quiser realizar qualquer desenvolvimento em cima do SugarCRM, este o lugar para se estar. um recurso completo para qualquer desenvolvedor do Sugar, com links para o guia oficial do desenvolvedor do SugarCRM, fruns de programadores, e tutoriais sobre personalizaes e temas comuns. Possui tambm um blog que mantido pela equipe da SugarCRM, que fornece informaes de desenvolvedores sobre os futuros recursos do desenvolvedor em SugarCRM ou truques e dicas sobre desenvolvimento de aplicaes com SugarCRM. Como voc pode ver, SugarCRM no como um software comercial tpico, mas ela tem a opinio mais refinada de software aberto. Este livro debrua-se sobre esta distino, assim na parte 1 vamos olhar em profundidade a plataforma SugarCRM e as caractersticas do produto que o tornam ideal para a construo de uma aplicao de negcio. OBTENDO O SUGARCRM A fim de melhor acompanhar juntamente com os Listagems nos restantes captulos, voc provavelmente deve transferir e instalar SugarCRM. A edio da comunidade do SugarCRM est disponvel para download em http://www.sugarcrm.com/crm/download/sugar-suite.html. Voc tem duas opes para instalar SugarCRM deste site. Uma opo fazer o download do arquivo zip que contm a aplicao e instala-lo em sua mquina local ou servidor Web. Para fazer isso, voc precisar dos seguintes componentes instalados e configurados: Servidor Web: Apache 1.3 ou posterior, ou o IIS 6 ou posterior com FastCGI instalado se voc estiver usando o Windows. PHP: verso 5.2.1 ou posterior instalado e configurado para ser utilizado com os acima Web Server. Servidor de banco de dados: MySQL 5.0 ou posterior, ou o SQL Server 2005 ou posterior. Para instalar SugarCRM, basta abrir um browser web e apontar para o local onde SugarCRM foi descompactado. Se voc descompactou-o no diretrio de Sugar na raiz do servidor Web na sua mquina local, ponto o seu browser da web para http://localhost/sugar, e ento o instalador interativo do Sugar ir gui-lo para o resto do processo de instalao Para tornar mais fcil a pilha instalada, SugarCRM fornece vrios "faststack" instaladores que ir instalar SugarCRM junto com o Apache, MySQL, (ou o SQL Server Express para Windows), e empilha o PHP, para que voc possa estar preparado para rodar em poucos instantes. RESUMO Neste captulo, voc olhou o SugarCRM, e viu como open source e a natureza orientada pela comunidade da empresa que ajudou o produto crescer com um tal sucesso. Em seguida, voc olhou o produto, as vrias edies disponveis, bem como as diversas maneiras que SugarCRM pode ser implementado e usado por empresas. Em seguida, voc virou em direo a comunidade do SugarCRM, vendo como o SugarCRM como uma empresa e para a comunidade de Sugar pode interagir atravs dos dois fruns e wikis para repositrios e mercados de pacote. Finalmente, voc teve um breve olhar instalando Sugar, de modo que voc possa seguir com os Listagems para o restante deste livro. Vamos continuar com um mergulho profundo na sua plataforma destacando da SugarCRM. No captulo 2, voc vai olhar para o framework MVC em que Sugar construdo. ARQUITETURA MVC Com o lanamento do SugarCRM 5.0 , uma nova arquitetura MVC nasceu. Esta arquitetura foi concebida para eliminar as tarefas penosas para a construo de um mdulo para SugarCRM. Em vez de ter que manualmente definir templates e criar interaes e relaes de objeto, voc pode facilmente utilizar o framework, utilizando modelos padronizados e arquivos de definio para construir os vrios pontos de vises de informaes(views). O sistema tambm muito extensvel, permitindo novas views e ("templating") personalizados para serem construdos em cima dele. Antes de aprofundar em como o modelo MVC do SugarCRM funciona, vamos dar um passo para trs e ver o que MVC realmente . O QUE MVC MVC significa Modelo View Controller, e um padro arquitetnico muito comum de design de aplicao utilizado tanto na web quanto para desktop. Os objetivos de utilizar o padro MVC separar a lgica da interface do utilizador da lgica de aplicao, tendo uma camada entre os dois para facilitar a comunicao entre eles. Cada um dos Models, Views e Controllers tm a tarefa de realizar a manipulao de alguns papeis dentro de uma aplicao (ver Figura 2 ). FIGURA 2 - DIAGRAMA DO PADRO MVC
A camada Model representa a camada de lgica da aplicao. O objetivo desta camada para gerenciar a comunicao com quaisquer recursos externos, tais como bases de dados, Web Services, e ficheiros. Ele tambm contm alguma lgica de negcio da aplicao, tais como formas de calcular os valores do campo. Um bom modelo fornece uma interface limpa para os detalhes do pedido, fornecendo mtodos e funes para interagir facilmente com os servios de menor nvel e fornecer qualquer transformao ou interpretao necessria para que outras partes da aplicao possam ser utilizadas facilmente. A camada View representa a interface do usurio. Isto onde qualquer lgica de visualizao tratada, como layout de formulrio e exibio de dados, assim, para uma aplicao web a View seria uma pgina tpica da web. A camada View especfica para o papel que ela est destinada a ter, podendo ser uma perspectiva de entrada de dados o que seria diferente de uma View de visualizao de registro, embora eles possam representar o mesmo modelo. A camada Controller a unio entre o Model e a View. Um bom Controller ir aceitar o pedido do utilizador, chamar o Model para obter as informaes de que necessita, e ento chamar a View para retornar a informao ao usurio. Esta camada destinada a ser uma fina camada. Ela no deve conter lgica de negcios, ou comunicar-se com um banco de dados diretamente, ou lidar com a forma de exibir informaes ao usurio. Sugar tem utilizado o padro MVC para substituir a arquitetura envelhecida utilizado antes da verso 5.0. Apesar de ter sido baseado em muitos dos princpios da arquitetura MVC, no era verdadeiramente otimizado de forma a tirar o melhor partido dela. Vejamos agora a SugarCRM MVC. A FORMA MVC DO SUGAR O Sugar utiliza o padro MVC para processar os pedidos dos utilizadores. Cada pedido tem o seu entrypoint(Ponto de entrada) primrio no caso (ndex.php) que ir especificar as variveis de solicitao HTTP indicando o mdulo (que mapeia a definio de MVC de controlador) e a Action (que mapeia para a definio de MVC de View) como segue: http://servername/index.php?module=contacts&action=editview. Para a URL anterior, o pedido de Sugar seria para a Action EditView do mdulo de Contacts. A Figura 2- 2 mostra o que acontece internamente quando o pedido seja efetuado. FIGURA 3 - FLUXOGRAMA SUGAR MVC
SUGARAPPLICATION O primeiro passo no tratamento do pedido ocorre no nvel da SugarApplication. Esta classe gerencia muito dos pr-requisitos necessrios para a aplicao do Sugar, incluindo verificao da sesso, autenticao do usurio, definio do tema, e realizao da conexo com o banco de dados. Tambm trata muito da lgica pr- processamento da aplicao. Por exemplo a definio do tempo da zona do usurio no primeiro login, e permitindo que o usurio saiba quando o seu password expirou. A classe no concebida para ser modificada ou ampliada pelos desenvolvedores. No entanto, um mtodo de pr-processamento que existe na classe SugarController permite aos programadores inserir lgica para o tratamento do pedido antes que o controlador seja executado. Aps o carregamento do controlador, as seguintes tarefas so realizadas antes de executar o controlador: Verificao da autenticao do usurio. Se o usurio j estiver autenticado, ento voc vai continuar com a solicitao, caso contrrio voc ser redirecionado para o formulrio de login. Eu vou falar mais detalhadamente sobre autenticao de usurio no captulo 5. Utilizando as configuraes do usurio, qualquer controlador de acesso (ACL) listas as regras aplicadas para acesso ao modulo pelo usuario. Quaisquer regras preprocess desde que sejam definidas no nvel de aplicao so aplicadas pelo auditor. A definio do fuso horrio para o usurio em seu primeiro login tratada aqui. As strings corretas de idioma so carregadas, como definido pelo usurio aps o login. No captulo 5, eu vou falar sobre como SugarCRM pode ser internacionalizado para qualquer idioma. O tema que est atualmente selecionado pelo usurio inicializado e carregado. Eu vou falar mais sobre a forma como os temas trabalho no Captulo 5. O mtodo de preProcess() do controlador melhor usado quando se precisa ser alguma lgica de inicial antes de voc fazer qualquer coisa com um mdulo. A Listagem 2-1 prov um exemplo do que isso seria. Listagem 2-1. Listagem do mtodo de preProcess() no Controlador. <?php function preProcess() { global $current_user; if ( !is_admin($current_user) ) { echo 'This module is for admin use only!'; sugar_die(); } } Voc poderia usar isso se o mdulo vai ser um mdulo somente de admin, assim voc poder verificar inicialmente no controlador para ver se o usurio tem acesso a ele ou no. Isto evita a necessidade de adicionar esta lgica para cada perspectiva, o mdulo. Depois de todos estes pr-requisitos sejam atendidos, voc pode em seguida, passar para o SugarController, que projetado para ter o pedido e execut-lo. SUGARCONTROLLER A classe SugarController processa o fluxo principal do pedido, e destina-se a controlar todos os pedidos para o mdulo especificado. O SugarController implementa mapas de interpretao e execuo do que um controlador ir fazer no modelo MVC, e contm vrias aes-ganchos para aes comuns que voc teria em um mdulo tpico. Estas aes ficam disponveis fora da caixa padro, e incluem implementaes completas para DetailView, EditView, ListView alem de cadastro e deleo de registros. Vrias delas tm arquivos de definio, ou metadados, que so utilizados para definir o que eles veem e como agem, voc vai aprender mais sobre isso no Captulo 3. O SugarController ir fornecer uma representao para cada um dos pontos de viso do mdulo para o qual ela controla. Ele faz isto, fornecendo duas maneiras de lidar com o mapeamento de uma view. A primeira forma atravs de um mtodo de Action; a classe do controlador, o que representa a Action e controla a transferncia para a view. No mnimo, este mtodo ir especificar o ponto da View de utilizao com esta Action, mas ela tambm pode realizar alguma lgica a este nvel que no est realmente relacionada com a camada de visualizao. Listagem 2-2 mostra um Listagem, que vou chamar de "getthemail". Listagem 2-2. action_getthemail() <?php Public function action_getthemail() { if (mailExists()){ $this->view = 'getthemail'; } else{ $this->view = 'hasnomail'; } } O gancho de Action vai primeiro adicionar uma verificao para ver se o email existe antes de redirecionar para a view "getthemail. Se no houver correspondncia, ento ele ir usar hasnomail. Este tipo de situao comum, e pode fornecer ganchos para direcionar opinies diferentes de utilizao dependendo do estado da aplicao ou do tipo de pedido. Por Listagem, voc poderia ter diferentes opes baseadas em JSON ou dados em HTML, mas a lgica de ncleo poderia usar o mesmo gancho de Action. Se voc tiver lgica adicional do controlador que necessita ser adicionada, como, por Listagem, lidar com os parmetros extras do pedido, voc pode nomear a subclasse da classe SugarController como ModulenameController e salvando o arquivo como .php no diretrio do mdulo controlador. Listagem 2-3 um Listagem onde voc ir sobrescrever a Action EditView do mdulo reunies para permitir marcao de uma reunio concluda, passando o parmetro Close. Listagem 2-3. MeetingsController Class <?php class MeetingsController extends SugarController{ public function action_editview(){ if ( isset($_REQUEST['close'] )$this->bean->status = 'Held'; } } No Listagem anterior, voc simplesmente acrescentou uma nova pea de lgica para a Action da EditView que ir definir o status da reunio para "Held", se voc tiver solicitado para Close. O objeto bean corresponde aos dados do registro do mdulo solicitado. A id do registro pode ser pega na varivel record , ela e inicializada e carregado automaticamente na classe SugarController como uma parte do processamento do pedido, antes de chamar a lgica real da Action. s vezes, voc pode querer ser seletivo sobre substituir a Action do controlador, adicionando lgica antes ou aps a Action ser chamada. A classe SugarController proporciona ganchos para isto, por ter mtodos de pre_action() e post_action(), que so chamados antes e aps a Action chamada, se eles estiverem definidos. Existem vrios usos para isso. Listagem 2-4 mostra um Listagem onde voc ir verificar um valor alterado do campo de status durante um save do mdulo Bugs registrado na classe BugsController. Listagem 2-4. BugsController Class <?php class BugsController extends SugarController{ protected $_prevStatus = '';
public function pre_save(){ $bugFocus = new Bug; $bugFocus->retrieve($_REQUEST['record']); if (isset($bugFocus->id)){ $this->_prevStatus = $bugFocus->status; } parent::pre_save(); }
public function post_save(){ if ( ($bugFocus->status != $this->bean->status) && ($this->bean->status != 'Closed') ) { // Faa somente se o status no for FECHADO } parent::post_save(); } } No mtodo pre_save(), voc vai guardar o valor do status do bug na varivel de classe privada, $_prevStatus e ento poder verificar para ver se ele mudou para 'Closed' no mtodo post_save(). importante aqui para chamar os mtodos parentes pre_save() e post_save(), uma vez que no existe lgica para estes na classe SugarController. Outro uso para os mtodos pre_action() e post_action() para dar opes para estender a lgica necessria para uma Action sem a necessidade de sobrepor o mtodo principal de Action. Isto muito til para voc dividir a lgica de uma Action em vrias partes. Ento, se ela precisa ser ultrapassada por uma subclasse, voc s tem que ignorar a parte que precisa mudar. Vamos dizer que voc deseja sobrepor o BugsController no Listagem 2-4 com outra seleo para um tipo diferente de estado. Listagem 2-5 mostra como isto feito. Listagem 2-5. CustomBugsController Class <?php class CustomBugsController extends SugarController{ public function post_save(){ if ( ($bugFocus->status != $this->bean->status)&& ($this->bean->status != 'Pending') ) { // Faa algo agora que o bug no est pendente } parent::post_save(); // Chame a classe pai BugsController } } Agora j adicionamos uma verificao adicional no mtodo post_save() para os bugs que esto pendentes; neste caso, voc pode enviar por correio eletrnico para verificao por um analista ou equipe para a correo do problema. Se voc no tem lgica adicional para adicionar ao controlador, voc pode simplesmente criar um mapeamento a partir do nome da View e no final chamar o arquivo action_view_map.php. Este arquivo pode ser especificado em nvel de aplicao, no diretrio custom/include/MVC/Controller do Controller ou no nvel raiz do mdulo no diretrio de mdulos ou no diretrio de mdulos Custom. simplesmente definido como um array associativo com a chave como nome da Action e o valor da chave como o arquivo da View a ser chamada. Listagem 2-6 mostra uma Listagem deste cdigo. Listagem 2-6. action_view_map.php <?php $action_view_map['myspecialview']= 'edit'; $action_view_map['myreallyspecialview']= 'edit'; Utilizando o prefixo action_view_map para o arquivo do modulo de casos que voc deseja mapear no EditView. SUGARVIEW Aps o cdigo do controlador ser processado, e uma View vlida especificada, a classe extendida SugarView chamada. Esta classe fornece qualquer view necessria para manipulao, como a configurao do modelo de apresentao. Por predefinio, os ships da aplicao Sugar, como muitas views so projetadas out- of-box para lidar com certos tipos de Views. Tabela 1 especifica essas views. TABELA 1 - ALGUMAS DAS EXIBIES PADRO EM SUGAR Arquivo da View Nome da View Descrio view.edit.php
ViewEdit Handles Exibi a EditView ao usurio utilizando o framework de metadados. view.detail.php ViewDetail Exibi a ViewDetail ao usurio utilizando o framework de metadados. view.list.php ViewList Exibi a ViewList ao usurio utilizando o framework de metadados. view.ajax.php ViewAjax Usado para retornar dados ajax de voltar ao utilizador cliente view.popup.php ViewPopup Exibi a ViewPopup ao usurio utilizando o framework de metadados. view.classic.php ViewClassic Exibe a view criada utilizando os arquivos de estilo pr-MVC view.json.php ViewJson Retornam dados em formato JSON diretamente para o usurio sem qualquer outra marcao. view.noaccess.php ViewNoaccess Chamado quando o usurio no tem permisso para acessar determinada Action view.vcard.php ViewVcard Retorna os dados de um determinado objeto como um vCard Voc vai aprender mais sobre como o framework de metadados funciona no Captulo 3. Cada uma das Views anteriores tambm so personalizveis, estendendo a classe e adicionando as funcionalidades de que se necessita. Normalmente, quando sobre-escrevemos uma View, existem dois mtodos que voc ir querer sobre-escrever: o mtodo display() que projetado para lidar com a lgica real da View que esta sendo renderizada. Que por padro um mtodo vazio, para que possa ser personalizar a sada de tudo o que se precisa (chamando um modelo, um html, ou retornando uma string JSON). Existe tambm o mtodo predisplay(), que utilizado para o tratamento de qualquer cdigo de lgica de no-exibio, e tambm muitas vezes utilizado nas Views de base enumerados anteriormente. Isto permite que as Views de base definam lgica de visualizao de tal modo que, se forem sobrescritas, a classes filhas podem simplesmente substituir o mtodo de visualizao e no tm de se preocupar com a certeza de que o mtodo display() da classe pai ser chamado. Voc pode tambm definir as suas prprias views. Trata-se de um processo em duas partes: a primeira parte envolve adicionar um mtodo de Action no respectivo controlador que especifica o fim da chamada, enquanto outra parte adicionar uma entrada no action_view_map.php para direcionar a Action para a view a ser exibida. Listagem 2-7 mostra uma chamada de Action de Listagem no controlador (vai chamar-se View helloworld). Listagem 2-7. Mtodo de camada Controller action_helloworld() <?php public function action_helloworld(){ $this->view = 'helloworld'; } A chave aqui certificar-se de que a propriedade de View do Controller seja definida para o nome da View a ser chamada. Da, voc pode criar a sua prpria View, que sera definido no diretrio custom/include/MVC/View/views, e para o caso de um nvel de aplicao (disponvel para todos os mdulos) no module/modulename/views, ou no diretrio custom/module/modulename/views para as View definidas no nvel do modulo. Listagem 2-8 um Listagem da criao de seu prprio ponto de vista para a helloworld da Action. Listagem 2-8. view.helloworld.php <?php class ViewHelloworld extends SugarView{ var $message = 'Hello World!'; public function __construct(){ parent::SugarView(); } public function preDisplay(){ if ( isset($_REQUEST['message']) ) $this->message = $_REQUEST['message']; } public function display(){ echo "<p>{$this->message}</p>"; } } Se voc chamar a View do Listagem anterior, definido como uma View comum para a aplicao, e especificar o ponto de vista helloworld com argumentos, voc teria a emisso da mensagem Ol, Mundo! para o visor. Se voc especificar a mensagem a afixar nas variveis de pedido, Seria ignorarada a mensagem padro no mtodo preDisplay(), e a sada para o usurio no mtodo display(); Voc tambm pode adicionar personalizaes no fim das Views existentes no diretrio Custom. Isto muito til se voc estiver querendo personalizar um mdulo que define muitas Views, mas fazendo de maneira segura no caso de atualizaes do SugarCRM, que no requerem que voc copie e cole um bando de cdigo. Listagem 2-9 mostra como voc pode estender as seguintes chamadas EditView. Listagem 2-9. Customize a Module Defined View <?php require_once('modules/Calls/views/view.edit.php'); class CustomCallsEditView extends CallsEditView{ public function __construct(){ parent::CallsEditView(); } public function display(){ // code to add parent::display(); } } A qualquer hora voc estender uma classe, certifique-se de fazer a chamada ao mtodo dos pais, bem como para assegurar que voc est aproveitando qualquer lgica, acrescentada. Obviamente, que assume a personalizao que voc est fazendo reescreve o mtodo inteiro. ENTRYPOINTS Algumas vezes, determinadas aes na aplicao no se aplica realmente o modelo de modulo-ao. Muitas vezes este cdigo no exige autenticao para a aplicao, como, por Listagem, controle de imagens que so inseridas em um e-mail HTML. Para estas situaes, todo o fluxo do processo do normal do framework MVC, Ou no funciona ou no necessrio, e por isso que um entrypoint diferente na aplicao frequentemente necessrio. No entanto, ainda existem um pouco de cdigo que precisa ser criado e vrias medidas de segurana associadas que necessitam ser levadas em conta. Por causa disto o SugarCRM possui um mecanismo especial que garante acesso e o privilgio de poder nomear um arquivo como ponto de entrada para que esses casos sejam atendidos adequadamente. Para ajudar a dinamizar a utilizao de entrypoints, o Sugar 5.1 adicionou a habilidade de diretamente manipular estes pontos de entrada apesar do framework MVC. Isto feito em duas partes: a primeira parte um registro do entrypoint, que definido em include/MVC/Controller/entry_point_registry.php,e especifica os entrypoints disponveis; sempre que existam no sistema de arquivos, e se requerem autenticao ou no. Listagem 2-10 mostra parte do arquivo entry_point_registry.php. Listagem 2-10. entry_point_registry.php <?php $entry_point_registry = array( 'download' => array('file' => 'download.php', 'auth' => true), 'export' => array('file' => 'export.php', 'auth' => true), 'image' => array('file' => 'modules/Campaigns/image.php', 'auth' => false), 'acceptDecline' => array('file' => 'modules/Contacts/AcceptDecline.php','auth' => false), 'removeme' => array('file' => 'modules/Campaigns/RemoveMe.php', 'auth' => false), 'process_queue' => array('file' => 'process_queue.php', 'auth' => true), 'process_workflow' => array('file' => 'process_workflow.php', 'auth' => true), A chave do array de registro $entry_point_registry o nome entrypoint, que ser dado como parte do URL. O seu valor um array() com dois elementos: o elemento file o caminho para o arquivo entrypoint a ser chamado, e o elemento auth e a indicao se o entrypoint requer autenticao. O arquivo pode ser substitudo no diretrio custom/include/MVC/Controller/ Agora que o entrypoint foi definido, voc pode agora acessar a partir do navegador. Apontando o browser para a seguinte URL: http://servername/index.php?entryPoint=entrypoint. Se voc converter um entrypoint que no existia antes do Sugar 5.1 para o novo mdulo, certifique-se de alterar: if(!defined('sugarEntry'))define('sugarEntry', true); Para if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point'); No topo do arquivo entrypoint anterior. O QUE ACONTECE COM O MODELO? A camada de modelo muitas vezes a parte esquecida do paradigma MVC. Este, por sua vez, representado por uma classe bean obtidos a partir da classe principal SugarBean (definido em data/SugarBean.php) que cada bean deriva. O SugarBean fornece uma interface de baixo nvel para funcionalidades de armazenar, recuperar e excluir dados do banco de dados, bem como uma ferramenta de interpretao da estrutura da tabela definida em um arquivo vardefs.php em cada mdulo. Os conceitos centrais da camada de modelo no SugarCRM giram em torno das classes de beans, os vardefs, e a camada de dados. Vamos comear por olhar para as classes de beans. BEAN CLASSES E OS OBJETOS SUGAR A classe do bean o local primrio em que a camada de modelo do framework MVC do Sugar interage com o banco de dados ou quaisquer outros depositos de dados. O seu objetivo o de fornecer todos os mtodos que voc precisa no controlador para interagir com o mdulo. Ele vem com vrios mtodos por padro, como: Listagem, Salvar, Excluir, e Recuperar os registros, bem como mtodos auxiliares para as vistas padro que o SugarCRM fornece (Detalhe, Editar, e Lista). Uma coisa que aviso a maioria das pessoas e com eles construindo seus mdulos no SugarCRM que, muitas vezes, estes podem possuir dados com campos semelhantes com outros mdulos. Estes mdulos podem ser tambm objetos que representam o mesmo tipo de entidade. Por exemplo, um mdulo de aluno e professores seria provvel que ambos tenham endereos e campos de nmero de telefone. Devido a este tipo de situao, existem vrios modelos de mdulo que voc pode utilizar para se basear o seu mdulo. Eles esto listados na Tabela 2-2, e esto localizadas no diretrio include/SugarObjects/ TABELA 2 - MODELOS DE OBJETOS SUGAR NOME E DESCRIO Nome do modelo Descrio Basic Um modelo bsico com campos apenas para um nome e descrio, Alm dos campos behind of the scene id, deleted flag e created/modified timestamps. Este modelo extende praticamente todos os demais. Company Modelo com informaes que normalmente seriam utilizados por uma empresa, tais como nome, endereo, telefone, site, indstria, etc. File Usado quando o usurio carrega armazena arquivos. Issue Para modelar um problema ou sistema de rastreamento tarefa. Person Campos que representam uma pessoa como nome, endereo, telefone, email, etc. Sale Utilizado para objetos de transaes de vendas ou previso. Alm disso, voc poder aplicar os controles ajustveis ou team_security (para SugarCRM Professional e Enterprise apenas)de campos para qualquer um dos mdulos anteriores para permitir que os registros devam ser atribudas a uma pessoa ou uma equipe. Estas no so modelos plenos como os enumerados anteriormente que contm arquivos de bean, metadados de arranque e outros cdigos especficos, mas so apenas conjuntos adicionais de campos que um mdulo pode usar. Vamos ver como simples criar um novo mdulo baseado em um desses modelos. Se voc quiser um mdulo de Applicants para uma empresa, o modelo de Person e o mais apropriado para isto. A nova definio do bean seria algo como Listagem 2-11. Listagem 2-11. Applicants Bean Class <?php require_once('include/SugarObjects/templates/person/Person.php'); class Applicants extends Person{ public function __construct(){ parent::Person(); } // // Aqui, acrescente qualquer outro mtodo da classe bean que seria necessrio. // } VARDEFS Vardefs definem a forma como os campos de dados deve existir no banco de dados, bem como fornece propriedades de cada um sobre como Sugar deve lidar com eles. definido como um array associativo, e contm vrios pedaos. No nvel superior, voc encontrar informaes sobre o framework como um todo, tais como nome de tabela, se a tabela fornece auditoria e capacidades globais de pesquisa e uma descrio do objetivo da tabela. Isto definido no nvel superior do array associativo. FIELDS As definies dos campos so definidas no atributo 'fields' do array. Cada campo uma chave para este array e possui vrias propriedades, conforme mostrado na Tabela 2-3.
Attribute Default Setting Description name -- O nome do campo deve ser definido como o mesmo valor como a chave para este fielddef. vname -- O id do pacote de idioma para o rtulo deste campo. Isto utilizado na camada dos metadados para fornecer uma etiqueta de exibio para o campo. type -- O tipo de atributo: 'relate' representa o campo relacionado ao bean. 'datetime' e um valor do tipo date/time. 'bool' e um valor booleano. 'enum' e um campo enumerado 'assigned_user_name' e o link para o nome do usuario 'varchar' e uma string de valor varivel. 'link' promove o relacionamento com outro mdulo. table -- A tabela ao qual o campo pertence comment -- Uma descrio do que o campo representa. isnull True Defina esta opo para false se o campo no permitido armazenar valores nulos. len -- Tamanho do campo. dbType same as type attribute O tipo de campo do banco de dados reportable True Defina esta opo para false se este campo no deveria constar na lista de campos para o mdulo de relatrios (s se aplica para os mdulos que so utilizados no mdulo de relatrios). required False Definir isto como verdadeiro se este campo um campo obrigatrio. No EditView, o campo ser indicado como necessrio, e devem ter um valor vlido para salvar. Default -- O valor padro para este campo. massupdate True Defina este campo para false se este campo no pode sofrer atualizaes em massa. Unified_search false Defina para true se deseja este campo possa ser pesquisado quando fazendo uma busca unificada sobre este mdulo. S aplicvel se o vardef do mdulo tem o atributo de "unified_search" estabelecido no nvel superior da array vardef. rname -- O campo relacionado do mdulo que contm o valor para este campo. (Usado somente quando o tipo de campo se relacionar.) id_name -- O campo do mdulo que armazena o id do mdulo relacionado. (usado somente quando o tipo de campo se relacionar.) source Db Defina este atributo:"no-db", se o valor do campo no so provenientes do banco de dados. Isto concebido para ser usado para o campo calculado ou se o valor do campo pode ser recuperado em alguma outra forma. sort_on -- Se este campo representa valores concatenados no banco de dados, isto ir especificar qual campo de base de dados voc ele deve ser classificado. fields -- Se este campo representa valores concatenados no banco de dados, isso um array contendo os campos que so concatenados. Por Listagem: 'fields' => array('first_name','last_name'). db_concat_fields -- Se este campo representa valores concatenados no banco de dados, isso um array contendo os campos para concatenar no DB. Por Listagem: 'db_concat_fields' =>array('first_name','last_name'). importable True Defina este para "falso" se o campo no for importvel, ou defina como 'required' se o campo necessria para importar. options -- Se o campo um tipo enum, isto ser a chave para o pack de linguagem que especifica a enumerao dos valores de uso. relationship -- Para campos do tipo link, esse ser o nome da definio do relacionamento utilizado para construir este link.
Listagem 2-12 fornece uma amostra de alguns campos que seriam definidos na seco dos campos do vardefs para o mdulo do Listagem anterior. Listagem 2-12. Campo para o modulo Applicants definido no arquivo vardefs.php <?php $dictionary['Applicants']['fields']['first_name'] = array( 'name' => 'first_name', 'vname' => 'LBL_FIRST_NAME', 'type' => 'varchar', 'len' => '100', 'comment' => 'First name of the applicant', ); $dictionary['Applicants']['fields']['last_name'] = array ( 'name' => 'last_name', 'vname' => 'LBL_LAST_NAME', 'type' => 'varchar', 'len' => '100', 'comment' => 'Last lname of the applicant', ); $dictionary['Applicants']['fields']['name'] = array ( 'name' => 'name', 'rname' => 'name', 'vname' => 'LBL_NAME', 'type' => 'name', 'fields' => array('first_name', 'last_name'), 'sort_on' => 'last_name', 'source' => 'non-db', 'group'=>'last_name', 'len' => '255', 'db_concat_fields'=> array(0=>'first_name', 1=>'last_name'), 'importable' => 'false', ); $dictionary['Applicants']['fields']['referral_source'] = array ( 'name' => 'referral_source', 'vname' => 'LBL_REFERRAL_SOURCE', 'type' => 'enum', 'options' => 'referral_source_dom', 'len' => '100', 'audited' => true, 'comment' => 'Referral source of the application ( Recruiter, Existing Employee,etc )', 'merge_filter' => 'enabled', ); $dictionary['Applicants']['fields']['position_id'] = array( 'name' => 'position_id', 'vname' => 'LBL_POSITION_ID', 'type' => 'id', 'isnull' => 'true', 'reportable' => false, 'massupdate' => false, 'duplicate_merge'=> 'disabled', 'comment' => 'ID field of the position in the Positions module' ); $dictionary['Applicants']['fields']['position_name'] = array( 'name' => 'position_name', 'rname' => 'name', 'id_name' => 'position_id', 'vname' => 'LBL_ACCOUNT_NAME', 'type' => 'relate', 'table' => 'positions', 'isnull' => 'true', 'module' => 'Positions', 'dbType' => 'varchar', 'len' => '255', 'source' => 'non-db', 'unified_search' => false, 'comment' => 'Name field of the position in the Positions module' ); Voc definiu os primeiros e ltimos campos da tabela, e tambm adicionou um campo para o campo de nome, que dever ser a concatenao dos primeiros e ltimos campos de nome. No entanto, este domnio est disponvel apenas no bean e no sero guardados na base de dados. Voc tambm definiu um campo enum para armazenar a fonte de referncia, que provm de uma lista predefinida que na entrada de referral_source_dom no pack de linguagem. Em seguida, voc criou um campo relacionado ao mdulo de Position. O campo position_id armazenar uma referncia a tabela do modulo Position. O valor position_name de campo ser proveniente do mdulo das posies. NDICES Definies de ndices esto na chave indices da array, e representam todos os ndices da tabela. Cada uma das entradas da array, esta lista no tem as chaves. A tabela 2-4 apresenta a especificao dos atributos para as definies de ndice.
Atributo Descrio Name O nome do ndex que voc quer possuir no banco de dados. Type Primary o principal ndice da tabela, e no deve ser apenas um entre eles. Ele adiciona uma consistencia que apenas valores nicos so permitidos para os campos que este ndice utiliza. Index um ndice padro na tabela, til para agilizar as buscas e ordenar alternate_key, mesmo como ndice. foreing key a chave que liga um campo em uma tabela de um campo para outro, adicionando uma consistencia para os valores que podem ser utilizados no campo. Se o banco de dados ou tabela no suporta as chaves estrangeiras ento um ndice regular ser criada em vez. Fulltext um ndice Fulltext, til para fazer pesquisas de texto completo sobre uma mesa. Se o banco de dados ou tabela no suporta ndices fulltext ento o ndice ser ignorada. Fields Uma array que especifica o campo que compe o ndice, na ordem que voc deseja que eles indexados. Por Listagem: 'fields' => array('id','name','deleted'),. Db Defina um mysql, mssql, oracle ou se voc quer apenas o ndice nessa respectiva base de dados. Os padres para a definio do ndice em todas as bases de dados.
Listagem 2-13 um Listagem de alguns ndices citados no mdulo Applicants, como eles seriam definidos no arquivo vardefs. Listagem 2-13. Listagem de ndices no arquivo vardefs.php <?php $dictionary['Applicants']['indices'][] = array( 'name' =>'applicantspk', 'type' =>'primary', 'fields'=>array('id') ); $dictionary['Applicants']['indices'][] = array( 'name' =>'idx_applicants_name', 'type' =>'index', 'fields'=>array('last_name','first_name')) ); $dictionary['Applicants']['indices'][] = array( 'name' =>'idx_applicants_name_unique', 'type' =>'unique', 'fields'=>array('last_name','first_name','position_id')) ); Voc definiu trs ndices para a tabela. O primeiro deles o seu ndice principal, que o campo id e o principal identificador para o registro na tabela. Em seguida, voc cria um ndice com o nome da requerente de last_name first_name. Por ltimo, adicionar um ndice nico para a mesa que integra o nome do requerente e o id da posio que ele est aplicando para, que ir ajud-lo a evitar tendo registros duplicados na base de dados.
RELACIONAMENTOS As relaes esto no array 'relationships', e mostram as relaes entre este mdulo e os outros mdulos da aplicao. Cada relao listada na Tabela 2-5 deve ter um campo de ligao tambm na seo de campos dos vardefs para referncia.
Atributo Descrio lhs_module O modulo a esquerda do relacionamento. lhs_table A tabela do lado esquerdo do relacionamento. lhs_key A coluna chave primaria da tabela do lado esquerdo do relacionamento. rhs_module O modulo do lado direito do relacionamento. rhs_table A tabela do lado direito do relacionamento. rhs_key A coluna chave primaria da tabela do lado direito do relacionamento. relationship_type O tipo de relacionamento, que pode ser um-para-um, um-para-muitos, muitos-para-um, muitos-para-muitos. relationship_role_column O tipo de regra do relacionamento. relationship_role_column_value Define o identificador nico para a regra de relacionamento. join_table Para o relacionamento muitos-para-muitos, ele especifica o nome da juno da tabela. join_key_lhs Para relacionamentos muitos-para-muitos, esta a chave para juno da lhs_key na tabela de lhs_table. join_key_rhs Para muitos-para-muitos relacionamentos, isto a chave para ingressar na tabela que adere ao rhs_key no rhs_table. relationship_role_column Em relacionamentos Um-para-muitos, este definir um campo adicional no rhs_table para ser utilizado para igualar o registro. Isto mais comumente utilizado em relacionar campos flex, quando um campo utilizado para fornecer uma relao de vrios mdulos diferentes. Voc vai aprender mais sobre relacionar campo flexvel quando voc criar seu aplicativo de amostra no Captulo 11. relationship_role_column_value Para relacionamentos um-para-muitos, utilizado em conjunto com o campo 'relationship_role_column. Este define qual deve ser o valor desse campo adicional na rhs_table, que usado para igualar o registro.
Vamos construir alguns relacionamentos para o mdulo de Applicants que tenham trabalhado com a presente seo. Listagem 2-14 mostra como voc poderia defini-los nos vardefs. Listagem 2-14. Mostra as relaes definidas no arquivo vardefs.php <?php $dictionary['Applicants']['relationships']['applicants_modified_user' ] = array ( 'lhs_module' => 'Users', 'lhs_table' => 'users', 'lhs_key' => 'id', 'rhs_module' => 'Applicants', 'rhs_table' => 'applicants', 'rhs_key' => 'modified_user_id', 'relationship_type' => 'one-to-many', ); $dictionary['Applicants']['relationships']['applicants_notes'] = array ( 'lhs_module' => 'Applicants', 'lhs_table' => 'applicants', 'lhs_key' => 'id', 'rhs_module' => 'Notes', 'rhs_table' => 'notes', 'rhs_key' => 'parent_id', 'relationship_type' => 'one-to-many', 'relationship_role_column' => 'parent_type', 'relationship_role_column_value' => 'Applicants', ); O primeiro relacionamento um padro, definindo o relacionamento um-para-muitos entre os Users e o Applicants da tabela para efeitos do acompanhamento do usurio que realizou a ltima modificao do registro. A segunda relao permite-lhe atribuir notas aos registros de Applicants. Uma vez que as notas mdulo utiliza um relacionamento de campo flex, assim que voc pode especificar mais de um tipo de mdulo de relacionar a nota, voc deve especificar coluna de regra e valor de 'Applicants' que ajudam a qualificam a relao. CAMADA DE BANCO DE DADOS SugarCRM suporta trs outros sistemas de base de dados (DBMS) por predefinio: MySQL, Microsoft SQL Server e Oracle. Sugar fornece uma camada de abstrao para cada uma das interfaces do PHP para as bases de dados individuais. Isto permite abstrair os dados de programao em cada uma das classes de bean. Quanto ao Sugar 5.5, as seguintes extenses de dados listados na Tabela 2-6 so suportadas.
Extenso Descrio Notas mysql PHP mysql driver para MySQL 4.0 e posteriores. mysqli PHP mysql improved driver criado para MySQL 4.1+. oci8 Oracle OCI8 driver mssql PHP Microsoft SQL Server driver no suporta totalmente UTF-8 character set deprecated. dblib FreeTDS driver pode ser baixado em: http://www.sugarforge.org/frs/?group_id=6. sqlsrv Microsoft SQL Server Driver for PHP Adicionado ao Sugar 5.5 does no possui completo suporte a UTF-8 mais ir possuir no futuro.
Como afirmado anteriormente, a camada de banco de dados projetado de tal forma que muito abstrata, portanto voc nunca deveria ter que fazer chamadas para o BD com funes nativas, mas sim utilizar as reas expostas ou mtodos de classe para fazer todo o trabalho necessrio. Na listagem 2-15 mostra um Listagem de uma consulta da tabela de usurios, iterao atravs dos resultados, e elaborao e atualizao dos registros, se necessrio. Listagem 2-15. Iterao na Tabela de usurios atravs dos Mtodos Camada de banco de dados <?php $db = DBManagerFactory::getInstance(); $res = $db->query("select * from users"); while ( $row = $db->fetchByAssoc($res) ) { // remove the admin privilege from any non-active users if ( $row['status'] != 'Active' ) { $db->query("update users set is_admin = 0 where id = '{$row['id']}'"); } } O mtodo de consulta do objeto de banco de dados executa uma consulta ao banco de dados, e retorna de volta um recurso que pode ser manipulado como resultado. Em seguida, voc pode percorrer o conjunto de resultados, pegando cada linha usando o mtodo fetchbyassoc(). Uma parte prtica desse mtodo que por padro o html codifica os dados de voltar para o usurio, que pode ser desabilitado se isto no necessrio. Isto elimina outra dor de cabea, impedindo o processamento de scripts entre sites (XSS) ataques quando o contedo pode incluir cdigo javascript perigoso que invisvel para o utilizador. SUGAR ANTES DO MVC Os Mdulos do SugarCRM so frequentemente referenciados em duas categorias, MVC e pr-MVC. Os mdulos pr-MVC so parte do Sugar 4.5.1 e anteriores, e no usa a estrutura muito estruturada de aplicao para encaminhamento da requisio. Enquanto a URL solicitada seria a mesma interface usando o 'index.php' como o entrypoint e solicitando as variveis 'module' e 'action' para rota do pedido, seria contar com um arquivo PHP existente na raiz do diretrio do mdulo como ponto para a requisio. Isto causou um monte de trabalho extra para criar views muito comuns, como irei falar no Captulo 3. Uma parte agradvel sobre a transio da pr-MVC a MVC mdulos do Sugar que o estilo pr-MVC ainda suportado em verses do SugarCRM 5.0 e posterior. Voc tambm pode misturar e combinar estilos dentro de um mdulo, com algumas aes usando o estilo pr-MVC e outros usando o estilo MVC. Isto d aos programadores do mdulo alguma flexibilidade na transio para o mais recente modelo design. No entanto, recomenda-se a no construir novos mdulos ou reforar antigos utilizando esse padro uma vez que pode ser abandonada no futuro. RESUMO Neste captulo, voc aprendeu sobre o framework MVC. Voc teve um olhar mais aprofundado sobre o fluxo de pedido de aplicao atravs de um pedido, e viu como fcil de personalizar isto para satisfazer as suas necessidades. Voc tambm teve um olhar para aquilo que Sugar oferece 'out-of-box' em termos de aes, para que voc possa reutilizar estes em seus mdulos facilmente. Voc acabou de olhar, entrypoints na aplicao e como voc pode usar aqueles com o framework MVC. CAMADA DE METADADOS Muitas vezes, a essncia de um mdulo no seguem a logica CRUD Create, Recovery, Update e Delete. Esses mdulos tambm utilizam as mesmas formas bsicas de cada uma destas aes. Freqentemente, os programadores copiam e colam o mesmo cdigo bsico para manipular cada vez que criar uma nova vista, alterando apenas os tipos de entrada de nomes dos campos reais mostrado. Isto pode ser muito complicado e moroso, e atualizaes para determinados tipos (como um widget de calendrio) de campo teria que ser feita em toda a codebase, que pode ser uma tarefa bastante importante. At Sugar 5.0 , isto o que o criador tinha de tratar quando construir as vistas mais comuns em uso: o EditView, DetailView e ListView. Com o advento do Sugar 5.0 , este modelo foi alterado de forma que o layout destas opinies comuns podem ser definidos em um arquivo de metadados, de modo que mais fcil de construir e manter essas formas. Eu vou falar sobre a camada metadados, a respeito das diferentes formas em que utilizado. Este modelo tambm possui ganchos diretos com as ferramentas visuais de desenvolvimento do estdio e o construtor mdulos, que vou falar mais sobre nos Captulos 6 e 9. Vamos comear com o Listagem em que os metadados so utilizados para definir o DetailView e EditView. DETAILVIEW E EDITVIEW O formulrio principal de entrada dados para SugarCRM conhecido como o EditView. Este formulrio serve para tanto criar novos registros e atualizar registros existentes. Aps um save bem sucedido, ele redireciona para o DetailView, que a view apenas de leitura no registro. Ambas as formas trabalham em conjunto uns com os outros para fornecer o caminho principal para interagir com um registro de um mdulo. Tanto o detail e edit views dentro do Sugar do modelo MVC esto predefinidas para utilizar os metadados para construir os formulrios que so exibidos para o usurio. Eles fazem isso usando a classe EditView(definido em include/EditView/EditView2.php) para o EditView, e depois se estende a classe para a subclasse DetailView (definido em include/DetailView/DetailView2.php) para construir o DetailView. Cada uma destas classes trabalham da mesma forma. O primeiro passo configurar a view carregando o arquivo de metadados. Este arquivo estruturado como um array associativo que parte do array global $viewdefs. O esquema tem duas partes: a parte templateMeta define alguns elementos gerais para o form, conforme mostrado na Tabela 3-1 . A outra parte a seo do formulrio, que na prxima seo. TABELA 3 - A SEO TEMPLATEMETA EDIT E DETAIL VIEWDEFS Parent Attribute Atributo Default Descrio preRow none Codigo HTML inserido antes do form element. form buttons array('SAVE','CANCEL') para EditView array('EDIT','DUPLICATE', 'DELETE') para DetailView Um array de botes que aparece no topo do formulrio. Os seguintes botes esto predefinidos e disponveis, especificando a string como a array valor: "SALVAR": boto de salvar (EditView apenas) . "CANCELAR": boto Cancelar (EditView apenas) . "ELIMINAR": Delete current boto gravar. "DUPLICAR": duplicar o registro atual (DetailView apenas) . "EDITAR": ir para o Editview para a registro corrente (DetailView apenas) . "CONNECTOR": Boto para entrar no assistente para fuso de dados a partir de uma ficha. Se voc deseja utilizar o cdigo personalizado para definir o seu boto, voc pode faz-lo em uma array e especificar o atributo 'customcode' para especificar o cdigo do seu boto. Listagem: array( 'customcode" => ". form hidden array() Array de elementos html de entrada ocultos para colocar no formulrio. form hideAudit false True Se quiser ocultar o boto de auditoria. form headerTpl null Defina o caminho do arquivo de modelo de cabealho que deseja utilizar no lugar do padro. form footerTpl null Defina o caminho do arquivo de template do rodap que pretende utilizar no lugar do padro. form links array() Array de links para colocar no topo do formulrio. maxColumns 2 Numero de colunas de campos do formulario. widths Auto-calculado com base no nmero de colunas nos forms.
Definido como um array, um elemento para cada coluna, uma chave para o label e outro para o field. Listagem: array( '0' => array('label'=>'10','field'=>'30'), '1' => array('label'=>'10','field'=>'30'), ). A prxima parte dos viewdefs contm as definies de campo. Estes tambm so definidos em arrays associativos, mas so agrupadas por sees e por linhas. Agrupados por camadas permitem que voc faa um formulrio multi-seo, agrupando campos em comum. Alm disso, o agrupamento de linhas d aos usuarios a capacidade de ditar a colocao exata dos elementos sobre o formulrio. Se tiver definido o seu formulrio para que sejam duas colunas largas e tm duas sees, a seo panels da vardefs para as contas detailview seria algo como Listagem 3-1. Listagem 3-1. Seo dos campos de viewdefs para coluna de dois tipos. <?php $viewdefs['Accounts']['DetailView']['panels'] = array( 'default' => array( array( 'name', 'phone_office' ), array( 'parent_name', 'account_type' ), ), 'lbl_account_information' => array( array( 'ownership', 'rating' ), array( 'industry', 'sic_code' ), array( 'employees', 'annual_revenue' ), ), ); A view anterior teria duas seces do formulrio, um seria a seco ''Default' enquanto a segunda seria "lbl_account_information" a partir das strings mdulo de linguagem. O esquema seria duas colunas largas, com as principais informaes no topo do formulrio e o resto na segunda seco do formulrio. Quando renderizado seria semelhante a Figura 3-1 .
FIGURA 4 - VIEW ACCOUNTS_DETAILS COMO PERSONALIZADOS POR VIEWDEFS NO LISTAGEM 3-1 Agora que voc viu como fcil construir um layout de formulrio para um mdulo, vejamos como a renderizao interna do DetailView e do EditView trabalha. COMO DETAILVIEW E EDITVIEW TRABALHAM O controle do layout dos formulrios impulsionado pelos arquivos DetailView2.php e EditView2.php que contm as classes DetailView e EditView. (Note que h tambm as classes DetailView e EditView no DetailView.php e EditView.php bem, mas estas so utilizadas para Sugar 5.0 e anteriores) que faz o trabalho de analisar os arquivos de viewdefs, e realizar a construo dos templates, alem de preencher os campos em vrias etapas.
FIGURA 5 - DIAGRAMA DE FUNCIONAMENTO DO FLUXO BSICO. A primeira parte do trabalho ocorre no mtodo render(), que chamado no incio do mtodo process(). Este mtodo ir fazer o processamento real do arquivo viewdef, que ir comear a passar todos os painis e os campos que foram definidos. Ele tambm ir calcular a largura da coluna para que o layout do formulrio seja consistente em todo o formulrio. Isto ocorre apenas uma vez, no entanto, quando o formulario estiver pronto para ser exibido. A composio principal armazenada no diretorio cache/modules/modulename/ quando o formulrio processado pelo Smarty (http://www.smarty.net), que uma ferramenta html de template. A seguir, vamos olhar para o mtodo process() , onde as variveis de solicitao e os vardefs do mdulo so processados. A primeira parte lida com as variveis da solicitao, definindo algumas como 'return_module', 'return_action', e 'return_id' as variveis de classe que sero posteriormente definidos como valores ocultos do formulrio de modelo. A prxima parte intera atravs dos campos, formatao para o ecr, que cada tipo de campo exige. Os campos de Data e hora so formatados e convertidos para serem a data e hora correta na zona de tempo correta. Para campos enum e multienum, o mtodo process() vai passar e preencher as opes que fazem parte da seleo pendente que apresenta sobre o form; ele vai pegar os valores do array de definies de idioma $app_list_strings baseadando-se na chave dada no atributo 'options'. Ela tambm tem um gancho para que se o nome do campo for passado como uma varivel de pedido, ento ele ir preencher o campo com o mesmo valor. Por Listagem, se o $_REQUEST['name'] e definido como Jonh ento o campo no formulrio ser definido para esse valor. Finalmente, a ltima parte ocorre no mtodo de exibio, que realmente constri o template. Isto feito em duas partes: a primeira parte faz uma anlise inicial dos templates (os templates do cabealho e o rodap, bem como a seco principal do template) e sada para o diretrio cache/modules/modulename/. Este modelo ser construdo de acordo com as definies viewdef, e s ter de ser construda uma vez que armazenado no diretrio de cache depois construdo. Esse modelo em cache , ento, utilizado como base para a segunda parte, onde os valores de campo so preenchidos no formulrio. A segunda parte de construir e depois toma a sada temporria de um de parte e preenche os valores de campo; este o modelo que vai ser exibido para o usurio. Cada um dos campos da EditView DetailView e Forms so construdos a partir de templates comuns, que so integrados no modelo durante a primeira anlise deste modelo. Esses modelos de campos so provenientes dos modelos do SugarField, que iremos olhar adiante. SUGARFIELDS Cada campo apresentado no Form, sejam elas o EditView, DetailView, ou Formulario de pesquisa construdo para o tipo de campo que est sendo usando no SugarFields templates fields. A parte agradvel sobre este sistema que voc pode ter uma visualizao consistente cada vez que o tipo de campo exibido. SugarFields esto localizados no diretorio include/SugarFields/Fields/. Cada campo possui a definio base do campo do SugarFields, que tem modelos padro para cada uma das Views: EditView, DetailView e SearchForms widgets, bem como a classe denominada SugarFieldBase. Os ganchos exibem o modelo correto dependendo da viso que est sendo solicitada. Os outros campos so baseados sobre esta definio, mas apenas necessitando especificar o que diferente do modelo de base ou o modelo sob o qual o campo derivado. Por exemplo, o campo "Phone' apenas especifica uma sobreposio do modelo DetailView, se a integrao do Skype ativada de modo a exibir ser um link em vez de apenas texto. Listagem 3-2 mostra o cdigo. Listagem 3-2. Phone SugarField DetailView Template {if !empty({{sugarvar key='value' string=true}})} {assign var="phone_value" value={{sugarvar key='value' string=true}} } {sugar_phone value=$phone_value } {/if} {{if !empty($displayParams.enableConnectors)}} {{sugarvar_connector view='DetailView'}} {{/if}} Da mesma forma, voc tambm pode modificar a visualizao de qualquer um dos tipos de campo, simplesmente por inserir uma cpia do arquivo correspondente no interior do diretorio custom/include/SugarFields/Fields/fieldname/. Por exemplo, se voc gostaria de mudar a forma de renderizaodo campo "Link" da DetailView, voc poderia simplesmente adicionar o cdigo da listagem 3-3 para o arquivo custom/include/SugarFields/Fields/Link/DetailView.tpl. Listagem 3-3. DetailView Template Sobreescrita campo do tipo 'Link' {if !empty($vardef.value)} <a href='{$vardef.value}' target="_blank">{$vardef.value}</a> {/if} O cdigo anterior teria sempre links abertos em uma nova janela, independentemente de quaisquer definies que podem ser feitas nas vardefs. Da mesma forma, voc tambm pode configurar os tipos de campos personalizados. Vamos dizer que em vez de alterar o cdigo do modelo do link de padro, voc pretende definir um tipo diferente de campo link que por padro a abertura do link em uma nova pgina. Para fazer isso, voc poderia simplesmente criar um novo diretrio custom/include/ SugarFields/Fields/ chamados Newpagelink, e copiar o DetailView.tpl mostrada na listagem 3-3 para esse diretrio. Ralete, um tipo de SugarField, que utilizado quando especificamos um registro para se relacionar com o registro atual. Uma parte deste campo um boto 'Select', que exibe uma janela para selecionar o registro para se relacionar. Um Form pop-up que voc ver tambm muito definvel atravs metadados, como voc vai ver na prxima seo. LISTVIEWS A vista predefinida para maioria dos mdulos a ListView, que fornece uma listagem de registos atuais do mdulo. Ela tambm tem tanto a pesquisa bsica para rapidamente localizar registros, como uma forma mais aprofundada de pesquisa, para construir consultas mais detalhadas, que d a opo de salvar os termos de pesquisa para uso posterior. Utilizando o formulrio do ListView tambm possvel fazer atualizaes em massa de registros com facilidade (Ver listagem 3-4 ). Listagem 3-4. Listviewdefs.php Para o Mdulo Calls <?php $listViewDefs['Calls'] = array( 'SET_COMPLETE' => array( 'width' => '1', 'label' => 'LBL_LIST_CLOSE', 'link' => true, 'sortable' => false, 'default' => true, 'related_fields' => array('status') ), 'DIRECTION' => array( 'width' => '10', 'label' => 'LBL_LIST_DIRECTION', 'link' => false, 'default' => true ), 'NAME' => array( 'width' => '40', 'label' => 'LBL_LIST_SUBJECT', 'link' => true, 'default' => true ), 'CONTACT_NAME' => array( 'width' => '20', 'label' => 'LBL_LIST_CONTACT', 'link' => true, 'id' => 'CONTACT_ID', 'module' => 'Contacts', 'default' => true, 'ACLTag' => 'CONTACT' ), 'PARENT_NAME' => array( 'width' => '20', 'label' => 'LBL_LIST_RELATED_TO', 'dynamic_module' => 'PARENT_TYPE', 'id' => 'PARENT_ID', 'link' => true, 'default' => true, 'sortable' => false, 'ACLTag' => 'PARENT', 'related_fields' => array('parent_id', 'parent_type') ), 'DATE_START' => array( 'width' => '15', 'label' => 'LBL_LIST_DATE', 'link' => false, 'default' => true, 'related_fields' => array('time_start'), ), 'ASSIGNED_USER_NAME' => array( 'width' => '2', 'label' => 'LBL_LIST_ASSIGNED_TO_NAME', 'default' => true ), 'STATUS' => array( 'width' => '10', 'label' => 'LBL_STATUS', 'link' => false, 'default' => false ) ); TABELA 4 - OPES DE ATRIBUTO DE LISTVIEWDEF Atributo Descrio width Tamanho do campo label Label do Language pack utilizado para o cabealho de coluna. link True se este campo ser um link, o padro false. default True, se este campo est na ListView padro. False, se no na ListView padro, mas podem ser adicionados mais tarde. sortable False se esta coluna no e ordenvel, o padro true. related_fields Array de campos que so usados em conjunto com determinado campo de visualizao. Uma utilizao comum para relacionar campos de lista os outros campos necessrios para ajudar a pegar os valores do campo. Id Para incidir sobre campos, isto o id do mdulo atual que fornece um link para o outro mdulo. dynamic_module Para se relacionar campos flex, este o campo que contm o nome do mdulo que voc esto relacionadas. module Para campos relacionados, este o nome do mdulo ao qual esta relacionado ACLTag Este o mdulo utilizado para verificar se o usurio tem acesso ao mdulo conexo segundo a ACL. Sortable e default so usadas mais frequentemente. Tendo o atributo Sortable definido para false pode ser muito teis para os campos que so calculados, pois muitas vezes estes campos so impossveis de classificar corretamente utilizando declaraes de SQL no Listview. O atributo padro permite-lhe configurar uma lista de campos 'default' e 'available', de modo que o que apresentado para o usuario uma lista mais sensata de campos a se ter, ainda tendo a capacidade de ajustar o layout conforme necessrio. O usurio pode modificar os campos que ele ou ela deseje mostrar ou ocultar atravs de uma seo especial dentro do painel de busca avanada de pesquisa (Figura 3-3). FIGURA 6 - LISTVIEW CUSTOMIZADA
As duas primeiras colunas controlam a visibilidade das colunas para o ListView. Voc tambm pode definir a ordem de classificao padro e direo da "Order by column" e "Direction'". Uma vez que voc tenha o conjunto de busca definido, voc pode salv-lo bem aqui. Falando do formulrio de pesquisa, este tambm uma parte do ListView que podem ser facilmente personalizados. Vamos ver como ela funciona. DEFININDO CAMPOS DE BUSCA Um componente importante dos ListViews so as caixas de pesquisa no topo da lista. Os formulrios de pesquisa permitem-lhe filtrar os registros do ListView abaixo, bem como salvar estes parmetros para utilizao posterior. A execuo de pesquisas no SugarCRM possui dois conjuntos de caixas de pesquisa: uma pesquisa bsica com um nmero pequeno de campos comuns e uma pesquisa avanada que oferece opes mais completas de pesquisa. No h nenhuma restrio sobre o uso destes conjuntos de campos de pesquisa, mas a inteno ter o conjunto padro de campos de pesquisa que consistem em apenas aqueles que so mais comumente utilizados, como, por exemplo, pesquisando pelo nome. O ponto de vista de pesquisa avanada para proporcionar uma busca mais detalhada, com opes para pesquisar por mais de um campos existentes na tabela. A pgina de pesquisa avanada tambm ir conter um widget para mudar os campos apresentados na forma do ListView, bem como guardar a pesquisa atual para que possa ser acessado posteriormente. No entanto, recomendvel acrescentar ndices do banco de dados para todos os campos que voc pretende pesquisar sobre, o que voc aprendeu a fazer novamente no Captulo 2. O arquivo de metadados searchdefs.php parece muito semelhante ao editviewdefs.php e detailviewdefs.php, como voc pode ver na listagem 3-5 , que mostra o arquivo searchdefs.php para o mdulo de Contas. Listagem 3-5. Searchdefs.php Arquivo de Metadados do modulo de contas. <?php $searchdefs['Accounts'] = array( 'templateMeta' => array( 'maxColumns' => '3', 'widths' => array( 'label' => '10', 'field' => '30' ), ), 'layout' => array( 'basic_search' => array( 'name', 'billing_address_city', 'phone_office', array( 'name' => 'address_street', 'label' =>'LBL_BILLING_ADDRESS', 'type' =>'name' , 'group'=>'billing_address_street' ), array( 'name'=>'current_user_only', 'label'=>'LBL_CURRENT_USER_FILTER', 'type'=>'bool' ), ), 'advanced_search' => array( 'name', array( 'name' => 'address_street', 'label' =>'LBL_ANY_ADDRESS', 'type' =>'name' ), array( 'name' => 'phone', 'label' =>'LBL_ANY_PHONE', 'type' => 'name' ), 'website', array( 'name' => 'address_city', 'label' =>'LBL_CITY', 'type' => 'name' ), array( 'name' => 'email', 'label' =>'LBL_ANY_EMAIL', 'type' => 'name' ), 'annual_revenue', array( 'name' => 'address_state', 'label' =>'LBL_STATE', 'type' => 'name' ), 'employees', array( 'name' => 'address_postalcode', 'label' =>'LBL_POSTAL_CODE', 'type' =>'name' ), array( 'name' => 'billing_address_country', 'label' =>'LBL_COUNTRY', 'type' =>'name', 'options' => 'countries_dom', ), 'ticker_symbol', 'sic_code', 'rating', 'ownership', array( 'name' => 'assigned_user_id', 'type' => 'enum', 'label' =>'LBL_ASSIGNED_TO', 'function' => array( 'name' => 'get_user_array', 'params' =>array(false) ) ), 'account_type', 'industry', ), ), ); Tal como os editviewdefs e detailviewdefs, voc pode apenas especificar o nome do campo vardef para utilizao, ou especifique-o como um array se voc precisar fazer alteraes para a implementao padro do campo no mesmo ponto de vista. As opes de array so as mesmas que os detailviewdefs e editviewdefs. A grande diferena com o arquivo de metadados searchdefs.php que existe um atributo "layout" em vez do atributo "panels", que tem duas opes de 'basic_search' e 'advanced_search' para especificar os campos sobre os formulrios de pesquisa. FIELD OVERLAYS s vezes, voc gostaria de entregar um pouco mais informaes ao usurio sobre um registro, mas no queremos que eles vo DetailView para chegar a ele. Felizmente, os ListViews permitem-lhe definir texto que iria aparecer em uma janela pop-up quando o usurio paira sobre um campo no ListView, que podem puxar os seus contedos com os valores dos campos do registro atual. Este arquivo de metadados funciona de forma diferente do que os outros. Voc ir especificar uma funo de chamada, cujo nome est no formato de 'additionalDetailsobjectname' que ir retornar um array. Os atributos da array, mostrados na Tabela 3-3, ir fornecer a definio do campo substituies. TABELA 5 - ADDITIONALDETAILS FUNO RETORNAR ATRIBUTOS DE MATRIZ Atributo Descrio String O texto a mostrar na sobreposio do campo. width Opcional, a largura da janela de sobreposio do campo. Padres de 300px. editLink Opcional, o link para onde ir ao clicar sobre o boto 'edit' do campo. viewLink Opcional, o link para onde ir ao clicar sobre o boto 'view' no ttulo de sobreposio do campo. fieldToAddTo Nome do campo na EditView adicionar sobreposio do campo.
Na pgina do ListView, voc ver um cone pendente de seta, que indica os detalhes adicionais disponveis. A razo deste arquivo de metadados funciona de forma diferente do que os outros que, muitas vezes, o atributo 'string um valor calculado. A funo passada com um array de valores dos diversos campos no mdulo para esse registro, que por sua vez pode construir o texto para mostrar no popup. Listagem 3-6 mostra uma listagem desta funo, neste caso, o exemplo utilizado para construir a sobreposio do campo para o mdulo de bugs. Listagem 3-6. additionalDetails.php Arquivo de metadados para o modulo Bugs. <?php function additionalDetailsBug($fields) { static $mod_strings; global $app_strings; if(empty($mod_strings)) { global $current_language; $mod_strings = return_module_language($current_language, 'Bugs'); } $overlib_string = ''; if(!empty($fields['DATE_ENTERED'])){ $overlib_string .= '<b>'. $app_strings['LBL_DATE_ENTERED'] . '</b> ' . $fields['DATE_ENTERED'] . '<br>'; } if(!empty($fields['SOURCE'])){ $overlib_string .= '<b>'. $mod_strings['LBL_SOURCE'] . '</b> '. $fields['SOURCE'] . '<br>'; } if(!empty($fields['PRODUCT_CATEGORY'])){ $overlib_string .= '<b>'. $mod_strings['LBL_PRODUCT_CATEGORY'] . '</b>' . $fields['PRODUCT_CATEGORY'] . '<br>'; } if(!empty($fields['RESOLUTION'])){ $overlib_string .= '<b>'. $mod_strings['LBL_RESOLUTION'] . '</b>' . $fields['RESOLUTION'] . '<br>'; } if(!empty($fields['DESCRIPTION'])){ $overlib_string .= '<b>'. $mod_strings['LBL_DESCRIPTION'] . '</b>' . substr($fields['DESCRIPTION'], 0, 300); if(strlen($fields['DESCRIPTION']) > 300){ $overlib_string .= '...'; $overlib_string .= '<br>'; } } if(!empty($fields['WORK_LOG'])) { $overlib_string .= '<b>'. $mod_strings['LBL_WORK_LOG'] . '</b>' . substr($fields['WORK_LOG'], 0, 300); if(strlen($fields['WORK_LOG']) > 300){ $overlib_string .= '...'; } } return array( 'fieldToAddTo' => 'NAME', 'string' => $overlib_string, 'editLink' =>"index.php?action=EditView&module=Bugs&return_module=Bugs&record={$fields['ID']}", 'viewLink' =>"index.php?action=DetailView&module=Bugs&return_module=Bugs&record={$fields['ID']}" ); } A Figura 3-4 mostra o resultado final do arquivo additionaldetails.php no mdulo de bugs Listview. Ele ativado clicando no cone da seta para baixo no incio da linha. FIGURA 7 - DETALHES ADICIONAIS DO REGISTRO
SUBPANELS Como vimos no Captulo 2, os mdulos podem ser ligados a outros mdulos de muitas formas. Relacionamento Um-pra-Um so normalmente expressos usando um campo id correspondentes em cada mdulo, fornecendo um registro para o outro. Relacionamentos Um-para-Muitos para os mdulo childs so geralmente expressos da mesma forma, proporcionando um campo id para explorao o id do registro do mdulo parents no registro do mdulo child. Trabalhar com esses tipos de relaes, muitas vezes uso a expresso 'relate' ou 'parent' no tipo de campo do DetailView, que foi mostrado no incio deste captulo, quando falei sobre os diferentes tipos de campos. No entanto, ao expressar uma relao muitos-para-muitos, ou os registos relacionados mostre o child em um registro do mdulo parent em um relacionamento um-para-muitos, sera necessrio utilizar um paradigma diferente que pode mostrar todos os registros relacionados ao registro atual. Para isso, voc vai reciclar o ListView utilizado antes, mas desta vez torn-lo parte do formulrio DetailView. Isto permite trabalhar com o ListView de forma mais interactiva. A Figura 3-5 mostra os diversos tipos de relacionamento disponveis. FIGURA 8 - DIAGRAMA ILUSTRANDO OS DIFERENTES TIPOS DE RELACIONAMENTO DISPONVEIS
H duas partes para a construo de um painel. A primeira parte definir a estrutura real do painel propriamente dito. Estas definies so armazenadas no diretrio /subpanels/ dentro do diretrio de metadados. A definio do padro do painel armazenado no arquivo default.php nesse diretrio; um exemplo disto pode ser visto na listagem 3-7 , onde voc v como definido o Subpainel do mdulo de contatos. A segunda parte discutida na prxima seo. Listagem 3-7. Definio padro para o Subpainel do Modulo de Contatos <?php $subpanel_layout = array( 'top_buttons' => array( array('widget_class' => 'SubPanelTopCreateButton'), array('widget_class' => 'SubPanelTopSelectButton', 'popup_module' => 'Contacts'), ), 'where' => '', 'list_fields' => array( 'first_name'=>array( 'name'=>'first_name', 'usage' => 'query_only', ), 'last_name'=>array( 'name'=>'last_name', 'usage' => 'query_only', ), 'name'=>array( 'name'=>'name', 'vname' => 'LBL_LIST_NAME', 'sort_by' => 'last_name', 'sort_order' => 'asc', 'widget_class' => 'SubPanelDetailViewLink', 'module' => 'Contacts', 'width' => '23%', ), 'account_name'=>array( 'name'=>'account_name', 'module' => 'Accounts', 'target_record_key' => 'account_id', 'target_module' => 'Accounts', 'widget_class' => 'SubPanelDetailViewLink', 'vname' => 'LBL_LIST_ACCOUNT_NAME', 'width' => '22%', 'sortable'=>false, ), 'account_id'=>array( 'usage'=>'query_only', ), 'email1'=>array( 'name'=>'email1', 'vname' => 'LBL_LIST_EMAIL', 'widget_class' => 'SubPanelEmailLink', 'width' => '30%', 'sortable'=>false, ), 'phone_work'=>array ( 'name'=>'phone_work', 'vname' => 'LBL_LIST_PHONE', 'width' => '15%', ), 'edit_button'=>array( 'vname' => 'LBL_EDIT_BUTTON', 'widget_class' => 'SubPanelEditButton', 'module' => 'Contacts', 'width' => '5%', ), 'remove_button'=>array( 'vname' => 'LBL_REMOVE', 'widget_class' => 'SubPanelRemoveButton', 'module' => 'Contacts', 'width' => '5%', ), ), ); Existem trs partes distintas da definio painel: Atributo 'top_buttons' : uma array que define os botes que aparecem no topo da grade painel. Estes provm dos modelos no diretorio include/generic/SugarWidgets/, tal como especificado pelo atributo "widget_class". Atributo 'where' : uma seqncia de caracteres que permite que ao painel passar uma condio suplementar para a clusula WHERE da Query SQL subjacente que vai construir o painel. Atributo 'list_fields' : um array associativo dos campos para mostrar no painel. Ela segue um padro semelhante ao detailviewdefs.php e editviewdefs.php H algumas coisas interessantes de observar na definio painel. Em primeiro lugar, cada campo que no est apenas exibindo o texto deve indicar que SugarWidget utilizando para tornar o campo. O SugarWidget mais comum utilizado o "SubPanelDetailViewLink", que utilizado para fornecer um link para a determinado registro ou para um registro correspondente. No caso de um registo correspondente, o campo "target_module" usado para especificar os campos relacionados do mdulo, bem como o campo "target_record_key" utilizado para fornecer o id do registro do mdulo actual que se relaciona com o outro mdulo. Uma coisa que voc pode ter notado que este campo esta tambm na definio painel, mesmo que no sej mostrado. utilizado na construo de uma consulta que preencher os campos painel, portanto, atribuir a opo "usage" e configurando-a para "query_only" para certificar-se de que voc no mostrar a tabela. Os botes editar e remover tambm tm seus prprios widgets. Uma vez que voc tenha a definio do painel construda, voc pode agora adicionar uma referncia a ela no arquivo subpaneldefs.php , que est localizado na pasta metadata/ do mdulo. Isto um array associativo, que desligado da varivel global $layout_defs. Para cada painel que deseja, voc vai adicionar uma entrada no arquivo subpaneldefs.php Listagem 3-8 mostra uma entrada neste arquivo. Neste caso, para as citaes painel no mdulo de Contatos. Listagem 3-8 - SubPainel definido no Mdulo Contatos no arquivo subpaneldefs.php <?php $layout_defs['Contacts']['subpanel_setup']['quotes'] => array( 'order' => 50, 'module' => 'Quotes', 'sort_order' => 'desc', 'sort_by' => 'date_quote_expected_closed', 'subpanel_name' => 'default', 'get_subpanel_data' => 'quotes', 'add_subpanel_data' => 'quote_id', 'title_key' => 'LBL_QUOTES_SUBPANEL_TITLE', 'get_distinct_data' => true, 'top_buttons' => array(array('widget_class' => 'SubPanelTopCreateButton')) ); A definio anterior do painel bastante simples. Voc indica o campo de link (quotes) e mdulo que so relativas a (Quotes). Pode tambm especificar um tipo campo de ordenao padro afim de a utilizar quando exibindo o painel. Evidentemente, isso pode ser alterado pelo utilizador caso ele ou ela altere a ordem de classificao de um ListView, clicando no cabealho da coluna. Voc tambm ter a oportunidade de alterar os botes que sero exibidos no topo do formulrio, no caso de querer alterar o atributo "top_buttons" como na definio painel. s vezes, o subpainel do mdulo deve ser apresentados de forma diferente dependendo da situao em que utilizada. Para isso, voc pode definir um arquivo adicional de definio com um nome diferente para o mesmo diretrio subpanels/ e em seguida, a partir do arquivo subpaneldefs.php, voc pode fazer referncia ao nome. Listagem 3-9 um exemplo do subpainel de contratos no mdulo documentos.
Listagem 3-9 Subpainel de Contratos definido no modulo de documentos no arquivo subpaneldefs.php <?php $layout_defs['Contacts']['subpanel_setup']['contracts'] => array( 'order' => 20, 'sort_order' => 'desc', 'sort_by' => 'name', 'module' => 'Contracts', 'subpanel_name' => 'ForDocuments', 'get_subpanel_data' => 'contracts', 'add_subpanel_data' => 'contract_id', 'title_key' => 'LBL_CONTRACTS_SUBPANEL_TITLE', 'top_buttons' => array(), ); Voc deve especificar o arquivo de definio do subpainel para utilizao, dando o seu nome no arquivo no atributo "subpanel_name". Puxando todos juntos, voc tem um painel completo construdo. A Figura 3-6 mostra um Listagem do painel contactos nos modulo de contas. FIGURA 9 - SUBPAINEL DE CONTATOS NO MODULO CONTAS
RESUMO Neste captulo, voc explorou as partes principais do framework de metadados. Voc comeou a olhar os arquivos editviewdefs.php e detailviewdefs.php, e viu como eles constroem os principais formularios utilizados no mdulo. Voc analisou ento o ListViews, como eles so construdos, assim como os componentes adicionais, como as caixas de busca e os detalhes adicionais de sobreescrita de campo. Voc finalmente olhou os SubPanels, e mostrei como construir-los no mdulo, bem como acrescentar-lhes o formulario de DetailView do mdulo relacionado. Voc j olhou para os dois principais componentes da plataforma, a MVC e framework de metadados. Vamos agora passar aprendizagem como SugarCRM pode interagir com outras aplicaes que utilizam a Web Services framework. WEB SERVICES Uma das maiores questes sobre qualquer aplicao construda nos ltimos anos gira em torno dos Web Services. O aplicativo suporta? Como pode uma aplicao interagir com eles? Que mtodos so suportados? Web Services so uma das formas mais populares de no apenas ter a sua aplicao interagindo com outras aplicaes, mas que tambm sirvam como ferramentas para o mundo exterior interagir com voc. O QUE SO WEBSERVICES? Um servio Web definido pelo W3C como "um sistema de software projetado para suportar interoperacionalidade mquina-a-mquina sobre a rede." Voc costuma usar Web Services em termos de uma API que pode ser acessada atravs de uma rede. Nos tempos antigos, estavam incorporadas tecnologias como Object Management Group (OMG) Common Object Request Broker Architecture (CORBA), Microsoft'S DCOM (Distributed Component Object Model), ou Java/Remote Method Invocation (RMI)da SUN . Como a internet tem crescido nos ltimos anos, os protocolos tm crescido para tomar o lugar dessas tecnologias obsoletas. Com este crescimento de servios Web, alguns padres diferentes emergiram. Um padro o Object Access Protocol (SOAP) padro simples, que permite chamadas a servios apenas como se fossem objetos e bibliotecas locais. Trata-se de um protocolo de Webservices muito popular pois muito fcil integrar a nvel de cdigo, e porque a maioria das linguagem tm apoia a novela que trata as chamadas SOAP como se elas fossem chamadas locais normais da funo. um padro altamente estruturado, no entanto, usando o XML como um formato de mensagens que bastante detalhado. muitas vezes considerado muito pesado para muitas tarefas, Uma vez que a resposta real uma pequena poro da carga devolvida. Outro padro importante Representational State Transfer (REST), que um formato de Web Services muito mais enxuto. Na verdade, considerado mais na arquitetura de software, mas comumente utilizado no contexto de Servios Web quando usando os verbos HTTP de GET, POST e DELETE para interagir com outra aplicao. Trata-se de um padro frouxamente definido. No h uma exigncia explcita de utilizar qualquer tipo de mensagens formato ou estrutura dos dados que esto sendo transferidos. Os formatos so frequentemente determinados pelos requisitos da aplicao. Tais como HTML e JSON so muitas vezes utilizadas quando interagimos com outros aplicativos comuns de web que fcil de consumir, enquanto XML muitas vezes usado quando especificanda uma API externa. SugarCRM construdo com o pensamento "open", tanto em termos de permitir que outras aplicaes possam acessar dados do SugarCRM e permitindo tambm o SugarCRM consumir dados de outras aplicaes. Para fazer isto, SugarCRM possui uma API SOAP j h bastante tempo, e a SugarCRM 5.5 tem melhorado este componente constantemente, e tambm adicionou uma API REST para o mix. Alm disso, Sugar 5.2 adicionou um framework de conectores, que abre SugarCRM a uma infinidade de dados consumveis existentes na web. Vejamos como este quadro funciona e como voc pode adicionar novos servios da Web para serem consumidos pelo SugarCRM. CONNECTORS O framework conector projetado para fornecer uma camada abstrata em torno dele, essencialmente as suas databases, e sera considerado apenas outro conector parte de qualquer conector SOAP ou REST. Abstraindo-se a camada do conector que pode, ser trocada com perfeio. Estes conectores podem ento ser carregados por factory e retornar e chamar com base em seus mtodos e interfaces. Na Community Edition, o framework vai permitir a colocao de cones "hover" sobre campos em um registro no DetailView. Estes icones de "hover" podem ser links para Web Services externos ou widgets para obter informaes adicionais. Ele tambm inclui suporte LinkedIns Company Insider widget, lanado na community edition. Na Professional Edition e Enterprise Edition, o sistema ir conter tambm conectores adicionais (ambos contm Hoovers e Jigsaw) e tem a capacidade de mesclar os dados em registros existentes Os principais componentes para o framework so as factories, source, e formatter classes, As factories implementam o Factory pattern, retornando a instancia source ou formatter adequada do conector. As Sourcer so responsveis por encapsular a obteno dos dados como um registro nico, ou uma lista de registros, dos conectores. Os formatters so responsveis por renderizar os elementos de exibio dos conectores. Vamos ver como um conector construdo. CONSTRUINDO A FONTE DO CONECTOR As sources so o elemento central do framework dos conectores. O nome da classe da source deve ser prefixado com qualquer "ext_soap_" ou "ext_rest_" porque o caracter "_" serve como um delimitador para o sistema de arquivo encontrar a classe. Por exemplo, uma implementao do SOAP para uma Source, chamada "Test" ter o "ext_soap_test" de nome de classe e uma aplicao REST ser "ext_rest_test" de nome de classe. Existem duas categorias de fontes, uma para REST e uma para SOAP, para a classe do conector que deve ser extendida. A classe do conector possui dois mtodos que devem implementar: getItem() e getList( ). Os mtodos funcionam apenas como seria de esperar; getList() ir retornar uma lista de registros para os argumentos fornecidos passados para ela, enquanto getItem() retorna um nico registro que foi passado sobre os mesmos critrios de argumento. O que importante para seu conector ser capaz de possuir um identificador nico para cada registro fornecido pelo servio. Isso pode ser um id nico real como um GUID, um endereo de correio eletronico, ou gravar em formato especial. O que importante que cada registro pode ser inequivocamente identificado. Isto importante para o metodo getList() desde que o array retornado seja multidimensional, e esperado que cada chave do array de registro para que seja um identificador nico. tambm importante para o mtodo getItem(), uma vez que este mtodo muitas vezes ser chamado quando se quer um registro exato, e vai precisar referencia-lo por id. A listagem 4-1 mostra um exemplo de como a sua ficha poder olhar para o servio baseado em REST que retorna dados json. Listagem 4-1 Definio de fonte de dados do conector <?php require_once('include/connectors/sources/ext/rest/rest.php'); class ext_rest_sample extends ext_rest{ protected $service_url = 'http://example.com/rest/'; public function getItem($args=array(), $module=null){ $curl = curl_init($this->service_url.'item/'); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $args); $curl_response = curl_exec($curl); curl_close($curl); return json_decode($curl_response); } public function getList($args=array(), $module=null){ $curl = curl_init($this->service_url.'list/'); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $args); $curl_response = curl_exec($curl); curl_close($curl); $ids = json_decode($curl_response); $returnArray = array(); foreach ( $ids as $id ){ $returnArray[$id] = $this->getItem(array('id'=>$id)); } return $returnArray; } } Aqui voc pode usar a biblioteca curl do PHP para fazer as chamadas de REST. Existem dois servios REST: http://example.com/rest/list/ usado para obter uma lista de registros e http://example.com/rest/item/ usado para obter um determinado registro, ambos usando HTTP POST. Voc fazer as chamadas e, em seguida, traduzir os resultados para um array PHP usando a funo json_decode(). Para o mtodo de getList(), voc realmente aproveita o mtodo de getItem() para ajudar a preencher os valores na array de registro individual. Como mencionado anteriormente, estas funes esperam que os registros formatados de uma certa maneira. Para o mtodo getItem(), a array retornada pareceria o Listagem 4-2. Listagem 4-2 getItem() Array Array( ['id'] => 19303193202, ['recname'] => 'SugarCRM, Inc', ['addrcity'] => 'Cupertino', ) A array de getList() muito semelhante, apenas acrescentando uma outra dimenso para a array que atua como um continer para o array. Listagem 4-3 getList() Array <?php Array( [19303193202] => Array( ['id'] => 19303193202, ['recname'] => 'SugarCRM, Inc', ['addrcity'] => 'Cupertino', ), [39203032990] => Array( ['id'] => 39203032990, ['recname'] => 'Google', ['addrcity'] => 'Mountain View', ) ) Outra opo fornecer uma interface de teste para seu conector. Este um passo opcional onde voc pode desejar fornecer funcionalidade para seu conector de modo que ele pode ser testado atravs da interface de Administrao sob a seo "Set Connector Properties". valioso por s vezes um servio da Web caiu ou mudou seus parmetros, para que esse mtodo possa realizar um simples teste para certificar-se de que a conectividade pode ser realizada como servio da Web. Para permitir testes de seu conector, configure a varivel de classe $_has_testing_enabled para true no construtor e fornea uma implementao do mtodo Test (), como mostrado na Listagem 4-4. Listagem 4-4. Prev testar a funcionalidade da fonte do conector. <?php require_once('include/connectors/sources/ext/rest/rest.php'); class ext_rest_sample extends ext_rest{ protected $service_url = 'http://example.com/rest/'; protected $_has_testing_enabled = true; public function getItem($args=array(), $module=null){ $curl = curl_init($this->service_url.'item/'); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $args); $curl_response = curl_exec($curl); curl_close($curl); return json_decode($curl_response); } public function getList($args=array(), $module=null){ $curl = curl_init($this->service_url.'list/'); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $args); $curl_response = curl_exec($curl); curl_close($curl); $ids = json_decode($curl_response); $returnArray = array(); foreach ( $ids as $id ){ $returnArray[$id] = $this->getList(array('id'=>$id)); } return $returnArray; } public function test() { $item = $this->getItem(array('id'=>'1')); return !empty($item['firstname']) && ($item['firstname'] == 'John'); } } DEFININDO OS CAMPOS DO WEBSERVICES Como voc definiu um arquivo vardefs.php para a tabela de banco de dados no captulo 2, voc tambm ir definir um aqui para descrever os campos retornados do conector. Cada valor de chave na matriz dos mtodos getList() e getItem() deve ser mapeado para esta vardefs.php, e que est contido dentro da fonte. O formato semelhante ao anterior, como voc pode ver no Listagem 4-5. Listagem 4-5 vardefs.php para Connector <?php $dictionary['ext_rest_test'] = array( 'comment' => 'vardefs for test connector', 'fields' => array ( 'id' => array ( 'name' => 'id', 'vname' => 'LBL_ID', 'type' => 'id', 'hidden' => true 'comment' => 'Unique identifier' ), 'addrcity' => array ( 'name' => 'addrcity', 'input' => 'bal.location.city', 'vname' => 'LBL_CITY', 'type' => 'varchar', 'comment' => 'The city address for the company', 'options' => 'addrcity_list', 'search' => true, ), ) ); Uma diferena de vardefs.php que voc usou com tabelas de banco de dados a adio da chave 'input' para a entrada de addrcity. A chave 'input' permite alguma converso de mapeamento de argumento interno que a fonte usa. O ponto (.) usado como um separador para mapear o valor de entrada em uma matriz. No Listagem da entrada de addrcity, o bal.location.city de valor ser traduzido para o argumento de matriz ['bal'] [' location '] ['city']. A chave 'search' para a entrada de addrcity possa ser utilizada para o formulrio de pesquisa no conector com o Assistente de Mesclar dados, disponvel para as edies Professional e Enterprise. Voc tambm pode definir um arquivo de mappings.php, que ajuda com o processo de mapeamento dos campos como eles vm do conector para como eles existiram no banco de dados. Uma maneira como isso pode ser feito especificando o mapeamento dos valores de origem para um campo que voc ir us-los no banco de dados. Voc vai notar a chave 'options' para a entrada de addrcity. Este 'options' mapeia as chaves para uma entrada no arquivo mapping.php. O mappings.php tambm pode especificar mapeamentos de campo do mdulo especfico, no caso dos campos serem mapeados diferentemente com base no mdulo que voc est usando. Listagem 4-6 mostra um Listagem de arquivo de mappings.php. Listagem 4-6 Simple arquivo de mapeamento mappings.php <?php $mapping = array ( 'beans' => array ( 'Contacts' => array ( 'id' => 'id', 'addrcity' => 'primary_address_city', ), 'Accounts' => array ( 'id' => 'id', 'addrcity' => 'billing_address_city', ), ), 'options' => array ( 'addrcity_list' => array ( '001' => 'sjc', //San Jose '032' => 'sfo', //San Francisco ), ), ); Aqui voc alterar seu mapeamento de campo com base em qual mdulo usar o conector. No caso do mdulo de contactos, o campo 'addrcity' sera mapeado para o campo 'primary_address_city'. No entanto, este campo no existem no mdulo de contas, voc vai mapear para o campo 'billing_address_city' em vez disso. Alm disso, voc forneceu uma maneira de mapear valores de addrcity dado queles que voc usaria no interior de Sugar. FORMATTERS Os componentes opcionais do formatador so usados pela estrutura do conector para processar a janela de 'Cloud View' que pode exibir informaes e detalhes adicionais. Fora da caixa, eles so mostrados em telas DetailView para mdulos que so habilitados para o conector. Como a classe de origem, a classe de formatador tem uma classe de fbrica (FormatterFactory) correspondente. Os formatadores tambm seguem a mesma conveno de usar o prefixo "ext_rest_" ou "ext_soap_". No entanto, para distinguir os nomes de classe conflitantes, um sufixo "_formatter" tambm usado. Formatadores estendem-se do default_formatter. Por padro, o formatador ir procurar um default.tpl no diretrio tpls/ do conector, que processar no primeiro campo do DetailView. um modelo simples de Smarty que pode fornecer as informaes que o registro ligado para dentro do DetailView. (Como voc pode lembrar do captulo 3, estes so modelos que usa o SugarCRM para manusear a exibir a interface do usurio para o cliente). Listagem 4-7 mostra o formatador usado para o conector do LinkedIn. Listagem 4-7 LinkedIn Connector Formatter <div style="visibility:hidden;" id="linkedin_popup_div"></div> <script src="{{$config.properties.company_url}}" type="text/javascript"></script> <script type="text/javascript" src="{sugar_getjspathfile='include/connectors/formatters/default/company_detail.js'}"></script> <script type="text/javascript"> function show_ext_rest_linkedin(event) {literal} { var xCoordinate = event.clientX; var yCoordinate = event.clientY; var isIE = document.all?true:false; if(isIE) { xCoordinate = xCoordinate + document.body.scrollLeft; yCoordinate = yCoordinate + document.body.scrollTop; } {/literal} cd = new CompanyDetailsDialog("linkedin_popup_div", '<div id="linkedin_div"></div>', xCoordinate, yCoordinate); cd.setHeader("{$fields.{{$mapping_name}}.value}"); cd.display(); linked_in_popup = new LinkedIn.CompanyInsiderBox("linkedin_div", "{$fields.{{$mapping_name}}.value}"); {literal} } {/literal} </script> A classe default_formatter far a varredura no diretrio tpls para um arquivo de modelo do Smarty chamado aps o mdulo que est sendo visualizado. Por exemplo, o arquivo formatters/ext/rest/linkedin/tpls/Accounts.tpl ser usado para a exibio de pop-up de contas se o arquivo existe. Se o mdulo chamado no arquivo de modelo no for encontrado, ele tentar usar um arquivo chamado default.tpl. LOCALIZATION Os conectores oferecem suporte a localizao com o uso de arquivos de idioma, colocado em uma pasta chamada language sob a pasta de raiz do conector. O arquivo deve declarar uma matriz chamada $connector_strings de chave/valor. As entradas de vardefs.php usar a chave padro 'vname' para denotar a chave de rtulo no arquivo de linguagem. As etiquetas de configurao mostradas nas telas de administrao usam o valor da chave nos arquivos config.php para processar o rtulo. Listagem 4-8 fornece um exemplo de como este arquivo ficaria. Listagem 4-8 Localization File para o conector <?php $connector_strings = array ( //vardef labels 'LBL_ID' => 'ID', 'LBL_FIRST_NAME' => 'First Name', 'LBL_LAST_NAME' => 'Last Name', 'LBL_JOB_TITLE' => 'Job Title', 'LBL_IMAGE_URL' => 'Image URL', 'LBL_COMPANY_NAME' => 'Company Name', //Configuration labels 'url' => 'URL', 'api_key' => 'API Key', ); PUXANDO JUNTOS Fontes tambm precisaro fornecer um arquivo config XML que pode conter Propriedades de tempo de execuo opcional, como a URL do arquivo WSDL de SOAP e chaves da API. Essas propriedades de tempo de execuo devem ser colocadas sob a matriz 'properties'. No mnimo, uma chave de 'name' deve ser prevista a fonte (Ver Listagem 4-9). Listagem 4-9 Sample config.php <?php $config = array( 'name' => 'Test', //Name of the source 'properties' => array( 'TEST_ENDPOINT' => 'http://test-dev.com/axis2/services/AccessTest', 'TEST_WSDL' => 'http://hapi-dev.test.com/axis2/test.wsdl', 'TEST_API_KEY' => 'abc123', ) ); Neste ponto, a estrutura de diretrio para um conector REST chamado 'teste' deve parecer semelhante ao seguinte: custom/modules/Connectors/connectors/sources/ext/rest/test/test.php custom/modules/Connectors/connectors/sources/ext/rest/test/vardefs.php custom/modules/Connectors/connectors/sources/ext/rest/test/config.php custom/modules/Connectors/connectors/sources/ext/rest/test/mapping.php(optional) custom/modules/Connectors/connectors/sources/ext/rest/test/language/en_us.lang.php (default English language file for localization) custom/modules/Connectors/connectors/formatters/ext/rest/test/test.php custom/modules/Connectors/connectors/formatters/ext/rest/test/tpls/test.gif (optional) custom/modules/Connectors/connectors/formatters/ext/rest/test/tpls/default.tpl (optional) Voc trocaria 'SOAP' para o 'REST' nos caminhos anteriores se foram criando um conector baseados em SOAP. WEB SERVICES API A outra metade do suporte a Web Services no SugarCRM a API de servios Web, que fornece uma maneira para aplicativos externos interagir com sua instncia de Sugar. SugarCRM tem uma API SOAP, que abriu-se o acesso aos parmetros do SugarCRM de tal forma que qualquer aplicao ou linguagem de programao com uma biblioteca SOAP ou capacidades SOAP pode se conectar ao SUGAR. Voc ver em breve como Sugar 5.5 submeteu uma grande transformao, simplificando bastante a interface, que lhe permite ser facilmente personalizado e adicionando uma interface REST para complementar a existente interface SOAP. Um grande passo em frente na sua API de servios Web no Sugar 5.5 a adio de um framework de controle de verso e extensibilidade. Com isso, voc pode fazer alteraes para a API de Webservices que no ira quebrar qualquer aplicativos existentes, uma vez que seu aplicativo pode direcionar uma determinada verso da API cuja interface permanecer constante. Ele tambm torna mais fcil personalizar a API de servios Web com mtodos adicionais e alterar as definies de mtodo existente. Estas revises podem ser marcadas com uma determinada verso que permanecer constante, mesmo por meio de upgrades para o aplicativo. J que este um framework separado da API SOAP que existia nas verses anteriores do SugarCRM, 5.5 e vai continuar a apoiar a compatibilidade para a verso 1 da sua API de servios Web. Todas as classes usadas para implementar os servios da Web ao vivo em um diretrio de servio. O diretrio de servio contm as seguintes subpastas: core/: contm todas as classes de ncleo que so obtidos com a API de servios Web. REST/: contm todas as classes de REST usadas para retornar os dados em um formato especfico, como JSON, serialize data ou RSS. v2/: contm todas as classes especficas verso 2 para implementao SOAP e REST da API de servios Web. No diretrio v2/, voc ir definir o novo entrypoints para a API de servios Web. O entrypoints ser semelhante listagem de 4-10, que o cdigo usado para definir o ponto de entrada de v2 SOAP. Listagem 4-10 Web Service API Entrypoint para v2 SOAP Web Services <?php chdir('../..');// nome da classe de webservices $webservice_class = 'SugarSoapService2';// Localizao da classe acima $webservice_path = 'service/v2/SugarSoapService2.php';// nome da classe que responsvel pelo registro de todos os tipos de dados complexos e funes disponveis para chamar $registry_class = 'registry';// caminho para a classe acima $registry_path = 'service/v2/registry.php';// nome da classe de implementao para todas as funes $webservice_impl_class = 'SugarWebServiceImpl';// Localizao do entrypoint SOAP (deve ser o URI para este script) $location = '/service/v2/soap.php'; require_once('service/core/webservice.php'); Para acessar a nova verso dos servios da Web que voc vai usar a URL http://sugar_root_url/ service/v2/soap.php para se conectar. Agora vamos ver como voc pode conectar para a nova API de servios Web do Sugar usando SOAP e REST. SOAP O SOAP provavelmente o protocolo de servios da Web mais usado. Ele fornece uma forma de trocar informaes estruturadas como funcionalidade do aplicativo. Uma interface SOAP pode ser definida por seu arquivo descrio linguagem WSDL (Web Service), que simplesmente fornece as definies de todos os mtodos disponveis para o cliente. Uma das maiores atraes ao utilizar SOAP como um servio da Web sobre servios de peso mais leves, como REST, o que faz interagir com servios Web remotos to perfeitamente como fazer chamadas de funo local. Ele pode fazer isso porque SOAP suporta vrias linguagens permitindo o objeto imitar chamadas de mtodo, assim o uso de tipos de dados internos, com eles fazendo automaticamente as converses necessrias entre os dados fornecidos por um mtodo para aqueles usados na prpria classe. Vou me concentrar na mais recente verso da interface SOAP neste livro. SugarCRM vai continuar a apoiar a compatibilidade da interface SOAP anterior, que tem sido usada por muitas verses at agora. Eu recomendo atualizar para as bibliotecas mais recentes porque so muito mais eficientes do que as bibliotecas mais velhas (menos chamadas necessrias para atingir os mesmos resultados finais da nova biblioteca versus a velha), bem como facilitar a escrever mtodos SOAP personalizados. Vejamos algumas aes comuns e como faz-las com a interface SOAP. Voc vai usar a biblioteca nusoap SOAP do PHP para todos os Listagems a seguintes, mas eles devem traduzir facilmente para uma language/library de sua escolha. REALIZANDO A CONEXO Para comear, voc precisa se conectar ao servio. Iniciar este processo inicializao do objeto de SOAP com o URL da instncia do SOAP e, em seguida, usando o mtodo login para autenticar contra a instncia do Sugar. Listagem 4-11 fornece a implementao. Listagem 4-11 Conexo com a instncia do Sugar usando SOAP <?php $soapclient = new nusoapclient('http://sugar_root_url/service/v2/soap.php?wsdl', true);// Create the SOAP client instance $result = $soapclient- >call('login',array('user_auth'=>array('user_name'=>$user_name,'password'=>md5($user_password), 'version'=>'.01'), 'application_name'=>'SoapTest'));// Login to the server $session = $result['id'];// Get the user_id of the logged on user $user_id = $soapclient->call('get_user_id',array('session'=>$session)); Voc passar as credenciais que voc est usando para acessar a instncia usando o parmetro 'user_auth' o mtodo de logon. A chave da matriz 'user_name' especifica o nome de usurio e a chave 'password' especifica a senha, que voc precisar passar md5 codificado para maior segurana. Retornado da chamada de mtodo, entre outras coisas, o 'session_id', que retornado como o elemento-chave 'id' da matriz. Essa chave importante, pois voc precisar pass-lo como o primeiro argumento para todas as outras chamadas de funo do SOAP. Um problema de desempenho que voc viu ao lidar com o arquivo WSDL. Carreg-lo em cada chamada de cliente SOAP pode degradar o desempenho consideravelmente. Tenho visto at 40% de melhoria de desempenho ao simplesmente armazenar em cache o arquivo WSDL localmente, em vez de carreg-lo de controle remoto fonte de cada vez. NuSOAP fornecem uma classe para fazer tal coisa, chamada wsdlcache, que integra muito bem ao cliente NuSOAP (Ver listagem 4-12). Listagem 4-12 Armazenamento em cache o arquivo WSDL com NuSOAP <?php $cache = new wsdlcache("C:\temp", $cachelifetimeinseconds); $wsdl = $cache->get("http://localhost/soap.php?wsdl"); if (is_null($wsdl)) { // Retrieve the WSDL file and store it in the cach $wsdl = new wsdl("http://localhost/soap.php?wsdl"); $cache->put($wsdl); } else { $wsdl->debug_str = ''; $wsdl->debug('Retrieved from cache'); } // else // instantiate the soap client using the cached wsdl file $soapclient = new nusoapclient($wsdl, true); Voc pode ver na Listagem 4-12 como estabelecer um local de cache WSDL; verifique se o arquivo WDSL que voc precisa est no cach, se no for, voc pode usar o mtodo put() do objeto wsdlcache para armazenar o arquivo WSDL recuperado. Finalmente, voc pode especificar a instncia do objeto de wsdlcache em vez de uma URL como o primeiro parmetro para o Construtor nusoapclient para usar o arquivo WSDL em cache, em vez de recuper-lo da fonte remota de cada vez. Observe que usando arquivos WSDL no so obrigadas por este servio SOAP. Ele fornecido apenas como uma convenincia. Voc pode sempre escolher no puxar o arquivo WSDL, quando voc inicia a conexo de SOAP (em NuSOAP, voc iria passar false para o segundo argumento do Construtor nusoapclient). OBTENDO LISTAS E CONTANDO REGISTROS Agora que voc pode estabelecer uma conexo com o servidor SOAP, vamos tentar realmente consultar os dados l. Um bom lugar para comear , tentando obter uma contagem de registros disponveis para um mdulo. Listagem 4-13, voc vai fazer isso para o mdulo de contas, retornando o nmero de registros no- excludos de volta para voc. Listagem 4-13 Obter uma contagem de registros em um mdulo <?php // Create the SOAP client instance $soapclient = new nusoapclient('http://sugar_root_url/service/v2/soap.php?wsdl', true); // Login to the server $result = $soapclient->call( 'login',array( 'user_auth'=>array( 'user_name'=>$user_name, 'password'=>md5($user_password), 'version'=>'.01' ), 'application_name'=>'SoapTest' ) ); $session = $result['id']; // Get the count of records $result = $soapclient->call( 'get_entries_count', array( 'session'=>$session, 'module_name' => 'Accounts', 'query' => '', 'deleted' => 0 ) ); $count = $result['result_count']; Voc inicializar sua instncia SOAP e realizar o login e, em seguida, realiza a chamada SOAP 'get_entries_count'. Voc vai passar o 'id' de sesso como um parmetro, como o nome do mdulo que voc est consultando. O parmetro 'query' na chamada permite adicionar condies extras para os registros a serem contados. Por exemplo, voc pode configur-lo 'array('industry = 'Banking')' para retornar somente contas no sector bancrio. O parmetro excludo no final especifica que deseja apenas no-excludos registros contados. Extendendo este exemplo, vamos agora realmente obter os registros para um mdulo. A chamada SOAP que voc usar aqui 'get_entry_list', que retorna uma matriz de campos para o determinado parmetro especificado. Listagem 4-14 mostra um exemplo em ao para recuperar todos os contatos na instncia do Sugar. Listagem 4-14 Obter todos os contatos em um mdulo <?php // Create the SOAP client instance $soapclient = new nusoapclient('http://sugar_root_url/service/v2/soap.php?wsdl', true); // Login to the server $result = $soapclient->call( 'login', array( 'user_auth'=>array( 'user_name'=>$user_name, 'password'=>md5($user_password), 'version'=>'.01' ), 'application_name'=>'SoapTest' ) ); $session = $result['id']; // Get the list of records $result = $soapclient->call( 'get_entry_list', array( 'session'=>$session, 'module_name'=>'Contacts', 'query'=>'', 'order_by'=>'', 'offset'=>0, 'select_fields'=>array(), 'link_name_to_fields_array' => '', 'max_results'=>10, 'deleted'=>-1 ) ); $records_returned = $result['result_count']; $next_offset = $result['next_offset']; $field_list = $result['entry_list']; Os registros reais recuperados ser na matriz $field. O $records_returned e $next_offset so valores inteiro teis se voc deseja os resultados retornados em pginas no caso de voc espera o conjunto resultados grande (como o SugarCRM ListViews pode lidar apenas com 20 registros por vez). Para lidar com a paginao, voc pode especificar o parmetro de 'offset' para o mtodo de get_entry_list para o resultado dado por $next_offset, limitando o tamanho de pgina definido pelo parmetro 'max_results'. Voc saber quando voc j chegou ao fim quando a chamada de mtodo no retorna nenhum registro ou o $records_returned menor que o valor usado para 'max_results'. ADICIONAR UM NOVO REGISTRO Adicionando um registro um exerccio bastante simples. Chamar o mtodo set_entry usado aqui, onde voc ir especificar uma matriz de pares nome/valor que cada registro deve ser definido como. Listagem 4-15 tem o cdigo para este exemplo. Listagem 4-15 Adicionar um novo registro com set_entry <?php // Create the SOAP client instance $soapclient = new nusoapclient('http://sugar_root_url/service/v2/soap.php?wsdl', true); // Login to the server $result = $soapclient->call( 'login', array( 'user_auth'=>array( 'user_name'=>$user_name, 'password'=>md5($user_password), 'version'=>'.01' ), 'application_name'=>'SoapTest' ) ); $session = $result['id']; // Add the new record $result = $soapclient->call( 'set_entry', array( 'session'=>$session, 'module_name'=>'Contacts', 'name_value_list'=>array( array( 'name'=>'last_name', 'value'=>"Mertic" ), array( 'name'=>'first_name', 'value'=>'John' ) ) ) ); $id = $result['id']; O parmetro de 'name_value_list' que voc usa uma matriz com cada campo especificado. A chave 'name' o subarray o nome do campo que voc vai definir, enquanto o campo 'value' o valor. A id de registro resultante retornado de volta na chave 'id' da matriz $result, que voc rapidamente capturar e armazenar em uma varivel local. Voc pode usar o mesmo mtodo para atualizao de registros. Nesse caso, voc s precisa especificar o que o id do registro para atualizar. Supondo que o recorde anterior foi criado com xito na Listagem 4-15, voc vai estender esse exemplo para atualizar o registro de contato recm-criado com um ttulo na Listagem 4-16. Listagem 4-16 Adicionar um novo registro de contato e, em seguida, actualiz-lo <?php // Create the SOAP client instance $soapclient = new nusoapclient('http://sugar_root_url/service/v2/soap.php?wsdl', true); // Login to the server $result = $soapclient->call( 'login', array( 'user_auth'=>array( 'user_name'=>$user_name, 'password'=>md5($user_password), 'version'=>'.01' ), 'application_name'=>'SoapTest' ) ); $session = $result['id']; // Add the new record $result = $soapclient->call( 'set_entry', array( 'session'=>$session, 'module_name'=>'Contacts', 'name_value_list'=>array( array( 'name'=>'last_name', 'value'=>"Mertic" ), array( 'name'=>'first_name', 'value'=>'John' ) ) ) ); $id = $result['id']; // Now change a field in the newly created record $result = $soapclient->call( 'set_entry', array( 'session'=>$session, 'module_name'=>'Contacts', 'name_value_list'=>array( array( 'name'=>'id', 'value'=>$id ), array( 'name'=>'title', 'value'=>'Author' ) ) ) ); $id = $result['id']; Digamos que voc tem um monte de registros para atualizar ou criar em um tiro de um mdulo. Em vez de ter que fazer vrias chamadas de set_entry em uma linha, voc pode poupar o tempo de rede extra e use o mtodo set_entries (Observe que plural) para fazer vrias alteraes em um nico tiro. A maior diferena que agora o parmetro 'name_value_list' se torna 'name_value_lists' (novamente, plural). Listagem 4-17 tem todos os detalhes do cdigo.
Listagem 4-17 Criando vrios registros com set_entries <?php // Create the SOAP client instance $soapclient = new nusoapclient('http://sugar_root_url/service/v2/soap.php?wsdl', true); // Login to the server $result = $soapclient->call( 'login', array( 'user_auth'=>array( 'user_name'=>$user_name, 'password'=>md5($user_password), 'version'=>'.01' ), 'application_name'=>'SoapTest' ) ); $session = $result['id']; // Specify the list of records to add $name_value_lists[] = array( array('name'=>'last_name' , 'value'=>"Mertic"), array('name'=>'first_name' , 'value'=>'John') ); $name_value_lists[] = array( array('name'=>'last_name' , 'value'=>"Mertic"), array('name'=>'first_name' , 'value'=>'Dominic') ); $name_value_lists[] = array( array('name'=>'last_name' , 'value'=>"Mertic"), array('name'=>'first_name' , 'value'=>'Mallory') ); // Now add all the new records $result = $soapclient->call( 'set_entries', array( 'session'=>$session, 'module_name'=>'Contacts', 'name_value_lists'=>$name_value_lists ) ); $ids = $result['ids']; Voc especificar os registros para criar ou atualizar da mesma forma que antes, mas desta vez envolv- los em uma matriz a mais, usando essa matriz como o valor para o parmetro de 'name_value_lists' na chamada do mtodo SOAP. O resultado retornado similar como bem, desta vez retornando uma chave 'ids' com a lista de ids criado ou atualizado. SALVANDO E RECUPERANDO ANEXOS No deixe que a simples criao de registro par-lo em sua integrao SOAP. Voc tambm pode carregar e recuperar anexos, como os usados no mdulo de Notes. Faa isso como uma chamada secundria em vez de usar set_entry, como voc faria para registro de dados normal. Aqui voc pode usar o mtodo set_note_attachment para carregar o arquivo real para o registro de instncia do Sugar. Listagem 4-18 mostra a voc como fazer isso para o mdulo de notas. Listagem 4-18 Adicionar um novo registro de notas com um anexo <?php // Create the SOAP client instance $soapclient = new nusoapclient('http://sugar_root_url/service/v2/soap.php?wsdl', true); // Login to the server $result = $soapclient->call( 'login', array( 'user_auth'=>array( 'user_name'=>$user_name, 'password'=>md5($user_password), 'version'=>'.01' ), 'application_name'=>'SoapTest' ) ); $session = $result['id']; // Add the new note record $result = $soapclient->call( 'set_entry',array( 'session'=>$session, 'module_name'=>'Notes', 'name_value_list'=>array( array('name'=>'name', 'value'=>"My new note" ), array( 'name'=>'description', 'value'=>'This is a note with a file attached to it' ) ) ) ); $id = $result['id']; // Now attach the file to the newly created note $file = base64_encode(file_get_contents('attach.txt')); $result = $soapclient->call( 'set_note_attachment', array( 'session'=>$session, 'note'=>array( 'id'=>$id, 'filename'=>'attach.txt', 'file'=>$file ) ) ); $id = $result['id']; Voc cria o anexo de arquivo do arquivo local chamado 'Attach.txt'. Voc pegar o contedo dele e codific-lo para base64 para o transporte na chamada do mtodo SOAP, pass-lo sob o parmetro 'file'. Voc tambm precisar especificar o nome real do arquivo, como deve ser armazenado no servidor no atributo 'filename'. O que entra deve sair tambm, portanto, chamar o mtodo get_note_attachment fornece essa funcionalidade. Aqui voc vai assumir a existncia do registro no mdulo de notas, e voc vai assumir que voc j sabe a identificao do que registro (que fornecida na varivel $id). Listagem 4-19 mostra os detalhes sobre as partes mais interessantes do processo de recuperao de arquivo. Listagem 4-19 Pegue um determinado anexo no registro de notas <?php // Create the SOAP client instance $soapclient = new nusoapclient('http://sugar_root_url/service/v2/soap.php?wsdl', true); // Login to the server $result = $soapclient->call( 'login', array( 'user_auth'=>array( 'user_name'=>$user_name, 'password'=>md5($user_password), 'version'=>'.01' ), 'application_name'=>'SoapTest' ) ); $session = $result['id']; // Grab the given record's attachment $result = $soapclient->call( 'get_note_attachment', array( 'session'=>$session, 'id'=>$note_id ) ); $file_contents = base64_decode($result['note_attachment']['file']); $filename = $result['note_attachment']['filename']; // Now store the contents in a local file file_put_contents($filename,$file_contents); O mtodo get_note_attachment muito simples, retornando de volta uma matriz com todos os detalhes do arquivo. Tudo o que voc est procurando sob a chave de 'note_attachment', com chaves de dois subarray, 'file' e 'filename', dando-lhe o arquivo real de contedo (isso base64 codificado, ento voc precisa decodificar para seu uso), bem como o nome do arquivo como ele existentes na instncia do Sugar. Voc toma estes dois elementos e us-los com o mtodo file_put_contents() para salvar o arquivo em seu sistema de arquivos local ao mesmo tempo, tambm usando o mesmo nome, como era no servidor. REGISTROS RELACIONADOS Uma parte agradvel sobre SugarCRM a capacidade de ter registros de mdulos diferentes relacionados entre si. Da mesma forma, a interface SOAP fornece o mesmo tipo de capacidade por meio da chamada de mtodo set_relationship. Listagem 4-20 mostra a voc como fazer isso comparando um contato com um registro de conta. Listagem 4-20 Relacionando contato com uma conta usando SOAP <?php // Create the SOAP client instance $soapclient = new nusoapclient('http://sugar_root_url/service/v2/soap.php?wsdl', true); // Login to the server $result = $soapclient->call( 'login', array( 'user_auth'=>array( 'user_name'=>$user_name, 'password'=>md5($user_password), 'version'=>'.01' ), 'application_name'=>'SoapTest' ) ); $session = $result['id']; // Add the new Contact record $result = $soapclient->call( 'set_entry', array( 'session'=>$session, 'module_name'=>'Contacts', 'name_value_list'=>array( array( 'name'=>'last_name', 'value'=>"Mertic" ), array( 'name'=>'first_name' , 'value'=>'John' ) ) ) ); $contact_id = $result['id']; // Add the new Account record $result = $soapclient->call( 'set_entry', array( 'session'=>$session, 'module_name'=>'Accounts', 'name_value_list'=>array( array( 'name'=>'name', 'value'=>"John's House of Cards" ) ) ) ); $account_id = $result['id']; // Now relate the contact to the account $result = $soapclient->call( 'set_relationship', array( 'session'=>$session, 'module_name' => 'Accounts', 'module_id' => $account_id, 'link_field_name' => 'contacts', 'related_ids' => array($contact_id) ) ); Depois de criar os dois novos registros, voc relacion-los usando o mtodo de set_relationship. Primeiro voc especificar o nome do mdulo pai e a identificao de parmetros 'module_name' e 'module_id'. Em seguida, deve indicar qual campo do link que voc est usando para se relacionar com o mdulo de destino. No caso do mdulo de contas, o nome de campo de link para a relao do mdulo de contato 'contatos' (veja captulo 2 para obter informaes sobre este tipo de campo). Finalmente, voc pode especificar uma lista de matriz de ids de contatos que deve ser marcado como sendo relacionado para o account_id determinada no parmetro related_ids. REST Uma nova adio para a estrutura de servios da Web do Sugar na verso 5.5 uma interface REST. Esta tem sido uma das adies mais solicitadas para o servio, como ela adiciona uma maneira muito mais leve para os desenvolvedores obterem acesso a dados em um sistema em comparao com a interface SOAP usado em verses anteriores do SugarCRM. REST considerado a implementao de servios Web prefervel para implementaes de servios da Web transacionais superiores (aqueles onde muitas chamadas so feitas para o servio da Web ao mesmo tempo), mas tambm quando usado com implementaes de cliente de navegador onde toda renderizao acontece no navegador. Implementao REST no SugarCRM torna isso ainda mais fcil, usando o formato JSON nativo do Javascript, como o padro para dados em todas as chamadas de servios Web com a interface do REST, e tambm usar dados serializados como um tipo alternativo tambm. Voc mesmo pode definir seu prprio tipo de dados para entrada e sada de dados na interface REST simplesmente estendendo a classe de SugarRest dentro do diretrio service/core/REST/. Dois mtodos devem ser aplicados: serve() decodifica os dados da chamada de mtodo REST como dado, enquanto o generateResponse() usado para codificar os dados de retorno para retorn-lo ao cliente. Voc pode misturar e combinar a entrada e sada dos tipos no REST mesmo especificando o 'input_type' e 'response_type', ento voc poderia ter dados JSON introduzidos, mas serializavam dados retornados. Os exemplos que voc vai usar nesta seo ilustrar usando a interface de resto de Javascript, usando o objeto de conexo da biblioteca de Interface do Yahoo. FAA O LOGIN USANDO REST Registrar-se na instncia de Sugar atravs de REST, usa o mesmo mtodo como voc fez antes, quando se lida com a interface SOAP, mas desta vez naturalmente voc precisar lidar com os dados um pouco diferente devido usar interfacs diferentes. Listagem 4-21 mostra-lhe como fazer isso. var loginData = [{ user_name: 'user', password: 'password' },'javascriptTest']; data = YAHOO.lang.JSON.stringify(loginData); YAHOO.util.Connect.asyncRequest('POST', 'v2/rest.php' , {success:success},'method=login&input_type=json&response_type=json&rest_data='+data); function success(o) { var data = YAHOO.lang.JSON.parse(o.responseText); var session = data['id']; alert(session); } Voc usou o mtodo asyncRequest() do objeto YUI Connect para fazer a chamada REST. O argumento rest_data para o servio de REST onde voc passar os dados. Voc pode usar as ferramentas de YUI JSON para preparar corretamente estes dados para a utilizao. Caso contrrio, todos os exemplos anteriores da interface SOAP tambm se aplicam interface do resto tambm. WEBSERVICES PERSONALIZADOS Antes do lanamento de 5.5 s foi possvel adicionar nova funcionalidade de servios Web modificando arquivos do ncleo. Cada atualizao subseqente ento exigiria que usurio do Sugar verifica-se os arquivos para certificar-se de que o mais nova patch/upgrade a ser aplicada no os arquivos em conflito. Na verso 2.0 da interface de Web Services, introduzido com o SugarCRM 5.5, voc agora tem uma estrutura extensvel que permite ao desenvolvedor adicionar e distribuir a nova funcionalidade de servios da Web sem a necessidade de se preocupar com a fuso de cdigo com cada patch/upgrade. Para isso, so necessrios os seguintes itens: criar um registro personalizado, fornecer uma classe de implementao e, em seguida, adicionar o arquivo de interface SOAP ou REST. Voc vai cri-los em um novo diretrio custom/services/ que voc vai chamar v2_1 para ajudar a ilustrar como uma extenso da biblioteca existente. CRIANDO UM REGISTRO CUSTOMIZADO Primeiro, voc precisar fornecer seu prprio arquivo de registry.php no novo diretrio criado anteriormente. Voc vai cham-lo customregistry.php e defini-lo como uma classe da classe do registro como mostrado na Listagem 4-22. Listagem 4-22. customregisty.php <?php require_once('service/v2/registry.php'); class customregistry extends registry{ public function __construct($serviceClass){ parent::__construct($serviceClass); } protected function registerFunction(){ parent::registerFunction(); $this->serviceClass->registerFunction('get_entry', array('session' => 'xsd:string', 'module_name' => 'xsd:string', 'id' => 'xsd:string', ), array('return' => 'xsd:string',) ); } } A principal mudana aqui dentro do mtodo de registerFunction(), onde voc pode adicionar o mtodo 'get_entry' para a lista disponvel de funes que podem ser usadas com este webservice. Na definio, voc pode especificar os parmetros de entrada, bem como o tipo de retorno para a funo. Voc tambm chamar a definio do mtodo pai tambm, para que voc possa incluir todas as funes padro principal interface SOAP. FORNECENDO UMA CLASSE DE IMPLEMENTAO Em seguida, voc vai estender a classe SugarWebServiceImpl para adicionar o novo mtodo que voc est expondo o cliente. Listagem 4-23, mostra este exemplo. Listagem 4-23 SugarWebServiceImpl_v2_1.php <?php require_once('service/core/SugarWebServiceImpl.php'); class SugarWebServiceImpl_v2_1 extends SugarWebServiceImpl{ public function get_entry($session, $module_name, $id){ return $id; } } Como voc pode ver, o mtodo de get_entry realmente simple. Ele s retorna o id passado. ADICIONE OS ARQUIVOS SOAP.PHP E REST.PHP Agora voc s precisa fornecer o arquivo de interface para chamadas SOAP e REST. Voc pode v-los em listas de 4-24 e 25. Listagem 4-24. Example soap.php para acessar custom/service/v2_1/soap.php <?php Chdir('../..'); $webservice_class = 'SugarSoapService2'; $webservice_path = 'service/v2/SugarSoapService2.php'; $registry_class = 'customregistry'; $registry_path = 'custom/service/v2_1/customregistry.php'; $webservice_impl_class = 'SugarWebServiceImpl_v2_1'; $location = '/custom/service/v2_1/soap.php'; require_once('service/core/webservice.php'); Listagem 4-25. Exemplo rest.php para ser acessar http://sugar root url/service/v2_1/rest.php <?php Chdir('../..'); $webservice_class = 'SugarRestService'; $webservice_path = 'service/v2/SugarRestService.php'; $registry_class = 'customregistry'; $registry_path = 'custom/service/v2_1/customregistry.php'; $webservice_impl_class = 'SugarRestServiceImpl_v2_1'; $location = '/custom/service/v2_1/rest.php'; require_once('service/core/webservice.php'); Voc alterar as definies de antigas usadas para apontar para os locais corretos dos novos arquivos que voc criou dentro do diretrio service/v2_1/. RESUMO Neste captulo, voc aprendeu sobre as vrias integraes de servio Web, o SugarCRM fornece a plataforma. Voc olhou primeiro para conectores, um recurso adicionado no Sugar 5.2 com interface direta a Webservices remotos de sua instncia de Sugar. Em seguida, olhou para a interface de Web Services, que permite que outros aplicativos facilmente interface em com o SugarCRM. Voc viu como e fcil utilizar as interfaces para inbound e outbound de dados e como voc pode facilmente personaliz-los se desejar. No prximo captulo, voc vai terminar sua escavao nas entranhas do SugarCRM, dando uma olhada em alguns do valores adicionando caractersticas e ferramentas como autenticao de usurio, Dashlets e temas. MAIS RECURSOS DE PLATAFORMA Nos captulos anteriores, voc olhou para os grandes recursos da plataforma de Sugar. Captulo 2 enfoca a MVC framework, tais como as solicitaes so tratadas, como voc pode controlar a sada para o usurio e como interagir com a camada de banco de dados. Captulo 3 mostramos a estrutura de metadados, que fornece uma maneira de construir os pontos de vista comuns do aplicativo (ou seja, o DetailView EditView e ListView) com facilidade e consistncia. Em seguida, no captulo 4, voc olhou como voc pode usar servios da Web por consumi-las dentro de sua instncia de Sugar, bem como a forma como voc pode expor servios da Web da sua instncia de Sugar para serem consumidos por outros aplicativos. Este captulo ir focar as caractersticas "menos importantes" da plataforma SugarCRM. Pense neste captulo como o captulo de diversos do livro, onde voc vai olhar para vrias caractersticas aleatrias que so dignos de nota suficiente para ser mencionado no livro, mas no necessariamente se encaixam em nenhum dos captulos anteriores. Coisas que vou me concentrar incluem: usurio e gerenciamento de equipe, que essencial para qualquer aplicativo multi-usurio. Voc tambm vai olhar para Dashlets, que fornece uma maneira para exibir dados de vrias fontes em uma pgina. Ento, eu vou tocar no Sugar feeds, registro, importao e exportao, temas e o agente de log de Sugar. Vamos comear olhando para gerenciamento de usurios no SugarCRM. GERENCIAMENTO DE USURIO Um recurso central de qualquer aplicativo multi-usurio gerenciamento de usurio. Muitas vezes uma das primeiras preocupaes ao criar um novo aplicativo, desde que ter isso permite que a segurana do aplicativo e tambm permite a auditoria de aes do usurio. SugarCRM faz isso para voc, fornecendo um esquema de autenticao de padro muito seguro, bem mais avanados que autenticao LDAP. Autenticao LDAP permite que voc ligar o Sugar para servidores existente LDAP directory de sua empresa (como o Active Directory) para fornecer autenticao. Por padro, o Sugar usa sua autenticao interna e armazena as informaes de usurios dentro do prprio banco de dados. Os usurios podem ter muitas propriedades e preferncias que lhes esto associadas, como seria de esperar. No painel de Admin, a opo de gerenciamento de usurio permite que a voc criar, editar, ativar e desativar usurios em Sugar. Voc pode criar um usurio Sugar, administrador do sistema, usurio de grupo ou Portal de usurio apenas. Tabela 5-1 descreve os tipos de usurio diferente. Usuario Descrio Sugar User Pode acessar e usar os mdulos de Sugar mas no tem privilgios administrativos. System Administrator Usurio que tem privilgios administrativos em Sugar para executar tarefas como criao de usurios. O administrador do sistema tem os direitos de acesso a todos os mdulos e registos. Group User Um balde que usado para e-mails de entrada e no contam para o nmero de licenas de Sugar que voc compra para sua organizao. Por exemplo, quando voc cria uma conta de correio do grupo de apoio, a usuria grupo de apoio criada para lidar com questes de suporte ao cliente. Usurios podem ento distribuir os e-mails para outros usurios da caixa de entrada do grupo. Portal Only Usurio usado por portais criados em Sugar para acessar o sistema. Usurios do Portal no contam para o nmero de licenas de Sugar que voc compra para sua organizao. TABELA 6 - TIPOS DE USUARIOS DO SUGARCRM Quando voc criar um usurio, por padro o sistema cria um usurio de Sugar a menos que voc especifique o Portal somente usurio, usurio de grupo ou administrador. H muitas coisas que voc pode definir em uma conta de usurio, incluindo preferncias sobre como as coisas funcionam e olhar enquanto eles usam o aplicativo. Preferncias de usurio so armazenadas separadamente do usurio como serializar e dados codificado na base64. No entanto, ele pode ser facilmente recuperado e atualizados usando os mtodos getPreference() e setPreference() do objeto de Bean do usurio. Desde que o objeto de usurio do usurio conectado no momento est sempre disponvel atravs do $current_user global, voc pode obter qualquer preferncia de usurio que voc precisa facilmente. Na listagem 5-1, veja como Pesquisar a preferncia para mostrar o cone do mdulo como favicon do navegador e agir em conformidade. Listagem 5-1 Manipular o module_favicon de preferncia do usurio. <?php $user_module_favicon = $GLOBALS['current_user']->getPreference('module_favicon'); if(!isset($user_module_favicon)){ if isset($GLOBALS['sugar_config']['default_module_favicon'])){ $user_module_favicon = $GLOBALS['sugar_config']['default_module_favicon']; }else{ $user_module_favicon = false; } } Aqui voc verificar a preferncia do usurio atual para exibir o cone do mdulo como o favicon em vez de usar o favicon de aplicao normal. Se voc no encontrar a preferncia, voc cair para trs para olhar para a configurao padro na $sugar_config e se ainda no encontrou voc simplesmente assume a configurao para false. Depois de ter os usurios, voc precisa controlar o seu acesso ao sistema. SugarCRM fornece um sistema ACL para fazer isso. ACL Com um sistema multiusurio, existe geralmente muitos tipos diferentes de usurios. Alguns usurios podem ser de entrada de dados, pessoas, outros poucos precisam no precisam de um monte de opes que nunca vai usar. Pessoal de Vendas muitas vezes tm mais restries, para mant-los afastados de informaes contbeis que no pertencem a eles. Muito poucos usurios precisam acesso completo ao sistema (e nem teriam muitos administradores de sistemas os quer). As ACLs so usadas para restringir o acesso a mdulos do Sugar e os dados e aes disponveis (por exemplo, "Excluir" e "Salvar") aos usurios em mdulos de Sugar. ACLs so definidas na rea de funes do painel de administrao do Sugar e podem ser aplicadas a qualquer mdulo do sistema e suas aes. Sugar Professional e Enterprise Editions levam este passo mais longe, permitindo que os administradores restringam o usurio acessar at campos especficos, como fazer certos administradores de usurios de determinados mdulos do sistema, sem ter que dar-lhes o nvel de acesso de administrador completo para todos os mdulos. Fazer ACL no SugarCRM, criar funes de usurio. Uma funo define um conjunto de permisses para executar aes, como a visualizao, edio e excluso de informaes. Ento voc assumi estes papis e os aplica aos usurios, que afetaro os mdulos, aes e campos que podem ver ou interagir. Os usurios podem ter zero ou mais funes aplicadas a eles, que se aplicaro as regras de papel na ordem em que eles so definidos. Se um usurio no for atribudo um papel, eles podem, por padro, acesso a qualquer ao em qualquer mdulo. Funes tambm podem ser atribudas a mais de uma pessoa, o que til para gerenciar o grupo e as permisses de acesso de nvel de funcionrios. Por exemplo, se voc quiser impedir que um grupo de usurios na sua organizao possa acessar o mdulo de oportunidades, voc pode criar uma funo que restringe o acesso a este mdulo. Quando voc atribuir esta funo a um engenheiro, o indivduo j no ser capaz de acessar o mdulo de oportunidades. Ou, voc pode querer atribuir representantes de vendas Jnior para um papel que lhes permite ver e editar contatos, contas e oportunidades, mas os impede de apagar estes registros. O nico isento de funes de usurio o administrador do sistema, que tem sempre o direito de acessar todos os mdulos e registos. Quando voc cria uma funo, voc especifica se o acesso permitido ou no, os mdulos e o papel que pode acessar, o acesso digite tal como Normal (para usurios regulares do Sugar) ou administrador e as aes que podem ser executadas. Criao de funes para um mdulo envolve as seguintes etapas: 1. Identificar os mdulos que voc deseja controlar o acesso. melhor manter regras ACL especficos nos quais so seus objetivos, assim voc pode combin-las com outras funes para atingir o nvel desejado de controle de acesso para o usurio. 2. Definir o nvel de acesso para o mdulo a uma das seguintes opes: 3. Enabled: isso permite que o usurio veja o mdulo. 4. Disabled: Isso esconde o mdulo do usurio e os impede de acess-lo. 5. Not Set: Isso no muda a configurao existente para o nvel de acesso. 6. Defina o tipo de acesso para o mdulo. As opes aqui so mostradas na lista a seguir: 7. Normal: oferece ao usurio direitos normais para o mdulo. 8. Admin: D o privilgio de nvel de administrador do usurio para o mdulo, tais como alterar as configuraes no painel de administrao e ser capaz de Visualizar, editar e excluir qualquer registro no mdulo. 9. Developer: Permite ao usurio fazer alteraes no mdulo atravs de estdio, Gerenciador de fluxo de trabalho e Editor do menu suspenso. 10. Admin e Developer: combina os privilgios de dois anteriores. 11. Not Set: No altera a configurao existente para o tipo de acesso. 12. Definir os direitos para as permisses de Delete, Edit, export, import, List e View para uma das seguintes configuraes: 13. Todos: Pode executar determinada ao. 14. Proprietrio: Somente o proprietrio do registro pode executar determinada ao. 15. None: No possvel executar a ao determinada. 16. Not Set: No altera a configurao existente para a determinada ao. 17. Para edies Professional e Enterprise, voc pode definir a permisso para cada campo no mdulo, assim como para um dos seguintes: leitura/gravao, proprietrio de leitura/gravao, somente leitura, proprietrio proprietrio de leitura/gravao, nenhum ou no definido. Quando um usurio atribudo a vrias funes, as definies de funes so mescladas e prevalecem as definies mais restritivas. Por exemplo, se um usurio atribudo a dois papis pertencente a um mdulo onde uma funo concede acesso de administrador e os outros subsdios acesso do usurio, o usurio tem apenas acesso de usurio final. Neste caso, o acesso do usurio final substitui o papel com o acesso administrativo porque mais restritivo. Um caso especial o valor de "Not Set" em uma definio de funo. Voc pode usar o "Not Set" para garantir que um papel no afeta uma determinada configurao. Isso permite que funes simples possam ser construdas e ento combinadas para atingir o nvel de segurana desejado. Por exemplo, se os usurios so atribudos a ambas as seguintes funes: Role A, onde o Access Type = Admin and Export (ao) = None Role B, onde o Access Type = Normal and Export (ao) = All Ento, usurios podem ver apenas os registros que so atribudos a eles, mas no possvel exportar os dados. Se voc alterar o tipo de acesso no definindo: Role A, onde o Access Type = Admin and Export (ao) = All Role B, onde o Access Type = Not Set and Export (ao) = None Em seguida, o usurio pode ver todos os registros no mdulo, mas no possvel exportar os dados. GERENCIAMENTO DE SENHAS O recurso de gerenciamento de senhas, que tem sido adicionado a partir do Sugar 5.5, permite que os administradores de sistema criem e gerenciem regras de senha para os usurios e senhas geradas pelo sistema. Primeiro, ele entra em jogo quando um usurio criado. Aqui senhas geradas pelo sistema so enviadas automaticamente para novos usurios, quando os administradores do sistema criam novos registros de usurio. Os administradores de sistema tambm podem enviar novas senhas para usurios a qualquer momento, dando-lhes a capacidade de redefinir a senha em caso de problemas de segurana com a aplicao. Voc tambm pode fornecer uma data de validade para qualquer senha que gerada automaticamente, forar o usurio a redefinir sua senha, logo depois emitido uma nova senha. Para ajudar com segurana de senha, voc pode definir requisitos sobre que tipo de senha pode ser usado. Voc pode definir opes para o comprimento mximo e mnimo, bem como o contedo da senha propriamente dito, como exigir que os caracteres em maisculas ou minsculas, nmeros e smbolos. Se os requisitos do padro no so suficientes, uma regex pode ser utilizada para aplicar as regras de que no permitido em uma senha. Sempre que uma senha criada, as regras para criar o nome de usurio devem ser seguidas. Se no, ento o usurio ser notificado e a senha fornecida no ser aceito. Um problema comum para os administradores quando os usurios esquecerem suas senhas.O SugarCRM resolve este problema fornecendo os usurios um link esqueceu a senha na pgina de Login, ento quando o usurio d o seu nome de usurio e endereo de e-mail (e desde que ambos correspondem a um usurio ativo no sistema) ele ir enviar um link gerado pelo sistema para a pgina onde ele pode redefinir sua senha. Voc tambm pode exigir um Captcha no formulrio evitar que ferramentas automatizadas solicitando essas novas solicitaes de senha. Os links gerados pelo sistema para redefinir senhas pode ser definidos com uma data de validade, bem como, para que eles devam ser respondidos em um curto espao de tempo, a partir do momento em que eles so enviados. Voc tambm pode personalizar os modelos de e-mail usados para enviar senhas de usurios gerados pelo sistema e links para redefinir senhas para fornecer informaes adicionais ao usurio podem precisar. Para proteger ainda mais seu sistema de aqueles que tentam acess-lo sem credenciais adequadas, voc tambm pode ativar o recurso de bloqueio de Login para usurios de bloqueio do sistema aps um determinado nmero de tentativas de login falhas. All-in-All, SugarCRM agora tem um esquema de gerenciamento de senha muito robusto, que tanto ajuda a aliviar a carga sobre os administradores no gerenciamento de senha do usurio, mas tambm ajuda os usurios a resolver o problema de comum "Esqueci minha senha". Ele tambm adiciona outro nvel de segurana para senhas de usurio, para ajudar a evitar contas facilmente sendo rachadas em aplicando regras de falha de login e senha configurvel. ACOMPANHAMENTO DE AES DO USURIO Outra caracterstica importante de qualquer sistema multiusurio o acompanhamento de aes do usurio. Isso traz benefcios tanto para usurios e administradores. Enquanto os administradores tm a capacidade de rastrear usurios e padres de acesso ao sistema, os usurios tambm ganham a habilidade de facilmente obter registros recentes, sem ter que procur-las explicitamente. O SugarCRM faz isso automaticamente e de forma transparente, dando aos administradores e desenvolvedores um complemento muito til na gesto de sua aplicao. Originalmente, o SugarCRM iria controlar aes do usurio de edio e/ou exibir registros de dados. Essa funcionalidade deu aos usurios uma lista dos ltimos registros visualizados na sua tela, que formo os links para acessar os registros. Com SugarCRM 5.1, isso foi bastante reforado para controlar tambm mtricas de desempenho, mtricas de consulta e informao de sesso. Este tipo de informao muito til para administradores de sistema, ento eles podem ajustar seus sistemas para um melhor desempenho baseado em suas necessidades individuais. Tambm til para os gestores, para que podem ver quanto seus funcionrios esto usando o sistema e para qu. Os relatrios Tracker dashlet fornece uma maneira rpida e fcil de acessar a esta informao (vamos falar sobre Dashlets no final deste captulo). Mostrado na Figura 5-1, tem uma interface simples para encontrar os tipos comuns de solicitaes de dados do controlador.
FIGURA 10 - TRACKER REPORTS DASHLET H vrios relatrios disponveis presente no dashlet: ltimos dez registros modificados Usurios ativos Contagem de usurios ativos Usurio Top Meu uso semanal Minha utilizao dos modulos Meus Tops trs mdulos mais usados Tempo de Login cumulativo (esta semana) Tempo cumulativo de Login dos usurios (esta semana) O backend do Tracker tambm configurvel. Painel de administrao de configuraes do Tracker permite desabilitar a captura de certas aes como: visualizaes de pgina, informaes de sesso, mtricas de desempenho e consulta log de rastreamento. Voc tambm pode ajustar o limite de tempo de consulta lenta e a quantidade de dados do controlador de tempo armazenada. O principal motivo para isso seria por motivos de desempenho, uma vez que a lousa cheia de mtricas de controle de funcionamento pode ser bastante desgastante o sistema. Uma vez que muitos administradores no podem ser interessados em certos aspectos do presente em todos os momentos, desativando os itens no utilizados podem resultar em um aumento de desempenho perceptvel. TEAM MANAGEMENT A Professional e a Enterprise Editions do SugarCRM adicionam a capacidade de gerir os usurios em grupos de equipes. Isso pode ser muito til para as organizaes maiores, onde existem diferentes grupos de usurios que compartilham as mesmas responsabilidades a trabalharem em conjunto em projetos. Equipes no SugarCRM podem ter um ou mais usurios, e cada usurio pode ter uma ou mais equipes. Alm disso, a partir de SugarCRM 5.5, um registro pode pertencer a uma ou mais equipes, permitindo que as organizaes gerenciem suas informaes de forma muito eficaz. Dependendo das necessidades da sua organizao, voc pode projetar suas equipes de vrias maneiras. Por exemplo, com base na hierarquia de relatrios, voc pode querer criar uma equipe de usurios que se reportam ao mesmo gerente. Com base nos requisitos de gerenciamento de produto, voc pode querer criar uma equipe multidisciplinar de usurios que se reporta a gerentes diferentes, mas que controlam o mesmo produto. Por padro, todos os registros do Sugar como contas, contratos e oportunidades so atribudos a uma equipe especfica e s podem ser acessados pelos membros da equipe. Como mencionado, um usurio pode pertencer a uma ou mais equipes. Quando voc criar um usurio, o sistema automaticamente cria uma equipa privada da pessoa. Qualquer registro que o usurio cria como um contrato ou um oramento atribudo equipe privada do usurio por padro. Somente o usurio pode acessar e gerenciar registros atribudos a esta equipe. Mas o usurio pode atribuir uma equipe diferente para gerenciar o registro. Gerentes podem exibir qualquer registro que podem exibir seus subordinados, mesmo se o registro no atribudo mesma equipe o gerente uma parte de. Os usurios podem ser explicitamente e implicitamente atribudos s equipes e aparecer como membro ou membro a que se reporta. Quando um usurio atribudo manualmente, ou explicitamente, a uma equipe, o usurio ir aparecer como um membro na coluna de associao. Por exemplo, Will e Chris se reportam a Jim. Will um membro da equipe do leste; Chris um membro da equipe do oeste. Como resultado, Jim ser um membro implcito de equipes do leste e do oeste. Quando um usurio atribudo manualmente para uma equipe,o gerente a quem se reporta hierarquicamente tambm e adicionado automaticamente. Isso garante que os membros da hierarquia de gerenciamento do usurio tambm tenham visibilidade sobre os registros do usurio em questo. Membros implcitos aparecem como se reporta a: membro na coluna de associao. No entanto, quando um usurio implicitamente se torna parte de uma equipe, no pode ser removido manualmente da equipe. Em vez disso, voc deve remov-los da equipe herdada. No exemplo anterior, para excluir o Jim da equipe do oeste quer Chris devem ser removidas da equipe do oeste, ou Chris no deve reporta-se a Jim. Voc apenas no pode remover Jim da equipe do oeste. Em relao aos Times, o novo recurso adicionado no SugarCRM 5.5 a capacidade de ter vrias equipes para um registro. Isso til em grandes organizaes, onde um registro pode ter diferentes partes do mesmo que precisam ser usados por diferentes reas da empresa. Por exemplo, um registro de conta talvez precise ser compartilhado pelo departamento de contabilidade, equipe de vendas e o departamento que faz o trabalho de servio para a conta. Por ter vrias equipes para um registro, todos os trs equipes podem compartilhar este registro entre eles. Uma correo adicional para o recurso de vrios Times em Sugar 5.5 a capacidade de exibir registros voc est atribudo, mesmo se voc fosse um membro da equipe no tem acesso ao registro. Funcionalidade da equipe no SugarCRM flexvel o suficiente para lidar com quaisquer necessidades de organizaes. Tambm muito fcil de usar, ainda mais rpido e mais poderoso. DASHLETS Comunicao uma parte importante de qualquer aplicativo que se mantm em cima dos seus dados. No entanto, muitas necessidades de relatrios so bastante simples. Quais so meus top dez contas? Qual chamada precisa ser feita hoje? Mostre-me um grfico de todos os tipos de oportunidades que eu tenho. Em uma vida anterior como desenvolvedor de aplicativos internos para uma pequena empresa, muitos destes relatrios foram construdos mo, sob demanda, em iriam continuar por pginas e pginas. No final, pessoas olhava em primeira pgina e, em seguida, seguem em frente. Isto no era apenas uma inconvenincia para o desenvolvedor do aplicativo pobre, mas tambm o usurio final que tem que olhar atravs de tantas pginas para obter as informaes necessrias. Para resolver este problema, a home page do SugarCRM foi projetada para ser um painel, um lugar onde todos os tipos de informaes diferentes listado em uma maneira que os usurios finais podem ver o que est acontecendo em um s lugar. No Sugar 5.0, isso tem sido prorrogado por no s melhorar oz Dashlets disponveis, mas tambm permitindo ao usurio agrupar seus Dashlets em guias diferentes. Figura 5-2 mostra a tpica home page com Dashlets.
FIGURA 11 - HOME PAGE COM DASHLETS Da perspectiva do desenvolvedor, h muitas maneiras de personalizar aqui. Dashlets so adicionados no nvel de mdulo e dentro do diretrio Dashlets/. Colocando um subdiretrio embaixo nome do Dashlet e um script PHP com a classe child estendida da base, Dashlet obtm a classe que voc comeou. Existem trs tipos principais de Dashlets em Sugar: ListView dashlet: exibe listas de registros como o ListViews ou subpainis. Grfico dashlet: exibe um grfico para o usurio usando o flash. Iframe dashlet: exibe uma pgina da web dentro do dashlet. Vamos quebrar estes ver como podemos criar cada um deles. LISTVIEW DASHLET Para isso, h muito pouco cdigo PHP necessrio. O que voc precisa a subclasse da classe Dashlet de construo. Em vez de diretamente herdar a classe Dashlet, no entanto em vez disso , voc vai herdar da classe DashletGeneric, que tem todos os mtodos comuns para este tipo de dashlet predefinido. Isso lhe permite utilizar metadados para personalizar o dashlet, em vez de depender de cdigo PHP. A listagem 5-2 mostra a classe filha para o exemplo ApplicantsDashlet. Listagem 5-2 ApplicantsDashlet Class <?php require_once('include/Dashlets/DashletGeneric.php'); require_once('modules/ApplicantsDashlet/ApplicantsDashlet.php'); class ApplicantsDashlet extends DashletGeneric{ public function __construct($id,$def = null){ global $current_user, $app_strings; require('modules/ApplicantsDashlet/metadata/dashletviewdefs.php'); parent::DashletGeneric($id, $def); if(empty($def['title'])) $this->title = translate('LBL_HOMEPAGE_TITLE','test_basic'); $this->searchFields = $dashletData['ApplicantsDashlet']['searchFields']; $this->columns = $dashletData['ApplicantsDashlet']['columns']; $this->seedBean = new ApplicantsDashlet(); } } Tudo o que o construtor faz aqui apontar a direo correta. Voc comea carregando o arquivo de definio, que contm a searchfields e as colunas para o dashlet. Voc tambm defini o ttulo e, em seguida, o objeto de Bean para o mdulo. A prxima parte definir os campos de pesquisa e da coluna. Para isso, voc ter um arquivo de dashletviewdefs.php no mdulo, definido no diretrio de metadados do mdulo (Ver listagem 5-3). Listabem 5-3ApplicantsDashlet Metadata <?php $dashletData['ApplicantsDashlet']['searchFields'] = array ( 'date_entered' =>array ( 'default' => '' ), 'assigned_user_id' =>array ( 'type' => 'assigned_user_name', 'default' => 'Administrator') ); $dashletData['ApplicantsDashlet']['columns'] = array ( 'name' =>array ( 'width' => '40%', 'label' => 'LBL_LIST_NAME', 'link' => true, 'default' => true, 'name' => 'name', ), 'date_entered' =>array ( 'width' => '15%', 'label' => 'LBL_DATE_ENTERED', 'default' => true, 'name' => 'date_entered', ), 'assigned_user_name' =>array ( 'width' => '8%', 'label' => 'LBL_LIST_ASSIGNED_USER', 'name' => 'assigned_user_name', 'default' => true, ), 'date_modified' =>array ( 'width' => '15%', 'label' => 'LBL_DATE_MODIFIED', 'name' => 'date_modified', 'default' => true, ), ); Voc definiu quatro campos para exibir: nome do requerente, a data em que foi introduzido no sistema, a quem esta atribudo, e a data em que o registro de Applicants foi modificado pela ltima vez. Voc habilitou tambm pesquisar por data de entrada e id de usurio atribudo. A exibio deste como o ListView padro, como voc pode ver na Figura 5-3.
FIGURA 12 - APPLICANTSDASHLET LISTVIEW Voc pode atualizar os dados de dashlet clicando no cone de atualizao na barra (aquele que tem duas setas em crculo), de ttulo que pega os dados atualizados em uma solicitao ajax. Clicar no cone X ir remover o dashlet da pgina. Voc pode obter para a caixa de dilogo de configurao para o dashlet clicando no cone de lpis, que abre uma janela que olha como figura 5-4.
FIGURA 13 - APPLICANTSDASHLET OPTIONS DIALOG A primeira parte da caixa de dilogo permite personalizar o dashlet propriamente dito, como alterar o ttulo, o nmero de linhas a exibir e as colunas amostra. A prxima parte incorpora o searchFields que voc definiu anteriormente, permitindo que voc personalize a exibio do dashlet. Um item que sempre adicionado o checkbox 'My itens Only', que til para filtrar outros registros de usurios no caso de voc estiver fazendo Dashlets de itens apenas para si mesmo. Estas podem ser personalizadas atravs do arquivo de metadados anteriormente mostrado na Listagem 2-2. CHART DASHLETS Grfico Dashlets funcionam de modo semelhante para o Listview Dashlets, a nica diferena na exibio do Dashlet propriamente dito. Aqui voc pode usar o mtodo de visualizao do Bean para construir e exibir o prprio grfico. A classe SugarCharts pode ser usada para fazer isso, porque tem modelos de grfico para muitos tipos diferentes de grficos, como grficos de barras, grficos de linhas, grficos de pizza e grficos de funil. O mtodo de exposio da classe dos childs do Dashlet manipulam toda a estrutura deste, de pegar os dados do banco de dados para exibi-lo para o usurio final, como voc pode ver na listagem 5-4. Listabem 5-4 mtodo de display() do OutcomeByMonthDashlet <?php public function display(){ $currency_symbol = $GLOBALS['sugar_config']['default_currency_symbol']; if ($GLOBALS['current_user']->getPreference('currency')){ require_once('modules/Currencies/Currency.php'); $currency = new Currency(); $currency->retrieve($GLOBALS['current_user']->getPreference('currency')); $currency_symbol = $currency->symbol; } require("modules/Charts/chartdefs.php"); $chartDef = $chartDefs['outcome_by_month']; require_once('include/SugarCharts/SugarChart.php'); $sugarChart = new SugarChart(); $sugarChart->setProperties('',translate('LBL_OPP_SIZE', 'Charts') . ' ' . $currency_symbol . '1'.translate('LBL_OPP_THOUSANDS', 'Charts'),$chartDef['chartType']); $sugarChart->base_url = $chartDef['base_url']; $sugarChart->group_by = $chartDef['groupBy']; $sugarChart->url_params = array(); $sugarChart->getData($this->constructQuery()); $sugarChart->is_currency = true; $sugarChart->data_set = $sugarChart->sortData($sugarChart->data_set, 'm', false,'sales_stage', true, true); $xmlFile = $sugarChart->getXMLFileName($this->id); $sugarChart->saveXMLFile($xmlFile, $sugarChart->generateXML()); return $this->getTitle('<div align="center"></div>') . '<div align="center">' . $sugarChart- >display($this->id, $xmlFile, '100%','480', false) . '</div><br />'; } /** * @see DashletGenericChart::constructQuery() */ protected function constructQuery(){ $query = "SELECT sales_stage," . db_convert('opportunities.date_closed','date_format',array("'%Y- %m'"),array("'YYYY-MM'"))." as m, " . "sum(amount_usdollar/1000) as total, count(*) as opp_count FROM opportunities "; $query .= " WHERE opportunities.date_closed >= ".db_convert("'".$this->obm_date_start."'",'datetime') . " AND opportunities.date_closed <= ".db_convert("'".$this->obm_date_end."'",'datetime') ." AND opportunities.deleted=0"; if (count($this->obm_ids) > 0){ $query .= " AND opportunities.assigned_user_id IN ('" . implode("','",$this->obm_ids) . "')"; } $query .= " GROUP BY sales_stage," . db_convert('opportunities.date_closed','date_format',array("'%Y- %m'"),array("'YYYY-MM'")) . " ORDER BY m"; return $query; } Com a refatorao d consulta real de construo para o mtodo de constructQuery(). Voc pode aliment-lo diretamente para o mtodo de SugarChart::getData() para lidar com o processo de construo do grfico inteiro. Para exibir o grfico que voc vera um processo de duas partes. Primeiro cria os dados de xml usados para construir o grfico para o diretrio de cache de sada, ento, em segundo lugar, voc alimenta ele volta para o mtodo SugarChart::display(), que exibe o grfico como uma animao em Adobe Flash. Voc pode ver isso em ao na Figura 5-5
FIGURA 14 OUTCOMEBYMONTH IFRAME DASHLETS Este um tipo muito simple de dashlet que apenas exibe uma pgina da web para o usurio final dentro de um iframe. No h nenhuma codificao necessria para este dashlet. Basta adicionar qual 'Portal da minha' dashlet para sua Home page, em seguida, defina a URL que voc quer apontar nas opes de configurao. Enquanto qualquer pgina da web pode ser utilizada dentro deste dashlet, realmente melhor atender somente determinados tipos de contedo no seu interior. Um tipo de contedo pginas web mveis. Eles so geralmente projetados para telas pequenas como celulares e tablets. Desde que as propores do iframe neste dashlet esteja na mesma situao, uma excelente escolha para iframe dashlets (consulte a Figura 5-6).
FIGURA 15 - GOOGLE TALK DASHLET Para criar o precedente dashlet de Google Talk, voc pode simplesmente definir a URL para o dashlet para http://talkgadget.google.com/talkgadget/popout na caixa de dilogo opes para o dashlet. CUSTOM DASHLETS Voc pode construir qualquer tipo de dashlet usando o framework dashlet. A nica exigncia para estender a classe Dashlet e implementar o mtodo de display() e, opcionalmente, os mtodos displayOptions() e saveOptions() se o dashlet configurvel. Voc pode controlar se o dashlet configurvel, definindo a propriedade de $isConfigurable na classe filha. Vejamos um exemplo de um dashlet personalizado que vem com o Sugar, Notices Dashlet, na listagem 5- 5. Listabem 5-5 TeamNoticesDashlet Class <?php require_once('include/Dashlets/Dashlet.php'); class TeamNoticesDashlet extends Dashlet{ public $isRefreshable = false; public $hasScript = true; public function __construct($id){ parent::Dashlet($id); if(empty($def['title']))$this->title = translate('LBL_MODULE_NAME', 'TeamNotices'); } public function displayScript() {} public function display(){ $data = array(); require_once('include/Sugar_Smarty.php'); $ss = new Sugar_Smarty(); require_once('modules/TeamNotices/TeamNotice.php'); $focus = new TeamNotice(); $today = db_convert("'".gmdate($GLOBALS['timedate']->dbDayFormat)."'", 'date'); $query = $focus->create_list_query("date_start",$focus->table_name.".date_start <= $today and ".$focus->table_name.".date_end >= $today and ".$focus->table_name.'.status=\'Visible\''); if ( $result = $focus->db->query($query) ){ while ( $row = $focus->db->fetchByAssoc($result) ){ $data[] = $row; } $ss->assign("data", $data); } return parent::display() . $ss- >fetch('modules/TeamNotices/Dashlets/TeamNoticesDashlet/TeamNoticesDashlet.tpl'); } } O mtodo de exibio aqui manipula a exibio de todo o contedo para o usurio. Duas outras propriedades so $isRefreshable, que controla a exibio do boto atualizar, e a propriedade de $hasScript, que true se o javascript usado na exibio do dashlet. Isso til se $hasScript definida como true, em seguida, a pgina inteira deve ser recarregada antes o dashlet pode ser usado. Seguinte, vamos olhar Sugar alimenta outra dashlet personalizada, que leva a interao no SugarCRM para um nvel totalmente novo. SUGAR FEEDS Redes sociais tornaram-se a nova maneira de interagir com as pessoas. Sites como Facebook, MySpace e LinkedIn tem ido de nicho online de aplicativos web so as principais ferramentas para nos manter em contacto com outros em todo o mundo. SugarCRM viu esta tendncia e viu a necessidade de adot-la no mbito do CRM. Muitas vezes membros de empresas e equipes podem estar geograficamente separados, ou podem estar apenas fora de contato com os outros, uma vez que esto envolvidos em diferentes projetos. Como pode todos ainda manterem contato e acompanhar o que est acontecendo dentro da organizao? Para isso, o conceito de Sugar Feeds nasceu. Sugar feeds uma ferramenta para redes sociais dentro de SugarCRM. Em sua forma mais simples, ele age como um quadro de mensagens intra-empresa, permitindo aos usurios postar mensagens e contedo para que outros possam ver. Este contedo pode ser um nmero de fontes diferentes: um link para outra pgina da web, uma imagem ou at mesmo um vdeo do YouTube. Para aqueles que utilizam SugarCRM Professional ou Enterprise Edition, voc pode at mesmo ter o contedo publicado para uma equipe especial, que permite que mensagens de entupimento da alimentao principal, do que o resto da empresa veria. Feeds de Sugar no so habilitadas por padro. Para habilitar o Sugar feeds voc precisar ir para o Sugar alimentar as configuraes no painel de Admin. Figura 5-7 mostra isso.
FIGURA 16 - SUGAR FEEDS ADMIN PANEL H duas fontes diferentes para Sugar feeds. Um so os feeds do usurio, que conduzido pelo contedo e mensagens postadas pelos usurios no Sugar Feeds dashlet. A outra fonte de lgica ganchos, antes de salvar o registro do mdulo. Ganchos de lgica so cdigo personalizado que pode ser chamado durante certos processos do aplicativo. (Voc vai aprender mais sobre eles no captulo 7.) Estes ganchos logicos so adicionados automaticamente em cdigo que situa-se diretrio SugarFeeds/ do mdulo, so derivados da classe FeedLogicBase. Eles so chamados durante o salvamento de um registro de mdulos, antes que a gravao real dos dados no banco de dados ocorra. Apenas um mtodo necessrio para ser implementado, pushFeed(), que o cdigo usado para empurrar a nova entrada de alimentao para o feed. Listagem 5-6 mostra esse mtodo para o mdulo de Calls. Listabem 5-6 Leads Module SugarFeeds Hook <?php class LeadFeed extends FeedLogicBase{ var $module = 'Leads'; function pushFeed($bean, $event, $arguments){ global $locale; $text = ''; if(empty($bean->fetched_row)){ $full_name = $locale->getLocaleFormattedName($bean->first_name,$bean->last_name, ''); $text = '{SugarFeed.CREATED_LEAD} [' . $bean->module_dir . ':' . $bean->id . ':' . $full_name . ']'; }else{ if(!empty($bean->fetched_row['status'] ) && $bean->fetched_row['status']!= $bean- >status && $bean->status == 'Converted'){ // Repeated here so we don't format the name on "uninteresting" events $full_name = $locale->getLocaleFormattedName($bean->first_name,$bean- >last_name, ''); $text = '{SugarFeed.CONVERTED_LEAD} [' . $bean->module_dir . ':'. $bean->id . ':' . $full_name . ']'; } } if(!empty($text)){ SugarFeed::pushFeed2($text, $bean); } } } Aqui voc pode empurrar os condutores recm-convertidos no Sugar feeds para outros usurios. O mtodo de SugarFeed::pushFeed2() faz isso. Ele pega o nome da equipe da equipe do registro e coloca-lo nos feeds da equipe, que para as instncias de Sugar Professional/Enterprise. A presena da classe anterior no diretrio o SugarFeeds tudo o que necessrio para fazer o trabalho de Sugar Feeds, mas voc pode desabilitar os mdulos que so j 'Sugar Feeds habilitado' atravs do painel de administrao do Sugar feeds, no marcando as caixas para os mdulos que no queria, como voc pode ver anteriormente na Figura 5-7. O Sugar feeds dashlet o resultado, e ele mostra os itens de feeds disponveis para o usurio em ordem cronolgica, com os itens mais recentes no topo da lista. Esta tambm a interface usada por usurios finais para postar novos itens para o usurio da alimentao. Figura 5-8 mostra como Dashlet Sugar Feeds, que pode ser adicionada para a pgina inicial ou o painel de controle.
FIGURA 17 - SUGAR FEEDS DASHLET O Sugar feeds faz a interao entre colegas de trabalho pertos e longes, muito mais fcil como centralizador de comunicao para que todos podem acompanhar o que est acontecendo no aplicativo. tambm uma ferramenta muito til para as atualizaes de dados a todos, mantendo os usurios finais cientes das adies e alteraes de registros em vrios mdulos. RECORD IMPORTING AND EXPORTING Sugar fornece funcionalidades automticas para importar e exportar registros de um mdulo. Ele usa o ListView como a principal interface para exportar registros. Aqui, os usurios podem simplesmente selecionar os registros que desejam exportar, clicar no boto 'Exportar', e, em seguida, um arquivo CSV ser retornado para o usurio com os registros solicitados. Figura 5-9 mostra o widget de ListView com capacidades de exportao.
FIGURA 18 - WIDGET DE LISTVIEW COM CAPACIDADES DE EXPORTAO Clique as caixas de seleo ir selecionar registros individuais para exportar, enquanto clicando no menu suspenso selecione link d ao usurio a habilidade de selecionar todos os registros na pgina atual, ou mesmo todos os registros que coincidem com a consulta de ListView. Por padro, o Sugar constri a consulta com base em todos os campos do banco de dados na tabela do mdulo principal e tabela personalizada. No entanto, s vezes voc pode querer adicionar campos calculados adicionais para essa lista. Para fazer isso, voc pode usar o mtodo create_export_query() do modulo Bean. Ele ir retornar de volta a consulta utilizada para criar a lista de exportao. Listagem 5-7 mostra um exemplo do mdulo contatos, atravs da construo de uma consulta que tambm vai pegar algumas informaes da conta tambm. Listabem 5-7 Contacts Module create_export_query() method <?php public function create_export_query(&$order_by,&$where,$relate_link_join=''){ $custom_join = $this->custom_fields->getJOIN(true, true,$where); $custom_join['join'] .= $relate_link_join; $query = "SELECT contacts.*,email_addresses.email_address email1, accounts.name as account_name, accounts.employees as account_employees, accounts.industry as account_industry, users.user_name as assigned_user_name "; if($custom_join){ $query .= $custom_join['select']; } $query .= " FROM contacts "; $query .= "LEFT JOIN users ON contacts.assigned_user_id=users.id "; $query .= "LEFT JOIN accounts_contacts ON ( contacts.id=accounts_contacts.contact_id and (accounts_contacts.deleted is null or accounts_contacts.deleted = 0)) LEFT JOIN accounts ON accounts_contacts.account_id=accounts.id "; //join email address table too. $query .= ' LEFT JOIN email_addr_bean_rel on contacts.id = email_addr_bean_rel.bean_id and email_addr_bean_rel.bean_module=\'Contacts\' and email_addr_bean_rel.deleted=0 and email_addr_bean_rel.primary_address=1 '; $query .= ' LEFT JOIN email_addresses on email_addresses.id = email_addr_bean_rel.email_address_id ' ; if($custom_join){ $query .= $custom_join['join']; } $where_auto = "( accounts.deleted IS NULL OR accounts.deleted=0 ) AND contacts.deleted=0 "; if($where != ""){ $query .= "where ($where) AND ".$where_auto; }else{ $query .= "where ".$where_auto; } if(!empty($order_by)){ $query .= " ORDER BY ". $this->process_order_by($order_by, null); } return $query; } A consulta anterior incluir o nome da conta, funcionrios e indstria campo juntamente com os dados de contato. A prxima parte da equao a importao dos dados para sua instncia de Sugar. Sugar 5.1 fez uma grande renovao do processo de importao, que bastante reforada pela importao atravs da interface do usurio e recursos de arquivo de importao, permitindo importao recorde de mais de 100.000 registros por vez. Ele tambm acrescentou uma maneira muito fcil de adicionar capacidades de importao para qualquer mdulo no produto tudo que necessrio so duas mudanas a seu mdulo existente. A primeira mudana necessria para adicionar a propriedade $importable para o bean do mdulo e definir o valor para true, enquanto o segundo discutido aps o cdigo a seguir. Listagem 2-7 mostra o mdulo de amostra que voc vai chamar os Applicants. Listagem 2-7. Applicants Module Bean Class with the Importable Property <?php require_once('include/SugarObjects/templates/person/Person.php'); class Applicants extends Person{ // we set importable to true to enable importing in our module public $importable = true; public function __construct(){ parent::Person(); } } O padro da propriedade Importable false se no for especificado o contrrio. A segunda parte a adio da opo de menu no menu do lado esquerdo atalhos para entrar no processo de importao para o mdulo atual. O menu de atalhos esquerda definido no arquivo Menu.php no diretrio do mdulo, e tudo o que voc precisa adicionar uma entrada para a opo de importao. Listagem 2-8 mostra isso para o mdulo de amostra de candidatos que voc usada no exemplo anterior. Listagem 2-8 Applicants Module Menu.php File <?php global $mod_strings, $app_strings, $sugar_config; if(ACLController::checkAccess('Applicants', 'edit', true)){ $module_menu[] = Array("index.php?module=Applicants&action=EditView&return_module=Applicants&return_action=index", $mod_strings['LNK_NEW_APPLICANT'],"CreateApplicants",'Applicants'); } if(ACLController::checkAccess('Applicants', 'list', true)){ $module_menu[] =Array("index.php?module=Applicants&action=index&return_module=Applicants&return_action=DetailView", $mod_strings['LNK_APPLICANT_LIST'],"Applicants", 'Applicants'); } if(ACLController::checkAccess('Applicants', 'import', true)){ $module_menu[] =Array("index.php?module=Import&action=Step1&import_module=Applicants&return_module=Applicants&r eturn_action=index", $app_strings['LBL_IMPORT'],"Import",'Applicants'); } O menu de atalho a esquerda e tpico para um mdulo que ter dois links: um para criar um novo registro e outra para acessar o ListView para o mdulo. O que voc fez adicionar um link depois que comear o processo de importao. Com essas duas alteraes, voc fez um mdulo disponvel que sero importados. Muito simples, considerando todas as coisas. H outras personalizaes disponveis para o processo de importao tambm. Uma comum excluir campos que esto sendo importados. As razes para isso so que normalmente devido a um campo de clculo no mdulo, assim voc no iria querer a determinada configurao importada para substituir esse clculo. Para ter um campo que ser excludo, basta adicionar o atributo importvel para a definio de campo no arquivo vardefs.php, conforme mostrado na Listagem 2-9. Voc tambm pode lidar com a situao onde um determinado campo deve ser importado. Novamente, voc pode usar o atributo importvel da definio do campo aqui, definindo-o como o valor ' required '. Quando o campo definido como obrigatrio, ento ele deve ser mapeado durante a etapa de mapeamento do processo de importao. Listagem 2-10. Exemplos de campos utilizando o atributo 'importable' <?php $dictionary['Applicants']['fields']['applied_position'] => array ( 'name' => 'applied_position', 'vname' => 'LBL_APPLIED_POSITION', 'type' => 'varchar', 'source' => 'non-db', 'len' => '32', 'importable' => 'required', ); $dictionary['Applicants']['fields']['applied_department'] => array ( 'name' => 'applied_department', 'vname' => 'LBL_APPLIED_DEPARTMENT', 'type' => 'varchar', 'source' => 'non-db', 'len' => '32', 'group'=>'portal', 'reportable' => false, 'importable' => 'false', ); A listagem anterior um exemplo tpico de um campo que no deseja importar. O campo de applied_department no caso um campo calculado com base no cdigo de posio, que dado no campo applied_position, ento voc no iria querer permitir a importao de um valor para isso desde que voc no iria us-lo no registro. Alm disso, o campo de applied_position um campo obrigatrio, uma vez que voc quer cada requerente para ser conectado a uma posio que ele est se candidatando. Como voc pode ver adicionar importao um mdulo uma coisa muito simples de fazer. Personalizando o processo de importao para um mdulo, onde podemos controlar os campos disponveis para importar para o e quais campos devem ser mapeados, tambm to simples. Agora vejamos como voc pode personalizar a aparncia do Sugar com temas. THEMES O Tema de um aplicativo web um dos aspectos mais importantes de qualquer aplicao. importante para a aceitao do utilizador final, porque se o aplicativo no esteticamente agradvel, ou tem m usabilidade, as pessoas no vo sentir muito favorveis para seu aplicativo (mesmo que faa sua vida muito mais fcil). Em implantaes corporativas, temas que inclui a identidade visual corporativa uma exigncia muitas vezes importante para as partes interessadas. Um enorme passo em frente para o desenvolvimento do tema foi feito com Sugar 5.5. O maior obstculo que anteriormente ao desenvolvimento do tema foi em criao. Normalmente, voc deve iniciar, copiando um tema existente para um novo diretrio e alterar os itens que voc deseja alterar. O maior problema com esta abordagem que era muito difcil de aplicar estilos em novos elementos da interface do usurio, muitas vezes exigindo o desenvolvedor fazer muito trabalho para trazer o seu tema atual com a nova verso. especialmente inconveniente se existem muito poucos que necessitam de alteraes personalizarem o tema ao seu gosto. Outra questo que os temas do fora-de-caixa no foram personalizveis, que significava que qualquer mudana que voc fizer para esses temas precisam ser reaplicados a cada atualizao. Com o advento do Sugar 5.5, o framework de tema foi melhorado dramaticamente. Para comear os temas agora contenham apenas imagens, arquivos css, templates smarty e cdigo javascript, mas nenhum cdigo PHP como havia anteriormente. Fazendo simplificando gradativamente a estrutura de diretrio, conforme mostrado na Figura 5-10.
FIGURA 19 - FIGURA 18 - THEME DIRECTORY LAYOUT Voc j deve ter percebido que eu disse uma pequena mentira, h um arquivo PHP que faz parte do tema. um arquivo de definio do tema, criado da mesma forma como muitos dos outros arquivos de definio no aplicativo como uma matriz associativa. Listagem 5-8 mostra a estrutura desse arquivo. Listagem 5-8. themedefs.php file <?php $themedef = array( 'name' => "Sugar", // theme name 'description' => "Sugar", // short description of the theme 'colors' => array("sugar","red","green","blue","purple","gray"),// list of color.*.css files provided 'fonts' => array("normal", "larger", "largest"), // list of font.*.css files provided 'maxTabs' => $max_tabs, // maximum number of tabs shown in the bar 'pngSupport' => true, // true if png image files are used in this theme, false if gifs 'parentTheme' => "ParentTheme", // name of the theme this theme inherits from, if something other than the default theme. 'barChartColors' => array(....), 'pieChartColors' => array(....), ); Uma coisa a notar o atributo de 'parentTheme', porque isso onde a mgica acontece. Digamos que voc gosta do tema de Sugar out-ofthe-box, mas precisa fazer alguns ajustes para ele. Antes, voc iria ter que copiar para um novo diretrio e comear cortando e colando. Mas com o novo quadro no Sugar 5.5, voc pode simplesmente criar um novo tema e especificar 'Sugar', como o tema do pai. A partir da, o novo tema conter somente as alteraes para o tema de pai necessrios para obter o resultado desejado, ento se voc quisesse usar imagens diferentes voc colocar imagens com o mesmo nome que o original no diretrio images/ do novo tema e colocar quaisquer alteraes de css no Style.css do arquivo no diretrio css/. Arquivos JavaScript e Smarty templates tambm podem ser sobreescritos. No caso de arquivos CSS e javascript, os arquivos sero adicionados para os arquivos existentes, enquanto imagens e templates smarty substituem os arquivos existentes. Agora tambm abriu a possibilidade de fazer alteraes personalizadas para temas. Essas personalizaes usam a mesma estrutura de herana que voc tem com a construo de novos temas em cima de temas j existentes, mas o faz adicionando um diretrio personalizado custom/themes/themename/ com a mesma estrutura que o tema original, especificando apenas as partes que voc deseja alterar. Reunindo a capacidade de personalizar qualquer tema existente de uma forma segura de atualizao ou construir um novo tema sobre um tema existente, voc pode mudar drasticamente a interface de usurio com muito poucas linhas de cdigo. Digamos que voc deseja adicionar um fundo do cabealho mais dramtico para o tema padro do Sugar. Voc iria comear criando os diretrios custom/themes/Sugar/images/ e custom/themes/Sugar/css/, que iro receber as alteraes. Em seguida, voc adicionar um arquivo Style.css no diretrio custom/themes/Sugar/css/, que contm as alteraes que voc deseja realizar para o tema. Listagem 5-9 mostra o arquivo style.css, que tem uma regra para a adio de um fundo para a div #header (esta div contm toda a seo superior do modelo tema). Listagem 5-9. style.css arquivo CSS com as modificaes de thema. #header { background: url(../../../../custom/themes/Sugar/images/header.jpg); } #globalLinks, #welcome, #search, #sitemapLink, #globalLinks a, #welcome a, #search a, #sitemapLink a { color: white !important; } Voc vai adicionar a nova imagem para o diretrio custom/themes/Sugar/images/header.jpg. Uma vez que a imagem que voc escolheu tiver algumas cores mais escuras, eu decidi fazer o texto branco, assim destaca-se mais. O produto acabado mostrado na Figura 5 - 11.
FIGURA 20 - SUGAR THEME WITH CUSTOM MODIFICATIONS Voc pode ver aqui que fazer algumas pequenas mudanas para um tema pode resultar em uma grande diferena. Esse o poder do do framework de themas do Sugar 5.5. Ele permite que o usurio faa pequenas coisas que podem resultar em grandes diferenas no produto como um todo. Este tipo de facilidade para o desenvolvedor ajuda a vender a experincia do usurio do Sugar para os usurios finais, que por sua vez facilita a sua vida como um desenvolvedor um pouco, tambm. LOGGER Como um desenvolvedor, uma das tarefas mais difceis a depurao de problemas. Rastrear onde suas personalizaes do errado pode ser uma tarefa assustadora, que at mesmo o desenvolvedor mais experiente pode lutar s vezes. Enquanto PHP tem ferramentas de rastreamento e depurao de risco, como apd ou XDebug (um dos meus favoritos), estes tipos de ferramentas de abrandar seu cdigo uma quantidade considervel, tornando seu uso em um ambiente de produo menos do que ideal. Felizmente, o SugarCRM vem com seu prprio agente de log conhecido internamente como o SugarLogger. uma ferramenta muito simples que pode ser configurado para ser to tranquila ou to detalhada, conforme necessrio, que o torna ideal para todos os tipos de necessidades log. Grande parte do cdigo que vem com SugarCRM usa o agente de log extensivamente para ajudar o desenvolvedor para ajudar a diagnosticar problemas sem afetar o usurio final em todos (exceto, claro, para o sucesso de desempenho pequeno vo ter as chamadas extras). Existem duas partes para o usando o agente de log. A primeira parte habilitar o agente de log, que pode ser feito a partir do arquivo config.php no diretrio raiz, ou na seo "Definies de sistema" do painel de administrao. Para configurar manualmente o agente de log, voc pode simplesmente editar o config. php e altere a configurao da chave de 'logger', como mostra a listagem 5 - 10. A maneira de mud-lo na interface do usurio mostrada na Figura 5-12. Listagem 5-10 config.php 'logger' key <?php 'logger' =>array ( 'level' => 'fatal', // options here can be one of: 'debug', 'info', 'warn','error', 'fatal', 'security', or 'off' 'file' => array ( 'ext' => '.log', // log file name extension 'name' => 'sugarcrm', // log file base name 'dateFormat' => '%c', // date format used in the log file for the entries;uses the settings from the PHP strftime() function 'maxSize' => '10MB', // max size of a single log file before it rolls over 'maxLogs' => 10, // max number of log files before it deletes the oldest one ), ),
FIGURA 21 - CHANGING THE LOGGER SETTINGS IN THE SYSTEM SETTINGS UI A escolha do nvel de log importante, pois voc pode filtrar a quantidade a fazer, alterando o nvel de log. A ordem dos nveis de log 'debug', 'info', 'warn','error', 'fatal', 'security', ento 'off', com 'debug', sendo o registro mais detalhado e 'off' no tendo nenhum log de tudo. Agora no seu cdigo, voc pode facilmente acionar o agente de log fazendo chamadas, como mostra a listagem 5-11. Listagem 5-11 Making Calls to the Logger <?php $GLOBALS['log']->info( "Write me to the info log"); // write to the log at the info level $GLOBALS['log']->debug( "Variable set to $x"); // write to the log at the debug level,with the current value of $x $GLOBALS['log']->security( "Illegal access by user {$current_user->username}");// write to the log at the security level, with the current user's username Com a listagem anterior, voc pode facilmente assistir por problemas em seu aplicativo que so grandes (como problemas de nvel de segurana) como solucionar problemas com o seu cdigo usando o nvel de 'debug' log, ou usar uma das configuraes no meio para dar a quantidade adequada de log necessrio. RESUMO Voc pode ver agora que o SugarCRM fornece vrias ferramentas que ir usar a maioria dos aplicativos, como gerenciamento de usurio painel itens, importao e exportao, temas e registro em log, automaticamente e totalmente integrados no produto. Eles tambm so muito controlveis de uma perspectiva de GUI, permitindo que os desenvolvedores realmente colocar as atividades cotidianas do sistema nas mos do usurio. Voc j viu as peas principais da plataforma SugarCRM. Na prxima seo do livro, voc vai olhar para as ferramentas disponveis para personaliz-lo para atender s necessidades de sua organizao. PERSONALIZANDO COM O STUDIO Na parte 1 do livro, voc viu todas as entranhas do SugarCRM e como eles funcionam juntos. No deixo qualquer pedra sobre pedra, mostrando como o MVC processa cada solicitao meticulosamente, como a estrutura de banco de dados construda usando arquivos de vardef, como a estrutura de metadados remove a necessidade de codificao manualmente pontos de vista comuns e onde procurar para os vrios componentes de um mdulo. Embora eu insinuada de maneiras de personalizar isso como voc foi junto, nesta seo do livro voc vai dedicar seu tempo olhando realmente para personalizar o aplicativo de como ele vem como voc precisar us-lo. As personalizaes que voc vai olhar so apenas extenses dos mdulos j existentes. Na parte 3 do livro, voc ir focar realmente construir nova funcionalidade em cima do SugarCRM. Eu vou mostrar maneiras mais fceis de personalizar Sugar neste captulo, usando o estdio. Voc ver como simples mas poderosa essa ferramenta , porque ele permite que a maioria das personalizaes de SugarCRM para ter lugar sem ter que tocar qualquer cdigo PHP. Esta ferramenta tambm um fator importante para a acessibilidade do SugarCRM para aqueles com pouca ou nenhuma experincia de programao, capacitando-os a estender facilmente sua instncia. COMEANDO COM O STUDIO Studio, dentre as vrias ferramentas para desenvolvedores que SugarCRM, foi projetado para ser usado de dentro do prprio aplicativo. uma ferramenta nica para um aplicativos da web (ou qualquer aplicativo de negcios) porque ele permite que voc faa a atualizao segura personalizaes para sua instncia usando uma simples ferramenta de GUI. Figura 6-1 mostra como o estdio parece quando voc digit-lo, o primeiro do link Admin > Studio.
FIGURA 22 - TELA PRINCIPAL DO STUDIO A interface para o Studio tem trs partes distintas: a coluna mais esquerda uma exibio de rvore de todos os mdulos personalizveis em sua instncia. Voc pode expandir a rvore para acessar as personalizaes disponveis para qualquer parte especfica de um mdulo. A seo center a exibio de contedo principal para estdio, contendo a informaes primria, que voc est preocupado ao fazer personalizaes. A coluna mais direita usada para exibir a ajuda, como voc trabalha atravs de estdio, para ajudar o guia sobre como usar efetivamente o estdio e mostrar o impacto das suas alteraes. Mencionei anteriormente que os mdulos apenas mostrados aqui so mdulos que podem ser personalizados. Quando eu digo personalizvel, quero dizer Studio personalizvel. Nem todos os mdulos so personalizados por padro, principalmente porque alguns tm um monte de cdigo legado em vistas deles ou muito personalizada. Para estes, voc no pode usar o estdio, mas em vez disso, ser necessrio personaliz- los usando o cdigo que voc ver no captulo 8. Para aqueles que podem ser personalizados usando o estdio, voc s precisa adicionar um arquivo de studio.php dentro do diretrio modules/modulename/metadata/. O arquivo no precisa ter nada dentro mera presena para o studio sabe o mdulo est pronto para a personalizao. Studio projetado para permitir que o usurio faa os seguintes tipos de personalizaes: Adicione novos campos para um mdulo. Alterar os nomes de exibio (o nome do campo que o usurio visualiza) de campos existentes em um mdulo. Edite vrias seqncias de caracteres de rtulo usadas em um mdulo. Personalize os layouts Edit, Detail, e List views, bem como a caixa de pesquisa no topo do Listviews e a forma de Quickcreate usados na coluna da esquerda na pgina. Adicionar novas relaes do mdulo determinando em outro mdulo (ou o mesmo mdulo). Personalize a exibio de subpainis no registro para o determinado mdulo DetailView. Eu vou separar os tpicos anteriores em sees para mostrar como cada um deles funciona. ADICIONANDO NOVOS CAMPOS PARA UM MDULO Adicionando campos um das personalizaes mais comuns que as pessoas fazem a SugarCRM. A maior razo para isso que todo mundo tem um ou dois campos extras que necessitam para seus prprios fins, se uma caixa de seleo para indicar um status de algo ou talvez um campo para especificar um nmero de identificao interno de uma conta. Isso uma coisa que SugarCRM entende sobre sua base de usurios. CRM no um tipo de um-tamanho-fix-all do aplicativo, por isso bobagem para forar as pessoas a esse tipo de pensamento. Nesse contexto, o primeiro e mais importante e usa o Studio que capaz de adicionar novos campos personalizados para um mdulo. Adicionar novos campos personalizados, um exerccio muito simples. No ecr principal do Studio, clique sobre o mdulo que voc deseja editar e, em seguida, clique no link 'Campos'.De l, ir mostrar uma lista de todos os campos no mdulo, como voc pode ver na Figura 6-2.
FIGURA 23 - VIEW OF FIELDS FOR THE ACCOUNTS MODULE Observe que a lista de campos dividida em sees separadas. A parte superior (que atualmente no tem nenhum campos como voc pode ver o rtulo '-None-') onde sero listados todos os campos personalizados para um mdulo. Abaixo da linha horizontal onde os campos normais para o mdulo esto listados. Isto til j que campos personalizados permitem lotes de personalizao para eles atravs do estdio, enquanto campos normais s permitem que seu rtulo de exibio seja alterado. A partir daqui, voc pode adicionar novos campos personalizados para seu mdulo. Para fazer isso, voc simplesmente clique no boto 'Adicionar campo', que trar uma nova janela de dilogo para dar os detalhes do novo campo para adicionar (consulte a Figura 6-3).
FIGURA 24 - ADD FIELD DIALOG O campo de dropdown inicial mostrado na Figura 6-3 indica que tipo de dados, este campo ser. (No captulo 2, discuti os arquivos vardef e vrios tipos de campo em Sugar). As opes mostradas aqui so usadas para definir os valores na definio do campo. Eles so diferentes dependendo do tipo de dados que voc escolher para o campo, ento voc notar-alterao ao selecionar um tipo de campo diferente do padro. No entanto, as opes tpicas mostradas anteriormente tendem a ser bastante consistente entre os vrios tipos de campo, com a adio de alguns e algumas novas opes conforme necessrio. Voc tambm vai notar por padro que Studio ir adicionar o sufixo 'optimistas' para o nome do campo que voc escolher. Isso feito como uma Conveno para campos personalizados e no necessrio. Digamos que o novo campo que voc deseja adicionar muito semelhante a um campo existente no mdulo. Em vez de ir pela dificuldade de criar um novo campo e na esperana de acertar todas as configuraes, voc pode simplesmente clonar o campo que voc deseja copiar de tornar o novo campo. Para fazer isso, clique no campo que deseja clonar o seu novo campo personalizado, que traz a caixa de dilogo Editar. Ao lado de salvar boto ser um boto Clone, que quando clicado vai abrir um novo campo Editar Exibir com as configuraes do campo atual j preenchido. A partir daqui voc pode alterar qualquer coisa que quiser (especialmente o nome de domnio) e clique em salvar para salvar o campo. Olhando como os campos so adicionados no SugarCRM do ponto de vista dos bastidores, os novos campos adicionados por meio de estdio so realmente adicionados separadamente dos campos padro para um mdulo. Para cada tabela do mdulo principal, uma tabela secundria com o sufixo '_cstm' adicionada quando voc criar campos personalizados, e esta tabela possui os campos personalizados para um mdulo. Durante o salvar e recuperar processo, voc juntar os campos na tabela principal e a tabela personalizada, a fim de obter todos os campos necessrios para o registro. importante saber disso por motivos de desempenho, porque se voc tem os campos personalizados que voc vai estar buscando fortemente, voc pode querer considerar adicionar ndices para eles tambm. Isso algo que voc precisa fazer no prprio banco de dados usando alguma forma do comando SQL CREATE INDEX. Certifique-se de que, quando voc fizer isso, voc incluir o campo de id de registro ('id_c') para garantir que esse ndice escolhido pelo otimizador de consulta do banco de dados. Uma vez que voc adicionou os campos que voc precisa para o mdulo, o prximo passo adicionar os campos para os pontos de vista para que os usurios podem interagir com eles. CUSTOMIZANDO VIEW TEMPLATES Cada um dos modos de exibio de metadados so personalizveis atravs do estdio. Faz-lo atravs do Studio oferece vrias vantagens em relao a edit-los manualmente. Como voc viu no captulo 3, pode ser tedioso obter tudo correto e evitar erros nos arquivos de metadados. O Studio permite que voc edite atravs de arrastar e soltar, tornando a personalizao dos forms num piscar de olhos. CUSTOMIZANDO EDIT E DETAIL VIEWS Vamos comear olhando os detalhes e editar pontos de vista. Voc pode obter a estes, indo para a seo de Layouts aps selecionar o mdulo que deseja personalizar. A partir da, voc pode selecionar links EditView ou DetailView para personalizar o modo de exibio determinado. Quando a vista carrega, voc ver uma tela semelhante figura 6-4.
FIGURA 25 - STUDIO EDITVIEW EDITING FOR THE THE ACCOUNTS MODULE A seo principal deste formulrio mostra o layout do EditView. Se voc se lembra do captulo 3, quando falei sobre a estrutura de metadados, as formas so dispostas em forma de tabela, e voc pode agrupar conjuntos de campos em painis diferentes para ajudar a facilitar a entrada de dados e visualizao de registros. O lado esquerdo tem uma lista de campos disponveis para adicionar ao form como um elemento, adicionar um novo painel para o formulrio e adicionar uma nova linha para um painel existente. Os painis so mais para organizar campos em grupos de reas afins, como a colocao de todos os campos de endereo em uma seo. Cada painel contm uma ou mais linhas, onde voc pode colocar um campo para cada clula da coluna. A vista muito interativa. Voc pode adicionar e remover elementos do formulrio simplesmente clicando e arrastando os vrios elementos de formulrio ao redor para obter a viso resultante que voc deseja ter. Quando voc est satisfeito com suas alteraes, voc pode clicar em salvar para salv-los, ou implantar & Save para salvar as alteraes e depois disponibiliza-los para todos os usurios imediatamente. H alguns outros pontos de vista que usam este estilo de edio tambm. Por exemplo, a QuickCreate, forms de exibio so utilizadas para criar ou editarem os registros do Subpainel em linha usando ajax em vez de carregar plenamente a exibio de edio. Eles usam esta mesma forma de edio para personalizar seus pontos de vista. Aqueles que usam as verses Professional e Enterprise do Sugar tambm tem a capacidade de usar o seu dispositivo mvel, como um iPhone ou BlackBerry, com vista especialmente formulada para o aplicativo que pode ser facilmente usado em movimento. Comeando com Sugar 5.5, esses modos de exibio podem ser editados atravs do estdio tambm atravs da mesma interface mostrada anteriormente. A principal questo que as pessoas podem deparar com a verso mvel do Sugar que apenas alguns dos mdulos so habilitados para ser usado com dispositivos mveis, por padro e assim esto ausentes do estdio ser personalizvel l. Felizmente, outra adio de Sugar 5.5 foi uma interface do usurio para adicionar e remover mdulos disponveis da verso mvel do Sugar, como mostrado na Figura 6-5.
FIGURA 26 - DILOGO PARA ADICIONAR E REMOVER MDULOS DA VERSO MVEL DO SUGAR Isso tambm pode ser feito em Sugar 5.1 ou 5.2 Criando o arquivo custom/include/MVC/Controller/wireless_module_registry.php e adicionando a entrada $wireless_module_registry['modulename'] = array(); para ele. PERSONALIZANDO O LISTVIEWS ListViews so um pouco diferentes do que suas contrapartes Edit e Detail Views. Por um lado, o layout fsico diferente, como se concentra mais em dados de coluna, em vez de um form grande. Mas uma outra grande diferena que ListViews tambm pode ser personalizvel pelo usurio. Podem tanto mudar a ordem de colunas, mas tambm remover e adicionar colunas visualizao. Devido a esses fatos, voc precisa ter o estdio agindo de formas diferentes. Para comear como ListViews podem ser personalizados com Studio selecionando ListView depois de escolhemos o mdulo que desejamos personalizar. Figura 6-6 mostra a exibio de edio para o ListView por padro.
FIGURA 27 - PERSONALIZANDO O LISTVIEW PARA O MDULO DE ACCOUNTS NO STUDIO O editor de ListView possui trs colunas de campos. A primeira coluna uma lista de campos que aparecer por padro quando voc est no modo ListView do mdulo. Se voc olhar o arquivo listviewdefs.php d o mdulo, voc ver esses campos listados com o atributo 'default' definido como true. A coluna do meio uma lista de campos que esto disponveis para o usurio incluir no ListView, mas no so mostrados por padro. Finalmente, a ltima coluna uma lista de todas as colunas que esto escondidos do visor para o usurio. Esta coluna deve incluir apenas o campo que, sob nenhuma circunstncia um usurio final, poderia ter includo no ListView. O formulrio em si muito interativo, assim como o modo de exibio de editar e detalhe editores form.Voc pode livremente reordenar qualquer um dos campos nas colunas mostrados, tambm clicando e arrastando e soltando campos entre as colunas conforme necessrio. Clicando no cone permite que voc altere o rtulo de exibio e larguras de cada coluna, o que muito til com ele seu ListView se encaixa muito melhor e exibir os dados de forma muito mais clara, se ele j no faz isso por padro. Quando voc tem os campos da form que lhe desejar, clicando em Save & implant vai formalizar as alteraes para todos usurio comearem a utilizar imediatamente. Para personalizar os painis de pesquisa usando o Studio e subpainis, usada uma verso modificada da tela de edio de ListView. Desde que os usurios no possam personalizar quais campos aparecero na busca, ou para um Subpainel, voc pode remover a coluna disponvel a vista de edio, como mostrado na Figura 6-7.
FIGURA 28 - PERSONALIZANDO O SUBPAINEL CONTATOS NO MDULO ACCOUNTS USANDO O STUDIO A edio de vista funciona exatamente do mesmo jeito que a edio para o ListView: por que permite arrastar e soltar o posicionamento do campo e ordenandar a exibio. Trabalhar com os painis de pesquisa idntico, exceto que voc vai querer estar ciente do nmero de colunas utilizadas no painel de pesquisa. As contrapartes mveis para o ListView e painis de pesquisa funcionaro como os painis de pesquisa normal e o ListView, respectivamente. EDIO DE ROTULOS Como voc viu, o SugarCRM separa strings em arquivos de linguagem para permitir a aplicao ser facilmente traduzida para diversas lnguas. Isso tem sido muito bem sucedido para o Sugar, como foi traduzido para mais de 75 lnguas diferentes desde a sua criao, tornando-o um produto verdadeiramente global. Mas esta camada de abstrao tambm permite que os usurios alterem o palavreado de exposio usado em vrias partes do aplicativo para combinar os termos que fazem mais sentido para a sua empresa ou fluxo de trabalho. Existem duas principais maneiras de fazer isso. A maneira mais simples para fazer a mudana , porm, a opo de rtulos sob o mdulo em estdio. Figura 6-8 lista todas as seqncias de caracteres para o idioma atual em determinado mdulo, permitindo que voc edite-os ali.
FIGURA 29 - EDIO DE RTULOS PARA UM MDULO tela de edio muito simples, fornecendo os valores atuais para as vrias cadeias de caracteres e uma caixa de entrada para alter-los. Se voc tem vrios pacotes de idiomas instalados em sua instncia de Sugar, voc pode selecionar o idioma que voc deseja editar no menu Idioma suspenso na parte superior do formulrio para alterar a seqncia de caracteres usada em outras lnguas. Depois de ter feito as alteraes, clicando em Save & Deploy salva as alteraes e aplica-as imediatamente para a instncia atual. A segunda maneira que voc tambm pode fazer alteraes a um campo diretamente. Essa abordagem pode ser preferida, pois permite que voc saiba exatamente qual seqncia de exibio ser usada com cada campo, removendo quaisquer ambiguidades em decidir que etiqueta para editar na opo de etiquetas sob o mdulo no estdio. Para acessar isso, basta clicar sobre o nome de domnio listado na opo dos campos sob o mdulo e so retornados de uma forma semelhante figura 6-9.
FIGURA 30 - O RTULO DE EXIBIO PARA UM DETERMINADO CAMPO DE EDIO A partir daqui, voc pode simplesmente fazer seu campo exibir a mudana de rtulo na caixa de entrada e clique em salvar para que as alteraes sejam feitas imediatamente. Vamos dizer que voc s precisa de nome de exibio do campo alterado em um dos metadados impulsionada exibies, como o EditView, mas no quer que ele mudou em todos os lugares. Em vez de editar o rtulo de exibio que voc tenha anteriormente, voc pode edit-lo atravs da exibio de personalizao EditView. Para fazer isso, clique no cone no campo como listado no display do modelo de vista, que far aparecer a caixa de dilogo mostrada na Figura 6-10.
FIGURA 31 - EDITAR O NOME DO CAMPO ATRAVS DA TELA DE PERSONALIZAO DE MODELO DE EXIBIO Aqui voc pode especificar o rtulo exato para utilizar este campo para esta exibio de metadados. Salvar sua mudana voc comprometer a usar determinada seqncia de caracteres para este campo no modo de exibio. Se voc deixar em branco, em seguida, a seqncia de caracteres de padro para o campo ser usada. RELACIONAMENTOS, RELACIONAMENTOS, RELAES Uma das ferramentas mais teis no Studio a capacidade de adicionar novos relacionamentos para outros mdulos do produto. Se voc se lembra do captulo 2, voc pode definir vrios tipos de relacionamentos entre lidar com as necessidades especficas que voc tem em seu exemplo de Sugar. Fazer isso manualmente pode tornar-se um processo de vrias etapas muito tedioso, exigindo-lhe corrigir adicionar as peas necessrias para o vardefs para ambos os mdulos, criar subpainis para exibir os dados e at mesmo adicionar campos extras para o EditView e DetailViews do mdulo para exibir esses dados extras. Felizmente, a capacidade do estdio para criar relaes lida com isso tudo automaticamente para recebe-lo pronto para ir a uma instncia. Para comear a criar novos relacionamentos, v para o link de relaes sob o mdulo que deseja personalizar. Uma vez que voc fz aquele, voc ver uma tela semelhante figura 6-11.
FIGURA 32 - RELAO A LISTAGEM PARA O MDULO DE ACCOUNTS NO STUDIO A lista de relacionamentos do mdulo mostra todas as relaes que existem atualmente para o mdulo. Voc pode ver o nome da relao, o mdulo principal do relacionamento (muitas vezes referido como o mdulo do pai), o tipo de relao e o mdulo que relacionado a (tambm conhecido como o mdulo child). Todos os mdulos que voc adicionou atravs do estdio tambm aparecem aqui com um asterisco ao lado do nome do relacionamento. Uma vez que voc fez isso aqui, voc pode simplesmente clicar em adicionar relaopara adicionar uma nova relao. Quando voc faz assim, ser mostrada a nova tela de relao, como voc pode ver na Figura 6-12.
FIGURA 33 - CRIANDO UMA NOVA RELAO COM O MDULO DE ACCOUNTS USANDO O STUDIO A nova forma de relacionamento permite que voc selecione os mdulos primrios e afins para o relacionamento. H trs opes para este tipo de relacionamento que voc pode criar atravs deste formulrio: Um a um: O mdulo principal tem um registro que se relaciona com apenas um registro no mdulo relacionado. Um para muitos: O mdulo principal tem um registro que se refere a um ou mais registros no mdulo relacionado. Muitos para muitos: O mdulo principal pode ter um ou mais registros que refere-se a um ou mais registros no mdulo relacionado. A nova forma de relacionamento muito dinmica, assim quando voc alterar o tipo de relao na coluna central do form, os detalhes do relacionamento de cada lado da coluna sero alterado em conformidade. Se o lado da relao contm a parte de muitos (o que significaria esse mdulo tem mais de um registro relativos ao outro lado da relao), ento as opes para fornecer um rtulo para o Subpainel no lado oposto da relao est disponvel, juntamente com uma opo para escolher o layout do Subpainel a usar. Aps clicar em Deploy, a relao torna-se permanente e imediatamente disponvel para todos os usurios. Isto onde acontece a "magia". Ocorrer uma das muitas coisas diferentes, dependendo do tipo de relacionamento que voc escolher: Um a um: O mdulo principal e o mdulo relacionado tm relacionar campos adicionados aos pontos de vista editar e detalhe para permitir que os usurios finais construir o relacionamento entre os registros. Um para muitos: O mdulo principal ter um Subpainel listando todos os registros relacionados nos mdulos relacionados, que inclui a capacidade de adicionar todos os registros existentes relacionados a esse registro ou adicionar um novo registro, que relacionado a esse registro de l. No mdulo relacionado, referem-se de campo ser adicionado a modos de exibio Editar e detalhe para permitir que usurios finais se relacionar com o registro um registro no mdulo principal Muitos para muitos: tanto o primrio e os mdulos relacionados tero um Subpainel listando todos os registros relacionados no mdulo oposto, que inclui a capacidade de adicionar todos os registros existentes relacionados a esse registro ou adicionar um novo registro, que relacionado a esse registro de l. Adicionando um registro relacionado o outro mdulo far aparecer em subpainis para esse registro e o registro no mdulo oposto. Voc pode ver o que estdio realmente faz tudo o que voc precisa aqui adicionar relaes a qualquer mdulo personalizvel de estdio no Sugar. Uma coisa que o estdio no permite a capacidade de excluir relacionamentos que voc adicionou, mas eu lhe darei uma soluo para esse problema na prxima seo. AJUDA! MINHAS PERSONALIZAES TEM DADO ERRADO Digamos que voc se jogou ao redor com Studio neste captulo. Voc adicionou um monte de novos campos personalizados, modos de exibio e adicionado um relacionamento ou dois. Aps atravessar o caminho de aprender os meandros de sua instncia de Sugar com estdio de personalizao, voc percebe que voc foi longe demais e agora deseja voltar. No tenho medo, como tudo o que voc fez pode ser facilmente desfeito. Todas as personalizaes de metadados (personalizaes para qualquer uma das vistas de detail/edit/listviews e subpanels) feitas so armazenadas no diretrio /custom. Simplesmente removendo o arquivo de metadados associados (editviewdefs.php, detailviewdefs.php, listviewdefs.php, etc.) do diretrio /custom/modules/modulename/metadata/, o modo de exibio personalizado desfeito e voc pode continuar usando os layouts de exibio fora-de-caixa. O Studio tambm armazena o histrico de suas mudanas de exibio dentro do diretrio custom/history/modules/modulename/metadata/, assim voc pode percorrer para trs as alteraes voc fez para a exibio do formulrio. Figura 6-13 ilustra isso em ao, e voc pode acess-lo clicando no boto Exibir histrico.
FIGURA 34 - VISO HISTRICA DAS ALTERAES FEITAS PELO MDULO CONSTRUTOR PARA EXIBIO Clicando em Preview d para olhar para o que se parecia a vista naquele momento no tempo. Quando voc encontrar o que deseja, basta clicar em Restore e ele volta vida. Remover campos personalizados muito simples da interface do usurio do Studio, simplesmente clique no campo que voc deseja excluir da vista de campos e, em seguida, clique no boto apagar em modo de edio do campo. Voc tambm pode remov-los manualmente, mas uma tarefa tediosa. Se voc se lembrar, as definies de campo personalizado so realmente armazenadas no banco de dados, em vez do prprio sistema de arquivo. Portanto, o processo para remover o campo envolve realmente olhar para a tabela field_meta_data e remover a definio de campo personalizado da tabela. Para olhar para o campo, verifique se o id do campo a ser definido como o nome do mdulo mais o nome do campo. Se o nome do campo personalizado no mdulo de contas for foobar_c, procure o registro com o campo id definido como 'Accountsfoobar_c'. A partir da, voc pode definir o valor do campo excludo daquela linha para 1, ou simplesmente excluir a linha da tabela. Ento, voc precisar recriar os arquivos de vardef. Voc pode fazer isso no Sugar, v para Admin > Repair > Repair Database, ento simplesmente removendo o arquivo cache/modules/modulename/modulenamevardefs.php. Relacionamentos so tambm tratados inteiramente dentro do diretrio custom/, mas eles no vm com uma bonita interface do usurio para remov-los (Lembre-se a mensagem de aviso gigante sobre a incapacidade de remover quaisquer relacionamentos criados). No tenham medo, embora, voc pode vasculhar o diretrio custom/ para desfazer estas alteraes tambm. H trs arquivos diferentes que precisam removidos: custom/metadata/relationship_nameMetaData.php custom/Extension/modules/firstrelatedmodulename/Ext/Vardefs/customrelationship_name.php custom/Extension/modules/secondrelatedmodulename/Ext/Vardefs/customrelationship_name.php
Substitua o nome da relao (geralmente firstrelatedmodulename_secondrelatedmodulename) nos exemplos anteriores. Se a relao refere-se voltar para o mesmo mdulo, ento voc s tem dois arquivos para excluir. Uma vez que esses arquivos sejam removidos, voc precisar ir Admin > Repair > Rebuild Relationships, seguido por um Admin > Repair > Repair Database para limpar todo o restante que faz referncia ao mdulo anterior no vardefs cache. Se voc tiver quaisquer reas afins para o mdulo pai do mdulo filho, ento voc tambm vai querer remover estes manualmente a partir de arquivos de metadados de viewdef ou usando o Studio. Lembre-se de que a desfazer qualquer personalizao apenas to perigoso como fazer personalizaes, portanto recomendo tentar isso em uma instncia de teste antes de faz-lo em sua instncia de produo. Runa pode ser especialmente perigosa, j que voc pode perder quaisquer personalizaes que voc no quis remover. RESUMO Neste captulo, voc aprendeu tudo sobre Studio, uma ferramenta muito poderosa e nica que permite que os usurios finais a personalizar sua instncia de Sugar com pouca ou nenhuma experincia de programao necessria. Studio permite que voc adicione novos campos personalizados para um mdulo personalizar a seqncia de caracteres usada em um mdulo e adicionar relaes adicionais entre o determinado mdulo e outro mdulo, ou mesmo de volta para o mdulo atual. Voc explorou cada um desses tpicos em detalhes, mostrando a facilidade de uso que o estdio fornece para fazer essas personalizaes. Voc tambm viu como as alteraes so feitas enquanto estiver usando o Studio, usando a UI de estdio prprio, removendo os arquivos do diretrio custom/ e/ou remover as entradas da tabela de field_meta_data. No prximo captulo, voc olhar em personalizaes projetadas para modificar os dados no aplicativo baseado sobre as aes que os usurios executar. Muito parecido com Studio, estes ganchos tero front-ends amigvel a eles; tambm permitem alteraes mais poderosas atravs de cdigo PHP personalizado. FLUXOS DE TRABALHO E GANCHOS DE LGICA Pense em processos de negcios por um segundo. Eles geralmente envolvem vrias etapas com decises a tomar em cada passo de como continuar. Eles envolvem todos os tipos de lgica, interrogando-se sobre os resultados de uma etapa ou o status do processo e como us-lo para fazer a transio para o prximo passo no processo. Esses processos podem ficar muito complicados. Lembro-me de antigos projetos em que s vezes o diagrama final parece um labirinto gigante de crculos e setas que fazem voc ficar tonto apenas olhando para ele. Mas, a realidade que a maioria das empresas dependem esses tipos de processos (mesmo se eles so confusos) e preciso model-los em suas aplicaes de software tambm. Felizmente, o SugarCRM vem com uma forma segura de fazer isso. Neste captulo, voc vai dar uma olhada em ganchos de lgica, que fornece uma ferramenta para adicionar esses processos em sua instncia de Sugar. Voc tambm vai olhar para fluxos de trabalho, que uma maneira de criar muitos ganchos de lgica comum, usando uma interface de apontar e clicar. O QUE SO GANCHOS LGICOS? Ganchos de lgica fornecem maneiras de estender o SugarCRM com cdigo PHP. O que o torna diferente da maioria das personalizaes que se voc no for alterar ou substituir o cdigo existente com a personalizao. Em vez disso, voc est adicionando o cdigo que projetado para ser chamado, em determinadas circunstncias, durante a execuo do aplicativo. Pense em ganchos de lgica como seu playground, onde voc pode adicionar qualquer tipo de cdigo para que o aplicativo execute as aes necessrias. H um nmero de lugares no aplicativo onde voc pode adicionar lgica de ganchos. Tabela 7-1 descreve-los. Tipo Descrio after_ui_frame Acionado aps o frame foi chamado e antes o rodap foi invocado. Este gancho no tem acessar para o objeto atual do Bean (ou seja, voc no pode visualizar ou alterar valores de um registro). after_ui_footer Acionado aps o rodap ser chamado. Este gancho no tem acessar para o objeto atual do Bean server_round_trip Acionado no final de cada pgina do SugarCRM. Ele chamado no mtodo sugar_cleanup(), que chamado como a funo de desligamento para o Sugar. Este gancho no tem acessar para o objeto atual do Bean before_delete Acionado antes que um registro excludo usando o SugarBean::mark_deleted(). after_delete Acionado depois que um registro excludo usando o SugarBean::mark_deleted(). before_restore Acionado antes que um registro recuperado usando o mtodo de SugarBean::mark_undeleted(). after_restore Acionado depois que um registro recuperado usando o mtodo de SugarBean::mark_undeleted(). before_retrieve Acionado antes que um registro foi obtido do banco de dados usando o mtodo de SugarBean::retrieve(). Este gancho no disparar quando voc cria um novo registro. after_retrieve Acionado depois que um registro foi obtido do banco de dados usando o mtodo de SugarBean::retrieve(). Este gancho no disparar quando voc cria um novo registro. before_save Demitido antes que um registro salvo usando o mtodo de SugarBean::save(). Uma coisa a notar que com alguns mdulos, como Bugs e casos a identificao legvel do registro (como o campo de case_number no mdulo de processo), no est disponvel dentro de uma chamada de before_save desde a lgica de negcios que calcula esse valor simplesmente ainda no foi executado ainda. after_save Acionado depois que um registro salvo usando o mtodo de SugarBean::save(). Uma coisa a notar que com alguns mdulos, como Bugs e casos a identificao legvel do registro (como o campo de case_number no mdulo de processo), no est disponvel dentro de uma chamada de after_save desde a lgica de negcios que calcula esse valor simplesmente ainda no foi executado ainda. process_record Acionado imediatamente antes da consulta de banco de dados, resultando em um registro que est sendo feito atual. Isso d aos desenvolvedores a oportunidade de examinar e adaptar as consultas subjacentes. Este tambm um lugar perfeito para definir valores em antes de campos de um registro para exibir no DetailView ou ListView. Este evento no acionado no EditView. before_logout Acionado antes de um usurio faz logon no sistema. after_logout Acionado depois que um usurio faz logon no sistema. Este gancho no tem acessar para o objeto atual do Bean after_login Acionado depois que um usurio faz logon no sistema. Este gancho no tem acessar para o objeto atual do Bean before_login Acionado depois que um usurio faz logon no sistema. Este gancho no tem acessar para o objeto atual do Bean login_failed Disparado em uma tentativa de logon falhou. Este gancho no tem acessar para o objeto atual do Bean Voc pode ver na tabela 7-1 que h muitos ganchos de lgica disponveis para uso. Voc vai notar que muitos destes so ganchos de nvel de aplicativo e alguns so ganchos de nvel de mdulo todos os ganchos de nvel de aplicativo (after_ui_frame, after_ui_footer, server_round_trip) so projetados para lidar com aes de nvel de aplicativo, para que nenhuma informao do objeto do Bean estar disponvel para eles. Todos os outros ganchos de lgica ter as informaes atuais do Bean disponvel a eles (com exceo do ganchos after_logout, before_login e login_failed, j que nenhum objeto do Bean do usurio estar disponvel). Agora que voc sabe o que est disponvel para uso como escritores de gancho de lgica, vamos mergulhar mesmo criando seu primeiro gancho de lgica. CRIANDO SEU PRIMEIRO GANCHO DE LGICA Agora que voc j viu todas as opes de gancho de lgica, vamos realmente construir um. Os ganchos so classes PHP, enquanto os mtodos neles so os ganchos reais que sero executados. Existem duas partes para qualquer gancho de lgica: o arquivo de definio de gancho e o gancho prprio. O arquivo de definio de gancho ir instalar o gancho de lgica para a instncia em execuo, tornando-se instantaneamente disponvel. Isso feito automaticamente durante as primeiras partes do pedido. Olha dentro do arquivo de custom/modules/modulename/logic_hooks.php e o arquivo custom/modules/logic_hooks.php para essas definies. O arquivo de definio tem uma estrutura de matriz, uma amostra do que aparece na Listagem 7-1. Listagem 7-1 Sample logic_hooks.php File <?php $hook_version = 1; $hook_array = Array(); $hook_array[after_save] = Array(); $hook_array[after_save][] = Array(1, AccountHooks,custom/Accounts/AccountHooks.php,AccountHooks, checkForLead); $hook_array[before_save] = Array(); $hook_array[before_save][] = Array(1, AccountHooks, custom/Accounts/AccountHooks.php,AccountHooks, getParentAccountIndustry); Existem dois elementos essenciais para os arquivos de definio de gancho de lgica. A primeira parte est especificando o valor de $hook_version que deve ser definido como o valor inteiro '1.' (Isso projetado para ser usado no caso de SugarCRM atualiza a API para a construo lgica ganchos). Em seguida, voc construir a matriz lgica de definies de ganchos como uma matriz associativa. O primeiro nvel da matriz multidimensional indica o tipo de gancho que voc est definindo. A partir da, cada elemento na matriz aponta para os ganchos individuais a chamar. Essa matriz tem cinco elementos com as seguintes especificaes: Parmetro 1: classificao de ndice usado para classificar os conjuntos de definies de lgica gancho antes que eles so processados. Parmetro 2: um valor de seqncia de caracteres para identificar o gancho. Parmetro 3: caminho para o arquivo PHP para incluir o que contm o cdigo da lgica de gancho. Parmetro 4: nome da classe PHP o mtodo do gancho de lgica pol. Parmetro 5: nome do mtodo PHP para chamar. Com arquivo de definio lgica de gancho definido, voc pode realmente comear a escrever um gancho de lgica para seu aplicativo. Para fazer isso, voc vai continuar com o exemplo que voc comeou na Listagem 7-1. Voc tem dois ganchos de lgica para execuo antes e aps o save de um registro de Account. O gancho de after_save vai fazer uma verificao rpida para certificar-se de que voc no tenha definido o dado como um lead, usando as informaes de nome e endereo. Se tiver, vou ligar o registro de lead para este registro. Ento no gancho before_save, voc vai verificar o registro de conta do pai (se um dado) para um valor para o campo da indstria se ele no atualmente definido no registro atual. Listagem 7-2 mostra isso tudo em ao. Listagem 7-2 Arquivo de exemplo de lgica de ganchos para o modulo Accounts no arquivo AccountHooks.php <?php require_once(modules/Leads/Lead.php); require_once(modules/Accounts/Account.php); class AccountHooks{ public function checkForLead(SugarBean $bean,$event,$arguments){ $leadFocus = new Lead; $leadFocus->retrieve_by_string_fields( array( name => $bean->name, primary_address_street => $bean->billing_address_street, primary_address_city => $bean->billing_address_city, primary_address_state => $bean->billing_address_state, primary_address_postalcode => $bean->billing_address_postalcode, primary_address_country => $bean->billing_address_country, account_id => , ) ,false ); if (!empty($leadFocus->id)){ $bean->load_relationship(leads); $bean->leads->add($leadFocus->id); } } public function getParentAccountIndustry(SugarBean $bean,$event,$arguments){ if(empty($bean->industry) && !empty($bean->parent_id)){ $parentAccountFocus = new Account(); $parentAccountFocus->retrieve($bean->parent_id); if(!empty($parentAccountFocus->id)) $bean->industry = $parentAccountFocus->industry; } } } Voc criou com xito os ganchos de lgica. Agora em cada salvar de um registro de conta, o aplicativo ir verificar ligaes que tm o mesmo nome e o endereo do atual e relacion-los, bem como o campo da indstria da conta do pai gravar para o atual de aterramento. Em seguida, voc adicionar alguns ganchos de lgica mais a seu mdulo tambm. Digamos que voc adicionou alguns campos personalizados que so calculados a partir de outros campos no aplicativo. Por exemplo, talvez voc agrupar suas contas em regies baseadas no estado em que localizam-se. Supondo que voc tenha criado uma matriz app_strings_list das opes para a regio account_region_dom de nome de domnio, voc pode adicionar um gancho de lgica simples, como mostrado na Listagem 7-3 para lidar com esse caso. Listagem 7-3 lgica do ganchos after_retrieve getRegion para o mdulo de Accounts <?php public function getRegion(SugarBean $bean,$event,$arguments){ switch (strtoupper($bean->billing_address_state)){ case "AL": case "AK": case "AZ": case "AR": case "CA": case "CO": case "CT": $bean->region_c = $app_list_strings[account_region_dom][Region1]; break; case "DE": case "FL": case "GA": case "HI": case "ID": case "IL": case "IN": case "IA": case "KS": case "KY": $bean->region_c = $app_list_strings[account_region_dom][Region2]; break; case "LA": case "ME": case "MD": case "MA": case "MI": case "MN": case "MS": case "MO": case "MT": case "NE": case "NV": case "NH": case "NJ": case "NM": $bean->region_c = $app_list_strings[account_region_dom][Region3]; break; case "NY": case "NC": case "ND": case "OH": case "OK": case "OR": case "PA": case "RI": case "SC": case "SD": case "TN": case "TX": case "UT": case "VT": case "VA": $bean->region_c = $app_list_strings[account_region_dom][Region4]; break; case "WA": case "WV": case "WI": $bean->region_c = $app_list_strings[account_region_dom][Region5]; break; } O cdigo anterior verifica o estado de endereo faturamento da conta para determinar esse valor de campo. Isto tem a vantagem de ter este campo sempre com preciso exibido ao cliente facilmente. A parte agradvel que neste caso pode ser personalizado facilmente quando a empresa precisa mudar para refletir com preciso a regio correta. Outra alterao comum seria adicionar alguma lgica para o gancho de lgica login_failed. Por exemplo, talvez voc queira o administrador de sistema de e-mail quando algum tem problemas para fazer login em contas de administrador. Listagem 7-4 fornece uma soluo para isso. Listagem 7-4 Lgica do Gancho para alertas sobre falha de logons administrador <?php class LoginHooks{ public function alertSystemAdminOfBadAdminLogin($event,$arguments){ if ( $_REQUEST[user_name] == admin ) { mail("admin@localhost","BAD ADMIN LOGIN","Someone tried to login to the admin account and failed. Better check it out!"); } } } Voc apenas verificar o nome de usurio dado e se ele corresponder a conta de administrador, voc vai disparar um e-mail para o administrador do sistema sobre o assunto. Voc poder at mesmo incluir o celular do usurio tambm com um SMS se voc ficar muito poucos em uma fileira. Agora que voc j viu como escrever a nossos prpria lgica ganchos, vejamos como voc pode usar a ferramenta de fluxos de trabalho para fazer muitas com um ponto e clique em interface. PONTO E CLIQUE EM GANCHOS DE LGICA COM FLUXOS DE TRABALHO Voc j viu como criar ganchos de lgica usando cdigo PHP que interrompeu em diversos pontos da aplicao. A desvantagem que a lgica ganchos requerem PHP habilidades de codificao para cri-los, o que pode tornar difcil para a pessoa mdia para constru-los. Para ajudar essas pobres almas fora, SugarCRM vem com uma ferramenta para ajud-los a construir os ganchos de lgica mais comuns, chamados de fluxos de trabalho. (Fluxos de trabalho esto disponveis apenas nas verses Professional e Enterprise do SugarCRM). Fluxos de trabalho permitem que voc criar ganchos de lgica usando uma interface de usurio fcil de usar, em vez de ter que escrever cdigo PHP. Isso especialmente til para aqueles com pouca ou nenhuma experincia de programao. Eles podem simplesmente ir pelas caixas de dilogo para criar a lgica de que desejam adicionar. Porque voc est usando uma GUI, o tradeoff usando a interface de fluxos de trabalho para criar a lgica personalizada no to extensa, como pode ser feito com ganchos de lgica, ento se tiver muito complicadas necessidades, ento voc pode melhor servido escrevendo os ganchos de lgica mo. Voc ver as limitaes como voc anda atravs da criao de um fluxo de trabalho do incio ao fim, que ir ajud-lo a julgar qual abordagem melhor para voc. CRIAR O FLUXO DE TRABALHO O mdulo de fluxo de trabalho est escondido no painel de administrao, sob o ttulo, as definies de fluxo de trabalho. Para criar a sua definio de fluxo de trabalho, voc vai comear clicando no link criar definio de fluxo de trabalho, que traz a Figura 7-1.
FIGURA 35 - CRIAR CAIXA DE DILOGO DE DEFINIO DE FLUXO DE TRABALHO Depois de dar seu fluxo de trabalho de um nome, ento voc precisa escolher quando voc deseja que o fluxo de trabalho a ser executado. As escolhas aqui so quando um registro salvo, ou aps decorrido tempo (esta opo basicamente adiciona seu fluxo de trabalho para ser um evento agendado em vez de desencadeada por alteraes de dados, desde que tenha a ferramenta de Agendador de cron SugarCRM correndo naquele tempo). Voc ento escolher qual mdulo se este fluxo de trabalho aplica, se voc quer provocar a criao de um novo registro, salvar um registro existente, ou ambos e se voc quiser os alertas ou aes a serem processadas primeiro. Voc tambm pode adicionar uma descrio para o fluxo de trabalho, que uma boa idia, ento todo mundo sabe o que faz sem ter que vasculhar a definio inteira para descobrir isso. Estarei certo para marcar o fluxo de trabalho como inativo aqui o status at que voc tem tudo isso configurado, ento ele parcialmente no executar previamente. Depois de ter todas as opes definidas da maneira que quiser, clique em salvar e o fluxo de trabalho ser adicionado. Ento voc vai ser na tela DetailView para o fluxo de trabalho, conforme mostrado na Figura 7- 2.
FIGURA 36 - WORKFLOW DETAIL VIEW Voc pode agora comear a construir as entranhas do fluxo de trabalho daqui. Fluxos de trabalho tem trs partes bsicas: A primeira parte do fluxo de trabalho as condies, que definem o que precisa ser feito para que o fluxo de trabalho a ser executado. As outras duas partes so os alertas, que especifique a e-mails ou mensagens que sero enviadas para usurios especficos em uma condio ser verdadeira, e aes, que definem as alteraes de dados que esto a ocorrer quando as condies forem atendidas. Voc olhar para as duas ltimas partes em um minuto, mas primeiro vamos a p atravs da criao de uma condio para seu fluxo de trabalho. Para criar uma nova condio para um fluxo de trabalho, comea, clique no boto criar debaixo o Subpainel de condies. Aps fazer isso, voc ver uma janela como na Figura 7-3.
FIGURA 37 - DEFINE CONDITION FOR WORKFLOW DIALOG WINDOW Este o comeo de um assistente de duas partes para a definio de uma condio de fluxo de trabalho. Voc tem vrios tipos de condies, que voc pode definir aqui, como mostrado na Figura 7-3. As opes incluem: Disparo quando um campo no mdulo de um valor especfico para outro valor especificado. Acionar quando nada nas alteraes de mdulo. Desencadear quando um campo especfico em que as alteraes de mdulo de destino. Desencadear quando um campo no mdulo contm um valor especfico. Acionamento quando nada o mdulo muda e um campo no mdulo contm um valor especfico. Quando voc clicar no boto de rdio para sua escolha, a seo caixa branca da caixa de dilogo alteraes ao texto que indica o que vai fazer a condio. Um exemplo disso mostrado na Figura 7-4.
FIGURA 38 - DEFINIR A CONDIO PARA A JANELA DE DILOGO DE FLUXO DE TRABALHO DEPOIS DE ESCOLHER UMA OPO A parte do link destacado onde voc pode clicar para escolher o campo que voc estar tratando nesta condio de fluxo de trabalho. Clicando nesse link, aparecer uma caixa de dilogo, como na Figura 7-5.
FIGURA 39 - POPUP DE SELEO DE CAMPO DURANTE A CONDIO DE DEFINIR PARA DILOGO DE FLUXO DE TRABALHO Aqui voc apenas selecione o campo que voc deseja usar e, em seguida, clique em salvar ou clique em cancelar se voc no quiser salvar a sua seleo. Se voc poderia clicar em salvar aqui, ento a janela de dilogo original seria atualizada como segue na Figura 7-6.
FIGURA 40 - DEFINIR A CONDIO PARA A JANELA DE DILOGO DE FLUXO DE TRABALHO DEPOIS DE ESCOLHER UMA OPO E CAMPO A partir daqui, voc pode clicar em seguida para aplicar mais o resto da especificao para a condio. Note que alguns dos tipos de condio no tem uma segunda etapa (ou seja "Quando se altera o mdulo de destino" e\"quando um campo sobre as mudanas do mdulo de destino"), ento se voc escolher as opes que voc s clique no boto de salvar que est presente em vez de no boto Avanar. A segunda parte do formulrio diferente com base na seleo inicial do tipo de condio, mas geralmente segue a mesma conveno usada na caixa de dilogo anterior. Para o exemplo anterior de alterar o campo de posse de um valor para outro, voc ver um formulrio semelhante a Figura 7-7.
FIGURA 41 - DEFINA A CONDIO PARA A JANELA DE DILOGO DE FLUXO DE TRABALHO PARA ESPECIFICAR AS INFORMAES DE CAMPO ALTERADO. Novamente, aqui voc vai ter o mesmo tipo de recursos de edio que voc tinha na caixa de dilogo anterior, onde voc pode clicar em um link para editar essa parte da definio da condio. Ao clicar no link de valor, voc ter novamente um formulrio pop-up onde voc pode especificar o valor do campo deve ou no deve ser, como mostrado na Figura 7-8.
FIGURA 42 - ESPECIFICANDO O VALOR DO CAMPO DE CONDIO Voc v em frente e far a sua condio de ser quando o valor da propriedade de barra para Foo. Para fazer isso vamos checkbox ambos especificar nova propriedade: valor e especifica a posse velha: caixas de seleo, o que coloca ambas as regras em sua condio de valor. Voc vai clicar no link de campo para tornar o campo valor especificaes em conformidade para o antes e depois de valores que voc deseja ter. Figura 7-9 mostra os resultados finais.
FIGURA 43 - DEFINIR A CONDIO PARA A JANELA DE DILOGO DE FLUXO DE TRABALHO PARA ESPECIFICAR AS INFORMAES DE CAMPO ALTERADO TODAS CONCLUDAS Agora tudo que voc precisa fazer clicar Salvar e sua condio agora salvo. Voc pode adicionar condies como muitos como voc deseja para um fluxo de trabalho para garantir que o fluxo de trabalho executado sob as condies corretas. Agora vamos passar para a criao de alertas para quando ocorre um fluxo de trabalho. DEFINIO DE FLUXO DE TRABALHO DE ALERTAS Muitas vezes tudo o que precisa fazer quando mudar de campos ou um mdulo muda que algum precisa saber sobre ele. Por exemplo, usando o exemplo anterior, talvez voc precisa notificar uma certa pessoa quando altera o campo de posse, para que eles talvez podem chamar o cliente para verificar ou atualizar a contabilidade para alterar suas estruturas de preos. Esta uma opo trivial com fluxos de trabalho e que voc tambm pode adicionar um pouco de personalizao em tambm. Para comear a criar novos alertas, basta clicar no boto criar o Subpainel alertas, e voc ver o EditView de alertas, como mostrado na Figura 7-10.
FIGURA 44 - WORKFLOW ALERTS EDITVIEW. Alertas podem ser to simples como uma mensagem de e-mail, que apenas envia o texto especificado para a pessoa alertou. Mas voc tambm tem a opo de criar um modelo de e-mail de alerta, para que voc possa fornecer a pessoa alertou com informaes muito mais detalhadas. Primeiro, voc precisa primeiro criar esse modelo de alerta. Voc pode fazer isso clicando os modelos de E-mail de alerta na barra lateral e na tela resultante, escolha o mdulo que voc deseja criar um modelo para e clique em criar. Voc ser ento apresentado com o alerta EditView modelos, conforme mostrado na Figura 7- 11.
FIGURA 45 - ALERT TEMPLATES EDITVIEW Voc pode compor e-mails RTF usando essa ferramenta como soltando antes e depois de valores de campo juntamente com links recorde em modelo. Usar esta ferramenta permite que voc realmente dar a pessoa alertou uma vista muito mais informada sobre o que aconteceu e, opcionalmente, pode-se dar-lhes as ferramentas para agir corretamente sobre ela. Em seguida, no EditView de alertas, altere o tipo de fonte para o modelo personalizado e o campo de modelo personalizado recentemente aparecendo pode ser definido como o modelo que voc deseja usar. Para este exemplo, vou ficar com a mensagem de email bsico, ento aps clicar em salvar voc estar de volta ao DetailView de alertas de fluxo de trabalho, conforme mostrado na Figura 7-12.
FIGURA 46 - WORKFLOW ALERTS DETAILVIEW Agora voc s precisa adicionar destinatrios para o seu e-mail. Esta outra tarefa trivial com muitas opes. Figura 7-13 mostra a caixa de dilogo que voc ver aps clicar em Create no alerta anterior Subpainel de lista de destinatrios.
FIGURA 47 - ALERT RECIPIENT LIST POPUP DIALOG Novamente, voc tem muitas opes aqui, de notificar o usurio atribudo ao registro para notificar todas as equipe relacionado e membros da funo, ou apenas notificando uma certa pessoa de cada vez. A caixa de dilogo funciona exatamente o mesmo que as condies de fluxo de trabalho um, onde clicando nos links permitem "preencher os espaos em branco", por assim dizer. Voc tambm notar voc tem a opo para indicar qual campo de endereo deve ser usado pelo correio para o endereo de e-mail do usurio, quer seja para:, CC:, ou Bcc:, ento, novamente, h muitas opes. Para fazer as notificaes de e-mail disparadas de um fluxo de trabalho, voc deve ter habilitados nas configuraes de E-mail no painel de administrao de e-mails. Como as condies de fluxo de trabalho, voc pode adicionar tantos alertas e destinatrios de alertas que desejar para a determinada condio. Vamos agora passar para olhar em como criar aes para seu fluxo de trabalho. AES DE FLUXO DE TRABALHO A ltima pea do quebra-cabea de fluxo de trabalho (e, muitas vezes, a parte mais importante) que dados de aes devem ter lugar quando as condies forem atendidas. Novamente, voc tem uma caixa de dilogo de fcil uso para definir isso. Vai comear clicando em criar sob o Subpainel de aes em seu fluxo de trabalho para obter a caixa de dilogo popup mostrada na Figura 7-14.
FIGURA 48 - WORKFLOW ACTIONS DIALOG Aqui voc tem algumas opes sobre o que fazer: voc pode atualizar campos em determinado registro ou um registro relacionado ao registro, ou at mesmo criar novos registros no mdulo atual ou um relacionados. Semelhante a como funcionava o dilogo de condies de fluxo de trabalho, clicando em um dos botes de rdio comea a construir as regras, permitindo a personalizao, se voc v campos vinculados durante a mesma. Para este exemplo, vamos escolher atualizar os campos no registro atual, assim quando voc clicar em prximo voc pode ver a caixa de dilogo mostrada na Figura 7-15 e escolher quais campos para atualizar.
FIGURA 49 - WORKFLOW ACTIONS DIALOG TO INDICATE WHICH FIELD TO UPDATE. Esta caixa de dilogo permite que voc escolha um ou mais campos para atualizar para o determinado registro. Voc simplesmente checkbox o campo que voc deseja atualizar e, em seguida, no clique caixa seguir o link de campo para especificar o valor que voc deseja alterar para um determinado valor. Agora voc criou um totalmente funcional-to-end fluxo de trabalho, com condies de execuo, alerta para um usurio de ele disparar e uma ao que dever adoptar em determinado registro. Se voc est confortvel com suas escolhas, v em frente e edite o fluxo de trabalho para tornar o status ativo e salv-lo. Em seguida, tentar salvar uma conta com um campo de propriedade foi alterado de Foo a barra para ver o fluxo de trabalho em ao. GERENCIAR A SEQNCIA DE FLUXOS DE TRABALHO s vezes, fluxos de trabalho podem interferir uns com os outros (como podem ganchos de lgica, que Falarei mais sobre na seo "Armadilhas de ganchos de lgica" a seguir) ou importante para os fluxos de trabalho a serem processadas em uma determinada ordem para obter o efeito desejado. Por exemplo, um fluxo de trabalho pode definir um valor de um campo e outro pode definir o valor de um segundo campo com base na valor inicial do campo usado no outro fluxo de trabalho. Por estas e outras razes, a opo de encomendar seus fluxos de trabalho em uma determinada ordem pode ser muito importante, para que o Sugar tem a capacidade de personalizar isso tambm. Selecionando o link da ordem de execuo de fluxo de trabalho na barra lateral e, em seguida, escolha o mdulo que voc deseja ver lhe dar a lista de fluxos de trabalho atuais para ele, semelhante figura 7-16.
FIGURA 50 - WORKFLOW EXECUTION ORDER SCREEN Nesta tela, voc pode clique para cima e abaixo, as setas para alterar a posio do fluxo de trabalho da sequncia de fluxo de trabalho para o determinado mdulo. O primeiro listado o primeiro a executar, seguido pelo prximo da lista. Como voc viu, fluxos de trabalho so uma ferramenta muito til para criar ganchos de lgica que lidam com tarefas muito comuns. Quando os fluxos de trabalho no podem lidar com isso, ento os ganchos de lgica que voc aprendeu a construir na primeira parte deste captulo podem intervir para apoiar o extra necessrio voc precisa executar as aes que voc precisa para acontecer. s vezes as ferramentas tambm podem criar um mundo de problemas se voc no for cuidadoso. Na seo a seguir, voc vai explorar alguns desses problemas em potencial e que voc pode fazer sobre eles. ARMADILHAS DE GANCHOS DE LGICA Se voc ir para os fruns do Sugar e procure por ganchos de lgica, voc provavelmente vai ter uma tonelada de resultados com pessoas que tm coisas misteriosas acontecendo com seus ganchos de lgica. Ganchos de lgica esto longe de ser trivial, e muitas vezes tempo pode ser conduzir a resultados bastante confusos se voc no prestar ateno ao que o cdigo est fazendo. Nesta seo, destacarei algumas reas onde voc pode ter problemas com ganchos de lgica e discutir a melhor maneira de obter fora deles. MODIFICAR O OBJETO DO BEAN Uma coisa que muito importante a lembrar que o objeto do Bean passado para voc um objeto ao vivo. Enquanto isso abre a possibilidade para o gancho de lgica fazer algumas coisas poderosas, ela tambm pode criar problemas. Vejamos um exemplo na Listagem 7-5. Listagem 7-5. Exemplo de arquivo de AccountsHooks.php contendo ganchos de lgica para o mdulo de contas <?php class AccountHooks{ public function reassignNewRecordTeamBasedOnIndustry(SugarBean $bean,$event,$arguments){ $teamBean = new Team; // Set the team based upon the given industry. switch($bean->industry){ case "Banking": $teamBean->retrieve("Banking"); $bean->team_id = $teamBean->id; break; case "Energy": $teamBean->retrieve("Banking"); $bean->team_id = $teamBean->id; break; } } } Essa lgica projetada para ser chamado de um evento before_save. Quando voc chamar isso depois de inicialmente salvar um novo registro, tudo funciona como esperado e salva o registro recm-criado. Mas voc ver ainda mais defesas do registro parecem causar problemas. Isso ocorre porque o cdigo indiscriminado de se o registro foi salvo ou no. Portanto, voc vai manter reatribuindo o registro para a equipe indicada no gancho lgica, mantendo-o de alter-la no caminho. Para corrigir isso, voc precisar adicionar uma verificao para certifique-se de que o registro j no existe. Listagem 7-6, mostra o exemplo modificado para corrigir este problema. Listagem 7-6. Exemplo de arquivo de AccountsHooks.php que contm a lgica conecta para o mdulo de contas com uma correo para no disparar sobre criao de novos registros. <?php class AccountHooks{ public function reassignNewRecordTeamBasedOnIndustry(SugarBean $bean,$event,$arguments){ // Don't execute if the we aren't creating a new record if (!empty($bean->fetched_row) && !empty($bean->fetched_row['id'])) return; $teamBean = new Team; // Set the team based upon the given industry. switch ( $bean->industry ) { case "Banking": $teamBean->retrieve_by_string_fields (array('name' =>"Banking"),false); $bean->team_id = $teamBean->id; break; case "Energy": $teamBean-> retrieve_by_string_fields (array('name' =>"Energy"),false); $bean->team_id = $teamBean->id; break; } } } Voc adicionou uma simples verificao para ver se o campo de id de registro tiver sido definido anteriormente. Voc verificou que a matriz de fetched_row desde o registro de identificao real j ter sido definir no momento em que a lgica chamada independentemente de ser um registro recm-criado ou no de gancho. No entanto, a matriz de fetched_row no ser definida em novos registros, portanto, seguro para verific-lo para determinar se se trata de um novo registro, ou no. Tambm importante estar ciente de quando um gancho chamado durante a execuo do aplicativo. Vamos dar uma olhada o gancho de lgica na Listagem 7-7. Listagem 7-7. Gancho de lgica casos para verificar determinados limites de nmeros de processo <?php class CaseHooks{ public function alertSystemAdminOfCaseNumbers(SugarBean $bean,$event,$arguments){ // Don't execute if the we aren't creating a new record if ( !empty($bean->fetched_row) && !empty($bean->fetched_row['id']) ){ return; } if ( $bean->case_number % 1000 == 0 ) { $GLOBALS['log']->info("Reached case number " . $bean->case_number . "!"); } } } O maior problema aqui que seu nvel de informao sobre o arquivo sugarcrm.log ser agora preenchido com atingido caso nmero 0! para todos salvar. Este no o que voc quer em tudo. O problema que o campo de case_number um campo auto_increment, que, como todos os campos auto_increment, baseia- se no banco de dados para lidar com o valor correto. Por isso, o valor gerado no est disponvel em before_save ou after_save evento. No entanto, voc pode procurar ele no banco de dados do evento after_save com as seguintes modificaes para o gancho de lgica original, como mostrado na Listagem 7-8. Listagem 7-8. Gancho de lgica de casos fixa para verificar determinados limites de nmeros de processo <?php class CaseHooks{ public function alertSystemAdminOfCaseNumbers(SugarBean $bean,$event,$arguments){ // Don't execute if the we aren't creating a new record if ( !empty($this->fetched_row) && !empty($bean->fetched_row['id']) ){ return; } $casesBean = new Case; $casesBean->retrieve($bean->id); if ( !empty($casesBean->id) && $casesBean->case_number % 1000 == 0 ) { $GLOBALS['log']->info("Reached case number " . $casesBean->case_number . "!"); } } } Agora as mensagens de log de sugarcrm informao ser relatrio muito mais sensato e somente quando voc alcanou a cada 1.000 casos novos no sistema. GANCHOS DE LGICA CONFLITANTES Outra armadilha que voc pode arranjar em ter ganchos de lgica que esto fazendo aes que entram em conflito uns com os outros. Isto conduz frequentemente a resultados imprevisveis. Vejamos um exemplo dessa Listagem 7-9. Listagem 7-9. Erros de lgica ganchos para verificar fixed_in_release e Found_in_release campos <?php class BugHooks{ public function autoSetFixedInRelease(SugarBean $bean,$event,$arguments){ if ( empty($bean->fixed_in_release) ){ $bean->fixed_in_release = $bean->found_in_release; } } public function adjustInvalidFoundInRelease(SugarBean $bean,$event,$arguments){ if ( !empty($bean->fetched_row) && !empty($bean->fetched_row['found_in_release']) && ( $bean->fetched_row['found_in_release'] != $bean->found_in_release ) ) { $releaseBean = new Release; $releaseBean->retrieve($bean->found_in_release); if ( !empty($releaseBean->id) && $releaseBean->status == 'Inactive' ){ $bean->found_in_release = ''; } } } } Digamos que voc tem um cliente SOAP que est modificando registros de Bugs (digo isso pois libera inativo no so visveis na interface de usurio normal) e seu cliente acidentalmente define o campo found_in_release para um lanamento invlido. Idealmente, o gancho de adjustInvalidFoundInRelease() iria chutar e claro que para voc, retirar a especificao de verso invlida nesse campo. No entanto, se o gancho de autoSetFixedInRelease() executa primeiro? A especificao de verso inativa encontra seu caminho para o campo de fixed_in_release primeiro e, em seguida, o campo de found_in_release Obtm esvaziado direito depois. A melhor maneira de corrigir isso, deve certificar-se de que os ganchos se executados na ordem correta, especificando-os como o arquivo de definio de ganchos de lgica para o mdulo, como mostra a listagem 7- 10. Listagem 7-10. Arquivo de gancho de lgica de Bugs <?php $hook_version = 1; $hook_array = Array(); $hook_array['before_save'] = Array(); $hook_array['before_save'][] = Array(1, 'BugHooks','custom/Accounts/BugHooks.php','BugHooks', 'adjustInvalidFoundInRelease'); $hook_array['before_save'][] = Array(1, 'BugHooks','custom/Accounts/BugHooks.php','BugHooks', 'autoSetFixedInRelease'); Especificando-os na ordem que voc deseja-lhes a ser executado, voc tem a listagem anterior, voc j resolveu o problema dos campos sendo misteriosamente atualizado. GANCHO DE LGICA ANULADO PELO CDIGO EXISTENTE Tanto quanto lgica ganchos permite interpor seus prprios comportamentos em um objeto, s vezes as coisas so apenas fora de suas mos. Vejamos o seguinte cdigo na Listagem 7-11, por exemplo. Listagem 7-11. Before_save lgica gancho para especificar seu prprio registro Ids <?php class AllHooks{ public function setGUID(SugarBean $bean,$event,$arguments){ // Only execute if the we are creating a new record if ( empty($bean->id) ){ $bean->id = myRecordIDGenerator(); } } } Este um gancho de lgica. Seu objetivo no gancho lgica anterior o uso da funo assumida myRecordIDGenerator() (voc supor que isso seja algum tipo de gerador de identificao que no vai dar IDs duplicados) para dar o registro ID para usar para este recm criado registro. Mas se voc empurrar a funo de gancho de lgica para o mtodo de before_save de qualquer determinado mdulo, voc encontrar que ele nunca ser chamado. Por que isso? Porque o registro ID gerado antes disso gravar est sendo criado, ento aqui sua tentativa para alter-lo s anulada. Voc pode corrigir isso mudando o seu cdigo de deteco, como mostrado na Listagem 7-12. Listagem 7-12. Corrigido before_save gancho de lgica para especificar seu prprio registro Ids <?php class AllHooks{ public function setGUID(SugarBean $bean,$event,$arguments){ // Only execute if the we are creating a new record if ( empty($bean->fetched_row) && !$bean->new_with_id ){ $bean->id = myRecordIDGenerator(); } } } Voc simplesmente ajustar o cdigo para verificar no haver uma linha buscada (ou seja, h um novo registro, desde que ele no existe no banco de dados), ento se o new_with_id Propriedade est sendo definido como false voc sabe que voc deve lanar a sua lgica de gerador de registro de identificao. FRAQUEZAS DO GANCHO DE LGICA Alm de todas as edies anteriores que eu j ilustrado, h uma srie de outros possveis problemas que voc deve estar ciente de quando se trata de ganchos de lgica. A seguir est uma lista de alguns desses itens: Lgica ganchos esto ligados s funes de baixo nvel aplicativo (tais como a recuperao de registros, gravar, salvar, etc.) e no para as aes de interface de usurio especfico no EditViews e DetailViews. Isso significa que voc no pode escrever um gancho de lgica que s est destinado a ser disparado em DetailViews. No entanto, todas as funes as aes de interface de usurio que usam as funes de baixo nvel de aplicativo, como salvar um registro ou recuperar um registro, sero acionado o gancho de lgica correspondente. Se a ao do usurio faz uma consulta direta no banco de dados (ou seja, no utilizando os mtodos de SugarBean) ento os ganchos de lgica correspondente no sero chamados. Em outras palavras, se voc adicionar que ganchos de uma lgica de before_save(), se o cdigo faz uma direta SQL INSERT na tabela subjacente, o gancho de lgica no vai ser chamado. melhor por motivos de portabilidade, usar sempre os mtodos de Save () e retrieve() de SugarBean, a menos que haja um especfico precisa desses mtodos no possvel endereo, mas tambm desde a no faz-lo ignora qualquer lgica de ganchos. Uma das causas mais simples para a lgica ganchos no trabalhar so problemas de permisses. Os arquivos de gancho de lgica (como qualquer arquivo personalizado na instncia) precisam ser lido pelo servidor web. melhor simplesmente manter o diretrio custom/ legvel em todos os momentos, s para evitar qualquer possvel problema aqui. Ganchos de lgica so um dos recursos mais poderosos do SugarCRM, mas tambm um dos que causam mais problemas no aplicativo para desenvolvedores. importante estar ciente de que esto metendo-se em projetar lgica ganchos e certifique-se de testar totalmente muitos diferentes casos de uso em que sua lgica ganchos so projetados segurar antes de implant-lo em qualquer ambiente de produo. RESUMO Neste captulo, voc aprendeu tudo sobre ganchos de lgica no SugarCRM, que so uma poderosa ferramenta para personalizar como muitos comportamentos diferentes na aplicao ocorrer. Voc primeiro olhou para os vrios tipos de ganchos de lgica oferecidos, e vi alguns exemplos de como us-los em ao, incluindo exemplos de adicionar lgica adicional antes e depois salva e quando carregar um registro em particular. Em seguida, voc viu o ponto e clique a maneira de fazer ganchos de lgica, que chamada de fluxos de trabalho. Fluxos de trabalho so uma ferramenta muito poderosa para aqueles sem muito conhecimento de programao para configurar os ganchos de lgica mais comuns facilmente usando uma interface muito fcil de seguir. Voc ento terminou o captulo olhando para todas as \"armadilhas\" de ganchos de lgica coisas que causam a usurios finais tristeza ao escrever-lhes e coisas para estar ciente de que poderia causar problemas abaixo da estrada. Construtor de mdulo e ganchos de lgica e fluxos de trabalho so mecanismos que so projetados em mente para desenvolvedores e usurios finais para ajudar a personalizar suas instncias. Mas s vezes eles no so suficientes, e voc precisar fazer alteraes mais detalhadas que essas ferramentas no podem manipular. No prximo captulo, voc vai fazer um mergulho profundo em muitas das outras personalizaes que esto disponveis para os desenvolvedores e como escrev-los de forma segura de atualizao para evitar problemas com futuros lanamentos e atualizaes. SUBSTITUIR O CDIGO EXISTENTE At este ponto, voc j olhou para maneiras de personalizar o SugarCRM usando as ferramentas de desenvolvimento padro, como estdio, fluxos de trabalho e lgica de ganchos. Essas ferramentas so geralmente consideradas a maneira mais fcil de personalizar o SugarCRM, pois a maneira mais comum e mais suportada para personalizar sua instncia. s vezes o SugarCRM no atinge o nvel de personalizao, que voc pode precisar. Talvez voc precise alterar alguns comportamentos padro do aplicativo, ou talvez as ferramentas GUI que voc olhou no captulo 6 apenas no fazem exatamente o que voc precisa. Neste ponto, a personalizao de nvel de cdigo realmente a nica opo. SugarCRM tem sido construdo e concebido com a antecipao de usurios que precisam personalizar suas instncias. Devido a isso, o SugarCRM tomou a abordagem de oferecendo aos desenvolvedores a capacidade, mas sem comprometer sua instalao como um todo. Neste captulo, voc vai olhar para essa capacidade e por sua vez, d uma olhada em muitas personalizaes de cdigo comuns que voc pode fazer no produto com facilidade. SEGURANA ENCONTRA-SE NO DIRETRIO PERSONALIZADO A maior dor para a personalizao de qualquer produto apoi-lo no futuro. Enquanto a verso que voc tem hoje pode atender s suas necessidades perfeitamente, se convincente de atualizaes e novas funcionalidades se tornam disponveis e voc deseja integr-los para trs em sua verso? Ou se a editora tem correes de bugs, patches de segurana e melhorias de desempenho? Com certeza voc iria querer integr-los por trs em sua aplicao local. Mas quando voc tiver personalizado a sua instncia, qual o impacto disto? Em muitos casos, os custos superam os benefcios, razo pela qual existem legies de aplicaes legadas pelo mundo (muitos em ambientes de misso crtica) que manter mescladas verses no mais suportados por seus fornecedores, causando dores de cabea interminveis para aqueles de sua manuteno. SugarCRM tomou a abordagem de permitir personalizaes de atualizao de segurana para o aplicativo, o que significa fornecer um mecanismo para personalizar sua instncia de tal forma que qualquer futuras atualizaes ou correes de manuteno no substituir as personalizaes. Para fazer isso, voc tem um diretrio custom/ na raiz do diretrio de instncia do Sugar, onde essas personalizaes podem ser feitas. Na maior parte, qualquer Sugar atualiza ou instala alteraes em nada neste diretrio. completamente o parque do desenvolvedor e reservado para a sua utilizao. A nica coisa , Sugar usa este diretrio ainda com as ferramentas de desenvolvedor do GUI (Studio, mdulo Construtor, etc.) tambm armazenam suas personalizaes aqui tambm e por isso durante uma atualizao, voc pode corrigir alguns dos arquivos criados por essas ferramentas. O layout deste diretrio geralmente corresponde a que da rvore principal do aplicativo, com a adio de alguns diretrios juntamente com o uso do Studio/mdulo Construtor; personalizaes e alguns que so construdas automaticamente nos metadados e vardef processos de construo. Tabela 8-1 detalha esses diretrios. Subdiretorio Descrio history/ Contm a histria de todos os EditViews, DetailViews, ListViews e pesquisas que so personalizadas por meio do estdio. modulebuilder/ Contm o cdigo do mdulo como construdo pelo construtor de mdulo (mais no mdulo construtor no captulo 9). modules/ Customizations made to the modules. This is where much of the MVC and metadata frameworks will look for customizations. Some customizations here are autogenerated from those made in the custom/Extension/modules/ directory, such as language string changes, subpanel customizations, menu changes (the one typically on the left sidebar), and Vardef changes. Extension/ Isto onde a fonte de muitas personalizaes so feitas. Eles sero recriados para odiretorio custom/modules/ e armazenados em cache ali. include/ Personalizaes para arquivos do diretorio include/ . themes/ Temas personalizados ou personalizaes feitas para temas que veio com o acar. Temas personalizados so considerados temas individuais em seu prprio direito, mas claro, podem ser estendidos de qualquer outro tema que pode ser selecionado por um usurio, enquanto personalizaes existentes temas realmente vo mudar esse tema. workflow/ Contm quaisquer fluxos de trabalho de nvel de aplicativo. working/ Legado usado pelo pr Studio 5.0. backup/ Legado usado pelo pr Studio 5.0. Qualquer coisa fora das estruturas de diretrio predefinido aqui tambm jogo justo. Digamos que voc tenha algumas bibliotecas caseiras que so utilizadas para interface em um sistema legado. Voc poderia adicion-los aqui em um subdiretrio, para que eles possam ser facilmente includos em quaisquer outras modificaes. Uma vez que todas as personalizaes so armazenadas inteiramente dentro do diretrio /custom e voc mesmo poder gerenciar todas as personalizaes atravs de um sistema de controle de fonte como Subversion ou Git. Esse mtodo garante que nenhuma das suas alteraes sero substitudas por um patch de atualizao ou manuteno de verso do SugarCRM. PERSONALIZAES QUE VOC PODE FAZER As liberdades do diretrio personalizado nos permitem personalizar as aes do fora-de-caixa no SugarCRM com facilidade atravs de muitos meios diferentes. Algumas personalizaes so feitas, simplesmente fornecendo arquivos alternativos para o que j existe no sistema, onde os arquivos de substituio tomam o lugar do que j est l. Outras personalizaes so adicionais, que significam tomam a definio existente e aplicar as alteraes que voc especificar para ele. Finalmente, algumas personalizaes fornecem uma nova funo a um mdulo onde ele no existia antes. O maior exemplo disso adicionando uma viso inteiramente nova para um mdulo. Uma vez que nem todas as personalizaes so feitas da mesma forma, melhor estar ciente de que voc est se metendo. O restante deste captulo vai passar por vrias personalizaes comuns que voc pode fazer em cdigo em Sugar e como fazer cada um deles. Vamos pular direito em com alter aes de exibio, se eles existem aes de exibio ou novos. ALTERAR A AES DE VISTA Aes de exibio so algumas das coisas mais simples para substituir atravs do diretrio personalizado. Voc aprendeu sobre estes no captulo 2, quando voc viu como as funes do framework MVC do Sugar. Por simplesmente inserir o arquivo de classe no diretrio custom/modulename/views/, o ViewFactory saber usar esse arquivo de exibio personalizada em vez do padro de um especificado pelo mdulo ou pelo aplicativo. Por padro, qualquer arquivo de ao de exibio definidos no diretrio custom/ ser usado em vez de um arquivo de ao de exibio est sendo definido no diretrio do mdulo ou a definio de exibio base definido no diretrio include/MVC/View/views/. A personalizao de views a mais fcil de se fazer, basta adicionar um novo modo de exibio. Se voc quer ter a personalizao aplicada somente a um mdulo, ento voc pode soltar os novos arquivos de exibio dentro do diretrio custom/modulename/views/. Listagem 8-1 mostra como adicionar uma nova viso para o mdulo de contas. Listagem 8-1. Contas mdulo personalizado view.quickinfo.php <?php require_once('include/MVC/View/SugarView.php'); class CustomAccountsViewQuickinfo extends SugarView{ public function __construct(){ parent::SugarView(); } public function preDisplay(){ if (empty($_REQUEST['record']){ sugar_die($GLOBALS['app_strings']['ERROR_NO_RECORD']); } if ( !$this->bean->ACLAccess('view') ) { ACLController::displayNoAccess(true); sugar_cleanup(true); } } public function display(){ echo <<<EOHTML <h2>{$this->bean->name}</h2> <p>{$this->bean->description}</p> EOHTML; } } O modo de exibio de Informao Rpida que voc definiu uma exibio somente leitura que mostra apenas o nome da conta e a descrio. Isso til se voc precisa apenas ver as notas sobre uma conta. Voc j fez algumas coisas aqui. Primeiro, voc definiu o mtodo de preDisplay() para verificar a existncia de identificao do registro sendo passada na URL. Se no existir, voc chamar sugar_die(). Voc tambm passou pela verificao de ACL para ver se o usurio tem acesso ao registro ou no. Finalmente, no mtodo display() voc far a sada real dos dados para o usurio. Em nome da brevidade, eu apenas codifiquei a sada em HTML, mas voc tambm poderia ter chamado um modelo Smarty. Voc pode acessar o objeto Smarty da view no SugarView::$ss varivel de membro. Voc precisa fazer outra coisa para se certificar de que sua view acessvel, que registr-la com a classe de SugarController. Voc viu duas maneiras diferentes de lidar com isso no captulo 2. O caminho mais elaborado a subclasse SugarController e adicionar a view l. No entanto, a maneira mais fcil (e a maneira recomendada; a menos que voc precise interpor lgica no controlador) dar incio a um new action view map inserindo o arquivo action_view_map.php dentro do diretrio custom/modulename/. A Listagem 8-2 mostra o arquivo do exemplo anterior. Listagem 8-2. arquivo action_view_map.php para a view QuickInfo do modulo personalizado de contas. <?php $action_view_map['quickinfo'] = 'quickinfo'; Uma vez que este (ou a subclasse do controlador acima mencionado) est no lugar, voc pode acessar o modo de exibio anterior diretamente do navegador usando o URL http://instancename/index.php?module=Accounts&action=quickinfo&record=recordid. A outra forma de personalizao de exibio substituir a ao de exibio bsica com suas prprias aes. Para este exemplo, voc usar o mdulo Bugs, substituindo a exibio de edio de Bugs. Voc vai estender a classe ViewEdit j que o mdulo de Bugs no define sua prpria subclasse de ViewEdit especfico (se o fizesse, voc estenderia em vez disso). Voc vai usar isso para ajudar a definir um valor padro encontrado no campo de lanamento, para o principal ativo de lanamento (conforme determinado pela configurao de campo list_order da tabela de lanamentos). Os registros da tabela de lanamentos so configurao no painel de administrao em lanamentos (Ver listagem 8-3). Listagem 8-3. Bugs mdulo EditView <?php require_once('include/MVC/View/views/view.edit.php'); class CustomBugsViewEdit extends ViewEdit{ public function __construct(){ parent::ViewEdit(); } public function display(){ if ( empty($this->bean->id) ) { $releaseFocus = new Release(); $releases = $releaseFocus->get_releases(TRUE, "Active"); $this->bean->found_in_release = array_shift(array_keys($releases)); } parent::display(); } } O exemplo anterior bastante simple. Voc apenas modificar o valor do Bean para o primeiro nome de liberao de ativos fornecido ao um novo Bug que voc est criando (voc sabe isso, verificando se o campo de identificao tenha sido definido ou no). O valor de retorno da funo $releaseFocus->get_releases() uma matriz associativa de id de lanamento, lanamento de pares de nome, ento voc usou o array_keys() para obter as chaves como uma matriz e o mtodo array_shift() para obter o primeiro item de matriz de item, que o primeiro id do lanamento ativo. Um problema que voc pode topar com personalizaes de views se h alteraes no Sugar de uma nova verso. s vezes um novo modo de exibio pode ser adicionado para ajudar a corrigir um bug no produto, onde seu novo modo de exibio personalizado pode ignorar isso. Portanto, antes de criar qualquer nova exibio personalizada que ir estender ou substituir um existente, voc deve verificar que no est faltando algo que tenha sido adicionado, uma vez que voc fez sua personalizao inicial. MUDANDO OS PONTOS DE VISTA ORIENTADA A METADADOS Os modos de exibio Editar e detalhe, no so totalmente necessrios alterar o cdigo de exibio para fazer modificaes. Muitas personalizaes podem ser feitas nos arquivos de metadados de definio. Voc aprendeu sobre a estrutura desses arquivos no captulo 3, e quais so as opes disponveis para voc como um escritor de mdulo para personalizar essas exibies. Voc pode usar todos os recursos que esto disponveis para personalizar a exibio como voc precisar. Para personalizar o modo de exibio voc precisa copiar o arquivo de metadados que voc deseja alterar para o diretrio custom/modules/modulename/metadata/. Este arquivo de metadados ser chamado, em seguida, em vez do original. Alm disso, certifique-se de ativar o modo de desenvolvedor nas configuraes do sistema no painel de administrao antes de fazer quaisquer personalizaes para esses arquivos, assim as alteraes sero apanhadas automaticamente. Um exemplo simples seria remover os campos de date_modified e date_created DetailView do mdulo mdulos notas. O arquivo detailviewdefs.php resultante seria parecido com o cdigo na Listagem 8-4. Listagem 8-4 Detailviewdefs.php arquivo de metadados personalizado para o mdulo de notas. <?php $viewdefs['Notes']['DetailView'] = array( 'templateMeta' => array( 'maxColumns' => '2', 'widths' => array( array('label' => '10', 'field' => '30'), array('label' => '10', 'field' => '30') ), ), 'panels' => array( array ( 'contact_name', array ( 'name' => 'parent_name', 'customLabel' => '{sugar_translate label=\'LBL_MODULE_NAME\'module=$fields.parent_type.value}', ), ), array( array( 'name' => 'contact_phone', 'type'=>'phone', 'label' => 'LBL_PHONE' ), ), array( array( 'name' => 'contact_email', 'label' => 'LBL_EMAIL_ADDRESS' ), ), array( array( 'name' => 'name', 'label' => 'LBL_SUBJECT' ), ), array( array( 'name'=>'filename', 'type'=>'file', 'displayParams'=>array( 'id'=>'id', 'link'=>'filename' ) ), ), array ( array( 'name' => 'description', 'label' => 'LBL_NOTE_STATUS' ), ), ), ); Por padro o DetailView ir mostrar trs botes na parte superior e inferior do formulrio (editar, duplicar e excluir) e o EditViews vai mostrar dois botes (salvar e cancelar), e pode tambm visualizar o boto View Change Log se o mdulo possui auditoria habilitado. Digamos que voc deseja adicionar a capacidade de procurar registros duplicados do EditView. Voc vai atualizar seu metadados para listar os botes que deseja ter na Listagem 8-5. Listagem 8-5 Editviewdefs.php personalizado arquivo para o mdulo de contatos com o adicionado encontrar duplicatas boto. <?php $viewdefs['Contacts']['EditView'] = array( 'templateMeta' => array( 'form'=>array( 'hidden'=>array( '<input type="hidden" name="opportunity_id" value="{$smarty.request.opportunity_id}">', '<input type="hidden" name="case_id" value="{$smarty.request.case_id}">', '<input type="hidden" name="bug_id" value="{$smarty.request.bug_id}">', '<input type="hidden" name="email_id" value="{$smarty.request.email_id}">', '<input type="hidden" name="inbound_email_id" value="{$smarty.request.inbound_email_id}">', ), 'buttons'=>array( 'SAVE', 'CANCEL', 'FIND_DUPLICATES', ), ), 'maxColumns' => '2', 'widths' => array( array('label' => '10', 'field' => '30'), array('label' => '10', 'field' => '30'), ), ), 'panels' =>array( 'lbl_contact_information' => array( array( array( 'name' => 'first_name', 'customCode' => '{html_options name="salutation" options=$fields.salutation.options selected=$fields.salutation.value} <input name="first_name" size="25" maxlength="25" type="text" value="{$fields.first_name.value}">', ), 'phone_work', ), array( array( 'name'=>'last_name', 'displayParams'=>array( 'required'=>true, ) ), 'phone_mobile', ), array( array( 'name'=>'account_name', 'displayParams'=>array( 'key'=>'billing', 'copy'=>'primary', 'billingKey'=>'primary', 'additionalFields'=>array( 'phone_office'=>'phone_work', ) ) ), 'phone_home', ), array( 'lead_source', 'phone_other', ), array( 'campaign_name', 'phone_fax', ), array( 'title', 'birthdate', ), array ( 'department', ), array( 'report_to_name', 'assistant', ), array( 'sync_contact', 'assistant_phone', ), array( 'do_not_call', ), array( 'assigned_user_name', ), ), 'lbl_email_addresses'=>array( array( 'email1', ) ), 'lbl_address_information' => array( array( array( 'name' => 'primary_address_street', 'hideLabel' => true, 'type' => 'address', 'displayParams'=>array( 'key'=>'primary', 'rows'=>2, 'cols'=>30, 'maxlength'=>150 ), ), array( 'name'=>'alt_address_street', 'hideLabel'=>true, 'type' => 'address', 'displayParams'=>array( 'key'=>'alt', 'copy'=>'primary', 'rows'=>2, 'cols'=>30, 'maxlength'=>150 ), ), ), ), 'lbl_description_information' => array( array( array( 'name'=>'description', 'displayParams'=>array( 'rows'=>6, 'cols'=>80 ), 'label'=>'LBL_DESCRIPTION' ), ), ), ) ); Todas as caixas de pesquisa em SugarCRM so trs colunas de largura por padro. Digamos que a maioria de seus usurios finais so utilizam telas pequenas ou realmente tem o desejo de manter suas telas em 800 600 (tive esta situao quando escrevi um app pequeno negcio para uma empresa anterior). Voc pode fazer um arquivo de searchdefs.php de ajuste simples para lidar com essa situao, alterando o atributo maxColumns na seo de templateMeta do arquivo. Listagem 8-6 mostra um exemplo de como isso ficaria se voc modifica-se o mdulo de contatos. Listagem 8-6 arquivo Searchdefs.php personalizado para o mdulo de contatos <?php $searchdefs['Contacts'] = array( 'templateMeta' => array( 'maxColumns' => '2', 'widths' => array('label' => '15', 'field' => '35'), ), 'layout' => array( 'basic_search' => array( 'first_name', 'last_name', 'account_name', array('name'=>'current_user_only', 'label'=>'LBL_CURRENT_USER_FILTER', 'type'=>'bool'), ), 'advanced_search' => array( 'first_name', array( 'name' => 'address_street', 'label' =>'LBL_ANY_ADDRESS', 'type' =>'name' ), array( 'name' => 'phone', 'label' =>'LBL_ANY_PHONE', 'type' => 'name' ), 'last_name', array( 'name' => 'address_city', 'label' =>'LBL_CITY', 'type' => 'name' ), array( 'name' => 'email', 'label' =>'LBL_ANY_EMAIL', 'type' => 'name' ), 'account_name', array( 'name' => 'address_state', 'label' =>'LBL_STATE', 'type' => 'name' ), 'do_not_call', 'assistant', array( 'name' => 'address_postalcode', 'label' =>'LBL_POSTAL_CODE', 'type' =>'name' ), array( 'name' => 'primary_address_country', 'label' =>'LBL_COUNTRY', 'type' =>'name', 'options' => 'countries_dom', ), 'lead_source', array( 'name' => 'assigned_user_id', 'type' => 'enum', 'label' =>'LBL_ASSIGNED_TO', 'function' => array( 'name' => 'get_user_array', 'params' =>array( false ) ) ), ), ), ); Outra modificao que voc pode querer fazer desativar a classificao para um mdulo. Alguns campos so campos impossveis classificar com o ListViews (todos os campos nondatabase, como campos calculados ou campos que vm de outros mdulos), ento voc definitivamente querer ter certeza que aqueles no devem ser classificados. Voc tambm poder bloquear a classificao por um determinado campo por motivos de desempenho, j que pode ser um recurso muito intensivo para o banco de dados para que voc no possa adicionar um ndice no campo no banco de dados. Para isso, voc s precisa adicionar o atributo classificvel e defini-lo como false para esse campo. Listagem 8-7 mostra um exemplo deste, que desativa a classificao por prioridade na ListView Bugs. Listagem 8-7 arquivo Listviewdefs.php modelo personalizado para o ListView de Bugs <?php $listViewDefs['Bugs'] = array( 'BUG_NUMBER' => array( 'width' => '5', 'label' => 'LBL_LIST_NUMBER', 'link' => true, 'default' => true ), 'NAME' => array( 'width' => '32', 'label' => 'LBL_LIST_SUBJECT', 'default' => true, 'link' => true ), 'STATUS' => array( 'width' => '10', 'label' => 'LBL_LIST_STATUS', 'default' => true ), 'TYPE' => array( 'width' => '10', 'label' => 'LBL_LIST_TYPE', 'default' => true ), 'PRIORITY' => array( 'width' => '10', 'label' => 'LBL_LIST_PRIORITY', 'sortable' => false, 'default' => true ), 'RELEASE_NAME' => array( 'width' => '10', 'label' => 'LBL_FOUND_IN_RELEASE', 'default' => false, 'related_fields' => array( 'found_in_release', ), 'module' => 'Releases', 'id' => 'FOUND_IN_RELEASE', ), 'FIXED_IN_RELEASE_NAME' => array( 'width' => '10', 'label' => 'LBL_LIST_FIXED_IN_RELEASE', 'default' => true, 'related_fields' => array( 'fixed_in_release' ), 'module' => 'Releases', 'id' => 'FIXED_IN_RELEASE', ), 'RESOLUTION' => array( 'width' => '10', 'label' => 'LBL_LIST_RESOLUTION', 'default' => false ), 'ASSIGNED_USER_NAME' => array( 'width' => '9', 'label' => 'LBL_LIST_ASSIGNED_USER', 'default' => true ) ); Existem muitos mais personalizaes possveis ajustando o arquivo de metadados. A personalizao mais comum feita por meio de arquivos de metadados personalizar a exibio de campo, que pode ser feita atravs do atributo de 'customCode' de cada campo. Tambm em ListViews, voc pode substituir o mtodo get_list_view_data() da classe do bean do mdulo para alterar como o valor de um campo e exibido no ListView. s vezes voc quer que as mesmas alteraes feitas cada vez que um tipo de campo usado. Voc pode fazer isso modificando esse campo, como voc ver a seguir. ADIO DE NOVOS TIPOS DE CAMPO PERSONALIZADO O Sugar vem com muitos tipos de campo diferentes por padro que lidam com praticamente todos os diferentes tipos de campos que voc pode quiser, desde caixas de entrada padro para listas de seleo. Isso no significa que pode haver um tipo diferente de campo, que poder estar disponvel para uso em toda a instncia do Sugar. Ou talvez voc precise ajustar uma especificao de campo existente para lidar com algum outro tipo de parmetro ou exibi-lo de forma diferente para o usurio. Os SugarFields so personalizveis em ambos os sentidos, dando-lhe como um desenvolvedor um pouco de alavancagem em Personalizar como campos olham e trabalham em sua instncia do Sugar. A melhor coisa a fazer personalizar como um campo exibido. Voc pode fazer isso por muitas razes diferentes. Por exemplo, voc pode no gostar da maneira que voc exibir campos, ento voc pode querer mud-lo para exibir o que voc quer. Por exemplo, o campo do arquivo (o que representa um arquivo carregado) apresenta apenas uma caixa de entrada de arquivo pronta para que voc selecione o arquivo que voc est carregando. Ele no indica se um arquivo j foi carregado, assim voc no sabe se deve substitu-lo. Para fazer isso, voc pode fazer algumas mudanas para a definio de campo. Primeiro, voc vai exibir o nome do arquivo carregado logo abaixo do arquivo, assim voc vai copiar o arquivo de template include/SugarFields/Fields/File/EditView.tpl para custom/include/SugarFields/Fields/File/EditView.tpl e fazer suas modificaes para o modelo, como mostrado na Listagem 8-8 Listagem 8-8 Arquivo de modelo EditView de arquivo personalizado <input id="{{sugarvar key='name'}}" name="{{sugarvar key='name'}}" type="file" title='{{$vardef.help}}' size="{{$displayParams.size|default:30}}" {{if !empty($vardef.len)}}maxlength='{{$vardef.len}}'{{elseif !empty($displayParams.maxlength)}}maxlength="{{$displayParams.maxlength}}" {{else}}maxlength="255"{{/if}} value="{$fields[{{sugarvar key='name' stringFormat=true}}].value}" {{$displayParams.field}}> <br />{$fields[{{sugarvar key='name' stringFormat=true}}].value} Voc vai notar em alguns lugares na Listagem 8-8 voc usam colchetes duplos ({{) versus nico ({}). Isso ocorre porque a maioria dos modelos Smarty controlados por metadados construdo em duas passagens. O passo um puxa todos os modelos de campo para os principais modelos e, em seguida, salva-o no diretrio de cache, assim ele no precisa reconstrur a cada vez. Passo dois enche os valores de dados reais que sero mostrados ao usurio no modelo final construdo. Esta passagem feita em cada solicitao. No anterior, voc simplesmente adicionou ao modelo existente uma quebra de linha e, em seguida, o valor de seqncia de caracteres do campo determinado. De agora em diante, quando voc usar um arquivo de SugarField em qualquer EditView, a definio de widget acima ser usada em vez do padro um. Digamos que voc quer que isso de um passo em frente tendo um tipo de campo de arquivo que permite apenas que voc inicialmente transfira o arquivo, mas no nunca mud-lo. Esse comportamento semelhante ao funcionamento do mdulo de documentos com o tipo de arquivo SugarField. Para fazer isso, voc vai estender o tipo de campo de arquivo em um novo tipo de campo voc vai chamar Filereadonly. Voc vai criar este campo no diretrio personalizado sob custom/include/SugarFields/Fields/Filereadonly/. Em seguida, voc vai comear a definir o tipo de campo. A primeira parte deste tipo de campo criar a classe child de SugarField para o widget, ento voc sabe herdar todas as aes de tipo de arquivo SugarField (consulte a listagem 8-9). Listagem 8-9 Child Classe personalizada Filereadonly SugarField <?php require_once('include/SugarFields/Fields/File/SugarFieldFile.php'); class SugarFieldFilereadonly extends SugarFieldFile{ public function save(&$bean, $params, $field, $properties){ if(!empty($bean->id) && isset($_REQUEST[$field])){ unset($_REQUEST[$field]); } return parent::save(bean, $params, $field, $properties); } } Listagem 8-9, voc v o uso do mtodo Save() em uma subclasse de SugarField. Isso chamado durante a parte de pre_action() do salvar vista chamada em SugarController em cada campo para aplicar qualquer necessrio transformao antes de realmente salvar os dados de campo. Nesse caso, voc vai us-lo para limpar qualquer valor passado para esse campo se voc no estiver criando um novo registro, preservando assim a sua inteno original de no permitir que o arquivo carregado especificado para ser alterado. A prxima parte dessa personalizao envolve retrabalhar o modelo EditView para exibir o widget correto para o usurio, como mostrado na Listagem 8-10. Listagem 8-10 Arquivo Filereadonly EditView modelo personalizado {if $id == ''} <input id="{{sugarvar key='name'}}" name="{{sugarvar key='name'}}" type="file" title='{{$vardef.help}}' size="{{$displayParams.size|default:30}}" {{if !empty($vardef.len)}}maxlength='{{$vardef.len}}'{{elseif !empty($displayParams.maxlength)}}maxlength="{{$displayParams.maxlength}}" {{else}}maxlength="255"{{/if}} value="{$fields[{{sugarvar key='name' stringFormat=true}}].value}" {{$displayParams.field}}> {else} {$fields[{{sugarvar key='name' stringFormat=true}}].value} {/if} A Varivel $id definida por padro para todos os EditViews. Especificar o id do registro para o registro atual. Voc pode usar essa varivel para acionar o que fazer quando chegar este widget de campo. Se nenhuma identificao definida, ento voc assumi isso como sendo um novo registro, para que voc exiba uma caixa de entrada do arquivo para o usurio para eles localizarem e carregarem o arquivo de seu sistema de arquivos local. Se no existir um id de registro, voc pode, em seguida, no permitir que um arquivo seja carregado, ento voc apenas ir exibir o nome do arquivo que j foi carregado, permitindo nenhuma alterao do usurio. Para usar esta widget em vez de um arquivo normal, altere o atributo de 'tipo' de vardef do campo para 'filereadonly'. Uma questo, que voc pode topar com classes personalizadas nas sees restantes do produto, tais como ListViews e relatrios, que usam o tipo mais antigo de widget conhecido como o SugarWidget para exibir os dados em vez do objeto de SugarField mais comum, que utilizado praticamente em qualquer outro lugar. Nesses casos, voc vai querer definir o atributo de 'dbType' da definio do campo para um dos tipos mais internos, como varchar, assim um SugarWidget vlido pode ser usado se o campo usado nessas reas do produto. Esta uma rea que deve ser limpada em uma verso futura do SugarCRM, assim voc no vai exigir isso adicionando o arquivo de vardefs.php para o mdulo. ALTERAR AS SEQNCIAS DE CARACTERES DE IDIOMA Uma personalizao muito comum de voc ver (e como ele acontece, uma muito simples de fazer) personalizar as sequencias de caracteres de idiomas que so usadas em todo o produto. Voc viu no captulo 6, que voc pode fazer algumas dessas personalizaes no prprio Studio, mas s vezes eles so muito mais simples de personalizar o direito no prprio cdigo. Existem trs tipos de seqncias de caracteres de idioma no SugarCRM: app_strings: Estas so seqncias de caracteres pode ser usado em qualquer lugar no aplicativo. mod_strings: Estas so seqncias de caracteres que so especficas para uma determinada seo do aplicativo. app_list_strings: Estas so arrays associativos, que so frequentemente utilizados para campos como enums ou multienums. Cada tipo de seqncia de caracteres de idioma personalizado de forma diferente. Para app_strings e app_list_strings, voc pode adicionar as alteraes de seqncia de caracteres para o custom/include/language/en_us.lang.php ou custom/application/Ext/Language/en_us.lang.ext.php. Qualquer localizao ser analisada para alteraes de seqncia de caracteres. Por exemplo, voc deseja alterar as opes de status do Bug para ter mais algumas opes e alterar o texto em alguns deles. Voc vai adicionar uma nova opo reaberta, bem como alterar a seqncia de exibio para nova recm criada. Listagem 8-11 mostra o que voc precisa adicionar o arquivo para que isso acontea. Listagem 8-11 arquivo personalizado En_us.lang.php atualiza a chave de bug_status_dom na app_list_strings $app_list_strings['bug_status_dom']['New'] = 'Newly Created'; // was 'New' $app_list_strings['bug_status_dom']['Reopened'] = 'Reopened'; // new entry O outro arquivo de seqncia de caracteres de nvel de aplicativo principal pode ser atualizado da mesma forma, adicionando-se as seqncias de caracteres que voc deseja atualizar no mesmo arquivo. melhor manter as alteraes dentro do arquivo custom/include/language/en_us.lang.php, desde que o arquivo custom/application/Ext/Language/en_us.lang.ext.php seja normalmente usado para mudanas de seqncia de caracteres no estdio. Tambm Observe que quaisquer alteraes feitas no arquivo custom/include/language/en_us.lang.php so feitas aps aquelas no arquivo custom/application/Ext/Language/en_us.lang.ext.php, ento check-in o arquivo antigo se suas alteraes de estdio no esto tornando-se disponveis para o usurio. Seqncias especficas para o mdulo (acima referido como mod_strings) so mantidas no interior de cada mdulo e s esto disponveis dentro desse mdulo. Para personaliz-los, voc pode soltar o arquivo en_us.lang.php no diretrio custom/modules/modulename/language/. Personalizaes para o mod_strings trabalham as mesmas para o a app_strings e app_list_strings, como visto na Listagem 8-12, que mostra como substituir algumas seqncias de caracteres no mdulo de Bugs. Listagem 8-12 arquivo personalizado En_us.lang.php atualizar alguns mod_strings para o mdulo de Bugs $mod_strings['LBL_SOURCE'] = 'Defect Source:'; // was 'Source' $mod_strings['LBL_PRODUCT_CATEGORY'] = 'Product Category:'; // was 'Category' Voc j vem direcionando que seu idioma de correes para o pacote de idioma ingls americano padro. Usando-se a outras marcas de linguagem IETF no lugar de en_us, voc pode ajustar as seqncias de caracteres de qualquer pacote de idioma que voc est usando com sua instncia do Sugar. Digamos que voc instalou o pacote de idioma francs de SugarForge e voc precisa ajustar algumas strings no mdulo de chamadas. Basta soltar o arquivo de fr_FR.lang.php mostrado na Listagem 8-13 no diretrio custom/modules/Calls/language/ e voc estar pronto para ir. Listagem 8-13 Arquivo personalizado fr_FR.lang.php alguns mod_strings de atualizao para o mdulo de chamadas. $mod_strings['LBL_SUBJECT'] = 'Appel Sujet:'; // was 'Sujet:' $mod_strings['LBL_CONTACT_NAME'] = 'Appel Contact:'; // was 'Contact:' Voc pode ver que alterar as seqncias de caracteres de idioma ao redor tambm um exerccio muito simples. Vamos agora tentar modificar alguns dos arquivos vardef.php. AJUSTAR DEFINIES DE VARDEF Como voc aprendeu no captulo 2, arquivos vardef definem a estrutura e especificaes dos campos usados dentro de qualquer mdulo determinado na URL. Na maioria das vezes, os padres de determinados funcionam conforme o esperado uma forma comum de contornar quando no adicionar um campo personalizado para substituir o campo ofensivo. Se voc no est com medo de ficar um pouco "baixo e sujo" com o prprio cdigo, ficando longe dos limites seguros do Studio, voc pode ajustar os campos para trabalhar da maneira que desejar. Vejamos alguns cenrios comuns que so fceis de mudar atravs de personalizaes de vardef. Cada uma dessas personalizaes deve ser salvos em um arquivo com a extenso. php no diretrio custom/Extension/modules/modulename/. Digamos que voc quer ter certeza de que todo mundo quando importar Bugs realmente indique que a liberao do bug ocorreu quando o mesmo foi corrigido. Listagem 8-14 mostra o caminho aqui definindo o atributo importvel para o campo necessitado. Listagem 8-14 Definindo o atributo importvel para os campos de Bugs. $dictionary['Bug']['fields']['fixed_in_release']['importable'] = 'required'; $dictionary['Bug']['fields']['found_in_release']['importable'] = 'required'; Outra situao que voc pode querer habilitar a pesquisa por um campo adicional na busca global. Esta pesquisa aquele que normalmente o cabealho do aplicativo e projetado para ser uma ferramenta facilmente procurar registros com base em determinada seqncia de caracteres em um ou mais mdulos por vez. Mdulos podem ser includos nessa busca, adicionando o atributo 'unified_search' definido como true na raiz da matriz $vardef para um mdulo, e pode ser adicionado um campo individual, definindo tambm o mesmo atributo 'unified_search' para true, o campo de definio. Listagem 8-15 mostra um exemplo de como voc pode adicionar habilitado pesquisando no campo contact_name quando voc incluir o mdulo de chamadas na pesquisa global. Listagem 8-15 Definindo o atributo unified_search para True o campo do mdulo Calls $dictionary['Call']['fields']['contact_name']['unified_search'] = true; Voc tambm pode definir novos ndices tambm. til para defini-los aqui em vez de apenas adicion- los para o banco de dados, para que eles possam facilmente reparar o banco de dados mais tarde se necessario sem perder os ndices adicionados no processo. Para fazer isso, voc pode apenas adicionar a definio de ndice como uma matriz para a definio de vardef para o mdulo, um exemplo mostrado na Listagem 8-16, onde voc pode adicionar um ndice em id + nome + reference_code para o mdulo de contratos. Listagem 8-16 Adicionando um novo ndice para o mdulo de contatos $dictionary['Contract']['indices'][] = array( 'name' => 'idx_contract_id_name_refcode', 'type' => 'index', 'fields' => array('id', 'name', 'reference_code') ); Para adicionar esta mudana para seu mdulo, voc pode adicion-los dentro do diretrio custom/Extension/modules/modulename/Ext/Vardefs/ com qualquer nome de arquivo de sua escolha. Voc pode adicionar arquivos como voc quiser aqui tambm, o que til, pois permite que voc como um desenvolvedor agrupe suas personalizaes de vardef em diferentes arquivos para melhor organizao de seu cdigo. TEMAS PERSONALIZADOS E PERSONALIZAES DO TEMA (SIM, ELES SO DIFERENTES) No captulo 5, o novo framework de temas que foi adicionado Sugar 5.5 foi mencionado. Um recurso muito til e muito aguardado isso utilizar o diretrio personalizado para personalizaes do tema. Personalizaes de tema so muito teis, pois permitem que os desenvolvedores alterem a aparncia de sua instncia Sugar para coincidir com o que seus usurios gostam ou esperam do visual do aplicativo. At 5.5 do Sugar, esta tem sido uma modificao de segurana que no bem Atualizao, uma vez que basicamente copiando um dos temas para fora-de-caixa, mudando os elementos que voc deseja alterar, e ento mant-la ao longo de todas as atualizaes ou patches para Sugar, eles podem exigir que voc altere suas personalizaes mo para obter o novo bug e segurana fixa neles. Com Sugar 5.5, voc criou um tema padro que tem todos os elementos necessrios para qualquer tema pronto para ir, e agora permitem que os desenvolvedores basear quaisquer novos temas fora de temas existentes no produto. Alm disso, voc tambm pode fazer personalizaes simples e faceis para os temas includos, no caso de voc no gostar o que foi escolhido por padro. Vamos comear com o tipo mais fcil de personalizao. No caso, a imagem usada para uma parte especfica do aplicativo que voc pode no gostar, basta inserir uma imagem de mesmo nome no diretrio personalizado para esse tema > se voc quiser substituir a imagem de Accounts.gif voc iria criar sua verso no arquivo custom/themes/themename/images/Accounts.gif. O novo arquivo ser ento apanhado sem alteraes de cdigo necessrio: A nica coisa que voc pode ter que fazer limpar a cache temas atravs da opo Admin > Repair > Clear Theme Cache. Voc tambm pode especificar para substituir a imagem padro usada em todos os temas para esta imagem por deix-la substituir o arquivo custom/themes/default/images/Accounts.gif em vez disso. Uma outra coisa para certificar-se que o nome do arquivo o mesmo tipo que o original. Digamos que voc um grande f de imagens png e deseja usar um arquivo png em vez do arquivo gif aqui. No tem problema, apenas o nome do arquivo custom/themes/themename/images/Accounts.png e ele ir substituir o arquivo original themes/themename/images/Accounts.gif ou themes/default/images/Accounts.gif. Voc tambm pode substituir em arquivos terminando em jpg, bmp ou TIF tambm, dando-lhe mais opes no fornecimento de tipos de imagem; a ordem marcada para arquivos gif, png, jpg, tif e bmp. O outro tipo de personalizao que voc pode fazer dentro CSS usado em exibindo o contedo ao usurio. Estes so especificados no arquivo custom/themes/themename/css/style.css e sero adicionados aps os arquivos original de estilo do tema. Personalizaes JavaScript podem ser feitas de forma semelhante tambm soltando o arquivo style.js dentro do custom/themes/themename/js/ existentes de diretrio, o que permitir que ele seja adicionado a qualquer cdigo javascript fornecido pelo tema. Com estas ferramentas disponveis, personalizar um tema para uso em sua instncia um piscar de olhos. Mas digamos que voc no deseja substituir um dos temas existentes, mas realmente fazer um novo tema baseado nela. Isto uma tarefa simples; Basta fazer um novo diretrio custom/themes/newthemename/ e adicionar um arquivo de themedef.php a ele semelhante listagem 8-17. Listagem 8-17 arquivo de themedef.php para um novo tema personalizado SugarCustom <?php $themedef = array( name => "SugarCustom", // theme name description => "Sugar Custom Theme", // short description of the theme parentTheme => "Sugar", // name of the theme this theme inherits from, if something other than the default theme. ); Voc especificou que o nome do seu novo tema ser SugarCustom, para que este arquivo ser localizado no diretrio custom/themes/SugarCustom/, que conter tambm todas as imagens, arquivos css e javascript que sero personalizados para definir este tema. O principal atributo do arquivo de definio do tema o item de parentTheme. Isso indica que tema voc deseja herdar. Se voc no especificar um tema existente no produto aqui, ento voc apenas receber o padro tema css, javascript e imagens, que podem ser um bom comeo, se nenhum outro tema perto o que voc deseja construir. RESUMO Neste captulo que voc aprendeu sobre todo o tipo de personalizaes, voc pode fazer para sua instncia do Sugar atravs de cdigo. Voc aprendeu sobre o diretrio personalizado, que detm todas as personalizaes que voc pode fazer no produto e viu onde voc fara diferentes tipos de personalizaes. Voc, em seguida, deu uma olhada em alguns exemplos comuns de personalizao, como personalizar vistas, metadados, vardefs, pacotes de idioma e temas. Neste ponto, no livro, voc j sabe como tirar uma instncia do Sugar e personaliz-lo para trabalhar e olhar como voc gostaria que ele. Chegando na prxima seo do livro que voc vai aprender como construir novos mdulos em cima do Sugar para lidar com diferentes tipos de dados, que voc poder gerenciar com ele. USANDO O CONSTRUTOR MDULO PARA CONSTRUIR MDULOS PERSONALIZADOS Neste ponto do livro, voc j sabe sobre o que faz SugarCRM, desde coisas grandes como a camada MVC framework, a camada de metadados e Web Services para os itens menores, como autenticao de usurio e Dashlets. Aps esse estudo aprofundado do Sugar, voc ento olhou como personalizar o Sugar fora da caixa. Comeamos mostrando a ferramenta Studio fcil de usar que permite personalizar as vistas de metadados por meio de um ponto na interface do sistema. Ento vimos como interpor a lgica de negcios em seu aplicativo atravs do uso de ganchos de lgica e como interpor lgica comum em seu aplicativo usando fluxos de trabalho, que fornecem um ponto e clique em caminho para os no-programadores entre ns para adicionar lgica de negcios tambm. Se nenhum desses opes para personalizao faz o trabalho, ento voc viu como personalizar vrias outras reas do aplicativo de visualizaes e metadados para tipos de campo e temas. E se esse nvel de personalizao no suficiente para suas necessidades? CRM no uma soluo de "tamanho nica", so peas exatas para incluir e excluir e no partes concretas. CRM pretende ser uma ferramenta para aumentar sua produtividade, para tudo o que voc precisa fazer que, por isso de suma importncia, se adicionar novas peas ou alterar ou remover as existentes. Esta a razo principal por trs as ferramentas de personalizao fortemente discutidas na parte 1, bem como o que voc ver aqui na parte 3 sobre a adio de novos mdulos para o Sugar. Neste captulo, voc olhar para construtor mdulo. O Mdulo Builder uma ferramenta de GUI para construir um mdulo que pode ser usado dentro de sua instncia do Sugar, ou exportado para ser instalado em outras instncias de Sugar. Ele tem uma aparncia muito semelhante ao estdio, com o qual mdulo Construtor compartilha um monte de cdigo. Vamos em frente e ir direto para aprender como tudo funciona. GETTING STARTED Como mencionado, o mdulo Builder uma ferramenta de GUI que compartilha a mesma aparncia do Studio, que voc viu anteriormente no captulo 6. Voc pode obter a ele no painel de Admin, clicando no link do mdulo Construtor na seo de ferramentas do desenvolvedor. Uma vez que voc clicar nesse link, voc ver a tela mostrada na Figura 9-1.
FIGURA 51 - DEFAULT MODULE BUILDER SCREEN O Mdulo Construtor organiza coisas em unidades chamadas de pacotes, cada um deles pode conter um ou mais mdulos. A razo para esta abordagem porque na maioria das vezes voc est projetando uma soluo completa, que envolve muitos mdulos que funcionam em conjunto com os outros para preencher uma necessidade, ao invs de apenas um mdulo simples. Para criar um novo mdulo, voc precisa primeiro criar o pacote que ir cont-lo, ento voc vai clicar no link novo pacote mostrado na Figura 9-1, que vai trazer o novo pacote de formulrio mostrado na Figura 9-2.
FIGURA 52 - MODULE BUILDER NEW PACKAGE DIALOG Este formulrio usado para inserir os detalhes do pacote que voc est construindo. Voc vai definir o nome do seu pacote para MyNewPackage (deve ser alfanumrico, sem espaos) e colocar em meu nome (John), para o autor do pacote. O valor de chave usado para prefixar cada um dos nomes de objeto do mdulo para ajudar a garantir que os nomes de mdulo no interferir em outro mdulo, bem como oferecer uma maneira fcil de identificar na estrutura de diretrio que mdulos acompanham o pacote. Se voc construir um novo mdulo chamado co, em seguida, afigura-se como pack_dog na estrutura de diretrio (que seria o nome de mdulo). Voc tambm pode adicionar uma descrio para o pacote opcionalmente, bem como um arquivo Leiame, que exibido para o usurio quando ele instalado atravs de carregador de mdulo. Voc ver que quando voc realmente instalar o mdulo personalizado usando o carregador de mdulo. Aps clicar em salvar no form da Figura 9-2, o novo pacote ser criado e voc vai ficar na pgina principal do pacote, conforme mostrado na Figura 9-3.
FIGURA 53 - MAIN SCREEN IN MODULE BUILDER OF A PACKAGE Voc notar que a coluna mais esquerda na Figura 9-3 mostra agora seu pacote na listagem de pacotes. Isto onde voc vai basear todas as suas aes novas no pacote, e onde voc pode comear a criar um novo pacote, que voc ver como fazer na prxima seo. PROJETANDO UM NOVO MDULO Uma vez que voc tenha um pacote criado, voc pode ento adicionar um novo mdulo para ele. Para fazer isso, voc vai clicar no link de novo mdulo na tela principal do seu pacote (mostrado na Figura 9-3), que vai trazer o formulrio mostrado na Figura 9-4.
FIGURA 54 - CREATE NEW MODULE SCREEN IN MODULE BUILDER Voc comea pela nomeao de seu novo mdulo, dando-lhe um nome interno no nome do campo do mdulo, que usado para se referir a seu mdulo no cdigo, bem como um nome de exibio do seu mdulo, que como os usurios finais se referiro ao seu mdulo. Neste ponto, voc tem mais algumas opes para este mdulo: Importao: isso permite que a ferramenta de importao do Sugar importe dados para o mdulo. Segurana da equipe: Marque este item se desejar obter segurana no seu mdulo, o que significa que voc pode atribuir os registros do presente mdulo para uma ou mais equipas e restringir o acesso aos registros que so baseadas em qual time o usurio faz parte da equipe. Guia de navegao: Marque este item se desejar que o mdulo exibido na aba de navegao que geralmente na parte superior da tela com todos os outros mdulos disponveis. A principal razo que voc no iria querer essa opo marcada se o mdulo um submdulo de outro mdulo, onde voc no gostaria que as pessoas normalmente tm acesso direto a ele. Agora voc pode selecionar o tipo de mdulo que voc deseja criar. Estas so as mesmas escolhas que voc viu para modelos SugarObject no captulo 2, mas eu esboarei-los novamente para sua referncia na tabela 9-1. Tipo do Mdulo Descrio basic Um modelo bsico com apenas os campos de nome e descrio, alm desses campos "nos bastidores", como id, a flag de excludos e timestamps criado/modificado. Este modelo destina-se a ser base de todos os modelos a seguir enumerados. company Campos que seriam usados normalmente com uma empresa, como nome, endereo, telefone, site ou indstria. Ele tambm contm os campos no modelo bsico. file Usado quando o objeto armazena os arquivos que o usurio carrega. Ele tambm contm os campos no modelo bsico. issue Para a modelagem de um problema ou o emprego de sistema de rastreamento. Ele tambm contm os campos no modelo bsico. person Campos que representam uma pessoa, como nome, endereo, telefone ou e-mail. Um novo recurso do Sugar 5.5 que este mdulo ir automaticamente dar aos usurios a capacidade de importar e exportar vCards no mdulo. Ele tambm contm os campos no modelo bsico. sale Usado quando o objeto para transaes de vendas ou previso. Ele tambm contm os campos no modelo bsico. Depois de ter tudo do jeito que voc quiser, clique em salvar e seu mdulo ser criado. Voc ser direcionado para a tela principal do mdulo recm-criado, conforme mostrado na Figura 9-5.
FIGURA 55 - MAIN SCREEN FOR A MODULE WITH A PACKAGE IN MODULE BUILDER Com isso, voc criou um novo mdulo. Mas seu mdulo um pouco chato neste ponto, porque apenas os padres so definidos por ele. Vamos comear adicionando novos campos, o que voc vai aprender sobre na prxima seo. FIELDS A primeira coisa que a maioria das pessoas quer fazer quando projetam um mdulo adicionar os campos que o mdulo precisa. Esta uma tarefa fcil de realizar. Voc s precisa clicar no boto exibir campos na tela principal do mdulo (mostrado na Figura 9-5) e voc estar na tela de campos para o mdulo, mostrado na Figura 9-6.
FIGURA 56 - FIELDS SCREEN FOR A MODULE IN MODULE BUILDER A seo superior lista os campos que so especficos para o mdulo que voc criou. Cada seo representa os campos que so herdados de outros SugarObjects, ento para o mdulo anterior de pessoa que tem a segurana equipe de ativada voc vai herdar campos a pessoa Assignable, equipe de segurana e os modelos bsicos. Se voc escolher um tipo de mdulo diferente quando voc criou o mdulo na seo anterior (ou decidiu desativar segurana de equipe), voc teria uma lista diferente de campos herdado. Na Figura 9-6, voc no tem nenhum campos atualmente definidos especificamente para este mdulo. Para alterar isso, clique no boto Adicionar campo e voc ser capaz de adicionar um novo campo utilizando o ecr que mostrado na Figura 9-7.
FIGURA 57 - CREATE FIELD SCREEN FOR A MODULE IN MODULE BUILDER Esta a mesma caixa de dilogo, discutida no captulo 6 adicionando campos personalizados no estdio. Alterar os dados tipo vai mudar as entradas que so dadas na forma, igualzinho como funcionava no estdio tambm. Uma diferena do Studio que o campo que voc cria no ter o sufixo optimistas aplicado, desde que o campo de resultado no um campo personalizado, mas um campo real do mdulo. Este campo tambm, ser armazenado na tabela primria para o mdulo e no ser um auxiliar depois de instalar o mdulo, ao contrrio de como funciona o estdio. Uma vez que voc clicar em salvar o campo ser adicionado e a listagem de campo ser atualizada, conforme mostrado na Figura 9-8.
FIGURA 58 - TELA DE CRIAO DE CAMPO PARA UM MDULO NO MDULO CONSTRUTOR Enquanto voc no pode alterar qualquer uma das propriedades dos campos herdadas de outros SugarObjects, voc pode personalizar os rtulos dos campos que so exibidos para o usurio final. Isso poderia ser til se voc quiser redirecionar esses campos para suas prprias necessidades, ou mesmo se a descrio de determinado no a mesma terminologia que o usurio final estaria familiarizado. Em ambos os casos, voc pode alterar os rtulos de campo de duas maneiras: voc pode editar um campo individual, clicando sobre o nome do campo no menu principal do mdulo (mostrado na Figura 9-9) ou clicando os botes editar etiquetas e alterar os rtulos em questo, conforme mostrado na Figura 9-10.
FIGURA 59 - EDITAR O RTULO DE UM CAMPO HERDADO
FIGURA 60 - EDIO DE TODOS OS RTULOS DE UM MDULO Os benefcios de usar a ltima opo (todos os campos de edio ao mesmo tempo) que voc tambm pode editar os rtulos utilizados em outros pacotes de idiomas tambm ao mesmo tempo, como voc poderia em estdio. Isso ocorre porque usando a ltima opo edita a definio para as seqncias de caracteres de padro ao editar o ttulo do campo sobre as mudanas de tela de campos que definio de seqncia de caracteres usada para o campo. Agora que voc tem seus campos para seu mdulo, voc pode personalizar o layout para as diferentes formas de metadados utilizados. METADATA Voc aprendeu no captulo 3, sobre as virtudes dos metadados e como eles facilitam a criao de views de interao de dados primrios do seu mdulo de forma muito padronizada. Assim como o Studio, voc tambm pode editar esses modos de exibio do mdulo Builder tambm. Para isso, basta clicar sobre o link de Layouts de visualizao na tela principal do mdulo, que vai lanar a tela de layouts do mdulo, como mostrado na Figura 9-11.
FIGURA 61 - TELA DE LAYOUT DO MDULO NO MDULO CONSTRUTOR Voc pode clicar em qualquer um dos links na tela mostrada na Figura 9-11 para personalizar o modo de exibio em questo. No mdulo Construtor, assim como em estdio, voc pode adicionar ou remover qualquer um dos campos do formulrio e ajustar a posio e agrupamento na tela. Voc no pode alterar qualquer um dos botes no topo da tela (que deve ser feito manualmente). Para personalizar o EditView para seu mdulo, voc pode clicar no link de EditView, que lana a tela mostrada na Figura 9-12.
FIGURA 62 - EDIO DO MDULO NO MDULO CONSTRUTOR - EDIO DE VISUALIZAO Voc vai se lembrar do captulo 6 que esta tela muito fcil de usar, porque voc pode arrastar e soltar campos pretende adicionar ou remover de forma facilmente usando-se a rica interface AJAX. O formulrio funciona identicamente para como funciona no estdio. Voc pode adicionar novas linhas ou painis para o formulrio e adicionar e remover os campos que desejar. Quando voc tem a forma do jeito que voc quiser, basta clicar em salvar. Voc pode editar o ListView, bem como, apenas como voc fez no Studio (consulte a Figura 9-13). Este formulrio permite que voc especifique dois campos padro para mostrar no ListView alm os campos que esto disponveis, em geral, bem como dando uma ordem de campo padro para os campos no ListView.
FIGURA 63 - EDIO DE UM LISTVIEW NO MDULO CONSTRUTOR Novamente, o formulrio de pesquisa, edio de obras como ele fez em estdio. Aqui voc lista apenas os campos que esto disponveis a serem pesquisados no painel de pesquisa escolhido, se o bsico ou avanado. Eles ento so dispostos em ordem da parte superior do primeiro elemento do formulrio para o fundo do ltimo elemento do formulrio, tudo em trs colunas.
FIGURA 64 - EDIO DO PAINEL DE PESQUISA BSICA NO MDULO CONSTRUTOR Uma coisa adicionais para editar o dashlet criado automaticamente para o mdulo. Dashlets so a ferramenta que voc aprendeu sobre o captulo 5 que permitem que a voc exibir informaes sobre um mdulo ou qualquer outra parte do sugar na pgina inicial para referncia rpida e fcil. O que criado pelo mdulo Construtor dashlet o tipo de ListView, para que voc tenha duas partes dele disponvel para personalizao. A primeira parte os campos que aparecem na ListView propriamente dito. Voc ter um editor de ListView disponvel, como mostrado na Figura 9-15.
FIGURA 65 - EDITOR DE DASHLET LISTVIEW NO MDULO CONSTRUTOR A outra parte que voc pode personalizar os campos de pesquisa disponveis para personalizar a exibio do dashlet. Voc vai se lembrar que esses campos esto disponveis quando entrar em opes de configuraes a dashlet janela de dilogo e so uma maneira dos registros que iriam obter consta este dashlet de ajustes. Figura 9-16 mostra edio isso apenas como se fosse um painel de pesquisa normal.
FIGURA 66 - OS CAMPOS DE PESQUISA DASHLET PARA UM MDULO NO CONSTRUTOR DE MDULO DE EDIO Quando voc implantar ou instala este mdulo em uma instncia em execuo, o novo dashlet no ser automaticamente colocado nas pginas Home ou painel. Vai ser na lista de Dashlets disponveis para adicionar aquelas pginas, que os usurios podem escolher fazer uma vez que o mdulo est disponvel para o usurio. RELACIONAMENTOS Relacionamentos so a ltima pea do quebra-cabea na construo de qualquer novo mdulo, mas em muitos aspectos o mais importante. Relaes entre mdulos so uma das coisas que realmente valorizar o SugarCRM. Comparando registros juntos, atravs de mdulos ou dentro de um mdulo, voc abre a possibilidade de aumento da produtividade dando aos usurios a capacidade de reunir diferentes partes de informaes em um sistema facilmente. Para qualquer um construir um mdulo, torna-o fcil de construir em cima os mdulos de Sugar existentes em vez de ter que fazer ganchos elaborados e complicados para eles ou apenas reconstruir a funcionalidade pode dar ao seu mdulo em seu prprio pas. Para comear, clique em relaes de exibio da tela principal do mdulo, que far aparecer a caixa de dilogo mostrada abaixo na Figura 9-17.
FIGURA 67 - RELACIONAMENTOS EM UM MDULO NO MDULO CONSTRUTOR Por padro, nenhum relacionamento existe para um mdulo, por isso se voc quiser adicionar um voc precisa clicar no boto Adicionar relacionamento no formulrio para adicion-lo. Quando voc fizer isso, voc estar na tela criar relacionamento, conforme mostrado na Figura 9-18.
FIGURA 68 - CRIANDO RELACIONAMENTO NO MDULO CONSTRUTOR. Esta tela (muito parecido com a maioria do mdulo Construtor) funciona da mesma como sua contraparte no estdio. Lembre-se de captulo 3 que podes criar diferentes tipos de relaes usando o construtor de mdulo: Um a um: O mdulo principal tem um registro que se relaciona com apenas um registro no mdulo relacionado. Um para muitos: O mdulo principal tem um registro que se refere a um ou mais registros no mdulo relacionado. Muitos a um: O mdulo principal pode ter um ou mais registros que refere-se a um nico registro no mdulo relacionado. Muitos para muitos: O mdulo principal pode ter um ou mais registros que refere-se a um ou mais registros no mdulo relacionado. Uma diferena aqui com relacionamentos no mdulo Construtor versus estdio de edio que o mdulo construtor permite que voc editar e apagar seus relacionamentos depois de cri-las atravs da GUI, enquanto com o Studio, isto no era possvel. (Captulo 6, voc aprendeu uma maneira de vasculhar o cdigo para limpar essas relaes.) O grande motivo ele pode ser feito aqui, mas no no estdio, que as estruturas de mdulo no mdulo Construtor so muito mais maleveis no mdulo construtor do estdio. Studio escrever as personalizaes imediatamente ao mdulo Construtor s faz isso em uma publicao ou implantar. Depois de ter criado o relacionamento muitos-para-muitos, clique em salvar e o relacionamento vai ser construdo. Voc vai ser volta tela de relaes com o novo relacionamento adicionado, conforme mostrado na Figura 9-19.
FIGURA 69 - RELACIONAMENTO CRIADO Uma considerao que voc deve fazer ao adicionar relacionamentos para mdulos que no acompanham o seu pacote que voc deve se certificar que voc no est adicionando relacionamentos para mdulos que no existem no sistema de destino. Por exemplo, digamos que voc tem uma relao para o mdulo de contratos, mas algum que quer instalar o seu pacote na verso CE do Sugar. Ocorrer todos os tipos de problemas como esse mdulo no disponvel. Coisas como esta devem ser claramente documentadas no arquivo Leiame se elas existem, para que os administradores possam ter conscincia deles e evitar potenciais problemas. O QUE FAZER COM ESTE PACOTE? Agora voc tem seu mdulo do jeito que voc quer: todos os campos que voc precisa esto presentes, a propriedade de vistas de metadados personalizada, e os rtulos ajustados. hora de apresent-lo ao mundo! Para fazer isso, o Sugar fornece trs abordagens: Publicar o pacote do mdulo como um pacote carregvel que pode ser instalado em uma instncia usando o carregador de mdulo. Esta uma abordagem comum, se voc estiver desenvolvendo um mdulo para a implantao de muitas instncias diferentes de Sugar, uma vez que o administrador pode apenas carregar o pacote para sua instncia e instal-lo facilmente. Implantar o pacote do mdulo para a instncia em execuo atual. Exportar o pacote do mdulo como um pacote carregvel que s ser instalado no mdulo carregador para personalizao adicional no sistema de destino. Esta abordagem mais comumente usada quando vrios desenvolvedores esto trabalhando em um pacote, para que eles possam compartilhar as alteraes e para trs entre eles, ou se o pacote pode precisar de alguma configurao adicional uma vez que instalado na instncia do Sugar individual. Voc vai dar uma olhada em cada uma das opes disponveis e como eles funcionam. IMPLANTAR A INSTNCIA ATUAL Primeiro, voc vai olhar a soluo mais fcil e comum, que implantar o mdulo para a instncia em execuo atual. Para fazer isso, tudo que voc precisa fazer clicar no boto de implantar na tela principal do pacote e o pacote ser implantado para a instncia atual. Figura 9-20 mostra a caixa de dilogo implantar ao implantar um pacote usando o construtor de mdulo para a instncia atual.
FIGURA 70 - IMPLANTAO DE UM PACOTE USANDO O CONSTRUTOR DE MDULO Quando feito, o mdulo ento imediatamente disponvel para os usurios finais na instncia atual. Como voc fazer alteraes em seu mdulo, voc pode continuar a implantar o mdulo novamente e novamente, e suas alteraes iro substituir as atuais no mdulo. PUBLICANDO SUAS ALTERAES E INSTALANDO-AS COM CARREGADOR DE MDULO Se voc pensando em distribuir seu mdulo para o mundo, voc vai querer clicar no cone de publicao, que ir baixar o mdulo construdo como um arquivo .zip no seu computador local. Em seguida, voc pode tomar este pacote zip e instal-lo em qualquer outra instncia do Sugar muito facilmente usando o carregador de mdulo. Para fazer isso, voc vai para a tela principal do mdulo carregador clicando no link do carregador de mdulo no painel de administrao, na seo de ferramentas do desenvolvedor, que mostra a caixa de dilogo mostrada na Figura 9-21.
FIGURA 71 - TELA PRINCIPAL DO MDULO CARREGADOR Para comear a instalar o seu pacote, voc primeiro precisar carreg-lo. A segunda seo da tela na Figura 9-21 onde voc fazer isso. Basta navegar para selecionar o pacote .zip que voc baixou no seu computador local e clique em Upload para envi-lo para a instncia de Sugar. Quando voc fizer isso, ele aparecer na lista de mdulos mostrado no mdulo carregador, como voc pode ver na Figura 9-22.
FIGURA 72 CARREGADOR DE MDULO DEPOIS QUE VOC CARREGAR UM PACOTE Voc pode clicar em instalar agora para iniciar a instalao do seu pacote. Algumas verificaes sobre o pacote e o sistema sero executadas primeiro, e ento voc estar na tela de confirmao do pacote, como voc pode ver na Figura 9-23.
FIGURA 73 - TELA PARA CONFIRMAR A INSTALAO DE UM PACOTE ATRAVS DO MDULO CARREGADOR Voc precisa concordar com um contrato de licena, que includo por padro em todos os mdulos do construtor de mdulo. Voc pode substitu-lo no pacote alterando o arquivo License.txt dentro do pacote publicado. Se voc tiver especificado um README. txt para o pacote durante a criao do pacote, voc tambm ver aqui na segunda aba desta forma.
FIGURA 74 - SEO DE README DA TELA DE CONFIRMAO PARA A INSTALAO DE UM PACOTE ATRAVS DO MDULO CARREGADOR Quando voc estiver pronto para instalar o pacote, basta clicar em confirmar e a instalao comear. Isso pode levar algum tempo, porque no s vo precisar de arquivos a serem copiados, mas tambm uma srie de instrues SQL precisar ser executadas para criar as tabelas do banco de dados que sero usadas para o mdulo, como relaes de reconstruo para incluir qualquer recm-criado relacionamentos que voc especificou no mdulo construtor.
FIGURA 75 - INSTALAO DE PACOTES ATRAVS DO MDULO CARREGADOR Quando a instalao estiver concluda, voc pode clicar volta a boto de carregador de mdulo e ver que seu mdulo agora est instalado e pronto para usar. No h nenhum ajuste adicional necessria, para que o mdulo est imediatamente disponvel para todos os usurios com direitos para faz-lo. EXPORTANDO O PACOTE Na pgina principal do pacote, voc pode clicar no boto Exportar para exportar o pacote em um arquivo de zip carregveis do mdulo, que usa a mesma ferramenta de mdulo carregador usada para instalar um pacote publicado. No entanto ao instalar o pacote, ele apenas coloca-lo no mdulo construtor e no torn-lo disponvel a instncia em execuo de outros usurios fazer o que voc precisa implantar para a instncia. A principal razo para ter essa opo principalmente em casos onde vrios desenvolvedores trabalham colaborativamente em um mdulo e no tem um controle de verso sistema como SVN ou Git sua disposio. Este colaborador de uma maneira pode trabalhar em uma parte do mdulo e, em seguida, pass-lo para outro desenvolvedor para fazer a sua parte e assim por diante. Outro uso possvel seria se o mdulo pode ser necessrio alguma personalizao etapas em relao instncia implantada. Por exemplo, voc pode querer fornecer uma maneira para instncias que esto faltando um mdulo especfico para remover quaisquer relacionamentos a ele antes da implantao. REMOVER UM PACOTE INSTALADO No importa qual opo de implantao que voc escolher para ir, o pacote instalado aparece no mdulo carregador, como voc pode ver na Figura 9-26.
FIGURA 76 - MDULO CARREGADOR DEPOIS DE INSTALAR UM PACOTE Por aqui, podemos desinstalar o pacote, se voc no quiser mais us-lo, ou desativ-lo se voc quiser remov-lo por um momento, mas mant-lo instalado no sistema. Desabilitar uma boa opo se voc pode querer usa-lo novamente no futuro, mas precisa-removido por enquanto. Uma possvel razo pode ser que h algum problema de desempenho, assim voc deseja desativ-lo at que voc possa corrigi-lo. Desinstal-lo a melhor opo se voc no deseja usar o pacote todo. Quando voc clicar no boto de desinstalao, voc vai passar atravs de um rpido assistente que ir verificar o sistema para certificar-se de que pode desinstalar o pacote, conforme mostrado na Figura 9-27.
FIGURA 77 - DILOGO PARA DESINSTALAR UM PACOTE USANDO O MDULO CARREGADOR Voc tem aqui uma opo para remover as tabelas criadas pelo mdulo ou no. Normalmente, voc vai querer remover essas tabelas uma vez que mantendo-as seria carga extra no utilizada, em uso seu banco de dados. Seu DBA pode no queira executar vrios comandos DROP TABLE em um execuo de banco de dados SQL, porm, prefiro faz-lo eles mesmos. Portanto, a opo para ignorar esta etapa tambm fornecida. Voc s precisa clicar em confirmar e aparece a tela na Figura 9-28, que remove o mdulo da instncia do Sugar.
FIGURA 78 - DESINSTALAR UM PACOTE USANDO O MDULO CARREGADOR As mesmas etapas so usadas quando um mdulo instalado, apenas fazendo as aes inversa. Neste ponto, todos os vestgios do mdulo no esto mais disponveis para qualquer usurio, e clicando em Back to Module Loader boto voltar para a tela principal do mdulo carregador. Voc notar que o pacote desce volta grade inferior que lista os pacotes a serem instalados no caso voc quer reinstal-lo posteriormente. Se voc terminar com ele para sempre, clique no boto Delete Package essa grade e o pacote ser removido da lista. RESUMO Neste captulo, voc aprendeu tudo sobre mdulo Builder, uma ferramenta til para a construo de novos mdulos para o SugarCRM usando um ponto de fcil de usar e interface clicar. Voc olhou para a construo de um mdulo de pea por pea, comeando por ver como construir o pacote inicial e, em seguida, andaimes para o mdulo usando o construdo em modelos SugarObject. Voc atravessou Personalizando todas as peas do mdulo, os campos disponveis e seus rtulos visveis ao usurio para todas as exibies de controlados por metadados que comprometer o ncleo do seu mdulo. Voc, em seguida, olhou para implantar o mdulo fora para o mundo e que opes voc tem disponvel. Aqui voc pode usar implantar o direito sua instncia atual ou export-lo para fora para um arquivo zip onde ele poderia ser instalado em outras instncias tambm. Enquanto Construtor de mdulo funciona muito bem para seu mdulo de estilo tpico do CRUD, muitas vezes voc precisa executar tarefas mais personalizadas dentro de um mdulo que s pode ser feito atravs de cdigo PHP personalizado. No tenham medo, Sugar voc tem coberto aqui. No prximo captulo, voc olhar em construir um mdulo manualmente. CONSTRUO DE UM MDULO PERSONALIZADO MANUALMENTE No captulo 9, voc olhou para mdulo Builder, que uma ferramenta muito fcil de usar que voc pode usar para construir um mdulo. Usando Module Builder voc pode criar os tipos mais comuns de mdulos com facilidade, que normalmente so aqueles que empregam algum tipo de interface do CRUD para manter os registros no mdulo. Para muitas necessidades de mdulo que voc vai ter, este provavelmente tudo o que necessrio, mas lembre-se que voc pode usar os ganchos de lgica e fluxos de trabalho que voc aprendeu sobre no captulo 7 para adicionar o faltando pedaos de lgica de negcios para seu mdulo personalizado como voc podem com os construdo em mdulos. Com estas poderosas ferramentas ao seu alcance, voc vai encontrar-se pronto para construir mdulos para si mesmo rapidamente em nenhuma hora em tudo. Se seu mdulo no cabe este molde? Se voc precisa construir algum tipo de funcionalidade especial que Sugar no fornece fora da caixa? Em seguida, construir um mdulo manualmente definitivamente o curso de ao que voc vai precisar levar para realizar seus objetivos, e neste captulo, voc vai ter uma viagem passo a passo sobre como fazer isso. Vamos comear esta viagem primeiro olhando as razes que voc iria querer fazer algo assim. POR QUE VOC FARIA ISSO? A primeira pergunta que qualquer programador prtico pede-se por isso? Por que passar pela dificuldade de construo de um mdulo de pouco a pouco em vez do caminho fcil e apenas usando o construtor de mdulo? A seguir esto algumas razes: Deseja realmente aprender sobre as partes internas do SugarCRM. No se trata de raciocnio realmente mais rebuscado. Recentemente, passei algum tempo alguns mdulos de construo mo e aprendi uma riqueza de informaes sobre como funcionam as entranhas, que me deram muitos insights sobre a plataforma que eu usei para escrever este livro. Seu mdulo no o mdulo de CRUD-estilo normal (ou seja, um mdulo que contm um detalhe e editar lista de vistas). Por exemplo, o mdulo de importao no tem quaisquer telas de entrada de dados, mas pelo contrrio apenas uma interface de assistente passo a passo que executa uma operao em outro mdulo. Seu mdulo tenha alguns personalizados telas de entrada de dados. O mdulo de funes um bom exemplo disso, pois tem detalhes e editar modos de exibio que usam widgets no includos com o Studio ou construtor de mdulo. H tambm um meio-termo aqui tambm. Voc pode usar o construtor de mdulo para fazer o trabalho sujo de configurar os pontos de vista iniciais, criando os campos necessrios e construir relacionamentos. Depois do que a metade, voc poderia implantar o mdulo e, em seguida, personaliz-lo na instncia usando muitas das tcnicas que voc viu no captulo 8, como adicionar exibies adicionais ou personalizar os metadados de maneiras que voc no pode fazer com o Studio ou construtor de mdulo. Gostaria de recomendar essa abordagem se possvel uma vez que voc vai ser capaz de ignorar que vrios dos passos iniciais que criar a estrutura geral do mdulo e sua estrutura de arquivo e concentrar-se apenas o que voc precisa adicionar para realizar seus objetivos. Porm, se no seu mdulo o tpico dados-driven mdulo (como o mdulo de importao), ento melhor respeitar as seguintes instrues e construir seu mdulo mo. Ou, se voc est apenas curioso sobre como um mdulo construdo de baixo para cima, acompanhar para aprender o que precisa ser feito para que isso acontea. O QUE VOC PRECISA FAZER Se voc conseguiu este ponto, em seguida, voc decidiu que construir um mdulo mo exatamente o curso de ao que voc deseja embarcar, para uma das muitas razes descritas anteriormente. O processo para faz-lo requer um monte de etapas que so importantes, para que seu mdulo seja devidamente reconhecido pela instncia do Sugar. Faltando qualquer um passo pode potencialmente resultar em seu mdulo no funcionar como esperado, se ele por causa de erros, a perda de dados ou aplicativo. Para este exemplo, voc assumimos que voc est construindo um mdulo chamado peas, que sero usadas para construir um banco de dados de peas para sua instncia de Sugar. O mdulo de peas ser principalmente um mdulo normal de CRUD-estilo, com algumas reviravoltas ao longo do caminho. Vamos pular direto para o processo, comeando com a construo da estrutura de diretrio. CONSTRUIR A ESTRUTURA DE DIRETRIO A estrutura de diretrio para o mdulo o primeiro componente na construo de seu prprio mdulo. Seu mdulo recm-criado existiro dentro do diretrio modules/ na raiz do aplicativo, portanto, para o mdulo de parts que voc est construindo o nome do diretrio seria modules/Parts/. Essa pasta conter todos os arquivos que sero usados no seu mdulo. Tabela 10-1 contm uma diviso desses itens. File and/or Directory Description Language/ Contm todas as seqncias de caracteres do idioma para um determinado mdulo. Dashlets/ Contm qualquer dashlets para o determinado mdulo. metadata/ Contm todos os arquivos de metadados (para EditViews, DetailViews, pesquisas) para o mdulo. Estes incluem metadata/editviewdefs.php, metadata/detailviewdefs.php, metadata/searchdefs.php, metadata/listviewdefs.php e metadata/SearchFields.php. metadata/studio.php Arquivo existe se voc pode personalizar seu mdulo via Studio. No tem de ter qualquer coisa nele, apenas estar l. metadata/subpanels/ Contm os arquivos de metadados para a exibio de Subpainel deste mdulo dentro de outros mdulos. views/ Contm os arquivos de modo de exibio para o mdulo. tpls/ Contm qualquer Smarty templates usados no mdulo. javascript/ Contm qualquer cdigo javascript includo pela vista no mdulo. Forms.php Contm qualquer cdigo que voc deseja ser includo com qualquer acesso ao seu mdulo, tais como funes auxiliares. Por favor note que este arquivo deve existir, mesmo se ele estiver vazio para o mdulo funcione corretamente. Menu.php Contm qualquer matriz que usado para criar o menu do mdulo, o que geralmente est localizado na barra lateral esquerda e contm links para aes comuns do mdulo, como a criao de novos registros Beanname.php A classe principal do bean para o mdulo. vardefs.php Contm a estrutura da tabela, incluindo campos, ndices e relacionamentos com outros mdulos. TABELA 7 - DISCRIMINAO DO CONTEDO DE QUALQUER MDULO Eu esboarei o contedo dos diretrios listados na tabela 10-1 e qual o contedo dos arquivos mencionados l ao longo deste captulo. importante notar que Conveno de nomenclatura importante para o mdulo, no s por uma questo de consistncia dentro do aplicativo, mas tambm desde muitos plataforma - relacionados componentes esperam arquivos de existir em certos locais e no podem funcionar corretamente se eles no esto l. Por exemplo, o modelo de metadados EditView sempre deve ser localizado em modules/modulename/metadata/editviewdefs.php, como o EditView manipulador cdigo espera encontr- lo l. Neste ponto, muito importante ter todos os arquivos e diretrios listados na tabela 10-1 criado, menos os arquivos Menu.php, Beanname.php e vardefs.php que voc vai construir mais tarde. Uma vez que tudo feito, voc pode passar para obter seu mdulo registrado dentro do Sugar. REGISTRAR O MDULO COM A INSTNCIA Voc construiu a estrutura do seu novo mdulo de peas brilhante, mas h um problema: Sugar no tem nenhuma idia que ele existe. Para ajudar o Sugar, voc precisar registrar seu mdulo recm-criado com a instncia de Sugar. A primeira parte do registo envolve o arquivo include/modules.php. Se voc olhar para este arquivo em sua instncia, voc observar que contm referncias a todos os mdulos que existe no sistema. Seu mdulo de peas precisa ser includo no presente tambm. No entanto, voc no pode simplesmente adicionar o mdulo l se voc sempre espera que seu mdulo ser segura de atualizao. Em vez disso, voc adicion-lo para este arquivo adicionando-o por meio do diretrio custom/ arquivo que obtm a leitura pelo arquivo include/modules.php situa-se no arquivo custom/application/Ext/Include/modules.ext.php. Listagem 10-1 mostra o que precisa ser neste arquivo para que ele funcione. Listagem 10-1 arquivo custom/application/Ext/Include/modules.ext.php que contm adies para o arquivo include/modules.php <?php $beanList['Parts'] = 'Part'; $beanFiles['Part'] = 'modules/Parts/Part.php'; $moduleList[] = 'Parts'; ?> H uma questo que voc potencialmente poderia se deparar ao adicionar as peas diretamente para o arquivo de custom/application/Ext/Include/modules.ext.php. Se voc carregar todos os mdulos em sua instncia do Sugar em execuo, em seguida, suas alteraes iriam ser exterminadas. A melhor maneira de evitar que isso acontea tambm adicionar o cdigo relacionado na listagem 10-1 em um arquivo no diretrio custom/Extension/application/Ext/Include/ com qualquer nome de arquivo de sua escolha que termina com a extenso. php, como additions.php. Desta forma, sempre que um novo mdulo instalado em sua instncia, suas adies para o custom/application/Ext/Include/modules.ext.php continuar a ser incorporado qualquer arquivo. Existem tambm algumas outras opes que voc pode definir para seu mdulo, conforme mostrado na tabela 10-2. Array name Description $beanList Lista de chave do bean disponvel o nome do mdulo. $beanFiles Lista de caminhos de arquivo do bean da chave de todos os mdulos disponveis o nome do mdulo. $moduleList Lista de mdulos disponveis sem chave especificada. $modInvisList Lista de mdulo, que no deve nunca ser mostrado nas guias lista mdulo normalmente na parte superior da tela; nenhuma chave especificada $adminOnlyList Lista de mdulos que no so destinados a Admin apenas nenhuma chave especificada. O valor uma matriz na forma de: 'modulename' = > array ('all' = > 1) TABELA 8 - TODAS AS OPES PARA UM BEAN NO ARQUIVO MODULES.EXT.PHP A prxima pea adicionar o mdulo para o pacote de idiomas com o nome localizado correto para ele. Vou adicion-lo para duas chaves na $app_list_strings, como voc pode ver na listagem 10-2. Listagem 10-2 custom/Extension/application/Ext/Language/en_us.parts.php arquivo que contm adies para o include/languages/en_us.lang.php arquivo. <?php $app_list_strings['moduleList']['Parts'] = 'Parts'; $app_list_strings['moduleListSingular']['Parts'] = 'Part'; ?> As duas chaves que voc adicionar so 'moduleList' e 'moduleListSingular', ambos com os valores sendo o nome do mdulo. A chave de moduleList tem o valor do nome do mdulo, enquanto o moduleListSingular especifica o nome do mdulo no formulrio singular (em vez do nome do mdulo que o mais frequentemente na forma plural normal). Agora que o mdulo est corretamente registrado em sua instncia do Sugar, voc pode agora comear a construir o arquivo de classe do bean para sua instncia. ADD BEAN CLASS FILE No captulo 2, voc aprendeu que o arquivo de classe do bean representa a poro do modelo do padro de design Model View Controller usado dentro do Sugar. Seu objetivo fornecer uma interface para as estruturas de dados de back-end usados pelo mdulo, bem como fornecendo mtodos simples para as transformaes de dados que precisam feitos como parte da execuo do mdulo. Listagem 10-3 mostra o arquivo de classe Bean que voc vai usar para o mdulo de peas que voc est construindo. Listagem 10-3 Arquivo de classe do Bean Part.php <?php class Part extends Basic{ var $new_schema = true; var $module_dir = 'Parts'; var $object_name = 'Part'; var $table_name = 'parts'; var $importable = true; var $id; var $name; var $date_entered; var $date_modified; var $modified_user_id; var $modified_by_name; var $created_by; var $created_by_name; var $description; var $deleted; var $created_by_link; var $modified_user_link; var $team_id; var $team_set_id; var $team_count; var $team_name; var $team_link; var $team_count_link; var $teams; var $assigned_user_id; var $assigned_user_name; var $assigned_user_link; var $part_reference_number; var $part_location; public function __construct() { parent::Basic(); } public function bean_implements($interface){ switch($interface){ case 'ACL': return true; } return false; } public function fetchImageURL(){ if(!empty($this->part_reference_number)){ return 'http://partimageserver.local/getImage/' . $partBean->part_reference_number; } return 'include/images/blank.gif'; } public function save($check_notify = false){ // Default the part_location field if it's not otherwise specified if(empty($this->part_location)){ if ( strpos($this->part_reference_number,'790-') !== FALSE ){ $this->part_location = 'Warehouse'; } elseif ( strpos($this->part_reference_number,'890-') !== FALSE ){ $this->part_location = 'Stockroom'; } } return parent::save($check_notify); } } Para este mdulo ser herdado o modelo bsico, ento voc tambm subclasse arquivo de Bean do modelo bsico para seu arquivo de Bean para incluir corretamente qualquer lgica dele. As peas principais para o arquivo de Bean que voc precisa especificar incluem: As propriedades principais do Bean como o diretrio de mdulo, objeto, nome, nome da tabela, e se o mdulo permitir a importao nele. Propriedades de Bean para cada campo na tabela para este bean. Isso no absolutamente necessrio, mas faz escrever cdigo PHP para seu mdulo muito mais fcil. O mtodo de bean_implements(), que indica ao acar se este mdulo ir usar ACL para controlar o acesso ou no quaisquer outros novos mtodos ou mtodos substitudos que voc precisa. Para o ltimo item na lista, voc vai adicionar um mtodo e estender outro mtodo existente na classe bean. O mtodo Save (), que usado para salvar um registro no banco de dados, o mtodo que voc vai substituir com lgica para definir o local de parte com base no nmero de referncia de parte de determinado que o usurio tenha fornecido no caso de um local de parte no especificado. Em seguida, voc adicionar um mtodo chamado fetchImageURL(), que ir buscar uma URL que contm a imagem da parte com base no nmero de referncia de parte. Voc usar esse mtodo mais tarde para criar uma exibio que especificamente vai fazer isso. Este exemplo assume que o servidor http://partimageserver.local/getImage/ um servio de Web de REST que fornece imagens para as vrias partes. CONSTRUIR VARDEFS Vardefs de compilao, voc vai lembrar do captulo 2 que vardefs so arquivos usados para definir a estrutura base para a tabela de dados de para um determinado mdulo. Uma coisa legal que voc tenha baseado seu recm-criado mdulo dentre os modelos internos que vm com acar, assim voc no precisa especificar todos os campos que voc precisa, apenas aqueles que no so j uma parte do modelo que voc est baseando seu mdulo. Para o mdulo de peas que voc est construindo, voc vai adicionar dois campos a ele. O primeiro campo um campo varchar, chamado 'part_reference_number', que vai especificar um nmero de referncia que voc vai usar para sua pea e tambm vai ser usado para pesquisa da imagem, como voc viu no mtodo da classe bean anteriormente. Voc tambm adicionar um campo de enum chamado 'part_location', que d ao usurio uma seleo de lista suspensa da atual localizao da parte. Voc vai definir todas as opes para este campo enum na seo "Adicionar Strings de linguagem" mais tarde no presente captulo. Coloc-lo todos juntos, voc tem o arquivo de vardefs.php mostrado na listagem 10-4 Listagem 10-4 vardefs.php arquivo do mdulo de peas <?php $dictionary['Part'] = array( 'table' => 'parts', 'audited' => true, 'fields' => array( 'part_reference_number'=> array( 'name' => 'part_reference_number', 'vname' => 'LBL_PART_REFERENCE_NUMBER', 'type' => 'varchar', 'len' => '255', ), 'part_location' => array( 'name' => 'part_location', 'vname' => 'LBL_PART_REFERENCE_NUMBER', 'type' => 'enum', 'len' => '50', 'options' => 'parts_part_location_dom', ), ), 'indices' => array( array( 'name' => 'idx_parts_part_ref_id', 'type' => 'index', 'fields' =>array( 'id', 'part_reference_number' ) ), array( 'name' => 'idx_parts_part_location_id', 'type' => 'index', 'fields' =>array( 'id', 'part_location' ) ), ), 'relationships' => array ( ), 'optimistic_lock' => true, ); require_once('include/SugarObjects/VardefManager.php'); VardefManager::createVardef('Parts', 'Part', array('basic', 'assignable')); ?> Adicione alguns ndices adicionais tambm, para que seu recm adicionado part_reference_number e part_location podem ser consultados de forma ideal, que significa que o banco de dados pode usar estes ndices para acelerar a execuo das vrias consultas feitas em tabelas subjacentes. Na parte inferior do vardef arquivo onde voc incluir as definies de campo adicional desde o modelo bsico, voc est herdando, bem como o modelo pode ser atribudo, que adiciona todo o atribudo aos campos de usurio para o mdulo. Lembre-se que antes de usar o mdulo, voc precisar ir para o Admin > Repair > Repair Database antes de tentar usar o mdulo para o backend peas tabela ser construdo para seu mdulo. Voc deve fazer isso toda vez que uma mudana para o vardefs.php to bem feita, mesmo que uma mudana de banco de dados no necessria, j que ele tambm ir atualizar as cpias em cache do arquivo vardefs.php para o mdulo ao mesmo tempo. Depois que voc fizer isso, seu banco de dados ter os campos adicionados ou atualizados que so definidos nos arquivos vardef disponveis para seu mdulo para usar. Agora que voc tem a estrutura do mdulo construda, a classe bean criado, e a estrutura de banco de dados especificado, voc vai avanar com a construo de todos os modelos para as vrias vises de metadados impulsionado no seu mdulo. Agora que voc tem a estrutura do mdulo construda, a classe bean criada, e a estrutura de banco de dados especificado, voc vai avanar com a construo de todos os modelos para as vrias vises de metadados impulsionado no seu mdulo. CONSTRUIR QUALQUER MODELOS DE METADADOS Com o Bean de mdulo em seu lugar, voc pode agora construir os modelos de metadados. Voc viu no captulo 3 que o projeto bsico, estes so e todas as opes disponveis. Desde que o seu mdulo ser o mdulo de estilo normal do CRUD, voc precisar ter certeza que contm todas essas exibies de metadados nele tambm. Para isso, voc precisar construir todos os modelos de metadados para cada um dos pontos de vista que voc vai usar no seu mdulo. Vamos comear por construir o DetailView na listagem 10-5. Listagem 10-5 detailviewdefs.php arquivo do mdulo de peas <?php $viewdefs['Parts']['DetailView'] = array( 'templateMeta' => array( 'form' => array( 'buttons'=>array( 'EDIT', 'DUPLICATE', 'DELETE', array ( 'customCode' => '<input title="{$MOD.LBL_VIEWPARTIMAGE_TITLE}" accessKey="{$MOD.LBL_VIEWPARTIMAGE_BUTTON_KEY}" type="button" class="button" onClick="open_popup(\'Parts\', \'600\', \'400\','&action=Image&record={$fields.id.value}\');" name="image" value="{$MOD.LBL_VIEWPARTIMAGE}">' ), ), ), 'maxColumns' => '2', 'widths' => array( array( 'label' => '10', 'field' => '30' ), array( 'label' => '10', 'field' => '30' ) ), ), 'panels' =>array ( array ( 'name', 'assigned_user_name', ), array ( array ( 'name' => 'date_entered', 'customCode' => '{$fields.date_entered.value} {$APP.LBL_BY} {$fields.created_by_name.value}', 'label' => 'LBL_DATE_ENTERED', ), array ( 'name' => 'date_modified', 'customCode' => '{$fields.date_modified.value} {$APP.LBL_BY} {$fields.modified_by_name.value}', 'label' => 'LBL_DATE_MODIFIED', ), ), array ( 'part_reference_number', 'part_location', ), array ( 'description', ), ) ); ?> Aqui voc pode ver que seu DetailView bastante bsico, com os campos bsicos para o mdulo, como o nome da parte, descrio, atribudo o nome de usurio, data inscrita e modificado, bem como os campos especficos do mdulo de referncia da pea e localizao da parte. Voc tambm modificou os botes que aparecem na parte superior deste formulrio para adicionar um boto que vai lanar o popup de imagem para cada parte com base no nmero de referncia de parte. Voc vai construir o modo de exibio em "Adicionar quaisquer exibies adicionais necessrias" seo um pouco mais tarde no captulo. Agora vamos passar para o EditView, como mostrado na Listagem 6-10. O EditView praticamente o mesmo que o DetailView, com campos para o nome da parte, atribudo o nome de usurio, descrio, bem como seus campos especficos de mdulo de localizao de parte e nmero de referncia da pea. Agora vamos passar para o EditView, como mostrado na Listagem 6-10. O EditView praticamente o mesmo que o DetailView, com campos para o nome da parte, atribudo o nome de usurio, descrio, bem como seus campos especficos de mdulo de localizao de parte e nmero de referncia da pea. Listagem 10-6 editviewdefs.php arquivo do mdulo de peas <?php $viewdefs['Parts']['EditView'] = array( 'templateMeta' => array( 'maxColumns' => '2', 'widths' => array( array( 'label' => '10', 'field' => '30' ), array( 'label' => '10', 'field' => '30' ) ), ), 'panels' =>array ( 'default' => array ( array ( 'name', 'assigned_user_name', ), array ( 'part_reference_number', 'part_location', ), array ( 'description', ), ), ), ); ?> Vamos passar para o ListView. Novamente, se voc puxar de seu conhecimento sobre os modelos de metadados que voc aprendeu no captulo 3, voc sabe que existem trs modelos de metadados diferentes, que voc precisar construir todos os componentes no formulrio. O primeiro o arquivo listviewdefs.php, conforme mostrado na listagem 10-7. Listagem 10-7 listviewdefs.php arquivo do mdulo de peas <?php $listViewDefs['Parts'] = array( 'NAME' => array( 'width' => '32', 'label' => 'LBL_NAME', 'default' => true, 'link' => true ), 'PART_REFERENCE_NUMBER' => array( 'width' => '30', 'label' => 'LBL_PART_REFERENCE_NUMBER', 'default' => true ), 'PART_LOCATION' => array( 'width' => '30', 'label' => 'LBL_PART_LOCATION', 'default' => true ), 'ASSIGNED_USER_NAME' => array( 'width' => '9', 'label' => 'LBL_ASSIGNED_TO_NAME', 'default' => true ), 'DATE_MODIFIED' => array( 'width' => '5', 'label' => 'LBL_DATE_MODIFIED' ), 'DATE_ENTERED' => array( 'width' => '5', 'label' => 'LBL_DATE_ENTERED' ), 'CREATED_BY_NAME' => array( 'width' => '10', 'label' => 'LBL_CREATED' ), 'MODIFIED_BY_NAME' => array( 'width' => '10', 'label' => 'LBL_MODIFIED' ), ); ?> Voc ter quatro campos exibidos no ListView, nome, nmero de referncia da pea, parte local, e atribudo nome de usurio com a opo para que os usurios tambm adicionar a data criada e modificada campos, bem como os campos que representa o usurio que criou ou modificou o registro. Como voc pode lembrar do captulo 3, qualquer um desses campos pode ser classificada pelo usurio usando a interface do ListView, mas voc tambm pode fazer qualquer outro desses campos pesquisveis das interfaces de pesquisa bsica e avanada. Voc tem dois arquivos necessrios para fazer isso. O primeiro o arquivo searchdefs.php que define a interface de pesquisa que voc v neste formulrio de ListView, como mostrado na listagem 10-8. Listagem 10-8 searchdefs.php arquivo do mdulo de peas <?php $searchdefs['Parts'] = array( 'templateMeta' => array( 'maxColumns' => '3', 'widths' => array('label' => '10', 'field' => '30'), ), 'layout' => array( 'basic_search' => array( 'name', array( 'name'=>'current_user_only', 'label'=>'LBL_CURRENT_USER_FILTER', 'type'=>'bool' ), ), 'advanced_search' => array( 'name', 'part_reference_number', 'part_location', array( 'name' => 'assigned_user_id', 'label' => 'LBL_ASSIGNED_TO', 'type' => 'enum', 'function' => array( 'name' => 'get_user_array', 'params' => array( false ) ) ), ), ), ); ?> Lembre-se que voc tem dois layouts para editar aqui. A interface de pesquisa bsica o principal um, que deve conter mais frequentemente utilizados campos de pesquisa para o mdulo, enquanto a pgina de pesquisa avanada secundrio e usada para uma pesquisa mais personalizado dos campos mdulo. O segundo arquivo de metadados usado para procurar um mdulo o arquivo SearchFields.php, mostrado na listagem 10-9. Voc vai se lembrar do captulo 3 que voc usa este arquivo para definir como fazer esta pesquisa contra o mdulo, como se o campo de exibio na interface do formulrio de pesquisa diferente do campo que voc est realmente procurando contra. Listagem 10-9 Arquivo de SearchFields.php para o mdulo de peas <?php $searchFields['Parts'] = array ( 'name' => array( 'query_type'=>'default' ), 'part_reference_number' => array( 'query_type'=>'default' ), 'current_user_only'=> array( 'query_type'=>'default', 'db_field'=>array( 'assigned_user_id' ), 'my_items'=>true, 'vname' => 'LBL_CURRENT_USER_FILTER', 'type' => 'bool' ), 'assigned_user_id'=> array( 'query_type'=>'default' ), ); ?> Agora que voc tem todos os pontos de vista bsicos feitos para o mdulo, vamos olhar para alguns dos mais extras que voc usar com seu mdulo. Uma a exibio de Subpainel, que mostrada a DetailViews de todos os mdulos relacionados ao seu mdulo de peas. Voc pode ver o layout de metadados para isso na listagem 10-10. Listagem 10-10 subpanels/default.php arquivo do mdulo de peas Listagem 10-9. Arquivo de SearchFields.php para o mdulo de peas <?php $subpanel_layout = array( 'top_buttons' => array( array( 'widget_class' => 'SubPanelTopButtonQuickCreate' ), array( 'widget_class' => 'SubPanelTopSelectButton', 'popup_module' => 'Parts' ), ), 'where' => '', 'list_fields' => array( 'name'=>array( 'vname' => 'LBL_NAME', 'widget_class' => 'SubPanelDetailViewLink', 'width' => '45%', ), 'date_modified'=>array( 'vname' => 'LBL_DATE_MODIFIED', 'width' => '45%', ), 'part_reference_number'=>array( 'vname' => 'LBL_PART_REFERENCE_NUMBER', 'width' => '45%', ), 'edit_button'=>array( 'widget_class' => 'SubPanelEditButton', 'module' => 'Parts', 'width' => '4%', ), 'remove_button'=>array( 'widget_class' => 'SubPanelRemoveButton', 'module' => 'Parts', 'width' => '5%', ), ), ); ?> Subpainel tm definies tipicamente trs partes para eles. A primeira a definio dos botes no topo do Subpainel, que seu mdulo de peas, voc s precisa de um boto criar e um boto de seleo. Voc vai usar a opo de QuickCreate aqui, que mostra o criar forma inline em vez de uma janela de navegador subseqentes, desde seu EditView bastante simple. (Voc vai se lembrar do captulo 3 que voc poderia ter criado um quickcreatedefs.php separado se necessrio para simplificar a forma.) Voc tem uma chave 'onde' para especificar onde opes que voc precisa fazer para filtrar ainda mais para baixo os registros mostrados, seguido pela lista real de campos que vai ser uma parte do mdulo. Um modelo de metadados mais que voc adicionar seu mdulo um modelo de QuickCreate de lado, que usado para a forma de quickcreate que mostrada na barra lateral esquerda durante o ListView do mdulo e fornece uma maneira de adicionar rapidamente o novo recorde para um mdulo. Para o mdulo de peas que voc est construindo, voc usar um EditView simplificado com apenas o nome, descrio e usurio atribudo campos presentes, como mostra a listagem 10-11. Listagem 10-11 sidecreateviewdefs.php arquivo do mdulo de peas Listagem 10-9. Arquivo de SearchFields.php para o mdulo de peas <?php $viewdefs['Parts']['SideQuickCreate'] = array( 'templateMeta' => array( 'form' => array( 'buttons' => array('SAVE'), 'button_location' => 'bottom', 'headerTpl' => 'include/EditView/header.tpl', 'footerTpl' => 'include/EditView/footer.tpl', ), 'maxColumns' => '1', 'panelClass'=>'none', 'labelsOnTop'=>true, 'widths' => array( array( 'label' => '10', 'field' => '30' ), ), ), 'panels' =>array ( 'DEFAULT' => array ( array( array( 'name' => 'name', 'displayParams' => array( 'required' => true, 'size' => 20 ) ), ), array ( array( 'name' => 'description', 'displayParams' => array( 'rows' => 3, 'cols' => 20 ) ), ), array( array( 'name' => 'assigned_user_name', 'displayParams' => array( 'required' => true, 'size' => 11, 'selectOnly' => true ) ), ), ), ) ); ?> Voc tambm adicionar um arquivo de menu chamado Menu.php que est localizado na raiz do diretrio do mdulo (modules/Parts/) que ter uma lista de links para vrias vises que voc quer que o usurio tenha acesso direto. Listagem 10-12 mostra um exemplo do que voc gostaria de acrescentar aqui. Listagem 10-12 Arquivo de menu.php para o mdulo de peas <?php global $mod_strings, $app_strings, $sugar_config; if(ACLController::checkAccess('Parts', 'edit', true)){ $module_menu[]=Array("index.php?module=Parts&action=EditView&return_module=Parts&return_ac tion=index",$mod_strings['LNK_NEW_PART'],"CreateParts", 'Parts'); } if(ACLController::checkAccess('Parts', 'list', true)){ $module_menu[]=Array("index.php?module=Parts&action=index&return_module=Parts&return_action =DetailView",$mod_strings['LNK_PART_LIST'],"Parts", 'Parts'); } if(ACLController::checkAccess('Parts', 'import', true)){ $module_menu[]=Array("index.php?module=Import&action=Step1&import_module=Parts&return_mo dule=Parts&return_action=index", $app_strings['LBL_IMPORT'],"Import", 'Parts'); } ?> O arquivo de Menu.php acima, que voc construiu fornecer links para criar uma nova parte, peas ListView e importar novos registros para o mdulo de peas. Voc adicionou chamada ACLController::checkAccess() para fazer com que o usurio atual tem acesso lista de opo se ele no, ento a opo de menu no ser listada. Voc agora tem todos os metadados impulsionada vistas feitas, ento vamos definir as seqncias de caracteres de idioma que voc estar usando no seu mdulo. ADICIONAR ARQUIVOS DE IDIOMA As seqncias de caracteres de idioma so uma parte muito til do acar, pois ele permite que voc facilmente internacionalizar o seu mdulo (referido frequentemente como i18n). Ele faz isso por ter arquivos de definies de seqncia de caracteres de idioma para cada um dos idiomas que voc est apoiando em sua instncia, nomeada como language.lang.php no diretrio languages/ do seu mdulo, que obtm carregado automaticamente com base da atual linguagem selecionada para o usurio. Se no h cadeias de caracteres de idioma disponvel no seu mdulo para sua linguagem atual, ento ele se voltar usando as seqncias de caracteres de idioma pt_BR para seu mdulo, por isso importante sempre ter estes definidos acima de quaisquer outras seqncias de caracteres de idioma. Vamos em frente e ver as seqncias de caracteres de idioma para seu mdulo de partes, como mostra a listagem 10-13. Listagem 10-13 en_US.lang.php arquivo do mdulo de peas <?php $mod_strings = array ( 'LBL_TEAM' => 'Team', 'LBL_TEAMS' => 'Teams', 'LBL_TEAM_ID' => 'Team Id', 'LBL_ASSIGNED_TO_ID' => 'Assigned User Id', 'LBL_ASSIGNED_TO_NAME' => 'Assigned to', 'LBL_ID' => 'ID', 'LBL_DATE_ENTERED' => 'Date Created', 'LBL_DATE_MODIFIED' => 'Date Modified', 'LBL_MODIFIED' => 'Modified By', 'LBL_MODIFIED_ID' => 'Modified By Id', 'LBL_MODIFIED_NAME' => 'Modified By Name', 'LBL_CREATED' => 'Created By', 'LBL_CREATED_ID' => 'Created By Id', 'LBL_DESCRIPTION' => 'Description', 'LBL_DELETED' => 'Deleted', 'LBL_NAME' => 'Part Name', 'LBL_CREATED_USER' => 'Created by User', 'LBL_MODIFIED_USER' => 'Modified by User', 'LBL_LIST_FORM_TITLE' => 'Parts List', 'LBL_MODULE_NAME' => 'Parts', 'LBL_MODULE_TITLE' => 'Parts', 'LBL_HOMEPAGE_TITLE' => 'My Parts', 'LNK_NEW_RECORD' => 'Create Parts', 'LNK_LIST' => 'Parts', 'LBL_SEARCH_FORM_TITLE' => 'Search Parts', 'LBL_HISTORY_SUBPANEL_TITLE' => 'View History', 'LBL_ACTIVITIES_SUBPANEL_TITLE' => 'Activities', 'LBL_TEST_PARTS_SUBPANEL_TITLE' => 'Parts', 'LBL_NEW_FORM_TITLE' => 'New Parts', 'LBL_PART_REFERENCE_NUMBER' => 'Part Reference Number', 'LBL_PART_LOCATION' => 'Part Location', 'LBL_VIEWPARTIMAGE' => 'View Part Image', 'LBL_VIEWPARTIMAGE_TITLE' => 'View Part Image [Alt+P]', 'LBL_VIEWPARTIMAGE_BUTTON_KEY' => 'P', ); ?> Voc tambm vai se lembrar que voc tem um campo de enum, localizao de peas, definidos no seu mdulo. O campo enum vai usar uma matriz para especificar as opes que voc tem para o valor deste campo, e ele retira a matriz de cadeia de caracteres de idioma de app_list_strings $. Para definir essas opes, voc vai adicionar uma chave para o app_list_strings chamado 'parts_part_location_dom' com as opes de matriz para o campo enum especificado, como mostra a listagem 10-14. Listagem 10-14 custom/Extension/application/Ext/Language/en_us.partsdom.php arquivo que contm adies para o include/languages/en_us.lang.php arquivo. <?php $app_list_strings['parts_part_location_dom']= array( 'Warehouse' => 'Warehouse', 'Stockroom' => 'Stockroom', 'Supplier' => 'With A Supplier - Must Order', 'Unavailable' => 'Unavailable', ); ?> CRIAR UM DASHLET Mais uma coisa que voc vai querer fazer seu partes do mdulo criar um ListView configurvel que usurios podem cair em sua homepage ou o painel de controle. Esta uma tarefa muito fcil, como voc se lembra do captulo 5, onde para este tipo de Dashlet voc s precisa definir alguns arquivos e estar disponvel para todos os usurios usar. A primeira coisa que voc vai criar o arquivo de definio de Dashlet, que chamado PartsDashlet.meta.php e estratificado no diretrio Dashlets/PartsDashlet/, como mostrado na listagem de 10- 15. Listagem 10-15. Arquivo de PartsDashlet.meta.php <?php $dashletMeta['PartsDashlet'] = array( 'module' => 'Parts', 'title' => translate('LBL_HOMEPAGE_TITLE', 'Parts'), 'description' => 'A customizable view into the Parts module', 'icon' => SugarThemeRegistry::current()->getImageURL('icon_Parts_32.gif'), 'category' => 'Module Views' ); ?> Ento, voc precisa definir os campos de pesquisa e componentes ListView o dashlet. Voc vai se lembrar que o Dashlets no tem as formas tpicas busca e personalizao que o ListViews dentro dos mdulos ter, mas prefiro fazer isso a partir de uma tela do popup de configurao em vez disso. Os arquivos de metadados, no entanto, so construdos o mesmo, mas voc combin-los dentro de um arquivo em vez de dois entes separados e armazen-los no diretrio de metadados do seu mdulo dentro do arquivo de partsdashletviewdef.php (Ver listagem 10-16). Listagem 10-16 partsdashletviewdef.php arquivo <?php global $current_user; $dashletData['PartsDashlet']['searchFields'] = array( 'date_entered' => array( 'default' => '', ), 'date_modified' => array( 'default' => '', ), 'assigned_user_id' => array( 'type' => 'assigned_user_name', 'default' => $current_user->name, ), ); $dashletData['PartsDashlet']['columns'] = array( 'name' => array( 'width' => '40', 'label' => 'LBL_LIST_NAME', 'link' => true, 'default' => true ), 'date_entered' => array( 'width' => '15', 'label' => 'LBL_DATE_ENTERED', 'default' => true ), 'date_modified' => array( 'width' => '15', 'label' => 'LBL_DATE_MODIFIED' ), 'created_by' => array( 'width' => '8', 'label' => 'LBL_CREATED' ), 'assigned_user_name' => array( 'width' => '8', 'label' => 'LBL_LIST_ASSIGNED_USER' ), ); ?> Finalmente, voc vai definir a classe de PartsDashlet, que estende a classe DashletGeneric e controla todas as aes do dashlet. Voc precisa substituir um mtodo, o construtor, que apenas necessrio apontar o objeto DashletGeneric olhar nos lugares certos para as vrias definies de metadados de seu dashlet, como mostra a listagem 10-17 e tambm armazenado no diretorio Dashlets/PartsDashlet/. Listagem 10-17 Arquivo de classe PartsDashlet.php <?php require_once('include/Dashlets/DashletGeneric.php'); require_once('modules/Parts/Part.php'); class PartsDashlet extends DashletGeneric{ public function PartsDashlet($id,$def = null){ global $current_user, $app_strings; require('modules/Parts/metadata/partsdashletviewdef.php'); parent::DashletGeneric($id, $def); if(empty($def['title'])){ $this->title = translate('LBL_HOMEPAGE_TITLE', 'test_parts'); } $this->searchFields = $dashletData['PartsDashlet']['searchFields']; $this->columns = $dashletData['PartsDashlet']['columns']; $this->seedBean = new Part(); } } ?> Talvez voc precise limpar o arquivo de cache de dashlets.php, armazenado no diretrio cache/dashlets/, para seu recm-criado dashlet partes estejam disponveis para os usurios. O arquivo de cache usado para evitar a constante pesquisa do Dashlets disponveis pelo aplicativo. Vamos agora avanar e criar a necessidade de exibio personalizado para seu mdulo de peas do mdulo. ADICIONAR QUALQUER EXIBIES ADICIONAIS NECESSRIAS A rea maior, onde os desenvolvedores do mdulo de acar precisaro adicionar cdigo PHP personalizado exibies personalizadas. Eles so necessrios quando o mdulo mais do que implementar uma interface CRUD simples para os dados e talvez um boto personalizado necessria para permitir que dados a transferir-se de um mdulo para outro (um exemplo disso a opinio de converter levar no mdulo leva), ou talvez uma representao diferente dos dados necessria (como com o grfico de gantt e vistas de grade o mdulo de projetos). Uma necessidade comum para aqueles Construindo mdulos personalizados para sua prpria instncia de acar a interface para um sistema externo. Seu mdulo de peas, esta exatamente a necessidade voc tem, como voc vai pegar as imagens de suas partes de um sistema externo que fornece-los atravs de chamadas REST. Voc vai se lembrar que, no incio deste captulo voc adicionado um mtodo sua classe de feijo parte denominada fetchImageURL() que obtm o URL e um boto no seu DetailView para invocar um modo de exibio que exibe a imagem em uma janela popup. Listagem 10-18, voc adicionar a exibio real a seu mdulo que chamado, que ir exibir a imagem da parte para o usurio. Voc vai salvar o contedo no arquivo modules/Parts/views/view.image.php. Listagem 10-18 Exibio de imagem para o mdulo de peas <?php require_once('include/MVC/View/SugarView.php'); class PartsViewImage extends SugarView{ /** * Constructor */ public function __construct(){ parent::SugarView(); } /** * display the form */ public function display(){ if (!isset($_REQUEST['record'])){ return; } $partBean = new Part(); $partBean->retrieve($_REQUEST['record']); echo '<img src="' . $partBean->fetchImageURL() . '" />'; } } ?> Voc simplesmente busca o registro com o determinado registro ID (passado na varivel pedido de registro) e, em seguida, elemento de imagem eco o HTML para o usurio final com o atributo 'src' especificado com a URL retornada do mtodo Part::fetchImageURL(). Lembre-se de que voc precisa para registrar sua opinio tambm. No captulo 2, voc cobriu duas maneiras diferentes de fazer isso, seja atravs de um arquivo de controller.php com um mtodo que invoca-lo, ou adicionando um action_view_map.php com o modo de exibio especificado. Uma vez que no h qualquer cdigo de controlador adicional necessrio para seu mdulo, voc vai ir a rota fcil e adicionar apenas um arquivo de action_view_map.php, como mostra a listagem 10-19 no diretrio modules/Parts/. Listagem 10-19 arquivo action_view_map.php <?php $action_view_map['image'] = 'image'; ?> Depois de executar o reparo extenses no painel de administrao, sob a opo de reparo, usurios podem comear a utilizar o mdulo recm construdo. Com isso, voc tem um mdulo totalmente construdo. Agora voc deve ver que consta da lista de mdulo, na seo de cabealho do aplicativo. RESUMO Neste captulo, voc tomou a estrada longa e sinuosa de aprender a construir um mdulo de pea por pea. Voc primeiro analisado por que algum escolheria realmente fazer algo parecido com isto, ilustrando os casos de uso comum para o desenvolvimento do mdulo personalizado. Voc tambm mencionou que uma Terra mdia existe tambm, onde voc poderia usar o mdulo construtor para construir todos os itens tediosos, como metadados e vardefs, mas levar o pacote que ele construiu e personaliz-lo com a mo para atender suas necessidades. Em seguida voc foi passo a passo atravs de todos os componentes do mdulo e aprendeu como cri-los, usando um mdulo de exemplo chamado peas como o modelo para os exemplos de cdigo mostrados ao longo do caminho. Na verdade, voc pode encontrar todas as amostras de cdigo para este livro na rea de Download do cdigo-fonte do site da Apress em http://www.apress.com. Agora voc tem todo o fundo em SugarCRM para avanar com a construo de sua prpria aplicao em cima dele. Ns atravessaremos o processo de faz-lo usando todo o conhecimento que voc j aprendeu at agora. CRIANDO UMA APLICAO COMPLETA Parabns! Voc fez atravs de todos os detalhes detalhadssima, corajoso de internos de SugarCRM, aprendendo como tudo vai junto. Voc viu os frameworks MVC, metadados e Web Services. Voc aprendeu sobre gerenciamento de usurio e a equipe, Dashlets e temas. Voc trabalhou com as ferramentas de desenvolvedor rico de estdio, fluxos de trabalho e Construtor de mdulo. Voc sequer olhou fazendo modificaes nvel de cdigo para fazer acar de olhar e agir como voc quer. Com todo esse conhecimento, voc pode colocar tudo isso para uso prtico. Uma coisa que as equipes de gerenciamento de engenharia e produto no SugarCRM percebem que o CRM nunca uma soluo de "tamanho nico". Alis, no h uma definio exata do que uma aplicao de CRM deve ter e no deve ter. Cada mercado vertical de negcios tem diferentes requisitos e casos de uso precisam cobertos. Por exemplo, uma aplicao de CRM que iria ser destinada a um consultrio mdico muito diferente de um projetado para um call center. Ainda ambos os aplicativos tentam realizar os mesmos objetivos gerais de ser uma ferramenta para gerenciar seus relacionamentos com clientes e atividades de negcios e se encaixam bem dentro da definio de CRM. SugarCRM tem clientes e parceiros em todo o mundo que esto empurrando a definio de CRM, desta forma, projetar aplicativos de CRM que se encaixam perfeitamente com o seu negcio ou necessidades do mercado. A capacidade de criar aplicativos totalmente novos sobre SugarCRM o que realmente diferencia o pacote. Empresas costumavam ter que escrever suas prprias aplicaes personalizadas para fazer apenas esse tipo de coisa, mas essa proposio foi muito caro e demorado e muitas vezes trouxe resultados muito misturados. Eu costumava fazer apenas esse tipo de desenvolvimento em uma empresa do passado e olhando para trs eu poderia ter virado para fora aplicaes muito mais rpidas com uma forte ferramenta CRM, como o SugarCRM, disponvel para me construir aplicativos em cima de. Eu sei que eu no estava sozinho. Aposto que cada pessoa que l este livro tem feito esse tipo de desenvolvimento e refere-se a todas as etapas tediosas e demoradas, que voc deve percorrer para chegar a um aplicativo e ir. Como voc viu, o SugarCRM remove esses passos devido facilidade de construo de novos mdulos em cima do acar e modificar os j existentes para atender s suas necessidades. Neste captulo final, que o que voc vai fazer criar um aplicativo de negcios em cima do SugarCRM de forma totalmente segura de atualizao. Voc vai ler sobre os detalhes que voc aprendeu sobre nos captulos anteriores, por questes de brevidade, concentrando-se no design do aplicativo propriamente dito e o valor de usar o SugarCRM para fazer isso. PLANO DE FUNDO DO APLICATIVO O aplicativo que voc criar ser para a empresa mtica Pools de Pscoa, que est na necessidade desesperada de um aplicativo para ajudar a gerenciar sua piscina crescente e vendas de spa e servios de negcios. Um dos maiores problemas tm envolve a gesto de clientes, tentando responder a perguntas tais como quais produtos seus clientes prprios ou quando eles tm ltima manuteno-los. Agora, grande parte deste conhecimento est preso nas mentes daqueles que mais frequentemente trabalham com eles, mas se torna um problema quando um cliente pouco frequente deslizamentos de mente de todos. Ter um instantneo completo de um cliente na ponta dos dedos , definitivamente, uma coisa que poderia ajud-los a servio de seus clientes mais eficazmente. importante tambm distinguir entre suas contas corporativas e seus clientes de varejo, uma vez que cada grupo vai receber tratamento diferente. Tambm seria til para que sejam capazes de gerir seus negcios de servio mais eficaz. Direita agora, eles usam folhas de trabalho e um grande quadro de avisos para organizar todos os dia, juntamente com todos os trabalhos que precisam ser feitas. O problema aqui que ele requer muita ateno manual. Todos os dias os gerentes de servio sentar e organizar os postos de trabalho da tripulao, que exigem conhecimento especfico dos postos de trabalho (como quanto tempo eles levam, onde se situam, etc). Requer tambm ateno prioridade. Por exemplo, uma piscina em um grande cliente sendo para baixo requer a mxima prioridade enquanto algum precisando de uma banheira de hidromassagem aberta pode ser uma prioridade menor. Para cima, seria bom ser capaz de ter estimado e reais tempos necessrios para completar um trabalho, assim eles podem melhor otimizar seu servio de agendamento para ajud-los atravs das estaes ocupadas da Primavera e cair sem ter que empurrar suas tripulaes em longas horas de trabalho. Assim como muitas empresas, piscinas de Pscoa tem muitos fornecedores diferentes, trata de produtos, peas e outros suprimentos. Eles iriam encontr-lo til para ser capaz de ser que mais em sintonia o que seus vendedores de fornecem-los e quais partes trabalham com determinados produtos. Por exemplo, seria bom ser capaz de ver que peas de reposio esto disponveis para uma banheira de hidromassagem. Tambm seria til ser capaz de associar peas com uma chamada de servio, para que seja mais fcil saber o que necessrio puxado para mandar os caminhes de servio, bem como fornecer prestao de contas para peas usadas no campo. Se certas fontes esto quase esgotados, os responsveis pela ordenao gostaria de ser notificado sobre isso assim que eles podem reorden-las. Com tudo isso em mente, voc pode comear a projetar um aplicativo baseado em SugarCRM que ir atender suas necessidades e oferecem a facilidade de uso e inteligncia que ir ajud-los a gerenciar seus negcios, enquanto cresce. Vamos comear a projetar esta aplicao pea por pea e com ele veja como fcil usar o SugarCRM para a construo de um aplicativo. REPARTIO DOS VRIOS COMPONENTES Usaremos a ferramenta Construtor de mdulo para projetar a base do seu aplicativo. Portanto, os mdulos sero todos os mdulos de CRUD-estilo normais com base em modelos existentes de SugarObject que fornecem a funcionalidade genrica que voc precisa. Tabela 11-1 d uma repartio dos mdulos que voc vai construir. Module Description Customers Este mdulo ir basear-se no modelo de pessoa e conter todos os clientes de varejo com quem trabalham Jobs Com base no modelo de edio, voc vai usar este mdulo para acompanhar todas as chamadas de servio que faz de Pools de Pscoa Vendors Contm todos os fornecedores que trabalham com e baseia-se no modelo de empresa Vendor Contacts Contactos a vrios fornecedores que trabalham com, baseado no modelo de pessoa. Vendor Orders Ordens de faixas para vrias fontes que voc fez, com base no modelo de venda. Supplies Um mdulo bsico com informaes sobre os produtos vendidos, peas usadas com esses produtos, e outros suprimentos estoques de Pscoa piscinas e vende. TABELA 9 - MDULOS CONSTRUDOS PARA A APLICAO DE EASTER POOLS Desde a instalao de Sugar Community Edition do fora-de-caixa, voc estar usando o mdulo de contas e contatos para gerenciar seus clientes corporativos e o mdulo de documentos para facilitar o acesso a qualquer documentao de produto para todos os funcionrios. Voc tambm vai ser integrao com os mdulos de atividades (chamadas, reunies, tarefas, notas, E- mails) com seus clientes e fornecedores de mdulos, ento eles tm uma maneira de rastrear todas as comunicaes de que Pscoa piscinas tem com eles. Com um esboo de quais componentes voc vai usar em seu aplicativo Pools de Pscoa, vamos agora mover-se atravs da criao de cada um desses componentes usando o SugarCRM e ver quais personalizaes que voc precisa para construir isso. STUDIO Uma vez que voc vai estar usando vrios mdulos do fora-de-caixa com seu aplicativo, todas as personalizaes necessrias devem ser concludas atravs de Studio para que suas alteraes para ser segura de atualizao. Na maior parte, voc no precisar fazer muita personalizao aqui. Voc reutilizar o mdulo de contas e contatos do aplicativo principal, uma vez que elas definem muito bem o B2B estruturas de dados de gesto de vendas (Business-to-Business) que iro trabalhar com clientes corporativos dos Pools de Pscoa. Quanto as estruturas de dados destes mdulos, eles em grande parte permanecer inalterados, excepto para algumas adies s listas campo e mudanas para as relaes que vm de fora da caixa com acar CE. Vejamos o que voc estar fazendo para eles. CONTAS E CONTATOS A primeira coisa que voc estar fazendo a adio de campos para o mdulo de contas que ser somente leitura e reportar ao cliente informaes, tais como o balano total de faturas pendentes, data da ltima factura e a data do ltimo pagamento recebido, de cobrana, bem como uma janela de pop-up que pode dar uma anlise mais detalhada da facturao a histria. Voc no tem qualquer entrada de dados dentro do acar prprio para isso, mas em vez disso use o sistema de contabilidade existente piscinas de Pscoa e alguns scripts personalizados para empurrar esses dados ao acar. Voc vai olhar mais em como isso funcionaria mais tarde quando voc fala sobre as interfaces externas ao produto. Voc tambm vou acrescentar alguns campos mais para a facilidade de Pools de Pscoa. Uma questo que eles tinham estava planejando chamadas de servio, em particular as estimativas de tempo para o tempo de viagem para suas tripulaes do servio de planejamento, bem como dando-lhes uma maneira de encontrar o seu caminho at l. Uma maneira rpida e simples de fazer isso incorporar um mapa direita o DetailView para um cliente. Voc pode fazer isso adicionando um campo de iFrame para o mdulo de contas e especificando a URL padro como um modelo que o manipulador DetailView preencher automaticamente. A URL em uso : http://maps.google.com/maps?f=q&q={shipping_address_street}+{shipping_address_city}+{shipping_address_ state}+{shipping_address_postalcode}+{shipping_address_country}&source=embed&output=embed. Voc pode ver os resultados na figura abaixo:
FIGURA 79 - MAPA DE GOOGLE INCORPORADO NO DETAILVIEW A CONTAS Voc precisar tambm ajustar o tamanho do iFrame campo no modelo DetailView ento ele exibe totalmente nada mais 200 como o tamanho mximo deve funcionar muito bem. Alm disso, verifique se no h outro campo na coluna adjacente na visualizao, para que o mapa pode esticar para pegar em ambas as colunas. Tabelas 11-2 e 11-3 fornecem um resumo dos campos e relacionamentos que voc estar adicionando o mdulo de contas. Voc no precisar adicionar qualquer para o mdulo de contatos. Fields Description invoice_balance_c Currency: Armazena o saldo atual da fatura pendentes (somente leitura) last_invoice_date_c Date: Data da ltima factura (somente leitura) last_payment_date_c Date: Data do ltimo pagamento (somente leitura) map iFrame: Uso para embedded Google mapa FIGURA 80 - CAMPOS ADICIONADOS PARA O MDULO DE CONTAS Para as relaes na tabela 11-3, voc no ser capaz de adicion-los at os mdulos personalizados foram construdos na seo onde voc detalhar os mdulos personalizados voc vai construir seu aplicativo personalizado. Relate to Module Type Description Jobs One to Many Links para todos os trabalhos realizados para esta conta Supplies One to Many Links para todos os fornecimentos que comprou a conta TABELA 10 - RELAES ADICIONADAS PARA O MDULO DE CONTAS O mdulo de contas e contatos muito facilmente preencher as necessidades de gerenciamento de todas as contas comerciais. Mas e quanto a contas de varejo? Para isso, voc vai usar um mdulo separado mais projetado para o seu uso, que voc ver como criar usando o construtor de mdulo. MDULO CONSTRUTOR Agora, voc vai olhar no edifcio os novos mdulos necessrios para seu aplicativo. Para torn-lo simples, voc vai usar o construtor de mdulo para busc-la e ir primeiro e adicionar o cdigo personalizado mais tarde. Voc vai nomear seu pacote no mdulo Construtor EasterPools, com mdulo prefixo ep (assim os vrios mdulos que voc criar tero o prefixo de ep_ sobre eles).Voc vai comear olhando para o mdulo de clientes. CUSTOMERS B2C transaes (Business-to-Consumer) no so realmente tratadas de um ponto de vista de design no SugarCRM. A grande razo para isso simplesmente porque o mercado CRM a histrico B2B mais do que o B2C e CRM na paisagem B2C um mercado em evoluo. No entanto, com a flexibilidade de acar e as ferramentas de desenvolvedor ainda fcil de usar forte que vm com ele, voc pode facilmente construir um aplicativo de suporte a esses tipos de interaes. Voc vai basear seu mdulo no modelo de pessoa, que ir fornecer-nos com todos os campos necessrios para corresponder a um indivduo muito bem. Para obter consistncia, voc tambm vai fazer os mesmos tipos de personalizaes feitas para o mdulo de contas, bem como para o mdulo de clientes. Tabelas 11-4 e 11-5 contorno os campos necessrios e as relaes que voc vai adicionar, respectivamente. Fields Description invoice_balance_c Currency: Armazena o saldo atual da fatura pendentes (somente leitura) last_invoice_date_c Date: Data da ltima factura (somente leitura) last_payment_date_c Date: Data do ltimo pagamento (somente leitura) Map iFrame: Uso para embedded Google mapa TABELA 11 - CAMPOS ADICIONADOS PARA O MDULO DE CLIENTES Relate to Module Type Description Jobs One to Many Links para todos os trabalhos realizados para este cliente Supplies One to Many Links para todas as fontes que o cliente adquiriu Activities One to Many Links para todas as atividades para este cliente (chamadas, reunies, tarefas, notas, E-mails) TABELA 12 - RELAES ADICIONADAS PARA O MDULO DE CLIENTES Do ponto de vista do usurio final, cliente de B2C basicamente o mesmo que um cliente B2B como se relaciona com o resto do aplicativo. Ambos tm as mesmas relaes aos outros mdulos e muitos dos mesmos campos em comum (menos aquelas especficas para ser uma empresa ou uma pessoa). O maior motivo para a separao de mdulos, que no sejam as diferenas de campo entre eles, que piscinas de Pscoa pode gerenciar seus clientes corporativos e clientes de varejo separadamente. Cada grupo diferente da maneira que voc gerenci-los. Clientes corporativos tendem a ser mais servio completo do que o varejo ones e requerem muito mais ateno e prioridade quando eles tm solicitaes de servio. Clientes de varejo, muitas vezes, esto mais aptos a fazer certas coisas no seus prprios, como muitas tarefas simples de manuteno e reparos no- invasivos (claro, isso no verdadeiro para todos). Eles tambm tendem a ser mais baixo da escala de prioridade, simplesmente porque os clientes corporativos tm contratos com piscinas de Pscoa que ditam a garantias de nvel de servio, algo que muito poucos clientes de varejo tm. Devido a isso, os clientes corporativos so maior rendimento do que o varejo que assim fazer comparaes de applesto-mas entre eles no muito justo. Ter esta separao permite gerir o negcio melhor. Ele levanta alguns problemas quando voc est fazendo as relaes entre estes mdulos e os produtos e os postos de trabalho. Voc ver suas solues para esses problemas, como voc vai neste captulo, quando voc olha para adicionar o cdigo personalizado para os mdulos de postos de trabalho e produtos. JOBS Uma grande parte da avaliao dos requisitos para tal aplicativo original foi a capacidade de gerenciar o aspecto do servio do negcio piscinas de Pscoa. Voc observou um monte de coordenao e gesto feito nesta rea, e tendo as ferramentas para ajudar a ficar em cima disso seria muito til para o negcio como um todo. A base do seu mdulo de empregos ser o modelo de edio, que oferece praticamente todos os campos que voc vai precisar para ajudar a gerenciar seu mdulo. Voc vai fazer algumas modificaes para os campos como eles vm definidos para que o mdulo melhor se encaixa o que eles gostariam de fazer. Primeiro, voc vai modificar o campo de Status para terem mais valores relacionados ao servio suspenso, ou seja nova, programado, despachado, cancelado e concludo. Voc tambm vai ajustar o campo de resoluo para dar-lhe os mesmos valores que o campo de Status para melhor corresponder a uma chamada de servio, em vez de um bug de software, como o modelo de questes foi projetado para manipular. Isto pode ser segurado, modificando as matrizes ep_jobs_status_dom e ep_jobs_resolution_dom que sero adicionadas no arquivo custom/Extension/application/Ext/Language/en_us.test.php por SugarCRM depois que o mdulo implantado. Voc tambm adicionar um campo Flex se relacionam com uma lista personalizada definida de mdulos para relacionar o trabalho para incluir apenas as contas e o mdulo de clientes. Para uma coisa, voc vai precisar adicionar algum cdigo PHP para fazer como mdulo construtor e Studio fazer, mas no todas as personalizaes que voc precisa aqui esto fora da caixa (voc ver como fazer isso na seo de "Custom Code", deste captulo). Tabela 11-6 descreve o que voc precisar adicionar atravs do construtor de mdulo para este mdulo. Fields Description Flex Relate (internally consists of parent_name, parent_id, and parent_type) Usado para um trabalho de relativas a uma conta ou um cliente time_required_c Decimal: Quantidade de tempo necessrio para completar o trabalho TABELA 13 - CAMPOS ADICIONADOS PARA O MDULO DE POSTOS DE TRABALHO SUPRIMENTOS Principal negcio dos Pools de Pscoa envolve os produtos, peas e outros suprimentos que vendem aos seus clientes. Estes vm em uma infinidade de formas diferentes. Por exemplo, eles vendem kits de piscina e spas em tamanho real para seus clientes. Com isso, eles vendem o cloro e outros produtos qumicos usados para tratar a gua em suas piscinas e spas. Ento, se algo quebra na sua piscina ou spa, poder obter as peas de reposio necessrias para corrigi-lo. Estes so tambm muito inter-relacionados, com cada um dos principais produtos que eles vendem (spas, kits de piscina, aquecedores de piscina, filtros para piscinas) ter muitas peas de reposio que vo com eles. A maioria das peas de reposio trabalham sobre vrios produtos diferentes, ento isso complica o projeto correto das relaes tambm. Vou basear este mdulo no modelo bsico e adicionar uma relao que permite-lhe expandir-se sobre esse objetivo com cdigo personalizado mais tarde (Ver tabela 11-7). Relate to Module Type Description Jobs Many to Many Links para todos os trabalhos onde essa fonte usada Supplies Many to Many Links para todas as fontes relacionadas a esta oferta TABELA 14 - CAMPOS ADICIONADOS PARA O MDULO DE POSTOS DE TRABALHO Tabela 11-8 descreve o campo solitrio, que voc adicionar para este mdulo, que ir controlar o nmero de referncia da pea do fornecedor. Este campo vir a calhar mais tarde no captulo na seo "Custom Code" quando voc adicionar um processo de negcio para a reordenao de entregas do fornecedor. Fields Description vendor_ref_no Text field: Nmero de referncia da pea para o vendedor usar quando reordenao. TABELA 15 - CAMPOS ADICIONADOS PARA O MDULO DE SUPRIMENTOS FORNECEDORES, CONTATOS DE FORNECEDOR E ORDENS DE FORNECEDOR Fornecedores dos Pools de Pscoa tambm so uma parte crtica de seu fluxo de trabalho de negcios. Um monte de coordenao deve ter lugar em termos de gerenciamento de produtos, controle de estoque e atualizaes do sistema. Sem uma gesto adequada a fonte inteira e cadeias de servio desmoronar, destruindo o havoc em todos os seus clientes por no ter disponvel, as peas e suprimentos que precisam, ou levando-os a manter o inventrio extra na mo que pode levar meses para esgotar. Quando voc criar o mdulo de vendedores, voc precisa torn-lo mais do que apenas um rolodex de quem eles so, mas tambm devem fornecer suficiente inteligncia para dar dicas sobre o que eles fornecem para o negcio. A parte de base deste mdulo o mdulo de vendedores, que se basear no modelo de empresa. Voc tambm vai acompanhar os contatos que Pscoa piscinas tem nos escritrios de seus fornecedores, assim voc ter um mdulo de contatos de fornecedores, bem como, com base no modelo pessoa. Voc tambm adicionar o mdulo de ordens de fornecedor agora (com base no modelo de venda), que ir controlar a ordem em que voc fez para o fornecedor para reabastecer seus estoques. Voc no precisar adicionar quaisquer campos adicionais para qualquer um destes mdulos, uma vez que os modelos fornecem tudo que voc precisa para registrar todos os fatos vitais sobre seus fornecedores, incluindo telefone, endereo, informaes de e-mail e as encomendas. No entanto, voc precisar adicionar relacionamentos aqui para puxar tudo juntos, como mostrado nas tabelas 11-9, 11-10 e 11-11. Relate to Module Type Description Vendor Contacts One to Many Links para todos os contatos para este fornecedor. Vendor Orders One to Many Links para todos os pedidos feitos a este fornecedor. Supplies One to Links para todas as fontes deste fornecedor fornece. Many Activities One to Many Links para todas as atividades para este fornecedor (chamadas, reunies, tarefas, notas, E-mails). TABELA 16 - RELAES ADICIONADAS PARA O MDULO DE FORNECEDORES Relate to module Type Description Activities One to Many Links para todas as atividades para este fornecedor (chamadas, reunies, tarefas, notas, E-mails). TABELA 17 - CAMPOS ADICIONADOS PARA O MDULO DE SUPRIMENTOS Relate to module Type Description Supplies Many to Many Links para todos os fornecimentos encomendados com esta ordem de determinado fornecedor. TABELA 18 - CAMPOS ADICIONADOS PARA O MDULO DE SUPRIMENTOS CUSTOM CODE A ltima pea do quebra-cabea para seu aplicativo de acar adicionar algum cdigo personalizado para tornar as coisas agem do jeito que voc quer. Estas so as coisas que esto fora do escopo do que as ferramentas de estdio e o mdulo Construtor fornecem, mas, no entanto, mostram a flexibilidade da plataforma, j que todas essas modificaes so atualizao segura. Isto significa que quando voc atualizar sua verso do acar ou aplica patches de manuteno, as personalizaes no ser substitudas. Vamos comear analisando as modificaes que voc vai fazer a dois dos mdulos fora-de-thebox voc estiver trabalhando com: contas e contatos. CONTAS E CONTATOS Voc precisar atualizar os subpainis lista, onde voc vai esconder os subpainis para os mdulos de oportunidades, casos, Bug Tracker, projectos, campanhas e leva nos mdulos contas e contatos. Nenhum destes mdulos ser usado pelo seu aplicativo, portanto, faz mais sentido para remov-los. Existem duas maneiras de fazer isso. Uma forma usando os recursos de gerenciamento de ACL voc aprendeu sobre no captulo 5 para desabilitar o acesso a esses mdulos. Outra opo modificar as definies do layout dos mdulos, assim voc poderia deixar cair um arquivo de definies de layout atualizado dentro o diretrio custom/Extension/modules/modulename/Ext/Layoutdefs/ como o RemoveExtraSubpanels.php que mostra na listagem 11-1. Listagem 11-1 RemoveExtraSubpanels.php para a remoo de subpainis desnecessrias para o mdulo de contatos <?php $layout_defs['Contacts']['subpanel_setup']['opportunities'] = null; $layout_defs['Contacts']['subpanel_setup']['leads'] = null; $layout_defs['Contacts']['subpanel_setup']['cases'] = null; $layout_defs['Contacts']['subpanel_setup']['bugs'] = null; $layout_defs['Contacts']['subpanel_setup']['project'] = null; $layout_defs['Contacts']['subpanel_setup']['campaigns'] = null; ?> O exemplo mostra como isso feito para o mdulo de contatos. Para o mdulo de contas, basta substitua contatos para contas na listagem 11-1. Voc tambm estar adicionando algumas novas subpainis para o mdulo, nomeadamente os dos postos de trabalho, que iro mostrar a listagem de todas concludas e eventos prximos de servio para uma conta e os produtos o cliente adquiriu. JOBS Para cada mdulo contas e clientes, voc precisar adicionar uma relao para o vardefs para habilitar o Subpainel de empregos seja exibido corretamente no mdulo, como mostra a listagem 11-2. Listagem 11-2 Relao de postos de trabalho de contas <?php $dictionary["Accounts"]["fields"]["accounts_ep_jobs"] = array ( 'name' => 'accounts_ep_jobs', 'type' => 'link', 'relationship' => 'accounts_ep_jobs', 'source' => 'non-db', ); $dictionary["Accounts"]["relationships"]['accounts_ep_jobs'] = array ( lhs_module'=> 'Accounts', 'lhs_table'=> 'accounts', 'lhs_key' => 'id', 'rhs_module'=> 'ep_Jobs', 'rhs_table'=> 'ep_jobs', 'rhs_key' => 'parent_id', 'relationship_type'=>'one-to-many', 'relationship_role_column'=>'parent_type', 'relationship_role_column_value'=>'Accounts', ); ?> Voc vai precisar de um relacionamento similar no mdulo de clientes tambm. Listagem de 11-3 mostra como isso iria funcionar. Listagem 11-3 Relao de trabalhos de clientes <?php $dictionary["ep_Customers"]["fields"]["ep_customers_ep_jobs"] = array ( 'name' => 'ep_customers_ep_jobs', 'type' => 'link', 'relationship' => 'ep_customers_ep_jobs', 'source' => 'non-db', ); $dictionary["ep_Customers"]["relationships"]['ep_customers_ep_jobs'] = array ( 'lhs_module'=> 'ep_Customers', 'lhs_table'=> 'ep_customers', 'lhs_key' => 'id', 'rhs_module'=> 'ep_Jobs', 'rhs_table'=> 'ep_jobs', 'rhs_key' => 'parent_id', 'relationship_type'=>'one-to-many', 'relationship_role_column'=>'parent_type', 'relationship_role_column_value'=>'ep_Customers', ); Voc tambm adicionar uma relao para o mdulo de produtos aqui, para indicar peas ou suprimentos necessrios para este trabalho. Isso ajuda a cumprir a obrigao de avisar as equipes que precisam de tomar sobre os caminhes de servio com eles fora para chamar o servio. Outro requisito mencionado anteriormente foi uma maneira de ajudar a gerenciar a parte e fornecer o inventrio mais facilmente. Voc pode usar a relao de mdulos de empregos para ajudar com isso. Uma maneira fcil de faz- lo seria adicionar um gancho de lgica que acionado em salvar evento. A listagem 11-4 tem um exemplo de um, que deve ser salvo no diretrio custom/modules/ep_Jobs/ e nomeado ep_JobsHooks.php. Listagem 11-4 after_save gancho de lgica para o mdulo de postos de trabalho <?php require_once('modules/ep_Jobs/ep_Jobs.php'); require_once('modules/Accounts/Account.php'); class ep_JobsHooks{ public function updateProductInventory(SugarBean $bean,$event,$arguments){ if ( $bean->fetched_row['status'] != 'Dispatched' && $bean->status =='Dispatched' ) { $bean->load_relationship('ep_jobs_ep_supplies'); // load the relationship between Jobs and Supplies foreach ( $bean->build_related_list($bean->ep_jobs_ep_supplies->getQuery(),new LeadContact) as $ep_part) { $ep_part->on_hand = $ep_part->on_hand - 1; $ep_part->save(); } } } } ?> O que vai fazer esse gancho de lgica verificar para ver se o status do trabalho tiver sido definida para despachado, o que seria feito depois que o caminho foi carregado e deixou. Neste ponto, o inventrio est desaparecido, ento voc pode diminuir cada contagem de disponvel do produto em conformidade. Se por algum motivo, uma parte no necessria, ento ele pode ser verificado em e, em seguida, pode ser atualizado o inventrio de oferta. Voc tambm adicionar um boto acessvel para o DetailView do mdulo Jobs. Este boto ser usado para imprimir um mapa para chegar ao local de trabalho. Voc usar as informaes relacionadas a conta ou um cliente para construir um URL de mapas do Google que ir criar a rota de onde a empresa localiza-se o endereo que ele listado no registro do cliente. Construir o URL algo que voc vai fazer, substituindo o DetailView para o mdulo de postos de trabalho, como mostra a listagem 5-11. (O arquivo deve ser salvo como custom/modules/ep_Jobs/views/view.detail.php). Listagem 11-5 DetailView substituir para o mdulo de postos de trabalho <?php require_once('include/MVC/View/views/view.detail.php'); require_once('modules/Accounts/Account.php'); require_once('modules/ep_Jobs/ep_Jobs.php'); class ep_JobsViewDetail extends ViewDetail { public function __construct() { parent::ViewDetail(); } public function display() { $business_address = '123 Main Street Anytown, OH 44444'; $customer_address = ''; if ( !empty($this->ep_custome5229stomers_ida) ) { $bean = new Account(); $bean->retrieve($this->ep_custome5229stomers_ida); if ( !empty($bean->id) ){ $customer_address = "{$bean->shipping_address_address}, {$bean- >shipping_address_city}, {$bean->shipping_address_state}, {$bean->shipping_address_postalcode}"; } } elseif ( !empty($this->ep_jobs_ac056eccounts_ida) ) { $bean = new ep_Jobs(); $bean->retrieve($this->ep_custome5229stomers_ida); if ( !empty($bean->id) ){ $customer_address = "{$bean->primary_address_address}, {$bean- >primary_address_city}, {$bean->primary_address_state},{$bean->primary_address_postalcode}"; } } $this->ss- >assign("MAP_URL","http://maps.google.com/maps?f=d&source=s_d&saddr={$business_address}&daddr={$c ustomer_address}"); parent::display(); } } ?> Em seguida, voc adicionar o boto para acionar esta ao sobre o DetailView fazendo uma pequena modificao para o modelo de metadados, como mostrado na Listagem 6-11 (salvar o contedo para o custom/modules/ep_Jobs/metadata/detailviewdefs.php). Listagem 11-6 Adicionando o mapa de Get para boto de emprego para os metadados DetailView <?php require('modules/ep_Jobs/metadata/detailviewdefs.php'); // include in the existing view defs $viewdefs['ep_Jobs']['DetailView']['templateMeta']['form']['buttons'][] = array( 'customCode' => '<input title="{$MOD.LBL_GET_MAP_TO_JOB}" ' . ' accesskey="{$APP.LBL_GET_MAP_TO_JOB_KEY}" ' . ' class="button" ' . ' onclick=\'document.location.href = "{$MAP_URL}"; return false;\' ' . ' name="button" ' . ' value="{$APP.LBL_GET_MAP_TO_JOB_TITLE}" ' . ' type="submit">' ); ?> SUPRIMENTOS O design do mdulo suprimentos ter mltiplas facetas a ele. Primeiramente fora, voc vai permitir que cada oferta ter uma relao muitos-para-muitos com outras fontes, o que permite que qualquer alimentao ser relacionada a um nmero de diferentes fontes. Em seguida, voc precisar de categorizar cada item no mdulo suprimentos para ser um de um produto (ou seja, um produto desenvolvido que eles vendem, como um kit spa ou piscina), uma parte que vai para um dos produtos que eles vendem ou servio, ou um item de suprimento, como produtos qumicos da piscina, que ir junto com um dos produtos que eles vendem ou suportam. Com esses dois itens no lugar, voc pode comear a construir a web de como produtos, peas e suprimentos so todos relacionados entre si. O nico problema com a configurao de relaes como esta que tem que ele intermixes os produtos, peas e suprimentos juntos no Subpainel de suprimentos em DetailView cada registro, tornando difcil dizer a diferena entre cada tipo. Se voc se lembra do captulo 3, voc observou que cada definio de metadados Subpainel pode especificar argumentos de clusula adicional onde a broca mais para baixo para mostrar os registros que voc quer no Subpainel. Voc pode usar esse recurso para melhorar a vista Subpainel. Primeiro, voc vai criar trs pontos de vista Subpainel diferentes, um para cada um dos produtos, peas e suprimentos, como mostrado na listagem 11-7. Listagem 11-7 Igual arquivos de metadados de produtos apenas, apenas peas e suprimentos subpainis nicas relatedParts.php <?php $module_name='ep_Supplies'; $subpanel_layout = array( 'top_buttons' => array( array('widget_class' => 'SubPanelTopCreateButton'), array('widget_class' => 'SubPanelTopSelectButton', 'popup_module' => $module_name), ), 'where' => 'item_type = "Part"', 'list_fields' => array( 'name'=>array( 'vname' => 'LBL_NAME', 'widget_class' => 'SubPanelDetailViewLink', 'width' => '45%', ), 'date_modified'=>array( 'vname' => 'LBL_DATE_MODIFIED', 'width' => '45%', ), 'edit_button'=>array( 'widget_class' => 'SubPanelEditButton', 'module' => $module_name, 'width' => '4%', ), 'remove_button'=>array( 'widget_class' => 'SubPanelRemoveButton', 'module' => $module_name, 'width' => '5%', ), ), ); ?> relatedProducts.php <?php $module_name='ep_Supplies'; $subpanel_layout = array( 'top_buttons' => array( array('widget_class' => 'SubPanelTopCreateButton'), array('widget_class' => 'SubPanelTopSelectButton', 'popup_module' => $module_name), ), 'where' => 'item_type = "Product"', 'list_fields' => array( 'name'=>array( 'vname' => 'LBL_NAME', 'widget_class' => 'SubPanelDetailViewLink', 'width' => '45%', ), 'date_modified'=>array( 'vname' => 'LBL_DATE_MODIFIED', 'width' => '45%', ), 'edit_button'=>array( 'widget_class' => 'SubPanelEditButton', 'module' => $module_name, 'width' => '4%', ), 'remove_button'=>array( 'widget_class' => 'SubPanelRemoveButton', 'module' => $module_name, 'width' => '5%', ), ), ); ?> relatedSupplies.php <?php $module_name='ep_Supplies'; $subpanel_layout = array( 'top_buttons' => array( array('widget_class' => 'SubPanelTopCreateButton'), array('widget_class' => 'SubPanelTopSelectButton', 'popup_module' => $module_name), ), 'where' => 'item_type = "Supply"', 'list_fields' => array( 'name'=>array( 'vname' => 'LBL_NAME', 'widget_class' => 'SubPanelDetailViewLink', 'width' => '45%', ), 'date_modified'=>array( 'vname' => 'LBL_DATE_MODIFIED', 'width' => '45%', ), 'edit_button'=>array( 'widget_class' => 'SubPanelEditButton', 'module' => $module_name, 'width' => '4%', ), 'remove_button'=>array( 'widget_class' => 'SubPanelRemoveButton', 'module' => $module_name, 'width' => '5%', ), ), ); ?> Com cada uma das vistas Subpainel metadados definidas, o prximo passo configurar as definies de Subpainel para o mdulo de suprimentos. Voc vai fazer referncia cada um dos arquivos de metadados Subpainel acima criada na listagem 11-7, adicionando ttulos diferentes para cada um para que o usurio pode diferenciar, no qual o contedo deles . Listando 11-8 mostra como isso feito (salve o arquivo como custom/Extension/modules/ep_Supplies/Ext/Layoutdefs/extrasubpanels.php). Listagem 8-11 Subpainel definies para o mdulo de suprimentos <?php $layout_defs["ep_Supplies"]["subpanel_setup"]["ep_supplies_ep_supplies_1"] = array ( 'order' => 110, 'module' => 'ep_Supplies', 'subpanel_name' => 'relatedProducts', 'sort_order' => 'asc', 'sort_by' => 'id', 'title_key' => 'LBL_RELATED_PRODUCTS', 'get_subpanel_data' => 'ep_supplies_ep_supplies', 'top_buttons' =>array( 0 =>array( 'widget_class' => 'SubPanelTopCreateButton', ), 1 => array ( 'widget_class' => 'SubPanelTopSelectButton', 'mode' => 'MultiSelect', ), ), ); $layout_defs["ep_Supplies"]["subpanel_setup"]["ep_supplies_ep_supplies_2"] = array ( 'order' => 120, 'module' => 'ep_Supplies', 'subpanel_name' => 'relatedParts', 'sort_order' => 'asc', 'sort_by' => 'id', 'title_key' => 'LBL_RELATED_PARTS', 'get_subpanel_data' => 'ep_supplies_ep_supplies', 'top_buttons' => array ( 0 => array ( 'widget_class' => 'SubPanelTopCreateButton', ), 1 => array ( 'widget_class' => 'SubPanelTopSelectButton', 'mode' => 'MultiSelect', ), ), ); $layout_defs["ep_Supplies"]["subpanel_setup"]["ep_supplies_ep_supplies_3"] = array ( 'order' => 130, 'module' => 'ep_Supplies', 'subpanel_name' => 'relatedSupplies', 'sort_order' => 'asc', 'sort_by' => 'id', 'title_key' => 'LBL_RELATED_SUPPLIES', 'get_subpanel_data' => 'ep_supplies_ep_supplies', 'top_buttons' => array ( 0 => array ( 'widget_class' => 'SubPanelTopCreateButton', ), 1 => array ( 'widget_class' => 'SubPanelTopSelectButton', 'mode' => 'MultiSelect', ), ), ); unset(layout_defs["ep_Supplies"]["subpanel_setup"]["ep_supplies_ep_supplies"]); ?> Voc vai notar que a adio da chamada unset() para um Subpainel existente. Isto porque voc construiu este mdulo no mdulo construtor e adicionado o relacionamento l tambm, ento eles j definem um Subpainel para todos os fornecimentos. Isso significa que voc precisar desativar aquele criado pelo seu DetailView para evitar confuso para o usurio final. A maneira mais fcil de fazer isso simplesmente unset() o seu valor no array $layout_defs. Voc tambm tem uma relao de uma fonte para uma conta ou um cliente. Esta relao permite piscinas de Pscoa sabe o que os clientes compraram e produtos que eles usam. As vantagens de ter este link so numerosos. Por exemplo, pode ajudar o gerente de servio para saber quais partes de substituio precisam sair para um cliente, se algo se rompe ou se uma fonte tem um recall. Gerente de vendas de piscinas de Pscoa pode facilmente encontrar os clientes que atualmente tem a pea e podem agendar atendimentos para fazer qualquer trabalho de substituio necessrios. Para adicionar tal uma Subpainel, voc precisar criar um Subpainel de coleo, que um que rene dados de vrios mdulos e apresenta-los como um. O importante aqui para especificar os mdulos voc vai puxar juntos (no caso, apenas contas e clientes) e, em seguida, verifique se voc tem correspondncia Subpainel exibio de metadados para eles (o que voc vai definir como ForJobs). Listagem 9-11 mostra como tudo isso vem junto. Listagem de 11-9 Subpainel definies para um combinado Subpainel de clientes/contas <?php $layout_defs["ep_Items"]["subpanel_setup"]['clients'] => array( 'order' => 100, 'sort_order' => 'desc', 'sort_by' => 'date_start', 'title_key' => 'LBL_ACTIVITIES_SUBPANEL_TITLE', 'type' => 'collection', 'subpanel_name' => 'activities', //this values is not associated with a physical file. 'header_definition_from_subpanel'=> 'accounts', 'module'=>'Activities', 'collection_list' => array( 'accounts' => array( 'module' => 'Accounts', 'subpanel_name' => 'ForJobs', 'get_subpanel_data' => 'accounts', ), 'customers' => array( 'module' => 'ep_Customers', 'subpanel_name' => 'ForJobs', 'get_subpanel_data' => 'ep_customers', ), ) ); ?> FORNECEDORES O mdulo de fornecedores, voc ir adicionar alguma lgica para os relacionamentos e subpainis. Voc adicionar uma relao para o mdulo de produtos existentes, assim voc sabe quem o fornecedor e os itens que voc vende. O que acontece quando algum precisa reordenar um item dos fornecedores? Para acompanhamento, voc adicionar um mdulos de ordens do fornecedor, que vo ligar para o mdulo de produtos (assim voc tem uma histria da qual ordena que fizeram no passado para determinado produto e que fornece boa percepo de quantas vezes eles so colocar ordens em uma parte), bem como o mdulo de vendedores para mostrar quais ordens so feitas para o fornecedor. Voc ainda vai dividir os subpainis em duas partes assim como voc fez para as subpainis de produtos na seo anterior, para que voc pode seguir ordens pendentes e ordens histricas em painis separados. Listagem de 11-10 mostra como fazer isso. Listagem de 11-10. Igual arquivos de metadados de produtos apenas, apenas peas e suprimentos subpainis nicas currentOrders.php <?php $module_name='ep_VendorOrders'; $subpanel_layout = array( 'top_buttons' => array( array('widget_class' => 'SubPanelTopCreateButton'), array('widget_class' => 'SubPanelTopSelectButton', 'popup_module' => $module_name), ), 'where' => 'order_status != "Completed"', 'list_fields' => array( 'name'=>array( 'vname' => 'LBL_NAME', 'widget_class' => 'SubPanelDetailViewLink', 'width' => '45%', ), 'date_entered'=>array( 'vname' => 'LBL_DATE_ENTERED', 'width' => '45%', ), 'edit_button'=>array( 'widget_class' => 'SubPanelEditButton', 'module' => $module_name, 'width' => '4%', ), 'remove_button'=>array( 'widget_class' => 'SubPanelRemoveButton', 'module' => $module_name, 'width' => '5%', ), ), ); ?> previousOrders.php <?php $module_name='ep_VendorOrders'; $subpanel_layout = array( 'top_buttons' => array( array('widget_class' => 'SubPanelTopCreateButton'), array('widget_class' => 'SubPanelTopSelectButton', 'popup_module' => $module_name), ), 'where' => 'order_status = "Completed"', 'list_fields' => array( 'name'=>array( 'vname' => 'LBL_NAME', 'widget_class' => 'SubPanelDetailViewLink', 'width' => '45%', ), 'date_entered'=>array( 'vname' => 'LBL_DATE_ENTERED', 'width' => '45%', ), 'edit_button'=>array( 'widget_class' => 'SubPanelEditButton', 'module' => $module_name, 'width' => '4%', ), 'remove_button'=>array( 'widget_class' => 'SubPanelRemoveButton', 'module' => $module_name, 'width' => '5%', ), ), ); ?> SubPanelDefintions <?php $layout_defs["ep_Vendors"]["subpanel_setup"]["ep_vendors_ep_vendororders_1"] = array ( 'order' => 110, 'module' => 'ep_Vendors', 'subpanel_name' => 'currentOrders', 'sort_order' => 'asc', 'sort_by' => 'id', 'title_key' => 'LBL_CURRENT_ORDERS', 'get_subpanel_data' => 'ep_vendors_ep_vendororders', 'top_buttons' => array ( 0 => array ('widget_class' => 'SubPanelTopCreateButton',), 1 => array ( 'widget_class' => 'SubPanelTopSelectButton', 'mode' => 'MultiSelect', ), ), ); $layout_defs["ep_Vendors"]["subpanel_setup"]["ep_vendors_ep_vendororders_2"] = array ( 'order' => 120, 'module' => 'ep_Vendors', 'subpanel_name' => 'previousOrders', 'sort_order' => 'asc', 'sort_by' => 'id', 'title_key' => 'LBL_PREVIOUS_ORDERS', 'get_subpanel_data' => 'ep_vendors_ep_vendororders', 'top_buttons' => array ( 0 =>array ('widget_class' => 'SubPanelTopCreateButton',), 1 =>array ( 'widget_class' => 'SubPanelTopSelectButton', 'mode' => 'MultiSelect', ), ), ); ?> Voc tambm adicionar uma maneira de simplificar o processo de encomenda, adicionando um boto para o suprimentos DetailView chamado reordenar que vai pedir um item ser reordenadas. Este boto ir disparar uma ao de reordenar o mdulo de produtos que ir adicionar o produto ao mdulo de ordens de fornecedor, atribuindo-o para o usurio de reordenar que pode, em seguida, passar e realmente fazer a reordenao. Listagem de 11-11 mostra como voc pode adicionar sua ao por meio de modificar o controlador para o mdulo de produtos. Listagem 11-11 Reordenar a ao, o controlador de suprimentos <?php require_once("modules/ep_VendorOrders/ep_VendorOrders.php"); class ep_SuppliesController extends SugarController{ public function __construct(){ parent::SugarController(); } public function action_reorder(){ global $current_user; if ( empty($this->bean->id) ){ sugar_die("A record number must be specified to reorder"); } $bean = new ep_VendorOrders; $bean->name = $this->bean->name; $bean->status = 'Requested'; $bean->assigned_user_id = $current_user->retrieve_user_id('reorder'); $bean->save(true); $this->bean->load_relationship('ep_supplies_ep_vendororders'); $this->bean->add($bean->id); $this->bean->status = 'On Reorder'; $this->bean->save(); SugarApplication::redirect('index.php?module=ep_Supplies&action=DetailView&record=' . $this->bean->id . ''); } } ?> Voc tanto adiciona o produto para o mdulo de ordens de fornecedor como atualizar status do produto no reordenar e link do produto a reordenar solicitar para que todos em piscinas de Pscoa sabem que o produto no est disponvel, mas que reordenar e de que o estatuto de reordenar. GANCHOS DE FACTURAO Piscinas de Pscoa j tem um sistema de contabilidade existente em casa que o SugarCRM no vai sequer tentar replicar. A maioria das funes de contabilidade normalmente so considerados fora do escopo do que uma aplicao de CRM usada, portanto, os requisitos para aplicao dos Pools de Pscoa para integrar a facturao em suas chamadas de sistema para exportao e importao de dados em acar, mantendo o pesado trabalho de contabilidade com segurana nos confins de seu sistema existente. Voc tem dois objetivos para realizar aqui em relao a trabalhar com contabilidade. A primeira fornecer uma maneira de obter informaes sobre o trabalho para o sistema de contabilidade para que o cliente pode ser faturado. H um nmero de solues aqui, de escrever um personalizado interface entre os dois que realmente iro criar a factura apenas dando os analistas de conta a receber um relatrio dirio de postos de trabalho prontos para ser faturado. Agora Pscoa piscinas ainda tem um monte de inteligncia humana para tratar na cobrana de um cliente, ento a melhor maneira de lidar com isso simplesmente relatando as informaes para a contabilidade. Mas voc pode salvar uma rvore e fazer com que o processo de mover muito mais rpido por ter um e-mail de fluxo de trabalho a sair quando o trabalho est marcado como pronto para nota fiscal, que permitiria que o possvel faturamento mesmo do dia de um cliente por servios prestados. Isso tambm d a capacidade de usar seu e-mail como um fluxo de trabalho para o faturamento os analistas. Voc pode at adicionar uma opo no e-mail que dispararia o trabalho a ser marcado como facturado para melhor agilizar o processo (Ver listagem 11-12). Listando 11-12. Exibio de nota fiscal que ser usada pelos clientes e mdulos de contas <?php require_once('include/MVC/View/SugarView.php'); class ViewInvoices extends SugarView{ public function __construct(){ $this->options['show_title'] = false; $this->options['show_header'] = false; $this->options['show_footer'] = false; $this->options['show_subpanels'] = false; $this->options['show_search'] = false; parent::SugarView(); } public function display(){ global $mod_strings, $app_strings; $this->ss- >assign("MODULE_TITLE",get_module_title($mod_strings['LBL_MODULE_NAME'],$mod_strings['LBL_MODULE _NAME'] . ': ' . $app_strings['LBL_INVOICES'],true)); // Get the invoice data from our accounting system; it uses XML to do so $returnXML =file_get_contents("http://accounting.local/getInvoiceHistory?customer_id={$this- >bean->accounting_id}"); $xml = new SimpleXMLElement($returnXML); $invoices = array(); foreach ( $xml->invoice as $invoice ) { $invoices = array( 'date' => $invoice->date, 'amount' => $invoice->amount, 'due' => $invoice->due, ); } $this->ss->assign('invoices', $invoices); $this->ss->display('custom/include/MVC/tpls/invoices.tpl'); } } ?> Agora na listagem 11-13, voc definir o modelo de Smarty usado para exibir esses dados. No nada mais do que uma tabela HTML simples. Listagem 11-13 invoices.tpl file <?php {$MODULE_TITLE} {foreach from=$invoice key=key item=item name=rows} {if $smarty.foreach.rows.first} <table class="other view"> <tr> <th>{$APP.LBL_INVOICE_DATE}</th> <th>{$APP.LBL_INVOICE_AMOUNT}</th> <th>{$APP.LBL_INVOICE_DUE}</th> </tr> {/if} <tr> <td>{$item.date}</td> <td>{$item.amount}</td> <td>{$item.due}</td> </tr> {if $smarty.foreach.rows.last} </table> {/if} {foreachelse} {$APP.LBL_NO_RECORDS_FOUND} {/foreach} ?> Assim como voc construiu uma maneira para olhar as faturas pendentes que tem um cliente, voc tambm precisar definir uma maneira de obter faturas para seu sistema de contabilidade. Voc j fez a primeira parte do presente no mdulo de postos de trabalho, definindo um campo checkbox pronto para nota fiscal para indicar ao seu sistema de contabilidade que voc est pronto para faturar um cliente para o trabalho de servio que voc tenha feito para eles. Eu mencionei no incio deste captulo, quando voc olhou para o mdulo de clientes que o processo de faturamento para piscinas de Pscoa tem lgica humana nele, e eles escolheram no que incluem em seu aplicativo baseado em SugarCRM. No entanto, automatizar a transferncia de informaes para a contabilidade definitivamente uma parte desse processo. Voc pode automatizar esta usando ganchos de lgica. Primeiro, voc vai adicionar um gancho de lgica, para que onde prontas a factura checkbox est marcada que voc vai atribuir automaticamente a factura para a conta de usurio de facturao (que devero ser criadas separadamente). Listagem 11-14 mostra o gancho esta lgica que gostaria. Listagem 11-14 Jobs before_save logic Book <?php require_once('modules/ep_Jobs/ep_Jobs.php'); require_once('modules/Accounts/Account.php'); class ep_JobsHooks{ public function assignToInvoicing(SugarBean $bean,$event,$arguments){ global $current_user; if ( !$bean->fetched_row['ready_to_invoice'] && $bean-> ready_to_invoice ){ $bean->assigned_user_id = $current_user->retrieve_user_id('invoicing'); } } } Em seguida voc vai ativar notificaes dentro do configuraes de e-mail. Isto ir enviar automaticamente uma notificao por email quando um registro atribudo a um usurio, que neste caso ir notificar o usurio de facturao (voc vai definir este quem est manipulando a facturao para piscinas de Pscoa) para ser notificado de que um trabalho est pronto para ele a facturar. RETOQUES FINAIS Agora que voc j construiu todos os mdulos para seu aplicativo e configurado o seu sistema de contabilidade externa para integrar com seu aplicativo recentemente projetado apenas para piscinas de Pscoa, vamos agora limpar alguns restantes peas. A primeira coisa que voc vai querer fazer configurar os mdulos disponveis para usurios do aplicativo SugarCRM de Pools de Pscoa. Voc pode faz-lo de duas maneiras diferentes: a primeira apenas ocultar as guias de no utilizao da interface do usurio atravs da opo Configurar guias. O nico problema com esta abordagem que ela s esconde as abas, mas verdadeiramente no desabilitar os mdulos. Qualquer usurio pode apenas digite a URL para acessar qualquer mdulo no sistema. A nica maneira de realmente bloquear o acesso a esses mdulos que voc no est usando pela ACL papis, ento voc vai adicionar um novo um usurio chamado no painel de administrao de gerenciamento de funo para fazer isso.
FIGURA 81 - USERS ROLE Voc tambm deve personalizar o aplicativo um pouco para fazer a correspondncia de branding que usado no resto da empresa. A nica parte mais importante do sucesso de qualquer aplicativo de negcios a aceitao do usurio. Uma boa maneira de conseguir isso tornar o aplicativo, no apenas fcil de usar, mas visualmente atraente e ter a aparncia que ele integra o fluxo para o resto da empresa. Sua primeira tarefa em conseguir isso deve primeiro definir a empresa imagem de logotipo que usada no aplicativo e exibida no cabealho da pgina. Voc pode fazer isso muito facilmente atravs das configuraes do sistema no painel de administrao, apenas carregando a imagem que voc deseja usar para sua instncia (veja a Figura 11-3).
FIGURA 82 - SYSTEM SETTINGS SECTION FOR CHANGING THE COMPANY LOGO Voc tambm pode fazer essa alterao, largando a imagem no diretrio custom/themes/default/images, nomeando company_logo.png (ou company_logo.gif), se for uma imagem GIF. Um recurso interessante aqui que tenha sido adicionado com o novo quadro de tema introduzido no acar 5.5 que voc pode fazer o upload de uma imagem de qualquer tamanho e dimenso, e sero automaticamente redimensionada corretamente para caber no cabealho sem fazendo com que a imagem parea desproporcional. Voc tambm deseja personalizar sua seleo de tema tambm. Para manter o treinamento do usurio final consistente para todos aqueles que usaro a nova aplicao dos Pools de Pscoa, eles decidiram padronizar o tema RipCurl (principalmente devido ao seu tema aqutico-como, uma vez que se trata de um negcio de piscina). Para fazer isso, voc vai alterar o arquivo config XML, que armazena a configurao padro de acar especificar a configurao de default_theme para RipCurl em vez do tema padro do acar. Em seguida, voc pode desativar todos os outros temas na seo Configuraes de tema do painel de administrao, como voc v na Figura 11-4.
FIGURA 83 - THEMES SETTINGS OF THE ADMIN PANEL Estas mudanas simples podem parecer coisas menores (e eles so na maior parte), mas os detalhes como este que fazem a diferena para qualquer negcio. Mencionei anteriormente nesta seo a idia de aceitao do usurio e seu papel no sucesso de qualquer implantao de um aplicativo seja baseada em SugarCRM ou no. A diferena com SugarCRM d-lhe como um desenvolvedor de ferramentas para permitir a personalizao de seu aplicativo, fazendo com que estes toques finais fcil de fazer. RESUMO Neste captulo, voc usou todo o conhecimento acumulado ao longo de todo o livro e coloc-lo para uso prtico, projetando uma aplicao de negcios para uma empresa. O negcio mtico chamado Pools de Pscoa tinha os requisitos de criao de um aplicativo para gerenciar seus negcios em expanso. Em particular, eles precisavam de gesto da sua base de clientes diversificada abrangidos os clientes comerciais, bem como clientes de varejo que necessitam de produtos, peas, suprimentos e servios para suas piscinas e spas e a capacidade de facilmente e rapidamente ser capaz de dizer quais os produtos que eles prprios e a histria das nomeaes de servio que fizeram. Precisavam tambm de melhor gesto do seu negcio de servios, incluindo o estoque de peas, agendamento e priorizando os pedidos e automatizando a notificao de quando a fatura de um cliente. Gerenciamento de fornecedor tambm foi crtico, necessitando ambas insights sobre as peas, produtos e relacionamentos de suprimentos, bem como acompanhamento de pedidos feitos. Pedao por pedao, voc viu a versatilidade do SugarCRM brilhar aqui, mostrando como fcil estender e construir sobre ele para atender todas as necessidades. Voc construiu vrios novos mdulos e reutilizado algumas tambm, adicionando campos e relacionamentos adicionais para cumprir os requisitos para a aplicao, bem como adicionar algumas novas habilidades agradveis. Alm disso, voc adicionou a integrao externa, primeiro com o Google Maps para fornecer informaes de mapeamento para equipes de servio dos Pools de Pscoa para ajud-los a chegar a seus locais de trabalho. Voc adicionou a integrao em um sistema de conta j existente usando REST Web Services e o sistema de notificaes de envio interno que vem com o SugarCRM. Voc, em seguida, aproveitou um momento para adicionar algumas ltimas mudanas para seu aplicativo para limp-lo, escondendo os mdulos que voc no estar usando e tm coincidir a marca j existente usado por piscinas de Pscoa. O aplicativo de exemplo que voc olhou como construir neste captulo um bom modelo sobre como personalizar o acar para atender s suas necessidades. Ferramentas do desenvolvedor, que vm com enable acar para decolar seu aplicativo facilmente e de l voc pode adicionar suas prprias personalizaes de nvel de cdigo para que o aplicativo cumprir suas exigncias. Se h uma coisa que define SugarCRM para alm da embalagem sua versatilidade e com que todas as empresas possuem uma das caractersticas mais importantes para ter suas necessidades sempre em mudana assim seu aplicativo pode crescer com sua empresa.