Commit c41db556 by Gideon Greenspan

1.5.3

parent 8db35a82
...@@ -3,8 +3,6 @@ Question2Answer on GitHub ...@@ -3,8 +3,6 @@ Question2Answer on GitHub
By popular demand, beginning with version 1.5 beta 1, [Question2Answer] is now available here on GitHub for your forking and syncing pleasure. By popular demand, beginning with version 1.5 beta 1, [Question2Answer] is now available here on GitHub for your forking and syncing pleasure.
Please do not submit modifications / pull requests to this repository before discussing with me first. I'm new to the world of distributed version control and am likely to inadvertently ignore or overwrite your work. You can send me a message [here].
Thanks and enjoy! Thanks and enjoy!
Gideon Gideon
......
1.5.2 1.5.3
\ No newline at end of file \ No newline at end of file
...@@ -127,6 +127,8 @@ function qa_admin_click(target) ...@@ -127,6 +127,8 @@ function qa_admin_click(target)
} }
); );
qa_show_waiting_after(target, false);
return false; return false;
} }
......
...@@ -28,7 +28,7 @@ function qa_title_change(value) ...@@ -28,7 +28,7 @@ function qa_title_change(value)
if (lines[0]=='1') { if (lines[0]=='1') {
if (lines[1].length) { if (lines[1].length) {
qa_tags_examples=lines[1]; qa_tags_examples=lines[1];
qa_tag_hints(); qa_tag_hints(true);
} }
if (lines.length>2) { if (lines.length>2) {
...@@ -42,6 +42,18 @@ function qa_title_change(value) ...@@ -42,6 +42,18 @@ function qa_title_change(value)
else else
qa_ajax_error(); qa_ajax_error();
}); });
qa_show_waiting_after(document.getElementById('similar'), true);
}
function qa_html_unescape(html)
{
return html.replace(/&amp;/g, '&').replace(/&quot;/g, '"').replace(/&lt;/g, '<').replace(/&gt;/g, '>');
}
function qa_html_escape(text)
{
return text.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
} }
function qa_tag_click(link) function qa_tag_click(link)
...@@ -50,7 +62,7 @@ function qa_tag_click(link) ...@@ -50,7 +62,7 @@ function qa_tag_click(link)
var parts=qa_tag_typed_parts(elem); var parts=qa_tag_typed_parts(elem);
// removes any HTML tags and ampersand // removes any HTML tags and ampersand
var tag=link.innerHTML.replace(/<[^>]*>/g, '').replace('&amp;', '&'); var tag=qa_html_unescape(link.innerHTML.replace(/<[^>]*>/g, ''));
var separator=qa_tag_onlycomma ? ', ' : ' '; var separator=qa_tag_onlycomma ? ', ' : ' ';
...@@ -73,19 +85,22 @@ function qa_tag_click(link) ...@@ -73,19 +85,22 @@ function qa_tag_click(link)
function qa_tag_hints(skipcomplete) function qa_tag_hints(skipcomplete)
{ {
var elem=document.getElementById('tags'); var elem=document.getElementById('tags');
var parts=qa_tag_typed_parts(elem);
var html=''; var html='';
var completed=false; var completed=false;
// first try to auto-complete // first try to auto-complete
if (parts.typed && qa_tags_complete) { if (qa_tags_complete && !skipcomplete) {
html=qa_tags_to_html((qa_tags_examples+','+qa_tags_complete).split(','), parts.typed.toLowerCase().replace('&', '&amp;')); var parts=qa_tag_typed_parts(elem);
completed=html ? true : false;
if (parts.typed) {
html=qa_tags_to_html((qa_html_unescape(qa_tags_examples+','+qa_tags_complete)).split(','), parts.typed.toLowerCase());
completed=html ? true : false;
}
} }
// otherwise show examples // otherwise show examples
if (qa_tags_examples && !completed) if (qa_tags_examples && !completed)
html=qa_tags_to_html(qa_tags_examples.split(','), null); html=qa_tags_to_html((qa_html_unescape(qa_tags_examples)).split(','), null);
// set title visiblity and hint list // set title visiblity and hint list
document.getElementById('tag_examples_title').style.display=(html && !completed) ? '' : 'none'; document.getElementById('tag_examples_title').style.display=(html && !completed) ? '' : 'none';
...@@ -110,10 +125,10 @@ function qa_tags_to_html(tags, matchlc) ...@@ -110,10 +125,10 @@ function qa_tags_to_html(tags, matchlc)
if (matchlc) { // if matching, show appropriate part in bold if (matchlc) { // if matching, show appropriate part in bold
var matchstart=taglc.indexOf(matchlc); var matchstart=taglc.indexOf(matchlc);
var matchend=matchstart+matchlc.length; var matchend=matchstart+matchlc.length;
inner='<SPAN STYLE="font-weight:normal;">'+tag.substring(0, matchstart)+'<B>'+ inner='<SPAN STYLE="font-weight:normal;">'+qa_html_escape(tag.substring(0, matchstart))+'<B>'+
tag.substring(matchstart, matchend)+'</B>'+tag.substring(matchend)+'</SPAN>'; qa_html_escape(tag.substring(matchstart, matchend))+'</B>'+qa_html_escape(tag.substring(matchend))+'</SPAN>';
} else // otherwise show as-is } else // otherwise show as-is
inner=tag; inner=qa_html_escape(tag);
html+=qa_tag_template.replace(/\^/g, inner.replace('$', '$$$$'))+' '; // replace ^ in template, escape $s html+=qa_tag_template.replace(/\^/g, inner.replace('$', '$$$$'))+' '; // replace ^ in template, escape $s
...@@ -194,7 +209,7 @@ function qa_category_select(idprefix, startpath) ...@@ -194,7 +209,7 @@ function qa_category_select(idprefix, startpath)
if (val.length || (l==0)) { if (val.length || (l==0)) {
subelem=elem.parentNode.insertBefore(document.createElement('span'), elem.nextSibling); subelem=elem.parentNode.insertBefore(document.createElement('span'), elem.nextSibling);
subelem.id=idprefix+'_'+l+'_sub'; subelem.id=idprefix+'_'+l+'_sub';
subelem.innerHTML=' ...'; qa_show_waiting_after(subelem, true);
qa_ajax_post('category', {categoryid:val}, qa_ajax_post('category', {categoryid:val},
(function(elem, l) { (function(elem, l) {
...@@ -227,7 +242,7 @@ function qa_category_select(idprefix, startpath) ...@@ -227,7 +242,7 @@ function qa_category_select(idprefix, startpath)
if (String(qa_cat_exclude).length && (String(qa_cat_exclude)==parts[0])) if (String(qa_cat_exclude).length && (String(qa_cat_exclude)==parts[0]))
continue; continue;
newelem.options[newelem.options.length]=new Option(parts[1], parts[0]); newelem.options[newelem.options.length]=new Option(parts.slice(1).join('/'), parts[0]);
addedoption=true; addedoption=true;
} }
......
...@@ -48,6 +48,25 @@ function qa_set_outer_html(elem, type, html) ...@@ -48,6 +48,25 @@ function qa_set_outer_html(elem, type, html)
} }
} }
function qa_show_waiting_after(elem, inside)
{
if (elem && !elem.qa_waiting_shown) {
elem.qa_waiting_shown=true;
var w=document.getElementById('qa-waiting-template');
if (w) {
var c=w.cloneNode(true);
c.id=null;
if (inside)
elem.insertBefore(c, null);
else
elem.parentNode.insertBefore(c, elem.nextSibling);
}
}
}
function qa_vote_click(elem) function qa_vote_click(elem)
{ {
var ens=elem.name.split('_'); var ens=elem.name.split('_');
...@@ -112,6 +131,8 @@ function qa_favorite_click(elem) ...@@ -112,6 +131,8 @@ function qa_favorite_click(elem)
} }
); );
qa_show_waiting_after(elem, false);
return false; return false;
} }
......
...@@ -70,7 +70,7 @@ function qa_toggle_element(elem) ...@@ -70,7 +70,7 @@ function qa_toggle_element(elem)
return !(e||!elem); // failed to find item return !(e||!elem); // failed to find item
} }
function qa_submit_answer(questionid) function qa_submit_answer(questionid, elem)
{ {
var params=qa_form_params('a_form'); var params=qa_form_params('a_form');
...@@ -114,10 +114,12 @@ function qa_submit_answer(questionid) ...@@ -114,10 +114,12 @@ function qa_submit_answer(questionid)
} }
); );
qa_show_waiting_after(elem, false);
return false; return false;
} }
function qa_submit_comment(questionid, parentid) function qa_submit_comment(questionid, parentid, elem)
{ {
var params=qa_form_params('c_form_'+parentid); var params=qa_form_params('c_form_'+parentid);
...@@ -154,6 +156,8 @@ function qa_submit_comment(questionid, parentid) ...@@ -154,6 +156,8 @@ function qa_submit_comment(questionid, parentid)
} }
); );
qa_show_waiting_after(elem, false);
return false; return false;
} }
...@@ -186,6 +190,8 @@ function qa_answer_click(answerid, questionid, target) ...@@ -186,6 +190,8 @@ function qa_answer_click(answerid, questionid, target)
} }
); );
qa_show_waiting_after(target, false);
return false; return false;
} }
...@@ -217,10 +223,12 @@ function qa_comment_click(commentid, questionid, parentid, target) ...@@ -217,10 +223,12 @@ function qa_comment_click(commentid, questionid, parentid, target)
} }
); );
qa_show_waiting_after(target, false);
return false; return false;
} }
function qa_show_comments(parentid) function qa_show_comments(parentid, elem)
{ {
var params={}; var params={};
...@@ -240,6 +248,8 @@ function qa_show_comments(parentid) ...@@ -240,6 +248,8 @@ function qa_show_comments(parentid)
} }
); );
qa_show_waiting_after(elem, true);
return false; return false;
} }
......
...@@ -598,6 +598,49 @@ ...@@ -598,6 +598,49 @@
} }
function qa_avatar_html_from_userid($userid, $size, $padding)
/*
==========================================================================
YOU MAY MODIFY THIS FUNCTION, BUT THE DEFAULT BELOW WILL WORK OK
==========================================================================
qa_avatar_html_from_userid($userid, $size, $padding)
You should return some HTML for displaying the avatar of $userid on the page.
If you do not wish to show an avatar for this user, return null.
$size contains the maximum width and height of the avatar to be displayed, in pixels.
If $padding is true, the HTML you return should render to a square of $size x $size pixels,
even if the avatar is not square. This can be achieved using CSS padding - see function
qa_get_avatar_blob_html(...) in qa-app-format.php for an example. If $padding is false,
the HTML can render to anything which would fit inside a square of $size x $size pixels.
Note that this function may be called many times to render an individual page, so it is not
a good idea to perform a database query each time it is called. Instead, you can use the fact
that before qa_avatar_html_from_userid(...) is called, qa_get_users_html(...) will have been
called with all the relevant users in the array $userids. So you can pull out the information
you need in qa_get_users_html(...) and cache it in a global variable, for use in this function.
*/
{
return null; // show no avatars by default
/*
Example 1 - suitable if:
* All your avatars are square
* Your Q2A site: http://www.mysite.com/qa/
* Your avatar images: http://www.mysite.com/avatar/[userid]-[size]x[size].jpg
$htmlsize=(int)$size;
return '<IMG SRC="http://www.mysite.com/avatar/'.htmlspecialchars($userid).'-'.$htmlsize.'x'.$htmlsize.'.jpg" '.
'WIDTH="'.$htmlsize.'" HEIGHT="'.$htmlsize.'" CLASS="qa-avatar-image" ALT=""/>';
*/
}
function qa_user_report_action($userid, $action) function qa_user_report_action($userid, $action)
/* /*
========================================================================== ==========================================================================
......
...@@ -79,7 +79,7 @@ ...@@ -79,7 +79,7 @@
echo "QA_AJAX_RESPONSE\n1\n"; echo "QA_AJAX_RESPONSE\n1\n";
echo strtr(implode(',', $exampletags), "\r\n", ' ')."\n"; echo strtr(qa_html(implode(',', $exampletags)), "\r\n", ' ')."\n";
// Collect and output the list of related questions // Collect and output the list of related questions
......
...@@ -445,7 +445,7 @@ ...@@ -445,7 +445,7 @@
switch ($action) { switch ($action) {
case 'approve': case 'approve':
if ($queued && !qa_user_permit_error('permit_moderate')) { if ($queued && !qa_user_permit_error('permit_moderate')) {
qa_post_set_hidden($postid, false, null); qa_post_set_hidden($postid, false, $userid);
return true; return true;
} }
break; break;
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
{ {
qa_db_event_create_for_entity(QA_ENTITY_QUESTION, $questionid, $questionid, $lastpostid, $updatetype, $lastuserid, $timestamp); // anyone who favorited the question qa_db_event_create_for_entity(QA_ENTITY_QUESTION, $questionid, $questionid, $lastpostid, $updatetype, $lastuserid, $timestamp); // anyone who favorited the question
if (isset($lastuserid)) if (isset($lastuserid) && !QA_FINAL_EXTERNAL_USERS)
qa_db_event_create_for_entity(QA_ENTITY_USER, $lastuserid, $questionid, $lastpostid, $updatetype, $lastuserid, $timestamp); // anyone who favorited the user who did it qa_db_event_create_for_entity(QA_ENTITY_USER, $lastuserid, $questionid, $lastpostid, $updatetype, $lastuserid, $timestamp); // anyone who favorited the user who did it
if (isset($otheruserid) && ($otheruserid!=$lastuserid)) if (isset($otheruserid) && ($otheruserid!=$lastuserid))
......
...@@ -311,7 +311,7 @@ ...@@ -311,7 +311,7 @@
)); ));
if ($microformats) if ($microformats)
$fields['content']='<SPAN CLASS="entry-content">'.$fields['content'].'</SPAN>'; $fields['content']='<DIV CLASS="entry-content">'.$fields['content'].'</DIV>';
$fields['content']='<A NAME="'.qa_html($postid).'"></A>'.$fields['content']; $fields['content']='<A NAME="'.qa_html($postid).'"></A>'.$fields['content'];
// this is for backwards compatibility with any existing links using the old style of anchor // this is for backwards compatibility with any existing links using the old style of anchor
...@@ -357,11 +357,13 @@ ...@@ -357,11 +357,13 @@
// Pass information on vote viewing // Pass information on vote viewing
// $voteview will be one of: // $voteview will be one of:
// updown, updown-disabled-level, updown-disabled-page, updown-uponly-level // updown, updown-disabled-page, updown-disabled-level, updown-uponly-level
// net, net-disabled-level, net-disabled-page, net-uponly-level // net, net-disabled-page, net-disabled-level, net-uponly-level
$fields['vote_view']=(substr($voteview, 0, 6)=='updown') ? 'updown' : 'net'; $fields['vote_view']=(substr($voteview, 0, 6)=='updown') ? 'updown' : 'net';
$fields['vote_on_page']=strpos($voteview, '-disabled-page') ? 'disabled' : 'enabled';
$fields['upvotes_view']=($upvotes==1) ? qa_lang_html_sub_split('main/1_liked', $upvoteshtml, '1') $fields['upvotes_view']=($upvotes==1) ? qa_lang_html_sub_split('main/1_liked', $upvoteshtml, '1')
: qa_lang_html_sub_split('main/x_liked', $upvoteshtml); : qa_lang_html_sub_split('main/x_liked', $upvoteshtml);
...@@ -460,9 +462,13 @@ ...@@ -460,9 +462,13 @@
$fields['who']['level']=qa_html(qa_user_level_string($post['level'])); $fields['who']['level']=qa_html(qa_user_level_string($post['level']));
} }
if ((!QA_FINAL_EXTERNAL_USERS) && (@$options['avatarsize']>0)) if (@$options['avatarsize']>0) {
$fields['avatar']=qa_get_user_avatar_html(@$post['flags'], @$post['email'], @$post['handle'], if (QA_FINAL_EXTERNAL_USERS)
@$post['avatarblobid'], @$post['avatarwidth'], @$post['avatarheight'], $options['avatarsize']); $fields['avatar']=qa_get_external_avatar_html($post['userid'], $options['avatarsize'], false);
else
$fields['avatar']=qa_get_user_avatar_html(@$post['flags'], @$post['email'], @$post['handle'],
@$post['avatarblobid'], @$post['avatarwidth'], @$post['avatarheight'], $options['avatarsize']);
}
// Updated when and by whom // Updated when and by whom
...@@ -698,9 +704,13 @@ ...@@ -698,9 +704,13 @@
: qa_lang_html_sub_split('main/x_flags', $question['oflagcount']); : qa_lang_html_sub_split('main/x_flags', $question['oflagcount']);
unset($fields['avatar']); unset($fields['avatar']);
if ((!QA_FINAL_EXTERNAL_USERS) && (@$options['avatarsize']>0)) if (@$options['avatarsize']>0) {
$fields['avatar']=qa_get_user_avatar_html($question['oflags'], $question['oemail'], $question['ohandle'], if (QA_FINAL_EXTERNAL_USERS)
$question['oavatarblobid'], $question['oavatarwidth'], $question['oavatarheight'], $options['avatarsize']); $fields['avatar']=qa_get_external_avatar_html($post['ouserid'], $options['avatarsize'], false);
else
$fields['avatar']=qa_get_user_avatar_html($question['oflags'], $question['oemail'], $question['ohandle'],
$question['oavatarblobid'], $question['oavatarwidth'], $question['oavatarheight'], $options['avatarsize']);
}
return $fields; return $fields;
} }
...@@ -820,7 +830,7 @@ ...@@ -820,7 +830,7 @@
{ {
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); } if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
return trim(preg_replace('/([^A-Za-z0-9])((http|https|ftp):\/\/([^\s&<>"\'\.])+\.([^\s&<>"\']|&amp;)+)/i', '\1<A HREF="\2" rel="nofollow"'.($newwindow ? ' target="_blank"' : '').'>\2</A>', ' '.$html.' ')); return substr(preg_replace('/([^A-Za-z0-9])((http|https|ftp):\/\/([^\s&<>"\'\.])+\.([^\s&<>"\']|&amp;)+)/i', '\1<A HREF="\2" rel="nofollow"'.($newwindow ? ' target="_blank"' : '').'>\2</A>', ' '.$html.' '), 1, -1);
} }
...@@ -1094,7 +1104,7 @@ ...@@ -1094,7 +1104,7 @@
) { ) {
$url=qa_custom_page_url($page); $url=qa_custom_page_url($page);
$navigation[($page['flags'] & QA_PAGE_FLAGS_EXTERNAL) ? ('custom-'.$page['pageid']) : $page['tags']]=array( $navigation[($page['flags'] & QA_PAGE_FLAGS_EXTERNAL) ? ('custom-'.$page['pageid']) : ($page['tags'].'$')]=array(
'url' => qa_html($url), 'url' => qa_html($url),
'label' => qa_html($page['title']), 'label' => qa_html($page['title']),
'opposite' => ($page['nav']=='O'), 'opposite' => ($page['nav']=='O'),
...@@ -1408,10 +1418,10 @@ ...@@ -1408,10 +1418,10 @@
$classname='qa_html_theme_base'; $classname='qa_html_theme_base';
// Then load the selected theme if valid, otherwise load the default theme // Then load the selected theme if valid, otherwise load the Classic theme
if (!file_exists(QA_THEME_DIR.$theme.'/qa-styles.css')) if (!file_exists(QA_THEME_DIR.$theme.'/qa-styles.css'))
$theme='Default'; $theme='Classic';
$themeroothtml=qa_html(qa_path_to_root().'qa-theme/'.$theme.'/'); $themeroothtml=qa_html(qa_path_to_root().'qa-theme/'.$theme.'/');
...@@ -1613,10 +1623,10 @@ ...@@ -1613,10 +1623,10 @@
if (strlen($blobid) && ($size>0)) { if (strlen($blobid) && ($size>0)) {
qa_image_constrain($width, $height, $size); qa_image_constrain($width, $height, $size);
$html='<IMG SRC="'.qa_path('image', array('qa_blobid' => $blobid, 'qa_size' => $size), null, QA_URL_FORMAT_PARAMS). $html='<IMG SRC="'.qa_path_html('image', array('qa_blobid' => $blobid, 'qa_size' => $size), null, QA_URL_FORMAT_PARAMS).
'"'.(($width && $height) ? (' WIDTH="'.$width.'" HEIGHT="'.$height.'"') : '').' CLASS="qa-avatar-image"/>'; '"'.(($width && $height) ? (' WIDTH="'.$width.'" HEIGHT="'.$height.'"') : '').' CLASS="qa-avatar-image" ALT=""/>';
if ($padding) { if ($padding && $width && $height) {
$padleft=floor(($size-$width)/2); $padleft=floor(($size-$width)/2);
$padright=$size-$width-$padleft; $padright=$size-$width-$padleft;
$padtop=floor(($size-$height)/2); $padtop=floor(($size-$height)/2);
...@@ -1641,7 +1651,7 @@ ...@@ -1641,7 +1651,7 @@
if ($size>0) if ($size>0)
return '<IMG SRC="'.(qa_is_https_probably() ? 'https' : 'http'). return '<IMG SRC="'.(qa_is_https_probably() ? 'https' : 'http').
'://www.gravatar.com/avatar/'.md5(strtolower(trim($email))).'?s='.(int)$size. '://www.gravatar.com/avatar/'.md5(strtolower(trim($email))).'?s='.(int)$size.
'" WIDTH="'.(int)$size.'" HEIGHT="'.(int)$size.'" CLASS="qa-avatar-image"/>'; '" WIDTH="'.(int)$size.'" HEIGHT="'.(int)$size.'" CLASS="qa-avatar-image" ALT=""/>';
else else
return null; return null;
} }
......
...@@ -343,7 +343,7 @@ ...@@ -343,7 +343,7 @@
'show_user_points' => 1, 'show_user_points' => 1,
'show_user_titles' => 1, 'show_user_titles' => 1,
'show_when_created' => 1, 'show_when_created' => 1,
'site_theme' => 'Default', 'site_theme' => 'Snow',
'smtp_port' => 25, 'smtp_port' => 25,
'sort_answers_by' => 'created', 'sort_answers_by' => 'created',
'tags_or_categories' => 'tc', 'tags_or_categories' => 'tc',
...@@ -453,6 +453,8 @@ ...@@ -453,6 +453,8 @@
$captchamodules=qa_list_modules('captcha'); $captchamodules=qa_list_modules('captcha');
if (count($captchamodules)) if (count($captchamodules))
$value=reset($captchamodules); $value=reset($captchamodules);
else
$value='';
break; break;
case 'mailing_from_name': case 'mailing_from_name':
...@@ -556,20 +558,20 @@ ...@@ -556,20 +558,20 @@
if ($basetype=='Q') { if ($basetype=='Q') {
$view=qa_opt('voting_on_qs'); $view=qa_opt('voting_on_qs');
if (qa_user_permit_error('permit_vote_q')=='level') if (!($enabledif && ($full || !qa_opt('voting_on_q_page_only'))))
$disabledsuffix='-disabled-level';
elseif (!($enabledif && ($full || !qa_opt('voting_on_q_page_only'))))
$disabledsuffix='-disabled-page'; $disabledsuffix='-disabled-page';
elseif (qa_user_permit_error('permit_vote_q')=='level')
$disabledsuffix='-disabled-level';
elseif (qa_user_permit_error('permit_vote_down')=='level') elseif (qa_user_permit_error('permit_vote_down')=='level')
$disabledsuffix='-uponly-level'; $disabledsuffix='-uponly-level';
} elseif ($basetype=='A') { } elseif ($basetype=='A') {
$view=qa_opt('voting_on_as'); $view=qa_opt('voting_on_as');
if (qa_user_permit_error('permit_vote_a')=='level') if (!$enabledif)
$disabledsuffix='-disabled-level';
elseif (!$enabledif)
$disabledsuffix='-disabled-page'; $disabledsuffix='-disabled-page';
elseif (qa_user_permit_error('permit_vote_a')=='level')
$disabledsuffix='-disabled-level';
elseif (qa_user_permit_error('permit_vote_down')=='level') elseif (qa_user_permit_error('permit_vote_down')=='level')
$disabledsuffix='-uponly-level'; $disabledsuffix='-uponly-level';
......
...@@ -276,6 +276,7 @@ ...@@ -276,6 +276,7 @@
'categoryid' => $oldquestion['categoryid'], 'categoryid' => $oldquestion['categoryid'],
'notify' => isset($oldquestion['notify']), 'notify' => isset($oldquestion['notify']),
'email' => qa_email_validate($oldquestion['notify']) ? $oldquestion['notify'] : null, 'email' => qa_email_validate($oldquestion['notify']) ? $oldquestion['notify'] : null,
'delayed' => $oldquestion['created'],
)); ));
} }
} }
...@@ -502,6 +503,7 @@ ...@@ -502,6 +503,7 @@
'categoryid' => $oldanswer['categoryid'], 'categoryid' => $oldanswer['categoryid'],
'notify' => isset($oldanswer['notify']), 'notify' => isset($oldanswer['notify']),
'email' => qa_email_validate($oldanswer['notify']) ? $oldanswer['notify'] : null, 'email' => qa_email_validate($oldanswer['notify']) ? $oldanswer['notify'] : null,
'delayed' => $oldanswer['created'],
)); ));
} }
} }
...@@ -723,6 +725,7 @@ ...@@ -723,6 +725,7 @@
'categoryid' => $oldcomment['categoryid'], 'categoryid' => $oldcomment['categoryid'],
'notify' => isset($oldcomment['notify']), 'notify' => isset($oldcomment['notify']),
'email' => qa_email_validate($oldcomment['notify']) ? $oldcomment['notify'] : null, 'email' => qa_email_validate($oldcomment['notify']) ? $oldcomment['notify'] : null,
'delayed' => $oldcomment['created'],
)); ));
} }
} }
......
...@@ -172,29 +172,29 @@ ...@@ -172,29 +172,29 @@
$request.='/'.$slug; $request.='/'.$slug;
$navigation=array( $navigation=array(
'answers' => array( 'by-answers' => array(
'label' => qa_lang('main/nav_no_answer'), 'label' => qa_lang('main/nav_no_answer'),
'url' => qa_path_html($request), 'url' => qa_path_html($request),
), ),
'selected' => array( 'by-selected' => array(
'label' => qa_lang('main/nav_no_selected_answer'), 'label' => qa_lang('main/nav_no_selected_answer'),
'url' => qa_path_html($request, array('by' => 'selected')), 'url' => qa_path_html($request, array('by' => 'selected')),
), ),
'upvotes' => array( 'by-upvotes' => array(
'label' => qa_lang('main/nav_no_upvoted_answer'), 'label' => qa_lang('main/nav_no_upvoted_answer'),
'url' => qa_path_html($request, array('by' => 'upvotes')), 'url' => qa_path_html($request, array('by' => 'upvotes')),
), ),
); );
if (isset($navigation[$by])) if (isset($navigation['by-'.$by]))
$navigation[$by]['selected']=true; $navigation['by-'.$by]['selected']=true;
else else
$navigation['answers']['selected']=true; $navigation['by-answers']['selected']=true;
if (!qa_opt('voting_on_as')) if (!qa_opt('voting_on_as'))
unset($navigation['upvotes']); unset($navigation['by-upvotes']);
return $navigation; return $navigation;
} }
......
...@@ -114,6 +114,18 @@ ...@@ -114,6 +114,18 @@
} }
function qa_get_external_avatar_html($userid, $size, $padding=false)
/*
Return HTML to display for the avatar of $userid, constrained to $size pixels, with optional $padding to that size
*/
{
if (function_exists('qa_avatar_html_from_userid'))
return qa_avatar_html_from_userid($userid, $size, $padding);
else
return null;
}
} else { } else {
function qa_start_session() function qa_start_session()
......
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
*/ */
define('QA_VERSION', '1.5.2'); // also used as suffix for .js and .css requests define('QA_VERSION', '1.5.3'); // also used as suffix for .js and .css requests
define('QA_BUILD_DATE', '2012-04-29'); define('QA_BUILD_DATE', '2012-09-26');
// Execution section of this file - remainder contains function definitions // Execution section of this file - remainder contains function definitions
...@@ -687,10 +687,11 @@ ...@@ -687,10 +687,11 @@
} }
function qa_sanitize_html($html, $linksnewwindow=false) function qa_sanitize_html($html, $linksnewwindow=false, $storage=false)
/* /*
Return $html after ensuring it is safe, i.e. removing Javascripts and the like - uses htmLawed library Return $html after ensuring it is safe, i.e. removing Javascripts and the like - uses htmLawed library
Links open in a new window if $linksnewwindow is true Links open in a new window if $linksnewwindow is true. Set $storage to true if sanitization is for
storing in the database, rather than immediate display to user - some think this should be less strict.
*/ */
{ {
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); } if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
......
...@@ -27,6 +27,10 @@ ...@@ -27,6 +27,10 @@
define('QA_BASE_DIR', dirname(dirname(empty($_SERVER['SCRIPT_FILENAME']) ? __FILE__ : $_SERVER['SCRIPT_FILENAME'])).'/'); define('QA_BASE_DIR', dirname(dirname(empty($_SERVER['SCRIPT_FILENAME']) ? __FILE__ : $_SERVER['SCRIPT_FILENAME'])).'/');
require 'qa-base.php'; require 'qa-base.php';
require_once QA_INCLUDE_DIR.'qa-app-users.php';
if (qa_get_logged_in_level() < QA_USER_LEVEL_ADMIN)
qa_redirect('admin/general', null, qa_opt('site_url'));
header('Content-type: text/html; charset=utf-8'); header('Content-type: text/html; charset=utf-8');
?> ?>
...@@ -193,7 +197,7 @@ ...@@ -193,7 +197,7 @@
foreach ($langnewphrases as $prefix => $phrases) { foreach ($langnewphrases as $prefix => $phrases) {
echo '<H2>'.$language.' phrases to add to <code>qa-lang/'.$code.'/qa-lang-'.$prefix.'.php</code>:</H2>'; echo '<H2>'.$language.' phrases to add to <code>qa-lang/'.$code.'/qa-lang-'.$prefix.'.php</code>:</H2>';
echo 'Copy and paste this into the middle of <code>qa-lang/'.$code.'/qa-lang-'.$prefix.'.php</code> then translate the right-hand sides after the <code>=></code> symbol.'; echo 'Copy and paste this into the middle of <code>qa-lang/'.$code.'/qa-lang-'.$prefix.'.php</code> then translate the right-hand side after the <code>=></code> symbol.';
echo '<PRE>'; echo '<PRE>';
......
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
@define('QA_DB_RETRIEVE_TAGS', 200); @define('QA_DB_RETRIEVE_TAGS', 200);
@define('QA_DB_RETRIEVE_USERS', 200); @define('QA_DB_RETRIEVE_USERS', 200);
@define('QA_DB_RETRIEVE_ASK_TAG_QS', 500); @define('QA_DB_RETRIEVE_ASK_TAG_QS', 500);
@define('QA_DB_RETRIEVE_COMPLETE_TAGS', 10000); @define('QA_DB_RETRIEVE_COMPLETE_TAGS', 1000);
@define('QA_DB_RETRIEVE_MESSAGES', 10); @define('QA_DB_RETRIEVE_MESSAGES', 10);
......
...@@ -221,7 +221,7 @@ ...@@ -221,7 +221,7 @@
if (!isset($wordtoid[$word])) if (!isset($wordtoid[$word]))
$rowstoadd[]=array($word); $rowstoadd[]=array($word);
qa_db_query_sub('INSERT INTO ^words (word) VALUES $', $rowstoadd); qa_db_query_sub('INSERT IGNORE INTO ^words (word) VALUES $', $rowstoadd);
qa_db_query_sub('UNLOCK TABLES'); qa_db_query_sub('UNLOCK TABLES');
......
...@@ -370,7 +370,7 @@ ...@@ -370,7 +370,7 @@
Return the ids of up to $limit posts of $type that can be deleted from the database (i.e. have no dependents) Return the ids of up to $limit posts of $type that can be deleted from the database (i.e. have no dependents)
*/ */
{ {
$limitsql=isset($limit) ? (' LIMIT '.(int)$limit) : ''; $limitsql=isset($limit) ? (' ORDER BY ^posts.postid LIMIT '.(int)$limit) : '';
return qa_db_read_all_values(qa_db_query_sub( return qa_db_read_all_values(qa_db_query_sub(
"SELECT ^posts.postid FROM ^posts LEFT JOIN ^posts AS child ON child.parentid=^posts.postid WHERE ^posts.type=$ AND ^posts.postid>=# AND child.postid IS NULL".$limitsql, "SELECT ^posts.postid FROM ^posts LEFT JOIN ^posts AS child ON child.parentid=^posts.postid WHERE ^posts.type=$ AND ^posts.postid>=# AND child.postid IS NULL".$limitsql,
......
...@@ -207,9 +207,7 @@ ...@@ -207,9 +207,7 @@
if ($full) { if ($full) {
$selectspec['columns']['ocontent']=$poststable.'.content'; $selectspec['columns']['ocontent']=$poststable.'.content';
$selectspec['columns']['oformat']=$poststable.'.format'; $selectspec['columns']['oformat']=$poststable.'.format';
$selectspec['columns']['oupdated']='UNIX_TIMESTAMP('.$poststable.'.updated)';
if (!$fromupdated)
$selectspec['columns']['oupdated']='UNIX_TIMESTAMP('.$poststable.'.updated)';
} }
} }
...@@ -1123,7 +1121,7 @@ ...@@ -1123,7 +1121,7 @@
from offset $start. The selectspec will produce a sorted array with tags in the key, and counts in the values. from offset $start. The selectspec will produce a sorted array with tags in the key, and counts in the values.
*/ */
{ {
$count=isset($count) ? min($count, QA_DB_RETRIEVE_TAGS) : QA_DB_RETRIEVE_TAGS; $count=isset($count) ? $count : QA_DB_RETRIEVE_TAGS;
return array( return array(
'columns' => array('word', 'tagcount'), 'columns' => array('word', 'tagcount'),
...@@ -1448,7 +1446,7 @@ ...@@ -1448,7 +1446,7 @@
$selectspec['source'].= $selectspec['source'].=
" JOIN ^posts AS updateposts ON updateposts.postid=fullevents.lastpostid AND updateposts.type IN ('Q', 'A', 'C')". " JOIN ^posts AS updateposts ON updateposts.postid=fullevents.lastpostid AND updateposts.type IN ('Q', 'A', 'C')".
" AND (^posts.selchildid=fullevents.lastpostid OR NOT fullevents.updatetype<=>$) AND ^posts.type IN ('Q', 'A', 'C')". " AND (^posts.selchildid=fullevents.lastpostid OR NOT fullevents.updatetype<=>$) AND ^posts.type='Q'".
(QA_FINAL_EXTERNAL_USERS ? '' : ' LEFT JOIN ^users AS eventusers ON fullevents.lastuserid=eventusers.userid'). (QA_FINAL_EXTERNAL_USERS ? '' : ' LEFT JOIN ^users AS eventusers ON fullevents.lastuserid=eventusers.userid').
' LEFT JOIN ^userpoints AS eventuserpoints ON fullevents.lastuserid=eventuserpoints.userid'; ' LEFT JOIN ^userpoints AS eventuserpoints ON fullevents.lastuserid=eventuserpoints.userid';
$selectspec['arguments'][]=QA_UPDATE_SELECTED; $selectspec['arguments'][]=QA_UPDATE_SELECTED;
......
...@@ -81,10 +81,10 @@ ...@@ -81,10 +81,10 @@
'u_block', 'u_edit', 'u_level', 'u_message', 'u_password', 'u_save', 'u_unblock', 'u_block', 'u_edit', 'u_level', 'u_message', 'u_password', 'u_save', 'u_unblock',
); );
if ( if ((!isset($params['delayed'])) && (
is_numeric(array_search(strstr($event, '_'), $writeactions)) || is_numeric(array_search(strstr($event, '_'), $writeactions)) ||
is_numeric(array_search($event, $writeactions)) is_numeric(array_search($event, $writeactions))
) { )) {
if (isset($userid)) { if (isset($userid)) {
require_once QA_INCLUDE_DIR.'qa-app-users.php'; require_once QA_INCLUDE_DIR.'qa-app-users.php';
......
...@@ -97,14 +97,25 @@ ...@@ -97,14 +97,25 @@
function qa_get_public_from_userids($userids) function qa_get_public_from_userids($userids)
{ {
global $wpdb; global $wpdb, $qa_cache_wp_user_emails;
if (count($userids)) if (count($userids)) {
return qa_db_read_all_assoc(qa_db_query_sub( $useridtopublic=array();
'SELECT user_nicename, ID FROM '.$wpdb->base_prefix.'users WHERE ID IN (#)', $qa_cache_wp_user_emails=array();
$userfields=qa_db_read_all_assoc(qa_db_query_sub(
'SELECT ID, user_nicename, user_email FROM '.$wpdb->base_prefix.'users WHERE ID IN (#)',
$userids $userids
), 'ID', 'user_nicename'); ), 'ID');
else
foreach ($userfields as $id => $fields) {
$useridtopublic[$id]=$fields['user_nicename'];
$qa_cache_wp_user_emails[$id]=$fields['user_email'];
}
return $useridtopublic;
} else
return array(); return array();
} }
...@@ -136,6 +147,19 @@ ...@@ -136,6 +147,19 @@
return $usershtml; return $usershtml;
} }
function qa_avatar_html_from_userid($userid, $size, $padding)
{
require_once QA_INCLUDE_DIR.'qa-app-format.php';
global $qa_cache_wp_user_emails;
if (isset($qa_cache_wp_user_emails[$userid]))
return qa_get_gravatar_html($qa_cache_wp_user_emails[$userid], $size);
return null;
}
function qa_user_report_action($userid, $action) function qa_user_report_action($userid, $action)
......
...@@ -253,7 +253,7 @@ ...@@ -253,7 +253,7 @@
foreach ($modules as $modulename => $module) { foreach ($modules as $modulename => $module) {
$queries=$module->init_queries($tables); $queries=$module->init_queries($tables);
if (!empty($queries)) { // also allows single query to be returned if (!empty($queries)) { // also allows single query to be returned
$errorhtml.=strtr(qa_lang_html('admin/module_x_database_init'), array( $errorhtml=strtr(qa_lang_html('admin/module_x_database_init'), array(
'^1' => qa_html($modulename), '^1' => qa_html($modulename),
'^2' => qa_html($moduletype), '^2' => qa_html($moduletype),
'^3' => '', '^3' => '',
......
...@@ -98,6 +98,7 @@ ...@@ -98,6 +98,7 @@
'register_title' => 'Register as a new user', 'register_title' => 'Register as a new user',
'registered_user' => 'Registered user', 'registered_user' => 'Registered user',
'remember_label' => 'Remember me on this computer', 'remember_label' => 'Remember me on this computer',
'remember' => 'Remember',
'remove_avatar' => 'Remove avatar:', 'remove_avatar' => 'Remove avatar:',
'reset_code_another' => 'send another', 'reset_code_another' => 'send another',
'reset_code_emailed' => 'You have been emailed your reset code', 'reset_code_emailed' => 'You have been emailed your reset code',
......
...@@ -240,6 +240,7 @@ ...@@ -240,6 +240,7 @@
'flagging_notify_every' => 1, 'flagging_notify_every' => 1,
'flagging_notify_first' => 1, 'flagging_notify_first' => 1,
'max_num_q_tags' => 2, 'max_num_q_tags' => 2,
'max_rate_ip_logins' => 1,
'page_size_activity' => 1, 'page_size_activity' => 1,
'page_size_ask_check_qs' => 3, 'page_size_ask_check_qs' => 3,
'page_size_ask_tags' => 3, 'page_size_ask_tags' => 3,
...@@ -296,9 +297,14 @@ ...@@ -296,9 +297,14 @@
if (qa_has_gd_image()) if (qa_has_gd_image())
array_push($showoptions, 'avatar_allow_upload', 'avatar_store_size', 'avatar_default_show'); array_push($showoptions, 'avatar_allow_upload', 'avatar_store_size', 'avatar_default_show');
array_push($showoptions, '', 'avatar_profile_size', 'avatar_users_size', 'avatar_q_page_q_size', 'avatar_q_page_a_size', 'avatar_q_page_c_size', 'avatar_q_list_size', '');
} }
$showoptions[]='';
if (!QA_FINAL_EXTERNAL_USERS)
$showoptions[]='avatar_profile_size';
array_push($showoptions, 'avatar_users_size', 'avatar_q_page_q_size', 'avatar_q_page_a_size', 'avatar_q_page_c_size', 'avatar_q_list_size');
$checkboxtodisplay=array( $checkboxtodisplay=array(
'custom_register' => 'option_show_custom_register', 'custom_register' => 'option_show_custom_register',
...@@ -308,13 +314,17 @@ ...@@ -308,13 +314,17 @@
'show_message_history' => 'option_allow_private_messages', 'show_message_history' => 'option_allow_private_messages',
'avatar_store_size' => 'option_avatar_allow_upload', 'avatar_store_size' => 'option_avatar_allow_upload',
'avatar_default_show' => 'option_avatar_allow_gravatar || option_avatar_allow_upload', 'avatar_default_show' => 'option_avatar_allow_gravatar || option_avatar_allow_upload',
'avatar_profile_size' => 'option_avatar_allow_gravatar || option_avatar_allow_upload',
'avatar_users_size' => 'option_avatar_allow_gravatar || option_avatar_allow_upload',
'avatar_q_page_q_size' => 'option_avatar_allow_gravatar || option_avatar_allow_upload',
'avatar_q_page_a_size' => 'option_avatar_allow_gravatar || option_avatar_allow_upload',
'avatar_q_page_c_size' => 'option_avatar_allow_gravatar || option_avatar_allow_upload',
'avatar_q_list_size' => 'option_avatar_allow_gravatar || option_avatar_allow_upload',
); );
if (!QA_FINAL_EXTERNAL_USERS)
$checkboxtodisplay=array_merge($checkboxtodisplay, array(
'avatar_profile_size' => 'option_avatar_allow_gravatar || option_avatar_allow_upload',
'avatar_users_size' => 'option_avatar_allow_gravatar || option_avatar_allow_upload',
'avatar_q_page_q_size' => 'option_avatar_allow_gravatar || option_avatar_allow_upload',
'avatar_q_page_a_size' => 'option_avatar_allow_gravatar || option_avatar_allow_upload',
'avatar_q_page_c_size' => 'option_avatar_allow_gravatar || option_avatar_allow_upload',
'avatar_q_list_size' => 'option_avatar_allow_gravatar || option_avatar_allow_upload',
));
$formstyle='wide'; $formstyle='wide';
break; break;
...@@ -925,9 +935,9 @@ ...@@ -925,9 +935,9 @@
case 'site_theme_mobile': case 'site_theme_mobile':
$themeoptions=qa_admin_theme_options(); $themeoptions=qa_admin_theme_options();
if (!isset($themeoptions[$value])) if (!isset($themeoptions[$value]))
$value='Default'; // check here because we also need $value for qa_admin_addon_metadata() $value='Classic'; // check here because we also need $value for qa_admin_addon_metadata()
qa_optionfield_make_select($optionfield, $themeoptions, $value, 'Default'); qa_optionfield_make_select($optionfield, $themeoptions, $value, 'Classic');
$contents=file_get_contents(QA_THEME_DIR.$value.'/qa-styles.css'); $contents=file_get_contents(QA_THEME_DIR.$value.'/qa-styles.css');
...@@ -1436,6 +1446,8 @@ ...@@ -1436,6 +1446,8 @@
$listhtml.='<LI><B><A HREF="'.qa_path_html('admin/userfields').'">'.qa_lang_html('admin/add_new_field').'</A></B></LI>'; $listhtml.='<LI><B><A HREF="'.qa_path_html('admin/userfields').'">'.qa_lang_html('admin/add_new_field').'</A></B></LI>';
$qa_content['form']['fields'][]=array('type' => 'blank');
$qa_content['form']['fields']['userfields']=array( $qa_content['form']['fields']['userfields']=array(
'label' => qa_lang_html('admin/profile_fields'), 'label' => qa_lang_html('admin/profile_fields'),
'style' => 'tall', 'style' => 'tall',
......
...@@ -46,11 +46,17 @@ ...@@ -46,11 +46,17 @@
$usecaptcha=qa_opt('captcha_on_feedback') && qa_user_use_captcha(); $usecaptcha=qa_opt('captcha_on_feedback') && qa_user_use_captcha();
// Check feedback is enabled // Check feedback is enabled and the person isn't blocked
if (!qa_opt('feedback_enabled')) if (!qa_opt('feedback_enabled'))
return include QA_INCLUDE_DIR.'qa-page-not-found.php'; return include QA_INCLUDE_DIR.'qa-page-not-found.php';
if (qa_user_permit_error()) {
$qa_content=qa_content_prepare();
$qa_content['error']=qa_lang_html('users/no_permission');
return $qa_content;
}
// Send the feedback form // Send the feedback form
......
...@@ -200,7 +200,7 @@ ...@@ -200,7 +200,7 @@
$hasother=isset($question['opostid']); $hasother=isset($question['opostid']);
if ($question[$hasother ? 'ohidden' : 'hidden']) { if ($question[$hasother ? 'ohidden' : 'hidden'] && !isset($question[$hasother ? 'oupdatetype' : 'updatetype'])) {
$htmlfields['what_2']=qa_lang_html('main/hidden'); $htmlfields['what_2']=qa_lang_html('main/hidden');
if (@$htmloptions['whenview']) if (@$htmloptions['whenview'])
......
...@@ -167,7 +167,7 @@ ...@@ -167,7 +167,7 @@
(($nothiddenbyother && !$post['flagcount']) || !qa_user_permit_error('permit_hide_show')); (($nothiddenbyother && !$post['flagcount']) || !qa_user_permit_error('permit_hide_show'));
// cannot reshow a question if it was hidden by someone else, or if it has flags - unless you have global hiding permissions // cannot reshow a question if it was hidden by someone else, or if it has flags - unless you have global hiding permissions
$rules['deleteable']=$post['hidden'] && !qa_user_permit_error('permit_delete_hidden'); $rules['deleteable']=$post['hidden'] && !qa_user_permit_error('permit_delete_hidden');
$rules['claimable']=(!isset($post['userid'])) && isset($userid) && (strcmp(@$post['cookieid'], $cookieid)==0) && $rules['claimable']=(!isset($post['userid'])) && isset($userid) && strlen(@$post['cookieid']) && (strcmp(@$post['cookieid'], $cookieid)==0) &&
!(($post['basetype']=='Q') ? $permiterror_post_q : (($post['basetype']=='A') ? $permiterror_post_a : $permiterror_post_c)); !(($post['basetype']=='Q') ? $permiterror_post_q : (($post['basetype']=='A') ? $permiterror_post_a : $permiterror_post_c));
$rules['followable']=($post['type']=='A') ? qa_opt('follow_on_as') : false; $rules['followable']=($post['type']=='A') ? qa_opt('follow_on_as') : false;
...@@ -687,10 +687,9 @@ ...@@ -687,10 +687,9 @@
if ($skipfirst>0) if ($skipfirst>0)
$commentlist['cs'][$parentid]=array( $commentlist['cs'][$parentid]=array(
'url' => '?state=showcomments-'.qa_html($parentid).'&show='.qa_html($parentid). 'url' => qa_html('?state=showcomments-'.$parentid.'&show='.$parentid.'#'.urlencode(qa_anchor($parent['basetype'], $parentid))),
'#'.qa_html(urlencode(qa_anchor($parent['basetype'], $parentid))),
'expand_tags' => 'onClick="return qa_show_comments('.qa_js($parentid).');"', 'expand_tags' => 'onClick="return qa_show_comments('.qa_js($parentid).', this);"',
'title' => $expandtitle, 'title' => $expandtitle,
); );
...@@ -781,7 +780,7 @@ ...@@ -781,7 +780,7 @@
'buttons' => array( 'buttons' => array(
'answer' => array( 'answer' => array(
'tags' => 'onClick="'.$updatescript.' return qa_submit_answer('.qa_js($questionid).');"', 'tags' => 'onClick="'.$updatescript.' return qa_submit_answer('.qa_js($questionid).', this);"',
'label' => qa_lang_html('question/add_answer_button'), 'label' => qa_lang_html('question/add_answer_button'),
), ),
), ),
...@@ -908,7 +907,7 @@ ...@@ -908,7 +907,7 @@
'buttons' => array( 'buttons' => array(
'comment' => array( 'comment' => array(
'tags' => 'onClick="'.$updatescript.' return qa_submit_comment('.qa_js($questionid).', '.qa_js($parentid).');"', 'tags' => 'onClick="'.$updatescript.' return qa_submit_comment('.qa_js($questionid).', '.qa_js($parentid).', this);"',
'label' => qa_lang_html('question/add_comment_button'), 'label' => qa_lang_html('question/add_comment_button'),
), ),
......
...@@ -216,8 +216,6 @@ ...@@ -216,8 +216,6 @@
$qa_content['description']=qa_html(qa_shorten_string_line(qa_viewer_text($question['content'], $question['format']), 150)); $qa_content['description']=qa_html(qa_shorten_string_line(qa_viewer_text($question['content'], $question['format']), 150));
$qa_content['canonical']=qa_q_path_html($question['postid'], $question['title'], true);
$categorykeyword=@$categories[$question['categoryid']]['title']; $categorykeyword=@$categories[$question['categoryid']]['title'];
$qa_content['keywords']=qa_html(implode(',', array_merge( $qa_content['keywords']=qa_html(implode(',', array_merge(
...@@ -338,6 +336,11 @@ ...@@ -338,6 +336,11 @@
$pagestart=floor($position/$pagesize)*$pagesize; $pagestart=floor($position/$pagesize)*$pagesize;
} }
// set the canonical url based on possible pagination
$qa_content['canonical']=qa_path_html(qa_q_request($question['postid'], $question['title']),
($pagestart>0) ? array('start' => $pagestart) : null, qa_opt('site_url'));
// build the actual answer list // build the actual answer list
$answerids=array_slice($answerids, $pagestart, $pagesize); $answerids=array_slice($answerids, $pagestart, $pagesize);
......
...@@ -60,8 +60,12 @@ ...@@ -60,8 +60,12 @@
if (count($users)) { if (count($users)) {
foreach ($users as $userid => $user) foreach ($users as $userid => $user)
$qa_content['ranking']['items'][]=array( $qa_content['ranking']['items'][]=array(
'label' => (QA_FINAL_EXTERNAL_USERS ? '' : (qa_get_user_avatar_html($user['flags'], $user['email'], $user['handle'], 'label' =>
$user['avatarblobid'], $user['avatarwidth'], $user['avatarheight'], qa_opt('avatar_users_size'), true).' ')).$usershtml[$user['userid']], (QA_FINAL_EXTERNAL_USERS
? qa_get_external_avatar_html($user['userid'], qa_opt('avatar_users_size'), true)
: qa_get_user_avatar_html($user['flags'], $user['email'], $user['handle'],
$user['avatarblobid'], $user['avatarwidth'], $user['avatarheight'], qa_opt('avatar_users_size'), true)
).' '.$usershtml[$user['userid']],
'score' => qa_html(number_format($user['points'])), 'score' => qa_html(number_format($user['points'])),
); );
......
...@@ -611,7 +611,7 @@ ...@@ -611,7 +611,7 @@
$qa_content['logo']='<A HREF="'.qa_path_html('').'" CLASS="qa-logo-link" TITLE="'.qa_html(qa_opt('site_title')).'">'. $qa_content['logo']='<A HREF="'.qa_path_html('').'" CLASS="qa-logo-link" TITLE="'.qa_html(qa_opt('site_title')).'">'.
'<IMG SRC="'.qa_html(is_numeric(strpos($logourl, '://')) ? $logourl : qa_path_to_root().$logourl).'"'. '<IMG SRC="'.qa_html(is_numeric(strpos($logourl, '://')) ? $logourl : qa_path_to_root().$logourl).'"'.
($logowidth ? (' WIDTH="'.$logowidth.'"') : '').($logoheight ? (' HEIGHT="'.$logoheight.'"') : ''). ($logowidth ? (' WIDTH="'.$logowidth.'"') : '').($logoheight ? (' HEIGHT="'.$logoheight.'"') : '').
' BORDER="0"/></A>'; ' BORDER="0" ALT="'.qa_html(qa_opt('site_title')).'"/></A>';
else else
$qa_content['logo']='<A HREF="'.qa_path_html('').'" CLASS="qa-logo-link">'.qa_html(qa_opt('site_title')).'</A>'; $qa_content['logo']='<A HREF="'.qa_path_html('').'" CLASS="qa-logo-link">'.qa_html(qa_opt('site_title')).'</A>';
...@@ -704,7 +704,7 @@ ...@@ -704,7 +704,7 @@
$qa_content['notices'][]=qa_notice_form('welcome', qa_opt('notice_welcome')); $qa_content['notices'][]=qa_notice_form('welcome', qa_opt('notice_welcome'));
} }
$qa_content['script_rel']=array('qa-content/jquery-1.7.1.min.js'); $qa_content['script_rel']=array('qa-content/jquery-1.7.2.min.js');
$qa_content['script_rel'][]='qa-content/qa-page.js?'.QA_VERSION; $qa_content['script_rel'][]='qa-content/qa-page.js?'.QA_VERSION;
if ($voting) if ($voting)
......
...@@ -555,8 +555,17 @@ ...@@ -555,8 +555,17 @@
$blockwords=qa_block_words_explode($wordsstring); $blockwords=qa_block_words_explode($wordsstring);
$patterns=array(); $patterns=array();
foreach ($blockwords as $blockword) // * in rule maps to [^ ]* in regular expression foreach ($blockwords as $blockword) { // * in rule maps to [^ ]* in regular expression
$patterns[]=str_replace('\\*', '[^ ]*', preg_quote(qa_strtolower($blockword))); $pattern=str_replace('\\*', '[^ ]*', preg_quote(qa_strtolower($blockword), '/'));
if (!preg_match('/^('.QA_PREG_CJK_IDEOGRAPHS_UTF8.')/', $blockword))
$pattern='(?<= )'.$pattern; // assert leading word delimiter if pattern does not start with CJK
if (!preg_match('/('.QA_PREG_CJK_IDEOGRAPHS_UTF8.')$/', $blockword))
$pattern=$pattern.'(?= )'; // assert trailing word delimiter if pattern does not end with CJK
$patterns[]=$pattern;
}
return implode('|', $patterns); return implode('|', $patterns);
} }
...@@ -584,10 +593,10 @@ ...@@ -584,10 +593,10 @@
// assumes UTF-8 case conversion in qa_strtolower does not change byte length // assumes UTF-8 case conversion in qa_strtolower does not change byte length
$string=preg_replace('/'.QA_PREG_BLOCK_WORD_SEPARATOR.'/', ' ', $string); $string=preg_replace('/'.QA_PREG_BLOCK_WORD_SEPARATOR.'/', ' ', $string);
preg_match_all('/(?<= )('.$wordspreg.') /', ' '.$string.' ', $pregmatches, PREG_OFFSET_CAPTURE); preg_match_all('/'.$wordspreg.'/', ' '.$string.' ', $pregmatches, PREG_OFFSET_CAPTURE);
$outmatches=array(); $outmatches=array();
foreach ($pregmatches[1] as $pregmatch) foreach ($pregmatches[0] as $pregmatch)
$outmatches[$pregmatch[1]-1]=strlen($pregmatch[0]); $outmatches[$pregmatch[1]-1]=strlen($pregmatch[0]);
return $outmatches; return $outmatches;
......
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
function get_html($content, $format, $options) function get_html($content, $format, $options)
{ {
if ($format=='html') { if ($format=='html') {
$html=qa_sanitize_html($content, @$options['linksnewwindow']); // sanitize again for display, for extra safety, and due to new window setting $html=qa_sanitize_html($content, @$options['linksnewwindow'], false); // sanitize again for display, for extra safety, and due to new window setting
if (isset($options['blockwordspreg'])) { // filtering out blocked words inline within HTML is pretty complex, e.g. p<B>oo</B>p must be caught if (isset($options['blockwordspreg'])) { // filtering out blocked words inline within HTML is pretty complex, e.g. p<B>oo</B>p must be caught
require_once QA_INCLUDE_DIR.'qa-util-string.php'; require_once QA_INCLUDE_DIR.'qa-util-string.php';
...@@ -99,7 +99,27 @@ ...@@ -99,7 +99,27 @@
$nexttagmatch=array_shift($tagmatches); $nexttagmatch=array_shift($tagmatches);
} }
} }
} }
if (@$options['showurllinks']) { // we need to ensure here that we don't put new links inside existing ones
require_once QA_INCLUDE_DIR.'qa-util-string.php';
$htmlunlinkeds=array_reverse(preg_split('|<[Aa]\s+[^>]+>.*</[Aa]\s*>|', $html, -1, PREG_SPLIT_OFFSET_CAPTURE)); // start from end so we substitute correctly
foreach ($htmlunlinkeds as $htmlunlinked) { // and that we don't detect links inside HTML, e.g. <IMG SRC="http://...">
$thishtmluntaggeds=array_reverse(preg_split('/<[^>]*>/', $htmlunlinked[0], -1, PREG_SPLIT_OFFSET_CAPTURE)); // again, start from end
foreach ($thishtmluntaggeds as $thishtmluntagged) {
$innerhtml=$thishtmluntagged[0];
if (is_numeric(strpos($innerhtml, '://'))) { // quick test first
$newhtml=qa_html_convert_urls($innerhtml, qa_opt('links_in_new_window'));
$html=substr_replace($html, $newhtml, $htmlunlinked[1]+$thishtmluntagged[1], strlen($innerhtml));
}
}
}
}
} elseif ($format=='') { } elseif ($format=='') {
if (isset($options['blockwordspreg'])) { if (isset($options['blockwordspreg'])) {
......
<?php
/*
Question2Answer (c) Gideon Greenspan
http://www.question2answer.org/
File: qa-plugin/facebook-login/qa-facebook-layer.php
Version: See define()s at top of qa-include/qa-base.php
Description: Theme layer class for mouseover layer plugin
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
More about this license: http://www.question2answer.org/license.php
*/
class qa_html_theme_layer extends qa_html_theme_base {
function head_css()
{
qa_html_theme_base::head_css();
if (strlen(qa_opt('facebook_app_id')) && strlen(qa_opt('facebook_app_secret')))
$this->output(
'<STYLE><!--',
'.fb-login-button.fb_iframe_widget.fb_hide_iframes span {display:none;}',
'--></STYLE>'
);
}
}
/*
Omit PHP closing tag to help avoid accidental output
*/
\ No newline at end of file
...@@ -111,7 +111,7 @@ ...@@ -111,7 +111,7 @@
if (!strlen($app_id)) if (!strlen($app_id))
return; return;
$this->facebook_html($tourl, false); $this->facebook_html($tourl, false, $context);
} }
...@@ -123,14 +123,18 @@ ...@@ -123,14 +123,18 @@
return; return;
if (isset($_COOKIE['fbsr_'.$app_id])) // check we still have a Facebook cookie ... if (isset($_COOKIE['fbsr_'.$app_id])) // check we still have a Facebook cookie ...
$this->facebook_html($tourl, true); $this->facebook_html($tourl, true, 'menu');
else // ... if not, show a standard logout link, since sometimes the redirect to Q2A's logout page doesn't complete else // ... if not, show a standard logout link, since sometimes the redirect to Q2A's logout page doesn't complete
echo '<A HREF="'.qa_html($tourl).'">'.qa_lang_html('main/nav_logout').'</A>'; echo '<A HREF="'.qa_html($tourl).'">'.qa_lang_html('main/nav_logout').'</A>';
} }
function facebook_html($tourl, $logout) function facebook_html($tourl, $logout, $context)
{ {
if (($context=='login') || ($context=='register'))
$size='large';
else
$size='medium';
?> ?>
<div id="fb-root" style="display:inline;"></div> <div id="fb-root" style="display:inline;"></div>
...@@ -155,8 +159,7 @@ ...@@ -155,8 +159,7 @@
d.getElementsByTagName('head')[0].appendChild(js); d.getElementsByTagName('head')[0].appendChild(js);
}(document)); }(document));
</script> </script>
<div class="fb-login-button" style="display:inline;" <?php echo $logout ? 'autologoutlink="true"' : 'scope="email,user_about_me,user_location,user_website"'?>> <div class="fb-login-button" style="display:inline; vertical-align:middle;" size="<?php echo $size?>" <?php echo $logout ? 'autologoutlink="true"' : 'scope="email,user_about_me,user_location,user_website"'?>>
<?php echo qa_lang_html($logout ? 'main/nav_logout' : 'main/nav_login')?>
</div> </div>
<?php <?php
......
...@@ -28,12 +28,12 @@ ...@@ -28,12 +28,12 @@
Plugin Name: Facebook Login Plugin Name: Facebook Login
Plugin URI: Plugin URI:
Plugin Description: Allows users to log in via Facebook Plugin Description: Allows users to log in via Facebook
Plugin Version: 1.1.1 Plugin Version: 1.1.5
Plugin Date: 2012-03-13 Plugin Date: 2012-09-13
Plugin Author: Question2Answer Plugin Author: Question2Answer
Plugin Author URI: http://www.question2answer.org/ Plugin Author URI: http://www.question2answer.org/
Plugin License: GPLv2 Plugin License: GPLv2
Plugin Minimum Question2Answer Version: 1.3 Plugin Minimum Question2Answer Version: 1.5
Plugin Minimum PHP Version: 5 Plugin Minimum PHP Version: 5
Plugin Update Check URI: Plugin Update Check URI:
*/ */
...@@ -45,8 +45,10 @@ ...@@ -45,8 +45,10 @@
} }
if (!QA_FINAL_EXTERNAL_USERS) // login modules don't work with external user integration if (!QA_FINAL_EXTERNAL_USERS) { // login modules don't work with external user integration
qa_register_plugin_module('login', 'qa-facebook-login.php', 'qa_facebook_login', 'Facebook Login'); qa_register_plugin_module('login', 'qa-facebook-login.php', 'qa_facebook_login', 'Facebook Login');
qa_register_plugin_layer('qa-facebook-layer.php', 'Facebook Login Layer');
}
/* /*
......
<?php
/*
Question2Answer (c) Gideon Greenspan
http://www.question2answer.org/
File: qa-plugin/opensearch-support/qa-opensearch-layer.php
Version: See define()s at top of qa-include/qa-base.php
Description: Theme layer class for OpenSearch plugin
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
More about this license: http://www.question2answer.org/license.php
*/
class qa_html_theme_layer extends qa_html_theme_base {
function head_links()
{
qa_html_theme_base::head_links();
$this->output('<LINK REL="search" TYPE="application/opensearchdescription+xml" TITLE="'.qa_html(qa_opt('site_title')).'" HREF="'.qa_path_html('opensearch.xml').'"/>');
}
}
/*
Omit PHP closing tag to help avoid accidental output
*/
\ No newline at end of file
<?php
/*
Question2Answer (c) Gideon Greenspan
http://www.question2answer.org/
File: qa-plugin/opensearch-support/qa-opensearch-page.php
Version: See define()s at top of qa-include/qa-base.php
Description: Page module class for XML sitemap plugin
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
More about this license: http://www.question2answer.org/license.php
*/
class qa_opensearch_xml {
function match_request($request)
{
return ($request=='opensearch.xml');
}
function process_request($request)
{
@ini_set('display_errors', 0); // we don't want to show PHP errors inside XML
$titlehtml=qa_html(qa_opt('site_title'));
$template=str_replace('_searchTerms_placeholder_', '{searchTerms}', qa_path('search', array('q' => '_searchTerms_placeholder_'), qa_opt('site_url')));
header('Content-type: text/xml; charset=utf-8');
echo '<?xml version="1.0" encoding="UTF-8"?>'."\n";
echo '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:moz="http://www.mozilla.org/2006/browser/search/">'."\n";
echo "\t<ShortName>".$titlehtml."</ShortName>\n";
echo "\t<Description>".qa_lang_html('main/search_button').' '.$titlehtml."</Description>\n";
echo "\t".'<Url type="text/html" method="get" template="'.qa_html($template).'"/>'."\n";
echo "\t<InputEncoding>UTF-8</InputEncoding>\n";
echo '</OpenSearchDescription>'."\n";
return null;
}
}
/*
Omit PHP closing tag to help avoid accidental output
*/
\ No newline at end of file
<?php
/*
Question2Answer (c) Gideon Greenspan
http://www.question2answer.org/
File: qa-plugin/opensearch-support/qa-plugin.php
Version: See define()s at top of qa-include/qa-base.php
Description: Initiates OpenSearch plugin
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
More about this license: http://www.question2answer.org/license.php
*/
/*
Plugin Name: OpenSearch Support
Plugin URI:
Plugin Description: Allows OpenSearch clients to search Q2A site directly
Plugin Version: 1.0
Plugin Date: 2012-08-21
Plugin Author: Question2Answer
Plugin Author URI: http://www.question2answer.org/
Plugin License: GPLv2
Plugin Minimum Question2Answer Version: 1.5
Plugin Update Check URI:
*/
if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
header('Location: ../../');
exit;
}
qa_register_plugin_layer('qa-opensearch-layer.php', 'OpenSearch Layer');
qa_register_plugin_module('page', 'qa-opensearch-page.php', 'qa_opensearch_xml', 'OpenSearch XML');
/*
Omit PHP closing tag to help avoid accidental output
*/
\ No newline at end of file
# #
# Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. # Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
# For licensing, see LICENSE.html or http://ckeditor.com/license # For licensing, see LICENSE.html or http://ckeditor.com/license
# #
......
...@@ -7,7 +7,7 @@ Software License Agreement ...@@ -7,7 +7,7 @@ Software License Agreement
========================== ==========================
CKEditor - The text editor for Internet - http://ckeditor.com CKEditor - The text editor for Internet - http://ckeditor.com
Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
Licensed under the terms of any of the following licenses at your Licensed under the terms of any of the following licenses at your
choice: choice:
...@@ -1279,7 +1279,7 @@ EXHIBIT A -Mozilla Public License. ...@@ -1279,7 +1279,7 @@ EXHIBIT A -Mozilla Public License.
<p> <p>
<strong>CKEditor&trade;</strong> - The text editor for Internet&trade; - <a href="http://ckeditor.com"> <strong>CKEditor&trade;</strong> - The text editor for Internet&trade; - <a href="http://ckeditor.com">
http://ckeditor.com</a><br /> http://ckeditor.com</a><br />
Copyright &copy; 2003-2011, <a href="http://cksource.com/">CKSource</a> - Frederico Knabben. All rights reserved. Copyright &copy; 2003-2012, <a href="http://cksource.com/">CKSource</a> - Frederico Knabben. All rights reserved.
</p> </p>
<p> <p>
Licensed under the terms of any of the following licenses at your choice: Licensed under the terms of any of the following licenses at your choice:
......
/* /*
Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/* /*
Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
// Compressed version of core/ckeditor_base.js. See original for instructions. // Compressed version of core/ckeditor_base.js. See original for instructions.
/*jsl:ignore*/ /*jsl:ignore*/
if(!window.CKEDITOR)window.CKEDITOR=(function(){var a={timestamp:'',version:'3.6.2',revision:'7275',_:{},status:'unloaded',basePath:(function(){var d=window.CKEDITOR_BASEPATH||'';if(!d){var e=document.getElementsByTagName('script');for(var f=0;f<e.length;f++){var g=e[f].src.match(/(^|.*[\\\/])ckeditor(?:_basic)?(?:_source)?.js(?:\?.*)?$/i);if(g){d=g[1];break;}}}if(d.indexOf(':/')==-1)if(d.indexOf('/')===0)d=location.href.match(/^.*?:\/\/[^\/]*/)[0]+d;else d=location.href.match(/^[^\?]*\/(?:)/)[0]+d;return d;})(),getUrl:function(d){if(d.indexOf(':/')==-1&&d.indexOf('/')!==0)d=this.basePath+d;if(this.timestamp&&d.charAt(d.length-1)!='/')d+=(d.indexOf('?')>=0?'&':'?')+('t=')+this.timestamp;return d;}},b=window.CKEDITOR_GETURL;if(b){var c=a.getUrl;a.getUrl=function(d){return b.call(a,d)||c.call(a,d);};}return a;})(); if(!window.CKEDITOR)window.CKEDITOR=(function(){var a={timestamp:'',version:'3.6.4',revision:'7575',rnd:Math.floor(Math.random()*900)+100,_:{},status:'unloaded',basePath:(function(){var d=window.CKEDITOR_BASEPATH||'';if(!d){var e=document.getElementsByTagName('script');for(var f=0;f<e.length;f++){var g=e[f].src.match(/(^|.*[\\\/])ckeditor(?:_basic)?(?:_source)?.js(?:\?.*)?$/i);if(g){d=g[1];break;}}}if(d.indexOf(':/')==-1)if(d.indexOf('/')===0)d=location.href.match(/^.*?:\/\/[^\/]*/)[0]+d;else d=location.href.match(/^[^\?]*\/(?:)/)[0]+d;if(!d)throw 'The CKEditor installation path could not be automatically detected. Please set the global variable "CKEDITOR_BASEPATH" before creating editor instances.';return d;})(),getUrl:function(d){if(d.indexOf(':/')==-1&&d.indexOf('/')!==0)d=this.basePath+d;if(this.timestamp&&d.charAt(d.length-1)!='/'&&!/[&?]t=/.test(d))d+=(d.indexOf('?')>=0?'&':'?')+'t='+this.timestamp;return d;}},b=window.CKEDITOR_GETURL;if(b){var c=a.getUrl;a.getUrl=function(d){return b.call(a,d)||c.call(a,d);};}return a;})();
/*jsl:end*/ /*jsl:end*/
// Uncomment the following line to have a new timestamp generated for each // Uncomment the following line to have a new timestamp generated for each
......
/* /*
Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
// Compressed version of core/ckeditor_base.js. See original for instructions. // Compressed version of core/ckeditor_base.js. See original for instructions.
/*jsl:ignore*/ /*jsl:ignore*/
if(!window.CKEDITOR)window.CKEDITOR=(function(){var a={timestamp:'',version:'3.6.2',revision:'7275',_:{},status:'unloaded',basePath:(function(){var d=window.CKEDITOR_BASEPATH||'';if(!d){var e=document.getElementsByTagName('script');for(var f=0;f<e.length;f++){var g=e[f].src.match(/(^|.*[\\\/])ckeditor(?:_basic)?(?:_source)?.js(?:\?.*)?$/i);if(g){d=g[1];break;}}}if(d.indexOf(':/')==-1)if(d.indexOf('/')===0)d=location.href.match(/^.*?:\/\/[^\/]*/)[0]+d;else d=location.href.match(/^[^\?]*\/(?:)/)[0]+d;return d;})(),getUrl:function(d){if(d.indexOf(':/')==-1&&d.indexOf('/')!==0)d=this.basePath+d;if(this.timestamp&&d.charAt(d.length-1)!='/')d+=(d.indexOf('?')>=0?'&':'?')+('t=')+this.timestamp;return d;}},b=window.CKEDITOR_GETURL;if(b){var c=a.getUrl;a.getUrl=function(d){return b.call(a,d)||c.call(a,d);};}return a;})(); if(!window.CKEDITOR)window.CKEDITOR=(function(){var a={timestamp:'',version:'3.6.4',revision:'7575',rnd:Math.floor(Math.random()*900)+100,_:{},status:'unloaded',basePath:(function(){var d=window.CKEDITOR_BASEPATH||'';if(!d){var e=document.getElementsByTagName('script');for(var f=0;f<e.length;f++){var g=e[f].src.match(/(^|.*[\\\/])ckeditor(?:_basic)?(?:_source)?.js(?:\?.*)?$/i);if(g){d=g[1];break;}}}if(d.indexOf(':/')==-1)if(d.indexOf('/')===0)d=location.href.match(/^.*?:\/\/[^\/]*/)[0]+d;else d=location.href.match(/^[^\?]*\/(?:)/)[0]+d;if(!d)throw 'The CKEditor installation path could not be automatically detected. Please set the global variable "CKEDITOR_BASEPATH" before creating editor instances.';return d;})(),getUrl:function(d){if(d.indexOf(':/')==-1&&d.indexOf('/')!==0)d=this.basePath+d;if(this.timestamp&&d.charAt(d.length-1)!='/'&&!/[&?]t=/.test(d))d+=(d.indexOf('?')>=0?'&':'?')+'t='+this.timestamp;return d;}},b=window.CKEDITOR_GETURL;if(b){var c=a.getUrl;a.getUrl=function(d){return b.call(a,d)||c.call(a,d);};}return a;})();
/*jsl:end*/ /*jsl:end*/
// Uncomment the following line to have a new timestamp generated for each // Uncomment the following line to have a new timestamp generated for each
......
/* /*
Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
......
/* /*
Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
......
/* /*
Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
*/ */
......
Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license For licensing, see LICENSE.html or http://ckeditor.com/license
af.js Found: 549 Missing: 27 af.js Found: 548 Missing: 29
ar.js Found: 467 Missing: 109 ar.js Found: 470 Missing: 107
bg.js Found: 291 Missing: 285 bg.js Found: 394 Missing: 183
bn.js Found: 292 Missing: 284 bn.js Found: 292 Missing: 285
bs.js Found: 175 Missing: 401 bs.js Found: 175 Missing: 402
ca.js Found: 550 Missing: 26 ca.js Found: 549 Missing: 28
cs.js Found: 550 Missing: 26 cs.js Found: 577 Missing: 0
cy.js Found: 573 Missing: 3 cy.js Found: 575 Missing: 2
da.js Found: 417 Missing: 159 da.js Found: 575 Missing: 2
de.js Found: 576 Missing: 0 de.js Found: 575 Missing: 2
el.js Found: 306 Missing: 270 el.js Found: 391 Missing: 186
en-au.js Found: 345 Missing: 231 en-au.js Found: 347 Missing: 230
en-ca.js Found: 345 Missing: 231 en-ca.js Found: 345 Missing: 232
en-gb.js Found: 518 Missing: 58 en-gb.js Found: 517 Missing: 60
eo.js Found: 270 Missing: 306 eo.js Found: 577 Missing: 0
es.js Found: 576 Missing: 0 es.js Found: 575 Missing: 2
et.js Found: 575 Missing: 1 et.js Found: 577 Missing: 0
eu.js Found: 417 Missing: 159 eu.js Found: 417 Missing: 160
fa.js Found: 576 Missing: 0 fa.js Found: 575 Missing: 2
fi.js Found: 576 Missing: 0 fi.js Found: 575 Missing: 2
fo.js Found: 551 Missing: 25 fo.js Found: 575 Missing: 2
fr-ca.js Found: 319 Missing: 257 fr-ca.js Found: 319 Missing: 258
fr.js Found: 551 Missing: 25 fr.js Found: 575 Missing: 2
gl.js Found: 292 Missing: 284 gl.js Found: 292 Missing: 285
gu.js Found: 320 Missing: 256 gu.js Found: 575 Missing: 2
he.js Found: 576 Missing: 0 he.js Found: 575 Missing: 2
hi.js Found: 322 Missing: 254 hi.js Found: 327 Missing: 250
hr.js Found: 419 Missing: 157 hr.js Found: 575 Missing: 2
hu.js Found: 573 Missing: 3 hu.js Found: 572 Missing: 5
is.js Found: 326 Missing: 250 id.js Found: 1 Missing: 576
it.js Found: 573 Missing: 3 is.js Found: 326 Missing: 251
ja.js Found: 494 Missing: 82 it.js Found: 577 Missing: 0
ka.js Found: 569 Missing: 7 ja.js Found: 493 Missing: 84
km.js Found: 286 Missing: 290 ka.js Found: 568 Missing: 9
ko.js Found: 304 Missing: 272 km.js Found: 286 Missing: 291
lt.js Found: 576 Missing: 0 ko.js Found: 304 Missing: 273
lv.js Found: 294 Missing: 282 lt.js Found: 575 Missing: 2
mn.js Found: 320 Missing: 256 lv.js Found: 294 Missing: 283
ms.js Found: 276 Missing: 300 mk.js Found: 0 Missing: 577
nb.js Found: 575 Missing: 1 mn.js Found: 320 Missing: 257
nl.js Found: 576 Missing: 0 ms.js Found: 276 Missing: 301
no.js Found: 575 Missing: 1 nb.js Found: 577 Missing: 0
pl.js Found: 576 Missing: 0 nl.js Found: 575 Missing: 2
pt-br.js Found: 576 Missing: 0 no.js Found: 577 Missing: 0
pt.js Found: 293 Missing: 283 pl.js Found: 575 Missing: 2
ro.js Found: 317 Missing: 259 pt-br.js Found: 577 Missing: 0
ru.js Found: 576 Missing: 0 pt.js Found: 326 Missing: 251
sk.js Found: 365 Missing: 211 ro.js Found: 432 Missing: 145
sl.js Found: 426 Missing: 150 ru.js Found: 575 Missing: 2
sr-latn.js Found: 287 Missing: 289 sk.js Found: 364 Missing: 213
sr.js Found: 286 Missing: 290 sl.js Found: 426 Missing: 151
sv.js Found: 551 Missing: 25 sr-latn.js Found: 287 Missing: 290
th.js Found: 298 Missing: 278 sr.js Found: 286 Missing: 291
tr.js Found: 536 Missing: 40 sv.js Found: 550 Missing: 27
uk.js Found: 544 Missing: 32 th.js Found: 298 Missing: 279
vi.js Found: 493 Missing: 83 tr.js Found: 575 Missing: 2
zh-cn.js Found: 576 Missing: 0 ug.js Found: 572 Missing: 5
zh.js Found: 419 Missing: 157 uk.js Found: 575 Missing: 2
vi.js Found: 577 Missing: 0
zh-cn.js Found: 577 Missing: 0
zh.js Found: 433 Missing: 144
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment