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

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

add basis form for service object

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