Overview

Packages

  • Components
  • Internals
    • AR
  • RestApi
    • Objects
    • Services

Classes

  • CBHttpRequest
  • CBJson
  • CBJsonController
  • CBJsonInlineAction
  • CBJsonModel
  • Overview
  • Package
  • Class
  • Tree
  • Todo
  1: <?php
  2: /**
  3:  * Base class for JSON models.
  4:  *
  5:  * @since 1.0
  6:  * @package Components
  7:  * @author Konstantinos Filios <konfilios@gmail.com>
  8:  */
  9: class CBJsonModel extends CFormModel
 10: {
 11:     /**
 12:      * Throw exception if validation fails.
 13:      *
 14:      * @param array $attributes
 15:      * @param boolean $clearErrors
 16:      * @return boolean
 17:      * @throws CException
 18:      */
 19:     public function validate($attributes = null, $clearErrors = true)
 20:     {
 21:         if (parent::validate($attributes, $clearErrors)) {
 22:             return true;
 23:         }
 24: 
 25:         $allErrors = array();
 26:         foreach ($this->getErrors() as $attrName=>$attrErrors) {
 27:             $allErrors = array_merge($allErrors, $attrErrors);
 28:         }
 29: 
 30:         throw new CException(implode("\n", $allErrors));
 31:     }
 32: 
 33:     /**
 34:      * Types of non-scalar members.
 35:      *
 36:      * @return string[]
 37:      */
 38:     public function getAttributeTypes()
 39:     {
 40:         return array();
 41:     }
 42: 
 43:     /**
 44:      * Initialize from source object/array.
 45:      *
 46:      * @param array|object $source
 47:      * @return CBJsonModel
 48:      */
 49:     public function copyFrom($source)
 50:     {
 51:         if (is_array($source)) {
 52:             $isSourceArray = true;
 53:         } else if (is_object($source)) {
 54:             $isSourceArray = false;
 55:         } else {
 56:             throw new CException(get_class($this).' cannot be initialized from a '
 57:                     .gettype($source).'. An array or object is required');
 58:         }
 59: 
 60:         // Our attribute types
 61:         $attrTypes = $this->getAttributeTypes();
 62: 
 63:         foreach($this->attributeNames() as $attrName) {
 64:             // Loop through our attributes
 65: 
 66:             if ($isSourceArray) {
 67:                 // Array key
 68:                 $attrValue = isset($source[$attrName]) ? $source[$attrName] : null;
 69:             } else {
 70:                 // Object property
 71:                 $attrValue = isset($source->$attrName) ? $source->$attrName : null;
 72:             }
 73: 
 74:             if ($attrValue === null) {
 75:                 // Attribute not in source
 76:                 continue;
 77:             }
 78: 
 79:             if (!isset($attrTypes[$attrName])) {
 80:                 // Scalar type
 81:                 $this->$attrName = $attrValue;
 82:             } else {
 83:                 // Object or array of objects
 84:                 $attrType = $attrTypes[$attrName];
 85: 
 86:                 if (substr($attrType, -2) === '[]') {
 87:                     // Array of objects
 88: 
 89:                     // Remove "[]"
 90:                     $attrType = substr($attrType, 0, -2);
 91: 
 92:                     if (!is_array($attrValue)) {
 93:                         // Make sure value is an array of objects
 94:                         throw new CException('Attribute '.$attrName.' of '.get_class($this)
 95:                                 .' must be an array of '.$attrType.' instances');
 96:                     }
 97: 
 98:                     $arrayJsonModels = array();
 99:                     foreach ($attrValue as $fromJsonAttributeElement) {
100:                         // Loop through array of objects and create corresponding json models
101:                         $elementJsonModel = new $attrType();
102: 
103:                         // Recurse into sub-object
104:                         $elementJsonModel->copyFrom($fromJsonAttributeElement);
105: 
106:                         $arrayJsonModels[] = $elementJsonModel;
107:                     }
108:                     $this->$attrName = $arrayJsonModels;
109: 
110:                 } else {
111:                     // Object
112:                     $elementJsonModel = new $attrType();
113: 
114:                     // Recurse into sub-object
115:                     $this->$attrName = $elementJsonModel->copyFrom($attrValue);
116:                 }
117:             }
118:         }
119: 
120:         return $this;
121:     }
122: 
123:     /**
124:      * Model attributes as array.
125:      *
126:      * @return mixed
127:      */
128:     public function toArray()
129:     {
130:         return $this->getAttributes();
131:     }
132: 
133:     /**
134:      * Clones a source into a json model.
135:      *
136:      * @param array|object $source Source to clone attributes from.
137:      * @return CBJsonModel Cloned CBJsonModel subtype.
138:      */
139:     static public function createFromOne($source)
140:     {
141:         if ($source === null) {
142:             return null;
143:         }
144: 
145:         // Instantiate new subtype of CBJsonModel using Late Static Binding.
146:         $jsonModelClassName = get_called_class();
147:         $jsonModel = new $jsonModelClassName();
148:         /* @var $jsonModel CBJsonModel */
149: 
150:         // Copy attributes (include fromModel's dynamic properties)
151:         return $jsonModel->copyFrom($source);
152:     }
153: 
154:     /**
155:      * Clones an array of sources into an array of json models.
156:      *
157:      * Original model array keys are preserved in final array.
158:      *
159:      * @param array $sources Sources to clone attributes from.
160:      * @return CBJsonModel[] Cloned CBJsonModel subtypes.
161:      */
162:     static public function createFromMany(array $sources)
163:     {
164:         // Get new subtype of CBJsonModel using Late Static Binding.
165:         $jsonModelClassName = get_called_class();
166: 
167:         $jsonModels = array();
168:         foreach ($sources as $key=>$fromModel) {
169:             /* @var $fromModel CModel */
170: 
171:             $jsonModel = new $jsonModelClassName();
172:             /* @var $jsonModel CBJsonModel */
173: 
174:             // Copy attributes (include fromModel's dynamic properties)and add to final array
175:             $jsonModels[$key] = $jsonModel->copyFrom($fromModel);
176:         }
177: 
178:         return $jsonModels;
179:     }
180: 
181:     /**
182:      * Resolve an object to its proper JSON representation.
183:      *
184:      * @param mixed $inputObject
185:      * @param boolean $doSuppressNulls If true, null properties are suppressed from result.
186:      *
187:      * @return mixed
188:      */
189:     static public function resolveObjectRecursively($inputObject, $doSuppressNulls = false)
190:     {
191:         if (is_array($inputObject)) {
192:             //
193:             // Input object is an array, resolve its items
194:             //
195:             $objectArray = array();
196:             foreach ($inputObject as $key=>$responseObjectItem) {
197:                 $objectArray[$key] = self::resolveObjectRecursively($responseObjectItem, $doSuppressNulls);
198:             }
199:             return $objectArray;
200: 
201:         } else if (is_object($inputObject)) {
202:             //
203:             // Input object is a class instance, handle specially
204:             //
205:             if (is_a($inputObject, 'CBJsonModel')) {
206:                 //
207:                 // CBJsonModel subtype, handle attributes specially
208:                 //
209:                 $attributes = array();
210:                 foreach ($inputObject->toArray() as $attrName=>$attrValue) {
211:                     if (is_array($attrValue) || is_object($attrValue)) {
212:                         // Recurse
213:                         $attributes[$attrName] = self::resolveObjectRecursively($attrValue, $doSuppressNulls);
214: 
215:                     } else if (!$doSuppressNulls || $attrValue !== null) {
216:                         // Check suppression
217:                         $attributes[$attrName] = $attrValue;
218:                     }
219:                 }
220:                 return $attributes;
221: 
222:             } else {
223:                 //
224:                 // Unknown object type, let json-encoder do its thing
225:                 //
226:                 return $inputObject;
227:             }
228:         } else {
229:             //
230:             // Input object is a scalar
231:             //
232:             return $inputObject;
233:         }
234:     }
235: }
Bogo Yii Json Service API documentation generated by ApiGen 2.8.0