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

Revision 1344, 23.5 kB (checked in by mpaschal, 22 months ago)

Index plz

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