Pinned Posts Download 7.1dev4

5.0
German Michael Zülsdorff 5 months ago

Pinned Posts

An example of step-by-step development
release 7.1dev4: ready to use + 8 selectable background colors + language files

NOT to be used in production environments
release 7.1dev3: pinned posts being removed from original location + crash debug
release 7.1dev2: pinned posts appear on top of the newsfeed
release 7.1dev1: admin backend to save post ids + basic placement on top of newfeed

The idea of this component is to pin one or more selected posts on top of the newsfeeds as requested here:
https://www.opensource-socialnetwork.org/discussion/view/6844


How to pin one or more posts:
1 - Click the date of the post you want to pin:


enter image description here


This will open a new page with the ID of that post (346 in this example)

enter image description here


2 - Keep that ID in mind (write it down ... whatever ...)
3 - Proceed to your administrator page -> Configure -> PinnedPosts


enter image description here


4 - Enter the ID and save it


enter image description here


The first release of this component (7.1dev1) is implementing the basic placement of pinned posts and was derived from the Site Announcement component. No wonder that the result will look very much the same:


enter image description here


Now, that we have the post ID of interest already in place, the next task is to make use of it, fetch that post and display it.


Release 7.1dev2 comes implemented with the code to pin the actual post(s) now - using the ids which were saved via Configure -> PinnedPosts

See posts.php for more details...

So here's pinned post 346 again that I picked as an example:
enter image description here

Comments
German Michael Zülsdorff Replied 4 months ago

Oops, I thought it would be obvious when I wrote that I intentionally changed Arsalan's line of valid code

$return['order_by'] = 'o.guid ASC';

to this invalid line

$return['order_by'] = 'CRASH_ME!';

in order to force some debug output....

Okay, it was not. Then, what can we do?

1) Revert back to Arsalan's original code. But that would change the sort order in general. And that's not what you wanted.
2) Leave Arsalan's line in place but reverse the ordering in a valid way like

$return['order_by'] = 'o.guid DESC';

which wouldn't hurt but doesn't make too much sense because the default ordering is already DESCENDING
3) simply remove the invalid line :)

Bulgarian Georgi Shindarov Replied 4 months ago

Ok, what needs to be done next to get the component working?

German Michael Zülsdorff Replied 5 months ago

Yeah, what should happen next ... A closer look under the hood and a little explaining can't be bad, I think. ;)

So, let's recall what Arsalan suggested 2 weeks ago. His idea was using 3 hooks calling a function to simply reverse the default DESCENDING sort order to get the oldest post on top like:

function wall_posts_order($hook, $type, $return, $params){
                $return['order_by'] = 'o.guid ASC';
                return $return;
}

But since this didn't solve exactly what you wanted, we found a different way with release dev1 and dev2 to pin the post on top - using some code from the Site announcement component and the page handler of OssnWall.
Next, you requested to hide the original post - and that's where Arsalan's idea comes into conclusion again. Just a little changed - not to reverse the sort order but exclude the pinned posts instead.
Time to open ossn_com.php of this component now, and see what has changed:

if (isset($settings->PinnedPosts) && !empty($settings->PinnedPosts)) {
    // yes we have!
    // so let's extend the original SQL query to exclude these post ids
    $return['wheres'] = "o.guid NOT IN ({$settings->PinnedPosts})";
    // and stop here and see how the resulting query looks like ....
    $return['order_by'] = 'CRASH_ME!';
    return $return;
}

Aside from some checking if there are pinned posts at all, it's actually just one line to get that accomplished:

$return['wheres'] = "o.guid NOT IN ({$settings->PinnedPosts})";

Okay, but how do these wheres have an impact on fetching wall posts? In order to get a better understanding I decided to leave Arsalan's former line in place and change 'ASC' to 'CRASH_ME'. That's in fact no valid SQL the database could handle and hence throwing the error message:

OssnDatabaseException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'CRASH LIMIT 0, 10' at line 1 

SELECT DISTINCT  o.guid, o.time_created FROM ossn_object as o JOIN ossn_entities as e0 ON e0.owner_guid=o.guid JOIN ossn_entities_metadata as emd0 ON e0.guid=emd0.guid JOIN ossn_entities as e1 ON e1.owner_guid=o.guid JOIN ossn_entities_metadata as emd1 ON e1.guid=emd1.guid WHERE(o.subtype='wall' AND o.type='user' AND (e0.type='object' AND e0.subtype='access' AND (1=1) AND e1.type='object' AND e1.subtype='poster_guid' AND (emd0.value=2 OR emd0.value=3)) AND o.guid NOT IN (156))  ORDER by o.guid CRASH LIMIT 0, 10; 

Let's have a closer look at the query above:
Initially, the query would fetch ALL ids from the ossn_object table:

SELECT DISTINCT  o.guid, o.time_created FROM ossn_object ...

but then there are a lot of extra conditions to sort out those records which are actually posts:

WHERE(o.subtype='wall' AND o.type='user' AND (e0.type='object' AND e0.subtype='access' AND (1=1) AND e1.type='object' AND e1.subtype='poster_guid' AND (emd0.value=2 OR emd0.value=3)) AND o.guid NOT IN (156))

And now it becomes clear, which way the code

$return['wheres'] = "o.guid NOT IN ({$settings->PinnedPosts})";

was 'translated' to SQL and added to all other wheres at the end as

AND o.guid NOT IN (156)

with your post 156 which was already pinned and needs to be excluded from the original location on the wall as requested by you.

Bulgarian Georgi Shindarov Replied 5 months ago

Yes.. apparently this is some kind of test.. and what should happen next?

German Michael Zülsdorff Replied 5 months ago

Yep, this release leads to a crash - that's why I named it "the_crasher" :)
Thanks for sending the error report. So, the id of your pinned post is 156?

Bulgarian Georgi Shindarov Replied 5 months ago

Unfortunately there is some problem and the component is not working properly.. I am attaching an image

enter image description here

German Michael Zülsdorff Replied 5 months ago

I have implemented the hooks as suggested by Arsalan in release 7.1dev3_the_crasher now.
See ossn_com.php for details

Bulgarian Georgi Shindarov Replied 5 months ago

Can you show me in my thread or here how to do it.. How do I hide the original posts? I will be very thankful!

German Michael Zülsdorff Replied 5 months ago

I'd rather call this a problem - at least not a problem of my component - if you got only a handful of posts on your site and both the fixed and original appear twice on the same page. :)) It's just another feature request.

Anyway: Arsalan posted some the code to accomplish things like that 2 weeks ago in your thread already. That is: Use these hooks, and change the accompanying function to exclude the saved post ids.

Bulgarian Georgi Shindarov Replied 5 months ago

Thank you very much for starting to develop this component.. And is it possible to make it so that the original post that appears in the top position disappears from its previous position in the list of posts.. because at the moment we get very close repetition of posts and it seems a bit overloaded and unnecessary.. Will you be able to fix this problem in the next version of this component. Thank you again!

Component

Developer: Michael
License GPL v2
Type: Site admin
Requires Ossn Version : 7.1
Latest Version: 7.1dev4
Last Updated 4 months ago
Repository Url View Repository

Versions