상단

오픈소스로 제공되는, On-Premise/On-Demand/Appliance 방식의 CRM인 sugarCRM (Sugar Community Edition)을 소개한다.

 
 
 

Document


 
 
 

관리자 가이드


 

로그 설정

 
  • 로그 파일

    • $SUGAR_HOME/include/SugarLogger/LoggerManager.php

    • $SUGAR_HOME/include/SugarLogger/SugarLogger.php

     
  • $SUGAR_HOME/config.php에서 로그 설정

    log_dir : 로그가 저장되는 폴더 
    log_file : 로그 파일명, 초기값은 "sugarcrm.log" 
    log_memory_usage : 
    logger => level : 로그 레벨 (debug, info, error, fatal, security, off) logger => file :ext : 로그 파일 확장자, 초기값은 ".log" :name : 로그 파일명, 초기값은 "sugarcrm" :dateFormat : 날자 포맷 :maxSize : 로그 파일 최대 크기 :maxLogs : 로그 파일 최대 갯수 :suffix : 로그 파일 뒤에 붙는 문자열, 초기값은 "%m_%Y"

  • 프로그램에서 로그 남기기

 
 
 $GLOBALS['log']('log'.md)->debug('로그 메시지');
 $GLOBALS['log']('log'.md)->info('로그 메시지');
 

License 표시 변경

 
  • vi include/MVC/View/SugarView.php

    • 666 라인에 있는 $copyright 를 변경 한다.

 
 

한글팩 제작

 

SugarCRM의 한글팩을 만들기 위해 en_us 언어로 부터 ko_kr 파일을 추출하여 한글 언어팩을 작성 한다.

 
  • 한글팩 작성을 위한 폴더 생성

 
 
 mkdir /tmp/sugar            #--- 다운로드 받은 SugarCE-6.1.1.zip의 압축을 여기에 푼다.
 mkdir /tmp/sugar_ko_kr 
 
  • ant를 사용하여 언어로 부터 한글 파일을 복사하기 위한 build 파일을 만든다.

    • vi /tmp/sugar_ko_kr/build.xml

 
 
 
 
    
    
 
     
 
    
        
            
        
 
        
            
            
                
                
                
                
                
                
            
        
    
 
 
  • 영어 파일을 복사하여 한글 파일로 이름만 변경 한다. (위에서 만든 build.xml 파일 사용)

 
 
 cd /tmp/sugar_ko_kr
 ant init
 
  • vi /tmp/sugar_ko_kr/manifest.php

 
 
  array (
                'exact_matches' => array(),
                'regex_matches' => array (
                        0 => "6\.6\.1.*"
                ),
        ),
        'acceptable_sugar_flavors' => array (
                0 => 'CE',
                1 => 'PRO',
                2 => 'ENT',
        ),
        'name'                  => 'Korean Language Pack',
        'description'           => 'Korean Language Pack',
        'author'                => 'pnuskgh',
        'published_date'        => '2011/01/23',
        'version'               => '0.1',
        'type'                  => 'langpack',
        'icon'                  => '',''
        'is_uninstallable'      => true,
 );
 
 $installdefs = array(
        'id'=> 'langpack_ko_kr', 
 
        'copy' => array(
                array('from'=> '',
                          'to'=> '.',
                ),
        ),
 );
 ?>
 
  • SugarCRM 한글팩(langpack_ko_kr.zip) 작성

    • /tmp/sugar_ko_kr/ 폴더에 있는 파일을 열어 열심히 한글로 번역 한다.

    • /tmp/sugar_ko_kr/ 폴더의 내용을 묶어 langpack_ko_kr.zip 파일을 작성 한다.

 
 

