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

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

add related attribute to nethost: allow to indicate related host in bidiractionnal way

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