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

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

add description on aliases forms

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