한글 설치 프로그램 제작

 
  • vi /install.php 파일을 다음과 같이 수정 한다.

 
 
 $supportedLanguages = array(
    'ko_KR' => 'Korea - 한국어',  //--- 이 라인을 추가 한다.
    'en_us' => 'English (US)',
 
 $default_lang = 'ko_KR';          //--- 디폴트로 ko_KR을 지정 한다.
   
 
  • /install/language/ko_KR.lang.php 파일을 작성 한다.

  • /install/demoData.ko_KR.php 데모 데이터 파일을 작성 한다.

 
 

테마 구조

 

Dashlet

 
 
 

SOAP/REST


 
 
 
 wsdl2java.bat -o . -p com.sugar [http://cloud.smartprocess.co.kr/testEnt/service/v4/soap.php?wsdl](http://cloud.smartprocess.co.kr/testEnt/service/v4/soap.php?wsdl)
 
  • SugarsoapLocatior.java

 
 
 //    private java.lang.String sugarsoapPort_address = "[http://cloud.smartprocess.co.kr/testEnt/service/v4/soap.php](http://cloud.smartprocess.co.kr/testEnt/service/v4/soap.php)";
    private java.lang.String sugarsoapPort_address = Config.getString("sugar.serverurl", "[http://cloud.smartprocess.co.kr/testEnt/](http://cloud.smartprocess.co.kr/testEnt/)") + "service/v4/soap.php";
 
  • SugarsoapBuindingStub.java

 
 
 public static String SugarServerurl = Config.getString("sugar.serverurl", "[http://cloud.smartprocess.co.kr/testEnt/](http://cloud.smartprocess.co.kr/testEnt/)") + "service/v4/soap.php";
 _call.setSOAPActionURI(SugarsoapBindingStub.SugarServerurl + "/login");
 
  • SugarsoapBuindingStub.java 함수

 
 
 public com.sugar.Entry_value login(com.sugar.User_auth user_auth, java.lang.String application_name, com.sugar.Name_value[](.md) name_value_list)
 public void logout(java.lang.String session)
 public com.sugar.Get_entry_result_version2 get_entry(java.lang.String session, java.lang.String module_name, java.lang.String id, 
    java.lang.String[] select_fields, com.sugar.Link_name_to_fields_array[](.md) link_name_to_fields_array, boolean track_view)
 public com.sugar.Get_entry_result_version2 get_entries(java.lang.String session, java.lang.String module_name, java.lang.String[](.md) ids, 
    java.lang.String[] select_fields, com.sugar.Link_name_to_fields_array[](.md) link_name_to_fields_array, boolean track_view)
 public com.sugar.Get_entry_list_result_version2 get_entry_list(java.lang.String session, java.lang.String module_name, java.lang.String query, 
    java.lang.String order_by, int offset, java.lang.String[] select_fields, com.sugar.Link_name_to_fields_array[](.md) link_name_to_fields_array, 
    int max_results, int deleted, boolean favorites)
 public com.sugar.New_set_relationship_list_result set_relationship(java.lang.String session, java.lang.String module_name, 
    java.lang.String module_id, java.lang.String link_field_name, java.lang.String[] related_ids, com.sugar.Name_value[](.md) name_value_list, int delete)
 public com.sugar.New_set_relationship_list_result set_relationships(java.lang.String session, java.lang.String[](.md) module_names, 
    java.lang.String[] module_ids, java.lang.String[] link_field_names, java.lang.String[][] related_ids, com.sugar.Name_value[][] name_value_lists, int[](.md) delete_array)
 public com.sugar.Get_entry_result_version2 get_relationships(java.lang.String session, java.lang.String module_name, java.lang.String module_id, 
    java.lang.String link_field_name, java.lang.String related_module_query, java.lang.String[](.md) related_fields, 
    com.sugar.Link_name_to_fields_array[](.md) related_module_link_name_to_fields_array, int deleted, java.lang.String order_by)
 public com.sugar.New_set_entry_result set_entry(java.lang.String session, java.lang.String module_name, com.sugar.Name_value[](.md) name_value_list)
 public com.sugar.New_set_entries_result set_entries(java.lang.String session, java.lang.String module_name, com.sugar.Name_value[][](.md) name_value_lists)
 public com.sugar.Get_server_info_result get_server_info()
 public java.lang.String get_user_id(java.lang.String session)
 public com.sugar.New_module_fields get_module_fields(java.lang.String session, java.lang.String module_name, java.lang.String[](.md) fields)
 public int seamless_login(java.lang.String session)
 public com.sugar.New_set_entry_result set_note_attachment(java.lang.String session, com.sugar.New_note_attachment note)
 public com.sugar.New_return_note_attachment get_note_attachment(java.lang.String session, java.lang.String id)
 public com.sugar.New_set_entry_result set_document_revision(java.lang.String session, com.sugar.Document_revision note)
 public com.sugar.New_return_document_revision get_document_revision(java.lang.String session, java.lang.String i)
 public com.sugar.Return_search_result search_by_module(java.lang.String session, java.lang.String search_string, java.lang.String[](.md) modules, 
    int offset, int max_results, java.lang.String assigned_user_id, java.lang.String[](.md) select_fields, boolean unified_search_only, boolean favorites)
 public com.sugar.Module_list get_available_modules(java.lang.String session, java.lang.String filter)
 public java.lang.String get_user_team_id(java.lang.String session)
 public void set_campaign_merge(java.lang.String session, java.lang.String[](.md) targets, java.lang.String campaign_id)
 public com.sugar.Get_entries_count_result get_entries_count(java.lang.String session, java.lang.String module_name, java.lang.String query, int deleted)
 public com.sugar.Get_entry_result_for_reports get_report_entries(java.lang.String session, java.lang.String[] ids, java.lang.String[](.md) select_fields)
 public java.lang.String[] get_module_fields_md5(java.lang.String session, java.lang.String[](.md) module_names)
 public com.sugar.Last_viewed_entry[] get_last_viewed(java.lang.String session, java.lang.String[](.md) module_names)
 public com.sugar.Upcoming_activity_entry[](.md) get_upcoming_activities(java.lang.String session)
 

SugarCRM 아키텍처


 

사용 라이브러리

 

{| cellspacing="1" cellpadding="1" border="1" width="100%" 
|- | width="30%" bgcolor="cyan" align="center" valign="middle" | 라이브러리 | width="20%" bgcolor="cyan" align="center" valign="middle" | 라이선스

| width="50%" bgcolor="cyan" align="center" valign="middle" | 상세 설명 
|- | Sugar Community Edition | align="center" | GNU GPL 3.0

오픈소스 CRM
tcpdf
align="center"
PDF 제작
-
phpmailer
align="center"
메일 발송
-
[PHP_Compat](PHP Compat.md)
align="center"
-
nusoap
align="center"
Web Services Toolkit for PHP
-
[HTTP_WebDAV_Server](HTTP WebDAV Server.md)
align="center"
WebDAV 서버
-
[HTML_Safe](HTML Safe.md)
align="center"
-
[domit_rss](Domit rss.md)
align="center"
DOM based RSS parser for PHP
-
domit
align="center"
DOM parser for PHP
-
[Crypt_Blowfish](Crypt Blowfish.md)
align="center"
-
TreeView
align="center"
Javascript, Tree 형태의 항목을 표시
-
yui (Yahoo User Interface)
align="center"
Javascript, UI 모듈
-
[tiny_mce](Tiny mce.md)
align="center"
Javascript,
-
[Ext JS](Ext JS.md)
align="center"
Javascript,
-
jscalendar
align="center"
Javascript, 달력
}
 

프로그램 호출 구조

 
  • 호출 URL: http://localhost/sugar/index.php?module=Accounts&action=index

    • '''module''': /sugar/modules/Accounts/ 폴더에 있는 모듈이 사용됨

    • '''action'''::*/sugar/include/MVC/Controller/action_file_map.php 참조

      • /sugar/include/MVC/Controller/action_view_map.php 참조

      • 아래 정리된 범례. action_명 (view_명)

      • index:

      • DetailView (detail):

      • EditView (edit):

      • MultiEditView (multiedit):

      • Popup (popup):

      • Vcard (vcard):

      • ImportVcard (importvcard):

      • ImportVcardSave (importvcardsave):

      • SugarPdf (sugarpdf):

      • SaveTimezone

      • InitialSync

      • Logout

      • RetrieveEmail

      • view 명: ajax, classic, config, detail, edit, html, importvcard, importvcardsave, json, list, multedit, noaccess, popup, serialized, sidequickcreate, sugarpdf, vcard, xml

    • '''return_module'''

    • '''return_action'''

    • return_id:

    • id:

    • record:

    • view:

    • Delete:

    • entire:

    • mass:

    • type:

    • ie_assigned_user_id:

    • configure:

    • RTL:

    • LTR:

    • query_string:

    • module_tab:

    • parentTab:

    • popup:

    • lvso:

    • query:

    • displayColumns:

    • orderBy:

    • sortOrder:

    • entryPoint:

    • massupdate:

    • usertheme:

    • noThemeSave:

    • usercolor:

    • userfont:

    • userthemegrouptabs:

    • MSID:

     
  • 호출 URL에 따른 처리 프로그램

    • /sugar/include/MVC/Controller/SugarController.php#process();

    • /sugar/include/MVC/View/SugarView.php#process();

      • /sugar/modules/Accounts/views/view.view_명.php

      • /sugar/include/MVC/View/views/view.view_명.php

     
  • /sugar/modules/Accounts/ 폴더 구조

    • views/: Default. /sugar/include/MVC/View/views/

    • tpls/: Default. /sugar/include/MVC/View/tpls/

    • metadata/: 메타데이터

    • Dashlets/: 대쉬렛

    • SugarFeeds/: 피드

    • language/: 언어 파일, ko_KR.lang.php

 
 

디렉토리 구조

 

프로세스 구조

 

index.php를 분석하여 SugarCRM의 프로세스 흐름을 파악한다.

 
  • require_once('include/entryPoint.php')

    • require_once('config.php') : 환경 설정

    • require_once('config_override.php') : 환경 설정 개인화

    • require_once 'include/SugarObjects/SugarConfig.php' : SugarCRM 환경 설정

    • require_once('include/utils.php')

    • require_once('sugar_version.php');

    • require_once('include/database/PearDatabase.php');

    • require_once('include/database/DBManager.php');

    • require_once('include/database/DBManagerFactory.php');

    • require_once('include/dir_inc.php');

    • require_once('include/Localization/Localization.php');

    • require_once('include/javascript/jsAlerts.php');

    • require_once('include/TimeDate.php');

    • require_once('include/modules.php');

    • require_once('data/SugarBean.php');

    • require_once('include/utils/file_utils.php');

    • require_once('include/utils/mvc_utils.php');

    • require_once('include/SugarEmailAddress/SugarEmailAddress.php');

    • require_once('include/SugarLogger/LoggerManager.php');

    • require_once('modules/Trackers/BreadCrumbStack.php');

    • require_once('modules/Trackers/Tracker.php');

    • require_once('modules/Trackers/TrackerManager.php');

    • require_once('modules/ACL/ACLController.php');

    • require_once('modules/Administration/Administration.php');

    • require_once('modules/Administration/updater_utils.php');

    • require_once('modules/Users/User.php');

    • require_once('modules/Users/authentication/AuthenticationController.php');

    • require_once('include/utils/LogicHook.php');

    • require SUGAR_PATH . '/include/SugarObjects/SugarRegistry.php';

     
  • require_once('include/MVC/SugarApplication.php')

    • require_once('include/MVC/Controller/ControllerFactory.php')

      • require_once('include/MVC/Controller/SugarController.php') : 디폴터 Controller

        • require_once('include/MVC/View/SugarView.php');

        • require_once('modules/Administration/updater_utils.php');

        • $this->process();

        • $this->processView();
          :*$view->process();

      • require_once('custom/modules/'.$module.'/controller.php') : 모듈별 사용자 정의 Controller

      • require_once('modules/'.$module.'/controller.php') : Module별 Controller

      • $controller = new SugarController() : 디폴터 Controller

       
    • require_once('include/MVC/View/ViewFactory.php')

      • require_once('include/MVC/View/SugarView.php');

      • 'custom/modules/'.$module.'/views/view.'.$type.'.php : 사용자 정의 모듈별 View

      • modules/'.$module.'/views/view.'.$type.'.php' : Module별 View

      • custom/include/MVC/View/views/view.'.$type.'.php : 사용자 정의 디폴트 View

      • include/MVC/View/views/view.'.$type.'.php : 디폴트 View

       
    • require_once('modules/Users/authentication/AuthenticationController.php')

    • $app->execute()

      • Request parameter : module, action, usertheme, MSID, entryPoint, massupdate

      • $this->controller = ControllerFactory::getController($module);

      • $this->controller->checkEntryPointRequiresAuth($_REQUEST'entryPoint')

        • $this->loadUser();

        • $this->ACLFilter();

        • $this->preProcess();

        • $this->controller->preProcess();

      • $this->loadLanguages();

      • $this->checkDatabaseVersion();

      • $this->loadDisplaySettings();

      • $this->loadLicense();

      • $this->loadGlobals();

      • $this->setupResourceManagement($module);

      • $this->controller->execute();

      • sugar_cleanup();

       
    • require_once('include/resource/ResourceManager.php');

    • require_once ('modules/Sync/file_config.php');

    • require_once('modules/Sync/SyncController.php');

    • require_once('themes/'.$GLOBALS'theme'.'/layout_utils.php');

 
 

화면 구조

 
  • include/MVC/View/SugarView.php

    • $this->displayHeader();

      • Theme : header.tpl

 
 
 _leftFormHiddenLastViewed.tpl
 _leftFormHiddenShortcuts.tpl
 
 
 
_leftFormHide.tpl
 
  • $this->preDisplay();

  • $this->displayErrors();

  • $this->display();

    • Module과 Action에 해당하는 template이 사용됨

  • $this->displaySubPanels();

    • $subpanel->display();

  • $this->displayFooter();

    • Theme : footer.tpl

     
  • Default Theme

    • Sugar <- default

 
 

Shortcut Menu

 
  • SugarCRM의 좌측 메뉴에 보여지는 Shortcut Menu (바로가기 메뉴)를 정리 한다.

  • /modules/모듈명/Menu.php 에 권한에 따른 바로 가기 메뉴가 정의 되어 있다.

 
 

동적 구조


 
  • Relate 변수

 
 
 select name, type, ext2, ext3 
 from fields_meta_data 
 where custom_module = 'cases' 
  and type = 'relate';
 
 select custom_module, name, type, len, required, ext1, ext2, ext3, ext4 
  from fields_meta_data 
 where custom_module = 'Campaigns'
 order by name;
 
  • relationship

 
 
 desc relationships;
 

문제 해결


 
  • Sugar 화면이 깨어지고 Ajax 관련 오류 창이 표시됨

 
 
 CentOS에 설치된 PHP 라이브러리의 버전이 달라 문제가 발생 합니다. 
 
 - jssource/Minifier.php 파일 수정
 //--- 158 line, pnuskgh
 // $this->input = preg_replace('/\h/u', ' ', $this->input);
 $this->input = preg_replace('/[\t]()/u', ' ', $this->input); 
 
 - Admin -> Repair -> Repair JS Files 실행
 - cache/ 폴더의 파일을 모두 삭제
 
  • Home 화면에서 Dashlet의 탭이 계속 실행중으로 표시됨

    • cache/xml/ 폴더를 apache:apache 권한으로 생성을 합니다.

 
 

Localization


 

한글팩 작성

 
  • Localization 범위

    • 한글 번역, 이미지 등 한글화

    • 어순 : 성 이름

    • 날짜, 시간

    • 다중 통화 (Currency)

    • 주소

     
  • PHP 파일 번역

    • ko_KR.lang.php

    • ~Dashlet.ko_KR.lang.php

    • demoData.ko_KR.php

    • phpmailer.lang-ko.php

     
  • Template 파일 번역

    • LotusLiveSignup.ko_KR.tpl

    • footer.tpl

     
  • JavaScript 파일 번역

    • ko.js, ko_dlg.js

    • calendar.js, calendar-min.js

     
  • HTML 파일 번역

    • ko_KR.notify_template.html

    • ko_KR.Portal.html

     
  • 이미지 파일을 gimp를 사용하여 새로 작성

  • PDF 파일에서 한글이 깨어짐

    • TCPDF에서 hysmyeongjostdmedium.php 파일을 다운로드

    • include/tcpdf/fonts/ 폴더에 복사

    • "Admin -> Repair -> Quick Repair and Rebuild" 메뉴 실행

    • 개인별 Profile에서 PDF Settings을 다음과 같이 설정

      • Font for Header and Body : MyungJo Medium (Korean)

      • Font for Footer : MyungJo Medium (Korean)

    • http://www.xml-convert.com/en/convert-tff-font-to-afm-pfa-fpdf-tcpdf

     
  • vi include/Sugarpdf/sugarpdf_default.php

    • helvetica를 MyungJo Medium (Korean)로 변경 합니다. (미확인 사항)

 
 
 'PDF_FONT_NAME_MAIN'=>'helvetica',
 'PDF_FONT_NAME_DATA'=>'helvetica',
 
  • TCPDF에 ttf 폰트 추가 (실패)

    • 나눔글꼴을 다운로드 합니다.

    • http://www.xml-convert.com/en/convert-tff-font-to-afm-pfa-fpdf-tcpdf 사이트에서 ttf2ufm.exe 파일을 다운로드 합니다.

    • ttf2ufm.exe ~.ttf 명령을 사용하여 ~.ufm 파일을 생성 합니다.

    • /include/tcpdf/fonts/utils/makefont.php 파일을 수정하여 nanumgothiccoding.php, nanumgothiccoding.z, nanumgothiccoding.ctg.z 파일을 생성 합니다.

      • php -q makefont.php NanumGothicCoding.ttf NanumGothicCoding.ufm

      • 생성된 파일을 /include/tcpdf/fonts/ 폴더에 복사 합니다.

 
 

주소

 
  • Address Localization

    • include/SugarFields/Fields/Address/ko_KR.DetailView.tpl, ko_KR.EditView.tpl

 
 

한글로 모듈(거래처) 목록 검색

 
  • AJAX 목록 화면에서 한글로 검색시 화면이 표시되지 않음

 
 
 include/ListView/ListViewData.php 파일의 529 라인에서
 $queryString = htmlentities($_REQUEST[$field_name]($field_name.md));을 아래와 같이 변경함
 $queryString = htmlentities($_REQUEST[$field_name]($field_name.md), null, "UTF-8");
 

메일 발송시 보낸 사람 이름

 
  • 메일 발송시 보낸 사람 이름이 깨어짐

 
 
 modules/Emails/Email.php 851 line
 From : $this->from_addr_name = $this->from_addr;
 To   : $this->from_addr_name = "{$mail->FromName} <{$mail->From}>";
 
  • 근본적으로 해결을 하려면 $mail->FromName 값이 MIME으로 인코딩 되었을 경우에만 decode를 하도록 수정할 것

 
 

Tips


 
 
 

참고 문헌


 
 
 
 
 

지원 업체


 

{{지원업체}} 
[[Category:오픈소스|Category:오픈소스]]
[[Category:CRM|Category:CRM]]
[[Category:한글화|Category:한글화]]
[[Category:Sugar|Category:Sugar]]
분류: WebSite

최종 수정일: 2024-09-30 12:26:18

이전글 :
다음글 :