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

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