root/trunk/iMT/plugins/iMT/iMT.pl @ 695

Revision 695, 6.9 kB (checked in by bchoate, 18 months ago)

Added CHANGES.txt; updated version and readme.

  • Property svn:executable set to *
  • Property svn:keywords set to Id Revision
Line 
1# Copyright 2007 Six Apart. This code cannot be redistributed without
2# permission from www.sixapart.com.  For more information, consult your
3# Movable Type license.
4#
5# $Id$
6
7package MT::Plugin::iMT;
8
9use MT 4;
10use base qw( MT::Plugin );
11
12my $enabled = 0;
13our $VERSION = '1.02';
14my $plugin = __PACKAGE__->new({
15    name        => "iPhone / iPod touch UI Support",
16    author_name => "<a href='http://www.iwalt.com/'>Walt Dickinson</a>, <a href='http://bradchoate.com/'>Brad Choate</a>",
17    description => "Provides an iPhone and iPod touch-friendly UI for Movable Type. Once enabled, navigate to your MT installation from your iPhone (or iPod touch) to use this interface.",
18    version     => $VERSION,
19    registry => {
20        applications => {
21            cms => {
22                methods => {
23                    iphone_main => \&iphone_main,
24                    edit_entry => \&iphone_edit_entry,
25                    edit_comment => \&iphone_edit_comment,
26                    delete_confirm => \&iphone_delete_confirm,
27                    set_comment_status => \&iphone_set_comment_status,
28                    view => \&iphone_view,
29                    # save_entry => \&iphone_save_entry,
30                },
31            },
32        },
33        callbacks => {
34            template_param => \&page_param,
35            'template_param.list_comment' => \&iphone_list_comment_param,
36        },
37    },
38});
39MT->add_plugin($plugin);
40
41sub iphone_list_comment_param {
42    return unless $enabled;
43    my $cb = shift;
44    my ($app, $param, $tmpl) = @_;
45
46    if (my $pager_json = $param->{'pager_json'}) {
47        # Fix parameters for pagination of comments (app listing method
48        # no longer provides these, but populates a json value that is
49        # handled by a javascript routine to display pagination in MT4).
50        require JSON;
51        my $pager = JSON::jsonToObj($pager_json);
52        my $offset = $pager->{offset};
53        my $limit = $pager->{limit};
54        if ($offset) {
55            $param->{prev_offset}     = 1;
56            $param->{prev_offset_val} = $offset - $limit;
57            $param->{prev_offset_val} = 0 if $param{prev_offset_val} < 0;
58        }
59        my $next_offset = ( $offset || 0 ) + $limit;
60        if ($next_offset < $pager->{listTotal}) {
61            $param->{next_offset}     = 1;
62            $param->{next_offset_val} = $next_offset;
63        }
64    }
65}
66
67sub init_request {
68    my $plugin = shift;
69    my ($app) = @_;
70
71    $enabled = 0;
72
73    # user agent test; if iPhone and CMS app, switch template directory
74    if ($app->isa('MT::App::CMS')) {
75        # A bit of User Agent sniffing to determine if MT should
76        # be using our AppleWebKit mobile interface.
77        # Using keyword detection provided by Apple:
78        #    http://trac.webkit.org/projects/webkit/wiki/DetectingWebKit
79        if (my $ua = $ENV{HTTP_USER_AGENT}) {
80            if ((( $ua =~ m!AppleWebKit/! ) && ( $ua =~ m!Mobile/! )) ||
81                 ( $ua =~ m!Opera Mini/!)) {
82                $enabled = 1;
83
84                # Redirect 'dashboard' or 'default' modes to iphone_main
85                $app->mode('iphone_main')
86                    if ($app->mode eq 'default') || ($app->mode eq 'dashboard');
87
88                $app->config('AltTemplatePath', $plugin->path . '/tmpl');
89            }
90        }
91    }
92}
93
94sub iphone_view {
95    my $app = shift;
96    if ($enabled && ($app->param('_type') eq 'entry')) {
97        # We replace the 'view' mode since after saving an entry,
98        # we get redirected back to a view mode.
99        return iphone_edit_entry($app, @_);
100    }
101    else {
102        return undef;
103    }
104}
105
106sub iphone_main {
107    my $app = shift;
108    my $param = {};
109    $param->{blog_id} = $app->param('blog_id');
110    $app->build_blog_selector($param);
111    my $blog_loop = $param->{top_blog_loop} || [];
112    foreach (@$blog_loop) {
113        $_->{blog_name} = $_->{top_blog_name};
114        $_->{blog_id} = $_->{top_blog_id};
115    }
116    $param->{blogs} = $blog_loop;
117    $param->{user_has_weblog} = 1 if @$blog_loop;
118    $app->load_tmpl('main.tmpl', $param);
119}
120
121sub iphone_set_comment_status {
122    my $app = shift;
123    my $id = $app->param('id');
124    my $blog_id = $app->param('blog_id');
125    $app->param('_type', 'comment');
126    $app->return_args('__mode=list_comments&id=' . $id . '&blog_id=' . $blog_id);
127    my $status = $app->param('status');
128    if ( $status eq 'delete' ) {
129        return $app->delete();
130    }
131    elsif ( $status eq 'junk' ) {
132        return $app->handle_junk();
133    }
134    elsif ( $status eq '2' ) {
135        return $app->approve_item();
136    }
137    else {
138        return $app->unapprove_item();
139    }
140}
141
142sub iphone_delete_confirm {
143    my $app = shift;
144
145    my $blog_id = $app->param('blog_id');
146    my $type = $app->param('_type') || 'entry';
147    my $param = {
148        blog_id => $blog_id,
149        id => $app->param('id'),
150        type => $type,
151        return => 'edit_entry',
152        id_loop => [ $app->param('id') ],
153        script_parent_url => $app->uri,
154    };
155    return $app->build_page('delete_confirm.tmpl', $param);
156}
157
158sub iphone_edit_comment {
159    my $app = shift;
160    $app->param('_type', 'comment');
161    return $app->edit_object();
162}
163
164# sub iphone_save_entry {
165#     my $app = shift;
166#     return $app->save_entry(@_) unless $enabled;
167#
168#     if ($app->param('preview_entry')) {
169#         return $app->preview_entry(@_);
170#     }
171#     return $app->save_entry(@_);
172# }
173
174sub iphone_edit_entry {
175    my $app = shift;
176
177    $app->param('_type', 'entry');
178    my $tmpl = $app->edit_object();
179
180    my $sel_cats = $tmpl->param('selected_category_loop') || [];
181    my @cat_loop;
182    my $curr_cats = '';
183    my $curr_cat_ids = '';
184    my %selected;
185    foreach my $sel (@$sel_cats) {
186        my $cat = MT::Category->load($sel) or next;
187        $curr_cats .= ', ' if $curr_cats ne '';
188        $curr_cat_ids .= ',' if $curr_cat_ids ne '';
189        $curr_cats .= $cat->label;
190        $curr_cat_ids .= $cat->id;
191        $selected{$cat->id} = 1;
192    }
193
194    my $c_data = $app->_build_category_list(
195        blog_id => $app->blog->id,
196        type    => 'category',
197    );
198    for my $row (@$c_data) {
199        my $spacer = $row->{category_label_spacer} || '';
200        push @cat_loop, {
201            category_id => $row->{category_id},
202            category_label => $spacer . MT::Util::encode_html($row->{category_label}),
203            category_is_selected => $selected{$row->{category_id}} ? 1 : 0,
204        };
205    }
206    $tmpl->param('category_loop', \@cat_loop);
207    $tmpl->param('current_categories', $curr_cats);
208    $tmpl->param('current_category_ids', $curr_cat_ids);
209    return $tmpl;
210}
211
212sub page_param {
213    return unless $enabled;
214
215    my $cb = shift;
216    my ($app, $param, $tmpl) = @_;
217    $param->{portal_label} = MT->translate("Movable Type");
218    $param->{user_id} = $app->user && $app->user->id;
219    $param->{script_base_url} = $param->{script_parent_url} = $app->uri;
220    $param->{page_mode} = $app->mode;
221    $param->{static_uri} = $app->static_path . $plugin->{envelope} . '/';
222}
223
2241;
Note: See TracBrowser for help on using the browser.