]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/connectors/sources/default/source.php
Release 6.4.0
[Github/sugarcrm.git] / include / connectors / sources / default / source.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM Community Edition is a customer relationship management program developed by
5  * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38
39 /**
40  * source is the parent class of any source object.
41  * @api
42  */
43 abstract class source{
44         /**
45          * The name of an wrapper to use if the class wants to provide an override
46          */
47         public $wrapperName;
48         protected $_config;
49         protected $_mapping;
50         protected $_field_defs;
51         protected $_enable_in_wizard = true;
52         protected $_enable_in_hover = false;
53         protected $_has_testing_enabled = false;
54         protected $_required_config_fields = array();
55         protected $_required_config_fields_for_button = array();
56         protected $config_decrypted = false;
57
58     /**
59      * The ExternalAPI Base that instantiated this connector.
60      * @var _eapm
61      */
62     protected $_eapm = null;
63
64         public function __construct(){
65                 $this->loadConfig();
66                 $this->loadMapping();
67                 $this->loadVardefs();
68         }
69
70         public function init(){}
71
72         //////// CALLED FROM component.php ///////
73         public function loadMapping() {
74                 $mapping = array();
75                 $dir = str_replace('_','/',get_class($this));
76                 if(file_exists("custom/modules/Connectors/connectors/sources/{$dir}/mapping.php")) {
77                         require("custom/modules/Connectors/connectors/sources/{$dir}/mapping.php");
78                 } else if(file_exists("modules/Connectors/connectors/sources/{$dir}/mapping.php")){
79                         require("modules/Connectors/connectors/sources/{$dir}/mapping.php");
80                 }
81             $this->_mapping = $mapping;
82         }
83
84     public function saveMappingHook($mapping) {
85         // Most classes don't care that the mapping has changed, but this is here if they do.
86         return;
87     }
88
89     /**
90      * Load source's vardef file
91      */
92         public function loadVardefs() {
93                 $class = get_class($this);
94                 $dir = str_replace('_','/',$class);
95                 if(file_exists("custom/modules/Connectors/connectors/sources/{$dir}/vardefs.php")) {
96                         require("custom/modules/Connectors/connectors/sources/{$dir}/vardefs.php");
97                 } else if(file_exists("modules/Connectors/connectors/sources/{$dir}/vardefs.php")){
98                         require("modules/Connectors/connectors/sources/{$dir}/vardefs.php");
99                 }
100
101                 $this->_field_defs = !empty($dictionary[$class]['fields']) ? $dictionary[$class]['fields'] : array();
102         }
103
104         /**
105          * Given a parameter in a vardef field, return the list of fields that match the param and value
106          *
107          * @param string $param_name
108          * @param string $param_value
109          * @return array
110          */
111         public function getFieldsWithParams($param_name, $param_value)
112         {
113                 if(empty($this->_field_defs)){
114                         $this->loadVardefs();
115                 }
116                 $fields_with_param = array();
117                 foreach($this->_field_defs as $key => $def){
118                         if(!empty($def[$param_name]) && ($def[$param_name] == $param_value)){
119                                 $fields_with_param[$key] = $def;
120                         }
121                 }
122                 return $fields_with_param;
123         }
124
125         /**
126          * Save source's config to custom directory
127          */
128         public function saveConfig()
129         {
130                 $config_str = "<?php\n/***CONNECTOR SOURCE***/\n";
131
132         // Handle encryption
133         if(!empty($this->_config['encrypt_properties']) && is_array($this->_config['encrypt_properties']) && !empty($this->_config['properties'])){
134             require_once('include/utils/encryption_utils.php');
135             foreach($this->_config['encrypt_properties'] as $name) {
136                 if(!empty($this->_config['properties'][$name])) {
137                     $this->_config['properties'][$name] = blowfishEncode(blowfishGetKey('encrypt_field'),$this->_config['properties'][$name]);
138                 }
139             }
140         }
141
142
143                 foreach($this->_config as $key => $val) {
144                         if(!empty($val)){
145                                 $config_str .= override_value_to_string_recursive2('config', $key, $val, false);
146                         }
147                 }
148                 $dir = str_replace('_', '/', get_class($this));
149
150             if(!file_exists("custom/modules/Connectors/connectors/sources/{$dir}")) {
151                mkdir_recursive("custom/modules/Connectors/connectors/sources/{$dir}");
152             }
153             file_put_contents("custom/modules/Connectors/connectors/sources/{$dir}/config.php", $config_str);
154         }
155
156         /**
157          * Initialize config - decrypt encrypted fields
158          */
159         public function initConfig()
160         {
161         if($this->config_decrypted) return;
162         // Handle decryption
163         require_once('include/utils/encryption_utils.php');
164         if(!empty($this->_config['encrypt_properties']) && is_array($this->_config['encrypt_properties']) && !empty($this->_config['properties'])){
165             foreach($this->_config['encrypt_properties'] as $name) {
166                 if(!empty($this->_config['properties'][$name])) {
167                     $this->_config['properties'][$name] = blowfishDecode(blowfishGetKey('encrypt_field'),$this->_config['properties'][$name]);
168                 }
169             }
170         }
171         $this->config_decrypted = true;
172         }
173
174         /**
175          * Load config.php for this source
176          */
177         public function loadConfig()
178         {
179                 $config = array();
180                 $dir = str_replace('_','/',get_class($this));
181                 if(file_exists("modules/Connectors/connectors/sources/{$dir}/config.php")){
182                         require("modules/Connectors/connectors/sources/{$dir}/config.php");
183                 }
184                 if(file_exists("custom/modules/Connectors/connectors/sources/{$dir}/config.php")) {
185                         require("custom/modules/Connectors/connectors/sources/{$dir}/config.php");
186                 }
187                 $this->_config = $config;
188
189                 //If there are no required config fields specified, we will default them to all be required
190                 if(empty($this->_required_config_fields)) {
191                    foreach($this->_config['properties'] as $id=>$value) {
192                           $this->_required_config_fields[] = $id;
193                    }
194                 }
195         }
196
197     // Helper function for the settings panels
198     /**
199      * Filter which modules are allowed to connect
200      * @param array $moduleList
201      * @return array Allowed modules
202      */
203     public function filterAllowedModules( $moduleList )
204     {
205         // Most modules can connect to everything, no further filtering necessary
206         return $moduleList;
207     }
208
209         ////////////// GETTERS and SETTERS ////////////////////
210         public function getMapping()
211         {
212                 return $this->_mapping;
213         }
214
215         public function getOriginalMapping() {
216                 $mapping = array();
217                 $dir = str_replace('_','/',get_class($this));
218                 if(file_exists("modules/Connectors/connectors/sources/{$dir}/mapping.php")) {
219                         require("modules/Connectors/connectors/sources/{$dir}/mapping.php");
220                 } else if(file_exists("custom/modules/Connectors/connectors/sources/{$dir}/mapping.php")){
221                         require("custom/modules/Connectors/connectors/sources/{$dir}/mapping.php");
222                 }
223                 return $mapping;
224         }
225
226         public function setMapping($mapping)
227         {
228                 $this->_mapping = $mapping;
229         }
230
231         public function getFieldDefs()
232         {
233                 return $this->_field_defs;
234         }
235
236         public function getConfig()
237         {
238             if(!$this->config_decrypted) $this->initConfig();
239                 return $this->_config;
240         }
241
242         public function setConfig($config)
243         {
244                 $this->_config = $config;
245                 $this->config_decrypted = true; // Don't decrypt external configs
246         }
247
248     public function setEAPM(ExternalAPIBase $eapm)
249     {
250         $this->_eapm = $eapm;
251     }
252
253     public function getEAPM()
254     {
255         return $this->_eapm;
256     }
257
258     public function setProperties($properties=array())
259     {
260                 if(!empty($this->_config) && isset($this->_config['properties'])) {
261                    $this->_config['properties'] = $properties;
262                    $this->config_decrypted = true; // Don't decrypt external configs
263                 }
264         }
265
266         public function getProperties()
267         {
268                 if(!empty($this->_config) && isset($this->_config['properties'])) {
269                    if(!$this->config_decrypted) $this->initConfig();
270                    return $this->_config['properties'];
271                 }
272                 return array();
273         }
274
275         /**
276          * Check if certain property contains non-empty value
277          * @param string $name
278          * @return bool
279          */
280         public function propertyExists($name)
281         {
282             return !empty($this->_config['properties'][$name]);
283         }
284
285         public function getProperty($name)
286         {
287             if(!empty($this->_config) && isset($this->_config['properties'][$name])) {
288                 // check if we're asking for encrypted property and we didn't decrypt yet
289                 if(!$this->config_decrypted && !empty($this->_config['encrypt_properties']) && in_array($name, $this->_config['encrypt_properties']) && !empty($this->_config['properties'][$name])) {
290                     $this->initConfig();
291                 }
292                 return $this->_config['properties'][$name];
293                 } else {
294                         return '';
295                 }
296         }
297
298         /**
299          * hasTestingEnabled
300          * This method is used to indicate whether or not a data source has testing enabled so that
301          * the administration interface may call the test method on the data source instance
302          *
303          * @return enabled boolean value indicating whether or not testing is enabled
304          */
305         public function hasTestingEnabled() {
306                 return $this->_has_testing_enabled;
307         }
308
309         /**
310          * test
311          * This method is called from the administration interface to run a test of the service
312          * It is up to subclasses to implement a test and set _has_testing_enabled to true so that
313          * a test button is rendered in the administration interface
314          *
315          * @return result boolean result of the test function
316          */
317     public function test() {
318         return false;
319     }
320
321
322     /**
323      * isEnabledInWizard
324      * This method indicates whether or not the connector should be enabled in the wizard
325      * Connectors that do not support the getList/getItem methods via API calls should
326      * set the protected class variable _enable_in_wizard to false.
327      *
328      * @return $enabled boolean variable indicating whether or not the connector is enabled for the wizard
329      */
330     public function isEnabledInWizard() {
331         return $this->_enable_in_wizard;
332     }
333
334
335     /**
336      * isEnabledInHover
337      * This method indicates whether or not the connector should be enabled for the hover links
338      * Connectors that do not provide a formatter implementation should not
339      * set the protected class variable _enable_in_hover to true.
340      *
341      * @return $enabled boolean variable indicating whether or not the connector is enabled for the hover links
342      *
343      */
344     public function isEnabledInHover() {
345         return $this->_enable_in_hover;
346     }
347
348
349     /**
350      * getRequiredConfigFields
351      * This method returns an Array of the configuration keys that are required for the Connector.
352      * Subclasses should set the class variable _required_config_fields to
353      * return an Array of keys as specified in the Connector's config.php that are required.
354      *
355      * @return $fields Array of Connector config fields that are required
356      */
357     public function getRequiredConfigFields() {
358         return $this->_required_config_fields;
359     }
360
361
362     /**
363      * isRequiredConfigFieldsSet
364      * This method checks the configuration parameters against the required config fields
365      * to see if they are set
366      *
367      * @return $set boolean value indicating whether or not the required config fields are set
368      */
369     public function isRequiredConfigFieldsSet() {
370         //Check if required fields are set
371                 foreach($this->_required_config_fields as $field) {
372                 if(empty($this->_config['properties'][$field])) {
373                    return false;
374                 }
375                 }
376         return true;
377     }
378
379
380     /**
381      * getRequiredConfigFieldsForButton
382      * This method returns an Array of the configuration keys that are required before the
383      * "Get Data" button will include the Connector.  We use it as a subset of the
384      * $this->_required_config_fields Array.
385      *
386      * @return $fields Array of Connector config fields that are required to be set for the "Get Data" button to appear
387      */
388     public function getRequiredConfigFieldsForButton() {
389         return $this->_required_config_fields_for_button;
390     }
391
392
393     /**
394      * isRequiredConfigFieldsForButtonSet
395      * This method checks the configuration parameters against the required config fields
396      * for the "Get Button" to see if they are set
397      *
398      * @return $set boolean value indicating whether or not the required config fields are set
399      */
400     public function isRequiredConfigFieldsForButtonSet() {
401         //Check if required fields for button are set
402                 foreach($this->_required_config_fields_for_button as $field) {
403                 if(empty($this->_config['properties'][$field])) {
404                    return false;
405                 }
406                 }
407         return true;
408     }
409
410
411     /**
412      * Allow data sources to log information
413      *
414      * @param string $log_data
415      */
416     protected function log($log_data){
417         $name = get_class($this);
418         $property_name = $this->getProperty('name');
419         if(!empty($property_name)){
420                 $name = $property_name;
421         }
422         $GLOBALS['log']->info($name. ': '.$log_data);
423     }
424
425         /**
426          * getItem
427          * Returns an array containing a key/value pair(s) of a connector record. To be overridden by the implementation
428          * source.
429          *
430          * @param $args Array of arguments to search/filter by
431          * @param $module String optional value of the module that the connector framework is attempting to map to
432          * @return Array of key/value pair(s) of connector record; empty Array if no results are found
433          */
434         public abstract function getItem($args=array(), $module=null);
435
436
437         /**
438          * getList
439          * Returns a nested array containing a key/value pair(s) of a connector record. To be overridden by the
440          * implementation source.
441          *
442          * @param $args Array of arguments to search/filter by
443          * @param $module String optional value of the module that the connector framework is attempting to map to
444          * @return Array of key/value pair(s) of connector record; empty Array if no results are found
445          */
446         public abstract function getList($args=array(), $module=null);
447
448     /**
449          * Default destructor
450          *
451          */
452         public function __destruct(){
453          // Bug # 47233 - This desctructor was originally removed by bug # 44533.
454          // We have to add this destructor back in
455          // because there are customers who upgrade from 61x to 623
456          // who have the Jigsaw connector enabled, and the jigsaw connector
457          // makes a call to this destructor.
458
459      }
460 }