1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
17: class Field extends WireData implements Saveable {
18:
19: 20: 21: 22:
23: const flagAutojoin = 1;
24:
25: 26: 27: 28:
29: const flagGlobal = 4;
30:
31: 32: 33: 34:
35: const flagSystem = 8;
36:
37: 38: 39: 40:
41: const flagPermanent = 16;
42:
43: 44: 45: 46:
47: const flagFieldgroupContext = 2048;
48:
49: 50: 51: 52:
53: const flagSystemOverride = 32768;
54:
55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65:
66: protected $settings = array(
67: 'id' => 0,
68: 'type' => null,
69: 'flags' => 0,
70: 'name' => '',
71: 'label' => '',
72: );
73:
74: 75: 76: 77:
78: protected $prevTable;
79:
80: 81: 82: 83:
84: protected $prevFieldtype;
85:
86: 87: 88: 89:
90: static protected $lowercaseTables = null;
91:
92: 93: 94: 95:
96: public function set($key, $value) {
97:
98: if($key == 'name') return $this->setName($value);
99: else if($key == 'type' && $value) return $this->setFieldtype($value);
100: else if($key == 'prevTable') {
101: $this->prevTable = $value;
102: return $this;
103: } else if($key == 'prevFieldtype') {
104: $this->prevFieldtype = $value;
105: return $this;
106: } else if($key == 'flags') {
107: $this->setFlags($value);
108: return $this;
109: } else if($key == 'id') {
110: $value = (int) $value;
111: }
112:
113: if(isset($this->settings[$key])) $this->settings[$key] = $value;
114: else return parent::set($key, $value);
115:
116: return $this;
117: }
118:
119: 120: 121: 122:
123: protected function setFlags($value) {
124:
125: $value = (int) $value;
126: $override = $this->settings['flags'] & Field::flagSystemOverride;
127: if(!$override) {
128: if($this->settings['flags'] & Field::flagSystem) $value = $value | Field::flagSystem;
129: if($this->settings['flags'] & Field::flagPermanent) $value = $value | Field::flagPermanent;
130: }
131: $this->settings['flags'] = $value;
132: }
133:
134: 135: 136: 137:
138: public function get($key) {
139: if($key == 'table') return $this->getTable();
140: else if($key == 'prevTable') return $this->prevTable;
141: else if($key == 'prevFieldtype') return $this->prevFieldtype;
142: else if(isset($this->settings[$key])) return $this->settings[$key];
143: return parent::get($key);
144: }
145:
146: 147: 148: 149: 150: 151:
152: public function getTableData() {
153: $a = $this->settings;
154: $a['data'] = $this->data;
155: return $a;
156: }
157:
158: 159: 160: 161: 162: 163: 164:
165: public function setName($name) {
166: $name = $this->fuel('sanitizer')->fieldName($name);
167:
168: if(Fields::isNativeName($name))
169: throw new WireException("Field may not be named '$name' because it is a reserved word");
170:
171: if($this->fuel('fields') && ($f = $this->fuel('fields')->get($name)) && $f->id != $this->id)
172: throw new WireException("Field may not be named '$name' because it is already used by another field");
173:
174: if(strpos($name, '__') !== false)
175: throw new WireException("Field name '$name' may not have double underscores because this usage is reserved by the core");
176:
177: if($this->settings['name'] != $name) {
178: if($this->settings['name'] && ($this->settings['flags'] & Field::flagSystem)) {
179: throw new WireException("You may not change the name of field '{$this->settings['name']}' because it is a system field.");
180: }
181: $this->trackChange('name');
182: if($this->settings['name']) $this->prevTable = $this->getTable();
183: }
184:
185: $this->settings['name'] = $name;
186: return $this;
187: }
188:
189: 190: 191: 192: 193: 194: 195: 196: 197:
198: public function setFieldtype($type) {
199:
200: if(is_object($type) && $type instanceof Fieldtype) {
201:
202:
203: } else if(is_string($type)) {
204: $typeStr = $type;
205: $fieldtypes = $this->fuel('fieldtypes');
206: if(!$type = $fieldtypes->get($type)) {
207: $this->error("Fieldtype '$typeStr' does not exist");
208: return $this;
209: }
210: } else {
211: throw new WireException("Invalid field type in call to Field::setFieldType");
212: }
213:
214: if(!$this->type || ($this->type->name != $type->name)) {
215: $this->trackChange("type:{$type->name}");
216: if($this->type) $this->prevFieldtype = $this->type;
217: }
218: $this->settings['type'] = $type;
219:
220: return $this;
221: }
222:
223: 224: 225: 226: 227: 228:
229: public function save() {
230: $fields = $this->getFuel('fields');
231: return $fields->save($this);
232: }
233:
234:
235: 236: 237: 238: 239: 240:
241: public function numFieldgroups() {
242: return count($this->getFieldgroups());
243: }
244:
245: 246: 247: 248: 249: 250:
251: public function getFieldgroups() {
252: $fieldgroups = new FieldgroupsArray();
253: foreach($this->fuel('fieldgroups') as $fieldgroup) {
254: foreach($fieldgroup as $field) {
255: if($field->id == $this->id) {
256: $fieldgroups->add($fieldgroup);
257: break;
258: }
259: }
260: }
261: return $fieldgroups;
262: }
263:
264: 265: 266: 267: 268: 269:
270: public function getTemplates() {
271: $templates = new TemplatesArray();
272: $fieldgroups = $this->getFieldgroups();
273: foreach($this->templates as $template) {
274: foreach($fieldgroups as $fieldgroup) {
275: if($template->fieldgroups_id == $fieldgroup->id) {
276: $templates->add($template);
277: break;
278: }
279: }
280: }
281: return $templates;
282: }
283:
284:
285: 286: 287: 288:
289: public function getDefaultValue() {
290: $value = $this->get('default');
291: if($value) return $value;
292: return null;
293:
294: }
295:
296: 297: 298: 299: 300: 301: 302: 303:
304: public function ___getInputfield(Page $page, $contextStr = '') {
305:
306: if(!$this->type) return null;
307: $inputfield = $this->type->getInputfield($page, $this);
308: if(!$inputfield) return null;
309:
310:
311: $inputfield->attr('name', $this->name . $contextStr);
312: $inputfield->label = $this->label;
313:
314:
315: foreach($this->data as $key => $value) {
316: if($inputfield->has($key)) {
317: $inputfield->set($key, $value);
318: }
319: }
320:
321: return $inputfield;
322: }
323:
324: 325: 326: 327: 328: 329:
330: public function ___getConfigInputfields() {
331:
332: $wrapper = new InputfieldWrapper();
333: $fieldgroupContext = $this->flags & Field::flagFieldgroupContext;
334:
335: if(!$fieldgroupContext) {
336: $inputfields = new InputfieldWrapper;
337: $inputfields->head = "Field type details";
338: $inputfields->attr('title', 'Details');
339:
340: $fieldtypeInputfields = $this->type->getConfigInputfields($this);
341: if($fieldtypeInputfields) foreach($fieldtypeInputfields as $inputfield) {
342: $inputfields->append($inputfield);
343: }
344:
345: if(count($inputfields)) $wrapper->append($inputfields);
346: } else {
347:
348:
349: }
350:
351: $inputfields = new InputfieldWrapper();
352: $dummyPage = $this->fuel('pages')->get("/");
353:
354: if($inputfield = $this->getInputfield($dummyPage)) {
355: $inputfieldLabel = $inputfield->className();
356: if(!$fieldgroupContext) $inputfields->head = "Input field settings";
357: $inputfields->attr('title', 'Input');
358: $inputfieldInputfields = $inputfield->getConfigInputfields();
359: if($inputfieldInputfields) foreach($inputfieldInputfields as $i) {
360:
361:
362: if($fieldgroupContext && !in_array($i->name, array('collapsed', 'columnWidth'))) continue;
363: $inputfields->append($i);
364: }
365: }
366:
367: $wrapper->append($inputfields);
368:
369: return $wrapper;
370: }
371:
372:
373: public function getTable() {
374: if(is_null(self::$lowercaseTables)) self::$lowercaseTables = $this->config->dbLowercaseTables ? true : false;
375: $name = $this->settings['name'];
376: if(self::$lowercaseTables) $name = strtolower($name);
377: return "field_" . $name;
378: }
379:
380: 381: 382: 383:
384: public function __toString() {
385: return $this->settings['name'];
386: }
387:
388: public function __isset($key) {
389: if(parent::__isset($key)) return true;
390: return isset($this->settings[$key]);
391: }
392:
393:
394: }
395:
396: