We have a website created using elgg, and we have discussion part of elgg where pagination is not working properly.
When listing all discussion list, pagination is working correctly, from latest to oldest
But pagination inside topic (one of the discussion) where replies are too many, and they separated by pagination (Previous, next), it is showing replies incorrectly:
In the first page we have:
As you can see it is ordered from latest to oldest: 17 days ago and then comes 21 days ago.
But when you go next page:
It is ordered inside the page from latest to oldest, but the the pages should be swapped.
How can I fix it?
Thanks forward
It works properly. Discussions are ordered by last action on the thread. You may have older thread first due to it having most recent response of all threads.
To change it, look at discussion_handle_list_page function in mod/groups/lib/discussion and how it uses order_by parameter. You need to override this page and just remove order_by to use default ordering, which is creation time of the entity (in his case thread). You could do it by tapping to the "route" plugin hook, or overriding whole discussions page handler.
And that's why not just change it inline: http://learn.elgg.org/en/1.9/guides/dont-modify-core.html
I have found finally going through all pagination libraries, and annotation views.
The problem is when listing replies for discussion on replies.php file which in /views/default/discussion there are two jquery functions on the bottom of the page that reverse the order.
function reverse(arr){
var newArr = [];
for(var iter = arr.length -1; iter >= 0; iter--){
newArr.push(arr[iter])
}
return newArr;
}
I have change the iter to start from 0 and go to arr.lenthg.
But it is not all yet, in order to get the latest replies first, I have added to
$options = array(
'guid' => $vars['entity']->getGUID(),
'annotation_name' => 'group_topic_post',
);
this line:
'order_by'=> 'time_created desc'
And then I got my replies ordered correctly: from latest to oldest.
Related
I want a woocommerce order to be automatically marked as completed upon visiting a specific page in WordPress
This specific page will have the order_id in GET variable. Now what i need to know is how to find an order by order_id and mark the status as completed on a specific WordPress page.
You can do it with following piece of code:
if(is_page('page_title')){
$order = new WC_Order($_GET['your_order_id']);
//wc-completed, wc-processing
$update_status = array('ID'=>$_GET['your_order_id'],'post_status'=>'wc-completed');
wp_update_post( $update_status );
}
First check whether It is on your specific page or not.
Second thing is to get your order
Third step is to update status of order.
Let me know if you have any doubt.
EDITED
You can refer codex for more details on is_page.
If you have page_id then you need to put condition like if(is_page(42)) where 42 is ID of your page.
So, Rohil_PHPBeginner's answer works like a charme. If you urgently search for a "just copy and paste" solution and have no time to figure things out, go ahead and use this ready to use snippet for your functions.php:
Don't forget to replace the number 42 with the page id of your desired page that will handle as an order-completion-url. Afterwards you can call the order completion by url by: http://your-url.com/yourdeletionpage/?your_order_id=ORDER_ID_TO_BE_COMPLETED
function my_abhaken() {
if(is_page(42)){
$order = new WC_Order($_GET['your_order_id']);
//wc-completed, wc-processing
$update_status = array('ID'=>$_GET['your_order_id'],'post_status'=>'wc-completed');
wp_update_post( $update_status );
}
}
add_action('wp_head', 'my_abhaken');
There's a collection Comments. Currently comments for the specfic Content are all published to the client.
Without pagination I can successfully render them in my template, insert new comments and enjoy the reactivity.
I'm fine at the moment with all comments sent to the client but I want to implement all-client-side pagination to visually simplify the page much like FB does.
Hare are the rules:
Comments are always sorted by the creation timestamp ASC (newer at the bottom of the list)
I need to show the total number of records in the collection (T)
I need to show the total number of comments currently displayed (C)
If there are more comments (C < T) I need to show a 'See more' link
Initially I show 5 newest comments (or all of them if there're less than 5)
New comments (pushed from the server) are instantly shown at the end of the list
When I click the 'See more' link up to 10 extra comments (the newest from the currently invisible -- and all of them are older that those already shown) are shown in the beginning of the list
So effectively it could be like:
have the minTime variable
initially set it to the timestamp of the 5th newest comment
when I click the link set it to the timestamp of the 10th newest comment older than the current value
template renders all the comments not older than this value
at some point calculate values C and T and save them
I tried to solve this with a bunch of Session variables but didn't succeed -- I think at some point getting and setting these vars from the template leads to recursion or what?
Additional problem is that I don't reliably know the 'initial' moment when I should calculate the minTime for the 1st time -- comments may still not be synched when the template is created or rendered for the first time.
So, the question: what is the proper way to fulfill my requirements?
Solution:
Meteor.startup(function(){
Session.set('number_of_visible_comments', 5);
});
Template.comments = function() {
return Comments.find({content: id_of_content}, {
sort: {timestamp: -1},
limit: Session.get('number_of_visible_comments')
});
};
Template.total_number_of_comments = function() {
return Comments.find({content: id_of_content}).count();
};
Template.number_of_visible_comments = function() {
return Session.get('number_of_visible_comments').count();
};
Template.comments.events({
'click': function() {
var count = Session.get('number_of_visible_comments') + 10;
Session.set('number_of_visible_comments', count);
}
});
In the meantime there are tow Meteor package for doing client-side pagination, one within a table. I admit I didn't go through all your requirements because of the comment exchange with ram1 above, but the package may help:
https://atmosphere.meteor.com/package/reactive-table
https://github.com/alethes/meteor-pages
Is there a way i can have an exposed filter wherein the user can select the number of items displayed by the drupal view?
I am nearly positive that you can do this with hook_views_pre_build (&$view). I know for a fact that you can mess with $view->pager to update whether to use the pager or not and to alter the number of items per page.
This is a snippet from a custom module I did:
if (is_numeric($perpage) && (int) $perpage > 1) {
$view->pager["items_per_page"] = (int) $perpage;
} else if ($perpage == "all") {
$view->pager["use_pager"] = false;
$view->pager["items_per_page"] = 0;
}
I suspect you can turn the pager off and also set the items per page to limit the results.
EDIT:
OK, just saw the part about the exposed filter. The code snippet is actually from a bit of code that simulates an exposed filter for this case. The page has some links on it to select the number of items per page. The links refresh the page, and tack on a perpage=whatever parameter. The hook then sanitizes the input, and basically runs the code snippet above. I have also done something similar using HTML a select, and then wiring up the parameter w/ refresh using jQuery.
Based on this thread in the issue queue, that appears to be a long requested feature. It has apparently been added to the 6.x-3.x-dev branch, so it should be available in the 6.x-3.0-alpha3 release.
Or if you're using Drupal 7, it has been added to the 7.x-3.x-dev branch too, so it should be in the 7.x-3.0-alpha1 release.
i want to add an expiration date field to my custom content type in Drupal. it should specified by days (7-15-.... days after creating node) and after it reached the node should not display in site to visitors. but i need a renew option for it to allow creator renew it and activate it again.
is it too hard to impelmentation? how can i do it?
Have you already tried searching for modules?
Here's one that might do the trick http://drupal.org/project/auto_expire. There are others as well,but maybe you should check them out to see which one fits your needs (or can be altered easily if needed).
You can use Views to do that. Make a new View, specifically for a node or more nodes of that type, and put a filter on it with "Node:Updated". Then specify how many days you need.
You can create a View for the original poster and have him update the post, which will reset the counter.
A creative solution, but it should work.
Take a look at Node expire which sets up timers for nodes based on Rules. For a simpler approach, Scheduler can do it to. Both are linked from the Auto Expire module linked by wimvds, so there is some measure of duplication, though they do seem to have different approaches.
The following code may be of interest. It's a small snippet from a module i've had to create to auto expire adverts on an intranet site. The nodes simply unpublish after a number of days you specify in the code so could be hidden from your site and then the author of the content could simply just re -publish the nodes if they needed to.
/**
* Implementation of hook_cron().
*/
function auto_unpublish_pages_cron() {
//we only want to deal with all blog_post content type nodes
$c_type = 'blog_post';
//grab all nodes
$c_nodes = node_load_multiple(array(), array('type' => $c_type));
//setup time stamp for node expiry
$message_search_data = strtotime('- 7 days');
//now loop through nodes, & if they are old, expire them
foreach ($c_nodes as $m) {
$obj = entity_metadata_wrapper('node', $m);
//check when was last updated and if its still published
$last_update = $obj->changed->value();
$published = $obj->status->value();
//if it's still published & it's not recent, unpublish it
if (($message_search_date > $last_update) && $published<>0) {
$obj->status = 0;
$obj->save();
}
}
}
We've been having a new type of spam-bot this week at PortableApps.com which posts at a rate of about 10 comments a minute and doesn't seem to stop - at least the first hour or so (we've always stopped it within that time so far). We've had them about a dozen times in the last week - sometimes stopping it at 50 or 60, sometimes up to 250 or 300. We're working to stop it and other spam bots as much as possible, but at the moment it's still a real pest.
I was wondering whether in the mean time whether there's any sort of module to control the frequency a user can post at to e.g. 50 an hour or something like 10 in an hour for new users. That at least would mean that instead of having to clear up 300 comments 50 at a time in admin/content/comment we'd have a smaller number to clear. (A module to add a page to delete all content by a user and block them would also be helpful!)
I believe that there's a plugin to do this available for WordPress, but can't find any such thing for Drupal.
For your second question, i would have a look at the code of the User Delete module (click).
The module also disables the user account and unpublished all nodes/comments from a certain user. By extending the code, you could easily create another possibility to unpublish + delete all nodes/comments from a certain user and blocking the account.
After the unpublish code in the module, you should just put delete code (in sql if the module is selecting by a sql-query or by using the drupal delete functions).
Another option would be so make a view (using the view module) only to be viewed by administrators, where you choose a certain user using the filters and then lists his/her posts. Then in the node-contenttype.tpl.php you place a button that calls a function which deletes all nodes/comments and the user.
First problem (post frequency)
I've been thinking about the comment post limit. If I remember correctly Drupal stores comments in a seperate table and has comment specific functions.
I'd create a new module and using the comment_nodeapi function i would check in the operation 'insert' how much comments the current user has already made within a certain timeframe.
To check this I would write a custom sql query on the database which takes the count of alle comments made by uid where the post_date is larger then NOW-1hour. If that count is larger then 10 or 15 or whatever post frequency you want then you give a message back to the user. You can retrieve the user id and name by using the global $user variable.
(example: print $user->name;)
You have to check on your own for the sql query but here's some code when you have the amount:
<?php
function comment_nodeapi(&$node, $op, $arg = 0) {
switch ($op) {
case 'insert':
//PLACE HERE THE SQL TO GET THE COUNT
if($count > 15){
$repeat = FALSE;
$type = 'status'
drupal_set_message("You have reached the comment limit for this time.", $type, $repeat);
break;
}else{
db_query('INSERT INTO {node_comment_statistics} (nid, last_comment_timestamp, last_comment_name, last_comment_uid, comment_count) VALUES (%d, %d, NULL, %d, 0)', $node->nid, $node->changed, $node->uid);
break;
}
}
}
?>
(this code has not been tested so no guarantees, but this should put you on the right track)
I would suggest something like Mollom (from the creator of Drupal). It scans the message for known spam pattern/keywords/... and if this scan fails, it displays a CAPTCHA to the user to make sure that it's a real human that wants to enter content that has the same properties like spam.
They offer a free service and some paid solutions. We are using it for some customers and it's worth the money. It also integrates very well in Drupal.
Comment Limit is probably what you need.
http://drupal.org/project/spam
http://drupal.org/project/antispam - with akismet support