Re: movabletype-opensource upcoming uploads
On Sat, Jul 12, 2008 at 12:02:47AM +0200, Luk Claes wrote:
> Dominic Hargreaves wrote:
>
> > I just wanted to check with the release team about the state of
> > movabletype-opensource.
>
> > However, ideally I would like to ship the final 4.2 release with lenny.
> > Upstream are planning one more release candidate (probably) and then a
> > final release towards the end of July. This is after the advertised
> > freeze; however I anticipate the delta between rc4 and final to be quite
> > small, and to only contain bugfixes.
> >
> > Would a freeze exception for rc4 and/or the final release package be
> > approved, if required?
>
> It depends on what the changes are, how big they are and how much risk
> of breakage there is when the package is frozen... If it are only
> bugfixes chances are big we would consider it.
4.2 has now been released, a bit later than hoped.
Comparing 4.2~rc4-1 with 4.2-1 is a bit tedious because of a perltidy
run by upstream and a large number of translation updates.
If we look at the upstream repository
http://code.sixapart.com/svn/movabletype/branches/release-42/
and generate two diffs representing changes between rc4 and final:
r2834:2876
r2877:2922
(ie ignoring the perltidy) and manually excluding doc/translations
changes and changes in the test suite then we get the slightly more
palatable diff attached:
37 files changed, 245 insertions(+), 165 deletions(-)
Also notable is that Movable Type have mentioned several security issues
being fixed in rc5, though they aren't too specific:
http://www.movabletype.org/2008/08/movable_type_42_rc5_and_security_updates.html
Given all this, the low popcon count and lack of reverse dependencies,
and the fact that Six Apart do a *lot* of their own QA, I think that the
final package is a suitable candidate for lenny.
Thanks,
Dominic.
--
Dominic Hargreaves | http://www.larted.org.uk/~dom/
PGP key 5178E2A5 from the.earth.li (keyserver,web,email)
Index: php/lib/function.mtvar.php
===================================================================
--- php/lib/function.mtvar.php (revision 2834)
+++ php/lib/function.mtvar.php (revision 2876)
@@ -57,7 +57,7 @@
$key = $args['key'];
}
- if (preg_match('/^$/', $name)) {
+ if (preg_match('/^\$/', $name)) {
$name = $vars[$name];
if (!isset($name))
return $ctx->error($ctx->mt->translate(
@@ -182,4 +182,3 @@
}
return $return_val;
}
-?>
Index: php/lib/function.mtsetvar.php
===================================================================
--- php/lib/function.mtsetvar.php (revision 2834)
+++ php/lib/function.mtsetvar.php (revision 2876)
@@ -50,7 +50,7 @@
$key = $args['key'];
}
- if (preg_match('/^$/', $name)) {
+ if (preg_match('/^\$/', $name)) {
$name = $vars[$name];
if (!isset($name))
return $ctx->error($ctx->mt->translate(
@@ -147,4 +147,3 @@
}
return '';
}
-?>
Index: php/lib/block.mtsetvarblock.php
===================================================================
--- php/lib/block.mtsetvarblock.php (revision 2834)
+++ php/lib/block.mtsetvarblock.php (revision 2876)
@@ -40,7 +40,7 @@
$key = $args['key'];
}
- if (preg_match('/^$/', $name)) {
+ if (preg_match('/^\$/', $name)) {
$name = $vars[$name];
if (!isset($name))
return $ctx->error($ctx->mt->translate(
@@ -139,4 +139,3 @@
}
return '';
}
-?>
Index: default_templates/javascript.mtml
===================================================================
--- default_templates/javascript.mtml (revision 2834)
+++ default_templates/javascript.mtml (revision 2876)
@@ -234,7 +234,6 @@
if (u.name) str += "name:'" + mtEscapeJS(u.name) + "';";
if (u.url) str += "url:'" + mtEscapeJS(u.url) + "';";
if (u.email) str += "email:'" + mtEscapeJS(u.email) + "';";
- if (u.auth_type) str += "auth_type:'" + u.auth_type + "';";
if (u.is_authenticated) str += "is_authenticated:'1';";
if (u.profile) str += "profile:'" + mtEscapeJS(u.profile) + "';";
if (u.userpic) str += "userpic:'" + mtEscapeJS(u.userpic) + "';";
@@ -259,7 +258,7 @@
var u = {};
var m;
- while (m = s.match(/^((name|url|email|auth_type|is_authenticated|profile|userpic|sid|is_trusted|is_author|is_banned|can_post|can_comment):'([^']+?)';?)/)) {
+ while (m = s.match(/^((name|url|email|is_authenticated|profile|userpic|sid|is_trusted|is_author|is_banned|can_post|can_comment):'([^']+?)';?)/)) {
s = s.substring(m[1].length);
if (m[2].match(/^(is|can)_/)) // boolean fields
u[m[2]] = m[3] == '1' ? true : false;
Index: lib/MT/Upgrade.pm
===================================================================
--- lib/MT/Upgrade.pm (revision 2834)
+++ lib/MT/Upgrade.pm (revision 2876)
@@ -739,6 +739,34 @@
};
}
}
+ else {
+ # FIXME: copied from MT::CMS::Dashboard
+ my %default_widgets = (
+ 'new_version' => {
+ order => -1,
+ set => 'main',
+ template => 'widget/new_version.tmpl',
+ singular => 1
+ },
+ 'blog_stats' => {
+ param => { tab => 'entry' },
+ order => 1,
+ set => 'main'
+ },
+ 'this_is_you-1' => { order => 1, set => 'sidebar' },
+ 'mt_shortcuts' => { order => 2, set => 'sidebar' },
+ 'mt_news' => { order => 3, set => 'sidebar' },
+ );
+ my $blog_iter = MT->model('blog')->load_iter(
+ undef,
+ { fetchonly => ['id'] }
+ );
+ while ( my $blog = $blog_iter->() ) {
+ my $set = 'dashboard:blog:' . $blog->id;
+ $widget_store->{$set} = \%default_widgets;
+ }
+ $widget_store->{'dashboard:system'} = \%default_widgets;
+ }
$user->widgets($widget_store);
},
},
@@ -1147,7 +1175,6 @@
my $driver = $db_class->dbi_driver;
my $dbh = $driver->rw_handle;
my $dbd = $driver->dbd;
- my $stmt = $dbd->sql_class->new;
my $meta_col = $param{meta_column} || 'meta';
@@ -1155,16 +1182,20 @@
my $db_defs = $ddl->column_defs($db_class);
return 0 unless $db_defs && exists($db_defs->{$meta_col});
- my $id_col = $dbd->db_column_name($class->datasource, 'id');
- $meta_col = $dbd->db_column_name($class->datasource, $meta_col);
- $stmt->add_where( $meta_col => { not_null => 1 } );
- $stmt->limit( 101 );
-
- my $sql = join ' ', 'SELECT', $meta_col, ',', $id_col, 'FROM',
- $driver->table_for($class),
- $stmt->as_sql_where(),
- $stmt->as_limit;
-
+ my $terms = {
+ $meta_col => { not_null => 1 }
+ };
+ my $args = {
+ 'limit' => 101,
+ 'fetchonly' => [ 'id' ], # meta is added to the select list separately
+ $offset ? ( 'offset' => $offset ) : ()
+ };
+ my $stmt = $driver->prepare_statement( $class, $terms, $args );
+ my $db_meta_col = $dbd->db_column_name($class->datasource, $meta_col);
+ ## Meta column has to be added in here because it's already
+ ## gone from the column_names - something fetchonly relies on
+ $stmt->add_select( $db_meta_col => $db_meta_col );
+ my $sql = $stmt->as_sql;
my $sth = $dbh->prepare($sql);
return 0 if !$sth; # ignore this operation if _meta column doesn't exist
$sth->execute
@@ -1190,7 +1221,7 @@
my $cfclass = MT->model('field');
while (my $row = $sth->fetchrow_arrayref) {
$rows++;
- my ($rawmeta, $id) = @$row;
+ my ($id, $rawmeta) = @$row; ## add_select pushes the column - it should be in this order
if (defined $rawmeta) {
push @ids, $id;
if ($rawmeta =~ m/^SERG/) {
@@ -1246,9 +1277,10 @@
# now, clear the meta column for each of the objects touched
if (@ids) {
+ my $id_col = $dbd->db_column_name($class->datasource, 'id');
my $list = join ",", @ids;
my $sql = join " ", "UPDATE", $driver->table_for($class),
- "SET", $meta_col, "=NULL WHERE", $id_col, " IN ($list)";
+ "SET", $db_meta_col, "=NULL WHERE", $id_col, " IN ($list)";
$dbh->do($sql);
}
@@ -1260,8 +1292,7 @@
# if the driver cannot drop a column, it is likely
# to get dropped as the table is updated for other
# new columns anyway.
- $sql = $dbd->ddl_class->drop_column_sql($class,
- $param{meta_column} || 'meta');
+ $sql = $dbd->ddl_class->drop_column_sql($class, $meta_col);
$self->add_step('core_drop_meta_for_table', class => $db_class, sql => $sql);
}
$self->progress($msg . ' (100%)', $pid);
@@ -1279,7 +1310,15 @@
eval "require $class;";
my $driver = $class->dbi_driver;
my $dbh = $driver->rw_handle;
- $dbh->do($sql);
+ my $err;
+ eval {
+ $dbh->do($sql) or $err = $dbh->errstr;
+ };
+ # ignore drop errors; the column has probably been
+ # removed already
+ #if ($err) {
+ # print STDERR "$err: $sql\n";
+ #}
return 0;
}
Index: lib/MT/Object.pm
===================================================================
--- lib/MT/Object.pm (revision 2834)
+++ lib/MT/Object.pm (revision 2876)
@@ -361,9 +361,9 @@
if (defined *{$package.'::new'}) {
return $package;
} else {
- eval "# line " . __LINE__ . " " . __FILE__ . "\nno warnings 'all';use $package;";
+ eval "# line " . __LINE__ . " " . __FILE__ . "\nno warnings 'all';require $package;";
return $package unless $@;
- eval "# line " . __LINE__ . " " . __FILE__ . "\nno warnings 'all';use $pkg; $package->new;";
+ eval "# line " . __LINE__ . " " . __FILE__ . "\nno warnings 'all';require $pkg; $package->new;";
return $package unless $@;
}
}
@@ -1035,7 +1035,7 @@
my $key = $param->{key} || $obj->datasource . '_id';
my $obj_id = $obj->id;
for my $class (@classes) {
- eval "# line " . __LINE__ . " " . __FILE__ . "\nno warnings 'all';use $class;";
+ eval "# line " . __LINE__ . " " . __FILE__ . "\nno warnings 'all';require $class;";
$class->remove({ $key => $obj_id });
}
1;
Index: lib/MT/CMS/Template.pm
===================================================================
--- lib/MT/CMS/Template.pm (revision 2834)
+++ lib/MT/CMS/Template.pm (revision 2876)
@@ -774,6 +774,8 @@
my $tmpl;
my $user_id = $app->user->id;
+ return unless $app->validate_magic;
+
# We can only do previews on blog templates. Have to publish
# the preview file somewhere!
return $app->errtrans("Invalid request.") unless $blog;
@@ -996,6 +998,7 @@
}
$param{template_loop} = \@data;
$param{object_type} = $type;
+ $app->request('preview_object', $tmpl);
return $app->load_tmpl( 'preview_template_strip.tmpl', \%param );
}
@@ -1661,9 +1664,10 @@
$param->{'template_set_count'} = scalar @sets;
$param->{'template_set_loop'} = \@sets;
- $param->{screen_id} = "refresh-templates-dialog";
}
+ $param->{screen_id} = "refresh-templates-dialog";
+
# load template sets
$app->build_page('dialog/refresh_templates.tmpl',
$param);
Index: lib/MT/CMS/User.pm
===================================================================
--- lib/MT/CMS/User.pm (revision 2834)
+++ lib/MT/CMS/User.pm (revision 2876)
@@ -1068,6 +1068,7 @@
my $app = shift;
my $user = $app->user;
+ return unless $app->validate_magic;
my $blogs = $app->param('blog') || '';
my $authors = $app->param('author') || '';
Index: lib/MT/CMS/Entry.pm
===================================================================
--- lib/MT/CMS/Entry.pm (revision 2834)
+++ lib/MT/CMS/Entry.pm (revision 2876)
@@ -1023,6 +1023,7 @@
return $app->load_tmpl( 'preview_entry.tmpl', \%param );
}
else {
+ $app->request('preview_object', $entry);
return $app->load_tmpl( 'preview_strip.tmpl', \%param );
}
}
Index: lib/MT/App.pm
===================================================================
--- lib/MT/App.pm (revision 2834)
+++ lib/MT/App.pm (revision 2876)
@@ -992,7 +992,6 @@
email => $commenter->email,
userpic => scalar $commenter->userpic_url,
profile => "", # profile link url
- auth_type => ($commenter->auth_type eq 'MT' ? "1" : "0"),
is_authenticated => "1",
is_trusted => ($commenter->is_trusted($blog_id) ? "1" : "0"),
is_author => ($commenter->type == MT::Author::AUTHOR() ? "1" : "0"),
@@ -1162,7 +1161,7 @@
my $nick_escaped = MT::Util::escape_unicode( $nick );
my $timeout;
- if ( $user->auth_type eq 'MT' ) {
+ if ( $user->type == MT::Author::AUTHOR() ) {
if ($app->param('remember')) {
# 10 years, same as app sign-in 'remember me'
$timeout = '+3650d';
Index: lib/MT/AtomServer.pm
===================================================================
--- lib/MT/AtomServer.pm (revision 2834)
+++ lib/MT/AtomServer.pm (revision 2876)
@@ -787,7 +787,7 @@
unless $app->{perms}->can_edit_entry($entry, $app->{user});
# Delete archive file
- my $blog = MT::Blog->load($entry->blog_id);
+ $blog = MT::Blog->load($entry->blog_id);
my %recip = $app->publisher->rebuild_deleted_entry(
Entry => $entry,
Blog => $blog);
Index: lib/MT/Template/ContextHandlers.pm
===================================================================
--- lib/MT/Template/ContextHandlers.pm (revision 2834)
+++ lib/MT/Template/ContextHandlers.pm (revision 2876)
@@ -2547,11 +2547,13 @@
my ($ctx, $args, $cond) = @_;
my $start = (exists $args->{from} ? $args->{from} : $args->{start}) || 0;
- $start = 0 unless $start =~ /^\d+$/;
+ $start = 0 unless $start =~ /^-?\d+$/;
my $end = (exists $args->{to} ? $args->{to} : $args->{end}) || 0;
- return q() unless $end =~ /^\d+$/;
+ return q() unless $end =~ /^-?\d+$/;
my $incr = $args->{increment} || $args->{step} || 1;
+ # FIXME: support negative "step" values
$incr = 1 unless $incr =~ /^\d+$/;
+ $incr = 1 unless $incr;
my $builder = $ctx->stash('builder');
my $tokens = $ctx->stash('tokens');
@@ -3361,7 +3363,7 @@
$key = $args->{key} if exists $args->{key};
}
- if ($name =~ m/^$/) {
+ if ($name =~ m/^\$/) {
$name = $ctx->var($name);
}
@@ -3384,7 +3386,7 @@
$value = _hdlr_pass_tokens(@_) or return;
} elsif (ref($value) eq 'ARRAY') {
if ( defined $index ) {
- if ($index =~ /^\d+$/) {
+ if ($index =~ /^-?\d+$/) {
$value = $value->[ $index ];
} else {
$value = undef; # fall through to any 'default'
@@ -4450,8 +4452,10 @@
<$mt:Var name="contents"$>
(footer stuff)
-B<Attributes:>
+B<Important:> Modules used as IncludeBlocks should never be processed as a Server Side Include or be cached
+=head4 Attributes:
+
=over 4
=item * var (optional)
@@ -5489,7 +5493,7 @@
my($ctx, $args) = @_;
my $tag = lc $ctx->stash('tag');
my $name = $args->{name} || $args->{var};
- if ($name =~ m/^$/) {
+ if ($name =~ m/^\$/) {
$name = $ctx->var($name);
}
return $ctx->error(MT->translate(
@@ -5657,7 +5661,7 @@
$key = $args->{key} if exists $args->{key};
}
- if ($name =~ m/^$/) {
+ if ($name =~ m/^\$/) {
$name = $ctx->var($name);
return $ctx->error(MT->translate(
"You used a [_1] tag without a valid name attribute.", "<MT$tag>" ))
@@ -5683,7 +5687,7 @@
$existing = $existing->{ $key };
}
elsif ( 'ARRAY' eq ref($existing) ) {
- $existing = ( defined $index && ( $index =~ /^\d+$/ ) )
+ $existing = ( defined $index && ( $index =~ /^-?\d+$/ ) )
? $existing->[ $index ]
: undef;
}
@@ -5716,7 +5720,7 @@
return $ctx->error( MT->translate("'[_1]' is not an array.", $name) )
unless 'ARRAY' eq ref($data);
return $ctx->error( MT->translate("Invalid index.") )
- unless $index =~ /^\d+$/;
+ unless $index =~ /^-?\d+$/;
$data->[ $index ] = $val;
}
elsif ( defined $func ) {
Index: lib/MT/App/CMS.pm
===================================================================
--- lib/MT/App/CMS.pm (revision 2834)
+++ lib/MT/App/CMS.pm (revision 2876)
@@ -40,8 +40,8 @@
return {
'tools' => "${pkg}Tools::system_check",
'dashboard' => "${pkg}Dashboard::dashboard",
- 'menu' => '${pkg}Dashboard::dashboard',
- 'admin' => '${pkg}Dashboard::dashboard',
+ 'menu' => "${pkg}Dashboard::dashboard",
+ 'admin' => "${pkg}Dashboard::dashboard",
## Generic handlers
'save' => "${pkg}Common::save",
Index: lib/MT/Template.pm
===================================================================
--- lib/MT/Template.pm (revision 2834)
+++ lib/MT/Template.pm (revision 2876)
@@ -56,6 +56,7 @@
'rebuild_me' => 1,
'build_dynamic' => 0,
'build_type' => 1,
+ 'build_interval' => 0,
},
meta => 1,
child_of => 'MT::Blog',
Index: lib/MT/XMLRPCServer.pm
===================================================================
--- lib/MT/XMLRPCServer.pm (revision 2834)
+++ lib/MT/XMLRPCServer.pm (revision 2876)
@@ -346,6 +346,7 @@
$entry->excerpt($item->{mt_excerpt}) if $item->{mt_excerpt};
$entry->text_more($item->{mt_text_more}) if $item->{mt_text_more};
$entry->keywords($item->{mt_keywords}) if $item->{mt_keywords};
+ $entry->created_by($author->id);
if (my $tags = $item->{mt_tags}) {
require MT::Tag;
@@ -475,6 +476,7 @@
$entry->excerpt($item->{mt_excerpt}) if defined $item->{mt_excerpt};
$entry->text_more($item->{mt_text_more}) if defined $item->{mt_text_more};
$entry->keywords($item->{mt_keywords}) if defined $item->{mt_keywords};
+ $entry->modified_by($author->id);
if (my $tags = $item->{mt_tags}) {
require MT::Tag;
my $tag_delim = chr($author->entry_prefs->{tag_delim});
@@ -491,8 +493,9 @@
require MT::DateTime;
$entry->status(MT::Entry::FUTURE())
if MT::DateTime->compare(
- a => $entry->authored_on,
- b => { value => time(), type => 'epoch' } ) > 0;
+ blog => $blog,
+ a => $entry->authored_on,
+ b => { value => time(), type => 'epoch' } ) > 0;
}
$entry->discover_tb_from_entry();
Index: plugins/StyleCatcher/lib/StyleCatcher/CMS.pm
===================================================================
--- plugins/StyleCatcher/lib/StyleCatcher/CMS.pm (revision 2834)
+++ plugins/StyleCatcher/lib/StyleCatcher/CMS.pm (revision 2876)
@@ -134,6 +134,7 @@
# format of 'key: value' in comment-space
# The remixer only uses name, author, description at the moment.
my $app = shift;
+ return $app->json_error( $app->errstr ) unless $app->validate_magic;
my $data = fetch_themes($app->param('url'))
or return $app->json_error( $app->errstr );
Index: plugins/StyleCatcher/tmpl/view.tmpl
===================================================================
--- plugins/StyleCatcher/tmpl/view.tmpl (revision 2834)
+++ plugins/StyleCatcher/tmpl/view.tmpl (revision 2876)
@@ -490,6 +490,7 @@
'method': 'POST',
'arguments': {
'__mode': 'stylecatcher_js',
+ 'magic_token': '<mt:var name="magic_token">',
'url': url
}
});
Index: mt-static/mt.js
===================================================================
--- mt-static/mt.js (revision 2834)
+++ mt-static/mt.js (revision 2876)
@@ -1481,15 +1481,17 @@
eventSubmit: function( event ) {
+ this.eventSubmitForm = undefined;
+
var form = DOM.getFirstAncestorByTagName( event.target, "form", true );
if ( !form )
return;
-
+
if ( form.getAttribute( "mt:once" ) ) {
-
if ( form.submitted )
return event.stop();
-
+
+ this.eventSubmitForm = form;
this.toggleSubmit( form, true );
}
@@ -1501,6 +1503,13 @@
eventBeforeUnload: function( event ) {
+ /* re-enables disabled controls onunload, so they are enabled
+ if the user navigates back */
+ if ( this.eventSubmitForm ) {
+ this.toggleSubmit( this.eventSubmitForm, false );
+ this.submitted = false;
+ }
+
if ( this.changed ) {
if ( this.constructor.Editor )
return event.returnValue = Editor.strings.unsavedChanges;
Index: tmpl/cms/include/template_table.tmpl
===================================================================
--- tmpl/cms/include/template_table.tmpl (revision 2834)
+++ tmpl/cms/include/template_table.tmpl (revision 2876)
@@ -42,7 +42,7 @@
><__trans phrase="Delete"></a>
</mt:unless></mt:unless>
</mt:setvarblock>
-<mt:setvarblock name="table_id"><mt:var name="template_type">-listing</mt:setvarblock>
+<mt:setvarblock name="table_id"><mt:var name="template_type" default="template">-listing</mt:setvarblock>
<mtapp:listing id="$table_id" hide_pager="1" class="show-all" listing_class="show-actions-bar-top" type="template">
<mt:if __first__>
<thead>
Index: tmpl/cms/dialog/refresh_templates.tmpl
===================================================================
--- tmpl/cms/dialog/refresh_templates.tmpl (revision 2834)
+++ tmpl/cms/dialog/refresh_templates.tmpl (revision 2876)
@@ -73,7 +73,7 @@
label_class="top-label"
show_label="0"
show_hint="1"
- hint="<__trans phrase="Updates current templates while retaining any user-created or user-modified templates.">">
+ hint="<__trans phrase="Updates current templates while retaining any user-created templates.">">
<div class="field-header">
<label for="refresh_type_refresh"><input type="radio" name="refresh_type" id="refresh_type_refresh" value="refresh" onclick="disable('template_set');toggleHidden('confirm-clean');toggleHidden('confirm-refresh');" checked="checked" /> <$mt:var name="refresh_label"$></label>
</div>
Index: default_templates/category_archive_list.mtml
===================================================================
--- default_templates/category_archive_list.mtml (revision 2877)
+++ default_templates/category_archive_list.mtml (revision 2922)
@@ -7,7 +7,7 @@
<ul>
</mt:SubCatIsFirst>
<mt:If tag="CategoryCount">
- <li><a href="<$mt:CategoryArchiveLink$>"<mt:If tag="CategoryDescription"> title="<$mt:CategoryDescription$>"</mt:If>><__trans phrase="[_1] ([_2])" params="<$mt:CategoryLabel$>%%<$mt:CategoryCount$>"></a>
+ <li><a href="<$mt:CategoryArchiveLink$>"<mt:If tag="CategoryDescription"> title="<$mt:CategoryDescription remove_html="1" encode_html="1"$>"</mt:If>><__trans phrase="[_1] ([_2])" params="<$mt:CategoryLabel$>%%<$mt:CategoryCount$>"></a>
<mt:Else>
<li><$mt:CategoryLabel$>
</mt:If>
Index: default_templates/openid.mtml
===================================================================
--- default_templates/openid.mtml (revision 2877)
+++ default_templates/openid.mtml (revision 2922)
@@ -2,7 +2,7 @@
<div class="widget-openid widget">
<div class="widget-content">
<em><__trans phrase="[_1] accepted here" params="<strong>OpenID</strong>"></em>
- <a href="<__trans phrase="http://www.movabletype.com/openid/">"><__trans phrase="Learn more about OpenID"></a>
+ <a href="<__trans phrase="http://www.sixapart.com/labs/openid/">"><__trans phrase="Learn more about OpenID"></a>
</div>
</div>
</mt:IfRegistrationAllowed>
Index: lib/MT/Upgrade.pm
===================================================================
--- lib/MT/Upgrade.pm (revision 2877)
+++ lib/MT/Upgrade.pm (revision 2922)
@@ -834,7 +834,7 @@
require MT::Template;
my $styles = MT::Template->load({ blog_id => $blog->id, identifier => 'styles' });
if ($styles) {
- if ($styles->text =~ m{ <mt:?setvar \s+ name="page_layout" \s+ value="([^"]+)"> }xmsi) {
+ if ($styles->text =~ m{ <\$?mt:?setvar \s+ name="page_layout" \s+ value="([^"]+)"\$?> }xmsi) {
$layout = $1;
}
}
Index: lib/MT/ConfigMgr.pm
===================================================================
--- lib/MT/ConfigMgr.pm (revision 2877)
+++ lib/MT/ConfigMgr.pm (revision 2922)
@@ -208,6 +208,8 @@
sub save_config {
my $class = shift;
my $mgr = $class->instance;
+ # prevent saving when the db row wasn't read already
+ return 0 unless $mgr->{__read_db};
return 0 unless $mgr->is_dirty();
my $data = '';
my $settings = $mgr->{__dbvar};
@@ -301,6 +303,7 @@
$mgr->set($var, $val, 1);
}
}
+ $mgr->{__read_db} = 1;
1;
}
Index: lib/MT/Object.pm
===================================================================
--- lib/MT/Object.pm (revision 2877)
+++ lib/MT/Object.pm (revision 2922)
@@ -497,7 +497,7 @@
vclob
) ],
indexes => {
- id_type => { columns => [ $id_field, 'type' ] },
+ #id_type => { columns => [ $id_field, 'type' ] }, # redundant
type_vchar => { columns => [ 'type', 'vchar_idx' ] },
type_vdt => { columns => [ 'type', 'vdatetime_idx' ] },
type_vint => { columns => [ 'type', 'vinteger_idx' ] },
Index: lib/MT/ObjectDriver/DDL/mysql.pm
===================================================================
--- lib/MT/ObjectDriver/DDL/mysql.pm (revision 2877)
+++ lib/MT/ObjectDriver/DDL/mysql.pm (revision 2922)
@@ -96,6 +96,7 @@
$coltype = $ddl->db2type($coltype);
$defs->{$colname}{type} = $coltype;
$defs->{$colname}{auto} = ($row->{Extra} =~ m/auto_increment/i) ? 1 : 0;
+ $defs->{$colname}{key} = $row->{Key} eq 'PRI' ? 1 : 0;
if (($coltype eq 'string') && $size) {
$defs->{$colname}{size} = $size;
}
Index: lib/MT/ObjectDriver/DDL/SQLite.pm
===================================================================
--- lib/MT/ObjectDriver/DDL/SQLite.pm (revision 2877)
+++ lib/MT/ObjectDriver/DDL/SQLite.pm (revision 2922)
@@ -100,6 +100,7 @@
or return undef;
$sth->execute or return undef;
my $defs = {};
+ my @pks;
while (my $row = $sth->fetchrow_hashref) {
my $colname = lc $row->{name};
$colname =~ s/^\Q$field_prefix\E_//i;
@@ -108,13 +109,13 @@
$defs->{$colname}{size} = $1;
}
$defs->{$colname}{type} = $coltype;
+ # TODO: isn't key for pks, not foreign keys?
if ($colname =~ m/_id$/) {
$defs->{$colname}{key} = 1;
}
- if ( ($coltype eq 'integer') && $row->{pk} ) {
- # with sqlite, integer primary keys auto increment. always.
+ if ($row->{pk}) {
$defs->{$colname}{key} = 1;
- $defs->{$colname}{auto} = 1;
+ push @pks, $colname;
}
$defs->{$colname}{not_null} = 1
if $row->{notnull};
@@ -123,6 +124,15 @@
}
$sth->finish;
return undef unless %$defs;
+
+ if (@pks && 1 == scalar @pks) {
+ my ($colname) = @pks;
+ if ($defs->{$colname}{type} eq 'integer') {
+ # with sqlite, simple integer primary keys auto increment. always.
+ $defs->{$colname}{auto} = 1;
+ }
+ }
+
return $defs;
}
@@ -172,15 +182,14 @@
my $ddl = shift;
my ($class) = @_;
- my $table_name = $class->table_name;
- my $props = $class->properties;
+ my $table_name = $class->table_name;
+ my $props = $class->properties;
my $field_prefix = $class->datasource;
- my $indexes = $props->{indexes};
+ my $indexes = $props->{indexes};
+ my $pk = $props->{primary_key};
my @stmts;
if ($indexes) {
- # FIXME: Handle possible future primary key tuple case
- my $pk = $props->{primary_key};
foreach my $name (keys %$indexes) {
next if $pk && $name eq $pk;
if (ref $indexes->{$name} eq 'HASH') {
@@ -198,6 +207,11 @@
}
}
}
+ if ($pk && 'ARRAY' eq ref $pk) {
+ my @columns = map { join q{_}, $field_prefix, $_ } @$pk;
+ my $columns = join q{, }, @columns;
+ push @stmts, "PRIMARY KEY ($columns)";
+ }
if (@stmts) {
return ',' . join("\n", @stmts);
}
Index: lib/MT/ObjectDriver/DDL.pm
===================================================================
--- lib/MT/ObjectDriver/DDL.pm (revision 2877)
+++ lib/MT/ObjectDriver/DDL.pm (revision 2922)
@@ -27,8 +27,22 @@
sub index_table {()}
sub create_sequence {}
sub drop_sequence {}
-sub unique_constraint_sql { '' }
+sub unique_constraint_sql {
+ my $ddl = shift;
+ my ($class) = @_;
+
+ my $pk = $class->properties->{primary_key};
+ return q{} if !ref $pk || 'ARRAY' ne ref $pk;
+
+ my $driver = $class->driver;
+ my $dbd = $driver->dbd;
+ my $table = $class->table_name;
+
+ my @key_fields = map { $dbd->db_column_name($table, $_) } @$pk;
+ return ', PRIMARY KEY (' . join(q{, }, @key_fields) . ')';
+}
+
sub table_exists {
my $ddl = shift;
my ($class) = @_;
@@ -257,8 +271,8 @@
my @stmts;
if ($indexes) {
- # FIXME: Handle possible future primary key tuple case
my $pk = $props->{primary_key};
+ undef $pk if ref $pk; # ignore complex key
foreach my $name (keys %$indexes) {
next if $pk && $name eq $pk;
push @stmts, $ddl->index_column_sql($class, $name);
@@ -282,7 +296,7 @@
my $field_prefix = $class->datasource;
my $pk = $props->{primary_key};
if (!ref $indexes->{$name}) {
- if (!($pk && $name eq $pk)) {
+ if (!$pk || ref $pk || $name ne $pk) {
push @stmts, "CREATE INDEX ${table_name}_$name ON $table_name (${field_prefix}_$name)";
}
}
@@ -361,8 +375,10 @@
}
$default = ' DEFAULT ' . $value;
}
- my $key = '';
- $key = ' PRIMARY KEY' if $def->{key};
+ my $key = !$def->{key} ? q{}
+ : ref $class->properties->{primary_key} ? q{}
+ : ' PRIMARY KEY'
+ ;
return $field_prefix . '_' . $name . ' ' . $type . $nullable . $default . $key;
}
Index: lib/MT/CMS/Search.pm
===================================================================
--- lib/MT/CMS/Search.pm (revision 2877)
+++ lib/MT/CMS/Search.pm (revision 2922)
@@ -385,10 +385,6 @@
## we look for a comma (not a valid character in a column name) and split
## on it if it's there.
if ( ($search || '') ne '' ) {
- my $enc = $app->charset;
- $search = MT::I18N::encode_text( $search, 'utf-8', $enc )
- if ( $enc !~ m/utf-?8/i )
- && ( 'dialog_grant_role' eq $app->param('__mode') );
$search = quotemeta($search) unless $is_regex;
$search = '(?i)' . $search unless $case;
}
Index: lib/MT/CMS/Tag.pm
===================================================================
--- lib/MT/CMS/Tag.pm (revision 2877)
+++ lib/MT/CMS/Tag.pm (revision 2922)
@@ -155,9 +155,7 @@
my $blog_id = $app->param('blog_id');
my $obj_class = $app->model($obj_ds) or return;
my $tag_name = $app->param('tag') or return;
- if ( 'utf-8' ne lc( $app->config->PublishCharset) ) {
- $tag_name = MT::I18N::encode_text( $tag_name, 'utf-8', $app->config->PublishCharset );
- }
+
my $tag_obj =
$tag_class->load( { name => $tag_name }, { binary => { name => 1 } } );
Index: lib/MT/CMS/Template.pm
===================================================================
--- lib/MT/CMS/Template.pm (revision 2877)
+++ lib/MT/CMS/Template.pm (revision 2922)
@@ -310,6 +310,8 @@
$param->{enabled_archive_types} = join(", ", sort keys %at);
$param->{static_maps} = $build_type == MT::PublishOption::DYNAMIC() ? 0 : 1;
$param->{build_type_0} = 1 unless $build_type_0;
+ } else {
+ $param->{can_rebuild} = 0;
}
}
# publish options
@@ -558,7 +560,7 @@
if $app->param('dirty');
$param->{can_preview} = 1
- if (!$param->{is_special}) && (!$obj || ($obj && ($obj->outfile || '') !~ m/\.(css|xml|rss|js)$/));
+ if (!$param->{is_special}) && (!$obj || ($obj && ($obj->outfile || '') !~ m/\.(css|xml|rss|js)$/)) && (!exists $param->{can_preview});
1;
}
@@ -2161,6 +2163,8 @@
$return_args =~ s/^\?//;
$app->return_args( $return_args );
+ return $app->call_return unless %ats;
+
$app->param( 'template_id', $tmpl_id );
$app->param( 'single_template', 1 ); # forces fullscreen mode
$app->param( 'type', join(",", keys %ats) );
Index: lib/MT/CMS/Category.pm
===================================================================
--- lib/MT/CMS/Category.pm (revision 2877)
+++ lib/MT/CMS/Category.pm (revision 2922)
@@ -275,12 +275,6 @@
}
my $label = $app->param('label');
- my $enc = $app->config->PublishCharset;
-
- # XMLHttpRequest always send text in UTF-8... right?
- if ( 'utf-8' ne lc($enc) ) {
- $label = MT::I18N::encode_text( $label, 'utf-8', $enc );
- }
my $basename = $app->param('basename');
if ( !defined($label) || ( $label =~ m/^\s*$/ ) ) {
return $app->json_error( $app->translate("Invalid request.") );
Index: lib/MT/CMS/Common.pm
===================================================================
--- lib/MT/CMS/Common.pm (revision 2877)
+++ lib/MT/CMS/Common.pm (revision 2922)
@@ -449,18 +449,7 @@
if ($sess_obj) {
my $data = $sess_obj->thaw_data;
if ($data) {
-
- # XMLHttpRequest always send text in UTF-8... right?
- if ( 'utf-8' eq lc($enc) ) {
- $q->param( $_, $data->{$_} ) for keys %$data;
- }
- else {
- foreach ( keys %$data ) {
- my $encoded =
- MT::I18N::encode_text( $data->{$_}, 'utf-8', $enc );
- $q->param( $_, $encoded );
- }
- }
+ $q->param( $_, $data->{$_} ) for keys %$data;
$param{'recovered_object'} = 1;
}
else {
Index: lib/MT/CMS/Tools.pm
===================================================================
--- lib/MT/CMS/Tools.pm (revision 2877)
+++ lib/MT/CMS/Tools.pm (revision 2922)
@@ -1435,21 +1435,8 @@
sub convert_to_html {
my $app = shift;
my $format = $app->param('format');
- my $text = $app->param('text');
- # XMLHttpRequest always send text in UTF-8... right?
- if ( defined $text ) {
- $text = encode_text($text, 'utf-8', $app->config->PublishCharset);
- }
- else {
- $text = '' ;
- }
- my $text_more = $app->param('text_more');
- if ( defined $text_more ) {
- $text_more = encode_text($text_more, 'utf-8', $app->config->PublishCharset);
- }
- else {
- $text_more = '' ;
- }
+ my $text = $app->param('text') || '';
+ my $text_more = $app->param('text_more') || '';
my $result = {
text => $app->apply_text_filters( $text, [$format] ),
text_more => $app->apply_text_filters( $text_more, [$format] ),
Index: lib/MT/CMS/Entry.pm
===================================================================
--- lib/MT/CMS/Entry.pm (revision 2877)
+++ lib/MT/CMS/Entry.pm (revision 2922)
@@ -2042,7 +2042,6 @@
my $entry = MT::Entry->load($id)
or return $app->errtrans(
"One of the entries ([_1]) did not actually exist", $id );
- next if $entry->status == $new_status;
if ( $app->config('DeleteFilesAtRebuild')
&& ( MT::Entry::RELEASE() eq $entry->status ) )
{
Index: lib/MT/App.pm
===================================================================
--- lib/MT/App.pm (revision 2877)
+++ lib/MT/App.pm (revision 2922)
@@ -2,7 +2,7 @@
# This program is distributed under the terms of the
# GNU General Public License, version 2.
#
-# $Id: App.pm 2846 2008-07-28 02:46:54Z fumiakiy $
+# $Id$
package MT::App;
@@ -815,7 +815,17 @@
my @p = $q->param();
my $charset = $app->charset;
require Encode;
+ require MT::I18N::default;
$charset = 'UTF-8' if $charset =~ m/utf-?8/i;
+ my $request_charset = $charset;
+ if ( my $content_type = $q->content_type() ) {
+ if ( $content_type =~ m/;[ ]+charset=(.+)/i ) {
+ $request_charset = lc $1;
+ $request_charset =~ s/^\s+|\s+$//gs;
+ }
+ }
+ my $transcode = $request_charset ne $charset ? 1 : 0;
+ my %params;
foreach my $p (@p) {
if ( $p =~ m/[^\x20-\x7E]/ ) {
@@ -824,18 +834,42 @@
}
my @d = $q->param($p);
+ my @param;
foreach my $d (@d) {
- next
- if ( !defined $d )
- || ( $d eq '' )
- || ( $d !~ m/[^\x20-\x7E]/ );
+ if ( ( !defined $d )
+ || ( $d eq '' )
+ || ( $d !~ m/[^\x20-\x7E]/ ) )
+ {
+ push @param, $d if $transcode;
+ next;
+ }
+ $d = MT::I18N::default->encode_text_encode( $d, $request_charset, $charset )
+ if $transcode;
+ my $saved = $d;
eval { Encode::decode( $charset, $d, 1 ); };
return $app->errtrans(
"Invalid request: corrupt character data for character set [_1]",
$charset
) if $@;
+ push @param, $saved if $transcode;
}
+ if ( $transcode && @param ) {
+ if ( 1 == scalar(@param) ) {
+ $params{ $p } = $param[0];
+ }
+ else {
+ $params{ $p } = [ @param ];
+ }
+ }
}
+ while ( my ( $key, $val ) = each %params ) {
+ if ( ref $val ) {
+ $app->param( $key, @{ $params{ $key } } ) ;
+ }
+ else {
+ $app->param( $key, $val );
+ }
+ }
return 1;
}
Index: lib/MT/App/Trackback.pm
===================================================================
--- lib/MT/App/Trackback.pm (revision 2877)
+++ lib/MT/App/Trackback.pm (revision 2922)
@@ -38,15 +38,8 @@
my $q = $app->param;
# attempt to determine character set encoding based on
- # 'charset' parameter or 'charset' in content-type header:
+ # 'charset' parameter:
my $enc = $q->param('charset');
- unless ($enc) {
- my $content_type = $q->content_type();
- if ( $content_type =~ m/;[ ]+charset=(.+)/i ) {
- $enc = lc $1;
- $enc =~ s/^\s+|\s+$//gs;
- }
- }
local $app->{charset} = $enc if $enc;
return $app->SUPER::validate_request_params();
}
@@ -252,26 +245,12 @@
);
}
- my ( $title, $excerpt, $url, $blog_name, $enc )
+ my ( $title, $excerpt, $url, $blog_name )
= map scalar $q->param($_),
- qw( title excerpt url blog_name charset);
+ qw( title excerpt url blog_name);
- unless ($enc) {
- my $content_type = $q->content_type();
- if ( $content_type =~ m/;[ ]+charset=(.+)/i ) {
- $enc = lc $1;
- $enc =~ s/^\s+|\s+$//gs;
- }
- }
-
no_utf8( $tb_id, $title, $excerpt, $url, $blog_name );
- # guess encoding as possible
- $enc = MT::I18N::guess_encoding( $excerpt . $title . $blog_name )
- unless $enc;
- ( $title, $excerpt, $blog_name )
- = map { encode_text( $_, $enc ) } ( $title, $excerpt, $blog_name );
-
return $app->_response(
Error => $app->translate("Need a Source URL (url).") )
unless $url;
Index: lib/MT/App/CMS.pm
===================================================================
--- lib/MT/App/CMS.pm (revision 2877)
+++ lib/MT/App/CMS.pm (revision 2922)
@@ -421,16 +421,6 @@
my $pkg = '$Core::MT::CMS::';
return {
'entry' => {
- 'set_published' => {
- label => "Publish Entries",
- order => 100,
- code => "${pkg}Entry::publish_entries",
- permission => 'edit_all_posts,publish_post',
- condition => sub {
- return 0 if $app->mode eq 'view';
- return $app->blog && $app->blog->site_path ? 1 : 0;
- },
- },
'set_draft' => {
label => "Unpublish Entries",
order => 200,
@@ -476,16 +466,6 @@
},
},
'page' => {
- 'set_published' => {
- label => "Publish Pages",
- order => 100,
- code => "${pkg}Entry::publish_entries",
- permission => 'manage_pages',
- condition => sub {
- return 0 if $app->mode eq 'view';
- return $app->blog && $app->blog->site_path ? 1 : 0;
- },
- },
'set_draft' => {
label => "Unpublish Pages",
order => 200,
@@ -595,7 +575,7 @@
'untrust' => {
label => "Untrust Commenter(s)",
order => 100,
- code => "{$pkg}Comment::untrust_commenter",
+ code => "${pkg}Comment::untrust_commenter",
permission => 'manage_feedback',
},
'unban' => {
Index: lib/MT/Template.pm
===================================================================
--- lib/MT/Template.pm (revision 2877)
+++ lib/MT/Template.pm (revision 2922)
@@ -328,11 +328,15 @@
my $string_tmpl = '<mt:include widget="%s">';
my $text = q();
+ my @ids;
foreach my $wid (@inst) {
my ( $tmpl ) = grep { $_->id eq $wid } @widgets;
next unless $tmpl;
$text .= sprintf( $string_tmpl, $tmpl->name );
+ push @ids, $wid;
}
+ $obj->modulesets( join ',', @ids )
+ if scalar @ids != scalar @inst;
$obj->text($text) if $text;
return $obj->SUPER::save;
}
@@ -660,6 +664,25 @@
$tmpl->remove_children({ key => 'template_id' });
}
+sub post_remove_widget {
+ my $tmpl = shift;
+ return unless $tmpl->type eq 'widget';
+
+ my $iter = MT::Template->load_iter({
+ blog_id => [ $tmpl->blog_id, 0 ],
+ type => 'widgetset',
+ });
+ my @resave;
+ while ( my $ws = $iter->() ) {
+ my @mods = split( ',', $ws->modulesets );
+ if ( grep { $_ == $tmpl->id } @mods ) {
+ push @resave, $ws;
+ }
+ }
+ $_->save for @resave;
+}
+__PACKAGE__->add_trigger('post_remove' => \&post_remove_widget);
+
# Some DOM-inspired methods (replicating the interface, so it's more
# familiar to those who know DOM)
sub getElementsByTagName {
Index: lib/MT/Component.pm
===================================================================
--- lib/MT/Component.pm (revision 2877)
+++ lib/MT/Component.pm (revision 2922)
@@ -153,7 +153,7 @@
return unless -f $path;
require YAML::Tiny;
my $y = eval { YAML::Tiny->read($path) }
- or die "Error reading $path: " . $YAML::Tiny::errstr;
+ or die "Error reading $path: " . (YAML::Tiny->errstr||$@||$!);
if ( ref($y) ) {
# skip over non-hash elements
@@ -520,8 +520,7 @@
if ( -f $f ) {
require YAML::Tiny;
my $y = eval { YAML::Tiny->read($f) }
- or die "Error reading $f: "
- . $YAML::Tiny::errstr;
+ or die "Error reading $f: " . (YAML::Tiny->errstr||$@||$!);
# skip over non-hash elements
shift @$y
while @$y && ( ref( $y->[0] ) ne 'HASH' );
Index: plugins/StyleCatcher/lib/StyleCatcher/CMS.pm
===================================================================
--- plugins/StyleCatcher/lib/StyleCatcher/CMS.pm (revision 2877)
+++ plugins/StyleCatcher/lib/StyleCatcher/CMS.pm (revision 2922)
@@ -267,7 +267,7 @@
'/* This is the StyleCatcher theme addition. Do not remove this block. */';
my $footer = '/* end StyleCatcher imports */';
my $styles = $header . "\n";
- $styles .= "\@import url(".File::Spec->catfile($app->static_path, $base_css).");\n" if $base_css;
+ $styles .= "\@import url(".MT::Util::caturl($app->static_path, $base_css).");\n" if $base_css;
$styles .= "\@import url($url);\n";
$styles .= $footer;
print STDERR "styles=$styles\n";
Index: t/lib/MT/Test.pm
===================================================================
--- t/lib/MT/Test.pm (revision 2877)
+++ t/lib/MT/Test.pm (revision 2922)
@@ -57,6 +57,11 @@
push @to_export, $opt;
}
}
+
+ # We need *some* instance created up front, to initialize the database
+ # factory etc properly, so do so now.
+ MT->instance;
+
# Export requested or all exportable functions.
$pkg->export_to_level(1, @to_export || qw( :DEFAULT ));
}
Index: mt-static/js/tc/client.js
===================================================================
--- mt-static/js/tc/client.js (revision 2877)
+++ mt-static/js/tc/client.js (revision 2922)
@@ -88,7 +88,7 @@
args.push( a + '=' + e( param['arguments'][a] ) );
contents = args.join('&');
}
- c.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
+ c.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8' );
}
c.send( contents );
return c;
Index: tmpl/feeds/feed_comment.tmpl
===================================================================
--- tmpl/feeds/feed_comment.tmpl (revision 2877)
+++ tmpl/feeds/feed_comment.tmpl (revision 2922)
@@ -71,7 +71,7 @@
<li><a href="<TMPL_VAR NAME=MT_URL>?__mode=list_comments&blog_id=<TMPL_VAR NAME=LOG.COMMENT.BLOG_ID>"><MT_TRANS phrase="From this blog"></a></li>
- <li><a href="<TMPL_VAR NAME=MT_URL>?__mode=view&_type=entry&blog_id=<TMPL_VAR NAME=LOG.COMMENT.BLOG_ID>&id=<TMPL_VAR NAME=LOG.COMMENT.ENTRY.ID>&tab=comments"><MT_TRANS phrase="On this entry"></a></li>
+ <li><a href="<TMPL_VAR NAME=MT_URL>?__mode=list_comment&blog_id=<TMPL_VAR NAME=LOG.COMMENT.BLOG_ID>&filter_key=_comments_by_entry&filter_val=<TMPL_VAR NAME=LOG.COMMENT.ENTRY_ID>"><MT_TRANS phrase="On this entry"></a></li>
<TMPL_IF NAME=LOG.COMMENT.AUTHOR.AUTHENTICATED>
<li><a href="<TMPL_VAR NAME=MT_URL>?__mode=view&_type=commenter&id=<TMPL_VAR NAME=LOG.COMMENT.AUTHOR.ID>&blog_id=<TMPL_VAR NAME=LOG.COMMENT.BLOG_ID>&tab=comments"><MT_TRANS phrase="By commenter identity"></a></li>
Index: tmpl/feeds/feed_ping.tmpl
===================================================================
--- tmpl/feeds/feed_ping.tmpl (revision 2877)
+++ tmpl/feeds/feed_ping.tmpl (revision 2922)
@@ -68,7 +68,7 @@
<strong><MT_TRANS phrase="More like this">:</strong><br />
<li><a href="<TMPL_VAR NAME=MT_URL>?__mode=list_pings&blog_id=<TMPL_VAR NAME=LOG.TBPING.BLOG_ID>"><MT_TRANS phrase="From this blog"></a></li>
- <TMPL_IF NAME=LOG.TBPING.ENTRY.ID><li><a href="<TMPL_VAR NAME=MT_URL>?__mode=view&_type=entry&blog_id=<TMPL_VAR NAME=LOG.TBPING.BLOG_ID>&id=<TMPL_VAR NAME=LOG.TBPING.ENTRY.ID>&tab=pings"><MT_TRANS phrase="On this entry"></a></li>
+ <TMPL_IF NAME=LOG.TBPING.ENTRY.ID><li><a href="<TMPL_VAR NAME=MT_URL>?__mode=list_pings&blog_id=<TMPL_VAR NAME=LOG.TBPING.BLOG_ID>&filter=entry_id&filter_val=<TMPL_VAR NAME=LOG.TBPING.ENTRY.ID>"><MT_TRANS phrase="On this entry"></a></li>
</TMPL_IF><li><a href="<TMPL_VAR NAME=MT_URL>?__mode=search_replace&blog_id=<TMPL_VAR NAME=LOG.TBPING.BLOG_ID>&_type=ping&search=<TMPL_VAR NAME=LOG.TBPING.BLOG_NAME ESCAPE=URL>&do_search=1"><MT_TRANS phrase="By source blog"></a></li>
Reply to: