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: class RecordSelector {
48: 49: 50: 51: 52: 53:
54: private $relationObject = null;
55:
56: 57: 58: 59: 60: 61:
62: private $label;
63:
64: 65: 66: 67: 68: 69: 70:
71: private $accessingClassName;
72:
73: 74: 75: 76: 77: 78:
79: private $onloadJS = '';
80:
81: 82: 83: 84: 85: 86:
87: private $name;
88:
89: 90: 91: 92: 93: 94:
95: private static $logger = null;
96:
97: 98: 99: 100: 101: 102: 103: 104: 105: 106:
107: public function __construct($relation, $label='', $name='', $accessingClassName='') {
108: self::$logger = new Logger('RecordSelector');
109: self::$logger->debug('>>__construct(relation=['.$relation.'], label=['.$label.'], name=['.$name.'], accessingClassName=['.$accessingClassName.'])');
110:
111: if(!$relation instanceof Relation)
112: throw new IllegalArguementException('Invalid Relation object provided to the RecordSelector constructor!');
113:
114: $this->relationObject = $relation;
115: $this->label = $label;
116: $this->name = $name;
117: $this->accessingClassName = $accessingClassName;
118:
119: self::$logger->debug('<<__construct');
120: }
121:
122: 123: 124: 125: 126: 127: 128: 129: 130:
131: public function render($expanded=false, $buttons=true) {
132: self::$logger->debug('>>render(expanded=['.$expanded.'], buttons=['.$buttons.'])');
133:
134: global $config;
135:
136: $fieldname = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(AlphaSecurityUtils::encrypt($this->name)) : $this->name);
137:
138: $html = '';
139:
140:
141: if($this->relationObject->getRelationType() == 'MANY-TO-ONE') {
142:
143: $inputBoxValue = $this->relationObject->getRelatedClassDisplayFieldValue();
144:
145: $html .= '<div class="form-group">';
146: $html .= '<label for="'.$this->name.'_display">'.$this->label.'</label>';
147:
148: $html .= '<input type="text" size="70" class="form-control" name="'.$this->name.'_display" id="'.$this->name.'_display" value="'.$inputBoxValue.'" disabled/>';
149:
150: $js = " if(window.jQuery) {
151: window.jQuery.dialog = new BootstrapDialog({
152: title: 'Please select',
153: message: 'Loading...',
154: onshow: function(dialogRef){
155: dialogRef.getModalBody().load('".$config->get('app.url')."ViewRecordSelector/value/'+document.getElementById('".$fieldname."').value+'/field/".$this->name."/relatedClass/".$this->relationObject->getRelatedClass()."/relatedClassField/".$this->relationObject->getRelatedClassField()."/relatedClassDisplayField/".$this->relationObject->getRelatedClassDisplayField()."/relationType/".$this->relationObject->getRelationType()."');
156: },
157: buttons: [
158: {
159: icon: 'glyphicon glyphicon-remove',
160: label: 'Cancel',
161: cssClass: 'btn btn-default btn-xs',
162: action: function(dialogItself){
163: dialogItself.close();
164: }
165: }
166: ]
167: });
168: window.jQuery.dialog.open();
169: }";
170:
171:
172: $tmp = new Button($js, "Select", "relBut", '', 'glyphicon-check');
173: $html .= '<div class="centered lower">'.$tmp->render().'</div>';
174:
175:
176: $html .= '<input type="hidden" name="'.$fieldname.'" id="'.$fieldname.'" value="'.$this->relationObject->getValue().'"/>';
177:
178: if($this->relationObject->getRule() != '') {
179: $html .= '<input type="hidden" id="'.$fieldname.'_msg" value="'.$this->relationObject->getHelper().'"/>';
180: $html .= '<input type="hidden" id="'.$fieldname.'_rule" value="'.$this->relationObject->getRule().'"/>';
181: }
182:
183: $html .= '</div>';
184: }
185:
186:
187: if($this->relationObject->getRelationType() == 'ONE-TO-MANY') {
188: $objects = $this->relationObject->getRelatedObjects();
189:
190: if(count($objects) > 0) {
191:
192: if($this->name == 'tags' && $this->relationObject->getRelatedClass() == 'TagObject') {
193: $html .= '<tr><th>'.$this->label.'</th><td>';
194:
195: foreach($objects as $tag) {
196: $html .= ' <a href="'.$config->get('app.url').'search/q/'.$tag->get('content').'">'.$tag->get('content').'</a>';
197: }
198:
199: $html .= '</td></tr>';
200: }else{
201: $html .= '<div><strong>'.$this->label.':</strong>';
202: if($buttons) {
203: $html .= '<div class="spread">';
204: $tmp = new Button("document.getElementById('relation_field_".$this->name."').style.display = '';", "Show", $this->name."DisBut", '', 'glyphicon-list');
205: $html .= $tmp->render();
206: $tmp = new Button("document.getElementById('relation_field_".$this->name."').style.display = 'none';", "Hide", $this->name."HidBut", '', 'glyphicon-minus');
207: $html .= $tmp->render();
208: $html .= '</div>';
209: }
210: $html .= '</div>';
211:
212: $html .= '<div id="relation_field_'.$this->name.'" style="display:'.($expanded ? '' : 'none').';">';
213:
214: $customViewControllerName = AlphaController::getCustomControllerName(get_class($objects[0]), 'view');
215: $customEditControllerName = AlphaController::getCustomControllerName(get_class($objects[0]), 'edit');
216:
217: foreach($objects as $obj) {
218:
219:
220: if(mb_strpos($_SERVER['REQUEST_URI'], '/tk/') !== false) {
221: $viewURL = FrontController::generateSecureURL('act=Detail&bo='.get_class($obj).'&oid='.$obj->getOID());
222: $editURL = FrontController::generateSecureURL('act=Edit&bo='.get_class($obj).'&oid='.$obj->getOID());
223: }else{
224: if(isset($customViewControllerName)) {
225: if($config->get('app.use.mod.rewrite'))
226: $viewURL = $config->get('app.url').$customViewControllerName.'/oid/'.$obj->getOID();
227: else
228: $viewURL = $config->get('app.url').'controller/'.$customViewControllerName.'.php?oid='.$obj->getOID();
229: }else{
230: $viewURL = $config->get('app.url').'alpha/controller/Detail.php?bo='.get_class($obj).'&oid='.$obj->getOID();
231: }
232: if(isset($customEditControllerName)) {
233: if($config->get('app.use.mod.rewrite'))
234: $editURL = $config->get('app.url').$customEditControllerName.'/oid/'.$obj->getOID();
235: else
236: $editURL = $config->get('app.url').'controller/'.$customEditControllerName.'.php?oid='.$obj->getOID();
237: }else{
238: $editURL = $config->get('app.url').'alpha/controller/Edit.php?bo='.get_class($obj).'&oid='.$obj->getOID();
239: }
240: }
241:
242: 243: 244: 245:
246: $headerFields = $this->relationObject->getRelatedClassHeaderFields();
247: if(count($headerFields) > 0) {
248: foreach($headerFields as $field) {
249: $label = $obj->getDataLabel($field);
250: $value = $obj->get($field);
251:
252: if($field == 'created_by' || $field == 'updated_by') {
253: $person = new PersonObject();
254: $person->load($value);
255: $value = $person->getDisplayName();
256: }
257:
258: $html .= '<em>'.$label.': </em>'.$value.' ';
259: }
260:
261: if($obj->getCreateTS() != $obj->getUpdateTS()) {
262: try {
263: $html .= '<em>'.$obj->getDataLabel('updated_ts').': </em>'.$obj->get('updated_ts');
264: }catch(IllegalArguementException $e) {
265: $html .= '<em>Updated: </em>'.$obj->get('updated_ts');
266: }
267: }
268: }else{
269: $html .= '<em>'.$obj->getDataLabel('OID').': </em>'.$obj->get('OID');
270: }
271:
272: $value = str_replace("\n", '<br>', $obj->get($this->relationObject->getRelatedClassDisplayField()));
273: $html .= '<p>'.$value.'</p>';
274:
275: $html .= '<div class="centered">';
276: $html .= '<a href="'.$viewURL.'">View</a>';
277:
278: if(isset($_SESSION['currentUser']) && $_SESSION['currentUser']->getOID() == $obj->getCreatorId())
279: $html .= ' <a href="'.$editURL.'">Edit</a>';
280: $html .= '</div>';
281: }
282: $html .= '</div>';
283: }
284: }
285: }
286:
287:
288: if($this->relationObject->getRelationType() == 'MANY-TO-MANY') {
289:
290: $inputBoxValue = $this->relationObject->getRelatedClassDisplayFieldValue($this->accessingClassName);
291:
292: $inputBoxValue = str_replace(",", "\n", $inputBoxValue);
293:
294: $html .= '<div class="form-group">';
295: $html .= '<label for="'.$this->name.'_display">'.$this->label.'</label>';
296:
297: $html .= '<textarea id="'.$this->name.'_display" class="form-control" rows="5" readonly>';
298: $html .= $inputBoxValue;
299: $html .= '</textarea>';
300:
301: $fieldname1 = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(AlphaSecurityUtils::encrypt($this->name)) : $this->name);
302: $fieldname2 = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(AlphaSecurityUtils::encrypt($this->name.'_OID')) : $this->name.'_OID');
303:
304:
305: $js = "if(window.jQuery) {
306: BootstrapDialog.show({
307: title: 'Please select',
308: message: 'Loading...',
309: onshow: function(dialogRef){
310: dialogRef.getModalBody().load('".$config->get('app.url')."ViewRecordSelector/lookupOIDs/'+document.getElementById('".$fieldname1."').value+'/value/'+document.getElementById('".$fieldname2."').value+'/field/".$this->name."/relatedClassLeft/".$this->relationObject->getRelatedClass('left')."/relatedClassLeftDisplayField/".$this->relationObject->getRelatedClassDisplayField('left')."/relatedClassRight/".$this->relationObject->getRelatedClass('right')."/relatedClassRightDisplayField/".$this->relationObject->getRelatedClassDisplayField('right')."/accessingClassName/".$this->accessingClassName."/relationType/".$this->relationObject->getRelationType()."');
311: },
312: buttons: [
313: {
314: icon: 'glyphicon glyphicon-remove',
315: label: 'Cancel',
316: cssClass: 'btn btn-default btn-xs',
317: action: function(dialogItself){
318: dialogItself.close();
319: }
320: },
321: {
322: icon: 'glyphicon glyphicon-ok',
323: label: 'Okay',
324: cssClass: 'btn btn-default btn-xs',
325: action: function(dialogItself) {
326: setParentFieldValues();
327: $('[id=\'".$this->name."_display\']').blur();
328: dialogItself.close();
329: }
330: }
331: ]
332: });
333: }";
334:
335: $tmp = new Button($js, "Select", "relBut", '', 'glyphicon-check');
336: $html .= '<div class="centered lower">'.$tmp->render().'</div>';
337:
338: $html .= '</div>';
339:
340:
341: $html .= '<input type="hidden" name="'.$fieldname2.'" id="'.$fieldname2.'" value="'.$this->relationObject->getValue().'"/>';
342:
343:
344: if($this->relationObject->getSide($this->accessingClassName) == 'left')
345: $lookupOIDs = $this->relationObject->getLookup()->loadAllFieldValuesByAttribute('leftID', $this->relationObject->getValue(), 'rightID', 'DESC');
346: else
347: $lookupOIDs = $this->relationObject->getLookup()->loadAllFieldValuesByAttribute('rightID', $this->relationObject->getValue(), 'leftID', 'DESC');
348:
349: $html .= '<input type="hidden" name="'.$fieldname1.'" id="'.$fieldname1.'" value="'.implode(',', $lookupOIDs).'"/>';
350: }
351:
352: self::$logger->debug('<<__render [html]');
353: return $html;
354: }
355:
356: 357: 358: 359: 360: 361: 362:
363: public function renderSelector($lookupOIDs=array()) {
364: self::$logger->debug('>>renderSelector(lookupOIDs=['.var_export($lookupOIDs, true).'])');
365:
366: global $config;
367:
368: $fieldname = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(AlphaSecurityUtils::encrypt($_GET['field'])) : $_GET['field']);
369:
370:
371: $html = '<script language="JavaScript">
372: var selectedOIDs = new Object();
373:
374: function toggelOID(oid, displayValue, isSelected) {
375: if(isSelected)
376: selectedOIDs[oid] = displayValue;
377: else
378: delete selectedOIDs[oid];
379: }
380:
381: function setParentFieldValues() {
382: var OIDs;
383: var displayValues;
384:
385: for(key in selectedOIDs) {
386: if(OIDs == null)
387: OIDs = key;
388: else
389: OIDs = OIDs + \',\' + key;
390:
391: if(displayValues == null)
392: displayValues = selectedOIDs[key];
393: else
394: displayValues = displayValues + \'\\n\' + selectedOIDs[key];
395: }
396:
397: if(OIDs == null) {
398: document.getElementById(\''.$fieldname.'\').value = "00000000000";
399: document.getElementById(\''.$_GET['field'].'_display\').value = "";
400: }else{
401: document.getElementById(\''.$fieldname.'\').value = OIDs;
402: document.getElementById(\''.$_GET['field'].'_display\').value = displayValues;
403: }
404: }
405:
406: </script>';
407:
408:
409: if($this->relationObject->getRelationType() == 'MANY-TO-MANY') {
410:
411: $classNameLeft = $this->relationObject->getRelatedClass('left');
412: $classNameRight = $this->relationObject->getRelatedClass('right');
413:
414: if($this->accessingClassName == $classNameLeft) {
415: AlphaDAO::loadClassDef($classNameRight);
416: $tmpObject = new $classNameRight;
417: $fieldName = $this->relationObject->getRelatedClassDisplayField('right');
418: $fieldLabel = $tmpObject->getDataLabel($fieldName);
419: $oidLabel = $tmpObject->getDataLabel('OID');
420:
421: $objects = $tmpObject->loadAll(0, 0, 'OID', 'ASC', true);
422:
423: self::$logger->debug('['.count($objects).'] related ['.$classNameLeft.'] objects loaded');
424: }else{
425: AlphaDAO::loadClassDef($classNameLeft);
426: $tmpObject = new $classNameLeft;
427: $fieldName = $this->relationObject->getRelatedClassDisplayField('left');
428: $fieldLabel = $tmpObject->getDataLabel($fieldName);
429: $oidLabel = $tmpObject->getDataLabel('OID');
430:
431: $objects = $tmpObject->loadAll(0, 0, 'OID', 'ASC', true);
432:
433: self::$logger->debug('['.count($objects).'] related ['.$classNameLeft.'] objects loaded');
434: }
435:
436: $html .= '<table cols="3" class="table table-bordered">';
437: $html .= '<tr>';
438: $html .= '<th>'.$oidLabel.'</th>';
439: $html .= '<th>'.$fieldLabel.'</th>';
440: $html .= '<th>Connect?</th>';
441: $html .= '</tr>';
442:
443: foreach($objects as $obj){
444: $html .= '<tr>';
445: $html .= '<td width="20%">';
446: $html .= $obj->getOID();
447: $html .= '</td>';
448: $html .= '<td width="60%">';
449: $html .= $obj->get($fieldName);
450: $html .= '</td>';
451: $html .= '<td width="20%">';
452:
453: if(in_array($obj->getOID(), $lookupOIDs)) {
454: $this->onloadJS .= 'toggelOID(\''.$obj->getOID().'\',\''.$obj->get($fieldName).'\',true);';
455: $html .= '<input name = "'.$obj->getOID().'" type="checkbox" checked onclick="toggelOID(\''.$obj->getOID().'\',\''.$obj->get($fieldName).'\',this.checked);"/>';
456: }else{
457: $html .= '<input name = "'.$obj->getOID().'" type="checkbox" onclick="toggelOID(\''.$obj->getOID().'\',\''.$obj->get($fieldName).'\',this.checked);"/>';
458: }
459: $html .= '</td>';
460: $html .= '</tr>';
461: }
462: $html .= '</table>';
463:
464: }else{
465: $className = $this->relationObject->getRelatedClass();
466:
467: AlphaDAO::loadClassDef($className);
468:
469: $tmpObject = new $className;
470: $label = $tmpObject->getDataLabel($this->relationObject->getRelatedClassDisplayField());
471: $oidLabel = $tmpObject->getDataLabel('OID');
472:
473: $objects = $tmpObject->loadAll(0, 0, 'OID', 'DESC');
474:
475: $html = '<table cols="3" width="100%" class="bordered">';
476: $html .= '<tr>';
477: $html .= '<th>'.$oidLabel.'</th>';
478: $html .= '<th>'.$label.'</th>';
479: $html .= '<th>Connect?</th>';
480: $html .= '</tr>';
481:
482: foreach($objects as $obj){
483: $html .= '<tr>';
484: $html .= '<td width="20%">';
485: $html .= $obj->getOID();
486: $html .= '</td>';
487: $html .= '<td width="60%">';
488: $html .= $obj->get($this->relationObject->getRelatedClassDisplayField());
489: $html .= '</td>';
490: $html .= '<td width="20%">';
491: if($obj->getOID() == $this->relationObject->getValue()) {
492: $html .= '<img src="'.$config->get('app.url').'/alpha/images/icons/accept_ghost.png"/>';
493: }else{
494: $tmp = new Button("document.getElementById('".$fieldname."').value = '".$obj->getOID()."'; document.getElementById('".$_GET['field']."_display').value = '".$obj->get($this->relationObject->getRelatedClassDisplayField())."'; $('[Id=".$_GET['field']."_display]').blur(); window.jQuery.dialog.close();", "", "selBut", $config->get('app.url')."/alpha/images/icons/accept.png");
495: $html .= $tmp->render();
496: }
497: $html .= '</td>';
498: $html .= '</tr>';
499: }
500: $html .= '</table>';
501: }
502:
503: $html .= '<script type="text/javascript">'.
504: '$(document).ready(function() {';
505:
506: $html .= $this->onloadJS;
507:
508: $html .= '});</script>';
509:
510: self::$logger->debug('<<renderSelector[html]');
511: return $html;
512: }
513: }
514:
515: ?>