/[cvs]/nfo/php/libs/org.netfrag.patches/phphtmllib/widgets/TopicMapper.php
ViewVC logotype

Contents of /nfo/php/libs/org.netfrag.patches/phphtmllib/widgets/TopicMapper.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations)
Fri Jun 6 04:19:44 2003 UTC (21 years, 2 months ago) by joko
Branch: MAIN
CVS Tags: HEAD
initial commit

1 <?
2 /**
3 * $Id: InfoBox.php,v 1.1 2003/05/13 16:22:22 joko Exp $
4 *
5 * $Log: InfoBox.php,v $
6 *
7 */
8
9
10 class TopicMapper extends StandardFormContent {
11
12 /**
13 * holds reference to source object.
14 */
15 var $_datasource = NULL;
16
17 /**
18 * container for arguments needed for e.g. setting the source object.
19 */
20 var $_options = array();
21
22 var $_confirm_msg = "Die Daten wurden erfolgreich gespeichert!";
23
24 function TopicMapper($title, $model = array(), $blocks = array()) {
25 $this->_model = $model;
26 $this->_blocks = $blocks;
27
28 // new as of 2003-05-29
29 $this->RULESET = new RuleSet("TopicMapper");
30
31 //print "YAI!<br/>";
32
33 // prefetch data
34 //$this->data_prefetch();
35
36 // doesn't work if EditDataItem gets inherited
37 //$parent = get_parent_class($this);
38 //$this->$parent($title, $PHP_SELF, 600);
39
40 // Create FEListBox objects from elements inside $this->_model.
41 // new FEListBox( $key, TRUE, "250px", $cnt*15 . "pt", $list )
42 $this->_parts = array();
43 //print "count: " . count($this->_model) . "<br/>";
44 for ($i = 0; $i < count($this->_model); $i++) {
45 $this->_model[$i][data] = array_flip($this->_model[$i][data]);
46 $entry = $this->_model[$i];
47 $key = $entry[key];
48 array_push($this->_parts, $key);
49 $this->_area[$key] = new FEMultiListBox($key, FALSE, "200px", "250px");
50 //$this->_listbox = new FEMultiListBox($this->_options[key], FALSE, NULL, NULL, array( abc => "def" ) );
51 }
52
53 $this->StandardFormContent($title, $PHP_SELF, 600);
54
55 //$this->form_init_elements();
56
57 }
58
59 function normalize() {
60 // calculate changes to the right block - diff the "BUCKET"
61 // this uses two resources:
62 // a) the RuleSet
63 // b) the Bucket
64
65 // extract values from ruleset
66 $keys = array();
67 //$ruleset = new RuleSet("TopicMapper");
68 //$resolved = $ruleset->resolve('rightone');
69 $resolved = $this->RULESET->resolve_normalized('rightone');
70 print "unique: " . Dumper($resolved);
71 // diff against BUCKET | _model
72 $diff_plus = $this->BUCKET->diff($resolved[APPEND]);
73 $diff_minus = $this->BUCKET->intersect($resolved[REMOVE]);
74 }
75
76 function inject_data($data) {
77 $this->_data2rules($data);
78 }
79
80 // TODO: Init two boxes ( left & right ) here!
81 function form_init_elements() {
82
83 //print Dumper($_REQUEST);
84 //print Dumper($_POST);
85
86 $this->_action2rules();
87
88 /*
89 $this->_post2session();
90 $this->_init_session();
91 $this->_normalize_parts();
92 $this->apply_operation();
93 $this->data2widget();
94 */
95
96 $this->_rules2widget();
97
98 //$this->data2widget();
99
100 /*
101 $elem = $this->_listbox;
102 $this->add_element($elem);
103
104 $clipboard = new FEMultiListBox("clip", FALSE, NULL, "250px");
105 $this->add_element($clipboard);
106 */
107 foreach ($this->_parts as $key) {
108 //print Dumper($this->_area[$key]);
109 $this->add_element($this->_area[$key]);
110 }
111 }
112
113 function _data2rules($payload) {
114 foreach ($payload as $entry) {
115 $slot = $entry[key];
116 $data = $entry[data];
117 foreach ($data as $key => $value) {
118 //print "key: $key<br/>";
119 if ($value) {
120 $this->RULESET->add('APPEND', $slot, $key, $value, 'static');
121 }
122 }
123 }
124 }
125
126 function _action2rules() {
127
128 // check action "add"
129 if ($_REQUEST[ga] == 'add') {
130 //print Dumper($_REQUEST);
131 $values = $_REQUEST[payload];
132 //array_push($_SESSION[DataManager][op][$slot], $value);
133 foreach ($values as $slot => $value) {
134 if ($value) {
135 $this->RULESET->add('APPEND', $slot, $value, $value);
136 }
137 }
138 }
139
140 // check action "moveback"
141 // V1 - tied to add-logic
142 //$slots = array_keys($_REQUEST[values]);
143 // V2 - now independent
144 $slots = split(',', $_REQUEST[keys]);
145 if ($_REQUEST[move]) {
146 $value = $_REQUEST[$slots[0]];
147 $this->RULESET->add('APPEND', $slots[1], $value);
148 $this->RULESET->add('REMOVE', $slots[0], $value);
149 } elseif ($_REQUEST[moveback]) {
150 $value = $_REQUEST[$slots[1]];
151 $this->RULESET->add('APPEND', $slots[0], $value);
152 $this->RULESET->add('REMOVE', $slots[1], $value);
153 }
154
155 /*
156 foreach ($values as $slot => $value) {
157 if ($value) {
158 $this->RULESET->add('APPEND', $slot, $value);
159 }
160 }
161 */
162
163 }
164
165 function _rules2widget() {
166 while ($rule = $this->RULESET->read()) {
167 //print Dumper($rule);
168 $slot = $rule[slot];
169
170 $value = $rule[key];
171 $label = $rule[value];
172
173 $flag_reverse_lookup = 0;
174 if (!$label) {
175 $flag_reverse_lookup = 1;
176 }
177
178 if (!is_array($value)) {
179 $value = array( $value );
180 }
181 foreach ($value as $elem) {
182 if ($rule[op] == 'APPEND') {
183 //$this->_area[$slot]->_data_list[$elem] = $elem;
184 // HACK!!!
185 //$this->_area[$slot]->_data_list[$elem] = $label;
186 if ($flag_reverse_lookup) {
187 $label = $this->_reverse_lookup_label($elem);
188 }
189 $this->_area[$slot]->_data_list[$label] = $elem;
190 } elseif ($rule[op] == 'REMOVE') {
191 unset($this->_area[$slot]->_data_list[$elem]);
192 // HACK!!!
193 if ($flag_reverse_lookup) {
194 $label = $this->_reverse_lookup_label($elem);
195 unset($this->_area[$slot]->_data_list[$label]);
196 }
197 }
198 }
199 }
200 }
201
202 function result() {
203 $result = array();
204 foreach ($this->_parts as $slot) {
205 $result[$slot] = array_values( $this->_area[$slot]->_data_list );
206 }
207 return $result;
208 }
209
210 function _reverse_lookup_label($value) {
211 // If label is empty, try to look it up reverse from already
212 // established data inside _model - "use other part/area".
213 //print "NO LABEL<br/>";
214 foreach ($this->_parts as $key) {
215 //print "key: $key<br/>";
216 //print "value: $value<br/>";
217 //print Dumper($this->_area[$key]);
218 // new as of 2003-06-03: lookup label by key
219 $idx = array_search($value, $this->_area[$key]->_data_list);
220 //print "idx: $idx<br/>";
221 if ($idx) { return $idx; }
222 }
223 //print Dumper($this->_model);
224 //exit;
225 }
226
227 // This is not exactly like the others: Don't generate a table, just a (simple) container.
228 function form_content() {
229
230 $table = html_table(350, 0, 3, 2);
231 //$table->set_style("align: top;");
232 //print Dumper($table);
233 //$table->set_align("top");
234 //$table->_default_col_attributes = array( valign => "top" );
235 //print Dumper($table);
236
237 $row = array();
238 $row2 = array();
239
240 // string of concatenated keys, propagated as single hidden field
241 $keys = array();
242
243 // touch all parts
244 foreach ($this->_parts as $key) {
245
246 array_push($keys, $key);
247
248 // If anything went wrong, build a dummy FEBoxElement
249 // with the error-message as value to show at least something.
250 $elem = $this->get_element($key);
251 if (!is_object($elem)) {
252 $elem = new FEBoxElement($key);
253 $elem->set_value("Sorry, ListBox could not be rendered.");
254 $this->add_element($elem);
255 }
256
257 //$comp = container( $this->element_label($key), $this->element_form($key));
258 //$td->add();
259 array_push($row,
260 //container(
261 new TDtag(array( valign => "top" ),
262 //$this->element_label($key), html_br(),
263 $this->element_form($key) //, _HTML_SPACE
264 //link::action('add', array( subtopic => $_REQUEST[subtopic] ))
265 //, container("", html_input('', "payload[$key]"), form_submit("ga", "add"))
266 )
267 );
268 array_push($row,
269 //container(
270 new TDtag(array( valign => "middle" ),
271 form_submit('moveback', "<-----"),
272 form_submit('move', "----->")
273 //html_br(),
274 //, _HTML_SPACE
275 )
276 );
277
278
279 $appendix = html_div('',
280 html_input('', "payload[$key]"), form_submit("ga", "add")
281 );
282 $appendix->set_style("width:200px;");
283 array_push($row2, $appendix);
284 array_push($row2, NULL);
285
286 }
287
288 // handle even- & oddness
289 array_pop($row);
290 array_pop($row2);
291
292
293 // new as of 2003-06-04: side-pane (result-, init- ext)
294 foreach ($this->_blocks as $block) {
295 $elem = $this->get_element($block);
296 if (is_object($elem)) {
297 $td = new TDtag(array( valign => "top" ), $this->element_form($block));
298 $td->set_style("padding: 5px; border-left: 1px solid red;");
299 array_push($row, $td);
300 }
301 }
302
303 // propagate slots of $row to html table columns
304 $tr = new TRtag();
305 foreach ($row as $column) {
306 //$td = new TDtag(array( valign => "top" ), $column);
307 $tr->add($column);
308 }
309 $table->add_row( $tr );
310
311 $tr2 = new TRtag();
312 foreach ($row2 as $column) {
313 $tr2->add($column);
314 }
315 $table->add_row( $tr2 );
316
317 //$table->add( form_hidden("t", $_REQUEST[t]) );
318 $table->add( form_hidden("keys", join(',', $keys)) );
319
320 //$comp = $table;
321
322 $subtitle = $this->_options[title];
323 $this->add_form_block($subtitle, $table);
324 }
325
326 function form_content_buttons() {
327 //return;
328 $div = new DIVtag( array(
329 "style" => "background-color: #eeeeee;"
330 . "padding-top:5px;padding-bottom:5px;"
331 ,
332 "align"=>"center", "halign" => "middle",
333 "nowrap"),
334 //$this->add_action("Save"),
335 form_submit("ga", "Go"),
336 _HTML_SPACE,
337 $this->add_cancel()
338 );
339 return $div;
340 }
341
342 function add_block($name) {
343
344 $num_args = func_num_args();
345 $result_block = html_div();
346 $result_block->set_style("border: 1px solid groove; padding: 3px; font-family:Tahoma; font-size: 11px;");
347
348 for ($i = 1; $i < $num_args; $i++) {
349 $result_block->add( func_get_arg($i) );
350 }
351
352 $elem = new FEBoxElement($name);
353 $elem->set_value($result_block);
354 $this->add_element($elem);
355 }
356
357
358
359
360
361 // =============================================
362 // deprecated
363 // =============================================
364
365 function _init_session() {
366
367 // HACK: Check if slot 1 isn't empty. If so, subtract from slot 0.
368 // (add it to slot 0's associated clipboard)
369 // patched [2003-05-29]: just do this once!
370
371 /*
372 $part1 = $this->_parts[0];
373 $part2 = $this->_parts[1];
374 $clipboard_doubles = array_intersect($_SESSION[DataManager][op][$part1], $_SESSION[DataManager][op][$part2]);
375 */
376
377 //return;
378 //if (!isset($_SESSION[DataManager][used])) { $_SESSION[DataManager][used] = 0; }
379
380 if ($_SESSION[DataManager][used] == 0) {
381
382 print "INIT<br/>";
383
384 if (sizeof($this->_model[1][data])) {
385 $part1 = $this->_parts[0];
386 $part2 = $this->_parts[1];
387 $_SESSION[DataManager][op][$part1] = php::array_join_merge($_SESSION[DataManager][op][$part1], $this->_model[1][data]);
388 }
389
390 }
391
392
393 }
394
395
396
397 function _post2session() {
398
399 //print Dumper($_SESSION);
400
401 // TODO: clear complete clipboard
402 //unset($_SESSION[DataManager]);
403
404 foreach ($this->_parts as $part) {
405 if (!is_array($_SESSION[DataManager][op][$part])) {
406 $_SESSION[DataManager][op][$part] = array();
407 }
408 }
409
410 //print Dumper($_POST);
411
412 // detect & apply "Move selected elements from left to right."
413 foreach ($this->_model as $idx => $entry) {
414 $key = $entry[key];
415 $token = $entry[token];
416 $list = $entry[data];
417
418 // Just do it if list-var is defined?
419 //if (isset($_POST[$token]) && is_array($list)) {
420 if (isset($_POST[$token])) {
421 $_SESSION[DataManager][token] = $token;
422
423 // V1 - append POST to clipboard
424 //array_push($_SESSION[DataManager][op][$token], $_POST[$entry[key]]);
425
426 // V2 - *merge* POST to clipboard
427 $_SESSION[DataManager][op][$key] =
428 php::array_join_merge($_SESSION[DataManager][op][$key], $_POST[$entry[key]]);
429
430 // new as of 2003-05-29: flag session: "used" (actually this is a use-*count* per page-view)
431 print "used!<br/>";
432 $_SESSION[DataManager][used] = 1;
433
434 }
435 }
436
437 //print Dumper($_SESSION[DataManager]);
438 }
439
440 function _normalize_parts() {
441 // normalize parts (delete equals from *both* clipboards)
442 // by now: intersect *two* parts ...
443 $part1 = $this->_parts[0];
444 $part2 = $this->_parts[1];
445 $clipboard_doubles = array_intersect($_SESSION[DataManager][op][$part1], $_SESSION[DataManager][op][$part2]);
446
447 // ... and remove elements from both clipboards
448 foreach ($clipboard_doubles as $key) {
449 $this->_rmslot($key, $_SESSION[DataManager][op][$part1]);
450 $this->_rmslot($key, $_SESSION[DataManager][op][$part2]);
451 }
452 }
453
454 function apply_operation() {
455
456 // tracepoint
457 //print Dumper($_SESSION[DataManager][op]);
458 //print Dumper($this->_model);
459
460 // apply clipboard associated with each box to the others box content
461 // (merge $_SESSION of other $part to $this->_model)
462
463 $idx = 0;
464 $idx_other = 1;
465 // TODO: Better indexing! Enhance to actually make multiple columns possible!
466 $map = array(
467 );
468
469 foreach ($this->_parts as $part) {
470
471 // logic: Take diff from orig against clipboard, to calculate which are still left.
472 $orig = array_values($this->_model[$idx][data]);
473 $clipboard = $_SESSION[DataManager][op][$part];
474 $left = array_diff($orig, $clipboard);
475
476 // overwrite data in model with calculated "left" ones:
477 //$this->_model[$idx][data] = $left;
478
479 // unset all in model which are already in clipboard -
480 // doing kind of reverse mapping here utilizing array_search -
481 // and move underlying items to *other* $part of $this->_model.
482 foreach ($clipboard as $key) {
483 $this->_swapslot($key, $this->_model[$idx][data], $this->_model[$idx_other][data]);
484 }
485
486 /*
487 // tracepoint
488 print "$part-ORIG: " . Dumper($this->_model[$idx][data]);
489 print "$part-SESSION: " . Dumper($_SESSION[DataManager][op][$part]);
490 print "$part-left: " . Dumper($left);
491 */
492
493 $idx++;
494 $idx_other--;
495 }
496
497 }
498
499 function _rmslot($slot, &$haystack) {
500 $idx = array_search($slot, $haystack);
501 unset($haystack[$idx]);
502 }
503
504 function _swapslot($slot, &$one, &$other) {
505 // find itemkey from appkey
506 $idx = array_search($slot, $one);
507
508 // move key/value pair to other part of the model
509 $other[$idx] = $one[$idx];
510
511 // delete by key in this part of the model
512 unset($one[$idx]);
513 }
514
515 function data2widget() {
516 foreach ($this->_model as $entry) {
517 $key = $entry[key];
518 // V1
519 //$this->_area[$key]->_data_list =& $entry[data];
520 // V2
521 $this->_area[$key]->_data_list = php::array_join_merge($this->_area[$key]->_data_list, $entry[data]);
522 }
523 }
524
525
526 }
527
528
529
530 class RuleSet {
531
532 function RuleSet($token) {
533 $this->token = $token;
534 if (!isset($_SESSION[RuleSet][$this->token])) {
535 $_SESSION[RuleSet][$this->token] = array();
536 }
537 //print Dumper($_SESSION[RuleSet]);
538 reset($_SESSION[RuleSet][$this->token]);
539 }
540
541 function add($op, $slot, $key, $value = NULL, $tag = NULL) {
542 $rule = array(op => $op, slot => $slot, key => $key, value => $value, tag => $tag);
543 //print "rule: " . Dumper($rule);
544 array_push($_SESSION[RuleSet][$this->token], $rule);
545 }
546
547 function read() {
548 $current = current($_SESSION[RuleSet][$this->token]);
549 next($_SESSION[RuleSet][$this->token]);
550 return $current;
551 }
552
553 function readmulti() {
554 return $_SESSION[RuleSet][$this->token];
555 }
556
557 function resolve($slot) {
558 $keys = array();
559 $result = array();
560 $rules = $this->readmulti();
561 foreach ($rules as $rule) {
562 if ($rule[slot] == $slot && $rule[tag] != 'static') {
563 //array_push($keys, $rule[key]);
564 $keys[$rule[op]] = array_merge($keys[$rule[op]], $rule[key]);
565 }
566 //$keys[$rule[op]] = array_unique($keys[$rule[op]]);
567 }
568 return $keys;
569 }
570
571 function resolve_normalized($slot) {
572
573 $stats = array();
574 $normalized = array();
575 $resolved = $this->resolve($slot);
576
577 //print Dumper($resolved);
578 //exit;
579
580 // declare tokens used inside rules
581 $tokens = array( 'APPEND', 'REMOVE' );
582
583 // count operations
584 foreach ($tokens as $token) {
585 foreach ($resolved[$token] as $item) {
586 $stats[$token][$item]++;
587 }
588 }
589 //return $stats;
590
591 // apply normalization (delete all slots from $stats which have even counts)
592 // compare APPEND-count against REMOVE-count
593 $token1 = $tokens[0];
594 $token2 = $tokens[1];
595 //foreach ($tokens as $token) {
596 //foreach ($stats[$token1] as $item) {
597 //$stats[$token][$item]++;
598 if ($stats[$token1] == $stats[$token2]) {
599 unset($stats[$token1]);
600 unset($stats[$token2]);
601 } else {
602 //print "HMM???<br/>";
603 foreach ($stats[$token2] as $idx => $item) {
604 if ($stats[$token1][$idx] >= $stats[$token2][$idx]) {
605 //print "YAI!!!<br/>";
606 unset($stats[$token2][$idx]);
607 } else {
608 unset($stats[$token1][$idx]);
609 }
610 }
611 }
612 //}
613 //}
614
615 // build normalized result
616 foreach ($tokens as $token) {
617 $normalized[$token] = array_keys($stats[$token]);
618 }
619 return $normalized;
620
621 $intersection = array_intersect($resolved[APPEND], $resolved[REMOVE]);
622 foreach ($intersection as $item) {
623 //print "item: " . Dumper($item);
624 $normalized[APPEND] = array_diff( $intersection, $resolved[APPEND] );
625 $normalized[REMOVE] = array_diff( $intersection, $resolved[REMOVE] );
626 }
627 return $normalized;
628 }
629
630 }
631
632 ?>

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed