Overview

Packages

  • application
    • commands
    • components
      • actions
      • filters
      • leftWidget
      • permissions
      • sortableWidget
      • util
      • webupdater
      • x2flow
        • actions
        • triggers
      • X2GridView
      • X2Settings
    • controllers
    • models
      • embedded
    • modules
      • accounts
        • controllers
        • models
      • actions
        • controllers
        • models
      • calendar
        • controllers
        • models
      • charts
        • models
      • contacts
        • controllers
        • models
      • docs
        • components
        • controllers
        • models
      • groups
        • controllers
        • models
      • marketing
        • components
        • controllers
        • models
      • media
        • controllers
        • models
      • mobile
        • components
      • opportunities
        • controllers
        • models
      • products
        • controllers
        • models
      • quotes
        • controllers
        • models
      • services
        • controllers
        • models
      • template
        • models
      • users
        • controllers
        • models
      • workflow
        • controllers
        • models
      • x2Leads
        • controllers
        • models
  • None
  • system
    • base
    • caching
    • console
    • db
      • ar
      • schema
    • validators
    • web
      • actions
      • auth
      • helpers
      • widgets
        • captcha
        • pagers
  • zii
    • widgets
      • grid

Classes

  • ActionFormModel
  • ArrayUtil
  • ArrayValidator
  • AssociatedMediaBehavior
  • AuxLib
  • Changelog
  • DetailView
  • EncryptUtilTmp
  • EventsWidgetFieldFormatter
  • FailedLogins
  • FieldFormatter
  • FieldFormatterBase
  • FieldInputRenderer
  • FileFieldBehavior
  • FiltersForm
  • FilterUtil
  • FineDiff
  • FineDiffCopyOp
  • FineDiffDeleteOp
  • FineDiffInsertOp
  • FineDiffOp
  • FineDiffOps
  • FineDiffReplaceOp
  • GlobalCSSFormModel
  • GlobalImportFormModel
  • GoogleAuthenticator
  • JSONFieldsBehavior
  • JSONResponse
  • MediaFieldFormatter
  • MediaSelector
  • MobileActiveRecordFieldFormatter
  • MobileActivityFeed
  • MobileChartDashboard
  • MobileFieldFormatter
  • MobileFieldInputRenderer
  • ModuleModelNameValidator
  • MultiChildNode
  • MultiTypeAutocomplete
  • PasswordUtil
  • ProductFeature
  • ProfileWidgetLayout
  • QueryParamGenerator
  • RecordLimitBehavior
  • RecordView
  • RecordViewWidgetLayout
  • RelationshipsGridModel
  • RelationshipsJoin
  • RepairUserDataCommand
  • RequestUtil
  • RequiredIfNotSetValidator
  • ResponseUtil
  • RunMigrationScriptCommand
  • ServiceWebFormDesigner
  • Settings
  • StringUtil
  • TestEmailAction
  • TestEmailActionForm
  • ThemeGenerator
  • TimerUtil
  • TopicsFieldFormatter
  • TopicsWidgetLayout
  • TransactionalViewFieldFormatter
  • UrlUtil
  • ValidLinkValidator
  • WebFormDesigner
  • WebLeadFormDesigner
  • X2ActiveRecordBehavior
  • X2ActiveRecordFieldFormatter
  • X2ButtonColumn
  • X2ConditionList
  • X2ConsoleCommand
  • X2ControllerBehavior
  • X2DataColumn
  • X2DuplicateBehavior
  • X2Flashes
  • X2GridViewFieldFormatter
  • X2IPAddress
  • X2LeadsDataColumn
  • X2MergeableBehavior
  • X2MessageSource
  • X2MobileControllerBehavior
  • X2MobileProfileControllerBehavior
  • X2MobileQuotesControllerBehavior
  • X2MobileSiteControllerBehavior
  • X2MobileTopicsControllerBehavior
  • X2ModelConversionBehavior
  • X2ModelConversionWidget
  • X2ModelForeignKeyValidator
  • X2ModelUniqueIndexValidator
  • X2NonWebUser
  • X2StaticDropdown
  • X2StaticField
  • X2StaticFieldsBehavior
  • X2UrlManager
  • X2Validator
  • X2WidgetBehavior

