Mark Posts Read Ajax problem

Extensions, styles and support for everything else about phpBB
EVO_VV
Posts: 40
Joined: 23 Jun 2017, 16:03

Mark Posts Read Ajax problem

#1

Post by EVO_VV » 01 Mar 2018, 05:17

We have a moderately large forum with some Forums having quite a few posts.
The original designers of the forum added A-Z sub-forums to these not realising that SQL can accomplish the task easily and making it difficult to search though all the forums when wanting to use the Moderator tools. To say nothing of how difficult it is to change the permission on them when needed.

I have edited the code so that at the top of the Forum there is a horizontal A-Z menu which when a letter is clicked performs a search and returns a page(s) with all the entries for that particular letter.
This works very well but there is one problem I am trying to fix and that is the Mark Topics Read function.
The way this works normally is to mark All Topics in that forum read but our requirement is to only mark the topics that are in the returned page(s) from that menu.

As far as I can see there are two files that need to be edited - viewforum.php & functions.php
The viewforum.php has the code in this section (around line 250 - // Handle marking posts) to call markread in functions.php.
What I am trying to do is to add a parameter in there so that if the case is a result from that horizontal menu then that parameter is passed to functions.php so that the code in there can be edited to only mark the Topic IDs from the results rather than all of them if that parameter is set..

However, whenever I try to add that extra parameter in viewforum.php I get an Ajax error.
I have adjusted the markread function in functions.php to accept that parameter but I cannot seem to get past the Ajax error to be able to test the edits in functions.php.

I am obviously missing something to do with the Ajax but despite many attempts and research I still cannot figure out what the problem actually is.
Apart from my lack of knowledge of Java and how Ajax functions that is.

Any help will be greatly appreciated.

User avatar
kasimi
mChat developer
Posts: 737
Joined: 06 Oct 2016, 09:56
Location: Germany
Contact:

Re: Mark Posts Read Ajax problem

#2

Post by kasimi » 02 Mar 2018, 13:23

Does the browser console show any specific error message? Post the edits you made and I will have a look.

EVO_VV wrote:
01 Mar 2018, 05:17
To say nothing of how difficult it is to change the permission on them when needed.
Using permission roles should make it a matter a few clicks to update the permissions for all of them.

EVO_VV
Posts: 40
Joined: 23 Jun 2017, 16:03

Re: Mark Posts Read Ajax problem

#3

Post by EVO_VV » 02 Mar 2018, 13:49

When those A-Z forums were there, there were no specific Permission roles set.used and there were a lot of individual Member settings. It was a complete mess that I had to clear up before moving to the new server.

viewforum.php around 250ish

Code: Select all

	if ($az) {
		markread('topics', array($forum_id), false, $request->variable('mark_time', 0), $az); // Also tried adding the User_ID in here to match the function
		$redirect_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id,  'az=' . $az); // Also tried 'f=' . $forum_id .  'az=' . $az
		meta_refresh(3, $redirect_url);
		
	}else{
	//Do what was there before etc.
And

Code: Select all

		if ($request->is_ajax())
		{
			// Tell the ajax script what language vars and URL need to be replaced
			$data = array(
				'NO_UNREAD_POSTS'	=> $user->lang['NO_UNREAD_POSTS'],
				'UNREAD_POSTS'		=> $user->lang['UNREAD_POSTS'],
				'U_MARK_TOPICS'		=> ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'hash=' . generate_link_hash('global') . "&az=$az&f=$forum_id&mark=topics&mark_time=" . time()) : '',
				'MESSAGE_TITLE'		=> $user->lang['INFORMATION'],
				'MESSAGE_TEXT'		=> $user->lang['TOPICS_MARKED']
			);
			$json_response = new \phpbb\json_response();
			$json_response->send($data);
		}
I also played a little with what was in the If Else structure so not sure at the moment what the original was without looking at the original file.
The additional parameter is a string that will contain either 'All', 'Other' or just a particular letter of the alphabet.
If I can pass this to the markread function in functions.php (function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $user_id = 0, $az)) then I can edit the code in there to say if $az then the $sql = 'SQL Statements to Select the appropriate Topic IDs' else do what is already there which is all the topics in the Forum.

I either get an error something like 'Ajax not available' or 'Something went wrong'.
However if I comment out :- markread('topics', array($forum_id), false, $request->variable('mark_time', 0), $az); right at the top I do not get the error.

User avatar
kasimi
mChat developer
Posts: 737
Joined: 06 Oct 2016, 09:56
Location: Germany
Contact:

Re: Mark Posts Read Ajax problem

#4

Post by kasimi » 02 Mar 2018, 14:16

The markread() function in its original form takes 5 arguments, but the code you copied your version from only uses 4, which is why you need to pass another 0 as the $user_id argument before your $az:

