source: perl/lib/Net/XMPP/Roster.pm @ 3405394

barnowl_perlaimdebianrelease-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 3405394 was a75309a, checked in by Alejandro R. Sedeño <asedeno@mit.edu>, 15 years ago
Stream.pm: Proper call to SASL. Roster.pm: Removing print statements.
  • Property mode set to 100644
File size: 24.9 KB
Line 
1##############################################################################
2#
3#  This library is free software; you can redistribute it and/or
4#  modify it under the terms of the GNU Library General Public
5#  License as published by the Free Software Foundation; either
6#  version 2 of the License, or (at your option) any later version.
7#
8#  This library is distributed in the hope that it will be useful,
9#  but WITHOUT ANY WARRANTY; without even the implied warranty of
10#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11#  Library General Public License for more details.
12#
13#  You should have received a copy of the GNU Library General Public
14#  License along with this library; if not, write to the
15#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16#  Boston, MA  02111-1307, USA.
17#
18#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
19#
20##############################################################################
21
22package Net::XMPP::Roster;
23
24=head1 NAME
25
26Net::XMPP::Roster - XMPP Roster Object
27
28=head1 SYNOPSIS
29
30  Net::XMPP::Roster is a module that provides a developer an easy
31  interface to an XMPP roster.  It provides high level functions to
32  query, update, and manage a user's roster. 
33
34=head1 DESCRIPTION
35
36  The Roster object seeks to provide an easy to use API for interfacing
37  with a user's roster.  When you instantiate it, it automatically
38  registers with the connection to receivce the correct packets so
39  that it can track all roster updates, and presence packets.
40 
41=head2 Basic Functions
42
43  my $Client = new Net::XMPP::Client(...);
44
45  my $Roster = new Net::XMPP::Roster(connection=>$Client);
46    or
47  my $Roster = $Client->Roster();
48
49  $Roster->clear();
50
51  if ($Roster->exists('bob@jabber.org')) { ... }
52  if ($Roster->exists(Net::XMPP::JID)) { ... }
53
54  if ($Roster->groupExists("Friends")) { ... }
55
56  my @groups = $Roster->groups();
57
58  my @jids    = $Roster->jids();
59  my @friends = $Roster->jids("group","Friends");
60  my @unfiled = $Roster->jids("nogroup");
61
62  if ($Roster->online('bob@jabber.org')) { ... }
63  if ($Roster->online(Net::XMPP::JID)) { ... }
64
65  my %hash = $Roster->query('bob@jabber.org');
66  my %hash = $Roster->query(Net::XMPP::JID);
67
68  my $name = $Roster->query('bob@jabber.org',"name");
69  my $ask  = $Roster->query(Net::XMPP::JID,"ask");
70
71  my $resource = $Roster->resource('bob@jabber.org');
72  my $resource = $Roster->resource(Net::XMPP::JID);
73
74  my %hash = $Roster->resourceQuery('bob@jabber.org',"Home");
75  my %hash = $Roster->resourceQuery(Net::XMPP::JID,"Club");
76
77  my $show   = $Roster->resourceQuery('bob@jabber.org',"Home","show");
78  my $status = $Roster->resourceQuery(Net::XMPP::JID,"Work","status");
79
80  my @resource = $Roster->resources('bob@jabber.org');
81  my @resource = $Roster->resources(Net::XMPP::JID);
82
83  $Roster->resourceStore('bob@jabber.org',"Home","gpgkey",key);
84  $Roster->resourceStore(Net::XMPP::JID,"logged on","2004/04/07 ...");
85
86  $Roster->store('bob@jabber.org',"avatar",avatar);
87  $Roster->store(Net::XMPP::JID,"display_name","Bob");
88
89=head2 Advanced Functions
90
91  These functions are only needed if you want to manually control
92  the Roster.
93 
94  $Roster->add('bob@jabber.org',
95               name=>"Bob",
96               groups=>["Friends"]
97              );
98  $Roster->add(Net::XMPP::JID);
99
100  $Roster->addResource('bob@jabber.org',
101                       "Home",
102                       show=>"dnd",
103                       status=>"Working"
104                      );
105  $Roster->addResource(Net::XMPP::JID,"Work");
106
107  $Roster->remove('bob@jabber.org');
108  $Roster->remove(Net::XMPP::JID);
109
110  $Roster->removeResource('bob@jabber.org',"Home");
111  $Roster->removeResource(Net::XMPP::JID,"Work");
112
113  $Roster->handler(Net::XMPP::IQ);
114  $Roster->handler(Net::XMPP::Presence);
115
116=head1 METHODS
117
118=head2 Basic Functions
119
120
121  new(connection=>object) - This creates and initializes the Roster
122                            object.  The connection object is required
123                            so that the Roster can interact with the
124                            main connection object.  It needs to be an
125                            object that inherits from
126                            Net::XMPP::Connection.
127
128  clear() - removes everything from the database.
129
130  exists(jid) - return 1 if the JID exists in the database, undef
131                otherwise.  The jid can either be a string, or a
132                Net::XMPP::JID object.
133               
134  groupExists(group) - return 1 if the group exists in the database,
135                       undef otherwise.
136
137  groups() - returns a list of all of the roster groups.
138
139  jids([type,    - returns a list of all of the matching JIDs.  The valid
140       [group]])   types are:
141
142                    all     - return all JIDs in the roster. (default)
143                    nogroup - return all JIDs not in a roster group.
144                    group   - return all of the JIDs in the specified
145                              roster group.
146
147  online(jid) - return 1 if the JID is online, undef otherwise.  The
148                jid can either be a string, or a Net::XMPP::JID object.
149
150  query(jid,   - return a hash representing all of the data in the
151        [key])   DB for this JID.  The jid can either be a string,
152                 or a Net::XMPP::JID object.  If you specify a key,
153                 then only the value for that key is returned.
154
155  resource(jid) - return the string representing the resource with the
156                  highest priority for the JID.  The jid can either be
157                  a string, or a Net::XMPP::JID object.
158
159  resourceQuery(jid,      - return a hash representing all of the data
160                resource,   the DB for the resource for this JID.  The
161                [key])      jid can either be a string, or a
162                            Net::XMPP::JID object.  If you specify a
163                            key, then only the value for that key is
164                            returned.
165
166  resources(jid) - returns the list of resources for the JID in order
167                   of highest priority to lowest priority.  The jid can
168                   either be a string, or a Net::XMPP::JID object.
169
170  resourceStore(jid,      - store the specified value in the DB under
171                resource,   the specified key for the resource for this
172                key,        JID.  The jid can either be a string, or a
173                value)      Net::XMPP::JID object.
174
175  store(jid,      - store the specified value in the DB under the
176        key,        specified key for this JID.  The jid can either
177        value)      be a string, or a Net::XMPP::JID object.
178
179
180
181=head2 Advanced Functions
182
183add(jid,                 - Manually adds the JID to the Roster with the
184    ask=>string,           specified roster item settings.  This does not
185    groups=>arrayref       handle subscribing to other users, only
186    name=>string,          manipulating the Roster object.  The jid
187    subscription=>string)  can either be a string or a Net::XMPP::JID.
188
189addResource(jid,            - Manually add the resource to the JID in the
190            resource,         Roster with the specified presence settings.
191            priority=>int,    This does not handle subscribing to other
192            show=>string,     users, only manipulating the Roster object.
193            status=>string)   The jid can either be a string or a
194                              Net::XMPP::JID.
195
196remove(jid) - Removes all reference to the JID from the Roster object.
197              The jid can either be a string or a Net::XMPP::JID.
198
199removeResource(jid,      - Removes the resource from the jid in the
200               resource)   Roster object.  The jid can either be a string
201                           or a Net::XMPP::JID.
202
203handler(packet) - Take either a Net::XMPP::IQ or Net::XMPP::Presence
204                  packet and parse them according to the rules of the
205                  Roster object.  Note, that it will only waste CPU time
206                  if you pass in IQs or Presences that are not roster
207                  related.
208
209=head1 AUTHOR
210
211Ryan Eatmon
212
213=head1 COPYRIGHT
214
215This module is free software; you can redistribute it and/or modify
216it under the same terms as Perl itself.
217
218=cut
219
220use strict;
221use Carp;
222
223sub new
224{
225    my $proto = shift;
226    my $self = { };
227
228    my %args;
229    while($#_ >= 0) { $args{ lc(pop(@_)) } = pop(@_); }
230
231    if (!exists($args{connection}) ||
232        !$args{connection}->isa("Net::XMPP::Connection"))
233    {
234        croak("You must pass Net::XMPP::Roster a valid connection object.");
235    }
236
237    $self->{CONNECTION} = $args{connection};
238   
239    bless($self, $proto);
240
241    $self->init();
242   
243    return $self;
244}
245
246
247##############################################################################
248#
249# init - initialize the module to use the roster database
250#
251##############################################################################
252sub init
253{
254    my $self = shift;
255
256    $self->{CONNECTION}-> SetXPathCallBacks('/iq[@type="result" or @type="set"]/query[@xmlns="jabber:iq:roster"]'=>sub{ $self->handler(@_) });
257    $self->{CONNECTION}-> SetXPathCallBacks('/presence'=>sub{ $self->handler(@_) });
258}
259
260
261##############################################################################
262#
263# add - adds the entry to the Roster DB.
264#
265##############################################################################
266sub add
267{
268    my $self = shift;
269    my ($jid,%item) = @_;
270
271    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
272
273    $self->{JIDS}->{$jid} = \%item;
274
275    foreach my $group (@{$item{groups}})
276    {
277        $self->{GROUPS}->{$group}->{$jid} = 1;
278    }
279}
280
281
282
283##############################################################################
284#
285# addResource - adds the resource to the JID in the Roster DB.
286#
287##############################################################################
288sub addResource
289{
290    my $self = shift;
291    my $jid = shift;
292    my $resource = shift;
293    my (%item) = @_;
294
295    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
296
297    my $priority = $item{priority};
298    $priority = 0 unless defined($priority);
299
300    $self->{CONNECTION}->{DEBUG}->Log3("Roster::addResource: add $jid/$resource with priority $priority to the DB");
301
302    my $loc = -1;
303    $self->{JIDS}->{$jid}->{priorities}->{$priority} = []
304        unless exists($self->{JIDS}->{$jid}->{priorities}->{$priority});
305    foreach my $index (0..$#{$self->{JIDS}->{$jid}->{priorities}->{$priority}})
306    {
307        $loc = $index
308            if ($self->{JIDS}->{$jid}->{priorities}->{$priority}->[$index]->{resource} eq $resource);
309    }
310    $loc = $#{$self->{JIDS}->{$jid}->{priorities}->{$priority}} + 1 if ($loc == -1);
311
312    $self->{JIDS}->{$jid}->{resources}->{$resource}->{priority} = $priority;
313    $self->{JIDS}->{$jid}->{resources}->{$resource}->{status} = $item{status}
314        if exists($item{status});
315    $self->{JIDS}->{$jid}->{resources}->{$resource}->{show} = $item{show}
316        if exists($item{show});
317    $self->{JIDS}->{$jid}->{priorities}->{$priority}->[$loc]->{resource} = $resource;
318}
319
320
321###############################################################################
322#
323# clear - delete all of the JIDs from the DB completely.
324#
325###############################################################################
326sub clear
327{
328    my $self = shift;
329
330    $self->{CONNECTION}->{DEBUG}->Log3("Roster::clear: clearing the database");
331    foreach my $jid ($self->jids())
332    {
333        $self->remove($jid);
334    }
335    $self->{CONNECTION}->{DEBUG}->Log3("Roster::clear: database is empty");
336}
337
338
339##############################################################################
340#
341# exists - allows you to query if the JID exists in the Roster DB.
342#
343##############################################################################
344sub exists
345{
346    my $self = shift;
347    my ($jid) = @_;
348
349    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
350   
351    return unless exists($self->{JIDS});
352    return unless exists($self->{JIDS}->{$jid});
353    return 1;
354}
355
356
357sub fetch
358{
359    my $self = shift;
360
361    my %newroster = $self->{CONNECTION}->RosterGet();
362
363    $self->handleRoster(\%newroster);
364}
365
366
367##############################################################################
368#
369# groupExists - allows you to query if the group exists in the Roster
370#                       DB.
371#
372##############################################################################
373sub groupExists
374{
375    my $self = shift;
376    my ($group) = @_;
377
378    return unless exists($self->{GROUPS});
379    return unless exists($self->{GROUPS}->{$group});
380    return 1;
381}
382
383
384##############################################################################
385#
386# groups - returns a list of the current groups in your roster.
387#
388##############################################################################
389sub groups
390{
391    my $self = shift;
392
393    return () unless exists($self->{GROUPS});
394    return () if (scalar(keys(%{$self->{GROUPS}})) == 0);
395    return keys(%{$self->{GROUPS}});
396}
397
398
399##############################################################################
400#
401# handler - takes a packet and calls the correct handler.
402#
403##############################################################################
404sub handler
405{
406    my $self = shift;
407    my $sid = shift;
408    my $packet = shift;
409
410    $self->handleIQ($packet) if ($packet->GetTag() eq "iq");
411    $self->handlePresence($packet) if ($packet->GetTag() eq "presence");
412}
413
414
415##############################################################################
416#
417# handleIQ - takes an iq packet that contains roster, parses it, and puts
418#            the roster into the Roster DB.
419#
420##############################################################################
421sub handleIQ
422{
423    my $self = shift;
424    my $iq = shift;
425
426    my $type = $iq->GetType();
427    return unless (($type eq "set") || ($type eq "result"));
428
429    my %newroster = $self->{CONNECTION}->RosterParse($iq);
430
431    $self->handleRoster(\%newroster);
432}
433
434
435sub handleRoster
436{
437    my $self = shift;
438    my $roster = shift;
439
440    foreach my $jid (keys(%{$roster}))
441    {
442        $self->remove($jid);
443
444        if ($roster->{$jid}->{subscription} ne "remove")
445        {
446            $self->add($jid, %{$roster->{$jid}});
447        }
448    }
449}
450
451
452##############################################################################
453#
454# handlePresence - takes a presence packet and groks the presence.
455#
456##############################################################################
457sub handlePresence
458{
459    my $self = shift;
460    my $presence = shift;
461
462    my $type = $presence->GetType();
463    $type = "" unless defined($type);
464    return unless (($type eq "") ||
465                   ($type eq "available") ||
466                   ($type eq "unavailable"));
467
468    my $jid = $presence->GetFrom("jid");
469
470    my $resource = $jid->GetResource();
471    $resource = " " unless ($resource ne "");
472   
473    $jid = $jid->GetJID();
474    $jid = "" unless defined($jid);
475
476    return unless $self->exists($jid);
477    #XXX if it doesn't exist... is it us?
478    #XXX is this a presence based roster?
479
480    $self->{CONNECTION}->{DEBUG}->Log3("Roster::PresenceDBParse: fromJID(",$presence->GetFrom(),") resource($resource) type($type)");
481    $self->{CONNECTION}->{DEBUG}->Log4("Roster::PresenceDBParse: xml(",$presence->GetXML(),")");
482
483    $self->removeResource($jid,$resource);
484
485    if (($type eq "") || ($type eq "available"))
486    {
487        my %item;
488       
489        $item{priority} = $presence->GetPriority();
490        $item{priority} = 0 unless defined($item{priority});
491
492        $item{show} = $presence->GetShow();
493        $item{show} = "" unless defined($item{show});
494
495        $item{status} = $presence->GetStatus();
496        $item{status} = "" unless defined($item{status});
497
498        $self->addResource($jid,$resource,%item);
499    }
500}
501
502
503##############################################################################
504#
505# jids - returns a list of all of the JIDs in your roster.
506#
507##############################################################################
508sub jids
509{
510    my $self = shift;
511    my $type = shift;
512    my $group = shift;
513
514    $type = "all" unless defined($type);
515
516    my @jids;
517
518    if (($type eq "all") || ($type eq "nogroup"))
519    {
520        return () unless exists($self->{JIDS});
521        foreach my $jid (keys(%{$self->{JIDS}}))
522        {
523            next if (($type eq "nogroup") &&
524                     exists($self->{JIDS}->{$jid}->{groups}) &&
525                     ($#{$self->{JIDS}->{$jid}->{groups}} > -1));
526
527            push(@jids,new Net::XMPP::JID($jid));
528        }
529    }
530   
531    if ($type eq "group")
532    {
533        return () unless exists($self->{GROUPS});
534        if (defined($group) && $self->groupExists($group))
535        {
536            foreach my $jid (keys(%{$self->{GROUPS}->{$group}}))
537            {
538                push(@jids,new Net::XMPP::JID($jid));
539            }
540        }
541    }
542
543    return @jids;
544}
545
546
547###############################################################################
548#
549# online - returns if the jid is online or not.
550#
551###############################################################################
552sub online
553{
554    my $self = shift;
555    my $jid = shift;
556
557    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
558
559    return unless $self->exists($jid);
560
561    my @resources = $self->resources($jid);
562
563    return ($#resources > -1);
564}
565
566
567##############################################################################
568#
569# priority - return the highest priority for the jid, or for the specified
570#            resource.
571#
572##############################################################################
573sub priority
574{
575    my $self = shift;
576    my $jid = shift;
577    my $resource = shift;
578
579    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
580   
581    if (defined($resource))
582    {
583        return unless $self->resourceExists($jid,$resource);
584        return unless exists($self->{JIDS}->{$jid}->{resources}->{$resource}->{priority});
585        return $self->{JIDS}->{$jid}->{resources}->{$resource}->{priority};
586    }
587   
588    return unless exists($self->{JIDS}->{$jid}->{priorities});
589    my @priorities = sort{ $b <=> $a } keys(%{$self->{JIDS}->{$jid}->{priorities}});
590    return $priorities[0];
591}
592
593
594##############################################################################
595#
596# query - allows you to get one of the pieces of info from the Roster DB.
597#
598##############################################################################
599sub query
600{
601    my $self = shift;
602    my $jid = shift;
603    my $key = shift;
604
605    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
606   
607    return unless $self->exists($jid);
608    if (defined($key))
609    {
610        return unless exists($self->{JIDS}->{$jid}->{$key});
611        return $self->{JIDS}->{$jid}->{$key};
612    }
613    return %{$self->{JIDS}->{$jid}};
614}
615
616
617##############################################################################
618#
619# remove - removes the JID from the Roster DB.
620#
621##############################################################################
622sub remove
623{
624    my $self = shift;
625    my $jid = shift;
626
627    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
628
629    if ($self->exists($jid))
630    {
631        $self->{CONNECTION}->{DEBUG}->Log3("Roster::remove: deleting $jid from the DB");
632       
633        if (defined($self->query($jid,"groups")))
634        {
635            foreach my $group (@{$self->query($jid,"groups")})
636            {
637                delete($self->{GROUPS}->{$group}->{$jid});
638                delete($self->{GROUPS}->{$group})
639                    if (scalar(keys(%{$self->{GROUPS}->{$group}})) == 0);
640                delete($self->{GROUPS})
641                    if (scalar(keys(%{$self->{GROUPS}})) == 0);
642            }
643        }
644   
645        delete($self->{JIDS}->{$jid});
646        delete($self->{JIDS}) if (scalar(keys(%{$self->{JIDS}})) == 0);
647    }
648}
649
650
651##############################################################################
652#
653# removeResource - removes the resource from the JID from the Roster DB.
654#
655##############################################################################
656sub removeResource
657{
658    my $self = shift;
659    my $jid = shift;
660    my $resource = shift;
661
662    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
663
664    if ($self->resourceExists($jid,$resource))
665    {
666        $self->{CONNECTION}->{DEBUG}->Log3("Roster::removeResource: remove $jid/$resource from the DB");
667
668        my $oldPriority = $self->priority($jid,$resource);
669        $oldPriority = "" unless defined($oldPriority);
670
671        if (exists($self->{JIDS}->{$jid}->{priorities}->{$oldPriority}))
672        {
673            my $loc = 0;
674            foreach my $index (0..$#{$self->{JIDS}->{$jid}->{priorities}->{$oldPriority}})
675            {
676                $loc = $index
677                    if ($self->{JIDS}->{$jid}->{priorities}->{$oldPriority}->[$index]->{resource} eq $resource);
678            }
679           
680            splice(@{$self->{JIDS}->{$jid}->{priorities}->{$oldPriority}},$loc,1);
681
682            delete($self->{JIDS}->{$jid}->{priorities}->{$oldPriority})
683                if (exists($self->{JIDS}->{$jid}->{priorities}->{$oldPriority}) &&
684                    ($#{$self->{JIDS}->{$jid}->{priorities}->{$oldPriority}} == -1));
685        }
686
687        delete($self->{JIDS}->{$jid}->{resources}->{$resource});
688
689    }
690}
691
692
693###############################################################################
694#
695# resource - retrieve the resource with the highest priority.
696#
697###############################################################################
698sub resource
699{
700    my $self = shift;
701    my $jid = shift;
702
703    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
704
705    return unless $self->exists($jid);
706
707    my $priority = $self->priority($jid);
708
709    return unless defined($priority);
710
711    return $self->{JIDS}->{$jid}->{priorities}->{$priority}->[0]->{resource};
712}
713
714
715##############################################################################
716#
717# resourceExists - check that the specified resource exists.
718#
719##############################################################################
720sub resourceExists
721{
722    my $self = shift;
723    my $jid = shift;
724    my $resource = shift;
725   
726    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
727
728    return unless $self->exists($jid);
729    return unless exists($self->{JIDS}->{$jid}->{resources});
730    return unless exists($self->{JIDS}->{$jid}->{resources}->{$resource});
731}
732
733
734##############################################################################
735#
736# resourceQuery - allows you to get one of the pieces of info from the Roster
737#                 DB.
738#
739##############################################################################
740sub resourceQuery
741{
742    my $self = shift;
743    my $jid = shift;
744    my $resource = shift;
745    my $key = shift;
746
747    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
748   
749    return unless $self->resourceExists($jid,$resource);
750    if (defined($key))
751    {
752        return unless exists($self->{JIDS}->{$jid}->{resources}->{$resource}->{$key});
753        return $self->{JIDS}->{$jid}->{resources}->{$resource}->{$key};
754    }
755    return %{$self->{JIDS}->{$jid}->{resources}->{$resource};}
756}
757
758
759###############################################################################
760#
761# resources - returns a list of the resources from highest priority to lowest.
762#
763###############################################################################
764sub resources
765{
766    my $self = shift;
767    my $jid = shift;
768
769    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
770
771    return () unless $self->exists($jid);
772
773    my @resources;
774
775    foreach my $priority (sort {$b cmp $a} keys(%{$self->{JIDS}->{$jid}->{priorities}}))
776    {
777        foreach my $index (0..$#{$self->{JIDS}->{$jid}->{priorities}->{$priority}})
778        {
779            next if ($self->{JIDS}->{$jid}->{priorities}->{$priority}->[$index]->{resource} eq " ");
780            push(@resources,$self->{JIDS}->{$jid}->{priorities}->{$priority}->[$index]->{resource});
781        }
782    }
783    return @resources;
784}
785
786
787##############################################################################
788#
789# resourceStore - allows you to store anything on the item that you want to.
790#                 The only drawback is that when the item is removed, the data
791#                 is not kept.  You must restore it in the DB.
792#
793##############################################################################
794sub resourceStore
795{
796    my $self = shift;
797    my $jid = shift;
798    my $resource = shift;
799    my $key = shift;
800    my $value = shift;
801
802    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
803
804    return unless defined($key);
805    return unless defined($value);
806    return unless $self->resourceExists($jid,$resource);
807
808    $self->{JIDS}->{$jid}->{resources}->{$resource}->{$key} = $value;
809}
810
811
812##############################################################################
813#
814# store - allows you to store anything on the item that you want to.  The
815#         only drawback is that when the item is removed, the data is not
816#         kept.  You must restore it in the DB.
817#
818##############################################################################
819sub store
820{
821    my $self = shift;
822    my $jid = shift;
823    my $key = shift;
824    my $value = shift;
825
826    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
827
828    return unless defined($key);
829    return unless defined($value);
830    return unless $self->exists($jid);
831
832    $self->{JIDS}->{$jid}->{$key} = $value;
833}
834
835
8361;
837
Note: See TracBrowser for help on using the repository browser.