source: trunk/LATMOS-Accounts-Web/lib/LATMOS/Accounts/Web/Model/AttrForms.pm @ 984

Last change on this file since 984 was 959, checked in by nanardon, 12 years ago
  • merge all work around forms
File size: 16.9 KB
Line 
1package LATMOS::Accounts::Web::Model::AttrForms;
2
3use strict;
4use warnings;
5use base 'Catalyst::Model';
6use LATMOS::Accounts::Log;
7use HTML::Prototype;
8
9=head1 NAME
10
11LATMOS::Accounts::Web::Model::AttrForms - Catalyst Model
12
13=head1 DESCRIPTION
14
15Catalyst Model.
16
17=cut
18
19my $forms = {
20    usersys => {
21        name => 'SystÚme',
22        attrs => [ qw(
23            sn givenName description
24            uid uidNumber gidNumber gecos homeDirectory loginShell
25            mail initials nickname
26            expire
27            locked
28            create
29            date
30        ) ],
31    },
32    user => {
33        name => 'Statut',
34        attrs => [ qw(
35            sn givenName description
36            company
37            department
38            manager
39            managerContact
40            contratType
41            expire
42            snNative
43            givenNameNative
44            wWWHomePage
45            halReference
46            create
47            date
48        ) ],
49    },
50    useraddress => {
51        name => 'Adresse',
52        attrs => [ qw(
53            initials
54            mail
55        ) ],
56    },
57    usermy => {
58        name => 'My',
59        attrs => [ qw(
60            snNative
61            givenNameNative
62            wWWHomePage
63            halReference
64        ) ],
65    },
66    site => {
67        name => 'Site',
68        attrs => [ qw(
69            description
70            siteNick
71            streetAddress
72            postOfficeBox
73            postalCode
74            l
75            st
76            co
77            facsimileTelephoneNumber
78            create
79            date
80        ) ],
81    },
82    address => {
83        name => 'Adresse',
84        attrs => [ qw(
85            isMainAddress
86            telephoneNumber
87            streetAddress
88            postOfficeBox
89            postalCode
90            l
91            st
92            physicalDeliveryOfficeName
93            site
94            co
95            unexported
96            description
97        ) ],
98    },
99    group => {
100        name => 'SystÚme',
101        attrs => [ qw(
102            gidNumber description
103            managedBy
104            sutype
105            create
106            date
107        ) ],
108    },
109    nethost => {
110        name => 'Ordinateur',
111        attrs => [ qw(
112            name
113            description
114            serialNumber
115            owner
116            user
117            ip
118            macaddr
119            noDynamic
120            cname
121            otherName
122            reverse
123            create
124            date
125            unexported
126        ) ],
127    },
128    netzone => {
129        name => 'Zone réseau',
130        attrs => [ qw(
131            name
132            description
133            type
134            net
135            netExclude
136            outputD
137            templateD
138            site
139            allow_dyn
140            dynFrom
141            domain
142            ipCount
143            freeIPCount
144            create
145            date
146            dnsRevision
147            lastUpdate
148            unexported
149        ) ],
150    },
151    aliases => {
152        name => 'Alias mail',
153        attrs => [ qw(
154            forward
155            expire
156            finalpoint
157            parents
158            created
159            date
160            unexported
161        )],
162    },
163};
164
165sub escape {
166    my ($self, $text) = @_;
167    $text ||= '';
168    for ($text) {
169        s/&/&/g;
170        s/</&lt;/g;
171        s/>/&gt;/g;
172        s/"/&quot;/g;
173    }
174    $text;
175}
176
177sub new {
178    my ($class) = @_;
179    bless({}, $class);
180}
181
182# call either OBJ or type + base
183
184sub ACCEPT_CONTEXT {
185    my ($self, $c, $form, $object, $base) = @_;
186    my $new = {};
187    $new->{c} = $c;
188    $new->{form} = $form;
189    $new->{object} = $object if (ref $object);
190    $new->{base} = $base || ($object ? $object->base : undef) or return $self;
191    $new->{otype} = ref $object ? $object->type : $object;
192    bless($new, __PACKAGE__);
193}
194
195sub base {
196    my ( $self ) = @_;
197    $self->{base}
198}
199
200sub otype {
201    my ($self) = @_;
202    $self->{otype};
203}
204
205sub label {
206    my ($self) = @_;
207    $forms->{$self->{form}}->{name} || ''
208}
209
210sub attributes {
211    my ($self, $for) = @_;
212    grep { $_ }
213    grep { $self->base->attribute($self->otype, $_) }
214    @{ $forms->{$self->{form}}->{attrs} };
215}
216
217sub attr_label {
218    my ($self, $attr, $label, $hint) = @_;
219    $label ||= '';
220    $hint ||= '';
221    LATMOS::Accounts::Web->config->{attrs} ||= {};
222    my $attribute = $self->base->attribute($self->otype, $attr);
223    my $htmlname = $self->escape($self->attr_field_name($attr));
224    if (my $attr_config = LATMOS::Accounts::Web->config->{attrs}{$attr}) {
225        $label ||= $attr_config->{label} || '';
226        #utf8::is_utf8($label) && utf8::encode($label);
227        $hint ||= $attr_config->{hint} || '';
228        #utf8::is_utf8($hint) && utf8::encode($hint);
229    }
230    return sprintf('<label %sfor="%s">%s</label>',
231        ($hint ? sprintf('title="%s"', $self->escape($hint)) : ''),
232        $self->escape($htmlname),
233        $self->escape($label || $attr),
234    );
235}
236
237sub attr_hint {
238    my ($self, $attr) = @_;
239    LATMOS::Accounts::Web->config->{attrs} ||= {};
240    if (my $attr_config = LATMOS::Accounts::Web->config->{attrs}{$attr}) {
241        return $attr_config->{hint} || '';
242    }
243    return;
244}
245
246sub attr_raw_value {
247    my ($self, $attribute) = @_;
248    my @val = grep { $_ } 
249        ($self->{c}->req->param($attribute->name))
250        || ($self->{object}
251            ? ($self->{object}->get_attributes($attribute->name))
252            : ());
253
254    if (@val) {
255        return @val;
256    } else {
257        return (grep { $_ } ($attribute->default_value))
258    }
259}
260
261sub attr_field_name {
262    my ($self, $attr) = @_;
263    my $id = $self->{object}
264        ? ($self->{object}->id || '')
265        : '';
266    $id .= '_' if ($id);
267    $id =~ s/\./_/g;
268    $id =~ s/-/_/g;
269    $id . $attr;
270}
271
272sub attr_item {
273    my ($self, $attribute, $value, $htmlid) = @_;
274
275    my $html = $self->_attr_item($attribute, $value, $htmlid);
276   
277    if ($attribute->uniq) {
278        $html .= qq|<span class="inputvalidate" id="${htmlid}_uniq"></span>|;
279    }
280    if (my $ref = $attribute->reference) {
281        my $uri_part = $self->_uri_part($ref);
282        if ($self->base->attribute($ref, 'displayName')) {
283            my $text = '';
284            if ($value &&
285                (my $obj = $self->base->get_object($ref, $value))) {
286                $text = $obj->get_attributes('displayName');
287            }
288            $html .= sprintf(
289                qq|<span id="${htmlid}_ref" style="margin-left: 1em">$text</span>|,
290                $self->escape($text),
291            );
292        } elsif($value && $uri_part) {
293            $html .= sprintf(
294                '<a href="%s"><img class="attr" src="%s" title="%s"></a>',
295                $self->{c}->uri_for('/', $uri_part, $value),
296                $self->{c}->uri_for('/static', 'icons', 'arrow-right.png'),
297                $value,
298            );
299        }
300    }
301
302    $html
303}
304
305sub _attr_item {
306    my ($self, $attribute, $value, $htmlid) = @_;
307
308    my $htmlname = $self->escape($self->attr_field_name($attribute->name));
309    $htmlid ||= $htmlname;
310
311    for ($attribute->form_type) {
312            /^textarea$/i and do {
313                return sprintf(
314                    '<textarea id="%s" name="%s" cols="40">%s</textarea>',
315                    $self->escape($htmlid),
316                    $self->escape($htmlname),
317                    $self->escape($value || ''),
318                );
319                last;
320            };
321
322            /^label$/i and do {
323                $value or last;
324                my $html_field = $self->escape($value);
325                $html_field =~ s/\n/<br>/g;
326                $html_field .= sprintf('<input type="hidden" name="%s" value="%s">',
327                    $self->escape($htmlname), ($value || ''));
328                return $html_field;
329                last;
330            };
331
332            /^date$/i and do {
333                my ($date, $time) = split(/ /, $value || '');
334                if ($date && $date =~ /^(\d+)-(\d+)-(\d+)$/) {
335                    $date = "$3/$2/$1";
336                }
337                my $html = "\n" . q{<SCRIPT LANGUAGE="JavaScript" ID="js13">
338                var cal13 = new CalendarPopup();
339                </SCRIPT>} . "\n";
340                $html .= sprintf(
341                    '<input type="text" id="%s" name="%s" value="%s" size="12">',
342                    $self->escape($htmlid),
343                    $self->escape($htmlname),
344                    $self->escape($date)
345                );
346                $html .= q{<DIV ID="testdiv1" STYLE="position:absolute;visibility:hidden;background-color:white;layer-background-color:white;"></DIV>};
347                $html .= qq|
348                <A HREF="#"
349                    onClick="cal13.select(document.getElementById('$htmlid'),'${htmlid}_anc','dd/MM/yyyy');return false;"
350                    TITLE="Date"
351                    NAME="${htmlid}_anc" ID="${htmlid}_anc">
352                    <img class="attr" src="| . $self->{c}->uri_for(qw(/static icons view-calendar-day.png))
353                    . qq{" style="ref"></A>
354                    } . "\n";
355                return $html;
356                last;
357            };
358
359            /^checkbox/i and do {
360                my $options = $1 || '';
361                my $html = sprintf('<input type="checkbox" id="%s" name="%s"%s>',
362                    $htmlid,
363                    $self->escape($htmlname),
364                    $value ? '  checked="yes"' : ''
365                ); 
366                $html .= sprintf('<input type="hidden" name="%s">',
367                    $self->escape($htmlname));
368                if ($attribute->form_option('rawvalue')) {
369                    $html .= $value
370                        ? ' ' . $value
371                        : ''; 
372                }
373                return $html;
374                last;
375            };
376
377            /^LIST/i and do {
378                my $select = sprintf('<select id="%s" name="%s">',
379                    $self->escape($htmlid),
380                    $self->escape($htmlname)) . "\n";
381                $select .= '<option value="">--</option>' . "\n"
382                    unless($attribute->mandatory);
383                $value ||= '';
384                my $initial_observed = '';
385                my @valslist;
386                foreach my $val (sort $attribute->can_values) {
387                    push(@valslist, {
388                        val => $val,
389                        disp => $attribute->display($val || ''),
390                    });
391                }
392                foreach (sort { $a->{disp} cmp $b->{disp} } @valslist) {
393                    $select .= sprintf(
394                        '    <option value="%s"%s>%s</option>',
395                        $self->escape($_->{val} || ''),
396                        $value eq $_->{val} ? ' selected="selected"' : '',
397                        $self->escape($_->{disp} || ''),
398                    );
399                    $select .= "\n";
400                }
401                $select .= "</select>\n";
402
403                return $select;
404                last;
405            };
406
407            /^text/i and do {
408                return sprintf(
409                    '<input type="text" id="%s" name="%s" value="%s" size="%d">',
410                    $self->escape($htmlid),
411                    $self->escape($htmlname),
412                    $self->escape($value),
413                    $attribute->form_option('length') || 30,
414                );
415                last;
416            };
417        }
418    return '';
419}
420
421sub _uri_part {
422    my ($self, $ref) = @_;
423    my $uri_part = {
424        user => 'users',
425        group => 'groups',
426        nethost => 'nethosts',
427        netzone => 'netzones',
428        site => 'sites'
429    }->{$ref};
430}
431
432sub attr_js {
433    my ($self, $attribute, $value, $htmlid) = @_;
434
435    my (@js);
436
437    if (my $ref = $attribute->reference) {
438        my $uri_part = $self->_uri_part($ref);
439        if ($self->base->attribute($ref, 'displayName')) {
440            push(@js, 
441                $self->{c}->prototype->observe_field( $htmlid,
442                    {
443                        update => "${htmlid}_ref",
444                        url => $self->{c}->uri_for('/ajax', 'rawattr', $ref),
445                        frequency => 1,
446                        with   => "'attr=displayName&id=' + element.options[element.selectedIndex].text",
447                    }
448                )
449            ) if ($attribute->form_type =~ /list/i);
450        }
451    }
452
453    if ($attribute->uniq) {
454        push(@js,
455            $self->{c}->prototype->observe_field( $htmlid,
456                {
457                    update => "${htmlid}_uniq",
458                    url => $self->{c}->uri_for('/ajax', 'objattrexist',
459                        $self->otype, $attribute->name),
460                    frequency => 1,
461                    with => "'val='+element.value" .
462                    ($self->{object} ?
463                        "+'&exclude=" . ($self->{object}->id || '') . "'" 
464                        : ''),
465                }
466            )
467        );
468    }
469
470    return(join("\n", @js));
471}
472
473sub attr_field {
474    my ($self, $attr, $type) = @_;
475
476    my $attribute = ($type
477        ? ref $type
478            ? $self->base->attribute(
479                $self->otype,
480                { %$type, name => $attr },)
481            : $self->base->attribute(
482                $self->otype,
483                { formtype => $type , name => $attr },)
484        : ($self->{object}
485            ? $self->{object}->attribute($attr)
486            : $self->base->attribute($self->otype, $attr, { formtype => $type })))
487        || $self->base->attribute($self->otype, { name => $attr });
488
489
490    my $htmlname = $self->escape($self->attr_field_name($attr));
491
492    my @html_fields;
493
494    # Force Array context:
495    my @attr_raw_value = ();
496    if ($attribute->multiple) {
497        @attr_raw_value = grep { $_ } $self->attr_raw_value($attribute);
498    } else {
499        my ($val) = $self->attr_raw_value($attribute);
500        @attr_raw_value = ($val || '');
501    }
502
503    foreach my $attr_raw_value (@attr_raw_value) {
504
505        my $html_id = $htmlname .
506            (scalar(@html_fields) ? scalar(@html_fields) : '');
507        push(@html_fields,
508            join("\n",
509                $self->attr_item(
510                    $attribute, $attr_raw_value, $html_id
511                ),
512                $self->attr_js(
513                    $attribute, $attr_raw_value, $html_id
514                )
515            )
516        );
517    }
518
519    if ($attribute->{multiple} && !$attribute->readonly) {
520        my $html_id = $htmlname . '_m_SUBID';
521
522        my $attr = $self->attr_item($attribute, '', $html_id);
523        # JS: string are on the line only
524        $attr =~ s/\n//mg;
525        $attr =~ s/'/\'/g;
526
527        my $js = $self->attr_js($attribute, '', 'NANAR');
528        $js =~ s!'NANAR([_\w]*)'!('$html_id$1'.replace(/SUBID/g, cn))!gm;
529        $js =~ s!<script[^>]+>!!gm;
530        $js =~ s!</script>!!gm;
531        $js =~ s!-->!!gm;
532        $js =~ s/<!--//gm;
533
534        my $addempty = sprintf('<div id="%s"></div>', "${htmlname}_div_0");
535        $addempty .= "\n";
536        $addempty .= sprintf(qq#
537            <script type="text/javascript">
538            var cn_${htmlname} = 0;
539            function add_${htmlname} () {
540            cn_${htmlname}++;
541            // It work only using temporary variable
542            var cn = cn_${htmlname};
543            document.getElementById('${htmlname}_div_' + (cn - 1)).innerHTML +=
544                '$attr'.replace(/SUBID/g, cn );
545            document.getElementById('${htmlname}_div_' + (cn - 1)).innerHTML +=
546                '<div id="${htmlname}_div_'+ cn +'"></div>';
547            %s
548            }
549            </script>
550            #, $js
551        );
552
553        $addempty .= "\n";
554        $addempty .=
555            qq|<button type="button" onclick="add_${htmlname}()">+</button>|,
556
557        push(@html_fields, $addempty);
558    }
559
560    return join("<br>\n", @html_fields);
561}
562
563sub submit {
564    my ($self) = @_;
565    return sprintf(
566        '<input type="submit" name="%s" value="Enregistrer">',
567        $self->escape($self->label),
568    );
569}
570
571sub write_attributes {
572    my ($self) = @_;
573    my @attrs;
574    foreach ($self->attributes) {
575        my $attr = ($self->{object}
576            ? $self->{object}->attribute($_)
577            : $self->base->attribute($self->otype, $_)) or next;
578        $attr->readonly and next;
579        push(@attrs, $_);
580    }
581    @attrs;
582}
583
584sub set_attrs {
585    my ($self, $attrs) = @_;
586    $self->{c}->req->param($self->label) || $attrs or return;
587    my $prefix = $self->attr_field_name('');
588    my %fields;
589    foreach ($attrs ? @{ $attrs } : $self->write_attributes) {
590        my $attr = ($self->{object}
591            ? $self->{object}->attribute($_)
592            : $self->base->attribute($self->otype, $_)) or next;
593        if ($attr->{multiple}) {
594            $fields{$_} = [ grep { $_ } $self->{c}->req->param("$prefix$_") ];
595        } else {
596            $fields{$_} = $self->{c}->req->param("$prefix$_");
597        }
598    }
599    $self->{object}->set_c_fields(%fields) or do {
600        $self->{c}->stash->{page}{error} =
601            LATMOS::Accounts::Log::lastmessage(LA_ERR);
602        $self->{object}->base->rollback;
603        return;
604    };
605    $self->{object}->base->commit;
606}
607
608=head1 AUTHOR
609
610Thauvin Olivier
611
612=head1 LICENSE
613
614This library is free software, you can redistribute it and/or modify
615it under the same terms as Perl itself.
616
617=cut
618
6191;
Note: See TracBrowser for help on using the repository browser.