root/branches/release-29/lib/MT/Author.pm @ 1333

Revision 1333, 23.5 kB (checked in by takayama, 22 months ago)

Fixed BugId:65812
* Changed scheme_version to 4.0037
* Added basename column to MT_Author

  • Assigning basename when author saved

* Changed to use MTAuthorBasename instead of MTAuthorDisplayName

  • Property svn:keywords set to Author Date Id Revision
Line 
1# Movable Type (r) Open Source (C) 2001-2008 Six Apart, Ltd.
2# This program is distributed under the terms of the
3# GNU General Public License, version 2.
4#
5# $Id$
6
7package MT::Author;
8
9use strict;
10use base qw( MT::Object MT::Scorable );
11
12__PACKAGE__->install_properties({
13    column_defs => {
14        'id' => 'integer not null auto_increment',
15        'name' => 'string(255) not null',
16        'nickname' => 'string(255)',
17        'password' => 'string(60) not null',
18        'type' => 'smallint not null',
19        'email' => 'string(75)',
20        'url' => 'string(255)',
21        'hint' => 'string(75)',
22        'public_key' => 'text',
23        'preferred_language' => 'string(50)',
24        'api_password' => 'string(60)',
25        'remote_auth_username' => 'string(50)',
26        'remote_auth_token' => 'string(50)',
27        'entry_prefs' => 'string(255)',
28        'text_format' => 'string(30)',
29        'status' => 'integer',
30        'external_id' => 'string(255)',
31#        'last_login' => 'datetime',
32        # deprecated; permissions are in MT::Permission only now
33        'can_create_blog' => 'boolean',
34        'is_superuser' => 'boolean',
35        'can_view_log' => 'boolean',
36        'auth_type' => 'string(255)',
37        'userpic_asset_id' => 'integer',
38        'basename' => 'string(255)',
39    },
40    defaults => {
41        type => 1,
42        status => 1,
43    },
44    indexes => {
45        created_on => 1,
46        name => 1,
47        email => 1,
48        type => 1,
49        status => 1,
50        external_id => 1,
51        auth_type => 1,
52        # is_superuser => 1,
53    },
54    meta => 1,
55    child_classes => ['MT::Permission', 'MT::Association'],
56    datasource => 'author',
57    primary_key => 'id',
58    audit => 1,
59});
60__PACKAGE__->install_meta({
61    columns => [
62        'favorite_blogs',
63        'widgets',
64    ],
65});
66
67sub class_label {
68    MT->translate("User");
69}
70
71sub class_label_plural {
72    MT->translate("Users");
73}
74
75# Valid "type" codes:
76use constant AUTHOR => 1;
77use constant COMMENTER => 2;
78
79# Commenter statuses
80use constant APPROVED => 1;
81use constant BANNED => 2;
82use constant BLOCKED => 2; # alias for BANNED for backward compatibility
83use constant PENDING => 3;
84
85# Author statuses
86use constant ACTIVE   => 1;
87use constant INACTIVE => 2;
88#use constant PENDING => 3; # there *is* PENDING status for authors but it's the same name and value.
89
90use Exporter;
91*import = \&Exporter::import;
92use vars qw(@EXPORT_OK %EXPORT_TAGS);
93@EXPORT_OK = qw(AUTHOR COMMENTER ACTIVE INACTIVE APPROVED BANNED PENDING);
94%EXPORT_TAGS = (constants => [qw(AUTHOR COMMENTER ACTIVE INACTIVE APPROVED BANNED PENDING)]);
95
96sub set_defaults {
97    my $auth = shift;
98    my $cfg = MT->config;
99    $auth->SUPER::set_defaults(@_);
100    $auth->preferred_language($cfg->DefaultUserLanguage || $cfg->DefaultLanguage);
101}
102
103sub remove_sessions {
104    my $auth = shift;
105    require MT::Session;
106    my $sess_iter = MT::Session->load_iter({ kind => 'US' });
107    my @sess;
108    while (my $sess = $sess_iter->()) {
109        my $id = $sess->get('author_id');
110        next unless $id == $auth->id;
111        push @sess, $sess;
112    }
113    $_->remove foreach @sess;
114}
115
116sub set_password {
117    my $auth = shift;
118    my($pass) = @_;
119    my @alpha = ('a'..'z', 'A'..'Z', 0..9);
120    my $salt = join '', map $alpha[rand @alpha], 1..2;
121    # FIXME: use something besides 'crypt'
122    $auth->column('password', crypt $pass, $salt);
123}
124
125sub is_valid_password {
126    my $author = shift;
127    my($pass, $crypted, $error_ref) = @_;
128    $pass ||= '';
129    require MT::Auth;
130    return MT::Auth->is_valid_password($author, $pass, $crypted, $error_ref);
131}
132
133sub is_email_hidden {
134    my $auth = shift;
135    return ($auth->email =~ /^[0-9a-f]{40}$/i) ? 1 : 0;
136}
137
138# Existing comments of a user are made visible only if the
139# user is coming from "pending" status.
140
141sub set_commenter_perm {
142    my $this = shift;
143    my ($blog_id, $action) = @_;
144
145    require MT::Permission;
146    my %perm_spec = (
147        author_id => $this->id(),
148        blog_id => $blog_id
149    );
150    my $perm = MT::Permission->load(\%perm_spec);
151    if (!$perm) {
152        $perm = MT::Permission->new();
153        $perm->set_values(\%perm_spec);
154    }
155    if ($action eq 'approve') {
156        $perm->remove_restrictions('comment');
157        $perm->can_comment(1) if COMMENTER eq $this->type;
158    } elsif (($action eq 'ban') || ($action eq 'block')) {
159        $perm->set_these_restrictions('comment');
160        $perm->can_comment(0) if COMMENTER eq $this->type;
161    } elsif ($action eq 'pending') {
162        $perm->remove_restrictions('comment');
163        $perm->can_comment(0) if COMMENTER eq $this->type;
164    }
165    $perm->save()
166        or return $this->error(MT->translate("The approval could not be committed: [_1]", $perm->errstr));
167
168    return 1;
169}
170
171sub commenter_status {
172    my $this = shift;
173    return APPROVED if $this->is_superuser;
174    my ($blog_id) = @_;
175    require MT::Permission;
176    my $perm = MT::Permission->load(
177        { author_id=>$this->id, blog_id => $blog_id } );
178    return PENDING if !$perm;
179    return BANNED if $perm->is_restricted('comment');
180    return APPROVED if $perm->can_comment() || $perm->can_manage_feedback();
181    return PENDING;
182}
183
184sub is_active { shift->status() == ACTIVE; }
185sub is_trusted { shift->commenter_status(@_) == APPROVED; }
186sub is_banned { shift->commenter_status(@_) == BANNED; }
187*is_blocked = \&is_banned;
188sub is_not_trusted { shift->commenter_status(@_) == PENDING; }
189*is_untrusted = \&is_not_trusted;
190
191sub approve {
192    my $this = shift;
193    my ($blog_id) = @_;
194    $this->set_commenter_perm($blog_id, 'approve');
195}
196
197*trust = \&approve;
198
199sub pending {
200    $_[0]->set_commenter_perm($_[1], 'pending');
201}
202
203sub ban {
204    my $this = shift;
205    my ($blog_id) = @_;
206    $this->set_commenter_perm($blog_id, 'ban');
207}
208*block = \&ban;
209
210sub save {
211    my $auth = shift;
212
213    if ($auth->type == AUTHOR) {
214        if (!$auth->id) {
215            # New author, undefined API password. Generate one.
216            if (!defined $auth->api_password) {
217                my @pool = ('a'..'z', 0..9);
218                my $pass = '';
219                for (1..8) { $pass .= $pool[ rand @pool ] }
220                $auth->api_password($pass);
221            }
222        }
223        # Generate basename
224        my $basename = MT::Util::make_unique_author_basename($auth);
225        $auth->basename($basename);
226    }
227
228    my $privs;
229    if (exists $auth->permissions(0)->{changed_cols}->{permissions}) {
230         $privs = $auth->permissions(0)->permissions;
231    }
232    # delete new user's privilege from cache
233    delete MT::Request->instance->{__stash}->{'__perm_author_'} unless $auth->id;
234    $auth->SUPER::save(@_) or return $auth->error($auth->errstr);
235    if (defined $privs) {
236        my $perm = $auth->permissions(0);
237        $perm->permissions($privs);
238        $perm->save or return $auth->error("Error saving permission: " . $perm->errstr);
239    }
240    1;
241}
242
243sub remove {
244    my $auth = shift;
245    $auth->remove_sessions if ref $auth;
246    $auth->remove_children({ key => 'author_id' }) or return;
247    $auth->SUPER::remove(@_);
248}
249
250sub can_edit_entry {
251    my $author = shift;
252    die unless $author->isa('MT::Author');
253    return 1 if $author->is_superuser();
254    my($entry) = @_;
255    unless (ref $entry) {
256        require MT::Entry;
257        $entry = MT::Entry->load($entry);
258    }
259    die unless $entry->isa('MT::Entry');
260    my $perms = $author->permissions($entry->blog_id);
261    die unless $perms->isa('MT::Permission');
262    $perms->can_edit_all_posts ||
263    ($perms->can_create_post && $entry->author_id == $author->id);
264}
265
266sub is_superuser {
267    my $author = shift;
268    if (@_) {
269        $author->permissions(0)->can_administer(@_);
270        if ($_[0]) {
271            $author->permissions(0)->can_create_blog(@_);
272            $author->permissions(0)->can_view_log(@_);
273            $author->permissions(0)->can_manage_plugins(@_);
274            $author->permissions(0)->can_edit_templates(@_);
275        }
276    } else {
277        $author->permissions(0)->can_administer() ||
278            $author->SUPER::is_superuser();
279    }
280}
281
282sub can_create_blog {
283    my $author = shift;
284    if (@_) {
285        $author->permissions(0)->can_create_blog(@_);
286    } else {
287        $author->is_superuser() ||
288            $author->permissions(0)->can_create_blog(@_);
289    }
290}
291
292sub can_view_log {
293    my $author = shift;
294    if (@_) {
295        $author->permissions(0)->can_view_log(@_);
296    } else {
297        $author->is_superuser() ||
298            $author->permissions(0)->can_view_log(@_);
299    }
300}
301
302sub can_manage_plugins {
303    my $author = shift;
304    if (@_) {
305        $author->permissions(0)->can_manage_plugins(@_);
306    } else {
307        $author->is_superuser() ||
308            $author->permissions(0)->can_manage_plugins(@_);
309    }
310}
311
312sub can_edit_templates {
313    my $author = shift;
314    if (@_) {
315        $author->permissions(0)->can_edit_templates(@_);
316    } else {
317        $author->is_superuser() ||
318            $author->permissions(0)->can_edit_templates(@_);
319    }
320}
321
322sub blog_perm {
323    my $author = shift;
324    my ($blog_id) = @_;
325    $author->permissions($blog_id);
326}
327
328sub permissions {
329    my $author = shift;
330    my ($obj) = @_;
331    my $blog_id = $obj;
332
333    my $terms = { author_id => $author->id };
334    my $cache_key = "__perm_author_" . (defined($author->id) ? $author->id : q());
335    if ($obj) {
336        if ((ref $obj) && $obj->isa('MT::Blog')) {
337            $blog_id = $obj->id;
338        } elsif ($obj) {
339            $blog_id = $obj;
340            require MT::Blog;
341            $obj = MT::Blog->load($blog_id);
342        }
343        $cache_key .= "_blog_$blog_id";
344        $terms->{blog_id} = [ 0, $blog_id ];
345    } else {
346        $terms->{blog_id} = 0;
347    }
348
349    require MT::Request;
350    my $r = MT::Request->instance;
351    my $p = $r->stash($cache_key);
352    return $p if $p;
353
354    require MT::Permission;
355    my @perm = MT::Permission->load($terms);
356    my $perm;
357    if ($obj) {
358        if (@perm == 2) {
359            if (!$perm[0]->blog_id) {
360                @perm = reverse @perm;
361            }
362            ($perm, my $sys_perm) = @perm;
363            $perm->add_permission($sys_perm);
364        } elsif (@perm == 1) {
365            $perm = $perm[0];
366            if (!$perm->blog_id) {
367                $perm->blog_id($obj->id);
368                delete $perm->{column_values}->{id};
369                delete $perm->{changed_cols}->{id};
370            }
371        } elsif (@perm) {
372            die "invalid permissions for author " . $author->id;
373        }
374    } else {
375        $perm = $perm[0] if @perm;
376    }
377    unless (@perm) {
378        if ($blog_id || !@_) {
379            if ($author->is_superuser()) {
380                $perm = new MT::Permission;
381                $perm->author_id($author->id);
382                $perm->set_full_permissions;
383            }
384        }
385    }
386    unless ($perm) {
387        $perm = new MT::Permission;
388        $perm->author_id($author->id);
389        $perm->clear_full_permissions;
390    }
391    $r->stash($cache_key, $perm);
392    $perm;
393}
394
395sub common_blogs { # returns the blogs in the form of permission records of $this
396    die "This was removed";        # FIXME: this is to catch mistakes
397}
398sub can_administer {
399    die "This was removed";        # FIXME: this is to catch mistakes
400}
401
402sub entry_prefs {
403    my $author = shift;
404    my @prefs = split /,/, ($author->column('entry_prefs') || '');
405    my %prefs;
406    foreach (@prefs) {
407        my ($name, $value) = split /=/, $_, 2;
408        $prefs{$name} = $value;
409    }
410    if (@_) {
411        %prefs = (%prefs, @_);
412        my $pref = '';
413        foreach (keys %prefs) {
414            $pref .= ',' if $pref ne '';
415            $pref .= $_ . '=' . $prefs{$_};
416        }
417        $author->column('entry_prefs', $pref);
418    }
419
420    # default assignments for author entry preferences
421    $prefs{tag_delim} ||= MT->config->DefaultUserTagDelimiter;
422
423    \%prefs;
424}
425
426sub role_iter {
427    my $author = shift;
428    my ($terms, $args) = @_;
429    require MT::Association;
430    require MT::Role;
431    my $blog_id = delete $terms->{blog_id};
432    my $type;
433    if ($blog_id) {
434        $type = MT::Association::USER_BLOG_ROLE();
435    } else {
436        $type = MT::Association::USER_ROLE();
437    }
438    $args->{join} = MT::Association->join_on('role_id', {
439        type => $type,
440        author_id => $author->id,
441        $blog_id ? (blog_id => $blog_id) : (blog_id => 0),
442    });
443    MT::Role->load_iter($terms, $args);
444}
445
446sub blog_iter {
447    my $author = shift;
448    my ($terms, $args) = @_;
449    my $perm = $author->permissions;
450    if (!$author->is_superuser) {
451        require MT::Permission;
452        $args->{join} = MT::Permission->join_on('blog_id', {
453            author_id => $author->id,
454        });
455    }
456    require MT::Blog;
457    my $i = MT::Blog->load_iter($terms, $args);
458}
459
460sub group_iter {
461    my $author = shift;
462    my ($terms, $args) = @_;
463    my $grp_class = MT->model('group') or return undef;
464    require MT::Association;
465    $args->{join} = MT::Association->join_on('group_id', {
466        type => MT::Association::USER_GROUP(),
467        author_id => $author->id,
468    });
469    return $grp_class->load_iter($terms, $args);
470}
471
472sub group_role_iter {
473    my $author = shift;
474    my ($terms, $args) = @_;
475
476    my $grp_class = MT->model('group')
477        or return undef;
478    my @iters;
479    require MT::Association;
480    require MT::Role;
481    my $blog_id = delete $terms->{blog_id};
482    $args->{join} = MT::Association->join_on('role_id', {
483        type => $blog_id ? MT::Association::USER_BLOG_ROLE() : MT::Association::USER_ROLE(),
484        author_id => $author->id,
485        $blog_id ? (blog_id => $blog_id) : (),
486    });
487    my $user_iter = MT::Role->load_iter($terms, $args);
488    push @iters, $user_iter if $user_iter;
489
490    my @groups;
491    if (my $group_iter = $author->group_iter({ status => MT::Group::ACTIVE() })) {
492        while (my $g = $group_iter->()) {
493            push @groups, $g->id;
494        }
495    }
496    if (@groups) {
497        $args->{join} = MT::Association->join_on('role_id', {
498            type => $blog_id ? MT::Association::GROUP_BLOG_ROLE() : MT::Association::GROUP_ROLE(),
499            group_id => \@groups,
500            $blog_id ? (blog_id => $blog_id) : (),
501        });
502        my $group_iter = MT::Role->load_iter($terms, $args);
503        push @iters, $group_iter if $group_iter;
504    }
505    MT::Util::multi_iter(\@iters);
506}
507
508sub add_role {
509    my $author = shift;
510    my ($role, $blog) = @_;
511    $author->save unless $author->id;
512    $role->save unless $role->id;
513    $blog->save if $blog && !$blog->id;
514    require MT::Association;
515    MT::Association->link($author, @_);
516}
517
518sub add_group {
519    my $author = shift;
520    my ($group) = @_;
521    $author->save unless $author->id;
522    $group->save unless $group->id;
523    require MT::Association;
524    MT::Association->link($author, @_);
525}
526
527sub remove_role {
528    my $author = shift;
529    require MT::Association;
530    MT::Association->unlink($author, @_);
531}
532
533sub remove_group {
534    my $author = shift;
535    require MT::Association;
536    MT::Association->unlink($author, @_);
537}
538
539sub add_default_roles {
540    my $author = shift;
541    my $def = MT->config->DefaultAssignments;
542    return unless $def;
543
544    my $blog_class = MT->model('blog');
545    my $role_class = MT->model('role');
546
547    require MT::Association;
548    my @def = split ',', $def;
549    while (my $role_id = shift @def) {
550        my $blog_id = shift @def;
551        next unless $role_id && $blog_id;
552        my $blog = $blog_class->load($blog_id);
553        my $role = $role_class->load($role_id);
554        next unless ref $blog && ref $role;
555        MT::Association->link($author => $role => $blog);
556    }
557}
558
559sub to_hash {
560    my $author = shift;
561    my $hash = $author->SUPER::to_hash(@_);
562    my $app = MT->instance;
563    my $blog = $app->blog if $app->can('blog');
564    if ($blog) {
565        require MT::Permission;
566        if (my $perms = MT::Permission->load({ author_id => $author->id, blog_id => $blog->id })) {
567            my $perms_hash = $perms->to_hash;
568            $hash->{"author.$_"} = $perms_hash->{$_} foreach keys %$perms_hash;
569        }
570    }
571    $hash;
572}
573
574sub group_count {
575    my $author = shift;
576    require MT::Association;
577    MT::Association->count({
578        type => MT::Association::USER_GROUP(),
579        author_id => $author->id,
580    });
581}
582
583sub external_id {
584    my $author = shift;
585    if (@_) {
586        return $author->SUPER::external_id($author->unpack_external_id(@_));
587    }
588    my $value = $author->SUPER::external_id;
589    $value = $author->pack_external_id($value) if $value;
590}
591
592sub load {
593    my $author = shift;
594    my ($terms, $args) = @_;
595    if ((ref($terms) eq 'HASH') && exists($terms->{external_id})) {
596        $terms->{external_id} = $author->unpack_external_id($terms->{external_id});
597    }
598    $author->SUPER::load($terms, $args);
599}
600
601sub load_iter {
602    my $author = shift;
603    my ($terms, $args) = @_;
604    if ((ref($terms) eq 'HASH') && exists($terms->{external_id})) {
605        $terms->{external_id} = $author->unpack_external_id($terms->{external_id});
606    }
607    $author->SUPER::load_iter($terms, $args);
608}
609
610sub pack_external_id { return pack('H*', $_[1]); }
611sub unpack_external_id { return unpack('H*', $_[1]); }
612
613sub auth_icon_url {
614    my $author = shift;
615    my ($size) = @_;
616    $size ||= 'logo_small';
617
618    my $app = MT->instance;
619    my $static_path = $app->static_path;
620
621    my $auth_type = $author->auth_type;
622    return q() unless $auth_type;
623
624    if ( $author->type == MT::Author::AUTHOR() ) {
625        return $static_path . 'images/comment/mt_logo.png' ;
626    }
627   
628    my $authenticator = MT->commenter_authenticator( $auth_type );
629    return q() unless $authenticator;
630    return q() unless exists $authenticator->{$size};
631
632    my $logo = $authenticator->{$size};
633    if ( ( $logo !~ m!^https?://! ) || ( $logo !~ m!^/! ) ) {
634        $logo = $static_path . $logo;
635    }
636    return $logo;
637}
638
639sub userpic {
640    my $author = shift;
641
642    my $asset_id = $author->userpic_asset_id or return;
643    require MT::Asset;
644    my $asset = MT->model('asset.image')->load($asset_id) or return;
645
646    $asset;
647}
648
649sub userpic_thumbnail_options {
650    my $author = shift;
651
652    # Specify these to put an author's userpic thumbnail in a consistent
653    # place whenever userpic_url is called as an instance method on a
654    # particular author.
655    my %real_userpic_options = (
656        Path   => File::Spec->catdir( MT->config->AssetCacheDir, 'userpics' ),
657        Format => MT->translate('userpic-[_1]-%wx%h%x', $author->id),
658    ) if ref $author;
659
660    my $cfg = MT->config;
661    my $max_dim = $cfg->UserpicThumbnailSize;
662    my $square  = $cfg->UserpicAllowRect ? 0 : 1;
663    return (
664        Width  => $max_dim,
665        Height => $max_dim,
666        Square => $square,
667        Type   => 'png',
668        %real_userpic_options,
669    );
670}
671
672sub userpic_file {
673    my $author = shift;
674
675    my $asset = $author->userpic;
676    if (!$asset) {
677        $asset = MT->model('asset.image')->new;
678        $asset->file_name('userpic');
679    }
680
681    my %thumb_param = $author->userpic_thumbnail_options();
682    my $thumb_file = File::Spec->catfile(
683        $asset->thumbnail_path(%thumb_param),
684        $asset->thumbnail_filename(%thumb_param),
685    );
686
687    return $thumb_file;
688}
689
690sub userpic_url {
691    my $author = shift;
692    my (%param) = @_;
693
694    my $asset = delete $param{Asset};
695    if (!$asset && ref $author) {
696        $asset = $author->userpic;
697    }
698    return if !$asset;
699
700    my @info = $asset->thumbnail_url(
701        $author->userpic_thumbnail_options(),
702        %param,
703    );
704    return wantarray ? @info : $info[0];
705}
706
707sub userpic_html {
708    my $author = shift;
709    my ($thumb_url, $w, $h) = $author->userpic_url(@_) or return;
710    return unless $thumb_url;
711    sprintf q{<img src="%s" width="%d" height="%d" alt="" />},
712        MT::Util::encode_html($thumb_url), $w, $h;
713}
714
7151;
716
717__END__
718
719=head1 NAME
720
721MT::Author - Movable Type author record
722
723=head1 SYNOPSIS
724
725    use MT::Author;
726    my $author = MT::Author->new;
727    $author->name('Foo Bar');
728    $author->set_password('secret');
729    $author->save
730        or die $author->errstr;
731
732    my $author = MT::Author->load($author_id);
733
734=head1 DESCRIPTION
735
736An I<MT::Author> object represents a user in the Movable Type system. It
737contains profile information (name, nickname, email address, etc.), global
738permissions settings (blog creation, activity log viewing), and authentication
739information (password, public key). It does not contain any per-blog
740permissions settings--for those, look at the I<MT::Permission> object.
741
742=head1 USAGE
743
744As a subclass of I<MT::Object>, I<MT::Author> inherits all of the
745data-management and -storage methods from that class; thus you should look
746at the I<MT::Object> documentation for details about creating a new object,
747loading an existing object, saving an object, etc.
748
749The following methods are unique to the I<MT::Author> interface:
750
751=head2 $author->set_password($pass)
752
753One-way encrypts I<$pass> with a randomly-generated salt, using the Unix
754I<crypt> function, and sets the I<password> data field in the I<MT::Author>
755object I<$author>.
756
757Because the password is one-way encrypted, there is B<no way> of recovering
758the initial password.
759
760=head2 $author->is_valid_password($check_pass)
761
762Tests whether I<$check_pass> is a valid password for the I<MT::Author> object
763I<$author> (ie, whether it matches the password originally set using
764I<set_password>). This check is done by one-way encrypting I<$check_pass>,
765using the same salt used to encrypt the original password, then comparing the
766two encrypted strings for equality.
767
768=head1 DATA ACCESS METHODS
769
770The I<MT::Author> object holds the following pieces of data. These fields can
771be accessed and set using the standard data access methods described in the
772I<MT::Object> documentation.
773
774=over 4
775
776=item * id
777
778The numeric ID of the author.
779
780=item * name
781
782The username of the author. This is the username used to log in to the system.
783
784=item * nickname
785
786The author nickname (or "display" name). This is the preferred name used for publishing the author's name.
787
788=item * password
789
790The author's password, one-way encrypted. If you wish to check the validity of
791a password, you should use the I<is_valid_password> method, above.
792
793=item * type
794
795The type of author record. Currently, MT stores authenticated commenters in the author table. The type column can be one of AUTHOR or COMMENTER (constants defined in this package).
796
797=item * status
798
799A column that defines whether the records of an AUTHOR type are ACTIVE, INACTIVE or PENDING (constants declared in this package).
800
801=item * commenter_status
802
803This method requires a blog id to be passed as the argument and a value of APPROVED, BANNED or PENDING (constants declared in this package) is returned.
804
805=item * email
806
807The author's email address.
808
809=item * url
810
811The author's homepage URL.
812
813=item * hint
814
815The answer to the question used when recovering the user's password.
816
817=item * external_id
818
819A column for holding a value used to synchronize the MT author record with an external record.
820
821=item * can_create_blog
822
823A boolean flag specifying whether the author has permission to create a new
824blog in the system.
825
826=item * can_view_log
827
828A boolean flag specifying whether the author has permission to view the global
829system activity log.
830
831=item * created_by
832
833The author ID of the author who created this author. If the author was created by a process where no user was logged in to Movable Type, the created_by column will be empty.
834
835=item * public_key
836
837The author's ASCII-armoured public key, to be used in the future for verifying
838incoming email messages.
839
840=back
841
842=head1 DATA LOOKUP
843
844In addition to numeric ID lookup, you can look up or sort records by any
845combination of the following fields. See the I<load> documentation in
846I<MT::Object> for more information.
847
848=over 4
849
850=item * name
851
852=item * email
853
854=back
855
856=head1 NOTES
857
858=over 4
859
860=item *
861
862When you remove an author using I<MT::Author::remove>, in addition to removing
863the author record, all of the author's permissions (I<MT::Permission> objects)
864will be removed, as well.
865
866=back
867
868=head1 AUTHOR & COPYRIGHTS
869
870Please see the I<MT> manpage for author, copyright, and license information.
871
872=cut
Note: See TracBrowser for help on using the browser.