Code: Select all

if ($az) {
	markread('topics', array($forum_id), false, $request->variable('mark_time', 0), 0, $az);

Code: Select all

$redirect_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id,  'az=' . $az);
The $az needs to be appended to the second argument, and a $amp; should be used to separate them:

Code: Select all

$redirect_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id . '&az=' . $az);

EVO_VV
Posts: 40
Joined: 23 Jun 2017, 16:03

Re: Mark Posts Read Ajax problem

#5

Post by EVO_VV » 03 Mar 2018, 13:37

Many thanks for the clarification on the code.
I did notice that the markread function had 5 parameters and tried to account for that although I used False instead of 0.
I'm sure I also tried the & but in what combination of other failed attempts I'm not sure.
The code I posted was from my notes while testing, had I posted all my attempts after what I thought was right did not work it would have taken pages.....

Now I know for sure what is correct I tested that but still got the Ajax Error - Service Unavailable.
The code I used was :-

Code: Select all

if ($mark_read == 'topics')
{
	if ($az) {
		markread('topics', array($forum_id), false, $request->variable('mark_time', 0), 0, $az);
		$redirect_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id . '&az=' . $az);
		meta_refresh(3, $redirect_url);
		
	}else{
		$token = $request->variable('hash', '');
		if (check_link_hash($token, 'global'))
		{
			markread('topics', array($forum_id), false, $request->variable('mark_time', 0,0));
		}
		$redirect_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id);
		meta_refresh(3, $redirect_url);
	}
		if ($request->is_ajax())
		{
			// Tell the ajax script what language vars and URL need to be replaced
			$data = array(
				'NO_UNREAD_POSTS'	=> $user->lang['NO_UNREAD_POSTS'],
				'UNREAD_POSTS'		=> $user->lang['UNREAD_POSTS'],
				'U_MARK_TOPICS'		=> ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'hash=' . generate_link_hash('global') . "&az=$az&f=$forum_id&mark=topics&mark_time=" . time()) : '',
				'MESSAGE_TITLE'		=> $user->lang['INFORMATION'],
				'MESSAGE_TEXT'		=> $user->lang['TOPICS_MARKED']
			);
			$json_response = new \phpbb\json_response();
			$json_response->send($data);
		}
	
	trigger_error($user->lang['TOPICS_MARKED'] . '<br /><br />' . sprintf($user->lang['RETURN_FORUM'], '<a href="' . $redirect_url . '">', '</a>'));
}
I also tried including the if ($request->is_ajax()) block in the }else{ block but still got the same error.
However, if I comment out the markread('topics', array($forum_id), false, $request->variable('mark_time', 0), 0, $az); line then I get no error and the Topics appear as marked read.
Of course they do not stay that way as the code in functions.php is not executed.

From your instructions it should work as long as I have the correct code in functions.php which at the moment are not complete as I cannot test them step by step.
I'm trying to get the code working on a Lampp Stack on my PC that has no internet access, will that make any difference ?

User avatar
kasimi
mChat developer
Posts: 737
Joined: 06 Oct 2016, 09:56
Location: Germany
Contact:

Re: Mark Posts Read Ajax problem

#6

Post by kasimi » 07 Mar 2018, 22:29

EVO_VV wrote:
03 Mar 2018, 13:37
However, if I comment out the markread('topics', array($forum_id), false, $request->variable('mark_time', 0), 0, $az); line then I get no error and the Topics appear as marked read.
How did you change the markread() function exactly? To keep the changes as simple as possible, instead of doing if ($az) {, just add the $az variable to the exising call to markread() so that it's always passed, and use a falsey default value that you can check in the markread() function. Actually, why are you passing it at all? Why don't you grab it in the markread() function?

EVO_VV
Posts: 40
Joined: 23 Jun 2017, 16:03

Re: Mark Posts Read Ajax problem

#7

Post by EVO_VV » 08 Mar 2018, 13:54

The markread function now changed to
function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $user_id = 0, $az = false)
I had $az = 0 before.

Not sure how to grab $az in the markread function as I'm not sure of the 'scope' of it, but that does sound simpler if it keeps all the code edits in the one file.

Had not thought of just adding $az to the markread call and function because I'm not sure how that works. Saw both 'false' and '=0' in the function declaration.

Tried the following and still got the 'Service not Available' error.

markread('topics', array($forum_id), false, $request->variable('mark_time', 0),0, $az);

As it is still an Ajax error thought it might be the latter part so put an If statement in there to allow for both cases but still the same error.

Code: Select all

// Tell the ajax script what language vars and URL need to be replaced
if ($az) {
	$data = array(
		'NO_UNREAD_POSTS'	=> $user->lang['NO_UNREAD_POSTS'],
		'UNREAD_POSTS'		=> $user->lang['UNREAD_POSTS'],
		'U_MARK_TOPICS'		=> ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'hash=' . generate_link_hash('global') . "&az=$az&f=$forum_id&mark=topics&mark_time=" . time()) : '',
		'MESSAGE_TITLE'		=> $user->lang['INFORMATION'],
		'MESSAGE_TEXT'		=> $user->lang['TOPICS_MARKED']
	);
}else{
	$data = array(
		'NO_UNREAD_POSTS'	=> $user->lang['NO_UNREAD_POSTS'],
		'UNREAD_POSTS'		=> $user->lang['UNREAD_POSTS'],
		'U_MARK_TOPICS'		=> ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'hash=' . generate_link_hash('global') . "&f=$forum_id&mark=topics&mark_time=" . time()) : '',
		'MESSAGE_TITLE'		=> $user->lang['INFORMATION'],
		'MESSAGE_TEXT'		=> $user->lang['TOPICS_MARKED']
	);
}
Tried removing the added code to functions.php and the error went away, which leads me to think that something I'm doing in there is not correct or possibly complete, but do not understand why that would produce an Ajax error.
So far I've only dealt with the selection of the Topic IDs, have not got as far as the Tracking etc.

