1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36:
37:
38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50:
51: class Fields extends CActiveRecord {
52:
53: 54: 55: 56:
57: const NAMEID_DELIM = '_';
58:
59: const MULTI_ASSIGNMENT_DELIM = ', ';
60:
61: const RATING_MIN = 1;
62:
63: const RATING_MAX = 5;
64:
65: const WRITE_PERMISSION = 2;
66:
67: const READ_PERMISSION = 1;
68:
69: const NO_PERMISSION = 0;
70:
71: public $includeEmpty = true;
72:
73: private $_myTableName;
74:
75: private $_typeChanged = false;
76:
77: private static $_purifier;
78:
79: 80: 81: 82: 83: 84: 85:
86: public static $phpTypes = array(
87: 'assignment' => 'string',
88: 'boolean' => 'boolean',
89: 'credentials' => 'integer',
90: 'currency' => 'double',
91: 'date' => 'integer',
92: 'dateTime' => 'integer',
93: 'dropdown' => 'string',
94: 'email' => 'string',
95: 'int' => 'integer',
96: 'link' => 'string',
97: 'optionalAssignment' => 'string',
98: 'percentage' => 'double',
99: 'rating' => 'integer',
100: 'varchar' => 'string',
101: );
102:
103: 104: 105:
106: public function __construct($scenario = 'insert') {
107: parent::__construct($scenario);
108: if($scenario == 'search') {
109: $this->setAttributes(
110: array_fill_keys(
111: $this->attributeNames(),
112: null
113: ),
114: false);
115: }
116: }
117:
118: public function behaviors () {
119: return array_merge (parent::behaviors (), array (
120: 'CommonFieldsBehavior' => array (
121: 'class' => 'application.components.behaviors.CommonFieldsBehavior',
122: )
123: ));
124: }
125:
126: public function getDropdownValue ($fieldValue) {
127: return X2Model::model('Dropdowns')->getDropdownValue(
128: $this->linkType, $fieldValue);
129: }
130:
131: public function getDropdownOptions () {
132: return Dropdowns::getItems($this->linkType, null, true);
133: }
134:
135: public function setAttributes ($values, $safeOnly=true) {
136: if (isset ($values['type']) && $this->type !== $values['type']) {
137: $this->_typeChanged = true;
138: }
139: return parent::setAttributes ($values, $safeOnly);
140: }
141:
142: 143: 144: 145: 146: 147: 148: 149: 150:
151: public function rules(){
152:
153:
154: return array(
155: array('modelName, attributeLabel', 'length', 'max' => 250),
156: array('fieldName','length','max'=>64),
157: array('fieldName','match','pattern'=>'/^[a-zA-Z]\w+$/','message'=>Yii::t('admin','Field name may only contain alphanumeric characters and underscores.')),
158: array('fieldName','nonReserved'),
159: array('modelName, fieldName, attributeLabel', 'required'),
160: array(
161: 'modelName','in','range'=>array_keys(X2Model::getModelNames()),'allowEmpty'=>false),
162: array('defaultValue','validDefault'),
163: array('relevance','in','range'=>array_keys(self::searchRelevance())),
164: array('custom, modified, readOnly, searchable, required, uniqueConstraint', 'boolean'),
165: array('fieldName','uniqueFieldName'),
166: array('linkType','length','max'=>250),
167: array('description','length','max'=>500),
168: array('type','length','max'=>20),
169: array('keyType','in','range' => array('MUL','UNI','PRI','FIX','FOR'), 'allowEmpty'=>true),
170: array('keyType','requiredUnique'),
171: array('data','validCustom'),
172:
173:
174: array('id, modelName, fieldName, attributeLabel, custom, modified, readOnly, keyType', 'safe', 'on' => 'search'),
175: );
176: }
177:
178: 179: 180: 181: 182:
183: public function countNonNull() {
184: return Yii::app()->db->createCommand()->
185: select('COUNT(*)')->
186: from(X2Model::model($this->modelName)->tableName())->
187: where(
188: "{$this->fieldName} IS NOT NULL AND
189: {$this->fieldName} != :default AND
190: {$this->fieldName} != ''",
191: array(
192: ':default' => $this->defaultValue
193: )
194: )->queryScalar();
195: }
196:
197: public static function getLinkTypes () {
198: return Yii::app()->db->createCommand ("
199: SELECT distinct(modelName)
200: FROM x2_fields
201: WHERE fieldName='nameId'
202: ORDER by modelName ASC
203: ")->queryColumn ();
204: }
205:
206: 207: 208: 209: 210: 211: 212: 213: 214: 215:
216: public static function getDisplayedModelNamesList(){
217: $modelList = array();
218: foreach(X2Model::model('Modules')->findAllByAttributes(array('editable' => true, 'visible' => 1)) as $module){
219: if($modelName = X2Model::getModelName($module->name)){
220: $modelName = $module->name;
221: }else{
222: $modelName = ucfirst($module->name);
223: }
224: if(Yii::app()->user->checkAccess(ucfirst($module->name).'Index', array())){
225: $modelList[$modelName] = $module->title;
226: }
227: }
228: return array_map(function($term){
229: return Yii::t('app', $term);
230: },$modelList);
231: }
232:
233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247:
248: public static function getFieldTypes($scenario = null){
249: $fieldTypes = array(
250: 'varchar' => array(
251: 'title' => Yii::t('admin', 'Single Line Text'),
252: 'validator' =>'safe',
253: 'columnDefinition' => 'VARCHAR(255)',
254: 'phpType' => 'string'
255: ),
256: 'text' => array(
257: 'title' => Yii::t('admin', 'Multiple Line Text Area'),
258: 'validator' => 'safe',
259: 'columnDefinition' => 'TEXT',
260: 'phpType' => 'string'
261: ),
262: 'date' =>array(
263: 'title'=>Yii::t('admin','Date'),
264: 'validator'=>'int',
265: 'columnDefinition'=>'BIGINT',
266: 'phpType' => 'integer'
267: ),
268: 'dateTime' =>array(
269: 'title'=>Yii::t('admin','Date/Time'),
270: 'validator'=>'int',
271: 'columnDefinition'=>'BIGINT',
272: 'phpType' => 'integer'
273: ),
274: 'dropdown'=>array(
275: 'title'=>Yii::t('admin','Dropdown'),
276: 'validator'=>'safe',
277: 'columnDefinition'=>'VARCHAR(255)',
278: 'phpType' => 'string'
279: ),
280: 'int'=>array(
281: 'title'=>Yii::t('admin','Number'),
282: 'validator'=> 'int',
283: 'columnDefinition'=>'BIGINT',
284: 'phpType' => 'integer'
285: ),
286: 'percentage'=>array(
287: 'title'=>Yii::t('admin','Percentage'),
288: 'validator' => 'numerical',
289: 'columnDefinition' => 'FLOAT',
290: 'phpType' => 'double'
291: ),
292: 'email'=>array(
293: 'title'=>Yii::t('admin','Email'),
294: 'validator'=>'email',
295: 'columnDefinition'=>'VARCHAR(255)',
296: 'phpType' => 'string'
297: ),
298: 'currency'=>array(
299: 'title'=>Yii::t('admin','Currency'),
300: 'validator'=>'numerical',
301: 'columnDefinition'=>'DECIMAL(18,2)',
302: 'phpType' => 'double'
303: ),
304: 'url'=>array(
305: 'title'=>Yii::t('admin','URL'),
306: 'validator'=>'safe',
307: 'columnDefinition'=>'VARCHAR(255)',
308: 'phpType' => 'string'
309: ),
310: 'float'=>array(
311: 'title'=>Yii::t('admin','Decimal'),
312: 'validator'=>'numerical',
313: 'columnDefinition'=>'FLOAT',
314: 'phpType' => 'double'
315: ),
316: 'boolean'=>array(
317: 'title'=>Yii::t('admin','Checkbox'),
318: 'validator'=>'boolean',
319: 'columnDefinition'=>'BOOLEAN NOT NULL DEFAULT 0',
320: 'phpType' => 'boolean'
321: ),
322: 'link'=>array(
323: 'title'=>Yii::t('admin','Lookup'),
324: 'validator'=>'safe',
325: 'columnDefinition'=>'VARCHAR(255)',
326: 'phpType' => 'integer'
327: ),
328: 'rating'=>array(
329: 'title'=>Yii::t('admin','Rating'),
330: 'validator'=>'safe',
331: 'columnDefinition'=>'VARCHAR(255)',
332: 'phpType' => 'integer'
333: ),
334: 'assignment'=>array(
335: 'title'=>Yii::t('admin','Assignment'),
336: 'validator'=>'safe',
337: 'columnDefinition' => 'VARCHAR(255)',
338: 'phpType' => 'string'
339: ),
340: 'visibility'=>array(
341: 'title'=>Yii::t('admin','Visibility'),
342: 'validator'=>'int',
343: 'columnDefinition'=>'INT NOT NULL DEFAULT 1',
344: 'phpType' => 'boolean'
345: ),
346: 'timerSum'=>array(
347: 'title'=>Yii::t('admin','Action Timer Sum'),
348: 'validator'=>'safe',
349: 'columnDefinition'=>'INT',
350: 'phpType' => 'integer'
351: ),
352: 'phone'=>array(
353: 'title'=>Yii::t('admin','Phone Number'),
354: 'validator'=>'safe',
355: 'columnDefinition'=>'VARCHAR(40)',
356: 'phpType' => 'string'
357: ),
358: 'custom'=>array(
359: 'title' => Yii::t('admin','Custom'),
360: 'validator' => 'safe',
361: 'columnDefinition' => 'VARCHAR(255)',
362: 'phpType' => 'string'
363: ),
364: );
365:
366: if(empty($scenario)){
367: return $fieldTypes;
368: }else{
369:
370: if(!is_array($scenario)){
371: $scenario = array($scenario);
372: }
373: $ret = array();
374:
375: if(in_array('validator', $scenario)){
376: if(count($scenario) == 1){
377: foreach($fieldTypes as $fieldType => $data){
378: $ret[$fieldType] = $data['validator'];
379: }
380: }else{
381: foreach($fieldTypes as $fieldType => $data){
382: $ret[$fieldType]['validator']=$data['validator'];
383: }
384: }
385: }
386: if(in_array('title', $scenario)){
387: if(count($scenario) == 1){
388: foreach($fieldTypes as $fieldType => $data){
389: $ret[$fieldType] = $data['title'];
390: }
391: }else{
392: foreach($fieldTypes as $fieldType => $data){
393: $ret[$fieldType]['title']=$data['title'];
394: }
395: }
396: }
397: if(in_array('columnDefinition', $scenario)){
398: if(count($scenario) == 1){
399: foreach($fieldTypes as $fieldType => $data){
400: $ret[$fieldType] = $data['columnDefinition'];
401: }
402: }else{
403: foreach($fieldTypes as $fieldType => $data){
404: $ret[$fieldType]['columnDefinition']=$data['columnDefinition'];
405: }
406: }
407: }
408: return $ret;
409: }
410: }
411:
412: 413: 414: 415: 416: 417:
418: public static function getLinkId($type, $name){
419: if(strtolower($type) == 'contacts')
420: $model = X2Model::model('Contacts')->find('CONCAT(firstName," ",lastName)=:name', array(':name' => $name));
421: else
422: $model = X2Model::model(ucfirst($type))->findByAttributes(array('name' => $name));
423: if(isset($model))
424: return $model->name;
425: else
426: return null;
427: }
428:
429: 430: 431: 432: 433:
434: public static function getPurifier(){
435: if(!isset(self::$_purifier)){
436: self::$_purifier = new CHtmlPurifier();
437:
438: self::$_purifier->options = array(
439: 'HTML.ForbiddenElements' => array(
440: 'script',
441: 'form',
442: 'style',
443: 'iframe',
444: 'frame',
445: 'link',
446: 'video',
447: 'audio',
448: 'object',
449: ),
450: 'HTML.ForbiddenAttributes' => array(
451:
452: '*@id',
453: '*@class',
454: '*@name',
455:
456: ),
457:
458: );
459: }
460: return self::$_purifier;
461: }
462:
463: 464: 465: 466:
467: public static function model($className = __CLASS__){
468: return parent::model($className);
469: }
470:
471: 472: 473: 474: 475: 476: 477: 478: 479:
480: public static function nameAndId($nameId) {
481:
482: $delimPos = strrpos($nameId,Fields::NAMEID_DELIM);
483:
484: if($delimPos === false) {
485:
486: return array($nameId,null);
487: }
488:
489: if($delimPos >= strlen($nameId)-1) {
490:
491:
492: return array($nameId,null);
493: }
494:
495: $id = substr($nameId,$delimPos+1);
496: $name = substr($nameId,0,$delimPos);
497:
498: if(!ctype_digit($id)) {
499:
500: return array($nameId,null);
501: } else {
502:
503: return array($name,$id);
504: }
505: }
506:
507: public static function id ($nameId) {
508: list ($name, $id) = self::nameAndId ($nameId);
509: return $id;
510: }
511:
512: 513: 514:
515: public static function nameId($name,$id) {
516: return $name.self::NAMEID_DELIM.$id;
517: }
518:
519: 520: 521: 522: 523: 524:
525: public static function parseUsers($arr){
526: 527:
528: $str="";
529: if(is_array($arr)){
530: $arr = array_filter ($arr, function ($a) { return $a !== ''; });
531: $str=implode(', ',$arr);
532: } else if(is_string($arr))
533: $str = $arr;
534: return $str;
535: }
536:
537: 538: 539: 540: 541: 542: 543:
544: public static function parseUsersTwo($arr){
545: $str="";
546: if(is_array($arr)){
547: $arr=array_keys($arr);
548: $str=implode(', ',$arr);
549: }
550:
551: return $str;
552: }
553:
554: public static function searchRelevance() {
555: return array('Low' => Yii::t('app', 'Low'), "Medium" => Yii::t('app', "Medium"), "High" => Yii::t('app', "High"));
556: }
557:
558: 559: 560: 561: 562: 563: 564: 565:
566: public static function strToNumeric($input, $type = 'float', $curSym = null){
567: $sign = 1;
568:
569: $inType = gettype($input);
570: if($inType != 'string'){
571: if($type == $inType)
572: return $inType;
573: else
574: return ($type == 'int' ? (int) $input : (float) $input);
575: }
576:
577:
578: $value = trim($input);
579: if(strpos($value, '(') === 0)
580: $sign = -1;
581: $posNeg = strpos($value, '-');
582: if($posNeg === 0 || $posNeg === strlen($value) - 1)
583: $sign = -1;
584:
585:
586: if(!function_exists('stripSymbols')){
587: function stripSymbols($s){ return !empty($s); }
588: }
589: $stripSymbols = array_filter(array_values(Yii::app()->params->supportedCurrencySymbols), 'stripSymbols');
590:
591:
592: if (!is_null($curSym))
593: $stripSymbols[] = $curSym;
594:
595: $defaultSym = Yii::app()->getLocale()->getCurrencySymbol(Yii::app()->settings->currency);
596: if($defaultSym)
597: if(!in_array($defaultSym, $stripSymbols))
598: $stripSymbols[] = $defaultSym;
599: $stripSymbols[] = '%';
600: $grpSym = Yii::app()->getLocale()->getNumberSymbol('group');
601: if(!empty($grpSym) && $type != 'percentage')
602: $stripSymbols[] = $grpSym;
603: $value = strtr($value, array_fill_keys($stripSymbols, ''));
604:
605:
606: $value = trim($value, "-() ");
607: $converted = strtr($value, array_flip(get_html_translation_table(HTML_ENTITIES, ENT_QUOTES)));
608: $value = trim($converted, chr(0xC2).chr(0xA0));
609:
610: 611: 612: 613:
614: if($value === null || $value === '')
615: return null;
616: else if(!in_array($type, array('int', 'currency', 'float', 'percentage')))
617: return $value;
618: else if(!preg_match('/^([\d\.,]+)e?[\+\-]?\d*$/', $value))
619: return $input;
620:
621: $value = str_replace(Yii::app()->getLocale()->getNumberSymbol('decimal'), '.', $value);
622: if(in_array($type, array('float', 'currency', 'percentage'))){
623: return ((float) $value) * $sign;
624: }else if($type == 'int'){
625: return ((int) $value) * $sign;
626: } else
627: return $value;
628: }
629:
630: 631: 632: 633: 634:
635: public function beforeSave () {
636: $valid = parent::beforeSave ();
637: if ($valid && $this->_typeChanged) {
638: $table = Yii::app()->db->schema->tables[$this->myTableName];
639: $existing = array_key_exists($this->fieldName, $table->columns) &&
640: $table->columns[$this->fieldName] instanceof CDbColumnSchema;
641: if($existing){
642: $valid = $this->modifyColumn();
643: }
644: }
645: return $valid;
646: }
647:
648: 649: 650: 651: 652: 653: 654: 655: 656:
657: public function afterSave(){
658:
659: $table = Yii::app()->db->schema->tables[$this->myTableName];
660: $existing = array_key_exists($this->fieldName, $table->columns) &&
661: $table->columns[$this->fieldName] instanceof CDbColumnSchema;
662:
663: if(!$existing){
664: $this->createColumn();
665: }
666: if($this->keyType != 'PRI' && $this->keyType != 'FIX'){
667:
668:
669:
670: if($this->keyType != null){
671: $this->dropIndex();
672: $this->createIndex($this->keyType === 'UNI');
673: }else{
674: $this->dropIndex();
675: }
676: }
677: if ($this->isNewRecord) {
678:
679: $dataProvider = new CActiveDataProvider('Roles');
680: foreach ($dataProvider->getData() as $role) {
681: $permission = new RoleToPermission();
682: $permission->roleId = $role->id;
683: $permission->fieldId = $this->id;
684: $permission->permission = 2;
685: $permission->save();
686: }
687: }
688:
689: return parent::afterSave();
690: }
691:
692: public function afterDelete() {
693: $this->dropColumn();
694: return parent::afterDelete();
695: }
696:
697: 698: 699:
700: public function attributeLabels(){
701: return array(
702: 'id' => Yii::t('admin', 'ID'),
703: 'modelName' => Yii::t('admin', 'Model Name'),
704: 'fieldName' => Yii::t('admin', 'Field Name'),
705: 'attributeLabel' => Yii::t('admin', 'Attribute Label'),
706: 'custom' => Yii::t('admin', 'Custom'),
707: 'modified' => Yii::t('admin', 'Modified'),
708: 'readOnly' => Yii::t('admin', 'Read Only'),
709: 'required' => Yii::t('admin', "Required"),
710: 'searchable' => Yii::t('admin', "Searchable"),
711: 'relevance' => Yii::t('admin', 'Search Relevance'),
712: 'uniqueConstraint' => Yii::t('admin', 'Unique'),
713: 'defaultValue' => Yii::t('admin', 'Default Value'),
714: 'keyType' => Yii::t('admin','Key Type'),
715: 'data' => Yii::t('admin','Template'),
716: );
717: }
718:
719: 720: 721: 722: 723: 724: 725: 726:
727: public function beforeValidate() {
728: if($this->isNewRecord){
729: if(strpos($this->fieldName,'c_') !== 0 && $this->custom && $this->scenario != 'test'){
730:
731:
732: $this->fieldName = "c_{$this->fieldName}";
733: }
734: }
735: return parent::beforeValidate();
736: }
737:
738: 739: 740:
741: public function createColumn(){
742:
743: $fieldType = $this->type;
744: $columnDefinitions = Fields::getFieldTypes('columnDefinition');
745: if(isset($columnDefinitions[$fieldType])){
746: $fieldType = $columnDefinitions[$fieldType];
747: }else{
748: $fieldType = 'VARCHAR(250)';
749: }
750: $sql = "ALTER TABLE `{$this->myTableName}` ADD COLUMN `{$this->fieldName}` $fieldType";
751: try{
752: Yii::app()->db->createCommand($sql)->execute();
753: }catch(CDbException $e){
754: $this->delete();
755: }
756: }
757:
758: 759: 760:
761: public function modifyColumn () {
762:
763: $fieldType = $this->type;
764: $columnDefinitions = Fields::getFieldTypes('columnDefinition');
765:
766: if(isset($columnDefinitions[$fieldType])){
767: $fieldType = $columnDefinitions[$fieldType];
768: }else{
769: $fieldType = 'VARCHAR(250)';
770: }
771:
772:
773: $sql = "ALTER TABLE `{$this->myTableName}` MODIFY COLUMN `{$this->fieldName}` $fieldType";
774: try{
775: Yii::app()->db->createCommand($sql)->execute();
776: }catch(CDbException $e){
777: $this->addError ('type', $e->getMessage ());
778: return false;
779: }
780: return true;
781: }
782:
783: 784: 785:
786: public function createIndex($unique = false){
787: $indexType = $unique ? "UNIQUE" : "INDEX";
788: $sql = "ALTER TABLE `{$this->myTableName}` ADD $indexType(`{$this->fieldName}`)";
789: try{
790: Yii::app()->db->createCommand($sql)->execute();
791: return true;
792: }catch(CDbException $e){
793:
794:
795: return false;
796: }
797: }
798:
799: 800: 801:
802: public function dropColumn(){
803: $sql = "ALTER TABLE `{$this->myTableName}` DROP COLUMN `{$this->fieldName}`";
804: try{
805: Yii::app()->db->createCommand($sql)->execute();
806: return true;
807: }catch(CDbException $e){
808:
809:
810: return false;
811: }
812: }
813:
814: 815: 816:
817: public function dropIndex(){
818: $sql = "ALTER TABLE `{$this->myTableName}` DROP INDEX `{$this->fieldName}`";
819: try{
820: Yii::app()->db->createCommand($sql)->execute();
821: return true;
822: }catch(CDbException $e){
823:
824:
825: return false;
826: }
827: }
828:
829: 830: 831: 832:
833: public function getMyTableName() {
834: if(!isset($this->_myTableName)) {
835: $this->_myTableName = X2Model::model($this->modelName)->tableName();
836: }
837: return $this->_myTableName;
838: }
839:
840: 841: 842: 843:
844: public function nonReserved($attribute,$params = array()) {
845: if($this->isNewRecord){
846: $dataFiles = array();
847: $reservedWords = array();
848: $dataFiles[] = implode(DIRECTORY_SEPARATOR, array(Yii::app()->basePath, 'data', 'mysqlReservedWords.php'));
849: $dataFiles[] = implode(DIRECTORY_SEPARATOR, array(Yii::app()->basePath, 'data', 'modelReservedWords.php'));
850: foreach($dataFiles as $path){
851: if(file_exists($path)){
852: $reservedWords = array_merge($reservedWords, require($path));
853: }
854: }
855: if(in_array($this->$attribute, $reservedWords)){
856: $this->addError($attribute, Yii::t('admin', 'This field is a MySQL or X2Engine reserved word. Choose a different field name.'));
857: }
858: }
859: }
860:
861: 862: 863: 864: 865: 866:
867: public function parseValue($value, $filter = false){
868: if(in_array($this->type, array('int', 'float', 'currency', 'percentage'))){
869: return self::strToNumeric($value, $this->type);
870: }
871: switch($this->type){
872: case 'assignment':
873: return ($this->linkType === 'multiple') ? self::parseUsers($value) : $value;
874:
875: case 'date':
876: case 'dateTime':
877: if(is_numeric ((string) $value))
878: return $value;
879: $value = $this->type === 'dateTime' ? Formatter::parseDateTime($value) : Formatter::parseDate($value);
880: return $value === false ? null : $value;
881:
882: case 'link':
883: if(empty($value) || empty($this->linkType)){
884: return $value;
885: }
886: list($name, $id) = self::nameAndId($value);
887: if(ctype_digit((string) $id)){
888:
889: $linkedModel = X2Model::model($this->linkType)->findByAttributes(array('nameId' => $value));
890:
891:
892: return empty($linkedModel) ? $name : $value;
893: }else if(ctype_digit($value)){
894:
895: $link = Yii::app()->db->createCommand()
896: ->select('nameId')
897: ->from(X2Model::model($this->linkType)->tableName())
898: ->where('id=?', array($value))
899: ->queryScalar();
900: }else{
901:
902: $link = Yii::app()->db->createCommand()
903: ->select('nameId')
904: ->from(X2Model::model($this->linkType)->tableName())
905: ->where('name=?', array($name))
906: ->queryScalar();
907: }
908: return $link === false ? $name : $link;
909: case 'boolean':
910: return (bool) $value;
911: case 'text':
912: return self::getPurifier()->purify($value);
913: case 'dropdown':
914: return is_array($value) ? CJSON::encode($value) : $value;
915: default:
916: return $filter ? CHtml::encode($value) : $value;
917: }
918: }
919:
920: 921: 922:
923: public function relations(){
924: return array();
925: }
926:
927: 928: 929: 930:
931: public function search(){
932:
933:
934:
935: $criteria = new CDbCriteria;
936:
937: $criteria->compare('id', $this->id);
938: $criteria->compare('modelName', $this->modelName, true);
939: $criteria->compare('fieldName', $this->fieldName, true);
940: $criteria->compare('attributeLabel', $this->attributeLabel, true);
941: $criteria->compare('custom', $this->custom);
942: $criteria->compare('modified', $this->modified);
943: $criteria->compare('readOnly', $this->readOnly);
944:
945: return new CActiveDataProvider(get_class($this), array(
946: 'criteria' => $criteria,
947: ));
948: }
949:
950: 951: 952:
953: public function tableName(){
954: return 'x2_fields';
955: }
956:
957: 958: 959: 960:
961: public function requiredUnique($attribute, $params = array()) {
962: if($this->$attribute == 'UNI' && !$this->uniqueConstraint) {
963: $this->addError($attribute,Yii::t('admin','You cannot add a unique constraint unless you also make the field unique and required.'));
964: }
965: }
966:
967: 968: 969: 970: 971: 972: 973:
974: public function uniqueFieldName($attribute, $params = array()) {
975: $fields = self::model()->findAllByAttributes(array($attribute=>$this->$attribute,'modelName'=>$this->modelName));
976: if(count($fields) > 0) {
977:
978: $existingField = reset($fields);
979: if($this->id != $existingField->id) {
980:
981:
982:
983: $this->addError($attribute,Yii::t('admin','A field in the specified data model with that name already exists.'));
984: }
985: }
986: }
987:
988: 989: 990: 991: 992: 993:
994: public function validDefault($attribute,$params = array()) {
995: if($this->fieldName == '')
996: return;
997:
998:
999:
1000:
1001:
1002: $dummyModel = new AmorphousModel();
1003: $dummyField = new Fields;
1004: foreach($this->attributes as $name=>$value) {
1005: $dummyField->$name = $value;
1006: }
1007: $dummyField->fieldName = 'customized_field';
1008: $dummyModel->scenario = 'insert';
1009: $dummyModel->addField($dummyField,'customized_field');
1010: $dummyModel->setAttribute('customized_field',$this->$attribute);
1011: $dummyModel->validate();
1012: if($dummyModel->hasErrors('customized_field')) {
1013: foreach($dummyModel->errors['customized_field'] as $error) {
1014: $this->addError($attribute, str_replace($dummyField->attributeLabel, $dummyField->getAttributeLabel($attribute), $error));
1015: }
1016: }
1017: }
1018:
1019:
1020: 1021: 1022: 1023: 1024: 1025:
1026: public function validCustom($attribute,$params = array()) {
1027: if($this->type == 'custom') {
1028: if($this->linkType == 'formula') {
1029: $this->$attribute = trim($this->$attribute);
1030: if(strpos($this->$attribute,'=')!==0) {
1031: $this->$attribute = '='.$this->$attribute;
1032: }
1033: } else if($this->linkType == 'display') {
1034: $this->$attribute = self::getPurifier()->purify($this->$attribute);
1035: }
1036: }
1037: }
1038:
1039: 1040: 1041: 1042:
1043: private $_dropdown;
1044: public function getDropdown () {
1045: if ($this->type !== 'dropdown') return null;
1046: if (!isset ($this->_dropdown)) {
1047: $this->_dropdown = Dropdowns::model ()->findByPk ($this->linkType);
1048: }
1049: return $this->_dropdown;
1050: }
1051:
1052: public static function getFieldsOfModelsWithFieldLevelPermissions () {
1053: $fields = Fields::model()
1054: ->findAll(array('order' => 'modelName ASC'));
1055: $filtered = array ();
1056: foreach ($fields as $field) {
1057: $modelClass = $field->modelName;
1058: if (class_exists ($modelClass) &&
1059: $modelClass::model ()->supportsFieldLevelPermissions) {
1060:
1061: $filtered[] = $field;
1062: }
1063: }
1064: return $filtered;
1065: }
1066:
1067: }
1068: