root/branches/release-36/plugins/WidgetManager/lib/WidgetManager/CMS.pm @ 2047

Revision 2047, 12.7 kB (checked in by fumiakiy, 19 months ago)

Search templates in templates listing and widgets listing. Thanks Jay Allen for the patch. BugId:79449

  • Property svn:keywords set to Id Revision
Line 
1# Widget Manager plugin for Movable Type
2# Author: Byrne Reese, Six Apart (http://www.sixapart.com)
3# Released under the Artistic License
4#
5# $Id$
6
7package WidgetManager::CMS;
8
9use strict;
10
11sub plugin {
12    return MT->component('WidgetManager');
13}
14
15sub _permission_check {
16    my $app = MT->instance;
17    return ($app->user && $app->user->blog_perm($app->param('blog_id'))->can_edit_templates);
18}
19
20sub save {
21    my $app = shift;
22
23    return $app->error($app->translate('Permission denied.'))
24        unless _permission_check();
25
26    my $q = $app->param();
27
28    my $blog_id = scalar $q->param('blog_id');
29
30    my $str = build_module_list($q->param('modules'));
31
32    # Load the current widgetmanager data
33    my $current = $q->param('widgetmanager') || '';
34    $current = $q->param('name') if $current eq 'New Widget Manager';
35    my $modulesets = plugin()->load_selected_modules($blog_id);
36    $modulesets = {} unless $modulesets;
37
38    # delete old set
39    delete $modulesets->{$q->param('widgetmanager') || ''};
40    # Handle renaming: Delete the entry that has changed names.
41    delete $modulesets->{$q->param('old_name')}; # unless $q->param('old_name') eq $q->param('name');
42    if(exists $modulesets->{$q->param('name')}) {
43        return $app->error($app->translate(
44            "Can't duplicate the existing '[_1]' Widget Manager. Please go back and enter a unique name.",
45            $q->param('name')))
46    }
47    # add it back with a potential new name
48    $modulesets->{$q->param('name')} = $str;
49
50    plugin()->set_config_value('modulesets',$modulesets,"blog:$blog_id");
51
52    return $app->redirect( $app->uri( mode => 'list_widget', args => { blog_id => $blog_id, rebuild => 1 } ) );
53}
54
55sub delete {
56    my $app = shift;
57
58    return $app->error($app->translate('Permission denied.'))
59        unless _permission_check();
60
61    my $q = $app->param();
62    my $blog_id = scalar $q->param('blog_id');
63
64    my $modulesets = plugin()->load_selected_modules($blog_id);
65    $modulesets = {} unless $modulesets;
66
67    my @ids = $q->param('id');
68    delete $modulesets->{$_} for @ids;
69
70    plugin()->set_config_value('modulesets',$modulesets,"blog:$blog_id");
71   
72    return $app->redirect( $app->uri( mode => 'list_widget', args => { blog_id => $blog_id, deleted => 1 } ) );
73}
74
75sub edit {
76    my $app = shift;
77    my (%opt) = @_;
78
79    return $app->error($app->translate('Permission denied.'))
80        unless _permission_check();
81
82      my $q = $app->param();
83      my $blog_id = scalar $q->param('blog_id');
84
85      install_default_widgets($blog_id, 1);
86
87      my $tmpl = $app->load_tmpl('edit.tmpl');
88      $tmpl->param('blog_id'  => $blog_id);
89      $app->add_breadcrumb($app->translate('Main Menu'),$app->{mtscript_url});
90      require MT::Blog;
91      my $blog = MT::Blog->load ($blog_id);
92      $app->add_breadcrumb($blog->name, $app->mt_uri(mode => 'menu', args => { blog_id => $blog_id }));
93      $app->add_breadcrumb($app->translate('Widget Manager'),'?__mode=list_widget&blog_id='.$blog_id);
94      $app->add_breadcrumb($q->param('widgetmanager'));
95
96      my $modulesets = plugin()->load_selected_modules($blog_id);
97      $modulesets = {} unless $modulesets;
98
99      my @names = sort keys %$modulesets;
100      my $widgetmanager = $q->param('widgetmanager') || $names[0] || '';
101
102      # Find non-conflicting name for new Widget Manager
103      if ($widgetmanager eq $app->translate('New Widget Set')) { 
104          $widgetmanager = $app->translate('Widget Manager');
105          if (grep(/^\Q$widgetmanager\E$/, @names)) {
106              my $i = 1;
107              while (grep(/^\Q$widgetmanager $i\E$/, @names)) {
108                  $i++;
109              }
110              # $widgetmanager = "$widgetmanager $i";
111              $widgetmanager = "";
112          }
113      }
114
115      my @selected = exists($modulesets->{$widgetmanager})
116        ? split(/\s*,\s*/,$modulesets->{$widgetmanager})
117        : ();
118
119      my %constraints;
120      $constraints{blog_id} = $blog_id;
121      $constraints{type}    = 'widget';
122      my %options;
123      $options{sort}      = 'name';
124      $options{direction} = 'ascend';
125      require MT::Template;
126      my $iter = MT::Template->load_iter( \%constraints, \%options );
127      my @avail_modules;
128      my @inst_modules;
129      while (my $m = $iter->()) {
130          my $name = $m->name();
131          push @avail_modules, {
132            id => $m->id(),
133            name => $name,
134            selected => in_array($m->id,@selected),
135          };
136      }
137      foreach my $mid (@selected) {
138          for (my $i = 0; $i <= $#avail_modules; $i++) {
139              if ($avail_modules[$i]->{id} == $mid) {
140                  push @inst_modules,$avail_modules[$i];
141                  splice(@avail_modules,$i,1);
142              }
143          }
144      }
145
146      my @widgetmanagers = map { { widgetmanager => $_ } } keys %$modulesets;
147      $tmpl->param(object_loop => \@widgetmanagers);
148      $tmpl->param(search_type  => "template");
149      $tmpl->param(search_label => MT::Template->class_label_plural);
150
151      $tmpl->param(available => \@avail_modules);
152      $tmpl->param(installed => \@inst_modules);
153      $tmpl->param(name      => $widgetmanager);
154
155      $app->{breadcrumbs}[-1]{is_last} = 1;
156      $tmpl->param(breadcrumbs       => $app->{breadcrumbs});
157      $tmpl->param(plugin_version    => $MT::Plugin::WidgetManager::VERSION);
158      $tmpl->param(rebuild           => $opt{rebuild});
159      return $app->build_page($tmpl);
160}
161
162sub list {
163    my $app = shift;
164    my (%opt) = @_;
165
166    return $app->return_to_dashboard(redirect => 1)
167        unless $app->param('blog_id');
168
169    return $app->return_to_dashboard(permission => 1)
170        unless _permission_check();
171
172      my $q = $app->param;
173      my $blog_id = int(scalar $q->param('blog_id'));
174
175      my $tmpl = $app->load_tmpl('list.tmpl');
176      $tmpl->param('blog_id'  => $blog_id);
177      $app->add_breadcrumb($app->translate("Main Menu"),$app->{mtscript_url});
178      require MT::Blog;
179      my $blog = MT::Blog->load ($blog_id);
180      $app->add_breadcrumb($blog->name,$app->mt_uri( mode => 'menu', args => { blog_id => $blog_id }));
181      $app->add_breadcrumb($app->translate("Widget Manager"));
182
183      my $modulesets = plugin()->load_selected_modules($blog_id) || {};
184
185      my (%constraints, %options);
186      $constraints{blog_id} = $blog_id;
187      $constraints{type}    = 'widget';
188      $options{sort}        = 'name';
189      $options{direction}   = 'ascend';
190
191      require MT::Template;
192      my $iter = MT::Template->load_iter( \%constraints, \%options );
193      my %avail;
194      while (my $m = $iter->()) {
195          my $name = $m->name();
196          $avail{$m->id()} = $name;
197      }
198
199      my @names = sort keys %$modulesets;
200      my $widgetmanager = $q->param('widgetmanager') || $names[0] || '';
201
202      my @widgetmanagers;
203      my @keys = sort keys %$modulesets;
204
205      my $offset = $app->param('offset') || 0;
206      $tmpl->param( list_start => $offset + 1 );
207      $tmpl->param( list_end   => $offset + scalar @keys );
208
209      foreach my $key (@keys) {
210          # Collect the available widgets for this key.
211          my @w = ();
212          for my $w ( split /\s*,\s*/, $modulesets->{$key} ) {
213              push @w, $avail{$w} if $avail{$w};
214          }
215          push @widgetmanagers,{
216            widgetmanager => $key,
217            names   => join(', ', @w),
218            widgets => $modulesets->{$key}
219          };
220    }
221    if ($widgetmanager eq 'New Widget Manager') {
222        $widgetmanager = $q->param('name');
223    }
224
225    require MT::CMS::Template;
226    my $widget_loop = MT::CMS::Template::build_template_table( $app,
227        load_args => [ { type => 'widget', blog_id => $blog_id },
228        { sort => 'name', direction => 'ascend' } ],
229    );
230    $tmpl->param('widget_table', $widget_loop);
231    $tmpl->param('blog_view', 1) if $blog_id;
232
233    $tmpl->param(object_loop  => \@widgetmanagers);
234    $tmpl->param(object_type  => "widgetset");
235    $tmpl->param(search_type  => "template");
236    $tmpl->param(search_label => MT::Template->class_label_plural);
237
238    $app->{breadcrumbs}[-1]{is_last} = 1;
239    $tmpl->param(breadcrumbs       => $app->{breadcrumbs});
240    $tmpl->param(plugin_version    => $MT::Plugin::WidgetManager::VERSION);
241    $tmpl->param(rebuild           => $app->param('rebuild') || 0);
242    $tmpl->param(deleted           => $app->param('deleted') || 0);
243    $tmpl->param(listing_screen => 1);
244    $tmpl->param(screen_id => "list-widget-set");
245
246    return $app->build_page($tmpl);
247}
248
249sub build_module_list {
250    my $str = shift;
251    my @mods = split /;/, $str;
252    my @inst;
253    for (@mods) {
254        my ($id, $col) = /(\d+)=(\d+)\.(\d+)/;
255        push @inst, $id if $col == 1;
256    }
257    return join ',', @inst;
258}
259
260sub in_array {
261    my ($needle, @haystack) = @_;
262    for (@haystack) {
263        return 1 if $_ eq $needle;
264    }
265    return 0;
266}
267
268sub install_module {
269    my($blog_id, $name, $text) = @_;
270    my $app = MT->instance;
271    require MT::Template;
272    my $tmpl = MT::Template->new;
273    $tmpl->blog_id($blog_id);
274    $tmpl->type('widget');
275    $tmpl->name($app->translate($name));
276    $tmpl->text($app->translate_templatized($text));
277    $tmpl->save;
278    return $tmpl;
279}
280
281sub create_default_widgetsets {
282    my $app = MT->instance;
283    my ($blog_id) = @_;
284
285    my ( %constraints, %options );
286    $constraints{blog_id} = $blog_id;
287    $constraints{type}    = 'widget';
288    $options{sort}        = 'name';
289    $options{direction}   = 'ascend';
290
291    require MT::Template;
292    my $iter = MT::Template->load_iter( \%constraints, \%options );
293    my %widgets;
294    while ( my $tmpl = $iter->() ) {
295        my $name = $tmpl->name();
296        $widgets{$name} = $tmpl->id();
297    }
298
299    my $widgetsets = [
300        {
301            label   => '2-column layout - Sidebar',
302            widgets => [
303                'Search',
304                'About This Page',
305                'Home Page Widgets Group',
306                'Archive Widgets Group',
307                'Page Listing',
308                'Syndication',
309                'Powered By',
310            ],
311        },
312        {
313            label   => '3-column layout - Primary Sidebar',
314            widgets => [
315                'Archive Widgets Group',
316                'Page Listing',
317                'Syndication',
318                'Powered By',
319            ],
320        },
321        {
322            label   => '3-column layout - Secondary Sidebar',
323            widgets => [
324                'Search',
325                'Home Page Widgets Group',
326                'About This Page',
327            ],
328        },
329    ];
330
331    my $modulesets = plugin()->load_selected_modules($blog_id);
332    $modulesets = {} unless $modulesets;
333
334    foreach my $widgetset ( @{$widgetsets} ) {
335        my $label = plugin()->translate( $widgetset->{label} );
336        my @ids;
337        foreach my $widget ( @{ $widgetset->{widgets} } ) {
338            my $name = plugin()->translate($widget);
339            push @ids, $widgets{$name} if $widgets{$name};
340        }
341        $modulesets->{$label} = join ',', @ids;
342    }
343
344    plugin()->set_config_value( 'modulesets', $modulesets, "blog:$blog_id" );
345}
346
347sub install_default_widgets {
348    my $app = MT->instance;
349    my ( $blog_id, $reinstall ) = @_;
350    my ($tmpl,$default_widget_templates);
351
352    # Gather the existing modules.
353    my $modules = {};
354    require MT::Template;
355    for ( MT::Template->load({ blog_id => $blog_id, type => 'widget' }) ) {
356        my $name = $_->name();
357        $modules->{$name} = $_->linked_file();  # XXX The linked_file is undef for this plugin modules for some reason.
358    }
359
360    use File::Spec;
361    my $widgets_dir = File::Spec->catfile(plugin()->{full_path}, 'default_widgets');
362    my $cfg_file = File::Spec->catfile($widgets_dir, 'widgets.cfg');
363
364    local(*FH, $_, $/);
365    $/ = "\n";
366    open FH, $cfg_file or
367        return $app->error(MT->translate(
368            "Error opening file '[_1]': [_2]", $cfg_file, "$!" ));
369    my $cfg = join('',<FH>);
370    eval "$cfg;";
371    close FH;
372
373    foreach (@$default_widget_templates) {
374        next if exists $modules->{plugin()->translate($_->{label})};
375        open(TMPL, File::Spec->catfile($widgets_dir, $_->{template})) or die "Error: $!\n";
376        while (my $line = <TMPL>) {
377            $_->{text} .= $line;
378        }
379        close TMPL;
380        $tmpl = install_module($blog_id, $_->{label}, $_->{text});
381    }
382
383    unless( $reinstall ) {
384        # Set the 'installed' bit in the config
385        installed($blog_id, 1);
386
387        # Now that the plugin is installed for this blog, create a default widget sets
388        # with all modules pre-installed.
389        create_default_widgetsets($blog_id);
390    }
391}
392
393sub installed {
394    my $config = {};
395    my $app = MT->instance;
396    my ( $blog_id, $save ) = @_;
397
398    my $plugin = plugin();
399    if ($save) {
400        # Set the installed bit, save and return
401        return $plugin->set_config_value('installed',1,"blog:$blog_id");
402    } else {
403        # Return early if status check
404        return $plugin->get_config_value('installed',"blog:$blog_id");
405    }
406}
407
4081;
Note: See TracBrowser for help on using the browser.