12fbabac5f9d66c3e5a4b677e286691711d4f825
[tine20] / tine20 / Tinebase / Export / Spreadsheet / Abstract.php
1 <?php
2 /**
3  * Tine 2.0
4  *
5  * @package     Tinebase
6  * @subpackage  Export
7  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
8  * @author      Philipp Schüle <p.schuele@metaways.de>
9  * @copyright   Copyright (c) 2010-2015 Metaways Infosystems GmbH (http://www.metaways.de)
10  * 
11  */
12
13 /**
14  * Tinebase Abstract spreadsheet export class
15  * 
16  * @package     Tinebase
17  * @subpackage    Export
18  */
19 abstract class Tinebase_Export_Spreadsheet_Abstract extends Tinebase_Export_Abstract
20 {
21     /**
22      * group by this field
23      *
24      * @var string
25      */
26     protected $_groupBy = NULL;
27     
28     /**
29      * config for the groupBy field
30      * 
31      * @var Zend_Config
32      */
33     protected $_groupByFieldConfig = NULL;
34     
35     /**
36      * type of the field
37      * 
38      * @var string
39      */
40     protected $_groupByFieldType = NULL;
41     
42     /**
43      * count of columns
44      * 
45      * @var integer
46      */
47     protected $_columnCount = NULL;
48     
49     /**
50      * the constructor
51      *
52      * @param Tinebase_Model_Filter_FilterGroup $_filter
53      * @param Tinebase_Controller_Record_Interface $_controller (optional)
54      * @param array $_additionalOptions (optional) additional options
55      */
56     public function __construct(Tinebase_Model_Filter_FilterGroup $_filter, Tinebase_Controller_Record_Interface $_controller = NULL, $_additionalOptions = array())
57     {
58         parent::__construct($_filter, $_controller, $_additionalOptions);
59     
60         if ($this->_config->grouping) {
61             $this->_groupBy = (string) $this->_config->grouping->by;
62             $this->_sortInfo = array('sort' => $this->_groupBy);
63         }
64     }
65     
66     /**
67      * holds all records for the matrix
68      * 
69      * @var array
70      */
71     protected $_matrixCache = array();
72     
73     /**
74      * get export document object
75      * 
76      * @return Object the generated document
77      */
78     abstract public function getDocument();
79     
80     /**
81      * get cell value
82      * 
83      * @param Zend_Config $_field
84      * @param Tinebase_Record_Interface $_record
85      * @param string $_cellType
86      * @return string
87      * 
88      * @todo check string type for translated fields?
89      * @todo add 'config' type again?
90      * @todo move generic parts to Tinebase_Export_Abstract
91      */
92     protected function _getCellValue(Zend_Config $_field, Tinebase_Record_Interface $_record, &$_cellType)
93     {
94         $result = NULL;
95         
96         if (! (isset($_field->type) && $_field->separateColumns)) {
97             if (in_array($_field->type, $this->_specialFields)) {
98                 // special field handling
99                 $result = $this->_getSpecialFieldValue($_record, $_field->toArray(), $_field->identifier, $_cellType);
100                 $result = $this->_replaceAndMatchvalue($result, $_field);
101                 return $result;
102                 
103             } else if (isset($field->formula) 
104                 || (! isset($_record->{$_field->identifier}) 
105                     && ! in_array($_field->type, $this->_resolvedFields) 
106                     && ! in_array($_field->identifier, $this->_getCustomFieldNames())
107                 )
108             ) {
109                 // check if empty -> use alternative field
110                 if (isset($_field->empty)) {
111                     $fieldConfig = $_field->toArray();
112                     unset($fieldConfig['empty']);
113                     $fieldConfig['identifier'] = $_field->empty;
114                     $result = $this->_getCellValue(new Zend_Config($fieldConfig), $_record, $_cellType);
115                 }
116                 // don't add value for formula or undefined fields
117                 return $result;
118             }
119         }
120         
121         if ($_field->isMatrixField) {
122             return $this->_getMatrixCellValue($_field, $_record);
123         }
124         
125         switch($_field->type) {
126             case 'datetime':
127                 $result = Tinebase_Translation::dateToStringInTzAndLocaleFormat($_record->{$_field->identifier});
128                 // empty date cells, get displayed as 30.12.1899
129                 if(empty($result)) {
130                     $result = NULL;
131                 }
132                 break;
133             case 'date':
134                 $result = ($_record->{$_field->identifier} instanceof DateTime) ? $_record->{$_field->identifier}->toString('Y-m-d') : $_record->{$_field->identifier};
135                 // empty date cells, get displayed as 30.12.1899
136                 if (empty($result)) {
137                     $result = NULL;
138                 }
139                 break;
140             case 'tags':
141                 $result = $this->_getTags($_record);
142                 break;
143             case 'keyfield':
144                 $result = $this->_getResolvedKeyfield($_record->{$_field->identifier}, $_field->keyfield, $_field->application);
145                 break;
146             case 'currency':
147                 $currency = ($_field->currency) ? $_field->currency : 'EUR';
148                 $result = ($_record->{$_field->identifier}) ? $_record->{$_field->identifier} : '0';
149                 $result = number_format($result, 2, '.', '') . ' ' . $currency;
150                 break;
151             case 'percentage':
152                 $result    = $_record->{$_field->identifier} / 100;
153                 break;
154             case 'container_id':
155                 $result = $this->_getContainer($_record, $_field->field, $_field->type);
156                 break;
157                 /*
158             case 'config':
159                 $result = Tinebase_Config::getOptionString($_record, $_field->identifier);
160                 break;
161                 */
162             case 'relation':
163                 $result = $this->_addRelations(
164                     $_record,
165                     /* $relationType = */       $_field->identifier,
166                     /* $recordField = */        $_field->field,
167                     /* $onlyFirstRelation = */  isset($_field->onlyfirst) ? $_field->onlyfirst : false
168                 );
169                 break;
170             case 'notes':
171                 $result = $this->_addNotes($_record);
172                 break;
173             default:
174                 if (in_array($_field->identifier, $this->_getCustomFieldNames())) {
175                     // add custom fields
176                     if (isset($_record->customfields[$_field->identifier])) {
177                         $result = $_record->customfields[$_field->identifier];
178                     }
179                 } elseif (isset($_field->divisor)) {
180                     // divisor
181                     $result = $_record->{$_field->identifier} / $_field->divisor;
182                 } elseif (in_array($_field->type, $this->_userFields) || in_array($_field->identifier, $this->_userFields)) {
183                     // resolved user
184                     $result = $this->_getUserValue($_record, $_field);
185                 } else if (is_object($_record->{$_field->identifier}) && method_exists($_record->{$_field->identifier}, '__toString')) {
186                     // call __toString
187                     $result = $_record->{$_field->identifier}->__toString();
188                 } else {
189                     // all remaining
190                     $result = $_record->{$_field->identifier};
191                 }
192                 
193                 if (isset($_field->trim) && $_field->trim == 1) {
194                     $result = trim($result);
195                 }
196                 
197                 // set special value from params
198                 if (isset($_field->values)) {
199                     $values = $_field->values->value->toArray();
200                     if (isset($values[$result])) {
201                         $result = $values[$result];
202                     }
203                 }
204                 
205                 if (isset($_field->translate) && $_field->translate/* && $_cellType === OpenDocument_SpreadSheet_Cell::TYPE_STRING*/) {
206                     $result = $this->_translate->_($result);
207                 }
208                 
209                 $result = $this->_replaceAndMatchvalue($result, $_field);
210         }
211         
212         if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' field def: ' . print_r($_field->toArray(), TRUE));
213         if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' result: ' . $result);
214         
215         return $result;
216     }
217     
218     /**
219      * returns the value of a matrix field
220      * 
221      * @param Zend_Config $field
222      * @param Tinebase_Record_Interface $record
223      * @throws Tinebase_Exception_Data
224      * @return number
225      */
226     protected function _getMatrixCellValue($field, $record)
227     {
228         $result = 0;
229         
230         switch ($field->type) {
231             case 'tags':
232                 if (! isset($this->_matrixCache[$field->identifier])) {
233                     $this->_matrixCache[$field->identifier] = array();
234                 }
235             
236                 if (! isset($this->_matrixCache[$field->identifier][$record->getId()])) {
237                     // clear cache, its not needed anymore (could have been filled by the previous record)
238                     $this->_matrixCache[$field->identifier] = array();
239                     $this->_matrixCache[$field->identifier][$record->getId()] = Tinebase_Tags::getInstance()->getTagsOfRecord($record);
240                 }
241                 $result = $this->_matrixCache[$field->identifier][$record->getId()]->filter('name', $field->identifier)->count();
242                 break;
243             default:
244                 throw new Tinebase_Exception_Data('Other types than tags are not supported at the moment.');
245         }
246         
247         return $result;
248     }
249
250     /**
251      * get value from resolved user record
252      * 
253      * @param Tinebase_Record_Interface $_record
254      * @param Zend_Config $_fieldConfig
255      */
256     protected function _getUserValue($_record, $_fieldConfig)
257     {
258         $result = '';
259         if (in_array($_fieldConfig->type, $this->_userFields)) {
260             $user = $_record->{$_fieldConfig->type};
261         } else {
262             $user = $_record->{$_fieldConfig->identifier};
263         }
264         
265         if (! empty($user) && is_object($user)) {
266             if ($_fieldConfig->field) {
267                 $result = $user->{$_fieldConfig->field};
268             } else {
269                 $result = $user->accountDisplayName;
270             }
271         }
272         
273         return $result;
274     }
275 }