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

Last change on this file since 1282 was 1282, checked in by nanardon, 9 years ago

add comment attribute to some objects

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