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

Last change on this file since 1137 was 1137, checked in by nanardon, 12 years ago

add autoMemberFilter to group forms

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