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