An example of step-by-step development
The goal of this component is enabling the admin to pin one or more posts on top of the newsfeed, as requested here:: https://www.opensource-socialnetwork.org/discussion/view/6844
Changelog:
ready to use,
v7.3dev2: fixed wrong merging of extra 'wheres' to get*Posts queries
v7.3dev1: + option to un-/collapse pinned posts contributed by Dominik L.
v7.2dev4: + compatibility fix for Friends-Online component as reported by Dominik L.
v7.2dev3: + 'Pin' menu entries on any wall post
v7.2dev2: + 'Unpin' menu entries on Pinned Post's frontend panel
v7.2dev1: + option to hide/display comments
ready to use, but not recommended
v7.1dev4: + eight selectable background colors + language files
early releases NOT to be used in production environments
v7.1dev3: pinned posts being removed from original location + crash debug
v7.1dev2: pinned posts appear on top of the newsfeed
v7.1dev1: admin backend to save post ids + basic placement on top of newfeed
How to pin one or more posts:
Choose the post you want to pin, open its menu on the right and click 'Pin':
The page reloads and the result will look like this.
(With Greetings and Site Announcement installed, Pinned Posts will care about a meaningful ordering by the way.)
How to unpin one or more pinned posts:
Choose the post you want to unpin, open its menu on the right and click 'Unpin':
Collapsing pinned posts:
Since members may not be too delighted to find the same pinned posts again and again whenever they visit the newsfeed, they may collapse any post they don't want to see anymore...
to just one line ...
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 :)
Ok, what needs to be done next to get the component working?
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.
Yes.. apparently this is some kind of test.. and what should happen next?
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?
Unfortunately there is some problem and the component is not working properly.. I am attaching an image
I have implemented the hooks as suggested by Arsalan in release 7.1dev3_the_crasher
now.
See ossn_com.php for details
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!
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.
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!