The code I added to functions.php, as well as the declaration quoted at the top of this post, is :-

Code: Select all

// Mark all post/quote notifications read for this user in this forum
$topic_ids = array();
// Added
if ($az != false) {  // Also tried if ($az) first but still got the error
	switch ((string)$az){
		case "Other":
			$sql = "SELECT topic_id FROM " . TOPICS_TABLE . " WHERE forum_id = " . $forum_id . " AND topic_title NOT REGEXP '^[a-z]'";
			break;
		case "All":
			$sql = "SELECT topic_id FROM " . TOPICS_TABLE . " WHERE forum_id = " . $forum_id;
			break;
		default:
			$sql = "SELECT topic_id FROM " . TOPICS_TABLE . " WHERE forum_id = " . $forum_id . "AND topic_title LIKE " . $az ."%";
	}
}else{
$sql = 'SELECT topic_id
	FROM ' . TOPICS_TABLE . '
	WHERE ' . $db->sql_in_set('forum_id', $forum_id);
}
// End Added
		$result = $db->sql_query($sql);

User avatar
kasimi
mChat developer
Posts: 737
Joined: 06 Oct 2016, 09:56
Location: Germany
Contact:

Re: Mark Posts Read Ajax problem

#8

Post by kasimi » 08 Mar 2018, 14:28

Code: Select all

WHERE forum_id = " . $forum_id . "AND topic_title LIKE " . $az ."%";
The LIKE value is missing quotes and there's a space missing before AND, it should be:

Code: Select all

WHERE forum_id = " . $forum_id . " AND topic_title LIKE '" . $az ."%'";
Also, this code allows SQL injections. You have to escape $az. Also make sure that $forum_id is an integer by casting it to (int) in all 3 queries.

EVO_VV
Posts: 40
Joined: 23 Jun 2017, 16:03

Re: Mark Posts Read Ajax problem

#9

Post by EVO_VV » 09 Mar 2018, 15:55

Fixed those two silly errors - one was due to me trying to remember what I did successfully previously instead of looking and copying and the other with the 'And' was due to trying to make sure I did not make that mistake. Previously had it in three lines for clarity and put it into one to make sure it was correct.
Doh !!!

After correcting the code I still get the Ajax Service Unavailable error.

As the $forum_id is part of the original code and I have not altered it in any way, I don't think that it would need the cast to int().

Not quite sure what escaping the $az entails but looking at the existing code I assume you mean the sql_like_expression syntax.
Tested that by adjusting the code as below and using just the single character $az case but still get the same Ajax Service Unavailable error.
From
$sql = "SELECT topic_id FROM " . TOPICS_TABLE . " WHERE forum_id = " . $forum_id . " AND topic_title LIKE '" . $az ."%'";
To
$sql = "SELECT topic_id FROM " . TOPICS_TABLE . " WHERE forum_id = " . $forum_id . " AND topic_title " . $db->sql_like_expression(substr($first_char, 0, 1) . $db->get_any_char());

Have looked in the error logs I can see nothing in there to indicate where the problem may lie, the only indication is the logging of a 503 error.

User avatar
kasimi
mChat developer
Posts: 737
Joined: 06 Oct 2016, 09:56
Location: Germany
Contact:

Re: Mark Posts Read Ajax problem

#10

Post by kasimi » 09 Mar 2018, 16:32

We're getting there. :) In your 3 SQL queries, $forum_id is an array, so instead of doing WHERE forum_id = " . (int) $forum_id as I previously suggested, which would have made it even more difficult to actually find this bug, you should use WHERE " . $db->sql_in_set('forum_id', $forum_id).

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest