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

Last change on this file since 1186 was 1186, checked in by nanardon, 12 years ago

add managedAlsoBy attribute to group

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