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: 
 39: 
 40: /**
 41:  * Class to generate a CSS files from profile settings, works as a templating system.
 42:  * Templates files are .php files that return a string of css. The array $colors will be sent to 
 43:  * the files with generated keys based on $settingsList. 
 44:  *
 45:  * For example, because 'text' is a key in $settingsList, 
 46:  *       $colors[text]
 47:  *       $colors[dark_text]
 48:  *       $colors[darker_text]
 49:  *       $colors[bright_text]
 50:  *       $colors[brighter_text]
 51:  *       $colors[light_text]
 52:  *       $colors[lighter_text]
 53:  *       $colors[opaque_text]
 54:  *
 55:  *
 56:  * Are all avaliable to the templates.
 57:  * light and lighter keys are 'smart' meaning it 
 58:  * will appear brighter on dark themes and darker on dark themes.
 59:  *
 60:  *  In addition, the keys 
 61:  *
 62:  *  $colors[smart_text]
 63:  *  $colors[smart_text2]
 64:  *  
 65:  *  will adapt based on the difference in contrast between highlight1 and highlight2 with text 
 66:  *  respectively 
 67:  * 
 68:  * 
 69:  * An entry in the color array automatically adds the !important tag and a semicolon. 
 70:  * Example Template entry: 
 71:  * 
 72:  *   #content a:hover {
 73:  *      color: $colors[darker_link]  
 74:  *   }
 75:  *   
 76:  *   #content span {
 77:  *      background: $colors[highlight2]
 78:  *      color: $colors[smart_text2]
 79:  *   }
 80:  * 
 81:  * To use key that doesnt have the !important tag added, append _hex to the key
 82:  *   $colors[text_hex], $colors[darker_hex]
 83:  *
 84:  * @see ThemeBuildCommand for how to build themes out of theme tags.
 85:  */
 86: class ThemeGenerator {
 87: 
 88:     /**
 89:      * @var string Path to the folder of templates.
 90:      */
 91:     const TEMPLATE_PATH = 'components/ThemeGenerator/templates';
 92: 
 93:     /**
 94:     * @var name of default light theme
 95:     */
 96:     public static $defaultLight = 'Default';
 97: 
 98:     /**
 99:     * @var name of default dark theme
100:     */
101:     public static $defaultDark = 'Terminal';
102: 
103:     /**
104:      * @var array list of the profile setting keys and their descriptions
105:      * This list is used in the Profile Model to set up the the theme behavior
106:      * @deprecated use getProfileKeys instead
107:      */
108:     public static $settingsList = array(
109:         'background',
110:         'content',
111:         'text',
112:         'link',
113:         'highlight1',
114:         'highlight2',
115:     );
116: 
117:     private static function getCacheKey () {
118:         return get_called_class ().'_theme_'.Yii::app()->user->getName ();
119:     }
120: 
121:     public static function getSettingsList () {
122:         return array_merge (
123:             self::getProfileKeys (false, true, false));
124:     }
125: 
126:     public static function clearCache () {
127:         Yii::app()->cache->set (self::getCacheKey (), false, 0);
128:     }
129: 
130:     /**
131:      * Populates the array with different color option
132:      * @return array array filled with formatted css color strings
133:      */
134:     public static function generatePalette($preferences, $refresh=false){
135:         $computedTheme = Yii::app()->cache->get (self::getCacheKey ());
136:         if (!Yii::app()->user->isGuest && $computedTheme && !$refresh) {
137:             return $computedTheme;
138:         }
139: 
140:         $colors = $preferences;
141: 
142:         //Keys for smart text
143:         $colors['smart_text'] = '';
144:         $colors['smart_text2'] = '';
145: 
146:         if(isset($colors['backgroundImg']) && $colors['backgroundImg']) {
147:             $colors['background']='';
148:         }
149: 
150:         $settings = self::getSettingsList ();
151:         foreach($settings as $key){
152: 
153:             if (!isset ($colors[$key])) $colors[$key] = '';
154:             $value = $colors[$key];
155:             
156:             if (!preg_match("/#/", $value) && $value){
157:                 $colors[$key] = '#'.$value;
158:             }
159: 
160:             if (!preg_match ('/_override$/', $key)) {
161:                 $colors['darker_'.$key] = X2Color::brightness($value, -0.1, false);
162:                 $colors['dark_'.$key] = X2Color::brightness($value, -0.05, false);
163:                 
164:                 $colors['brighter_'.$key] = X2Color::brightness($value, 0.1, false);
165:                 $colors['bright_'.$key] = X2Color::brightness($value, 0.05, false);
166:         
167: 
168:                 $colors['opaque_'.$key] = X2Color::opaque($value, 0.2);
169:             }
170:             $colors['light_'.$key] = X2Color::brightness($value, 0.05, true);
171:             $colors['lighter_'.$key] = X2Color::brightness($value, 0.1, true);
172:         }
173: 
174:         // generate smart text for module overrides
175:         foreach (array_filter ($settings, function ($key) { 
176:             return preg_match ('/^background_.*_override$/', $key);
177:         }) as $key) {
178:             if (isset ($colors[$key]) && $colors[$key]) {
179:                 $colors[preg_replace ('/^background_/', 'smart_text_', $key)] = X2Color::smartText (
180:                     $colors[$key], $colors['text'] ? '' : '#000000');
181:             } else {
182:                 $colors[preg_replace ('/^background_/', 'smart_text_', $key)] = '';
183:             }
184:         }
185: 
186:         # settings for most borders in the app
187:         $colors['border'] = $colors['lighter_content'];
188: 
189:         # Smart text for highlight 1 (Buttons and Windows)
190:         if( isset($colors['highlight1'], $colors['text']) &&
191:                 !empty($colors['highlight1']) && !empty($colors['text']) ) {
192:             $colors['smart_text'] = X2Color::smartText($colors['highlight1'], $colors['text']);
193:         }
194: 
195:         # Smart text for highlight 2 (highlighted buttons)
196:         if( isset($colors['highlight2'], $colors['text']) &&
197:                 !empty($colors['highlight2']) && !empty($colors['text']) ) {
198:             $colors['smart_text2'] = X2Color::smartText($colors['highlight2'], $colors['text']);
199:         }
200: 
201:         Yii::app()->cache->set (self::getCacheKey (), $colors, 0);
202:         return $colors;
203:     }
204: 
205:     /**
206:      * Formats a color array to be CSS-ready by adding important tags and
207:      * adding a key appended with hex that does not have the important tags
208:      * @param array Array of color keys
209:      * @return array Array of formatted array
210:      */
211:     public static function formatColorArray($colors) {
212:         foreach($colors as $key => $value){
213:             # keep original value in special key
214:             $colors[$key.'_hex'] = $value;
215:             # Add important tags
216:             $colors[$key] = self::formatColor($value);
217:         }
218: 
219:         return $colors;
220:     }
221: 
222:     /**
223:      * Computes the theme and registers it with Yii
224:      * @param array $colors If set, will render CSS with these colors
225:      * Otherwise, it uses colors from the users profile
226:      */
227:     public static function render() {
228:         self::renderThemeWithColors ();
229:     }
230: 
231:     /**
232:      * Loads a theme for the login page
233:      * @param string $themeName string of the theme to render
234:      * @param bool $computed whether or not to include computed theme color values
235:      */
236:     public static function loadDefault($themeName, $computed=true) {
237:         //In case default light was deleted
238:         if ($themeName == self::$defaultLight) {
239:             return array('themeName'=>self::$defaultLight);
240:         }
241: 
242:         $media = X2Model::model('Media')->findByAttributes(
243:             array(
244:                 'associationType' => 'theme',
245:                 'fileName' => $themeName,
246:                 'private' => 0,
247:             )
248:         );
249: 
250:         if (!$media) {
251:             $media = X2Model::model('Media')->findByAttributes(
252:                 array(
253:                     'associationType' => 'theme',
254:                     'fileName' => self::$defaultDark
255:                 )
256:             );
257: 
258:             if (!$media) {
259:                 return self::loadDefault(self::$defaultLight);
260:             }
261:         }
262: 
263:         $theme = CJSON::decode ($media->description);
264:         if ($computed) {
265:             $colors = ThemeGenerator::generatePalette($theme, true);
266:         } else {
267:             $colors = $theme;
268:         }
269:         return $colors;
270:     }
271: 
272:    
273:     /**
274:      * Wrapper function for render and default render
275:      */
276:     public static function renderTheme($themeName=null) {
277:         if ($themeName) {
278:             $colors = self::loadDefault($themeName);
279:             self::renderThemeWithColors($colors);
280:         } else {
281:             self::render();
282:         }
283:     }
284: 
285:     public static function renderThemeColorSelector (
286:         $label, $key, $value, $htmlOptions=array (), $disabled=false) {
287: 
288:         $htmlOptions = X2Html::mergeHtmlOptions (array (
289:             'class' => 'row theme-color-selector',
290:         ), $htmlOptions);
291:         echo X2Html::openTag ('div', $htmlOptions);
292:         echo "
293:                 <label>
294:                     ".CHtml::encode ($label)."
295:                 </label>
296:                 <input type='text' name='preferences[$key]' id='preferences_$key' value='$value'
297:                  class='color-picker-input theme-attr' ".($disabled ? 'disabled="disabled"': '')."> 
298:                 </input>
299:               </div>";
300:     }
301: 
302:     /**
303:      * Renders the settings for the profile page based on the $settingsList array 
304:      * TODO: Move to a class for rendering the theme settings. 
305:      */
306:     public static function renderSettings(){
307:         $colors = self::generatePalette (Yii::app()->params->profile->getTheme());
308:         $translations = self::getTranslations();
309:         $settings = self::getSettingsList ();
310: 
311:         $i = 0;
312:         foreach($settings as $key){
313:             if (preg_match ('/_override$/', $key) && (!isset ($colors[$key]) || !$colors[$key])) {
314:                 continue;
315:             }
316:             $setting = isset ($translations[$key]) ? $translations[$key] : '';
317:             $value = isset($colors[$key]) ? $colors[$key] : '' ;
318:             self::renderThemeColorSelector ($setting, $key, $value);
319:             if (++$i % 3 == 0)
320:                 echo '</br>';
321:         }
322: 
323:         echo "<div style='clear:both;'></div>";
324:     }
325: 
326:     /**
327:      * Retrieves translated labels of field names
328:      */
329:     public static function getTranslations() {
330:         $translations = array(
331:             'background' => Yii::t('profile', 'Background'),
332:             'content' => Yii::t('profile', 'Content'),
333:             'text' => Yii::t('profile', 'Text'),
334:             'link' => Yii::t('profile', 'Links'),
335:             'highlight1' => Yii::t('profile', 'Windows and Buttons'),
336:             'highlight2' => Yii::t('profile', 'Highlight')
337:         );
338:         $moduleOverrideKeys = self::getModuleOverrideKeys (true);
339:         foreach ($moduleOverrideKeys as $key) {
340:             if (preg_match ('/^background_/', $key )) {
341:                 $translations[$key] = Modules::displayName (
342:                     true, preg_replace ('/background_([^_]*)_override$/', '$1', $key));
343:             }
344:         }
345:         return $translations;
346:     }
347: 
348:     /**
349:      * Function to remove the color from the #content element of a page. 
350:      */
351:     public static function removeBackdrop() {
352:         Yii::app()->clientScript->registerScript ('RemoveBackropJS', '
353:             $(function() {
354:                 $("#content").addClass("no-backdrop");
355:             });
356:         ', CClientScript::POS_END);
357:     }
358: 
359:     public static function isThemed() {
360:         $theme = Yii::app()->params->profile->theme['themeName'];
361:         return ($theme && $theme != self::$defaultLight);
362:     }
363: 
364:     /**
365:      * List of keys for the profile JSON fields behaviors
366:      */
367:     private static $_profileKeys;
368:     public static function getProfileKeys(
369:         $internal=true, $base=true, $computed=true) {
370: 
371:         if (!isset (self::$_profileKeys)) {
372:             $profileKeys = array(
373:                 'internal' => array (
374:                     // Internal Usage Keys (Do not use in CSS)
375:                     'themeName', 
376:                 ),
377: 
378:                 /***********************
379:                  *  Base Color Keys 
380:                  ***********************/
381: 
382:                  'base' => array (
383:                 
384:                     // The color of the background. Used in only one place
385:                     'background',
386: 
387:                      // Very common color in a theme. Background of all trays and content windows 
388:                      // in the app. Equates to White in the default theme.
389:                     'content',
390: 
391:                     // Text. Assumed to be in high contrast with 'content'
392:                     'text',
393: 
394:                     // Normal links. (<a> tags).
395:                     'link',
396: 
397:                     // Window headers, main menu bar, and buttons. 
398:                     'highlight1',
399: 
400:                     // Special Higlight color. Equates to highlightGreen color for
401:                     // the default theme. Good for highlighting save buttons. 
402:                     'highlight2',
403: 
404:                 ),
405: 
406:                 /***********************
407:                  *  Modifier Color Keys
408:                  ***********************/
409: 
410:                  'computed' => array (
411:                     // Text that will be in high contrast with highlight1. If the normal 'text' key
412:                     // does not have enough contrast, it will be inversed. 
413:                     'smart_text',
414: 
415:                     // See 'smart_text.' Same Idea but for highlight2
416:                     'smart_text2',
417: 
418:                     // Border color. Looks good with content colored elements. 
419:                     'border',
420: 
421:                     // Darker Keys will be 10% darker than what it is modifying
422:                     'darker_background',
423:                     'darker_content',
424:                     'darker_text',
425:                     'darker_link',
426:                     'darker_highlight1',
427:                     'darker_highlight2',
428: 
429:                     // Dark Keys will be 5% Darker than what it is modifying
430:                     'dark_background',
431:                     'dark_content',
432:                     'dark_text',
433:                     'dark_link',
434:                     'dark_highlight1',
435:                     'dark_highlight2',
436: 
437:                     // Bright keys will be 5% Lighter than what it is modifying
438:                     'bright_background',
439:                     'bright_content',
440:                     'bright_text',
441:                     'bright_link',
442:                     'bright_highlight1',
443:                     'bright_highlight2',
444: 
445:                     // Brighter keys will be 10% lighter than what it is modifying
446:                     'brighter_background',
447:                     'brighter_content',
448:                     'brighter_text',
449:                     'brighter_link',
450:                     'brighter_highlight1',
451:                     'brighter_highlight2',
452: 
453:                     // Apologies for the confusing names (brighter vs lighter)
454:                     // Light keys will be 5% lighter or 5% darker based on the theme
455:                     'light_background',
456:                     'light_content',
457:                     'light_text',
458:                     'light_link',
459:                     'light_highlight1',
460:                     'light_highlight2',
461: 
462:                     // Lighter Keys will be 10% lighter or 10% darker based on the theme
463:                     'lighter_background',
464:                     'lighter_content',
465:                     'lighter_text',
466:                     'lighter_link',
467:                     'lighter_highlight1',
468:                     'lighter_highlight2',
469:                         
470:                     // Opaque will be a a version of the color with 20% opaqueness i.e. 
471:                     // rgba(color, 0.2);
472:                     'opaque_background',
473:                     'opaque_content',
474:                     'opaque_text',
475:                     'opaque_link',
476:                     'opaque_highlight1',
477:                     'opaque_highlight2',
478:                 ),
479:             );
480: 
481:             $moduleOverrideKeys = self::getModuleOverrideKeys ();
482:             foreach ($moduleOverrideKeys as $type => $keys) {
483:                 $profileKeys[$type] = array_merge ($profileKeys[$type], $keys);
484:             }
485: 
486:             self::$_profileKeys = $profileKeys;
487:         }
488:         $profileKeys = self::$_profileKeys;
489: 
490:         $requestedKeys = array ();
491:         if ($internal) $requestedKeys = array_merge ($requestedKeys, $profileKeys['internal']);
492:         if ($base) $requestedKeys = array_merge ($requestedKeys, $profileKeys['base']);
493:         if ($computed) $requestedKeys = array_merge ($requestedKeys, $profileKeys['computed']);
494: 
495:         return $requestedKeys;
496:     }
497: 
498:     private static $_moduleOverrideKeys;
499:     private static function getModuleOverrideKeys ($flatten=false) {
500:         if (!isset (self::$_moduleOverrideKeys)) {
501:             $moduleNames = Modules::getModuleNames ();
502:             self::$_moduleOverrideKeys = 
503:                 array (
504:                     'base' => array_map (function ($name) {
505:                         return 'background_'.$name.'_override';
506:                     }, $moduleNames)
507:                 );
508:             self::$_moduleOverrideKeys['computed'] = 
509:                 array_merge (
510:                     array_map (function ($name) {
511:                         return 'smart_text_'.$name.'_override';
512:                     }, $moduleNames),
513:                     array_map (function ($name) {
514:                         return 'light_background_'.$name.'_override';
515:                     }, $moduleNames),
516:                     array_map (function ($name) {
517:                         return 'lighter_background_'.$name.'_override';
518:                     }, $moduleNames)
519:                 );
520:         }
521:         $moduleOverrideKeys = self::$_moduleOverrideKeys;
522:         if ($flatten) {
523:             $flattened = array ();
524:             foreach ($moduleOverrideKeys as $type => $keys) { 
525:                 $flattened = array_merge ($flattened, $keys);
526:             }
527:             return $flattened;
528:         }
529:         return $moduleOverrideKeys;
530:     }
531: 
532:     /**
533:      * Loads and processes the tempates with an array of keys
534:      * @return string $rendered css files
535:      */
536:     private static function loadTemplates($colors){
537:         $colors = self::validateColors ($colors);
538: 
539:         $css = '';
540:         $dir = new DirectoryIterator( 
541:             Yii::app()->basePath.DIRECTORY_SEPARATOR.self::TEMPLATE_PATH );
542:         foreach ($dir as $fileinfo) {
543: 
544:             if (preg_match ('/generatedModuleOverrides.php$/', $fileinfo)) {
545:                $customModuleNames = Modules::getModuleNames (true);
546:                foreach ($customModuleNames as $module) {
547:                    $css .= include $fileinfo->getPathname();
548:                }
549:             } elseif (preg_match ('/\.php$/', $fileinfo)) {
550:                 $css .= include $fileinfo->getPathname();
551:             }
552:         }
553: 
554:         return $css;
555:     }
556: 
557:     /**
558:      * Ensure that colors array has keys for all theme colors 
559:      */
560:     private static function validateColors (array $colors) {
561:         $expected = self::getProfileKeys (false, true, true);
562:         foreach ($expected as $key) {
563:             if (!isset ($colors[$key])) $colors[$key] = '';
564:             if (!isset ($colors[$key.'_hex'])) $colors[$key.'_hex'] = '';
565:         }
566:         return $colors;
567:     }
568: 
569:     /**
570:      * Loads a formatted color array into the templates and returns the generated CSS
571:      * @param array $colors Array of formatted colors
572:      * @return string string of total generated CSS 
573:      */
574:     private static function getCss($colors) {
575:         if (!$colors['themeName'] || $colors['themeName'] == self::$defaultLight){
576:             return "";
577:         }
578: 
579:         $colors = self::formatColorArray($colors);
580:         $css = self::loadTemplates($colors);
581:         return $css;
582:     }
583: 
584:     /**
585:      * Private helper method to reduce the number of places where the colors array is specified.
586:      * Allows simpler verification of colors array correctness.
587:      */
588:     private static function renderThemeWithColors ($colors=null) {
589:         if (!$colors) {
590:             $profile = Yii::app()->params->profile;
591: 
592:             // If no profile render the default theme
593:             if (!$profile) {
594:                 self::renderTheme(self::$defaultLight);
595:                 return;
596:             }
597: 
598:             $colors = $profile->getTheme();
599:             $colors = self::generatePalette($colors);
600:         }
601: 
602: 
603:         $css = self::getCss($colors);
604: 
605:         Yii::app()->clientScript->registerCSS(
606:             'ProfileGeneratedCSS', $css);
607:     }
608: 
609:     /**
610:      * Adds !important; to each set value. If a color is not set in the profile, 
611:      * simply adds a semicolon to prevent errors
612:      * @param $value string a hash code for a color (with the hash)
613:      * @return string returns the formatted color string
614:      */
615:     private static function formatColor($value){
616:         if (!$value) $value = ';';
617:         if (!preg_match('/#/', $value) && !preg_match('/rgb/', $value)) {
618:             return $value;
619:         }
620: 
621:         if(!isset($value) || !$value){
622:             $value = ';';
623:         } else {
624:             $value = "$value !important;";
625:         }
626: 
627:         return $value;
628:     }
629: 
630: }
631: 
632: ?>
633: 
X2CRM Documentation API documentation generated by ApiGen 2.8.0