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

  • X2Html
  • 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: class X2Html extends CHtml {
 38: 
 39:     /**
 40:      * Can be called to guarantee safety of attribute value before inserting into markup. 
 41:      * Far more restrictive than it needs to be, but useful in cases where a small character set
 42:      * is expected.
 43:      */
 44:      // uncomment if needed
 45:     public static function sanitizeAttribute ($value) {
 46:         // overly restrictive, but safe, regex. 
 47:         return preg_replace ("/[^a-zA-Z0-9-]/", '', $value);
 48:     }
 49: 
 50:     public static function clearfix () {
 51:         return '<span class="clearfix"></span>';
 52:     }
 53: 
 54:     public static function openBodyTag ($preferences, array $htmlOptions = array ()) {
 55:         $cs = Yii::app()->clientScript;
 56:         $baseUrl = $cs->baseUrl;
 57:         $fullscreen = $cs->fullscreen;
 58:         $style = '';
 59:         $classes = 'enable-search-bar-modes';
 60:         $noBorders = false;
 61:         if ($preferences != null && $preferences['backgroundColor'])
 62:             $style .= 'background-color:#'.$preferences['backgroundColor'].';';
 63: 
 64:         if ($preferences != null && $preferences['backgroundImg']) {
 65:             if (Yii::app()->user->isGuest) {
 66:                 $media = Media::model ()->findByAttributes (array (
 67:                     'id' => $preferences['backgroundImg']
 68:                 ));
 69:                 if ($media) {
 70:                     $mediaUrl = $media->getPublicUrl ();
 71:                 }
 72:             } else {
 73:                 $mediaUrl = $baseUrl.Yii::app()->request->scriptUrl.'/media/getFile/'.
 74:                     $preferences['backgroundImg'];
 75:             }
 76:              
 77:             if (isset ($mediaUrl)) {
 78:                 $style .= 'background-image:url('.$mediaUrl.');';
 79:                 $classes .= ' custom-background-image';
 80:             }
 81: 
 82:             switch($bgTiling = $preferences['backgroundTiling']) {
 83:                 case 'repeat-x':
 84:                 case 'repeat-y':
 85:                 case 'repeat':
 86:                     $style .= 'background-repeat:'.$bgTiling.';';
 87:                     break;
 88:                 case 'center':
 89:                     $style .=  'background-repeat:no-repeat;background-position:center center;';
 90:                     break;
 91:                 case 'stretch':
 92:                 default:
 93:                     $style .=  'background-attachment:fixed;background-size:cover;';
 94:                     $noBorders = true;
 95:             }
 96:         }
 97:         if($noBorders) $classes .= ' no-borders'; 
 98:         if($fullscreen) $classes .= ' no-widgets'; else $classes .=  ' show-widgets';
 99:         if(AuxLib::getLayoutType () !== 'responsive') $classes .=  ' disable-mobile-layout'; 
100:         $classes .= ' not-mobile-body';
101: 
102:         $htmlOptions = self::mergeHtmlOptions (array (
103:             'class' => $classes,
104:             'style' => $style
105:         ), $htmlOptions);
106:         return self::openTag ('body', $htmlOptions);
107:     }
108: 
109:     public static function renderPhoneLink ($phoneNumber) {
110:         // spaces can't be used as visual separators (see http://tools.ietf.org/html/rfc3966)
111:         $formattedNumber = preg_replace ('/ /', '', $phoneNumber);
112:         return '<a href="tel:+'.$formattedNumber.'">'.CHtml::encode ($phoneNumber) .'</a>';
113:     }
114: 
115:     public static function renderEmailLink ($emailAddress) {
116:         return '<a href="mailto:'.$emailAddress.'">'.CHtml::encode ($emailAddress) .'</a>';
117:     }
118: 
119:     public static function renderSkypeLink ($skypeUser) {
120:         $skypeUser = (array) $skypeUser;
121:         $id = uniqid ();
122:         echo 
123:             '<div id="'.$id.'">
124:                 <script>
125:                     Skype.ui ({
126:                         name: "dropdown",
127:                         element: "'.$id.'",
128:                         participants: '.CJSON::encode ($skypeUser).'
129:                     });
130:                 </script>
131:             </div>';
132:     }
133: 
134:     /**
135:      * renders a loading gif at the center of the screen (to center it within an element, add 
136:      * position: relative to one of its parents.
137:      * @param array $htmlOptions
138:      */
139:     public static function loadingIcon (array $htmlOptions=array ()) {
140:         $htmlOptions = self::mergeHtmlOptions (array (
141:             'class' => 'x2-loading-icon load8 full-page-loader x2-loader',
142:         ), $htmlOptions);
143:         $html = '';
144:         $html .= self::openTag ('div', $htmlOptions);
145:         $html .= self::openTag ('div', array ('class' => 'loader'));
146:         $html .= self::closeTag ('div');
147:         $html .= self::closeTag ('div');
148:         return $html;
149:     }
150: 
151:     /**
152:      * Safeguarded override of {@link CHtml::encode()}
153:      * 
154:      * Converts the text's encoding to avoid "invalid multibyte sequence" errors
155:      */
156:     public static function encode($text) {
157:         return parent::encode(Formatter::mbSanitize($text));
158:     }
159: 
160:     /**
161:      * Returns html for error, success, and notice flashes. 
162:      */
163:     public static function getFlashes () {
164:         if (Yii::app()->user->hasFlash('error')) {
165:             echo "<div class='flash-error'>";
166:             echo Yii::app()->user->getFlash('error');
167:             echo "</div>";
168:         }
169:         if (Yii::app()->user->hasFlash('notice')) {
170:             echo "<div class='flash-notice'>";
171:             echo Yii::app()->user->getFlash('notice');
172:             echo "</div>";
173:         }
174:         if (Yii::app()->user->hasFlash('success')) {
175:             echo "<div class='flash-success'>";
176:             echo Yii::app()->user->getFlash('success');
177:             echo "</div>";
178:         }
179:     }
180: 
181:     /**
182:      * Provides a way to add a '?' with a tooltip to show users how to use the app
183:      * 
184:      * @param type $text
185:      * @param type $superScript
186:      * @param type $id
187:      * @param type $brackets
188:      * @param type $encode
189:      * @return type
190:      */
191:     public static function hint(
192:         $text, $superScript = true, $id = null, $brackets = false, $encode = true){
193: 
194:         $text = Formatter::mbSanitize ($text);
195:         $htmlOptions = array(
196:             'class' => 'x2-hint x2-question-mark fa fa-question-circle',
197:             'title' => $encode ? htmlentities($text, ENT_QUOTES, Yii::app()->charset) : $text,
198:         );
199:         if($id !== null){
200:             $htmlOptions['id'] = $id;
201:         }
202:         return parent::tag('span', $htmlOptions, '');
203:     }
204: 
205:     public static function hint2 ($title, $htmlOptions=array (), $encode=true) {
206:         $htmlOptions = self::mergeHtmlOptions (array(
207:             'class' => 'x2-hint x2-question-mark fa fa-question-circle',
208:             'title' => $encode ? self::encode ($title) : $title
209:         ), $htmlOptions);
210:         return parent::tag('span', $htmlOptions, '');
211:     }
212: 
213:     public static function mergeHtmlOptions ($optsA, $optsB) {
214:         $opts = array ();
215:         if (isset ($optsA['class']) && isset ($optsB['class'])) {
216:             $opts['class'] = $optsA['class'].' '.$optsB['class'];
217:             unset ($optsA['class']);
218:             unset ($optsB['class']);
219:         }
220:         $opts = array_merge ($opts, $optsA, $optsB);
221:         return $opts;
222:     }
223: 
224:     /**
225:      * Generates a settings button 
226:      * @param string $alt the image alt
227:      * @param array $htmlOptions options to be applied to the settings button
228:      * @return string 
229:      */
230:     public static function settingsButton ($alt='', $htmlOptions) {
231:         if (!isset ($htmlOptions['class'])) {
232:             $htmlOptions['class'] = '';
233:         }
234:         $htmlOptions['class'] .= ' fa-lg fa fa-cog x2-settings-button';
235: 
236:         return self::openTag('span', $htmlOptions).'</span>';
237:     }
238: 
239:     /**
240:      * Renders main content page title 
241:      * @param string $pageTitle 
242:      */
243:     public static function renderPageTitle ($pageTitle, array $htmlOptions=array ()) {
244:         if (isset ($htmlOptions['class'])) {
245:             $htmlOptions['class'] .= ' page-title';
246:         } else {
247:             $htmlOptions['class'] = 'page-title';
248:         }
249:         echo self::tag('div', $htmlOptions, self::tag ('h2', array (), $pageTitle));
250:     }
251: 
252:     /**
253:      * Modified so that overridden listOptions method is called
254:      * This method is Copyright (c) 2008-2014 by Yii Software LLC
255:      * http://www.yiiframework.com/license/
256:      */
257:     public static function dropDownList($name,$select,$data,$htmlOptions=array())
258:     {
259:         /* x2modstart */ 
260:         if (isset($htmlOptions['class']) ) {
261:             $htmlOptions['class'] .= ' x2-select';
262:         } else {
263:             $htmlOptions['class'] = 'x2-select';
264:         }
265:         /* x2modend */ 
266: 
267:         $htmlOptions['name']=$name;
268: 
269:         if(!isset($htmlOptions['id']))
270:             $htmlOptions['id']=self::getIdByName($name);
271:         elseif($htmlOptions['id']===false)
272:             unset($htmlOptions['id']);
273: 
274: 
275:         self::clientChange('change',$htmlOptions);
276:         /* x2modstart */ 
277:         // use late static binding to call modified listOptions method
278:         $options="\n".static::listOptions($select,$data,$htmlOptions);
279:         /* x2modend */ 
280:         $hidden='';
281: 
282:         if(!empty($htmlOptions['multiple']))
283:         {
284:             if(substr($htmlOptions['name'],-2)!=='[]')
285:                 $htmlOptions['name'].='[]';
286: 
287:             if(isset($htmlOptions['unselectValue']))
288:             {
289:                 $hiddenOptions=isset($htmlOptions['id']) ? array('id'=>self::ID_PREFIX.$htmlOptions['id']) : array('id'=>false);
290:                 $hidden=self::hiddenField(substr($htmlOptions['name'],0,-2),$htmlOptions['unselectValue'],$hiddenOptions);
291:                 unset($htmlOptions['unselectValue']);
292:             }
293:         }
294:         // add a hidden field so that if the option is not selected, it still submits a value
295:         return $hidden . self::tag('select',$htmlOptions,$options);
296:     }
297: 
298:     /**
299:      * Modified so that overridden listOptions method is called
300:      * This method is Copyright (c) 2008-2014 by Yii Software LLC
301:      * http://www.yiiframework.com/license/ 
302:      */
303:     public static function activeDropDownList($model,$attribute,$data,$htmlOptions=array())
304:     {
305:         /* x2modstart */ 
306:         if (isset($htmlOptions['class']) ) {
307:             $htmlOptions['class'] .= ' x2-select';
308:         } else {
309:             $htmlOptions['class'] = 'x2-select';
310:         }
311:         /* x2modend */ 
312: 
313:         self::resolveNameID($model,$attribute,$htmlOptions);
314:         $selection=self::resolveValue($model,$attribute);
315:         /* x2modstart */ 
316:         // use late static binding to call modified listOptions method
317:         $options="\n".static::listOptions($selection,$data,$htmlOptions);
318:         /* x2modend */ 
319:         self::clientChange('change',$htmlOptions);
320: 
321:         if($model->hasErrors($attribute))
322:             self::addErrorCss($htmlOptions);
323: 
324:         $hidden='';
325:         if(!empty($htmlOptions['multiple']))
326:         {
327:             if(substr($htmlOptions['name'],-2)!=='[]')
328:                 $htmlOptions['name'].='[]';
329: 
330:             if(isset($htmlOptions['unselectValue']))
331:             {
332:                 $hiddenOptions=isset($htmlOptions['id']) ? array('id'=>self::ID_PREFIX.$htmlOptions['id']) : array('id'=>false);
333:                 $hidden=self::hiddenField(substr($htmlOptions['name'],0,-2),$htmlOptions['unselectValue'],$hiddenOptions);
334:                 unset($htmlOptions['unselectValue']);
335:             }
336:         }
337:         return $hidden . self::tag('select',$htmlOptions,$options);
338:     }
339: 
340:     /**
341:      * Modified to specially handle opt groups
342:      * This method is Copyright (c) 2008-2014 by Yii Software LLC
343:      * http://www.yiiframework.com/license/
344:      */
345:     public static function listOptions($selection,$listData,&$htmlOptions)
346:     {
347:         $raw=isset($htmlOptions['encode']) && !$htmlOptions['encode'];
348:         $content='';
349:         if(isset($htmlOptions['prompt']))
350:         {
351:             $content.='<option value="">'.strtr($htmlOptions['prompt'],array('<'=>'&lt;','>'=>'&gt;'))."</option>\n";
352:             unset($htmlOptions['prompt']);
353:         }
354:         if(isset($htmlOptions['empty']))
355:         {
356:             if(!is_array($htmlOptions['empty']))
357:                 $htmlOptions['empty']=array(''=>$htmlOptions['empty']);
358:             foreach($htmlOptions['empty'] as $value=>$label)
359:                 $content.='<option value="'.self::encode($value).'">'.strtr($label,array('<'=>'&lt;','>'=>'&gt;'))."</option>\n";
360:             unset($htmlOptions['empty']);
361:         }
362: 
363:         if(isset($htmlOptions['options']))
364:         {
365:             $options=$htmlOptions['options'];
366:             unset($htmlOptions['options']);
367:         }
368:         else
369:             $options=array();
370: 
371:         $key=isset($htmlOptions['key']) ? $htmlOptions['key'] : 'primaryKey';
372:         if(is_array($selection))
373:         {
374:             foreach($selection as $i=>$item)
375:             {
376:                 if(is_object($item))
377:                     $selection[$i]=$item->$key;
378:             }
379:         }
380:         elseif(is_object($selection))
381:             $selection=$selection->$key;
382: 
383:         foreach($listData as $key=>$value)
384:         {
385:             if(is_array($value))
386:             {
387:                 /* x2modstart */ 
388:                 // leave out optgroup label if key is empty string
389:                 if ($key !== '') {
390:                     $content.='<optgroup label="'.($raw?$key : self::encode($key))."\">\n";
391:                 }
392:                 /* x2modend */ 
393:                 $dummy=array('options'=>$options);
394:                 if(isset($htmlOptions['encode']))
395:                     $dummy['encode']=$htmlOptions['encode'];
396:                 $content.=self::listOptions($selection,$value,$dummy);
397:                 /* x2modstart */ 
398:                 if ($key !== '') {
399:                     $content.='</optgroup>'."\n";
400:                 }
401:                 /* x2modend */ 
402:             }
403:             else
404:             {
405:                 $attributes=array('value'=>(string)$key,'encode'=>!$raw);
406:                 if(!is_array($selection) && !strcmp($key,$selection) || is_array($selection) && in_array($key,$selection))
407:                     $attributes['selected']='selected';
408:                 if(isset($options[$key]))
409:                     $attributes=array_merge($attributes,$options[$key]);
410:                 $content.=self::tag('option',$attributes,$raw?(string)$value : self::encode((string)$value))."\n";
411:             }
412:         }
413: 
414:         unset($htmlOptions['key']);
415: 
416:         return $content;
417:     }
418: 
419:     public static function activeMultiTypeAutocomplete (
420:         CModel $model, $typeAttribute, $idAttribute, $options, array $config = array ()) {
421: 
422:         return Yii::app()->controller->widget ('MultiTypeAutocomplete', array_merge (array (
423:             'model' => $model,
424:             'selectName' => $typeAttribute,
425:             'hiddenInputName' => $idAttribute,
426:             'options' => $options,
427:         ), $config), true);
428: 
429:     }
430: 
431:     /**
432:      * @param CModel $model 
433:      * @param string $attribute 
434:      * @param array (optional) $htmlOptions 
435:      * @return string
436:      */
437:     public static function activeDatePicker (
438:         CModel $model, $attribute, array $htmlOptions = array (), $mode='date', 
439:         array $options = array ()) {
440: 
441:         $options = array_merge (array(
442:             'dateFormat' => Formatter::formatDatePicker(),
443:             'changeMonth' => true,
444:             'changeYear' => true,
445:         ), $options);
446: 
447:         ob_start ();
448:         ob_implicit_flush(false);
449:         Yii::import ('application.extensions.CJuiDateTimePicker.CJuiDateTimePicker');
450: 
451:         $model->$attribute = Formatter::formatDateTime ($model->$attribute);
452:         $renderWidget = function () use ($model, $attribute, $htmlOptions, $mode, $options) {  
453:             Yii::app()->controller->widget('CJuiDateTimePicker', array(
454:                 'model' => $model, 
455:                 'attribute' => $attribute, 
456:                 'mode' => $mode, 
457:                 'options' => $options,
458:                 'htmlOptions' => $htmlOptions,
459:                 'language' => (Yii::app()->language == 'en') ? '' : Yii::app()->getLanguage(),
460:             ));
461:         };
462:         if (Yii::app()->controller->isAjaxRequest ()) { // process output if this is an ajax request
463:             X2Widget::ajaxRender ($renderWidget);
464:         } else {
465:             $renderWidget ();
466:         }
467:         return ob_get_clean();
468:     }
469: 
470:     /**
471:      * Create a <ul> tag with <li> items from an array 
472:      * @param $listContents array of list item attributes to add to the list
473:      * The 'content' key in the array will be put on the inside of the tag rather 
474:      * than be an attribute
475:      * @param $htmlOptions html attributes to be given to the <ul> tag
476:      * @param $itemClass a class to add to all of the list Items 
477:      */
478:     public static function ul($listContents, $htmlOptions=array(), $itemClass='') {
479:         $html = '';
480:         $html .= self::openTag('ul', $htmlOptions);
481:         foreach($listContents as $item) {
482:             if( empty($item['content'] ) ) {
483:                 $content = '';
484:             } else {
485:                 $content = $item['content'];
486:                 unset( $item['content'] );
487:             }
488: 
489:             if( empty($item['class'] ) ) {
490:                 $item['class'] = '';
491:             }
492: 
493:             $item['class'].= " $itemClass";
494: 
495:             $html .= self::tag('li', $item, $content);
496:         }
497: 
498:         $html .=  '</ul>';
499: 
500:         return $html;
501:     }   
502: 
503:     public static function popUpDropDown ($list, $htmlOptions=array()) { 
504:         if (isset($htmlOptions['class'])) {
505:             $htmlOptions['class'] .= ' popup-dropdown-menu';
506:         } else {
507:             $htmlOptions['class'] = 'popup-dropdown-menu';
508:         }
509:         
510:         $ul = self::ul ($list);
511: 
512:         return self::tag('div', $htmlOptions, $ul);
513: 
514: 
515:     }
516: 
517: 
518: 
519:     /**
520:      * Create an font awesome icon tag
521:      * @param string $iconClass Name of icon such as 'fa-edit' or 'copy' (with or without fa)
522:      * @param array $htmlOptions extra options to be passed to the tag
523:      * @param string $optional content to be passed inside of the tag (not recommended)
524:      * @return string generated html content
525:      */
526:     public static function fa($iconClass, $htmlOptions = array(), $content=' ', $tag='i') {
527:         if (!isset($htmlOptions['class'])) {
528:             $htmlOptions['class'] = '';
529:         }
530: 
531:         // Prepend with fa- if not there
532:         if (!preg_match('/^fa-/', $iconClass)) {
533:             $iconClass = 'fa-'.$iconClass;
534:         }
535:         
536:         $htmlOptions['class'] .= " fa $iconClass";
537:         return self::tag($tag, $htmlOptions, $content);
538:     }
539: 
540:     /**
541:      * Create an custom icon tag
542:      * @param string $iconClass name of icon such as 'contact' or 'activity'
543:      * @param array $htmlOptions extra options to be passed to the tag
544:      * @param string $optional content to be passed inside of the tag (not recommended)
545:      * @return string generated html content
546:      */
547:     public static function x2icon($iconClass, $htmlOptions = array(), $content=' ') {
548:         if (!isset($htmlOptions['class'])) {
549:             $htmlOptions['class'] = '';
550:         }
551:         
552:         $htmlOptions['class'] .= " icon-$iconClass";
553:         return self::tag('i', $htmlOptions, $content);
554:     }
555: 
556: 
557:     public static function IEBanner($ver = 9, $echo = true) {
558:         if (AuxLib::getIEVer() >= $ver) {
559:             return false;
560:         }
561:         
562:         $htmlOptions = array(
563:             'class' => 'ie-banner'
564:         );
565: 
566:         $message = Yii::t('app', 
567:             'This feature does not support your version of Internet Explorer');
568:         
569:         if ($echo) {
570:             echo self::tag ('h2', $htmlOptions, Yii::t('app', $message));
571:             return true;
572:         } else {
573:             return self::tag ('h2', $htmlOptions, Yii::t('app', $message));
574:         }
575: 
576:     }
577: 
578:     /*********************************
579:     * Record view Page title items
580:     * (I believe these belong in a record-view shared class)
581:     ********************************/
582:     public static function emailFormButton() {
583:         return CHtml::link(
584:             '', 
585:             '#',
586:         array(
587:             'class' => 'x2-button icon right email',
588:             'title' => Yii::t('app', 'Open email form'),
589:             'onclick' => 'toggleEmailForm(); return false;'
590:         ));
591:     }
592: 
593:     public static function editRecordButton($model) {
594:         return CHtml::link('', array(
595:                 'update', 
596:                 'id' => $model->id
597:             ), array(
598:                 'class' => 'x2-button icon edit right',
599:                 'title' => Yii::t('app', "Edit")
600:         )); 
601:     }
602: 
603:     /**
604:      * Deprecated. Inline buttons are in the form now. 
605:      */
606:     public static function inlineEditButtons() {
607:         $html = '';
608:         $html .= CHtml::link( 
609:             X2Html::fa('fa-check-circle fa-lg').Yii::t('app', 'Confirm'),
610:             '#',
611:              array(
612:                 'id'=>'inline-edit-save',
613:                 'class'=>'x2-button icon right inline-edit-button highlight',
614:                 'style'=>'display:none;',
615:                 'title'=> Yii::t('app', 'Confirm change to fields')
616:             )
617:         );
618: 
619:         $html .= CHtml::link(
620:             X2Html::fa('fa-times fa-lg').'  '.Yii::t('app', 'Cancel'),
621:             '#',
622:             array(
623:                 'id'=>'inline-edit-cancel',
624:                 'class'=>'x2-button icon right inline-edit-button',
625:                 'style'=>'display:none;',
626:                 'title'=> Yii::t('app', 'Cancel changes to fields')
627:             )
628:         );
629: 
630:         return $html;
631:     }
632: 
633:     public static function addErrorCss(&$htmlOptions) {
634:         return parent::addErrorCss ($htmlOptions);
635:     }
636: 
637:     public static function quoteIcon () {
638:         // return X2Html::x2icon('quotes');
639:         return "
640:             <span class='fa-stack quote-icon'>
641:                 <i class='fa fa-file-o fa-stack-1x fa-flip-horizontal'></i>
642:                 <i class='fa fa-pencil fa-stack-1x'></i>
643:             </span>";
644:     }
645: 
646:     public static function activeRichTextArea (
647:         CModel $model, $attribute, array $htmlOptions=array ()) {
648: 
649:         Yii::app()->clientScript->registerPackage('emailEditor');
650: 
651:         if (isset ($htmlOptions['class'])) {
652:             $htmlOptions['class'] .= ' x2-rich-textarea';
653:         } else {
654:             $htmlOptions['class'] = 'x2-rich-textarea';
655:         }
656: 
657:         if (!isset ($htmlOptions['width'])) {
658:             $htmlOptions['width'] = '725px';
659:         }
660:         if (!isset ($htmlOptions['height'])) {
661:             $htmlOptions['height'] = '125px';
662:         }
663: 
664:         return CHtml::activeTextArea ($model, $attribute, $htmlOptions);
665:     }
666: 
667:     public static function activeCodeEditor (
668:         CModel $model, $attribute, array $htmlOptions = array ()) {
669: 
670:         if (isset ($htmlOptions['class'])) {
671:             $htmlOptions['class'] .= ' x2-code-editor';
672:         } else {
673:             $htmlOptions['class'] = 'x2-code-editor';
674:         }
675: 
676:         Yii::app()->clientScript->registerPackage('CodeMirrorJS');
677:         return CHtml::activeTextArea ($model, $attribute, $htmlOptions);
678:     }
679: 
680:     public static function minimizeButton (
681:         array $htmlOptions=array (), $hideableSelector=null, $left=true, $defaultOpen=false) {
682: 
683:         $orientation = $left ? 'left' : 'right';
684:         if ($hideableSelector) {
685:             $js = "$('$hideableSelector').toggle ();";
686:         } else {
687:             $js = "";
688:         }
689:         $html = 
690:             X2Html::fa('fa-caret-'.$orientation, array_merge (array (
691:                 'style' => !$defaultOpen ? '' : 'display: none;',
692:                 'onClick' => '$(this).hide (); $(this).next ().show ();'.$js.
693:                     '; event.stopPropagation (); event.preventDefault ();',
694:             ), $htmlOptions)).
695:             X2Html::fa('fa-caret-down', array_merge (array (
696:                 'style' => $defaultOpen ? '' : 'display: none;',
697:                 'onClick' => 
698:                     '$(this).hide (); $(this).prev ().show ();'.$js.
699:                     '; event.stopPropagation (); event.preventDefault ();',
700:             ), $htmlOptions));
701:         return $html;
702:     }
703:     
704:     /**
705:      * This method is Copyright (c) 2008-2014 by Yii Software LLC
706:      * http://www.yiiframework.com/license/ 
707:      */
708:     public static function css($text, $media='', array $htmlOptions=array ())
709:     {
710:         if($media!=='')
711:             $media=' media="'.$media.'"';
712:         return "<style ".self::renderAttributes ($htmlOptions)
713:             ." type=\"text/css\"{$media}>\n/*<![CDATA[*/\n{$text}\n/*]]>*/\n</style>";
714:     }
715: 
716:     public static function dynamicDate ($date) {
717:         return '<span title="'.
718:             CHtml::encode (Formatter::formatCompleteDate ($date)).'">'.
719:             CHtml::encode (Formatter::formatDateDynamic ($date)).
720:         '</span>';
721:     }
722: 
723:     /**
724:      * Echos a divider useful for custom forms. Example usage in webform creator
725:      * @param  string $width  width of divider
726:      * @param  string $margin Margin on either side of element
727:      */
728:     public static function divider($width='100%', $margin='15px') {
729:         return "<div class='x2-divider' style='width:100%;max-width:$width; margin-top: $margin; margin-bottom: $margin'></div>";
730:     }
731: 
732:     /**
733:      * Echos the default avatar for a profile
734:      */
735:     public static function defaultAvatar ($size='') {
736:         return self::x2icon ('profile-large', array(
737:             'style' => "font-size: ${size}px;",
738:             'class' => 'default-avatar', 
739:         ));
740:     }
741: 
742:     /**
743:      * Returns an input with the CSRF Token
744:      */
745:     public static function csrfToken(){
746:         return self::hiddenField('YII_CSRF_TOKEN', Yii::app()->request->csrfToken);
747:     }
748: 
749:     public static function logo ($type, array $htmlOptions = array ()) {
750:         assert (in_array ($type, array ('mobile', 'menu', 'login_white', 'login_black', 'about')));
751: 
752:         $logoName = $type.'_logo';
753:         $html = '';
754:         if (in_array ($type, array ('menu')) && Auxlib::isIE8() ||
755:             in_array ($type, array ('login_white', 'login_black', 'mobile')) && Auxlib::isIE()) {
756:             $htmlOptions = self::mergeHtmlOptions (array (
757:                 'class' => $logoName,
758:             ), $htmlOptions);
759:             $filename = $logoName.'.png';
760:             $html .= CHtml::image(
761:                 Yii::app()->request->baseUrl.'/images/'.$filename, 
762:                 Yii::app()->settings->appName,
763:                 $htmlOptions);
764:         } else {
765:             $htmlOptions = self::mergeHtmlOptions (array (
766:                 'class' => 'icon-x2-logo-square '.$logoName,
767:             ), $htmlOptions);
768:             $html .= CHtml::tag('span', $htmlOptions, ' ');
769:         }
770:         return $html;
771:     }
772: 
773:     public static function x2ActivePasswordField (
774:         CModel $model, $attr, array $htmlOptions=array (), $enableVisibilityToggle=false) {
775: 
776:         static $counter = 0;
777: 
778:         $html = '';
779:         if ($enableVisibilityToggle) {
780:             $id = isset ($htmlOptions['id']) ? 
781:                 $htmlOptions['id'] : 'X2Html_'.__FUNCTION__.'_'.$counter++;
782:                 $htmlOptions['id'] = $id;
783:         }
784:         $html .= CHtml::activePasswordField($model, $attr, $htmlOptions);
785:         if ($enableVisibilityToggle) {
786:             $html .= '<div class="password-visibility-toggle" 
787:                 title="'.CHtml::encode (Yii::t('app', 'Toggle password visibility')).'">';
788:             $html .= self::fa ('eye');
789:             $html .= self::fa ('eye-slash', array ('style' => 'display:none;'));
790:             $html .= '</div>';
791:             Yii::app()->clientScript->registerScript('activePasswordField'.$id,"
792:             ;(function () {
793:                 $('#$id').siblings ('.password-visibility-toggle').on ('click', function (elem) {
794:                     $(this).children ().toggle ();
795:                     var input$ = $('#$id');
796:                     input$.attr ('type', input$.attr ('type') === 'password' ? 'text' : 'password');
797:                 });
798:             }) ();
799:             ");
800:         }
801:         return $html;
802:     }
803: 
804:     public static function orderedList (array $items, array $htmlOptions=array ()) {
805:         return self::_list (true, $items, $htmlOptions);
806:     }
807: 
808:     public static function unorderedList (array $items, array $htmlOptions=array ()) {
809:         return self::_list (false, $items, $htmlOptions);
810:     }
811: 
812:     /**
813:      * Creates fragment targets which are offset by a little more than the height of the top menu. 
814:      * Allows you to link inside documents without having the top of the section you're linking to 
815:      * cut off.
816:      */
817:     public static function fragmentTarget ($id) {
818:         return self::tag (
819:             'span', 
820:             array ('class' => 'fragment-target-outer'), 
821:             self::tag ('span', array ('class' => 'fragment-target', 'id' => $id)));
822:     }
823: 
824:     private static function _list ($ordered=false, array $items, array $htmlOptions=array ()) {
825:         $html = '';
826:         $html .= self::openTag ($ordered ? 'ol' : 'ul', $htmlOptions);
827:         foreach ($items as $item) {
828:             $html .= self::tag ('li', array (), $item);
829:         }
830:         $html .= self::closeTag ($ordered ? 'ol' : 'ul');
831:         return $html;
832:     }
833: 
834:     public static function encodeArray ($arr) {
835:         return array_map (function ($elem) {
836:             return CHtml::encode ($elem);
837:         }, $arr);
838:     }
839: 
840:     public static function resolveId (CModel $model, $attr) {
841:         $htmlOptions = array ();
842:         self::resolveNameId ($model, $attr, $htmlOptions);
843:         return $htmlOptions['id'];
844:     }
845: 
846: }
847: 
X2CRM Documentation API documentation generated by ApiGen 2.8.0