Interfaces

  • AdminOwnedCredentials

Exceptions

  • CampaignMailingException
  • CodeExchangeException
  • GetCredentialsException
  • NoRefreshTokenException
  • NoUserIdException
  • StringUtilException

Functions

  • checkCurrency
  • checkDNS
  • checkServerVar
  • checkTimezone
  • decodeQuotes
  • echoIcons
  • encodeQuotes
  • exceptionForError
  • getField
  • getLanguageName
  • getModuleTitle
  • handleReqError
  • handleReqException
  • installer_t
  • installer_tr
  • isAllowedDir
  • mediaMigrationRrmdir
  • migrateMediaDir
  • printGraph
  • printR
  • renderFields
  • reqShutdown
  • RIP
  • translateOptions
  • tryGetRemote
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /*****************************************************************************************
  3:  * X2Engine Open Source Edition is a customer relationship management program developed by
  4:  * X2Engine, Inc. Copyright (C) 2011-2016 X2Engine Inc.
  5:  * 
  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 X2ENGINE, X2ENGINE DISCLAIMS THE WARRANTY
 11:  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 12:  * 
 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
 16:  * details.
 17:  * 
 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
 21:  * 02110-1301 USA.
 22:  * 
 23:  * You can contact X2Engine, Inc. P.O. Box 66752, Scotts Valley,
 24:  * California 95067, USA. or at email address contact@x2engine.com.
 25:  * 
 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.
 29:  * 
 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:  * X2Engine" 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 X2Engine".
 35:  *****************************************************************************************/
 36: 
 37: /**
 38:  * Abstract Class for rendering the Form view and Detail View
 39:  * Some things are awkward from being retroactivly applied. 
 40:  * STRUCTURE: 
 41:  * With a given form layout:
 42:  * 
 43:  *      RenderMain                      (getMainOptions)
 44:  *          RenderSections              (getSectionOptions)
 45:  *              RenderSectionTitle      
 46:  *              RenderRows              (getRowOptions)
 47:  *                  RenderColumns       (getColumnOptions)
 48:  *                      RenderItems     (getItemOptions)
 49:  *                          RenderLabel 
 50:  *                          RenderAttribute
 51:  *
 52:  * The get<part>Options() function return an array of html options for 
 53:  * that section. This makes it easier to override classes you want to add on 
 54:  * specific elements
 55:  */
 56: abstract class RecordView extends X2Widget {
 57: 
 58:     /**
 59:      * @var array $htmlOptions
 60:      */
 61:     public $htmlOptions = array (
 62:         'class' => 'x2-layout-island'
 63:     ); 
 64: 
 65:     /**
 66:      * JS Class 
 67:      * @var string
 68:      */
 69:     public $JSClass = 'RecordView';
 70: 
 71:     /**
 72:      * Model Name of the record being displayed
 73:      * @var string
 74:      */
 75:     public $modelName;
 76: 
 77:     /**
 78:      * Model obejct of the record being displayed
 79:      * @var [type]
 80:      */
 81:     public $model;
 82: 
 83:     /**
 84:      * Scenario of the form. options: Default, Inline
 85:      * @var string
 86:      */
 87:     public $scenario = 'Default';
 88: 
 89:     /**
 90:      * Fields to hide from the form
 91:      * @var array
 92:      */
 93:     public $suppressFields = array();
 94: 
 95:     /**
 96:      * Special fields to render within the view
 97:      * @var array
 98:      */
 99:     public $specialFields = array();
100: 
101:     /**
102:      * The parsed JSON created from the form layout editor
103:      * @var array
104:      */
105:     public $layoutData;
106: 
107:     /**
108:      * The form settings that contains the saved collapsed sections
109:      * @var array
110:      */
111:     protected $_formSettings;
112: 
113:     /**
114:      * Array of field permissions
115:      * @var array
116:      */
117:     protected $_fieldPermissions;
118: 
119:     /**
120:      * Array of fields objects to extract settings from
121:      * @var array
122:      */
123:     protected $_fields; 
124: 
125:     /**
126:      * Renders the Attribute of a form item. 
127:      * For a View, this is the value of the field.
128:      * For a Form, this is the inpute of the field
129:      * @param  array $item  array of item settings
130:      * @param  Field $field field object being rendered
131:      * @return string        HTML to add to the form
132:      */
133:     public abstract function renderAttribute ($item, Fields $field);
134: 
135:     /**
136:      * Gets the layout of the form.
137:      * @return array Array of the form layout
138:      */
139:     public abstract function getLayoutData ();
140: 
141:     public function setFormSettings (array $formSettings) {
142:         $this->_formSettings = $formSettings;
143:     }
144: 
145:     /**
146:      * Inititialization
147:      */
148:     public function init () {
149:         parent::init();
150: 
151:         // Get default Model name
152:         if (!isset($this->modelName)) {
153:             $this->modelName = get_class($this->model);
154:         }
155: 
156:         // get the form layout data
157:         if (!isset($this->layoutData)) {
158:             $this->layoutData = $this->getLayoutData();
159:         }
160: 
161:         // Get the form settings (Collapsed Rows)
162:         if (!isset ($this->_formSettings))
163:             $this->_formSettings = Profile::getFormSettings ($this->modelName);
164: 
165:         // Get the permission for fields
166:         $this->_fieldPermissions = $this->getFieldPermissions();
167: 
168:         // populate the fields array
169:         $this->_fields = $this->getFields();
170:     }
171: 
172:     public function run () {
173:         // These are necessary variables
174:         if(!$this->layoutData) return;
175:         if(!$this->_fields) return;
176: 
177:         // Echo Content
178:         echo $this->renderMain ();
179: 
180:         // Register JS
181:         $this->registerPackages();
182: 
183:         // Instantiate JS
184:         $this->instantiateJSClass (true);
185: 
186:     }
187: 
188:     public function getPackages () {
189:         return array_merge (parent::getPackages (), array(
190:             'RecordViewJS' => array (
191:                 'baseUrl' => Yii::app()->baseUrl,
192:                 'js' => array (
193:                     'js/recordView/RecordView.js'
194:                 ),
195:                 'depends' => array('auxlib')
196:             )
197:         ));
198:     }
199: 
200:     public function getJSClassParams () {
201:         return array_merge (parent::getJSClassParams(), array(
202:             'modelId' => $this->model->id,
203:             'modelName' => $this->modelName,
204:         ));
205:     }
206: 
207:     /**
208:      * HtmlOptions for the main tag that wraps the form
209:      * @return array HTML Attributes
210:      */
211:     public function getMainOptions () {
212:         return array (
213:             'class' => 'x2-layout'
214:         );
215:     }
216: 
217:     /**
218:      * HtmlOptions for the .formSection tags 
219:      * @return array HTML Attributes
220:      */
221:     public function getSectionOptions ($section, $collapsed) {
222:         $visibility = $collapsed ? 'hideSection' : 'showSection';
223:         $collapsible = $section['collapsible'] ? 'collapsible' : '';
224: 
225:         return array (
226:             'class' => "formSection $collapsible $visibility"
227:         );
228:     }
229: 
230:     /**
231:      * HtmlOptions for the .formSectionRow tags 
232:      * @return array HTML Attributes
233:      */
234:     public function getRowOptions($row) {
235:         return array (
236:             'class' => 'formSectionRow'
237:         );
238:     }
239: 
240:     /**
241:      * HtmlOptions for the .formSectionColumn tags 
242:      * @return array HTML Attributes
243:      */
244:     public function getColumnOptions($col, $count) {
245:         $width = $col['width'];
246:         if (!preg_match('/^\d+(\.\d+)?%$/', $col['width']) && $count > 0) {
247:             $width = (100.0/$count).'%'; 
248:         }
249: 
250:         return array(
251:             'style' => "width:$width",
252:             'class' => "formSectionColumn"
253:         );
254:     }
255: 
256:     /**
257:      * HtmlOptions for the .formItem tags 
258:      * @return array HTML Attributes
259:      */
260:     public function getItemOptions ($item, Fields $field) {
261: 
262:         // noLabel, topLabel, leftLabel, inlineLabel
263:         $labelClass = $item['labelType'].'Label';
264:         if ($item['labelType'] == 'none')  {
265:             $labelClass = 'noLabel';
266:         }
267: 
268:         $inputClass = $field->type == 'text' ? " textarea" : ""; 
269: 
270:         return array (
271:             'id' => "{$field->modelName}_{$field->fieldName}_field",
272:             'class' => "formItem $labelClass $inputClass",
273:         );
274:     }
275: 
276:     /**
277:      * Renders the upper level tag and all sections
278:      * @return string HTML
279:      */
280:     public function renderMain () {
281:         $html = X2Html::openTag('div', $this->getMainOptions());
282: 
283:         $html .= $this->renderSections ();
284: 
285:         $html .= '</div>';
286:         return $html;
287:     }
288: 
289:     protected function renderSections () {
290:         $html = '';
291:         foreach($this->layoutData['sections'] as $i => $section) {
292: 
293:             // collapsed settings are determined via index
294:             $collapsed = 
295:                 (isset($this->_formSettings[$i]) && !$this->_formSettings[$i]) ||
296:                 (!isset ($this->_formSettings[$i]) && isset ($section['collapsedByDefault']) &&
297:                  $section['collapsedByDefault']);
298: 
299: 
300:             // append section
301:             $html .= $this->renderSection($section, $collapsed);
302:         }
303:         return $html;
304:     }
305: 
306:     /**
307:      * Renders the tag for all sections and renders the interior rows
308:      * @return string HTML
309:      */
310:     public function renderSection ($section, $collapsed) {
311:         $section = array_merge (array(
312:             'title' => '',
313:             'collapsible' => false,
314:             'rows' => array()
315:         ), $section);
316: 
317:         // sections are only collapsed if the section can be collapsed
318:         $collapsed &= $section['collapsible'];
319:         $html = X2Html::openTag ('div', $this->getSectionOptions($section, $collapsed));
320: 
321:         $html .= $this->renderSectionHeader ($section);
322:         $html .= X2Html::openTag ('div', array(
323:             'class' => 'tableWrapper',
324:             'style' => $collapsed ? 'display:none' : ''
325:         ));
326: 
327:         foreach($section['rows'] as $row) {
328:             $html .= $this->renderRow ($row);
329:         }
330: 
331:         $html .= '</div>';
332:         $html .= '</div>';
333: 
334:         return $html;
335:     }
336: 
337:     /**
338:      * Renders a section header
339:      * @param  array $section  Section Options
340:      */
341:     public function renderSectionHeader ($section) {
342:         $html = X2Html::openTag('div', array(
343:             'class' => 'formSectionHeader'
344:         ));
345: 
346:         // Add the collapse Icon
347:         if ($section['collapsible']) {
348:             $html .= X2Html::link (
349:                 X2Html::fa('fa-caret-down'),
350:                 'javascript:void(0)',
351:                 array( 
352:                     'class' => 'formSectionHide'
353:                 )
354:             );
355: 
356:             $html .= X2Html::link (
357:                 X2Html::fa('fa-caret-right'),
358:                 'javascript:void(0)',
359:                 array( 
360:                     'class' => 'formSectionShow'
361:                 )
362:             );
363:         }
364: 
365:         $html .= X2Html::tag('span', array(
366:             'class' => 'sectionTitle',
367:             'title' => addslashes($section['title'])
368:             ), Yii::t(strtolower(Yii::app()->controller->id), $section['title'])
369:         );
370: 
371:         $html .= '</div>';
372:         return $html;
373:     }
374: 
375:     /**
376:      * Renders a .formSectionRow and interior columns
377:      */
378:     public function renderRow ($row) {
379:         $row = array_merge(array(
380:             'cols' => array(),
381:         ), $row);
382: 
383:         $html = X2Html::openTag('div', $this->getRowOptions($row));
384:         foreach($row['cols'] as $col) {
385:             $html .= $this->renderColumn($col, count($row['cols']));
386:         }
387:         $html .= '</div>';
388: 
389:         return $html;
390:     }
391: 
392:     /**
393:      * Renders .formSectionColumn and interior Items
394:      * Note that this is a table 
395:      * @param  array $col   Layout options for columns
396:      * @param  int $count count of columns in this row
397:      */
398:     public function renderColumn ($col, $count) {
399:         $col = array_merge(array(
400:             'width' => '',
401:             'items' => array()
402:         ), $col);
403: 
404:         $html = X2Html::openTag('table', $this->getColumnOptions($col, $count));
405:         foreach($col['items'] as &$item) {
406:             $html .= $this->renderItem ($item);
407:         }
408:         $html .= '</table>';
409: 
410:         return $html;
411:     }
412: 
413: 
414:     public function renderItem ($item) {
415:         $item = array_merge (array(
416:             'name' => '',
417:             'labelType' => 'left',
418:             'readOnly' => '',
419:             'height' => '',
420:             'tabindex' => ''
421:         ), $item);
422:         if (!is_string ($item['labelType']) ||
423:             !in_array (strtolower ($item['labelType']), array ('none', 'left', 'top', 'inline'))) {
424:             $item['labelType'] = 'left';
425:         }  
426: 
427:         // Return if field was not in fields array 
428:         $fieldName = preg_replace('/^formItem_/u', '', $item['name']);
429:         if (!isset($this->_fields[$fieldName])) {
430:             return;
431:         } 
432: 
433:         // Return if there is not view permission
434:         $field = $this->_fields[$fieldName];
435:         if (in_array($fieldName, $this->suppressFields) || !$this->canView($field)) {
436:             return;
437:         }
438: 
439:         if (!$this->canEdit($field)) {
440:             $item['readOnly'] = true;
441:         }
442: 
443:         $html = '';
444:         // Only if it is a top label can we omit this tag
445:         if ($item['labelType'] != 'top') {
446:             $html .= X2Html::openTag ('tr', $this->getItemOptions($item, $field));
447:         }
448: 
449:         // call the rendering function for this label type
450:         // inline, top, left, none
451:         $fn = 'render'.$item['labelType'].'label';
452: 
453:         $html .= $this->$fn($item, $field);
454: 
455:         $html .= '</tr>';
456: 
457:         return $html;
458:     }
459: 
460:     /**
461:      * Renders the None Label type.
462:      * Omits the label and increases colspan to to 2
463:      */
464:     public function renderNoneLabel ($item, Fields $field) {
465:         $html  = '';
466: 
467:         $html .= "<td class='attribute' colspan='2'>";
468:         $html .= $this->renderAttribute ($item, $field);
469:         $html .= '</td>';
470: 
471:         return $html;
472:     }
473: 
474:     /**
475:      * @see  renderNoneLabel
476:      */
477:     public function renderInlineLabel ($item, Fields $field) {
478:         return $this->renderNoneLabel($item, $field);
479:     }
480: 
481:     /**
482:      * Renders the top label type. 
483:      * Renders the label in it's own row, 
484:      * increases colspan to 2
485:      * @param  [type] $item  [description]
486:      * @param  [type] $field [description]
487:      * @return [type]        [description]
488:      */
489:     public function renderTopLabel ($item, Fields $field) {
490:         $html  = '';
491:         
492:         $html .= '<tr class="formItem topLabel">';
493:         $html .= "<td class='label' colspan='2'>";
494:         $html .= $this->renderLabel ($field);
495:         $html .= '</td>';
496:         $html .= '</tr>';
497: 
498:         $html .= X2Html::openTag ('tr', $this->getItemOptions($item, $field));
499:         $html .= $this->renderNoneLabel($item, $field);
500:         
501:         return $html;
502:     }
503: 
504:     /**
505:      * Renders the most common label, LeftLabel
506:      */
507:     public function renderLeftLabel ($item, Fields $field) {
508:         $html  = '';
509:         
510:         $html .= "<td class='label' >";
511:         $html .= $this->renderLabel ($field);
512:         $html .= '</td>';
513: 
514:         $html .= "<td class='attribute'>";
515:         $html .= $this->renderAttribute ($item, $field);
516:         $html .= '</td>';
517:         
518:         return $html;
519:     }
520: 
521:     /**
522:      * Renders the label of a field
523:      */
524:     public function renderLabel ($field) {
525:         return X2Html::label ($this->model->getAttributeLabel($field->fieldName), false);
526:     }
527: 
528:     /**
529:      * Gets the field Permissions into an aray
530:      * @return array array of field permissions
531:      */
532:     public function getFieldPermissions () {
533:         // Admin can edit all.
534:         if (Yii::app()->params->isAdmin || empty(Yii::app()->params->roles)) {
535:             return;
536:         }
537: 
538:         return $this->model->getFieldPermissions();
539:     }
540: 
541:     /**
542:      * Retrieves all Fields for this model
543:      * @return array array of Fields objects
544:      */
545:     public function getFields () {
546:         $fields = array();
547:         if (method_exists($this->model, 'getFields')) {
548:             $fields = $this->model->getFields(true);
549:         } else {
550:             foreach (X2Model::model('Fields')->findAllByAttributes(
551:                     array('modelName' => ucfirst($this->modelName))) as $fieldModel) {
552:                 $fields[$fieldModel->fieldName] = $fieldModel;
553:             }
554:         }
555: 
556:         return $fields;
557:     }
558: 
559:     /**
560:      * Returns if the form or a specific field can be edited. 
561:      * If Field is empty, it returns permissions of whole form
562:      */
563:     public function canEdit(Fields $field) {
564:         if(Yii::app()->params->isAdmin){
565:             return true;
566:         }
567: 
568:         // If field is read only no one can edit
569:         if($field->readOnly) {
570:             return false;
571:         }
572:         
573:         // If permissions aren't set, it can be edited
574:         if (!isset($this->fieldPermissions[$field->fieldName])) {
575:             return true;
576:         }
577: 
578:         // If permissions are set to 'edit', it can be edited
579:         if ($this->fieldPermissions[$field->fieldName] === 2) {
580:             return true;
581:         }
582: 
583:         // Otherwise, it cant be edited (permissions set to 0 or 1)
584:         return false;
585:     }
586: 
587:     public function canView($field) {
588:         if(Yii::app()->params->isAdmin){
589:             return true;
590:         }
591:         
592:         // If permissions aren't set, it can be viewed
593:         if (!isset($this->fieldPermissions[$field->fieldName])) {
594:             return true;
595:         }
596: 
597:         // If permissions are set to 'view', it can be viewed
598:         if ($this->fieldPermissions[$field->fieldName] >= 1) {
599:             return true;
600:         }
601: 
602:         // Otherwise, it cant be viewed (permissions set to 0 )
603:         return false;
604:     }
605: 
606: }
607: 
608: ?>
609: 
X2CRM Documentation API documentation generated by ApiGen 2.8.0