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

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