2 /*********************************************************************************
3 * SugarCRM is a customer relationship management program developed by
4 * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
6 * This program is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Affero General Public License version 3 as published by the
8 * Free Software Foundation with the addition of the following permission added
9 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
11 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
18 * You should have received a copy of the GNU Affero General Public License along with
19 * this program; if not, see http://www.gnu.org/licenses or write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
24 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26 * The interactive user interfaces in modified source and object code versions
27 * of this program must display Appropriate Legal Notices, as required under
28 * Section 5 of the GNU Affero General Public License version 3.
30 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31 * these Appropriate Legal Notices must retain the display of the "Powered by
32 * SugarCRM" logo. If the display of the logo is not reasonably feasible for
33 * technical reasons, the Appropriate Legal Notices must display the words
34 * "Powered by SugarCRM".
35 ********************************************************************************/
38 * SugarFieldBase translates and displays fields from a vardef definition into different formats
39 * including DetailView, ListView, EditView. It also provides Search Inputs and database queries
43 class SugarFieldBase {
44 var $ss; // Sugar Smarty Object
45 var $hasButton = false;
46 function SugarFieldBase($type) {
48 $this->ss = new Sugar_Smarty();
50 function fetch($path){
52 if(!$this->hasButton && !empty($this->button)){
53 $additional .= '<input type="button" class="button" ' . $this->button . '>';
55 if(!empty($this->buttons)){
56 foreach($this->buttons as $v){
57 $additional .= ' <input type="button" class="button" ' . $v . '>';
61 if(!empty($this->image)){
62 $additional .= ' <img ' . $this->image . '>';
64 return $this->ss->fetch($path) . $additional;
67 function findTemplate($view){
68 static $tplCache = array();
70 if ( isset($tplCache[$this->type][$view]) ) {
71 return $tplCache[$this->type][$view];
74 $lastClass = get_class($this);
75 $classList = array($this->type,str_replace('SugarField','',$lastClass));
76 while ( $lastClass = get_parent_class($lastClass) ) {
77 $classList[] = str_replace('SugarField','',$lastClass);
81 foreach ( $classList as $className ) {
82 $tplName = 'include/SugarFields/Fields/'. $className .'/'. $view .'.tpl';
83 if ( file_exists('custom/'.$tplName) ) {
84 $tplName = 'custom/'.$tplName;
87 if ( file_exists($tplName) ) {
92 $tplCache[$this->type][$view] = $tplName;
97 public function formatField($rawField, $vardef){
98 // The base field doesn't do any formatting, so override it in subclasses for more specific actions
103 public function unformatField($formattedField, $vardef){
104 // The base field doesn't do any formatting, so override it in subclasses for more specific actions
105 return $formattedField;
108 function getSmartyView($parentFieldArray, $vardef, $displayParams, $tabindex = -1, $view){
109 $this->setup($parentFieldArray, $vardef, $displayParams, $tabindex);
112 return $this->fetch($this->findTemplate($view));
115 function getListViewSmarty($parentFieldArray, $vardef, $displayParams, $col) {
116 // FIXME: Rework the listview to use two-pass rendering like the DetailView
119 $isArray = is_array($parentFieldArray);
120 $fieldName = $vardef['name'];
123 $fieldNameUpper = strtoupper($fieldName);
124 if ( isset($parentFieldArray[$fieldNameUpper])) {
125 $parentFieldArray[$fieldName] = $this->formatField($parentFieldArray[$fieldNameUpper],$vardef);
127 $parentFieldArray[$fieldName] = '';
130 if ( isset($parentFieldArray->$fieldName) ) {
131 $parentFieldArray->$fieldName = $this->formatField($parentFieldArray->$fieldName,$vardef);
133 $parentFieldArray->$fieldName = '';
136 $this->setup($parentFieldArray, $vardef, $displayParams, $tabindex, false);
138 $this->ss->left_delimiter = '{';
139 $this->ss->right_delimiter = '}';
140 $this->ss->assign('col',$vardef['name']);
142 return $this->fetch($this->findTemplate('ListView'));
146 * Returns a smarty template for the DetailViews
148 * @param parentFieldArray string name of the variable in the parent template for the bean's data
149 * @param vardef vardef field defintion
150 * @param displayParam parameters for display
151 * available paramters are:
152 * * labelSpan - column span for the label
153 * * fieldSpan - column span for the field
155 function getDetailViewSmarty($parentFieldArray, $vardef, $displayParams, $tabindex) {
156 return"<span id='{$vardef['name']}'>" . $this->getSmartyView($parentFieldArray, $vardef, $displayParams, $tabindex, 'DetailView') . '</span>';
159 // 99% of all fields will just format like a listview, but just in case, it's here to override
160 function getChangeLogSmarty($parentFieldArray, $vardef, $displayParams, $tabindex) {
161 return $this->formatField($parentFieldArray[$vardef['name']],$vardef);
165 function getEditViewSmarty($parentFieldArray, $vardef, $displayParams, $tabindex) {
166 if(!empty($vardef['function']['returns']) && $vardef['function']['returns'] == 'html'){
168 $this->type = 'Base';
169 $result= $this->getDetailViewSmarty($parentFieldArray, $vardef, $displayParams, $tabindex);
173 return $this->getSmartyView($parentFieldArray, $vardef, $displayParams, $tabindex, 'EditView');
176 function getImportViewSmarty($parentFieldArray, $vardef, $displayParams, $tabindex)
178 return $this->getEditViewSmarty($parentFieldArray, $vardef, $displayParams, $tabindex);
183 function getSearchViewSmarty($parentFieldArray, $vardef, $displayParams, $tabindex) {
184 if(!empty($vardef['auto_increment']))$vardef['len']=255;
185 return $this->getSmartyView($parentFieldArray, $vardef, $displayParams, $tabindex, 'EditView');
188 function getPopupViewSmarty($parentFieldArray, $vardef, $displayParams, $tabindex){
189 if (is_array($displayParams) && !isset($displayParams['formName']))
190 $displayParams['formName'] = 'popup_query_form';
191 else if (empty($displayParams))
192 $displayParams = array('formName' => 'popup_query_form');
193 return $this->getSearchViewSmarty($parentFieldArray, $vardef, $displayParams, $tabindex);
196 public function getEmailTemplateValue($inputField, $vardef, $displayParams = array(), $tabindex = 0){
197 // This does not return a smarty section, instead it returns a direct value
198 return $this->formatField($inputField,$vardef);
201 function displayFromFunc( $displayType, $parentFieldArray, $vardef, $displayParams, $tabindex = 0 ) {
203 if ( ! is_array($vardef['function']) ) {
204 $funcName = $vardef['function'];
207 $returnsHtml = false;
209 $funcName = $vardef['function']['name'];
211 if ( isset($vardef['function']['include']) ) {
212 $includeFile = $vardef['function']['include'];
214 if ( isset($vardef['function']['onListView']) && $vardef['function']['onListView'] == true ) {
219 if ( isset($vardef['function']['returns']) && $vardef['function']['returns'] == 'html' ) {
222 $returnsHtml = false;
226 if ( $displayType == 'ListView'
227 || $displayType == 'popupView'
228 || $displayType == 'searchView'
229 || $displayType == 'wirelessEditView'
230 || $displayType == 'wirelessDetailView'
231 || $displayType == 'wirelessListView'
233 // Traditionally, before 6.0, additional functions were never called, so this code doesn't get called unless the vardef forces it
235 if ( !empty($includeFile) ) {
236 require_once($includeFile);
239 return $funcName($parentFieldArray, $vardef['name'], $parentFieldArray[$vardef['name']], $displayType);
241 $displayTypeFunc = 'get'.$displayType.'Smarty';
242 return $this->$displayTypeFunc($parentFieldArray, $vardef, $displayParams, $tabindex);
245 if ( !empty($displayParams['idName']) ) {
246 $fieldName = $displayParams['idName'];
248 $fieldName = $vardef['name'];
250 if ( $returnsHtml ) {
251 $this->setup($parentFieldArray, $vardef, $displayParams, $tabindex);
252 $tpl = $this->findTemplate($displayType.'Function');
254 // Can't find a function template, just use the base
255 $tpl = $this->findTemplate('DetailViewFunction');
257 return "<span id='{$vardef['name']}'>" . $this->fetch($tpl) . '</span>';
259 return '{sugar_run_helper include="'.$includeFile.'" func="'.$funcName.'" bean=$bean field="'.$fieldName.'" value=$fields.'.$fieldName.'.value displayType="'.$displayType.'"}';
264 function getEditView() {
267 function getSearchInput() {
270 function getQueryLike() {
273 function getQueryIn() {
277 * Setup function to assign values to the smarty template, should be called before every display function
279 function setup($parentFieldArray, $vardef, $displayParams, $tabindex, $twopass=true) {
284 $this->ss->left_delimiter = '{{';
285 $this->ss->right_delimiter = '}}';
287 $this->ss->assign('parentFieldArray', $parentFieldArray);
288 $this->ss->assign('vardef', $vardef);
289 $this->ss->assign('tabindex', $tabindex);
291 //for adding attributes to the field
293 if(!empty($displayParams['field'])){
295 foreach($displayParams['field'] as $key=>$value){
296 $plusField .= ' ' . $key . '="' . $value . '"';//bug 27381
298 $displayParams['field'] = $plusField;
300 //for adding attributes to the button
301 if(!empty($displayParams['button'])){
303 foreach($displayParams['button'] as $key=>$value){
304 $plusField .= ' ' . $key . '="' . $value . '"';
306 $displayParams['button'] = $plusField;
307 $this->button = $displayParams['button'];
309 if(!empty($displayParams['buttons'])){
311 foreach($displayParams['buttons'] as $keys=>$values){
312 foreach($values as $key=>$value){
313 $plusField[$keys] .= ' ' . $key . '="' . $value . '"';
316 $displayParams['buttons'] = $plusField;
317 $this->buttons = $displayParams['buttons'];
319 if(!empty($displayParams['image'])){
321 foreach($displayParams['image'] as $key=>$value){
322 $plusField .= ' ' . $key . '="' . $value . '"';
324 $displayParams['image'] = $plusField;
325 $this->image = $displayParams['image'];
327 $this->ss->assign('displayParams', $displayParams);
333 * This should be called when the bean is saved. The bean itself will be passed by reference
334 * @param SugarBean bean - the bean performing the save
335 * @param array params - an array of paramester relevant to the save, most likely will be $_REQUEST
337 public function save(&$bean, $params, $field, $properties, $prefix = ''){
338 if ( isset($params[$prefix.$field]) ) {
339 if(isset($properties['len']) && isset($properties['type']) && 'varchar' == $properties['type']){
340 $bean->$field = trim($this->unformatField($params[$prefix.$field],$properties));
343 $bean->$field = $this->unformatField($params[$prefix.$field],$properties);