Version 4.1.2
This commit is contained in:
1 parent
3ba79295ee
commit
28bd025b35
1131 files changed
+63658
-20579
No files matched your search
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<emails><template><template_app>forums</template_app><template_name>digests__comment</template_name><template_content_html><![CDATA[<tr style='border-bottom: 1px solid #eeeeee'>
|
||||
<td width='40' align='center' valign='top' class=' '>
|
||||
<td dir='{dir}' width='40' align='center' valign='top' class=' '>
|
||||
<img src='{$comment->author()->photo}' width='32' height='32' style='border: 1px solid #000; vertical-align: middle;'>
|
||||
</td>
|
||||
<td align='left'>
|
||||
<td dir='{dir}' align='left'>
|
||||
<p style='font-family: "Helvetica Neue", helvetica, sans-serif; margin: 0; font-size: 13px; font-weight: bold'>
|
||||
{{if $comment->item()->isQuestion()}}
|
||||
{$email->language->addToStack("x_answered_a_question", FALSE, array( 'sprintf' => array( $comment->author()->name ) ) )}
|
||||
@@ -20,10 +20,10 @@
|
||||
</td>
|
||||
</tr>]]></template_content_html><template_data>$comment, $email</template_data><template_content_plaintext><![CDATA[{{if $comment->item()->isQuestion()}}{$email->language->addToStack("x_answered_a_question", FALSE, array( 'sprintf' => array( $comment->author()->name ) ) )}{{else}}{$email->language->addToStack("x_replied_to_a_topic", FALSE, array( 'sprintf' => array( $comment->author()->name ) ) )}{{endif}}: {$comment->item()->mapped('title')} ({$comment->url()})
|
||||
]]></template_content_plaintext></template><template><template_app>forums</template_app><template_name>digests__item</template_name><template_content_html><![CDATA[<tr style='border-bottom: 1px solid #eeeeee'>
|
||||
<td width='40' align='center' valign='top' class=' '>
|
||||
<td dir='{dir}' width='40' align='center' valign='top' class=' '>
|
||||
<img src='{$topic->author()->photo}' width='32' height='32' style='border: 1px solid #000; vertical-align: middle;'>
|
||||
</td>
|
||||
<td align='left'>
|
||||
<td dir='{dir}' align='left'>
|
||||
<p style='font-family: "Helvetica Neue", helvetica, sans-serif; margin: 0; font-size: 13px; font-weight: bold'>
|
||||
{{if $topic->isQuestion()}}
|
||||
{$email->language->addToStack("x_asked_new_question", FALSE, array( 'sprintf' => array( $topic->author()->name, $topic->container()->_title ) ) )}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<javascript app="forums">
|
||||
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/forum" javascript_name="ips.forum.forumList.js" javascript_type="controller" javascript_version="100045" javascript_position="1000050"><![CDATA[/**
|
||||
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/forum" javascript_name="ips.forum.forumList.js" javascript_type="controller" javascript_version="101012" javascript_position="1000050"><![CDATA[/**
|
||||
* IPS Social Suite 4
|
||||
* (c) 2013 Invision Power Services - http://www.invisionpower.com
|
||||
*
|
||||
@@ -67,7 +67,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/forum" javascript_name="ips.forum.forumPage.js" javascript_type="controller" javascript_version="100045" javascript_position="1000050">/**
|
||||
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/forum" javascript_name="ips.forum.forumPage.js" javascript_type="controller" javascript_version="101012" javascript_position="1000050">/**
|
||||
* IPS Social Suite 4
|
||||
* (c) 2013 Invision Power Services - http://www.invisionpower.com
|
||||
*
|
||||
@@ -109,7 +109,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/forum" javascript_name="ips.forum.hovercard.js" javascript_type="controller" javascript_version="100045" javascript_position="1000050">/**
|
||||
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/forum" javascript_name="ips.forum.hovercard.js" javascript_type="controller" javascript_version="101012" javascript_position="1000050">/**
|
||||
* IPS Social Suite 4
|
||||
* (c) 2013 Invision Power Services - http://www.invisionpower.com
|
||||
*
|
||||
@@ -159,7 +159,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="forums" javascript_location="admin" javascript_path="controllers/settings" javascript_name="ips.settings.archiveRules.js" javascript_type="controller" javascript_version="100045" javascript_position="1000050"><![CDATA[/**
|
||||
<file javascript_app="forums" javascript_location="admin" javascript_path="controllers/settings" javascript_name="ips.settings.archiveRules.js" javascript_type="controller" javascript_version="101012" javascript_position="1000050"><![CDATA[/**
|
||||
* IPS Social Suite 4
|
||||
* (c) 2013 Invision Power Services - http://www.invisionpower.com
|
||||
*
|
||||
@@ -224,7 +224,7 @@
|
||||
});
|
||||
}(jQuery, _));
|
||||
]]></file>
|
||||
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/topic" javascript_name="ips.topic.answers.js" javascript_type="controller" javascript_version="100045" javascript_position="1000100"><![CDATA[/**
|
||||
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/topic" javascript_name="ips.topic.answers.js" javascript_type="controller" javascript_version="101012" javascript_position="1000100"><![CDATA[/**
|
||||
* IPS Social Suite 4
|
||||
* (c) 2013 Invision Power Services - http://www.invisionpower.com
|
||||
*
|
||||
@@ -329,7 +329,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/topic" javascript_name="ips.topic.reply.js" javascript_type="controller" javascript_version="100045" javascript_position="1000100">/**
|
||||
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/topic" javascript_name="ips.topic.reply.js" javascript_type="controller" javascript_version="101012" javascript_position="1000100">/**
|
||||
* IPS Social Suite 4
|
||||
* (c) 2013 Invision Power Services - http://www.invisionpower.com
|
||||
*
|
||||
@@ -358,7 +358,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/topic" javascript_name="ips.topic.view.js" javascript_type="controller" javascript_version="100045" javascript_position="1000100">/**
|
||||
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/topic" javascript_name="ips.topic.view.js" javascript_type="controller" javascript_version="101012" javascript_position="1000100">/**
|
||||
* IPS Social Suite 4
|
||||
* (c) 2013 Invision Power Services - http://www.invisionpower.com
|
||||
*
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<language>
|
||||
<app key="forums" version="100045">
|
||||
<app key="forums" version="101012">
|
||||
<word key="__app_forums" js="0">Forums</word>
|
||||
<word key="frontnavigation_forums" js="0">Forums</word>
|
||||
<word key="__indefart_post" js="0">a post in a topic</word>
|
||||
<word key="__indefart_topic" js="0">a topic</word>
|
||||
<word key="__indefart_answer" js="0">an answer to a question</word>
|
||||
<word key="__indefart_question" js="0">a question</word>
|
||||
<word key="topic_container" js="0">Forum</word>
|
||||
<word key="module__forums_forums" js="0">Forums</word>
|
||||
<word key="module__forums_stats" js="0">Statistics</word>
|
||||
<word key="filestorage__forums_Icons" js="0">Forum Icons</word>
|
||||
@@ -70,6 +71,7 @@
|
||||
<word key="forums" js="0">Forums</word>
|
||||
<word key="forums_sg" js="0">Forum</word>
|
||||
<word key="forums_add_child" js="0">Create Subforum</word>
|
||||
<word key="forums_add_child_cat" js="0">Create Forum</word>
|
||||
<word key="forum_name" js="0">Name</word>
|
||||
<word key="forum_description" js="0">Description</word>
|
||||
<word key="forum_description_placeholder" js="0">Add a description...</word>
|
||||
@@ -83,7 +85,7 @@
|
||||
<word key="forum_type_redirect" js="0">Redirect</word>
|
||||
<word key="forum_type_redirect_desc" js="0">Redirects users to another location when clicked on.</word>
|
||||
<word key="forum_password_on" js="0">Password protected?</word>
|
||||
<word key="forum_password_on_desc" js="0"><![CDATA[When enabled, users who have permission to access the forum will need to provide the password. Users who do not have permission to access the forum will not be prompted for the password. The password applies only to this forum, if this forum has subforums, the password will not be required for them.<br>Topics posted in a password protected forum will not show in any sidebar, header or footer blocks.]]></word>
|
||||
<word key="forum_password_on_desc" js="0"><![CDATA[When enabled, users who have permission to access the forum will need to provide the password. Users who do not have permission to access the forum will not be prompted for the password. The password applies only to this forum, if this forum has subforums, the password will not be required for them.<br>Topics posted in a password protected forum will not show in any sidebar, header or footer blocks, and notifications for new topics and posts will not be sent.]]></word>
|
||||
<word key="forum_password" js="0">Password</word>
|
||||
<word key="forum_password_override" js="0">No Password Required</word>
|
||||
<word key="forum_display" js="0">Display Settings</word>
|
||||
@@ -176,7 +178,7 @@
|
||||
<word key="forums_new_questions_any" js="0">Questions which have not received any answers.</word>
|
||||
<word key="forums_rss" js="0">Enable RSS feeds?</word>
|
||||
<word key="archiving" js="0">Archiving</word>
|
||||
<word key="archiving_blurb" js="0">If you have a very large site, it can be beneficial to reduce the size of the database table storing posts. Archiving topics is an alternative to deleting which allows them to still exist and be viewed as normal, but moves them to a separate database table. Archived topics cannot be posted in, or edited. You can unarchive topics after they've been archived if you change your mind.</word>
|
||||
<word key="archiving_blurb" js="0">If you have a very large site, it can be beneficial to reduce the size of the database table storing posts. Archiving topics is an alternative to deleting which allows them to still exist and be viewed as normal, but moves them to a separate database table. Archived topics cannot be posted in or edited, and will not show in search results. You can unarchive topics after they've been archived if you change your mind.</word>
|
||||
<word key="archive_topics_where" js="0"><![CDATA[Archive topics when <em>all</em> of the following conditions are true...]]></word>
|
||||
<word key="archive_topic_forums" js="0">In forums</word>
|
||||
<word key="archive_topic_not_forums" js="0">In forums</word>
|
||||
@@ -329,7 +331,6 @@
|
||||
<word key="ask_byline" js="0">Asked by %s, %s</word>
|
||||
<word key="ask_byline_itemprop" js="0"><![CDATA[Asked by <span itemprop='name'>%s</span>, %s]]></word>
|
||||
<word key="ask_byline_no_date" js="0">Asked by %s</word>
|
||||
<word key="topic_container" js="0">Forum</word>
|
||||
<word key="forum_rss_title_topics" js="0">%s Latest Topics</word>
|
||||
<word key="forum_rss_title_questions" js="0">%s Latest Questions</word>
|
||||
<word key="first_post" js="0">First post</word>
|
||||
@@ -384,6 +385,7 @@
|
||||
<word key="share_this_post" js="0">Share this post</word>
|
||||
<word key="subforums" js="0">Subforums:</word>
|
||||
<word key="subforums_header" js="0">Subforums</word>
|
||||
<word key="subforums_header_category" js="0">Forums</word>
|
||||
<word key="reply_to_topic" js="0">Reply to this topic</word>
|
||||
<word key="link_to_post" js="0">Link to post</word>
|
||||
<word key="share_externally" js="0">Share on other sites</word>
|
||||
@@ -472,6 +474,7 @@
|
||||
<word key="topic_reply_postcount" js="0">Increment post count?</word>
|
||||
<word key="can_use_saved_actions" js="0">Can use saved actions?</word>
|
||||
<word key="modlog__saved_action" js="0"><![CDATA[Ran "%s" saved action on topic: <a href='%s'>%s</a>]]></word>
|
||||
<word key="modlog__unarchived_topic" js="0"><![CDATA[Unarchived topic: <a href='%s'>%s</a>]]></word>
|
||||
<word key="rss_import" js="0">RSS/Atom Feed Imports</word>
|
||||
<word key="rss_import_url" js="0">URL</word>
|
||||
<word key="rss_import_invalid" js="0">That is not a valid RSS or Atom feed.</word>
|
||||
@@ -525,43 +528,19 @@
|
||||
<word key="loc_forums_index" js="0">Viewing Forums Index</word>
|
||||
<word key="ad_forum_listing" js="0">After the first topic in each forum</word>
|
||||
<word key="ad_topic_view" js="0">After the first post in each topic</word>
|
||||
<word key="ad_forum_listing_desc" js="0"><![CDATA[Some platforms, such as <a href='{external.secure-ads-adsense}' target='_blank'>Google Adsense</a>, may require you to perform extra steps to display advertisements on restricted pages.]]></word>
|
||||
<word key="ad_topic_view_desc" js="0"><![CDATA[Some platforms, such as <a href='{external.secure-ads-adsense}' target='_blank'>Google Adsense</a>, may require you to perform extra steps to display advertisements on restricted pages.]]></word>
|
||||
<word key="stats_new_topics" js="0">New Topics</word>
|
||||
<word key="stats_new_posts" js="0">New Posts</word>
|
||||
<word key="stats_topics_title" js="0">New topics by time period</word>
|
||||
<word key="stats_posts_title" js="0">New posts by time period</word>
|
||||
<word key="widget_feed_container_topic" js="0">Forums</word>
|
||||
<word key="tfb_title" js="0">Title</word>
|
||||
<word key="tfb_forums" js="0">Fetch from</word>
|
||||
<word key="tfb_use_perms" js="0">Honor forum permissions?</word>
|
||||
<word key="tfb_use_perms_desc" js="0">If enabled, will only show results from forums the user is allowed to view</word>
|
||||
<word key="tfb_topic_status" js="0">Topic status</word>
|
||||
<word key="tfb_open_status_open" js="0">Open</word>
|
||||
<word key="tfb_open_status_closed" js="0">Closed</word>
|
||||
<word key="tfb_open_status_pinned" js="0">Pinned</word>
|
||||
<word key="tfb_open_status_notpinned" js="0">Not Pinned</word>
|
||||
<word key="tfb_open_status_visible" js="0">Visible</word>
|
||||
<word key="tfb_open_status_hidden" js="0">Hidden</word>
|
||||
<word key="tfb_open_status_featured" js="0">Featured</word>
|
||||
<word key="tfb_open_status_notfeatured" js="0">Not Featured</word>
|
||||
<word key="tfb_author" js="0">Topic started by</word>
|
||||
<word key="tfb_min_posts" js="0">Topic minimum posts</word>
|
||||
<word key="tfb_show" js="0">Number to show</word>
|
||||
<word key="tfb_sort_on" js="0">Sort By</word>
|
||||
<word key="tfb_sort_on_last_post" js="0">Last Post</word>
|
||||
<word key="tfb_sort_on_title" js="0">Title</word>
|
||||
<word key="tfb_sort_on_posts" js="0">Posts</word>
|
||||
<word key="tfb_sort_on_start_date" js="0">Start Date</word>
|
||||
<word key="tfb_sort_on_views" js="0">Views</word>
|
||||
<word key="tfb_sort_dir" js="0">Direction</word>
|
||||
<word key="tfb_sort_dir_dsc" js="0">Descending (9-0)</word>
|
||||
<word key="tfb_sort_dir_asc" js="0">Ascending (0-9)</word>
|
||||
<word key="tfb_all_forums" js="0">All forums</word>
|
||||
<word key="tfb_any_posts" js="0">Any</word>
|
||||
<word key="block_topicFeed_title" js="0">Topics</word>
|
||||
<word key="block_postFeed_title" js="0">Posts</word>
|
||||
<word key="rssimport_task_error" js="0">Attempting to import the feed failed with the following message: %s</word>
|
||||
<word key="block_poll" js="0">Poll</word>
|
||||
<word key="block_poll_desc" js="0">Create a block with a poll from a topic</word>
|
||||
<word key="widget_poll_tid" js="0">Topic</word>
|
||||
<word key="widget_poll_tid_desc" js="0">Start typing the name of the topic</word>
|
||||
<word key="poll_view_topic" js="0">View topic</word>
|
||||
<word key="forumMarkedRead" js="1">Forum marked as read</word>
|
||||
<word key="topicMarkedRead" js="1">Topic marked as read</word>
|
||||
<word key="js_num_topic_posts" js="1">{# [1:post][?:posts]} in this topic</word>
|
||||
|
||||
@@ -1470,34 +1470,6 @@
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"use_sig": {
|
||||
"allow_null": false,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "",
|
||||
"decimals": null,
|
||||
"default": "0",
|
||||
"length": 1,
|
||||
"name": "use_sig",
|
||||
"type": "TINYINT",
|
||||
"unsigned": false,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"use_emo": {
|
||||
"allow_null": false,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "",
|
||||
"decimals": null,
|
||||
"default": "0",
|
||||
"length": 1,
|
||||
"name": "use_emo",
|
||||
"type": "TINYINT",
|
||||
"unsigned": false,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"ip_address": {
|
||||
"allow_null": false,
|
||||
"auto_increment": false,
|
||||
@@ -1812,11 +1784,9 @@
|
||||
"edit_time": "0",
|
||||
"author_id": "1",
|
||||
"author_name": "<%ADMIN_NAME%>",
|
||||
"use_sig": "1",
|
||||
"use_emo": "1",
|
||||
"ip_address": "<%IP_ADDRESS%>",
|
||||
"post_date": "<%TIME%>",
|
||||
"post": "<p>Welcome to your new IPS Community Suite!<\/p> <br \/><p> Congratulations on your purchase of our software and setting up your community. Please take some time and read through the Getting Started Guide and Administrator Documentation. The Getting Started Guide will walk you through some of the necessary steps to setting up an IP.Board and starting your community. The Administrator Documentation takes you through the details of the capabilities of IP.Board.<\/p> <br \/><p> You can remove this message, topic, forum or even category at any time.<\/p> <br \/><p><a href='http:\/\/remoteservices.invisionpower.com\/docs\/getting-started' rel='external'>Go to the documentation now...<\/a><br \/><p>Nulled by IAF<\/p>",
|
||||
"post": "<p>Welcome to your new IPS Community Suite!<\/p> <br \/><p> Congratulations on your purchase of our software and setting up your community. Please take some time and read through the Getting Started Guide and Administrator Documentation. The Getting Started Guide will walk you through some of the necessary steps to setting up an IP.Board and starting your community. The Administrator Documentation takes you through the details of the capabilities of IP.Board.<\/p> <br \/><p> You can remove this message, topic, forum or even category at any time.<\/p> <br \/><p><a href='http:\/\/remoteservices.invisionpower.com\/docs\/getting-started' rel='external'>Go to the documentation now...<\/a>",
|
||||
"queued": "0",
|
||||
"topic_id": "1",
|
||||
"new_topic": "1",
|
||||
@@ -2404,34 +2374,6 @@
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"archive_show_signature": {
|
||||
"allow_null": false,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "",
|
||||
"decimals": null,
|
||||
"default": "0",
|
||||
"length": 1,
|
||||
"name": "archive_show_signature",
|
||||
"type": "INT",
|
||||
"unsigned": false,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"archive_show_emoticons": {
|
||||
"allow_null": false,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "",
|
||||
"decimals": null,
|
||||
"default": "0",
|
||||
"length": 1,
|
||||
"name": "archive_show_emoticons",
|
||||
"type": "INT",
|
||||
"unsigned": false,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"archive_show_edited_by": {
|
||||
"allow_null": false,
|
||||
"auto_increment": false,
|
||||
|
||||
+392
-185
@@ -39,13 +39,13 @@
|
||||
<div class="ipsPageHeader ipsClearfix">
|
||||
<header class='ipsSpacer_bottom'>
|
||||
<h1 class="ipsType_pageTitle">{$forum->_title}</h1>
|
||||
{{if $forum->sub_can_post}}
|
||||
{{if $forum->sub_can_post and !$forum->password}}
|
||||
<div class='ipsPos_right ipsResponsive_noFloat ipsResponsive_hidePhone'>
|
||||
{template="follow" app="core" group="global" params="'forums','forum', $forum->_id, $followerCount"}
|
||||
</div>
|
||||
{{endif}}
|
||||
{{if $forum->description}}
|
||||
<div class='ipsType_richText ipsType_normal ipsSpacer_top'>
|
||||
<div class='ipsType_richText ipsType_normal'>
|
||||
{$forum->description|raw}
|
||||
</div>
|
||||
{{endif}}
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
{{if $forum->children()}}
|
||||
<div class='ipsList_reset cForumList ipsBox ipsSpacer_bottom' data-controller='forums.front.forum.forumList' data-baseURL=''>
|
||||
<h2 class='ipsType_sectionTitle ipsType_reset'>{lang="subforums_header"}</h2>
|
||||
<h2 class='ipsType_sectionTitle ipsType_reset'>{{if $forum->sub_can_post}}{lang="subforums_header"}{{else}}{lang="subforums_header_category"}{{endif}}</h2>
|
||||
{{if theme.forum_layout === 'grid'}}
|
||||
<div class='ipsAreaBackground ipsPad' data-role="forums">
|
||||
<div class='ipsGrid ipsGrid_collapsePhone' data-ipsGrid data-ipsGrid-minItemSize='300' data-ipsGrid-maxItemSize='400' data-ipsGrid-equalHeights='row'>
|
||||
@@ -76,7 +76,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<ol class="ipsDataList ipsDataList_large ipsDataList_zebra ipsAreaBackground_reset">
|
||||
<ol class="ipsDataList ipsDataList_zebra ipsDataList_large ipsAreaBackground_reset">
|
||||
{{foreach $forum->children( 'view' ) as $childforum}}
|
||||
{template="forumRow" group="index" app="forums" params="$childforum, TRUE"}
|
||||
{{endforeach}}
|
||||
@@ -94,7 +94,7 @@
|
||||
{template="forumButtons" group="forums" params="$forum"}
|
||||
</ul>
|
||||
</div>
|
||||
{{if !\IPS\Request::i()->advancedSearchForm && $forum->sub_can_post}}
|
||||
{{if !\IPS\Request::i()->advancedSearchForm && $forum->sub_can_post and !$forum->password}}
|
||||
<div class='ipsResponsive_showPhone ipsResponsive_block ipsSpacer ipsSpacer_both'>
|
||||
{template="follow" app="core" group="global" params="'forums','forum', $forum->_id, $followerCount"}
|
||||
</div>
|
||||
@@ -557,7 +557,10 @@
|
||||
</div>
|
||||
{{if $table->canModerate()}}
|
||||
<div class='ipsDataItem_modCheck'>
|
||||
<input type='checkbox' data-role='moderation' name="moderate[{$row->$idField}]" data-actions="{expression="implode( ' ', $table->multimodActions( $row ) )"}" data-state='{{if $row->mapped('pinned')}}pinned{{endif}} {{if $row->mapped('featured')}}featured{{endif}}'>
|
||||
<span class='ipsCustomInput'>
|
||||
<input type='checkbox' data-role='moderation' name="moderate[{$row->$idField}]" data-actions="{expression="implode( ' ', $table->multimodActions( $row ) )"}" data-state='{{if $row->mapped('pinned')}}pinned{{endif}} {{if $row->mapped('featured')}}featured{{endif}}'>
|
||||
<span></span>
|
||||
</span>
|
||||
</div>
|
||||
{{endif}}
|
||||
</li>
|
||||
@@ -609,7 +612,7 @@
|
||||
{template="prefix" group="global" app="core" params="$row->prefix( TRUE ), $row->prefix()"}
|
||||
{{endif}}
|
||||
|
||||
<a href='{$row->url()}' {{if $row->tableHoverUrl and $row->canView()}}data-ipsHover data-ipsHover-target='{$row->url()->setQueryString('preview', 1)}' data-ipsHover-timeout='1.5'{{endif}} itemprop="url">
|
||||
<a href='{$row->url()}' {{if $row->tableHoverUrl and $row->canView()}}data-ipsHover data-ipsHover-target='{$row->url()->setQueryString('preview', 1)}' data-ipsHover-timeout='1.5'{{endif}} itemprop="url" {{if $row->canEdit()}} data-role="editableTitle"{{endif}}>
|
||||
<span itemprop="name">
|
||||
{{if $row->mapped('title')}}{wordbreak="$row->mapped('title')"}{{else}}<em class="ipsType_light">{lang="content_deleted"}</em>{{endif}}
|
||||
</span>
|
||||
@@ -644,7 +647,10 @@
|
||||
</div>
|
||||
{{if $table->canModerate()}}
|
||||
<div class='ipsDataItem_modCheck'>
|
||||
<input type='checkbox' data-role='moderation' name="moderate[{$row->$idField}]" data-actions="{expression="implode( ' ', $table->multimodActions( $row ) )"}" data-state='{{if $row->tableStates()}}{$row->tableStates()}{{endif}}'>
|
||||
<span class='ipsCustomInput'>
|
||||
<input type='checkbox' data-role='moderation' name="moderate[{$row->$idField}]" data-actions="{expression="implode( ' ', $table->multimodActions( $row ) )"}" data-state='{{if $row->tableStates()}}{$row->tableStates()}{{endif}}'>
|
||||
<span></span>
|
||||
</span>
|
||||
</div>
|
||||
{{endif}}
|
||||
</li>
|
||||
@@ -690,7 +696,7 @@
|
||||
</div>
|
||||
<hr class='ipsHr'>
|
||||
|
||||
<div class='ipsType_richText ipsType_small'>
|
||||
<div class='ipsType_richText ipsType_small' data-controller='core.front.core.lightboxedImages'>
|
||||
{$tabData[1]->content()|raw}
|
||||
</div>
|
||||
{{if count( $overviews ) > 1}}
|
||||
@@ -731,13 +737,16 @@
|
||||
</div>
|
||||
{{if $table->canModerate()}}
|
||||
<div class='ipsDataItem_modCheck'>
|
||||
<input type='checkbox' data-role='moderation' name="moderate[{$row->$idField}]" data-actions="{{if $row->mapped('featured')}}unfeature{{endif}} {{if $row->mapped('pinned')}}unpin{{endif}} delete" data-state='{{if $row->mapped('pinned')}}pinned{{endif}} {{if $row->mapped('featured')}}featured{{endif}}'>
|
||||
<span class='ipsCustomInput'>
|
||||
<input type='checkbox' data-role='moderation' name="moderate[{$row->$idField}]" data-actions="{{if $row->mapped('featured')}}unfeature{{endif}} {{if $row->mapped('pinned')}}unpin{{endif}} delete" data-state='{{if $row->mapped('pinned')}}pinned{{endif}} {{if $row->mapped('featured')}}featured{{endif}}'>
|
||||
<span></span>
|
||||
</span>
|
||||
</div>
|
||||
{{endif}}
|
||||
</li>
|
||||
{{endif}}
|
||||
{{else}}
|
||||
<li class="ipsDataItem ipsDataItem_responsivePhoto {{if $row->unread()}}ipsDataItem_unread{{endif}} {{if method_exists( $row, 'tableClass' ) && $row->tableClass()}}ipsDataItem_{$row->tableClass()}{{endif}} {{if $row->hidden()}}ipsModerated{{endif}}" data-rowID='{$row->$idField}' itemscope itemtype="http://schema.org/Article">
|
||||
<li class="ipsDataItem ipsDataItem_responsivePhoto {{if $row->unread()}}ipsDataItem_unread{{endif}} {{if method_exists( $row, 'tableClass' ) && $row->tableClass()}}ipsDataItem_{$row->tableClass()}{{endif}} {{if $row->hidden()}}ipsModerated{{endif}}" data-rowID='{$row->$idField}' itemprop="itemListElement" itemscope itemtype="http://schema.org/Article">
|
||||
{{if member.member_id}}
|
||||
<div class='ipsDataItem_icon ipsPos_top'>
|
||||
{{if $row->unread()}}
|
||||
@@ -758,40 +767,42 @@
|
||||
{{if $row->locked()}}
|
||||
<i class='fa fa-lock' data-ipsTooltip title='{lang="topic_locked"}'></i>
|
||||
{{endif}}
|
||||
|
||||
|
||||
{{if $row->mapped('pinned') || $row->mapped('featured') || $row->hidden() === -1 || $row->hidden() === 1}}
|
||||
<span>
|
||||
{{if $row->hidden() === -1}}
|
||||
<span class="ipsBadge ipsBadge_icon ipsBadge_small ipsBadge_warning" data-ipsTooltip title='{$row->hiddenBlurb()}'><i class='fa fa-eye-slash'></i></span>
|
||||
{{elseif $row->hidden() === 1}}
|
||||
<span class="ipsBadge ipsBadge_icon ipsBadge_small ipsBadge_warning" data-ipsTooltip title='{lang="pending_approval"}'><i class='fa fa-warning'></i></span>
|
||||
{{endif}}
|
||||
{{if $row->mapped('pinned')}}
|
||||
<span class="ipsBadge ipsBadge_icon ipsBadge_small ipsBadge_positive" data-ipsTooltip title='{lang="pinned"}'><i class='fa fa-thumb-tack'></i></span>
|
||||
{{endif}}
|
||||
{{if $row->mapped('featured')}}
|
||||
<span class="ipsBadge ipsBadge_icon ipsBadge_small ipsBadge_positive" data-ipsTooltip title='{lang="featured"}'><i class='fa fa-star'></i></span>
|
||||
{{endif}}
|
||||
</span>
|
||||
{{endif}}
|
||||
|
||||
{{if $row->prefix()}}
|
||||
{template="prefix" group="global" app="core" params="$row->prefix( TRUE ), $row->prefix()"}
|
||||
{{endif}}
|
||||
|
||||
<a href='{$row->url()}' {{if $row->tableHoverUrl and $row->canView()}}data-ipsHover data-ipsHover-target='{$row->url()->setQueryString('preview', 1)}' data-ipsHover-timeout='1.5'{{endif}} itemprop="url" {{if $row->canEdit()}}data-role="editableTitle"{{endif}}>
|
||||
<span itemprop="name">
|
||||
<a href='{$row->url()}' itemprop="url"{{if $row->tableHoverUrl and $row->canView()}} data-ipsHover data-ipsHover-target='{$row->url()->setQueryString('preview', 1)}' data-ipsHover-timeout='1.5'{{endif}}{{if $row->canEdit()}} data-role="editableTitle"{{endif}}>
|
||||
<span itemprop="name headline">
|
||||
{{if $row->mapped('title')}}{wordbreak="$row->mapped('title')"}{{else}}<em class="ipsType_light">{lang="content_deleted"}</em>{{endif}}
|
||||
</span>
|
||||
</a>
|
||||
<meta itemprop="position" content="{$row->tid}">
|
||||
</h4>
|
||||
{{if $row->mapped('pinned') || $row->mapped('featured') || $row->hidden() === -1 || $row->hidden() === 1}}
|
||||
<span>
|
||||
{{if $row->hidden() === -1}}
|
||||
<span class="ipsBadge ipsBadge_icon ipsBadge_small ipsBadge_warning" data-ipsTooltip title='{$row->hiddenBlurb()}'><i class='fa fa-eye-slash'></i></span>
|
||||
{{elseif $row->hidden() === 1}}
|
||||
<span class="ipsBadge ipsBadge_icon ipsBadge_small ipsBadge_warning" data-ipsTooltip title='{lang="pending_approval"}'><i class='fa fa-warning'></i></span>
|
||||
{{endif}}
|
||||
{{if $row->mapped('pinned')}}
|
||||
<span class="ipsBadge ipsBadge_icon ipsBadge_small ipsBadge_positive" data-ipsTooltip title='{lang="pinned"}'><i class='fa fa-thumb-tack'></i></span>
|
||||
{{endif}}
|
||||
{{if $row->mapped('featured')}}
|
||||
<span class="ipsBadge ipsBadge_icon ipsBadge_small ipsBadge_positive" data-ipsTooltip title='{lang="featured"}'><i class='fa fa-star'></i></span>
|
||||
{{endif}}
|
||||
</span>
|
||||
{{endif}}
|
||||
{{if $row->commentPageCount() > 1}}
|
||||
{$row->commentPagination( array(), 'miniPagination' )|raw}
|
||||
{{endif}}
|
||||
<div class='ipsDataItem_meta ipsType_reset ipsType_light ipsType_blendLinks'>
|
||||
<span itemprop="author" itemscope itemtype="http://schema.org/Person">
|
||||
{lang="byline_itemprop" htmlsprintf="$row->author()->link()"}
|
||||
</span>{datetime="$row->__get( $row::$databaseColumnMap['date'] )"}
|
||||
<meta itemprop="dateCreated" content="{expression="\IPS\DateTime::create( $row->__get( $row::$databaseColumnMap['date'] ) )->rfc3339()"}">
|
||||
</span>{datetime="$row->mapped('date')" lowercase="true"}
|
||||
<meta itemprop="dateCreated datePublished" content="{expression="\IPS\DateTime::create( $row->__get( $row::$databaseColumnMap['date'] ) )->rfc3339()"}">
|
||||
{{if !in_array( \IPS\Dispatcher::i()->controller, array( 'forums', 'index' ) )}}
|
||||
{lang="in"} <a href="{$row->container()->url()}">{$row->container()->_title}</a>
|
||||
{{endif}}
|
||||
@@ -812,7 +823,7 @@
|
||||
</li>
|
||||
{{endforeach}}
|
||||
</ul>
|
||||
<ul class='ipsDataItem_lastPoster ipsDataItem_withPhoto'>
|
||||
<ul class='ipsDataItem_lastPoster ipsDataItem_withPhoto ipsType_blendLinks'>
|
||||
<li>
|
||||
{{if $row->mapped('num_comments')}}
|
||||
{template="userPhoto" app="core" group="global" params="$row->lastCommenter(), 'tiny'"}
|
||||
@@ -835,7 +846,10 @@
|
||||
</ul>
|
||||
{{if $table->canModerate()}}
|
||||
<div class='ipsDataItem_modCheck'>
|
||||
<input type='checkbox' data-role='moderation' name="moderate[{$row->$idField}]" data-actions="{expression="implode( ' ', $table->multimodActions( $row ) )"}" data-state='{{if $row->tableStates()}}{$row->tableStates()}{{endif}}'>
|
||||
<span class='ipsCustomInput'>
|
||||
<input type='checkbox' data-role='moderation' name="moderate[{$row->$idField}]" data-actions="{expression="implode( ' ', $table->multimodActions( $row ) )"}" data-state='{{if $row->tableStates()}}{$row->tableStates()}{{endif}}'>
|
||||
<span></span>
|
||||
</span>
|
||||
</div>
|
||||
{{endif}}
|
||||
</li>
|
||||
@@ -862,6 +876,55 @@
|
||||
</h3>
|
||||
<p class='ipsType_normal ipsType_light ipsType_blendLinks ipsType_reset'>{lang="in"} <a href='{$topic->container()->url()}'>{$topic->container()->_title}</a></p>
|
||||
</div>]]></template>
|
||||
<template template_group="global" template_name="manageFollowNodeRow" template_data="$table, $headers, $rows" template_location="front" template_app="forums"><![CDATA[{{foreach $rows as $row}}
|
||||
{{$contentItemClass = $row::$contentItemClass;}}
|
||||
<li class="ipsDataItem {{if method_exists( $row, 'tableClass' ) && $row->tableClass()}}ipsDataItem_{$row->tableClass()}{{endif}}" data-controller='core.front.system.manageFollowed' data-followID='{$row->_followData['follow_area']}-{$row->_followData['follow_rel_id']}'>
|
||||
<div class='ipsDataItem_main'>
|
||||
<h4 class='ipsDataItem_title'>
|
||||
{{if $row->_locked}}
|
||||
<i class="fa fa-lock"></i>
|
||||
{{endif}}
|
||||
|
||||
<a href='{$row->url()}'>
|
||||
{$row->_title}
|
||||
</a>
|
||||
</h4>
|
||||
<ul class='ipsList_inline ipsType_light'>
|
||||
<li>{lang="posts_number" pluralize="$row->_comments + $row->_items"}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class='ipsDataItem_generic ipsDataItem_size1 ipsType_center ipsType_large'>
|
||||
<span class='ipsBadge ipsBadge_icon ipsBadge_new {{if !$row->_followData['follow_is_anon']}}ipsHide{{endif}}' data-role='followAnonymous' data-ipsTooltip title='{lang="follow_is_anon"}'><i class='fa fa-eye-slash'></i></span>
|
||||
</div>
|
||||
|
||||
<div class='ipsDataItem_generic ipsDataItem_size6'>
|
||||
<ul class='ipsList_reset'>
|
||||
<li title='{lang="follow_when"}' data-role='followDate'><i class='fa fa-clock-o'></i> {datetime="$row->_followData['follow_added']"}</li>
|
||||
<li title='{lang="follow_how"}' data-role='followFrequency'>
|
||||
{{if $row->_followData['follow_notify_freq'] == 'none'}}
|
||||
<i class='fa fa-bell-slash-o'></i>
|
||||
{{else}}
|
||||
<i class='fa fa-bell'></i>
|
||||
{{endif}} {lang="follow_freq_{$row->_followData['follow_notify_freq']}"}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class='ipsDataItem_generic ipsDataItem_size6 ipsType_center'>
|
||||
{template="manageFollow" group="system" app="core" params="$row->_followData['follow_app'], $row->_followData['follow_area'], $row->_followData['follow_rel_id']"}
|
||||
</div>
|
||||
|
||||
{{if $table->canModerate()}}
|
||||
<div class='ipsDataItem_modCheck'>
|
||||
<span class='ipsCustomInput'>
|
||||
<input type='checkbox' data-role='moderation' name="moderate[{$row->_id}]" data-actions="{expression="implode( ' ', $table->multimodActions( $row ) )"}" data-state=''>
|
||||
<span></span>
|
||||
</span>
|
||||
</div>
|
||||
{{endif}}
|
||||
</li>
|
||||
{{endforeach}}]]></template>
|
||||
<template template_group="global" template_name="row" template_data="$table, $headers, $topic, $showReadMarkers=TRUE" template_location="front" template_app="forums"><![CDATA[{{$idField = $topic::$databaseColumnId;}}
|
||||
{{$iPosted = isset( $table->contentPostedIn ) ? $table->contentPostedIn : ( $table AND method_exists( $table, 'container' ) AND $topic->container() !== NULL ) ? $topic->container()->contentPostedIn() : array();}}
|
||||
<li class="ipsDataItem ipsDataItem_responsivePhoto {{if $topic->unread()}}ipsDataItem_unread{{endif}} {{if method_exists( $topic, 'tableClass' ) && $topic->tableClass()}}ipsDataItem_{$topic->tableClass()}{{endif}} {{if $topic->hidden()}}ipsModerated{{endif}}">
|
||||
@@ -884,12 +947,6 @@
|
||||
{{endif}}
|
||||
<div class='ipsDataItem_main'>
|
||||
<h4 class='ipsDataItem_title ipsType_break'>
|
||||
<a href='{$topic->url()}' {{if $topic->canView()}}data-ipsHover data-ipsHover-target='{$topic->url()->setQueryString('preview', 1)}' data-ipsHover-timeout='1.5' {{endif}}>
|
||||
{{if $topic->isQuestion()}}
|
||||
<strong class='ipsType_light'>{lang="question_title"}:</strong>
|
||||
{{endif}}
|
||||
{wordbreak="$topic->mapped('title')"}
|
||||
</a>
|
||||
{{if $topic->mapped('pinned') || $topic->mapped('featured') || $topic->hidden() === -1 || $topic->hidden() === 1}}
|
||||
<span>
|
||||
{{if $topic->hidden() === -1}}
|
||||
@@ -905,6 +962,13 @@
|
||||
{{endif}}
|
||||
</span>
|
||||
{{endif}}
|
||||
|
||||
<a href='{$topic->url()}' {{if $topic->canView()}}data-ipsHover data-ipsHover-target='{$topic->url()->setQueryString('preview', 1)}' data-ipsHover-timeout='1.5' {{endif}}>
|
||||
{{if $topic->isQuestion()}}
|
||||
<strong class='ipsType_light'>{lang="question_title"}:</strong>
|
||||
{{endif}}
|
||||
{wordbreak="$topic->mapped('title')"}
|
||||
</a>
|
||||
</h4>
|
||||
{{if $topic->commentPageCount() > 1}}
|
||||
{$topic->commentPagination( array(), 'miniPagination' )|raw}
|
||||
@@ -971,7 +1035,10 @@
|
||||
</ul>
|
||||
{{if method_exists( $table, 'canModerate' ) AND $table->canModerate()}}
|
||||
<div class='ipsDataItem_modCheck'>
|
||||
<input type='checkbox' data-role='moderation' name="moderate[{$topic->tid}]" data-actions="{expression="implode( ' ', $table->multimodActions( $topic ) )"}" data-state='{{if $topic->tableStates()}}{$topic->tableStates()}{{endif}}'>
|
||||
<span class='ipsCustomInput'>
|
||||
<input type='checkbox' data-role='moderation' name="moderate[{$topic->tid}]" data-actions="{expression="implode( ' ', $table->multimodActions( $topic ) )"}" data-state='{{if $topic->tableStates()}}{$topic->tableStates()}{{endif}}'>
|
||||
<span></span>
|
||||
</span>
|
||||
</div>
|
||||
{{endif}}
|
||||
</li>]]></template>
|
||||
@@ -980,39 +1047,12 @@
|
||||
{template="row" group="global" app="forums" params="$table, $headers, $row"}
|
||||
{{endforeach}}
|
||||
{{endif}}</template>
|
||||
<template template_group="global" template_name="searchNoPermission" template_data="$topic, $lang, $link=NULL" template_location="front" template_app="forums"><![CDATA[<li class="ipsDataItem">
|
||||
<div class='ipsPad ipsType_center ipsType_light ipsType_large'>
|
||||
<template template_group="global" template_name="searchNoPermission" template_data="$lang, $link=NULL" template_location="front" template_app="forums"><![CDATA[<li class="ipsStreamItem ipsStreamItem_contentBlock ipsAreaBackground_reset ipsPad">
|
||||
<div class='ipsType_center ipsType_light ipsType_large'>
|
||||
{$lang}{{if $link}} <a href="{$link}">{lang="enter_password"}</a>{{endif}}
|
||||
</div>
|
||||
</li>
|
||||
]]></template>
|
||||
<template template_group="global" template_name="snippet" template_data="$activity, $type='activity'" template_location="front" template_app="forums"><![CDATA[{{if $activity instanceof \IPS\forums\Topic}}
|
||||
<div class='cSearchActivity_info ipsContained'>
|
||||
{{if $type != 'search'}}<a href='{$activity->url()}' class='ipsType_normal ipsType_break'>{$activity->mapped('title')}</a>{{endif}}
|
||||
{{if mb_strlen( trim( $activity->truncated() ) ) }}
|
||||
<div class='ipsType_medium ipsType_richText ipsContained {{if $type != 'search'}}ipsSpacer_both{{else}}ipsSpacer_bottom{{endif}} ipsSpacer_half' data-ipsTruncate data-ipsTruncate-size='3 lines' data-ipsTruncate-type='remove'>
|
||||
{$activity->truncated()|raw}
|
||||
</div>
|
||||
{{endif}}
|
||||
<ul class='ipsList_inline ipsType_light'>
|
||||
<li>{lang="replies_number" pluralize="$activity->posts-1"}</li>
|
||||
<li>{lang="num_views_with_number" pluralize="$activity->mapped('views')"}</li>
|
||||
</ul>
|
||||
</div>
|
||||
{{else}}
|
||||
{{if mb_strlen( trim( strip_tags( $activity->truncated() ) ) ) }}
|
||||
<div class='cSearchActivity_info ipsContained'>
|
||||
<div class='ipsType_medium ipsType_richText ipsContained ipsSpacer_bottom ipsSpacer_half' data-ipsTruncate data-ipsTruncate-size='3 lines' data-ipsTruncate-type='remove'>
|
||||
{$activity->truncated()|raw}
|
||||
</div>
|
||||
{{if $type != 'search' and $activity instanceof \IPS\Content\Reputation and settings.reputation_enabled}}
|
||||
<ul class='ipsList_inline ipsType_light'>
|
||||
<li>{template="reputationMini" group="global" app="core" params="$activity, '', NULL, TRUE"}</li>
|
||||
</ul>
|
||||
{{endif}}
|
||||
</div>
|
||||
{{endif}}
|
||||
{{endif}}]]></template>
|
||||
<template template_group="index" template_name="forumGridItem" template_data="$forum" template_location="front" template_app="forums"><![CDATA[{{if $forum->can('view')}}
|
||||
{{$lastPost = $forum->lastPost();}}
|
||||
<div class="ipsDataItem ipsGrid_span4 ipsAreaBackground_reset cForumGrid {{if \IPS\forums\Topic::containerUnread( $forum ) && !$forum->redirect_on}}cForumGrid_unread ipsDataItem_unread{{endif}} ipsClearfix" data-forumID="{$forum->_id}">
|
||||
@@ -1168,7 +1208,7 @@
|
||||
{{endif}}
|
||||
</div>
|
||||
<div class="ipsDataItem_main">
|
||||
<h4 class="ipsDataItem_title ipsType_large">
|
||||
<h4 class="ipsDataItem_title ipsType_large ipsType_break">
|
||||
{{if $forum->password && !$forum->loggedInMemberHasPasswordAccess()}}
|
||||
<a href="{$forum->url()->setQueryString( 'passForm', '1' )}" data-ipsDialog data-ipsDialog-size='narrow' data-ipsDialog-title='{lang="forum_requires_password"}'>{$forum->_title}</a>
|
||||
{{else}}
|
||||
@@ -1204,13 +1244,13 @@
|
||||
<strong class='ipsType_warning ipsType_medium'>
|
||||
<i class='fa fa-warning'></i>
|
||||
{{if $unapprovedContent['topics']}}
|
||||
<a href='{$forum->url()->setQueryString( array( 'advanced_search_submitted' => 1, 'topic_type' => 'queued_topics' ) )->csrf()}' data-ipsTooltip title='{lang="queued_topics_badge" pluralize="$forum->queued_topics"}' class='ipsType_blendLinks'>{$unapprovedContent['topics']}</a>
|
||||
<a href='{$forum->url()->setQueryString( array( 'advanced_search_submitted' => 1, 'topic_type' => 'queued_topics' ) )->csrf()}' data-ipsTooltip title='{lang="queued_topics_badge" pluralize="$unapprovedContent['topics']"}' class='ipsType_blendLinks'>{$unapprovedContent['topics']}</a>
|
||||
{{else}}
|
||||
<span class='ipsType_light'>0</span>
|
||||
{{endif}}
|
||||
/
|
||||
{{if $unapprovedContent['posts']}}
|
||||
<a href='{$forum->url()->setQueryString( array( 'advanced_search_submitted' => 1, 'topic_type' => 'queued_posts' ) )->csrf()}' data-ipsTooltip title='{lang="queued_posts_badge" pluralize="$forum->queued_posts"}' class='ipsType_blendLinks'>{$unapprovedContent['posts']}</a>
|
||||
<a href='{$forum->url()->setQueryString( array( 'advanced_search_submitted' => 1, 'topic_type' => 'queued_posts' ) )->csrf()}' data-ipsTooltip title='{lang="queued_posts_badge" pluralize="$unapprovedContent['posts']"}' class='ipsType_blendLinks'>{$unapprovedContent['posts']}</a>
|
||||
{{else}}
|
||||
<span class='ipsType_light'>0</span>
|
||||
{{endif}}
|
||||
@@ -1220,8 +1260,8 @@
|
||||
<ul class="ipsDataItem_lastPoster ipsDataItem_withPhoto">
|
||||
{{if $lastPost}}
|
||||
<li>{template="userPhoto" app="core" group="global" params="$lastPost['author'], 'tiny'"}</li>
|
||||
<li><a href="{$lastPost['topic_url']->setQueryString( 'do', 'getNewComment' )}" class='ipsType_break ipsContained' title='{$lastPost['topic_title']}'>{truncate="$lastPost['topic_title']" length="30"}</a></li>
|
||||
<li>{lang="byline_nodate" htmlsprintf="$lastPost['author']->link()"}</li>
|
||||
<li><a href="{$lastPost['topic_url']->setQueryString( 'do', 'getNewComment' )}" class='ipsType_break ipsContained' title='{$lastPost['topic_title']}'>{truncate="$lastPost['topic_title']" length="26"}</a></li>
|
||||
<li class='ipsType_blendLinks'>{lang="byline_nodate" htmlsprintf="$lastPost['author']->link()"}</li>
|
||||
<li class="ipsType_light"><a href='{$lastPost['topic_url']->setQueryString( 'do', 'getLastComment' )}' title='{lang="get_last_post"}' class='ipsType_blendLinks'>{datetime="$lastPost['date']"}</a></li>
|
||||
{{else}}
|
||||
<li class='ipsType_light ipsResponsive_showDesktop'>{{if $forum->password}}{lang="no_forum_posts_password"}{{else}}{lang="no_forum_posts"}{{endif}}</li>
|
||||
@@ -1230,7 +1270,10 @@
|
||||
{{endif}}
|
||||
{{if $table and $table->canModerate()}}
|
||||
<div class='ipsDataItem_modCheck'>
|
||||
<input type='checkbox' data-role='moderation' name="moderate[{$forum->_id}]" data-actions="{expression="implode( ' ', $table->multimodActions( $forum ) )"}" data-state=''>
|
||||
<span class='ipsCustomInput'>
|
||||
<input type='checkbox' data-role='moderation' name="moderate[{$forum->_id}]" data-actions="{expression="implode( ' ', $table->multimodActions( $forum ) )"}" data-state=''>
|
||||
<span></span>
|
||||
</span>
|
||||
</div>
|
||||
{{endif}}
|
||||
</li>
|
||||
@@ -1242,7 +1285,7 @@
|
||||
|
||||
{{if \IPS\Member::loggedIn()->member_id}}
|
||||
<ul class="ipsToolList ipsToolList_horizontal ipsResponsive_hideDesktop ipsResponsive_block ipsClearfix">
|
||||
{template="indexButtons" group="index" params=""}
|
||||
{template="indexButtons" group="index" app="forums" params=""}
|
||||
</ul>
|
||||
{{endif}}
|
||||
|
||||
@@ -1251,13 +1294,13 @@
|
||||
{{foreach \IPS\forums\Forum::roots() as $category}}
|
||||
{{if $category->can('view') && $category->hasChildren()}}
|
||||
<li data-categoryID='{$category->_id}' class='cForumRow ipsBox ipsSpacer_bottom'>
|
||||
<h2 class="ipsType_sectionTitle ipsType_reset ipsType_blendLinks cForumTitle">
|
||||
<a href='#' class='ipsPos_right ipsJS_show cForumToggle' data-action='toggleCategory' data-ipsTooltip title='{lang="toggle_this_category"}'></a>
|
||||
<h2 class="ipsType_sectionTitle ipsType_reset cForumTitle">
|
||||
<a href='#' class='ipsPos_right ipsJS_show ipsType_noUnderline cForumToggle' data-action='toggleCategory' data-ipsTooltip title='{lang="toggle_this_category"}'></a>
|
||||
<a href='{$category->url()}'>{$category->_title}</a>
|
||||
</h2>
|
||||
{{if theme.forum_layout === 'grid'}}
|
||||
<div class='ipsAreaBackground ipsPad' data-role="forums">
|
||||
<div class='ipsGrid ipsGrid_collapsePhone' data-ipsGrid data-ipsGrid-minItemSize='300' data-ipsGrid-maxItemSize='400' data-ipsGrid-equalHeights='row'>
|
||||
<div class='ipsGrid ipsGrid_collapsePhone' data-ipsGrid data-ipsGrid-minItemSize='250' data-ipsGrid-maxItemSize='500' data-ipsGrid-equalHeights='row'>
|
||||
{{foreach $category->children() as $forum}}
|
||||
{template="forumGridItem" group="index" app="forums" params="$forum"}
|
||||
{{endforeach}}
|
||||
@@ -1288,7 +1331,11 @@
|
||||
<option value=">" {{if isset( $value[0] ) and $value[0] == '>'}}selected{{endif}}>{lang="greater_than"}</option>
|
||||
<option value="<" {{if isset( $value[0] ) and $value[0] == '<'}}selected{{endif}}>{lang="less_than"}</option>
|
||||
</select>
|
||||
<input type="number" name="{$name}[1]" value="{{if isset( $value[1] )}}{$value[1]}{{endif}}" id='el{$name}_1' class="ipsField_short"> {lang="or"} <input type="checkbox" name="{$name}[2]" data-control="unlimited" {{if isset( $value[2] ) and $value[2]}}checked{{endif}}> <label for='el{$name}_1' class='ipsField_unlimited'>{{if in_array( $name, array( 'archive_topic_post', 'archive_topic_view', 'archive_topic_rating', 'archive_not_topic_post', 'archive_not_topic_view', 'archive_not_topic_rating' ) )}}{lang="no_restriction"}{{else}}{lang="any_time"}{{endif}}</label>]]></template>
|
||||
<input type="number" name="{$name}[1]" value="{{if isset( $value[1] )}}{$value[1]}{{endif}}" id='el{$name}_1' class="ipsField_short"> {lang="or"}
|
||||
<span class='ipsCustomInput'>
|
||||
<input type="checkbox" name="{$name}[2]" data-control="unlimited" {{if isset( $value[2] ) and $value[2]}}checked{{endif}}>
|
||||
<span></span>
|
||||
</span> <label for='el{$name}_1' class='ipsField_unlimited'>{{if in_array( $name, array( 'archive_topic_post', 'archive_topic_view', 'archive_topic_rating', 'archive_not_topic_post', 'archive_not_topic_view', 'archive_not_topic_rating' ) )}}{lang="no_restriction"}{{else}}{lang="any_time"}{{endif}}</label>]]></template>
|
||||
<template template_group="settings" template_name="archiveRules" template_data="$form, $totalTopics, $existingCount, $existingPercentage" template_location="admin" template_app="forums"><![CDATA[<div data-controller="forums.admin.settings.archiveRules">
|
||||
<div class="ipsPad ipsType_normal">{lang="archiving_blurb"}</div>
|
||||
<div data-ipsSticky data-ipsSticky-spacing='60' class="ipsPad_half ipsAreaBackground_reset ipsType_center">
|
||||
@@ -1305,17 +1352,25 @@
|
||||
</select>
|
||||
<input type="number" name="{$name}[1]" value="{{if isset( $value[1] )}}{$value[1]}{{endif}}" class="ipsField_short" min="0">
|
||||
<select name="{$name}[2]">
|
||||
<option value="d" {{if isset( $value[2] ) and $value[2] == 's'}}selected{{endif}}>{lang="days"}</option>
|
||||
<option value="d" {{if isset( $value[2] ) and $value[2] == 'd'}}selected{{endif}}>{lang="days"}</option>
|
||||
<option value="m" {{if isset( $value[2] ) and $value[2] == 'm'}}selected{{endif}}>{lang="months"}</option>
|
||||
<option value="y" {{if isset( $value[2] ) and $value[2] == 'y'}}selected{{endif}}>{lang="years"}</option>
|
||||
</select>
|
||||
{lang="ago"} {lang="or"} <input type="checkbox" name="{$name}[3]" id='el{$name}_3' data-control="unlimited" {{if isset( $value[3] ) and $value[3]}}checked{{endif}}> <label for='el{$name}_3' class='ipsField_unlimited'>{{if mb_strpos( $name, 'not' )}}{lang="no_restriction"}{{else}}{lang="any_time"}{{endif}}</label>]]></template>
|
||||
<template template_group="settings" template_name="popularNow" template_data="$name, $value" template_location="admin" template_app="forums"><![CDATA[<input type="number" name="{$name}[posts]" value="{$value['posts']}" class="ipsField_short"> {lang="posts_in_the_last"} <input type="number" name="{$name}[minutes]" value="{$value['minutes']}" class="ipsField_short"> {lang="minutes"} {lang="or"} <input type="checkbox" name="{$name}[never]" id='el{$name}_never' data-control="unlimited" {{if !$value['posts']}}checked{{endif}}> <label for='el{$name}_never' class='ipsField_unlimited'>{lang="never"}</label>]]></template>
|
||||
{lang="ago"} {lang="or"}
|
||||
<span class='ipsCustomInput'>
|
||||
<input type="checkbox" name="{$name}[3]" id='el{$name}_3' data-control="unlimited" {{if isset( $value[3] ) and $value[3]}}checked{{endif}}>
|
||||
<span></span>
|
||||
</span> <label for='el{$name}_3' class='ipsField_unlimited'>{{if mb_strpos( $name, 'not' )}}{lang="no_restriction"}{{else}}{lang="any_time"}{{endif}}</label>]]></template>
|
||||
<template template_group="settings" template_name="popularNow" template_data="$name, $value" template_location="admin" template_app="forums"><![CDATA[<input type="number" name="{$name}[posts]" value="{$value['posts']}" class="ipsField_short"> {lang="posts_in_the_last"} <input type="number" name="{$name}[minutes]" value="{$value['minutes']}" class="ipsField_short"> {lang="minutes"} {lang="or"}
|
||||
<span class='ipsCustomInput'>
|
||||
<input type="checkbox" name="{$name}[never]" id='el{$name}_never' data-control="unlimited" {{if !$value['posts']}}checked{{endif}}>
|
||||
<span></span>
|
||||
</span> <label for='el{$name}_never' class='ipsField_unlimited'>{lang="never"}</label>]]></template>
|
||||
<template template_group="submit" template_name="createTopic" template_data="$form, $forum, $title" template_location="front" template_app="forums"><![CDATA[
|
||||
{template="pageHeader" if="!\IPS\Request::i()->isAjax()" group="global" app="core" params="\IPS\Member::loggedIn()->language()->addToStack( $title )"}
|
||||
|
||||
{$form|raw}]]></template>
|
||||
<template template_group="submit" template_name="createTopicForm" template_data="$forum, $hasModOptions, $id, $action, $elements, $hiddenValues, $actionButtons, $uploadField, $class='', $attributes=array(), $sidebar=NULL, $form=NULL, $errorTabs=array()" template_location="front" template_app="forums"><![CDATA[{{$modOptions = array( 'topic_create_state', 'create_topic_locked', 'create_topic_pinned', 'create_topic_hidden', 'create_topic_featured', 'topic_open_time', 'topic_close_time');}}
|
||||
<template template_group="submit" template_name="createTopicForm" template_data="$forum, $hasModOptions, $topic, $id, $action, $elements, $hiddenValues, $actionButtons, $uploadField, $class='', $attributes=array(), $sidebar=NULL, $form=NULL, $errorTabs=array()" template_location="front" template_app="forums"><![CDATA[{{$modOptions = array( 'topic_create_state', 'create_topic_locked', 'create_topic_pinned', 'create_topic_hidden', 'create_topic_featured', 'topic_open_time', 'topic_close_time');}}
|
||||
|
||||
<form accept-charset='utf-8' class="ipsForm {$class}" action="{$action}" method="post" {{if $uploadField}}enctype="multipart/form-data"{{endif}} data-ipsForm>
|
||||
<input type="hidden" name="{$id}_submitted" value="1">
|
||||
@@ -1326,6 +1381,10 @@
|
||||
<input type="hidden" name="MAX_FILE_SIZE" value="{$uploadField}">
|
||||
<input type="hidden" name="plupload" value="{expression="md5( uniqid() )"}">
|
||||
{{endif}}
|
||||
|
||||
{{if $form->error}}
|
||||
<p class="ipsMessage ipsMessage_error">{$form->error}</p>
|
||||
{{endif}}
|
||||
|
||||
<div class='ipsBox'>
|
||||
<h2 class='ipsType_sectionTitle ipsType_reset'>{lang="topic_details"}</h2>
|
||||
@@ -1396,7 +1455,7 @@
|
||||
{{endif}}
|
||||
|
||||
<div class='ipsAreaBackground ipsPad ipsType_center'>
|
||||
<a href="{$forum->url()}" class="ipsButton ipsButton_link ipsButton ipsButton_link">{lang="cancel"}</a>
|
||||
<a href="{{if !is_null($topic)}}{$topic->url()}{{else}}{$forum->url()}{{endif}}" class="ipsButton ipsButton_link ipsButton ipsButton_link">{lang="cancel"}</a>
|
||||
<button type='submit' class='ipsButton ipsButton_medium ipsButton_primary' accesskey="s" role="button">{{if $forum->forums_bitoptions['bw_enable_answers']}}{lang="submit_question"}{{else}}{lang="submit_topic"}{{endif}}</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1432,19 +1491,27 @@
|
||||
</div>]]></template>
|
||||
<template template_group="topics" template_name="post" template_data="$item, $comment, $editorName, $app, $type, $class=''" template_location="front" template_app="forums"><![CDATA[{{$idField = $comment::$databaseColumnId;}}
|
||||
<div id='comment-{$comment->$idField}_wrap' data-controller='core.front.core.comment' data-commentApp='{$app}' data-commentType='{$type}' data-commentID="{$comment->$idField}" data-quoteData='{expression="json_encode( array('userid' => $comment->author()->member_id, 'username' => $comment->author()->name, 'timestamp' => $comment->mapped('date'), 'contentapp' => $comment::$application, 'contenttype' => $type, 'contentid' => $item->tid, 'contentclass' => $class, 'contentcommentid' => $comment->$idField) )"}' class='ipsComment_content ipsType_medium {{if $comment->hidden()}}ipsModerated{{endif}} ipsFaded_withHover'>
|
||||
{{if settings.reputation_highlight and $comment->reputation() >= settings.reputation_highlight}}
|
||||
<strong class='ipsComment_popularFlag' data-ipsTooltip title='{lang="this_is_a_popular_post"}'><i class='fa fa-heart'></i></strong>
|
||||
{{endif}}
|
||||
|
||||
<div class='ipsComment_meta ipsType_light'>
|
||||
<p class='ipsPos_right ipsType_reset ipsType_blendLinks ipsFaded ipsFaded_more'>
|
||||
{{if \IPS\Member::loggedIn()->modPermission('can_use_ip_tools') and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'modcp' ) )}}
|
||||
<span class='ipsResponsive_hidePhone'>(<a href="{url="app=core&module=modcp&controller=modcp&tab=ip_tools&ip=$comment->ip_address" seoTemplate="modcp_ip_tools"}">{lang="ip_prefix" sprintf="$comment->ip_address"}</a>) ·</span>
|
||||
{{endif}}
|
||||
<a href='{$comment->item()->url()->setQueryString( array( 'do' => 'findComment', 'comment' => $comment->pid ) )}' data-ipsTooltip title='{lang="share_this_post"}' data-ipsMenu data-ipsMenu-closeOnClick='false' id='elSharePost_{$comment->pid}'><i class='fa fa-share-alt'></i></a>
|
||||
<a href='{$comment->item()->url()->setQueryString( array( 'do' => 'findComment', 'comment' => $comment->$idField ) )}' data-ipsTooltip title='{lang="share_this_post"}' data-ipsMenu data-ipsMenu-closeOnClick='false' id='elSharePost_{$comment->$idField}' data-role='shareComment'><i class='fa fa-share-alt'></i></a>
|
||||
{{if count( $item->commentMultimodActions() ) and !$comment->mapped('first')}}
|
||||
· <input type="checkbox" name="multimod[{$comment->$idField}]" value="1" data-role="moderation" data-actions="{{if $comment->canSplit()}}split merge{{endif}} {{if $comment->hidden() === -1 AND $comment->canUnhide()}}unhide{{elseif $comment->hidden() === 1 AND $comment->canUnhide()}}approve{{elseif $comment->canHide()}}hide{{endif}} {{if $comment->canDelete()}}delete{{endif}}" data-state='{{if $comment->tableStates()}}{$comment->tableStates()}{{endif}}'>
|
||||
·
|
||||
<span class='ipsCustomInput'>
|
||||
<input type="checkbox" name="multimod[{$comment->$idField}]" value="1" data-role="moderation" data-actions="{{if $comment->canSplit()}}split merge{{endif}} {{if $comment->hidden() === -1 AND $comment->canUnhide()}}unhide{{elseif $comment->hidden() === 1 AND $comment->canUnhide()}}approve{{elseif $comment->canHide()}}hide{{endif}} {{if $comment->canDelete()}}delete{{endif}}" data-state='{{if $comment->tableStates()}}{$comment->tableStates()}{{endif}}'>
|
||||
<span></span>
|
||||
</span>
|
||||
{{endif}}
|
||||
</p>
|
||||
|
||||
<p class='ipsType_reset'>
|
||||
{$comment->dateLine()|raw}
|
||||
<a href='{$comment->item()->url()->setQueryString( array( 'do' => 'findComment', 'comment' => $comment->$idField ) )}' class='ipsType_blendLinks' title='{lang="share_this_comment"}'>{$comment->dateLine()|raw}</a>
|
||||
{{if $comment->editLine()}}
|
||||
({lang="edited_lc"})
|
||||
{{endif}}
|
||||
@@ -1462,11 +1529,7 @@
|
||||
{{endif}}
|
||||
|
||||
|
||||
<div class='cPost_contentWrap ipsPad'>
|
||||
{{if settings.reputation_highlight and $comment->reputation() >= settings.reputation_highlight}}
|
||||
<strong class='ipsComment_popularFlag' data-ipsTooltip title='{lang="this_is_a_popular_post"}'><i class='fa fa-star'></i></strong>
|
||||
{{endif}}
|
||||
|
||||
<div class='cPost_contentWrap ipsPad'>
|
||||
<div data-role='commentContent' itemprop='text' class='ipsType_normal ipsType_richText ipsContained' data-controller='core.front.core.lightboxedImages'>
|
||||
{$comment->content()|raw}
|
||||
|
||||
@@ -1584,7 +1647,7 @@
|
||||
{{if $item->isQuestion() and !$comment->new_topic}}
|
||||
{template="postRating" group="topics" app="forums" params="$item, $comment, $votes"}
|
||||
{{endif}}
|
||||
<aside class='ipsComment_author cAuthorPane ipsAreaBackground_light ipsColumn ipsColumn_medium'>
|
||||
<aside class='ipsComment_author cAuthorPane ipsColumn ipsColumn_medium'>
|
||||
<h3 class='ipsType_sectionHead cAuthorPane_author ipsType_blendLinks ipsType_break' itemprop="creator" itemscope itemtype="http://schema.org/Person"><strong itemprop="name">{$comment->author()->link( $comment->warningRef() )|raw}</strong> <span class='ipsResponsive_showPhone ipsResponsive_inline'> {template="reputationBadge" group="global" app="core" params="$comment->author()"}</span></h3>
|
||||
<ul class='cAuthorPane_info ipsList_reset'>
|
||||
{{if $comment->author()->member_title && $comment->author()->member_id}}
|
||||
@@ -1620,7 +1683,7 @@
|
||||
</div>
|
||||
</article>]]></template>
|
||||
<template template_group="topics" template_name="postRating" template_data="$item, $comment, $votes=array()" template_location="front" template_app="forums"><![CDATA[{{$idField = $comment::$databaseColumnId;}}
|
||||
<div class='cRatingColumn {{if $comment->post_bwoptions['best_answer']}}cRatingColumn_on{{else}}ipsAreaBackground_light{{endif}} {{if isset( $votes[ $comment->$idField ] ) && $votes[ $comment->$idField ] === 1}}cRatingColumn_up{{elseif isset( $votes[ $comment->$idField ] ) && $votes[ $comment->$idField ] === -1}}cRatingColumn_down{{endif}} ipsColumn ipsColumn_narrow ipsType_center' data-controller='forums.front.topic.answers'>
|
||||
<div class='cRatingColumn {{if $comment->post_bwoptions['best_answer']}}cRatingColumn_on{{else}}ipsAreaBackground{{endif}} {{if isset( $votes[ $comment->$idField ] ) && $votes[ $comment->$idField ] === 1}}cRatingColumn_up{{elseif isset( $votes[ $comment->$idField ] ) && $votes[ $comment->$idField ] === -1}}cRatingColumn_down{{endif}} ipsColumn ipsColumn_narrow ipsType_center' data-controller='forums.front.topic.answers'>
|
||||
<meta itemprop="upvoteCount" content="{$comment->post_field_int}">
|
||||
|
||||
<ul class='ipsList_reset'>
|
||||
@@ -1721,7 +1784,7 @@
|
||||
<div class='ipsColumn ipsColumn_fluid'>
|
||||
{{endif}}
|
||||
<div class="ipsPageHeader ipsClearfix">
|
||||
{{if !$topic->isArchived()}}
|
||||
{{if !$topic->isArchived() and !$topic->container()->password}}
|
||||
<div class='ipsPos_right ipsResponsive_noFloat ipsResponsive_hidePhone'>
|
||||
{template="follow" app="core" group="global" params="'forums', 'topic', $topic->tid, $topic->followersCount()"}
|
||||
</div>
|
||||
@@ -1730,14 +1793,6 @@
|
||||
{template="userPhoto" group="global" app="core" params="$topic->author(), 'small', $topic->warningRef()"}
|
||||
<div>
|
||||
<h1 class='ipsType_pageTitle'>
|
||||
{{if $topic->prefix()}}
|
||||
{template="prefix" group="global" app="core" params="$topic->prefix( TRUE ), $topic->prefix()"}
|
||||
{{endif}}
|
||||
{{if $topic->isQuestion()}}
|
||||
<span itemprop="name">{wordbreak="$topic->title"}</span>
|
||||
{{else}}
|
||||
{wordbreak="$topic->title"}
|
||||
{{endif}}
|
||||
{{if $topic->mapped('pinned') || $topic->mapped('featured') || $topic->hidden() === -1 || $topic->hidden() === 1}}
|
||||
{{if $topic->hidden() === -1}}
|
||||
<span class="ipsBadge ipsBadge_icon ipsBadge_warning" data-ipsTooltip title='{$topic->hiddenBlurb()}'><i class='fa fa-eye-slash'></i></span>
|
||||
@@ -1750,13 +1805,21 @@
|
||||
{{if $topic->mapped('featured')}}
|
||||
<span class="ipsBadge ipsBadge_icon ipsBadge_positive" data-ipsTooltip title='{lang="featured"}'><i class='fa fa-star'></i></span>
|
||||
{{endif}}
|
||||
{{endif}}
|
||||
{{endif}}
|
||||
|
||||
{{if $topic->prefix()}}
|
||||
{template="prefix" group="global" app="core" params="$topic->prefix( TRUE ), $topic->prefix()"}
|
||||
{{endif}}
|
||||
{{if $topic->isQuestion()}}
|
||||
<span itemprop="name">{wordbreak="$topic->title"}</span>
|
||||
{{else}}
|
||||
{wordbreak="$topic->title"}
|
||||
{{endif}}
|
||||
</h1>
|
||||
<p class='ipsType_reset ipsType_blendLinks'>
|
||||
<p class='ipsType_reset ipsType_blendLinks {{if count( $topic->tags() )}}ipsSpacer_bottom ipsSpacer_half{{endif}}'>
|
||||
<span class='ipsType_normal'>{{if $topic->isQuestion()}}{lang="ask_byline_no_date" htmlsprintf="$topic->author()->link( $topic->warningRef() )"}{{else}}{lang="topic_started_by" htmlsprintf="$topic->author()->link( $topic->warningRef() )"}{{endif}}</span>, <span class='ipsType_light ipsType_noBreak'>{datetime="$topic->start_date"}</span><br>
|
||||
</p>
|
||||
{{if count( $topic->tags() )}}
|
||||
<br>
|
||||
{template="tags" group="global" app="core" params="$topic->tags()"}
|
||||
{{endif}}
|
||||
</div>
|
||||
@@ -1782,7 +1845,7 @@
|
||||
|
||||
<div class='ipsClearfix'>
|
||||
{{if $topic->container()->forum_allow_rating}}
|
||||
<div class='ipsAreaBackground ipsAreaBackground_rounded ipsPad_half ipsPos_left ipsType_light ipsResponsive_hidePhone'>
|
||||
<div class='ipsPad_half ipsPos_left ipsType_light ipsResponsive_hidePhone'>
|
||||
{{if $topic->canRate()}}
|
||||
<p class='ipsType_reset ipsType_center ipsType_small'>
|
||||
{{if $topic->isQuestion()}}{lang="rate_this_question"}{{else}}{lang="rate_this_topic"}{{endif}}
|
||||
@@ -1813,7 +1876,7 @@
|
||||
{{endif}}
|
||||
</li>
|
||||
{{endif}}
|
||||
{{if $topic->canPin() or $topic->canUnpin() or $topic->canFeature() or $topic->canUnfeature() or $topic->canHide() or $topic->canUnhide() or $topic->canMove() or $topic->canLock() or $topic->canUnlock() or $topic->canDelete() or $topic->availableSavedActions()}}
|
||||
{{if $topic->canPin() or $topic->canUnpin() or $topic->canFeature() or $topic->canUnfeature() or $topic->canHide() or $topic->canUnhide() or $topic->canMove() or $topic->canLock() or $topic->canUnlock() or $topic->canDelete() or $topic->availableSavedActions() or $topic->canMerge() or $topic->canUnarchive() or \IPS\Member::loggedIn()->modPermission('can_view_moderation_log')}}
|
||||
<li>
|
||||
<a href='#elTopicActions_menu' id='elTopicActions' class='ipsButton ipsButton_link ipsButton_medium ipsButton_fullWidth' data-ipsMenu>{lang="moderator_actions"} <i class='fa fa-caret-down'></i></a>
|
||||
<ul id='elTopicActions_menu' class='ipsMenu ipsMenu_auto ipsHide'>
|
||||
@@ -1872,10 +1935,12 @@
|
||||
{$poll|raw}
|
||||
<br>
|
||||
{{endif}}
|
||||
<div data-controller='core.front.core.commentFeed,forums.front.topic.view' data-baseURL='{$topic->url()}' {{if $topic->isLastPage() and !$topic->isQuestion()}}data-lastPage{{endif}} data-feedID='topic-{$topic->tid}' class='cTopic ipsClear ipsSpacer_top'>
|
||||
<div data-controller='core.front.core.commentFeed,forums.front.topic.view' {{if settings.auto_polling_enabled}}data-autoPoll{{endif}} data-baseURL='{$topic->url()}' {{if $topic->isLastPage() and !$topic->isQuestion()}}data-lastPage{{endif}} data-feedID='topic-{$topic->tid}' class='cTopic ipsClear ipsSpacer_top'>
|
||||
{{if $topic->isQuestion() && $question}}
|
||||
<h2 class='ipsType_sectionTitle ipsType_reset'>{lang="question_title"}</h2>
|
||||
{template="postContainer" group="topics" app="forums" params="$topic, $question, $votes, 'cPostQuestion'"}
|
||||
<div class='ipsAreaBackground_light ipsPad'>
|
||||
{template="postContainer" group="topics" app="forums" params="$topic, $question, $votes, 'cPostQuestion'"}
|
||||
</div>
|
||||
|
||||
<div class='ipsBox ipsSpacer_top'>
|
||||
<h2 class='ipsType_sectionTitle ipsType_reset ipsType_medium'><meta itemprop="answerCount" content="{expression="$topic->posts - 1"}">{lang="answer_count" pluralize="( $topic->posts ) ? $topic->posts - 1 : 0"}</h2>
|
||||
@@ -1901,7 +1966,7 @@
|
||||
{{endif}}
|
||||
{{endif}}
|
||||
|
||||
<div data-role='commentFeed' data-controller='core.front.core.moderation'>
|
||||
<div data-role='commentFeed' data-controller='core.front.core.moderation' class='ipsAreaBackground_light ipsPad'>
|
||||
<form action="{$topic->url()->csrf()->setQueryString( 'do', 'multimodComment' )}" method="post" data-ipsPageAction data-role='moderationTools'>
|
||||
{{$postCount=0; $timeLastRead = $topic->timeLastRead(); $lined = FALSE;}}
|
||||
{{if count( $comments )}}
|
||||
@@ -1957,7 +2022,7 @@
|
||||
</div>
|
||||
{{endif}}
|
||||
|
||||
{{if !$topic->isArchived()}}
|
||||
{{if !$topic->isArchived() and !$topic->container()->password}}
|
||||
<div class='ipsResponsive_noFloat ipsResponsive_showPhone ipsResponsive_block ipsSpacer_top'>
|
||||
{template="follow" app="core" group="global" params="'forums', 'topic', $topic->tid, $topic->followersCount()"}
|
||||
</div>
|
||||
@@ -1968,6 +2033,62 @@
|
||||
</div>
|
||||
{{endif}}
|
||||
|
||||
{{if $topic->canPin() or $topic->canUnpin() or $topic->canFeature() or $topic->canUnfeature() or $topic->canHide() or $topic->canUnhide() or $topic->canMove() or $topic->canLock() or $topic->canUnlock() or $topic->canDelete() or $topic->availableSavedActions()}}
|
||||
<ul class="ipsToolList ipsToolList_horizontal ipsClearfix ipsSpacer_top ipsResponsive_hidePhone">
|
||||
<li>
|
||||
<a href='#elTopicActions_menu' id='elTopicActions' class='ipsButton ipsButton_link ipsButton_medium ipsButton_fullWidth' data-ipsMenu>{lang="moderator_actions"} <i class='fa fa-caret-down'></i></a>
|
||||
<ul id='elTopicActions_menu' class='ipsMenu ipsMenu_auto ipsHide'>
|
||||
{{if $topic->canFeature()}}
|
||||
<li class='ipsMenu_item'><a href='{$topic->url()->csrf()->setQueryString( array( 'do' => 'moderate', 'action' => 'feature' ) )}'>{lang="feature"}</a></li>
|
||||
{{endif}}
|
||||
{{if $topic->canUnfeature()}}
|
||||
<li class='ipsMenu_item'><a href='{$topic->url()->csrf()->setQueryString( array( 'do' => 'moderate', 'action' => 'unfeature' ) )}' >{lang="unfeature"}</a></li>
|
||||
{{endif}}
|
||||
{{if $topic->canPin()}}
|
||||
<li class='ipsMenu_item'><a href='{$topic->url()->csrf()->setQueryString( array( 'do' => 'moderate', 'action' => 'pin' ) )}' >{lang="pin"}</a></li>
|
||||
{{endif}}
|
||||
{{if $topic->canUnpin()}}
|
||||
<li class='ipsMenu_item'><a href='{$topic->url()->csrf()->setQueryString( array( 'do' => 'moderate', 'action' => 'unpin' ) )}' >{lang="unpin"}</a></li>
|
||||
{{endif}}
|
||||
{{if $topic->canHide()}}
|
||||
<li class='ipsMenu_item'><a href='{$topic->url()->csrf()->setQueryString( array( 'do' => 'moderate', 'action' => 'hide' ) )}' data-ipsDialog data-ipsDialog-title="{lang="hide"}">{lang="hide"}</a></li>
|
||||
{{endif}}
|
||||
{{if $topic->canUnhide()}}
|
||||
<li class='ipsMenu_item'><a href='{$topic->url()->csrf()->setQueryString( array( 'do' => 'moderate', 'action' => 'unhide' ) )}' >{{if $topic->hidden() === 1}}{lang="approve"}{{else}}{lang="unhide"}{{endif}}</a></li>
|
||||
{{endif}}
|
||||
{{if $topic->canLock()}}
|
||||
<li class='ipsMenu_item'><a href='{$topic->url()->csrf()->setQueryString( array( 'do' => 'moderate', 'action' => 'lock' ) )}' >{lang="lock"}</a></li>
|
||||
{{endif}}
|
||||
{{if $topic->canUnlock()}}
|
||||
<li class='ipsMenu_item'><a href='{$topic->url()->csrf()->setQueryString( array( 'do' => 'moderate', 'action' => 'unlock' ) )}' >{lang="unlock"}</a></li>
|
||||
{{endif}}
|
||||
{{if $topic->canMove()}}
|
||||
<li class='ipsMenu_item'><a href='{$topic->url()->csrf()->setQueryString( array( 'do' => 'move' ) )}' data-ipsDialog data-ipsDialog-size='narrow' data-ipsDialog-title="{lang="move"}" >{lang="move"}</a></li>
|
||||
{{endif}}
|
||||
{{if $topic->canMerge()}}
|
||||
<li class='ipsMenu_item'><a href='{$topic->url()->csrf()->setQueryString( array( 'do' => 'merge' ) )}' data-ipsDialog data-ipsDialog-size='narrow' data-ipsDialog-title="{lang="merge"}" >{lang="merge"}</a></li>
|
||||
{{endif}}
|
||||
{{if $topic->canUnarchive()}}
|
||||
<li class='ipsMenu_item'><a href='{$topic->url()->csrf()->setQueryString( array( 'do' => 'unarchive' ) )}' data-confirm data-confirmSubMessage="{$topic->unarchiveBlurb()}" >{lang="unarchive"}</a></li>
|
||||
{{endif}}
|
||||
{{if $topic->canDelete()}}
|
||||
<li class='ipsMenu_item'><a href='{$topic->url()->csrf()->setQueryString( array( 'do' => 'moderate', 'action' => 'delete' ) )}' data-confirm >{lang="delete"}</a></li>
|
||||
{{endif}}
|
||||
{{if !$topic->isArchived() and $topic->availableSavedActions()}}
|
||||
<li class='ipsMenu_sep'><hr></li>
|
||||
{{foreach $topic->availableSavedActions() as $action}}
|
||||
<li class="ipsMenu_item"><a href='{$topic->url()->csrf()->setQueryString( array( 'do' => 'savedAction', 'action' => $action->_id ) )}' data-confirm>{$action->_title}</a></li>
|
||||
{{endforeach}}
|
||||
{{endif}}
|
||||
{{if \IPS\Member::loggedIn()->modPermission('can_view_moderation_log')}}
|
||||
<li class='ipsMenu_sep'><hr></li>
|
||||
<li class="ipsMenu_item"><a href='{$topic->url()->csrf()->setQueryString( array( 'do' => 'modLog' ) )}' data-ipsDialog data-ipsDialog-title='{lang="moderation_history"}'>{lang="moderation_history"}</a></li>
|
||||
{{endif}}
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
{{endif}}
|
||||
|
||||
<div class='ipsGrid ipsGrid_collapsePhone ipsPager ipsClearfix ipsSpacer_top'>
|
||||
<div class="ipsGrid_span6 ipsType_left ipsPager_prev">
|
||||
<a href="{$topic->container()->url()}" title="{lang="go_to_forum" sprintf="$topic->container()->_title"}" rel="up">
|
||||
@@ -2038,7 +2159,7 @@
|
||||
</div>
|
||||
<div class='ipsDataItem_main'>
|
||||
<div class="ipsCommentCount ipsPos_right {{if ( $topic->posts - 1 ) === 0}}ipsFaded{{endif}}" data-ipsTooltip title='{lang="replies_number" pluralize="$topic->posts - 1"}'>{expression="$topic->posts - 1"}</div>
|
||||
<a href="{$topic->url()->setQueryString( 'do', 'getLastComment' )}" title='{lang="view_this_topic" sprintf="$topic->title"}' class='ipsDataItem_title ipsType_break'>{wordbreak="$topic->title"}</a>
|
||||
<a href="{$topic->url()->setQueryString( 'do', 'getNewComment' )}" title='{lang="view_this_topic" sprintf="$topic->title"}' class='ipsDataItem_title ipsType_break'>{wordbreak="$topic->title"}</a>
|
||||
{{if $topic->mapped('featured') || $topic->hidden() === -1 || $topic->hidden() === 1}}
|
||||
<span>
|
||||
{{if $topic->hidden() === -1}}
|
||||
@@ -2067,6 +2188,92 @@
|
||||
</ul>
|
||||
</div>
|
||||
{{endif}}
|
||||
{{endif}}]]></template>
|
||||
<template template_group="widgets" template_name="poll" template_data="$topic, $poll, $orientation='vertical'" template_location="front" template_app="forums">{$poll|raw}
|
||||
</template>
|
||||
<template template_group="widgets" template_name="pollFormWidget" template_data="$url, $id, $action, $elements, $hiddenValues, $actionButtons, $uploadField, $class='', $attributes=array(), $sidebar, $form=NULL" template_location="front" template_app="forums"><![CDATA[<form accept-charset='utf-8' class="ipsForm {$class}" action="{$url->setQueryString( 'do', 'widgetPoll' )}" method="post" {{if $uploadField}}enctype="multipart/form-data"{{endif}} {{foreach $attributes as $k => $v}}{$k}="{$v}"{{endforeach}} data-ipsForm>
|
||||
<input type="hidden" name="{$id}_submitted" value="1">
|
||||
{{foreach $hiddenValues as $k => $v}}
|
||||
<input type="hidden" name="{$k}" value="{$v}">
|
||||
{{endforeach}}
|
||||
{{foreach $elements as $collection}}
|
||||
<ol class='ipsList_reset cPollList cPollList_questions'>
|
||||
{{foreach $collection as $idx => $input}}
|
||||
<li class='ipsFieldRow ipsFieldRow_noLabel'>
|
||||
<h4 class='ipsType_normal ipsType_reset'>{$idx}. {wordbreak="$input->label"}</h4>
|
||||
{{if !$input->options['multiple']}}
|
||||
{template="radio" app="core" location="global" group="forms" params="$input->name, $input->value, $input->required, $input->options['options'], $input->options['disabled'], '', $input->options['disabled']"}
|
||||
{{else}}
|
||||
{template="checkboxset" app="core" location="global" group="forms" params="$input->name, $input->value, $input->required, $input->options['options'], $input->options['disabled'], $input->options['toggles'], isset( $input->options['descriptions'] ) ? $input->options['descriptions'] : NULL, $input->options['userSuppliedInput']"}
|
||||
{{endif}}
|
||||
{{if $input->error}}
|
||||
<br>
|
||||
<span class="ipsType_warning">{lang="$input->error"}</span>
|
||||
{{endif}}
|
||||
</li>
|
||||
{{endforeach}}
|
||||
</ol>
|
||||
<br>
|
||||
<a class='ipsType_light ipsType_break' href="{$url}">{lang="poll_view_topic"}</a>
|
||||
<br>
|
||||
{{endforeach}}
|
||||
<hr class='ipsHr'>
|
||||
<ul class="ipsPos_left ipsToolList ipsToolList_horizontal ipsList_reset ipsClearfix">
|
||||
{{foreach $actionButtons as $button}}
|
||||
<li>{$button|raw}</li>
|
||||
{{endforeach}}
|
||||
<li><a class='ipsButton ipsButton_link' title='{lang="show_results_title"}' href="{$url->setQueryString( '_poll', 'results' )}" {{if !settings.allow_result_view}}data-viewResults-confirm="{lang="warn_allow_result_view"}"{{endif}} data-action='viewResults'>{lang="show_results"}</a></li>
|
||||
</ul>
|
||||
</form>]]></template>
|
||||
<template template_group="widgets" template_name="pollWidget" template_data="$poll, $url" template_location="front" template_app="forums"><![CDATA[{{if !isset( \IPS\Request::i()->fetchPoll )}}
|
||||
<section class='ipsBox' data-controller='core.front.core.poll'>
|
||||
{{endif}}
|
||||
{{if $poll->canVote() and request._poll != 'results' and ( !$poll->getVote() or request._poll == 'form') and $pollForm = $poll->buildForm()}}
|
||||
<h3 class='ipsWidget_title ipsType_reset'>
|
||||
{wordbreak="$poll->poll_question"}
|
||||
<span class='ipsType_small ipsType_light'>{lang="poll_num_votes" pluralize="$poll->votes"}</span>
|
||||
</h2>
|
||||
<div class='ipsPad_half ipsWidget_inner ipsClearfix' data-role='pollContents'>
|
||||
{$pollForm->customTemplate( array( \IPS\Theme::i()->getTemplate( 'widgets', 'forums', 'front' ), 'pollFormWidget' ), $url )|raw}
|
||||
</div>
|
||||
{{elseif !$poll->canVote() or $poll->getVote() or ( request._poll == 'results' and settings.allow_result_view )}}
|
||||
<h3 class='ipsWidget_title ipsType_reset'>
|
||||
{wordbreak="$poll->poll_question"}
|
||||
<span class='ipsType_small ipsType_light'>{lang="poll_num_votes" pluralize="$poll->votes"}</span>
|
||||
</h3>
|
||||
<div class='ipsPad_half ipsWidget_inner ipsClearfix' data-role='pollContents'>
|
||||
<ol class='ipsList_reset cPollList'>
|
||||
{{foreach $poll->choices as $questionId => $question}}
|
||||
<li>
|
||||
<h3 class='ipsType_normal ipsType_reset'>{$questionId}. {wordbreak="$question['question']"}</h3>
|
||||
<br>
|
||||
<ul class='ipsList_reset cPollList_choices'>
|
||||
{{foreach $question['choice'] as $k => $choice}}
|
||||
<li class='ipsGrid ipsGrid_collapsePhone'>
|
||||
<div class='ipsGrid_span4 ipsType_right ipsType_richText ipsType_small ipsType_break'>
|
||||
{$choice|raw}
|
||||
</div>
|
||||
<div class='ipsGrid_span7'>
|
||||
<span class='cPollVoteBar'>
|
||||
<span style='width: {{if $poll->votes}}{expression="intval( ( $question['votes'][ $k ] / $poll->votes ) * 100 )"}{{else}}0{{endif}}%' data-votes='{{if $poll->votes}}{expression="round( ( $question['votes'][ $k ] / $poll->votes ) * 100, 2 )"}{{else}}0{{endif}}%' {{if $poll->votes && intval( ( $question['votes'][ $k ] / $poll->votes ) * 100 ) > 30}}class='cPollVoteBar_inside'{{endif}}></span>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
{{endforeach}}
|
||||
</ul>
|
||||
</li>
|
||||
{{endforeach}}
|
||||
</ol>
|
||||
{{if $poll->canVote() || !member.member_id}}
|
||||
<hr class='ipsHr'>
|
||||
{{if $poll->canVote()}}<a href="{$url->setQueryString( '_poll', 'form' )}" title='{lang="show_vote_options"}' class='ipsButton ipsButton_verySmall ipsButton_light' data-action='viewResults'><i class='fa fa-caret-left'></i> {lang="show_vote_options"}</a>{{endif}}
|
||||
{{if !member.member_id}}{lang="poll_guest" htmlsprintf="\IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login' ), \IPS\Http\Url::internal( 'app=core&module=system&controller=register', 'front', 'register' )"}{{endif}}
|
||||
{{endif}}
|
||||
<a class='ipsPos_right ipsType_light ipsType_small ipsType_break' href="{$url}">{lang="poll_view_topic"}</a>
|
||||
</div>
|
||||
{{endif}}
|
||||
{{if !isset( \IPS\Request::i()->fetchPoll )}}
|
||||
</section>
|
||||
{{endif}}]]></template>
|
||||
<template template_group="widgets" template_name="postFeed" template_data="$comments, $title, $orientation='vertical'" template_location="front" template_app="forums"><![CDATA[{{if !empty( $comments ) }}
|
||||
<h3 class='ipsType_reset ipsWidget_title'>{$title}</h3>
|
||||
@@ -2079,9 +2286,9 @@
|
||||
{template="userPhoto" group="global" app="core" params="$comment->author(), 'tiny'"}
|
||||
</div>
|
||||
<div class='ipsDataItem_main'>
|
||||
<a href="{$comment->url()}" title='{lang="view_this_topic" sprintf="$comment->item()->title"}' class='ipsDataItem_title ipsType_break'>{wordbreak="$comment->item()->title"}</a><br>
|
||||
<span class='ipsType_light ipsType_small'>{lang="byline_nodate" htmlsprintf="$comment->author()->link()"} · {$comment->dateLine()|raw}</span>
|
||||
<div class='ipsType_small ipsType_textBlock ipsType_richText ipsType_break' data-ipsTruncate data-ipsTruncate-type='remove' data-ipsTruncate-size='{{if $orientation == 'vertical'}}6 lines{{else}}2 lines{{endif}}'>
|
||||
<a href="{$comment->url()}" title='{lang="view_this_topic" sprintf="$comment->item()->title"}' class='ipsType_medium ipsType_break'>{wordbreak="$comment->item()->title"}</a><br>
|
||||
<p class='ipsType_reset ipsType_light ipsType_medium ipsType_blendLinks'>{lang="byline_nodate" htmlsprintf="$comment->author()->link()"} · <a href='{$comment->item()->url()->setQueryString( array( 'do' => 'findComment', 'comment' => $comment->id ) )}' class='ipsType_blendLinks' title='{lang="share_this_comment"}'>{$comment->dateLine()|raw}</a></p>
|
||||
<div class='ipsType_medium ipsType_textBlock ipsType_richText ipsType_break ipsContained ipsSpacer_top ipsSpacer_half' data-ipsTruncate data-ipsTruncate-type='remove' data-ipsTruncate-size='{{if $orientation == 'vertical'}}6 lines{{else}}2 lines{{endif}}'>
|
||||
{$comment->truncated( true )|raw}
|
||||
</div>
|
||||
</div>
|
||||
@@ -2093,55 +2300,54 @@
|
||||
<div class='ipsWidget_inner'>
|
||||
<ul class='ipsDataList'>
|
||||
{{foreach $comments as $comment}}
|
||||
<div class='ipsComment_header ipsPhotoPanel ipsPhotoPanel_mini'>
|
||||
{template="userPhoto" app="core" group="global" params="$comment->author(), 'mini', $comment->warningRef()"}
|
||||
<div>
|
||||
<p class='ipsPos_right ipsType_reset ipsType_blendLinks'>
|
||||
<a href='{$comment->item()->url()->setQueryString( array( 'do' => 'findComment', 'comment' => $comment->id ) )}' data-ipsTooltip title='{lang="share_this_comment"}' data-ipsMenu data-ipsMenu-closeOnClick='false' id='elShareComment_{$comment->id}'><i class='fa fa-share-alt'></i></a>
|
||||
</p>
|
||||
<h3 class='ipsComment_author ipsType_blendLinks'>
|
||||
<strong class='ipsType_normal'>{template="userLink" app="core" group="global" params="$comment->author(), $comment->warningRef()"}</strong>
|
||||
{template="reputationBadge" group="global" app="core" params="$comment->author()"}
|
||||
</h3>
|
||||
<p class='ipsComment_meta ipsType_light ipsType_medium'>
|
||||
{$comment->dateLine()|raw}
|
||||
{{if $comment->editLine()}}
|
||||
({lang="edited_lc"})
|
||||
{{endif}}
|
||||
{{if $comment->hidden()}}
|
||||
· {$comment->hiddenBlurb()}
|
||||
{{endif}}
|
||||
{{if $comment instanceof \IPS\Content\ReportCenter and !\IPS\Member::loggedIn()->group['gbw_no_report'] and $comment->hidden() !== 1 }}
|
||||
· <a href='{$comment->url('report')}' data-ipsDialog data-ipsDialog-remoteSubmit data-ipsDialog-size='medium' data-ipsDialog-flashMessage='{lang="report_submit_success"}' data-ipsDialog-title="{lang="report"}" data-action='reportComment' title='{lang="report_content"}'>{lang="report"}</a>
|
||||
{{endif}}
|
||||
</p>
|
||||
|
||||
{{if member.modPermission('mod_see_warn') and $comment->warning}}
|
||||
{template="commentWarned" group="global" app="core" params="$comment"}
|
||||
{{endif}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='ipsPad'>
|
||||
{{if in_array( 'IPS\Content\Reputation', class_implements( $comment ) ) and settings.reputation_highlight and $comment->reputation() >= settings.reputation_highlight}}
|
||||
<strong class='ipsComment_popularFlag' data-ipsTooltip title='{lang="this_is_a_popular_comment"}'><i class='fa fa-star'></i></strong>
|
||||
{{endif}}
|
||||
<a href="{$comment->url()}" title='{lang="view_this_topic" sprintf="$comment->item()->title"}' class='ipsDataItem_title ipsType_break'>{wordbreak="$comment->item()->title"}</a><br>
|
||||
<div data-role='commentContent' class='ipsType_normal ipsType_richText ipsType_break ipsContained' data-controller='core.front.core.lightboxedImages'>
|
||||
{{if $comment->hidden() === 1 && $comment->author()->member_id == \IPS\Member::loggedIn()->member_id}}
|
||||
<strong class='ipsType_medium ipsType_warning'><i class='fa fa-info-circle'></i> {lang="comment_awaiting_approval"}</strong>
|
||||
{{endif}}
|
||||
{$comment->content()|raw}
|
||||
|
||||
{{if $comment->editLine()}}
|
||||
{$comment->editLine()|raw}
|
||||
{{endif}}
|
||||
</div>
|
||||
<li class='ipsDataItem ipsClearfix'>
|
||||
<div class='ipsComment_header ipsPhotoPanel ipsPhotoPanel_mini'>
|
||||
{template="userPhoto" app="core" group="global" params="$comment->author(), 'mini', $comment->warningRef()"}
|
||||
<div>
|
||||
<p class='ipsPos_right ipsType_reset ipsType_blendLinks'>
|
||||
<a href='{$comment->item()->url()->setQueryString( array( 'do' => 'findComment', 'comment' => $comment->id ) )}' data-ipsTooltip title='{lang="share_this_comment"}' data-ipsMenu data-ipsMenu-closeOnClick='false' id='elShareComment_{$comment->id}' data-role='shareComment'><i class='fa fa-share-alt'></i></a>
|
||||
</p>
|
||||
<h3 class='ipsComment_author ipsType_blendLinks'>
|
||||
<strong class='ipsType_normal'>{template="userLink" app="core" group="global" params="$comment->author(), $comment->warningRef()"}</strong>
|
||||
{template="reputationBadge" group="global" app="core" params="$comment->author()"}
|
||||
</h3>
|
||||
<p class='ipsComment_meta ipsType_light ipsType_medium'>
|
||||
<a href='{$comment->item()->url()->setQueryString( array( 'do' => 'findComment', 'comment' => $comment->id ) )}' class='ipsType_blendLinks' title='{lang="share_this_comment"}'>{$comment->dateLine()|raw}</a>
|
||||
{{if $comment->editLine()}}
|
||||
({lang="edited_lc"})
|
||||
{{endif}}
|
||||
{{if $comment->hidden()}}
|
||||
· {$comment->hiddenBlurb()}
|
||||
{{endif}}
|
||||
{{if $comment instanceof \IPS\Content\ReportCenter and !\IPS\Member::loggedIn()->group['gbw_no_report'] and $comment->hidden() !== 1 }}
|
||||
· <a href='{$comment->url('report')}' data-ipsDialog data-ipsDialog-remoteSubmit data-ipsDialog-size='medium' data-ipsDialog-flashMessage='{lang="report_submit_success"}' data-ipsDialog-title="{lang="report"}" data-action='reportComment' title='{lang="report_content"}'>{lang="report"}</a>
|
||||
{{endif}}
|
||||
</p>
|
||||
|
||||
{{if $comment->hidden() !== 1 && $comment instanceof \IPS\Content\Reputation and settings.reputation_enabled}}
|
||||
{template="reputation" group="global" app="core" params="$comment, 'ipsPos_right ipsResponsive_noFloat'"}
|
||||
{{endif}}
|
||||
</div>
|
||||
{{if member.modPermission('mod_see_warn') and $comment->warning}}
|
||||
{template="commentWarned" group="global" app="core" params="$comment"}
|
||||
{{endif}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='ipsPad ipsClearfix'>
|
||||
<a href="{$comment->url()}" title='{lang="view_this_topic" sprintf="$comment->item()->title"}' class='ipsDataItem_title ipsType_break'>{wordbreak="$comment->item()->title"}</a><br>
|
||||
<div data-role='commentContent' class='ipsType_normal ipsType_richText ipsType_break ipsContained' data-controller='core.front.core.lightboxedImages'>
|
||||
{{if $comment->hidden() === 1 && $comment->author()->member_id == \IPS\Member::loggedIn()->member_id}}
|
||||
<strong class='ipsType_medium ipsType_warning'><i class='fa fa-info-circle'></i> {lang="comment_awaiting_approval"}</strong>
|
||||
{{endif}}
|
||||
{$comment->content()|raw}
|
||||
|
||||
{{if $comment->editLine()}}
|
||||
{$comment->editLine()|raw}
|
||||
{{endif}}
|
||||
</div>
|
||||
|
||||
{{if $comment->hidden() !== 1 && $comment instanceof \IPS\Content\Reputation and settings.reputation_enabled}}
|
||||
{template="reputation" group="global" app="core" params="$comment, 'ipsPos_right ipsResponsive_noFloat'"}
|
||||
{{endif}}
|
||||
</div>
|
||||
</li>
|
||||
{{endforeach}}
|
||||
</ul>
|
||||
</div>
|
||||
@@ -2161,7 +2367,6 @@
|
||||
</div>
|
||||
<div class='ipsDataItem_main'>
|
||||
<div class="ipsCommentCount ipsPos_right {{if ( $topic->posts - 1 ) === 0}}ipsFaded{{endif}}" data-ipsTooltip title='{lang="replies_number" pluralize="$topic->posts - 1"}'>{expression="$topic->posts - 1"}</div>
|
||||
<a href="{$topic->url()->setQueryString( 'do', 'getLastComment' )}" title='{lang="view_this_topic" sprintf="$topic->title"}' class='ipsDataItem_title ipsType_break'>{wordbreak="$topic->title"}</a>
|
||||
{{if $topic->mapped('featured') || $topic->hidden() === -1 || $topic->hidden() === 1}}
|
||||
<span>
|
||||
{{if $topic->hidden() === -1}}
|
||||
@@ -2174,8 +2379,12 @@
|
||||
{{endif}}
|
||||
</span>
|
||||
{{endif}}
|
||||
<a href="{$topic->url()->setQueryString( 'do', 'getNewComment' )}" title='{lang="view_this_topic" sprintf="$topic->title"}' class='ipsDataItem_title ipsType_break'>{wordbreak="$topic->title"}</a>
|
||||
<br>
|
||||
<span class='ipsType_light ipsType_small'>{lang="byline_nodate" htmlsprintf="$topic->author()->link()"} · {lang="topic_started_date" htmlsprintf="\IPS\DateTime::ts( $topic->mapped('date') )->html()"}</span>
|
||||
<p class='ipsType_reset ipsType_medium ipsType_blendLinks'>
|
||||
<span>{lang="byline_nodate" htmlsprintf="$topic->author()->link()"}</span><br>
|
||||
<span class='ipsType_light'>{lang="topic_started_date" htmlsprintf="\IPS\DateTime::ts( $topic->mapped('date') )->html()"}</span>
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
{{endforeach}}
|
||||
@@ -2238,10 +2447,8 @@
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
html[dir="ltr"] .cPost .ipsComment_content {
|
||||
html[dir] .cPost .ipsComment_content {
|
||||
padding-left: 7px;
|
||||
}
|
||||
html[dir="rtl"] .cPost .ipsComment_content {
|
||||
padding-right: 7px;
|
||||
}
|
||||
|
||||
@@ -2363,8 +2570,7 @@
|
||||
border-bottom: 1px solid rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.cForumTopicTable .ipsDataItem_title,
|
||||
#elVNC_main .ipsDataItem_title {
|
||||
.cForumTopicTable .ipsDataItem_title {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
@@ -2415,7 +2621,7 @@ html[dir="rtl"] .cTopicList .ipsDataItem_icon {
|
||||
}
|
||||
|
||||
.cTopicList .ipsDataItem_main {
|
||||
padding: 10px;
|
||||
padding: 12px 10px;
|
||||
}
|
||||
|
||||
.cTopicHovercard .cTopicHovercard_container {
|
||||
@@ -2447,13 +2653,6 @@ html[dir="rtl"] .cTopicList .ipsDataItem_icon {
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
|
||||
html[dir="ltr"] .cRatingColumn {
|
||||
border-right: 1px solid rgba(0,0,0,0.1);
|
||||
}
|
||||
html[dir="rtl"] .cRatingColumn {
|
||||
border-left: 1px solid rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.cRatingColumn_on {
|
||||
background: #e4ecdd;
|
||||
}
|
||||
@@ -2555,11 +2754,11 @@ html[dir="rtl"] .cAnswerRate {
|
||||
}
|
||||
|
||||
.cBestAnswerIndicator_off {
|
||||
background: #e5e5e5;
|
||||
background: #d4d4d4;
|
||||
}
|
||||
|
||||
.cBestAnswerIndicator_off:hover {
|
||||
background: #d4d4d4;
|
||||
background: #c9c9c9;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@@ -2579,8 +2778,8 @@ html[dir="rtl"] .cAnswerRate {
|
||||
background: {theme="moderated"};
|
||||
}
|
||||
|
||||
.cTopic .cPost:nth-of-type(1) {
|
||||
border-top: 0;
|
||||
.cTopic .cPost.ipsComment:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.cPost.cPostQuestion {
|
||||
@@ -2594,6 +2793,13 @@ html[dir="rtl"] .cPost .ipsComment_meta {
|
||||
padding: 15px 0px 10px 10px;
|
||||
}
|
||||
|
||||
html[dir="ltr"] .cPost.ipsComment_popular .ipsComment_meta {
|
||||
padding-right: 60px;
|
||||
}
|
||||
html[dir="rtl"] .cPost.ipsComment_popular .ipsComment_meta {
|
||||
padding-left: 60px;
|
||||
}
|
||||
|
||||
.cPost .ipsComment_controls {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@@ -2635,11 +2841,12 @@ html[dir="rtl"] .cPost .ipsComment_content {
|
||||
display: block;
|
||||
/* http://community.invisionpower.com/4bugtrack/infopane-display-name-split-r1164/ */
|
||||
/*word-break: break-all;*/
|
||||
line-height: 1.1;
|
||||
line-height: 1.2;
|
||||
word-wrap: initial;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
-moz-hyphens: initial;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.cAuthorPane_info .ipsRepBadge {
|
||||
|
||||
@@ -45,5 +45,18 @@
|
||||
"100042": "4.0.12",
|
||||
"100043": "4.0.12.1",
|
||||
"100044": "4.0.13",
|
||||
"100045": "4.0.13.1"
|
||||
"100045": "4.0.13.1",
|
||||
"101000": "4.1.0 Beta 1",
|
||||
"101001": "4.1.0 Beta 2",
|
||||
"101002": "4.1.0 Beta 3",
|
||||
"101003": "4.1.0 Beta 4",
|
||||
"101004": "4.1.0 Beta 5",
|
||||
"101005": "4.1.0 Beta 6",
|
||||
"101006": "4.1.0 Beta 7",
|
||||
"101007": "4.1.0 Beta 8",
|
||||
"101008": "4.1.0 Beta 9",
|
||||
"101009": "4.1.0 Beta 10",
|
||||
"101010": "4.1.0",
|
||||
"101011": "4.1.1",
|
||||
"101012": "4.1.2"
|
||||
}
|
||||
@@ -1 +1,45 @@
|
||||
{"forumStatistics":{"class":"\\IPS\\Widget\\PermissionCache","restrict":[],"default_area":"","allow_reuse":false,"menu_style":"menu","embeddable":true},"hotTopics":{"class":"\\IPS\\Widget\\PermissionCache","restrict":[],"default_area":"","allow_reuse":false,"menu_style":"menu","embeddable":true},"topicFeed":{"class":"\\IPS\\Widget\\PermissionCache","restrict":[],"default_area":"","allow_reuse":true,"menu_style":"modal","embeddable":true},"postFeed":{"class":"\\IPS\\Widget\\PermissionCache","restrict":[],"default_area":"","allow_reuse":true,"menu_style":"modal","embeddable":true}}
|
||||
{
|
||||
"forumStatistics": {
|
||||
"class": "\\IPS\\Widget\\PermissionCache",
|
||||
"restrict": [],
|
||||
"default_area": "",
|
||||
"allow_reuse": false,
|
||||
"menu_style": "menu",
|
||||
"embeddable": true
|
||||
},
|
||||
"hotTopics": {
|
||||
"class": "\\IPS\\Widget\\PermissionCache",
|
||||
"restrict": [],
|
||||
"default_area": "",
|
||||
"allow_reuse": false,
|
||||
"menu_style": "menu",
|
||||
"embeddable": true
|
||||
},
|
||||
"topicFeed": {
|
||||
"class": "\\IPS\\Widget\\PermissionCache",
|
||||
"restrict": [],
|
||||
"default_area": "",
|
||||
"allow_reuse": true,
|
||||
"menu_style": "modal",
|
||||
"embeddable": true
|
||||
},
|
||||
"postFeed": {
|
||||
"class": "\\IPS\\Widget\\PermissionCache",
|
||||
"restrict": [],
|
||||
"default_area": "",
|
||||
"allow_reuse": true,
|
||||
"menu_style": "modal",
|
||||
"embeddable": true
|
||||
},
|
||||
"poll": {
|
||||
"class": "\\IPS\\Widget\\PermissionCache",
|
||||
"restrict": [
|
||||
"sidebar",
|
||||
"cms"
|
||||
],
|
||||
"default_area": "",
|
||||
"allow_reuse": true,
|
||||
"menu_style": "modal",
|
||||
"embeddable": true
|
||||
}
|
||||
}
|
||||
@@ -23,9 +23,23 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
* @brief Content Router extension: Topics
|
||||
*/
|
||||
class _Topics
|
||||
{
|
||||
{
|
||||
/**
|
||||
* @brief Content Item Classes
|
||||
*/
|
||||
public $classes = array( 'IPS\forums\Topic' );
|
||||
public $classes = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \IPS\Member|NULL $member If checking access, the member to check for, or NULL to not check access
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( \IPS\Member $member = NULL )
|
||||
{
|
||||
if ( $member === NULL or $member->canAccessModule( \IPS\Application\Module::get( 'forums', 'forums', 'front' ) ) )
|
||||
{
|
||||
$this->classes[] = 'IPS\forums\Topic';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,8 +22,18 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
/**
|
||||
* Front Navigation Extension: Forums
|
||||
*/
|
||||
class _Forums
|
||||
class _Forums extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
{
|
||||
/**
|
||||
* Get Type Title which will display in the AdminCP Menu Manager
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function typeTitle()
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('frontnavigation_forums');
|
||||
}
|
||||
|
||||
/**
|
||||
* Can access?
|
||||
*
|
||||
@@ -31,7 +41,7 @@ class _Forums
|
||||
*/
|
||||
public function canView()
|
||||
{
|
||||
return !\IPS\Application::load('forums')->hide_tab and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'forums', 'forums' ) );
|
||||
return parent::canView() and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'forums', 'forums' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,14 +73,4 @@ class _Forums
|
||||
{
|
||||
return \IPS\Dispatcher::i()->application->directory === 'forums';
|
||||
}
|
||||
|
||||
/**
|
||||
* Children
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function children()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,19 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _DeleteLegacyPosts
|
||||
{
|
||||
/**
|
||||
* Parse data before queuing
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function preQueueData( $data )
|
||||
{
|
||||
$data['count'] = \IPS\Db::i()->select( 'COUNT(*)', 'forums_posts', 'queued > 2' )->first();
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run Background Task
|
||||
*
|
||||
@@ -60,7 +73,6 @@ class _DeleteLegacyPosts
|
||||
*/
|
||||
public function getProgress( $data, $offset )
|
||||
{
|
||||
$count = \IPS\Db::i()->select( 'COUNT(*)', 'forums_posts', 'queued > 2' )->first();
|
||||
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('queue_deleting_legacy_posts'), 'complete' => 100 / ( $count ?: 1 + $offset ) * $offset );
|
||||
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('queue_deleting_legacy_posts'), 'complete' => 100 / ( $data['count'] ?: 1 + $offset ) * $offset );
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,19 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _DeleteLegacyTopics
|
||||
{
|
||||
/**
|
||||
* Parse data before queuing
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function preQueueData( $data )
|
||||
{
|
||||
$data['count'] = \IPS\Db::i()->select( 'COUNT(*)', 'forums_topics', 'approved > 1' )->first();
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run Background Task
|
||||
*
|
||||
@@ -60,7 +73,6 @@ class _DeleteLegacyTopics
|
||||
*/
|
||||
public function getProgress( $data, $offset )
|
||||
{
|
||||
$count = \IPS\Db::i()->select( 'COUNT(*)', 'forums_topics', 'approved > 1' )->first();
|
||||
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('queue_deleting_legacy_topics'), 'complete' => 100 / ( $count ?: 1 + $offset ) * $offset );
|
||||
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('queue_deleting_legacy_topics'), 'complete' => 100 / ( $data['count'] ?: 1 + $offset ) * $offset );
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,7 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
/* Password protected */
|
||||
if ( $form = $forum->passwordForm() )
|
||||
{
|
||||
\IPS\Output::i()->title = $forum->_title;
|
||||
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forums', 'forums', 'front' ), 'forumPasswordPopup' ) );
|
||||
return;
|
||||
}
|
||||
@@ -76,7 +77,7 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Init table (it won't show anything until after the password check, but it sets navigation and titles) */
|
||||
$table = new \IPS\Helpers\Table\Content( 'IPS\forums\Topic', $forum->url(), $where, $forum, NULL, NULL );
|
||||
$table = new \IPS\Helpers\Table\Content( 'IPS\forums\Topic', $forum->url(), $where, $forum, NULL, NULL, isset( \IPS\Request::i()->rss ) ? FALSE : TRUE );
|
||||
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'forums', 'forums', 'front' ), 'forumTable' );
|
||||
$table->classes = array( 'cTopicList' );
|
||||
$table->title = \IPS\Member::loggedIn()->language()->addToStack( ( $forum->forums_bitoptions['bw_enable_answers'] ) ? 'count_questions_in_forum' : 'count_topics_in_forum', FALSE, array( 'pluralize' => array( $forum->topics ) ) );
|
||||
@@ -310,6 +311,7 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
/* Or actually show RSS feed */
|
||||
if ( isset( \IPS\Request::i()->rss ) )
|
||||
{
|
||||
/* Set the title, either topics or questions */
|
||||
if ( $forum->forums_bitoptions['bw_enable_answers'] )
|
||||
{
|
||||
$rssTitle = sprintf( \IPS\Member::loggedIn()->language()->get( 'forum_rss_title_questions'), \IPS\Member::loggedIn()->language()->get( "forums_forum_{$forum->id}" ) );
|
||||
@@ -318,21 +320,24 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$rssTitle = sprintf( \IPS\Member::loggedIn()->language()->get( 'forum_rss_title_topics'), \IPS\Member::loggedIn()->language()->get( "forums_forum_{$forum->id}" ) );
|
||||
}
|
||||
|
||||
$document = \IPS\Xml\Rss::newDocument( $forum->url(), $rssTitle, $rssTitle );
|
||||
|
||||
/* We can't include "moved" links in the RSS feed, as there is no content to include ( $topic->content() results in BadMethodCallException) */
|
||||
/* Don't include "moved" links in the RSS feed, as there is no content to include ( $topic->content() results in BadMethodCallException) */
|
||||
$table->where[] = array( 'forums_topics.moved_to IS NULL' );
|
||||
|
||||
/* Can we view the content (permission_showtopic may allow us to view the list, but not the content)? */
|
||||
$canViewContent = $forum->can('read');
|
||||
|
||||
/* Build the document */
|
||||
$document = \IPS\Xml\Rss::newDocument( $forum->url(), $rssTitle, $rssTitle );
|
||||
foreach ( $table->getRows( array() ) as $topic )
|
||||
{
|
||||
if ( ! $topic->hidden() )
|
||||
if ( !$topic->hidden() )
|
||||
{
|
||||
$document->addItem( $topic->title, $topic->url(), $topic->content(), \IPS\DateTime::ts( $topic->last_post ), $topic->tid );
|
||||
$document->addItem( $topic->title, $topic->url(), $canViewContent ? $topic->content() : NULL, \IPS\DateTime::ts( $topic->start_date ), $topic->tid );
|
||||
}
|
||||
}
|
||||
|
||||
/* @note application/rss+xml is not a registered IANA mime-type so we need to stick with text/xml for RSS */
|
||||
/* Display - note application/rss+xml is not a registered IANA mime-type so we need to stick with text/xml for RSS */
|
||||
\IPS\Output::i()->sendOutput( $document->asXML(), 200, 'text/xml' );
|
||||
}
|
||||
}
|
||||
@@ -423,7 +428,7 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
$hasModOptions = TRUE;
|
||||
}
|
||||
|
||||
$formTemplate = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'submit', 'forums' ) ), 'createTopicForm' ), $forum, $hasModOptions );
|
||||
$formTemplate = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'submit', 'forums' ) ), 'createTopicForm' ), $forum, $hasModOptions, NULL );
|
||||
|
||||
if ( \IPS\forums\Topic::moderateNewItems( \IPS\Member::loggedIn() ) )
|
||||
{
|
||||
|
||||
@@ -162,6 +162,12 @@ class _topic extends \IPS\Content\Controller
|
||||
if ( $topic->isQuestion() )
|
||||
{
|
||||
$question = $topic->comments( 1, 0 );
|
||||
try
|
||||
{
|
||||
$question->warning = \IPS\core\Warnings\Warning::constructFromData( \IPS\Db::i()->select( '*', 'core_members_warn_logs', array( array( 'wl_content_app=? AND wl_content_module=? AND wl_content_id1=? AND wl_content_id2=?', 'forums', 'forums-comment', $question->topic_id, $question->pid ) ) )->first() );
|
||||
}
|
||||
catch ( \UnderflowException $e ) { }
|
||||
|
||||
$page = ( isset( \IPS\Request::i()->page ) ) ? intval( \IPS\Request::i()->page ) : 1;
|
||||
|
||||
if( $page < 1 )
|
||||
@@ -313,18 +319,23 @@ class _topic extends \IPS\Content\Controller
|
||||
\IPS\Member::loggedIn()->language()->words['topic_mainTab'] = \IPS\Member::loggedIn()->language()->addToStack( 'question_mainTab', FALSE );
|
||||
}
|
||||
|
||||
if ( !$topic->canEdit() )
|
||||
if ( !$topic->canEdit() and !\IPS\Request::i()->form_submitted ) // We check if the form has been submitted to prevent the user loosing their content
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_noperm_edit', '2F173/E', 403, '' );
|
||||
\IPS\Output::i()->error( 'edit_no_perm_err', '2F173/E', 403, '' );
|
||||
}
|
||||
|
||||
$formElements = $class::formElements( $topic, $forum );
|
||||
|
||||
$hasModOptions = FALSE;
|
||||
|
||||
if ( $class::modPermission( 'lock', NULL, $forum ) )
|
||||
|
||||
/* We used to just check against the ability to lock, however this may not be enough - a moderator could pin, for example, but not lock */
|
||||
foreach( array( 'lock', 'pin', 'hide', 'feature' ) AS $perm )
|
||||
{
|
||||
$hasModOptions = TRUE;
|
||||
if ( $class::modPermission( $perm, NULL, $forum ) )
|
||||
{
|
||||
$hasModOptions = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form( 'form', \IPS\Member::loggedIn()->language()->checkKeyExists( $class::$formLangPrefix . '_save' ) ? $class::$formLangPrefix . '_save' : 'save' );
|
||||
@@ -347,14 +358,21 @@ class _topic extends \IPS\Content\Controller
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$topic->processForm( $values );
|
||||
$topic->save();
|
||||
$topic->processAfterEdit( $values );
|
||||
|
||||
\IPS\Output::i()->redirect( $topic->url() );
|
||||
if ( $topic->canEdit() )
|
||||
{
|
||||
$topic->processForm( $values );
|
||||
$topic->save();
|
||||
$topic->processAfterEdit( $values );
|
||||
|
||||
\IPS\Output::i()->redirect( $topic->url() );
|
||||
}
|
||||
else
|
||||
{
|
||||
$form->error = \IPS\Member::loggedIn()->language()->addToStack('edit_no_perm_err');
|
||||
}
|
||||
}
|
||||
|
||||
$formTemplate = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'submit', 'forums' ) ), 'createTopicForm' ), $forum, $hasModOptions );
|
||||
$formTemplate = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'submit', 'forums' ) ), 'createTopicForm' ), $forum, $hasModOptions, $topic );
|
||||
|
||||
$title = $forum->forums_bitoptions['bw_enable_answers'] ? 'edit_question' : 'edit_topic';
|
||||
|
||||
@@ -401,6 +419,9 @@ class _topic extends \IPS\Content\Controller
|
||||
|
||||
$topic->topic_archive_status = \IPS\forums\Topic::ARCHIVE_RESTORE;
|
||||
$topic->save();
|
||||
|
||||
/* Log */
|
||||
\IPS\Session::i()->modLog( 'modlog__unarchived_topic', array( $topic->url()->__toString() => FALSE, $topic->mapped( 'title' ) => FALSE ), $topic );
|
||||
|
||||
\IPS\Output::i()->redirect( $topic->url() );
|
||||
}
|
||||
@@ -412,8 +433,10 @@ class _topic extends \IPS\Content\Controller
|
||||
*/
|
||||
public function rateQuestion()
|
||||
{
|
||||
/* CSRF Check */
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
/* Get the question */
|
||||
try
|
||||
{
|
||||
$question = \IPS\forums\Topic::loadAndCheckPerms( \IPS\Request::i()->id );
|
||||
@@ -423,28 +446,41 @@ class _topic extends \IPS\Content\Controller
|
||||
\IPS\Output::i()->error( 'node_error', '2F173/8', 404, '' );
|
||||
}
|
||||
|
||||
if ( !$question->canVote() )
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_module_permission', '2F173/9', 403, '' );
|
||||
}
|
||||
|
||||
/* Voting up or down? */
|
||||
$rating = intval( \IPS\Request::i()->rating );
|
||||
if ( $rating !== 1 and $rating !== -1 )
|
||||
{
|
||||
\IPS\Output::i()->error( 'form_bad_value', '2F173/A', 403, '' );
|
||||
}
|
||||
|
||||
\IPS\Db::i()->insert( 'forums_question_ratings', array(
|
||||
'topic' => $question->tid,
|
||||
'forum' => $question->forum_id,
|
||||
'member' => \IPS\Member::loggedIn()->member_id,
|
||||
'rating' => $rating,
|
||||
'date' => time()
|
||||
), TRUE );
|
||||
/* Check we can cast this vote */
|
||||
if ( !$question->canVote( $rating ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_module_permission', '2F173/9', 403, '' );
|
||||
}
|
||||
|
||||
/* If we have an existing vote, we're just undoing that, otherwise, insert the vote */
|
||||
$ratings = $question->votes();
|
||||
if ( isset( $ratings[ \IPS\Member::loggedIn()->member_id ] ) )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'forums_question_ratings', array( 'topic=? AND member=?', $question->tid, \IPS\Member::loggedIn()->member_id ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Db::i()->insert( 'forums_question_ratings', array(
|
||||
'topic' => $question->tid,
|
||||
'forum' => $question->forum_id,
|
||||
'member' => \IPS\Member::loggedIn()->member_id,
|
||||
'rating' => $rating,
|
||||
'date' => time()
|
||||
), TRUE );
|
||||
}
|
||||
|
||||
/* Rebuild count */
|
||||
$question->question_rating = \IPS\Db::i()->select( 'SUM(rating)', 'forums_question_ratings', array( 'topic=?', $question->tid ) )->first();
|
||||
$question->save();
|
||||
|
||||
/* Redirect back */
|
||||
\IPS\Output::i()->redirect( $question->url() );
|
||||
}
|
||||
|
||||
@@ -614,7 +650,6 @@ class _topic extends \IPS\Content\Controller
|
||||
|
||||
/* Log */
|
||||
\IPS\Session::i()->modLog( 'modlog__saved_action', array( 'forums_mmod_' . $action->mm_id => TRUE, $topic->url()->__toString() => FALSE, $topic->mapped( 'title' ) => FALSE ), $topic );
|
||||
|
||||
\IPS\Output::i()->redirect( $topic->url() );
|
||||
}
|
||||
catch ( \LogicException $e )
|
||||
@@ -651,6 +686,29 @@ class _topic extends \IPS\Content\Controller
|
||||
\IPS\Output::i()->error( 'no_module_permission', '2F173/C', 403, 'no_module_permission_guest' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to use the custom widget poll template for ajax methods
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function widgetPoll()
|
||||
{
|
||||
try
|
||||
{
|
||||
$topic = \IPS\forums\Topic::loadAndCheckPerms( \IPS\Request::i()->id );
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2F173/N', 403, '' );
|
||||
}
|
||||
|
||||
$poll = $topic->getPoll();
|
||||
$poll->displayTemplate = array( \IPS\Theme::i()->getTemplate( 'widgets', 'forums', 'front' ), 'pollWidget' );
|
||||
$poll->url = $topic->url();
|
||||
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'widgets', 'forums', 'front' )->poll( $topic, $poll );
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit Comment/Review
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief 4.0.0 Upgrade Code
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 15 Jan 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\forums\setup\upg_101000;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 4.1.0 Beta 1 Upgrade Code
|
||||
*/
|
||||
class _Upgrade
|
||||
{
|
||||
/**
|
||||
* Finish - This is run after all apps have been upgraded
|
||||
*
|
||||
* @return mixed If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
|
||||
* @note We opted not to let users run this immediately during the upgrade because of potential issues (it taking a long time and users stopping it or getting frustrated) but we can revisit later
|
||||
*/
|
||||
public function finish()
|
||||
{
|
||||
\IPS\Task::queue( 'core', 'RebuildItemCounts', array( 'class' => 'IPS\forums\Topic', 'count' => 0 ), 4, array( 'class' ) );
|
||||
\IPS\Task::queue( 'core', 'RebuildContainerCounts', array( 'class' => 'IPS\forums\Forum', 'count' => 0 ), 5, array( 'class' ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"1": {
|
||||
"method": "dropColumn",
|
||||
"params": [
|
||||
"forums_archive_posts",
|
||||
"archive_show_signature"
|
||||
]
|
||||
},
|
||||
"2": {
|
||||
"method": "dropColumn",
|
||||
"params": [
|
||||
"forums_archive_posts",
|
||||
"archive_show_emoticons"
|
||||
]
|
||||
},
|
||||
"3": {
|
||||
"method": "dropColumn",
|
||||
"params": [
|
||||
"forums_posts",
|
||||
"use_sig"
|
||||
]
|
||||
},
|
||||
"4": {
|
||||
"method": "dropColumn",
|
||||
"params": [
|
||||
"forums_posts",
|
||||
"use_emo"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief 4.1.0 Beta 10 Upgrade Code
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 22 Oct 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\forums\setup\upg_101009;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 4.1.0 Beta 10 Upgrade Code
|
||||
*/
|
||||
class _Upgrade
|
||||
{
|
||||
/**
|
||||
* Step 1
|
||||
* Fix the first post flagged for topics
|
||||
*
|
||||
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
|
||||
*/
|
||||
public function step1()
|
||||
{
|
||||
$perCycle = 500;
|
||||
$did = 0;
|
||||
$limit = intval( \IPS\Request::i()->extra );
|
||||
|
||||
/* Try to prevent timeouts to the extent possible */
|
||||
$cutOff = \IPS\core\Setup\Upgrade::determineCutoff();
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'forums_topics', array( 'topic_firstpost=?', 0 ), 'tid ASC', array( $limit, $perCycle ) ) as $topic )
|
||||
{
|
||||
if( $cutOff !== null AND time() >= $cutOff )
|
||||
{
|
||||
return ( $limit + $did );
|
||||
}
|
||||
|
||||
$did++;
|
||||
|
||||
try
|
||||
{
|
||||
$firstPost = \IPS\Db::i()->select( 'pid', 'forums_posts', array( 'topic_id=?', $topic['tid'] ), 'post_date ASC', array( 1 ) )->first();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
\IPS\Db::i()->update( 'forums_topics', array( 'topic_firstpost' => $firstPost ), 'tid=' . $topic['tid'] );
|
||||
}
|
||||
|
||||
if( $did )
|
||||
{
|
||||
return ( $limit + $did );
|
||||
}
|
||||
else
|
||||
{
|
||||
unset( $_SESSION['_step1Count'] );
|
||||
|
||||
$toRun = \IPS\core\Setup\Upgrade::runManualQueries( array(
|
||||
array(
|
||||
'table' => 'forums_posts',
|
||||
'query' => "UPDATE " . \IPS\Db::i()->prefix . "forums_posts SET new_topic=1 WHERE pid IN ( SELECT topic_firstpost FROM " . \IPS\Db::i()->prefix . "forums_topics )"
|
||||
)
|
||||
) );
|
||||
|
||||
if ( count( $toRun ) )
|
||||
{
|
||||
$mr = \IPS\core\Setup\Upgrade::adjustMultipleRedirect( array( 1 => 'forums', 'extra' => array( '_upgradeStep' => 2, '_upgradeData' => 0 ) ) );
|
||||
|
||||
/* Queries to run manually */
|
||||
return array( 'html' => \IPS\Theme::i()->getTemplate( 'forms' )->queries( $toRun, \IPS\Http\Url::internal( 'controller=upgrade' )->setQueryString( array( 'key' => $_SESSION['uniqueKey'], 'mr_continue' => 1, 'mr' => $mr ) ) ) );
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom title for this step
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function step1CustomTitle()
|
||||
{
|
||||
$limit = isset( \IPS\Request::i()->extra ) ? \IPS\Request::i()->extra : 0;
|
||||
|
||||
if( !isset( $_SESSION['_step1Count'] ) )
|
||||
{
|
||||
$_SESSION['_step1Count'] = \IPS\Db::i()->select( 'COUNT(*)', 'forums_topics' )->first();
|
||||
}
|
||||
|
||||
$message = "Fixing flagged first posts (Upgraded so far: " . ( ( $limit > $_SESSION['_step1Count'] ) ? $_SESSION['_step1Count'] : $limit ) . ' out of ' . $_SESSION['_step1Count'] . ')';
|
||||
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief 4.1.2 Upgrade Code
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 29 Oct 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\forums\setup\upg_101012;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 4.1.2 Upgrade Code
|
||||
*/
|
||||
class _Upgrade
|
||||
{
|
||||
/**
|
||||
* Fix container counts that may be off due to bug with adding in archived posts count
|
||||
*
|
||||
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
|
||||
*/
|
||||
public function step1()
|
||||
{
|
||||
\IPS\Task::queue( 'core', 'RebuildContainerCounts', array( 'class' => 'IPS\forums\Forum', 'count' => 0 ), 5, array( 'class' ) );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom title for this step
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function step1CustomTitle()
|
||||
{
|
||||
return "Rebuilding forum post counts";
|
||||
}
|
||||
}
|
||||
@@ -228,6 +228,16 @@ class _Upgrade
|
||||
{
|
||||
\IPS\Db::i()->dropColumn( 'forums_forums', array( 'name', 'description', 'rules_text', 'permission_custom_error', 'rules_title' ) );
|
||||
|
||||
/* @link https://community.invisionpower.com/4bugtrack/active-reports/348-to-40121-column-last_id-cannot-be-null-r7650/ */
|
||||
\IPS\Db::i()->changeColumn( 'forums_forums', 'last_id', array(
|
||||
'name' => 'last_id',
|
||||
'type' => 'int',
|
||||
'length' => 10,
|
||||
'unsigned' => false,
|
||||
'allow_null' => true,
|
||||
'default' => null
|
||||
) );
|
||||
|
||||
unset( $_SESSION['_step3Count'] );
|
||||
return TRUE;
|
||||
}
|
||||
@@ -288,7 +298,7 @@ ADD INDEX last_post (forum_id, pinned, last_real_post, state)
|
||||
|
||||
if ( count( $toRun ) )
|
||||
{
|
||||
$mr = \IPS\core\Setup\Upgrade::adjustMultipleRedirect( array( 1 => 'forums', 'extra' => array( '_upgradeStep' => 2, '_upgradeData' => 0 ) ) );
|
||||
$mr = \IPS\core\Setup\Upgrade::adjustMultipleRedirect( array( 1 => 'forums', 'extra' => array( '_upgradeStep' => 5, '_upgradeData' => 0 ) ) );
|
||||
|
||||
/* Queries to run manually */
|
||||
return array( 'html' => \IPS\Theme::i()->getTemplate( 'forms' )->queries( $toRun, \IPS\Http\Url::internal( 'controller=upgrade' )->setQueryString( array( 'key' => $_SESSION['uniqueKey'], 'mr_continue' => 1, 'mr' => $mr ) ) ) );
|
||||
|
||||
@@ -269,11 +269,6 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
*/
|
||||
public function get__sortBy()
|
||||
{
|
||||
if ( $this->sort_key === 'last_post' )
|
||||
{
|
||||
return 'last_real_post';
|
||||
}
|
||||
|
||||
return $this->sort_key;
|
||||
}
|
||||
|
||||
@@ -352,6 +347,22 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
return $this->last_post ? \IPS\DateTime::ts( $this->last_post ) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the comment/approved/hidden counts
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function resetCommentCounts()
|
||||
{
|
||||
parent::resetCommentCounts();
|
||||
|
||||
/* Archiving? */
|
||||
if ( \IPS\Settings::i()->archive_on )
|
||||
{
|
||||
$this->_comments += \IPS\forums\Topic\ArchivedPost::db()->select( 'COUNT(*)', 'forums_archive_posts', array( 'archive_forum_id=?', $this->id ) )->first();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last post data
|
||||
*
|
||||
@@ -369,7 +380,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
and
|
||||
(
|
||||
!(
|
||||
\IPS\Member::loggedIn()->modPermission( 'forums' ) === 0
|
||||
\IPS\Member::loggedIn()->modPermission( 'forums' ) === -1
|
||||
or
|
||||
(
|
||||
is_array( \IPS\Member::loggedIn()->modPermission( 'forums' ) )
|
||||
@@ -434,8 +445,21 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
|
||||
if( $this->last_post )
|
||||
{
|
||||
if ( $this->last_poster_id )
|
||||
{
|
||||
$lastAuthor = \IPS\Member::load( $this->last_poster_id );
|
||||
}
|
||||
else
|
||||
{
|
||||
$lastAuthor = new \IPS\Member;
|
||||
if ( $this->last_poster_name )
|
||||
{
|
||||
$lastAuthor->name = $this->last_poster_name;
|
||||
}
|
||||
}
|
||||
|
||||
$result = array(
|
||||
'author' => \IPS\Member::load( $this->last_poster_id ),
|
||||
'author' => $lastAuthor,
|
||||
'topic_url' => \IPS\Http\Url::internal( "app=forums&module=forums&controller=topic&id={$this->last_id}", 'front', 'forums_topic', array( $this->seo_last_title ) ),
|
||||
'topic_title' => $this->last_title,
|
||||
'date' => $this->last_post
|
||||
@@ -470,6 +494,21 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
return static::$permissionMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Columns needed to query for search result / stream view
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function basicDataColumns()
|
||||
{
|
||||
$return = parent::basicDataColumns();
|
||||
$return[] = 'forums_bitoptions';
|
||||
$return[] = 'password';
|
||||
$return[] = 'password_override';
|
||||
$return[] = 'min_posts_view';
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the currently logged in member has access to a password protected forum
|
||||
*
|
||||
@@ -704,6 +743,11 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$buttons['permissions']['data'] = NULL;
|
||||
}
|
||||
|
||||
if ( !$this->sub_can_post and isset( $buttons['add'] ) )
|
||||
{
|
||||
$buttons['add']['title'] = 'forums_add_child_cat';
|
||||
}
|
||||
|
||||
return $buttons;
|
||||
}
|
||||
|
||||
@@ -876,8 +920,8 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
|
||||
$form->addTab( 'forum_display' );
|
||||
$form->addHeader( 'forum_display_forum' );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'forum_sort_key', $this->id ? $this->sort_key : 'last_post', FALSE, array( 'options' => array( 'last_post' => 'sort_updated', 'posts' => 'sort_num_comments', 'views' => 'sort_views', 'title' => 'sort_title', 'starter_name' => 'sort_author_name', 'last_poster_name' => 'sort_last_comment_name', 'start_date' => 'sort_date' ) ), NULL, NULL, NULL, 'forum_sort_key' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'forum_sort_key', $this->id ? $this->sort_key : 'last_post', FALSE, array( 'options' => array( 'last_post' => 'sort_updated', 'last_real_post' => 'sort_last_comment', 'posts' => 'sort_num_comments', 'views' => 'sort_views', 'title' => 'sort_title', 'starter_name' => 'sort_author_name', 'last_poster_name' => 'sort_last_comment_name', 'start_date' => 'sort_date' ) ), NULL, NULL, NULL, 'forum_sort_key' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'forum_show_rules', $this->id ? $this->show_rules : 0, FALSE, array(
|
||||
'options' => array(
|
||||
0 => 'forum_show_rules_none',
|
||||
@@ -942,7 +986,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'bw_disable_prefixes', !$this->forums_bitoptions['bw_disable_prefixes'], FALSE, array(), NULL, NULL, NULL, 'bw_disable_prefixes' ) );
|
||||
if ( !\IPS\Settings::i()->tags_open_system )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'forum_tag_predefined', $this->tag_predefined, FALSE, array( 'autocomplete' => array( 'unique' => 'true' ), 'nullLang' => 'forum_tag_predefined_unlimited' ), NULL, NULL, NULL, 'forum_tag_predefined' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'forum_tag_predefined', $this->tag_predefined ?: NULL, FALSE, array( 'autocomplete' => array( 'unique' => 'true' ), 'nullLang' => 'forum_tag_predefined_unlimited' ), NULL, NULL, NULL, 'forum_tag_predefined' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1149,21 +1193,21 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
* @brief Cached URL
|
||||
*/
|
||||
protected $_url = NULL;
|
||||
|
||||
|
||||
/**
|
||||
* Get URL
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
* @brief URL Base
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
if( $this->_url === NULL )
|
||||
{
|
||||
$this->_url = \IPS\Http\Url::internal( "app=forums&module=forums&controller=forums&id={$this->_id}", 'front', 'forums_forum', array( $this->name_seo ) );
|
||||
}
|
||||
|
||||
return $this->_url;
|
||||
}
|
||||
public static $urlBase = 'app=forums&module=forums&controller=forums&id=';
|
||||
|
||||
/**
|
||||
* @brief URL Base
|
||||
*/
|
||||
public static $urlTemplate = 'forums_forum';
|
||||
|
||||
/**
|
||||
* @brief SEO Title Column
|
||||
*/
|
||||
public static $seoTitleColumn = 'name_seo';
|
||||
|
||||
/**
|
||||
* Delete Record
|
||||
@@ -1190,6 +1234,16 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
return array( \IPS\Theme::i()->getTemplate( 'index', 'forums' ), 'forumTableRow' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get template for managing this nodes follows
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function manageFollowNodeRow()
|
||||
{
|
||||
return array( \IPS\Theme::i()->getTemplate( 'global', 'forums' ), 'manageFollowNodeRow' );
|
||||
}
|
||||
|
||||
/**
|
||||
* [ActiveRecord] Duplicate
|
||||
@@ -1234,7 +1288,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
}
|
||||
|
||||
/**
|
||||
* If there is only one forum (and it isn't a redirect forum), that forum, or NULL
|
||||
* If there is only one forum (and it isn't a redirect forum or password protected), that forum, or NULL
|
||||
*
|
||||
* @return \IPS\forums\Forum||NULL
|
||||
*/
|
||||
@@ -1248,7 +1302,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
foreach ( $root->children() as $forum )
|
||||
{
|
||||
if ( !$forum->redirect_url )
|
||||
if ( !$forum->redirect_url and !$forum->password )
|
||||
{
|
||||
return $forum;
|
||||
}
|
||||
@@ -1277,8 +1331,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
/* And then loop up the parents too... */
|
||||
foreach ( $this->parents() as $parent )
|
||||
{
|
||||
$permissions = $parent->permissions();
|
||||
$parentResult = $permissions['perm_view'];
|
||||
$parentResult = static::_getPermissions( $parent );
|
||||
|
||||
if( $result == '*' )
|
||||
{
|
||||
@@ -1447,4 +1500,23 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disabled permissions
|
||||
* Allow node classes to define permissions that are unselectable in the permission matrix
|
||||
*
|
||||
* @return array array( {group_id} => array( 'read', 'view', 'perm_7' );
|
||||
*/
|
||||
public function disabledPermissions()
|
||||
{
|
||||
$disabled = array();
|
||||
$guestGroup = \IPS\Member\Group::load( \IPS\Settings::i()->guest_group );
|
||||
|
||||
if( !$this->can_view_others )
|
||||
{
|
||||
$disabled[ $guestGroup->g_id ][] = 'view';
|
||||
}
|
||||
|
||||
return $disabled;
|
||||
}
|
||||
}
|
||||
@@ -204,42 +204,46 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\ReportCenter, \
|
||||
/**
|
||||
* Get HTML for search result display
|
||||
*
|
||||
* @return callable
|
||||
* @param array $indexData Data from the search index
|
||||
* @param array $authorData Basic data about the author. Only includes columns returned by \IPS\Member::columnsForPhoto()
|
||||
* @param array $itemData Basic data about the item. Only includes columns returned by item::basicDataColumns()
|
||||
* @param array|NULL $containerData Basic data about the author. Only includes columns returned by container::basicDataColumns()
|
||||
* @param array $reputationData Array of people who have given reputation and the reputation they gave
|
||||
* @param int|NULL $reviewRating If this is a review, the rating
|
||||
* @param bool $iPostedIn If the user has posted in the item
|
||||
* @param string $view 'expanded' or 'condensed'
|
||||
* @param bool $asItem Displaying results as items?
|
||||
* @return string
|
||||
*/
|
||||
public function searchResultHtml()
|
||||
{
|
||||
if ( $this->item()->container()->password and !\IPS\Member::loggedIn()->inGroup( explode( ',', $this->item()->container()->password_override ) ) and !( isset( \IPS\Request::i()->cookie[ 'ipbforumpass_' . $this->item()->container()->id ] ) and md5( $this->item()->container()->password ) === \IPS\Request::i()->cookie[ 'ipbforumpass_' . $this->item()->container()->id ] ) )
|
||||
public static function searchResult( array $indexData, array $authorData, array $itemData, array $containerData = NULL, array $reputationData, $reviewRating, $iPostedIn, $view, $asItem )
|
||||
{
|
||||
/* Password protected */
|
||||
if (
|
||||
$containerData['password'] // There is a password
|
||||
and !\IPS\Member::loggedIn()->inGroup( explode( ',', $containerData['password_override'] ) ) // We can't bypass it
|
||||
and (
|
||||
!isset( \IPS\Request::i()->cookie[ 'ipbforumpass_' . $indexData['index_container_id'] ] )
|
||||
or
|
||||
md5( $containerData['password'] ) !== \IPS\Request::i()->cookie[ 'ipbforumpass_' . $indexData['index_container_id'] ]
|
||||
) // We don't have the correct password
|
||||
)
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'forums' )->searchNoPermission( $this, \IPS\Member::loggedIn()->language()->addToStack('no_perm_post_password'), $this->item()->container()->url()->setQueryString( 'topic', $this->item()->tid ) );
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'forums' )->searchNoPermission(
|
||||
\IPS\Member::loggedIn()->language()->addToStack('no_perm_post_password'),
|
||||
\IPS\Http\Url::internal( \IPS\forums\Forum::$urlBase . $indexData['index_container_id'], 'front', \IPS\forums\Forum::$urlTemplate, array( $containerData[ \IPS\forums\Forum::$databasePrefix . \IPS\forums\Forum::$seoTitleColumn ] ) )->setQueryString( 'topic', $indexData['index_item_id'] )
|
||||
);
|
||||
}
|
||||
elseif ( $this->item()->container()->min_posts_view and $this->item()->container()->min_posts_view >= \IPS\Member::loggedIn()->member_posts )
|
||||
|
||||
/* Minimum posts */
|
||||
elseif ( $containerData['min_posts_view'] and $containerData['min_posts_view'] >= \IPS\Member::loggedIn()->member_po )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'forums' )->searchNoPermission( $this, \IPS\Member::loggedIn()->language()->addToStack( 'no_perm_post_min_posts', FALSE, array( 'pluralize' => array( $this->item()->container()->min_posts_view ) ) ) );
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'forums' )->searchNoPermission( \IPS\Member::loggedIn()->language()->addToStack( 'no_perm_post_min_posts', FALSE, array( 'pluralize' => array( $containerData['min_posts_view'] ) ) ) );
|
||||
}
|
||||
|
||||
/* Normal */
|
||||
else
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'search', 'core', 'front' )->contentComment( $this );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML for search result display
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public function activityStreamHtml()
|
||||
{
|
||||
if ( $this->item()->container()->password and !\IPS\Member::loggedIn()->inGroup( explode( ',', $this->item()->container()->password_override ) ) and !( isset( \IPS\Request::i()->cookie[ 'ipbforumpass_' . $this->item()->container()->id ] ) and md5( $this->item()->container()->password ) === \IPS\Request::i()->cookie[ 'ipbforumpass_' . $this->item()->container()->id ] ) )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'forums' )->searchNoPermission( $this, \IPS\Member::loggedIn()->language()->addToStack('no_perm_post_password'), $this->item()->container()->url()->setQueryString( 'topic', $this->item()->tid ) );
|
||||
}
|
||||
elseif ( $this->item()->container()->min_posts_view and $this->item()->container()->min_posts_view >= \IPS\Member::loggedIn()->member_posts )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'forums' )->searchNoPermission( $this, \IPS\Member::loggedIn()->language()->addToStack( 'no_perm_post_min_posts', FALSE, array( 'pluralize' => array( $this->item()->container()->min_posts_view ) ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'system', 'core', 'front' )->activityStreamResult( $this );
|
||||
return parent::searchResult( $indexData, $authorData, $itemData, $containerData, $reputationData, $reviewRating, $iPostedIn, $view, $asItem );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,17 +326,18 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\ReportCenter, \
|
||||
* @param \IPS\Lang|NULL $language The language to use, or NULL for the language of the currently logged in member
|
||||
* @return string
|
||||
*/
|
||||
public function indefiniteArticle( \IPS\Lang $lang = NULL )
|
||||
public static function _indefiniteArticle( array $containerData = NULL, \IPS\Lang $lang = NULL )
|
||||
{
|
||||
if ( $this->item()->isQuestion() )
|
||||
$bitOptions = ( $containerData['forums_bitoptions'] instanceof \IPS\Patterns\Bitwise ) ? $containerData['forums_bitoptions'] : new \IPS\Patterns\Bitwise( array( 'forums_bitoptions' => $containerData['forums_bitoptions'] ), \IPS\forums\Forum::$bitOptions['forums_bitoptions'] );
|
||||
|
||||
if ( $bitOptions['bw_enable_answers'] )
|
||||
{
|
||||
$lang = $lang ?: \IPS\Member::loggedIn()->language();
|
||||
|
||||
return ( $this->isFirst() ) ? $lang->get( '__indefart_question', FALSE ) : $lang->get( '__indefart_answer', FALSE );
|
||||
return $lang->addToStack( '__indefart_answer', FALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent::indefiniteArticle( $lang );
|
||||
return parent::_indefiniteArticle( $containerData, $lang );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -260,16 +260,16 @@ class _Topic extends \IPS\Content\Item implements
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional WHERE clauses for New Content view
|
||||
* Additional WHERE clauses for Follow view
|
||||
*
|
||||
* @param bool $joinContainer If true, will join container data (set to TRUE if your $where clause depends on this data)
|
||||
* @param array $joins Other joins
|
||||
* @return array
|
||||
*/
|
||||
public static function vncWhere( &$joinContainer, &$joins )
|
||||
public static function followWhere( &$joinContainer, &$joins )
|
||||
{
|
||||
$joinContainer = FALSE;
|
||||
return array_merge( parent::vncWhere( $joinContainer, $joins ), static::getItemsWithPermissionWhere( array(), 'read', NULL, $joinContainer ) );
|
||||
return array_merge( parent::followWhere( $joinContainer, $joins ), static::getItemsWithPermissionWhere( array(), 'read', NULL, $joinContainer ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -315,7 +315,7 @@ class _Topic extends \IPS\Content\Item implements
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
|
||||
if ( !$member->modPermission( 'can_read_all_topics' ) or $member->modPermission( 'forums' ) !== true )
|
||||
if ( !$member->modPermission( 'can_read_all_topics' ) or $member->modPermission( 'forums' ) !== -1 )
|
||||
{
|
||||
if ( $skipPermission instanceof \IPS\forums\Forum )
|
||||
{
|
||||
@@ -496,48 +496,53 @@ class _Topic extends \IPS\Content\Item implements
|
||||
/* Moderator actions */
|
||||
if ( isset( $values['topic_create_state'] ) )
|
||||
{
|
||||
if ( in_array( 'lock', $values['topic_create_state'] ) )
|
||||
|
||||
if ( static::modPermission( 'feature', NULL, $this->container() ) )
|
||||
{
|
||||
$this->state = 'closed';
|
||||
$this->state = ( in_array( 'lock', $values['topic_create_state'] ) ) ? 'closed' : 'open';
|
||||
}
|
||||
|
||||
if ( in_array( 'hide', $values['topic_create_state'] ) )
|
||||
if ( static::modPermission( 'hide', NULL, $this->container() ) )
|
||||
{
|
||||
$this->approved = -1;
|
||||
$this->approved = ( in_array( 'hide', $values['topic_create_state'] ) ) ? -1 : 1;
|
||||
}
|
||||
|
||||
if ( in_array( 'pin', $values['topic_create_state'] ) )
|
||||
if ( static::modPermission( 'pin', NULL, $this->container() ) )
|
||||
{
|
||||
$this->pinned = 1;
|
||||
$this->pinned = ( in_array( 'pin', $values['topic_create_state'] ) ) ? 1 : 0;
|
||||
}
|
||||
|
||||
if ( in_array( 'feature', $values['topic_create_state'] ) )
|
||||
if ( static::modPermission( 'feature', NULL, $this->container() ) )
|
||||
{
|
||||
$this->featured = 1;
|
||||
$this->featured = ( in_array( 'feature', $values['topic_create_state'] ) ) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set open/close time */
|
||||
if ( isset( $values['topic_open_time'] ) and $values['topic_open_time'] )
|
||||
|
||||
if ( static::modPermission( 'lock', NULL, $this->container() ) )
|
||||
{
|
||||
$this->topic_open_time = $values['topic_open_time']->getTimestamp();
|
||||
}
|
||||
if ( isset( $values['topic_close_time'] ) and $values['topic_close_time'] )
|
||||
{
|
||||
$this->topic_close_time = $values['topic_close_time']->getTimestamp();
|
||||
}
|
||||
else if( isset( $values['topic_create_state'] ) and !in_array( 'lock', $values['topic_create_state'] ) )
|
||||
{
|
||||
$this->topic_close_time = 0;
|
||||
$this->state = 'open';
|
||||
}
|
||||
|
||||
/* If open time is before close time, close now */
|
||||
if ( $this->topic_open_time and $this->topic_close_time and $this->topic_open_time < $this->topic_close_time )
|
||||
{
|
||||
$this->state = 'closed';
|
||||
/* Set open/close time */
|
||||
if ( isset( $values['topic_open_time'] ) and $values['topic_open_time'] )
|
||||
{
|
||||
$this->topic_open_time = $values['topic_open_time']->getTimestamp();
|
||||
}
|
||||
if ( isset( $values['topic_close_time'] ) and $values['topic_close_time'] )
|
||||
{
|
||||
$this->topic_close_time = $values['topic_close_time']->getTimestamp();
|
||||
}
|
||||
else if( isset( $values['topic_create_state'] ) and !in_array( 'lock', $values['topic_create_state'] ) )
|
||||
{
|
||||
$this->topic_close_time = 0;
|
||||
$this->state = 'open';
|
||||
}
|
||||
|
||||
/* If open time is before close time, close now */
|
||||
if ( $this->topic_open_time and $this->topic_close_time and $this->topic_open_time < $this->topic_close_time )
|
||||
{
|
||||
$this->state = 'closed';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -574,29 +579,21 @@ class _Topic extends \IPS\Content\Item implements
|
||||
* @brief Cached URLs
|
||||
*/
|
||||
protected $_url = array();
|
||||
|
||||
/**
|
||||
* Get URL
|
||||
*
|
||||
* @param string|NULL $action Action
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
public function url( $action=NULL )
|
||||
{
|
||||
$_key = md5( $action );
|
||||
|
||||
if( !isset( $this->_url[ $_key ] ) )
|
||||
{
|
||||
$this->_url[ $_key ] = \IPS\Http\Url::internal( "app=forums&module=forums&controller=topic&id={$this->tid}", 'front', 'forums_topic', array( $this->title_seo ) );
|
||||
|
||||
if ( $action )
|
||||
{
|
||||
$this->_url[ $_key ] = $this->_url[ $_key ]->setQueryString( 'do', $action );
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_url[ $_key ];
|
||||
}
|
||||
/**
|
||||
* @brief URL Base
|
||||
*/
|
||||
public static $urlBase = 'app=forums&module=forums&controller=topic&id=';
|
||||
|
||||
/**
|
||||
* @brief URL Base
|
||||
*/
|
||||
public static $urlTemplate = 'forums_topic';
|
||||
|
||||
/**
|
||||
* @brief SEO Title Column
|
||||
*/
|
||||
public static $seoTitleColumn = 'title_seo';
|
||||
|
||||
/**
|
||||
* Stats for table view
|
||||
@@ -695,7 +692,7 @@ class _Topic extends \IPS\Content\Item implements
|
||||
if
|
||||
(
|
||||
(
|
||||
$member->modPermission( 'forums' ) !== 0
|
||||
$member->modPermission( 'forums' ) !== -1
|
||||
and
|
||||
(
|
||||
is_array( $member->modPermission( 'forums' ) )
|
||||
@@ -729,48 +726,49 @@ class _Topic extends \IPS\Content\Item implements
|
||||
|
||||
if ( !$this->container()->can_view_others )
|
||||
{
|
||||
$return = array();
|
||||
|
||||
if ( $this->starter_id )
|
||||
/* If the search index permissions are empty, just return now because no one can see content in this forum */
|
||||
if( !$return )
|
||||
{
|
||||
$return[] = "m{$this->starter_id}";
|
||||
return $return;
|
||||
}
|
||||
|
||||
$normal = $return;
|
||||
$return = array();
|
||||
$members = array();
|
||||
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_moderators' ) as $moderator )
|
||||
{
|
||||
if ( $moderator['perms'] === '*' or in_array( 'can_read_all_topics', explode( ',', $moderator['perms'] ) ) )
|
||||
{
|
||||
$return[] = ( $moderator['type'] === 'g' ) ? $moderator['id'] : "m{$moderator['id']}";
|
||||
if( $moderator['type'] === 'g' )
|
||||
{
|
||||
$return[] = $moderator['id'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$members[] = "m{$moderator['id']}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$return = implode( ',', array_unique( $return ) );
|
||||
$return = ( $normal == '*' ) ? array_unique( $return ) : array_intersect( explode( ',', $normal ), array_unique( $return ) );
|
||||
|
||||
if ( $this->starter_id )
|
||||
{
|
||||
$members[] = "m{$this->starter_id}";
|
||||
}
|
||||
|
||||
if( count( $members ) )
|
||||
{
|
||||
$return = array_merge( $return, $members );
|
||||
}
|
||||
|
||||
$return = implode( ',', $return );
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML for search result display
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public function searchResultHtml()
|
||||
{
|
||||
if ( $this->container()->password and !\IPS\Member::loggedIn()->inGroup( explode( ',', $this->container()->password_override ) ) and !( isset( \IPS\Request::i()->cookie[ 'ipbforumpass_' . $this->container()->id ] ) and md5( $this->container()->password ) === \IPS\Request::i()->cookie[ 'ipbforumpass_' . $this->container()->id ] ) )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'forums' )->searchNoPermission( $this, \IPS\Member::loggedIn()->language()->addToStack('no_perm_topic_password'), $this->container()->url()->setQueryString( 'topic', $this->tid ) );
|
||||
}
|
||||
elseif ( $this->container()->min_posts_view and $this->container()->min_posts_view >= \IPS\Member::loggedIn()->member_posts )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'forums' )->searchNoPermission( $this, \IPS\Member::loggedIn()->language()->addToStack( 'no_perm_topic_min_posts', FALSE, array( 'pluralize' => array( $this->container()->min_posts_view ) ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'search', 'core', 'front' )->contentItem( $this );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Can Rate?
|
||||
*
|
||||
@@ -1042,18 +1040,38 @@ class _Topic extends \IPS\Content\Item implements
|
||||
*/
|
||||
public function canSetBestAnswer( \IPS\Member $member = NULL )
|
||||
{
|
||||
/* Archived topics cannot be modified */
|
||||
if ( $this->isArchived() )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
|
||||
if ( ( $member == $this->author() and $this->container()->forums_bitoptions['bw_enable_answers_member'] ) or $member->modPermission('can_set_best_answer') )
|
||||
/* If we asked this question, we can set the best answer */
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
if ( $member == $this->author() and $this->container()->forums_bitoptions['bw_enable_answers_member'] )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Or if we're a moderator */
|
||||
if
|
||||
(
|
||||
$member->modPermission( 'can_set_best_answer' )
|
||||
and
|
||||
(
|
||||
$member->modPermission( \IPS\forums\Forum::$modPerm ) === -1
|
||||
or
|
||||
(
|
||||
is_array( $member->modPermission( \IPS\forums\Forum::$modPerm ) )
|
||||
and
|
||||
in_array( $this->container()->_id, $member->modPermission( \IPS\forums\Forum::$modPerm ) )
|
||||
)
|
||||
)
|
||||
) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Otherwise no */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1115,13 +1133,7 @@ class _Topic extends \IPS\Content\Item implements
|
||||
{
|
||||
throw new \InvalidArgumentException;
|
||||
}
|
||||
|
||||
/* Downvoting disabled? */
|
||||
if ( $rating === -1 and !\IPS\Settings::i()->forums_questions_downvote )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Guests can't vote */
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
if ( !$member->member_id )
|
||||
@@ -1151,6 +1163,12 @@ class _Topic extends \IPS\Content\Item implements
|
||||
}
|
||||
}
|
||||
|
||||
/* Downvoting disabled? */
|
||||
if ( $rating === -1 and !\IPS\Settings::i()->forums_questions_downvote and ( !isset( $ratings[ $member->member_id ] ) or $ratings[ $member->member_id ] != 1 ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1184,19 +1202,21 @@ class _Topic extends \IPS\Content\Item implements
|
||||
* @param \IPS\Lang|NULL $language The language to use, or NULL for the language of the currently logged in member
|
||||
* @return string
|
||||
*/
|
||||
public function indefiniteArticle( \IPS\Lang $lang = NULL )
|
||||
public static function _indefiniteArticle( array $containerData = NULL, \IPS\Lang $lang = NULL )
|
||||
{
|
||||
if ( $this->isQuestion() )
|
||||
$bitOptions = ( $containerData['forums_bitoptions'] instanceof \IPS\Patterns\Bitwise ) ? $containerData['forums_bitoptions'] : new \IPS\Patterns\Bitwise( array( 'forums_bitoptions' => $containerData['forums_bitoptions'] ), \IPS\forums\Forum::$bitOptions['forums_bitoptions'] );
|
||||
|
||||
if ( $bitOptions['bw_enable_answers'] )
|
||||
{
|
||||
$lang = $lang ?: \IPS\Member::loggedIn()->language();
|
||||
return $lang->get( '__indefart_question', FALSE );
|
||||
return $lang->addToStack( '__indefart_question', FALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent::indefiniteArticle( $lang );
|
||||
return parent::_indefiniteArticle( $containerData, $lang );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* !Sitemap */
|
||||
|
||||
/**
|
||||
@@ -1508,10 +1528,17 @@ class _Topic extends \IPS\Content\Item implements
|
||||
return $comments[ $_hash ];
|
||||
}
|
||||
|
||||
$includeWarnings = NULL;
|
||||
$includeWarnings = NULL;
|
||||
$commentClass = NULL;
|
||||
|
||||
if ( $this->isArchived() )
|
||||
{
|
||||
$class = static::$archiveClass;
|
||||
/* We need to set $commentClass to the archive class, otherwise the includeHidden checks in _comments fail, as they verify $class == static::$commentClass */
|
||||
$class = static::$archiveClass;
|
||||
$commentClass = static::$commentClass;
|
||||
|
||||
static::$commentClass = $class;
|
||||
|
||||
$includeWarnings = FALSE;
|
||||
|
||||
if( $extraWhereClause !== NULL )
|
||||
@@ -1535,13 +1562,19 @@ class _Topic extends \IPS\Content\Item implements
|
||||
}
|
||||
|
||||
$comments[ $_hash ] = $this->_comments( $class, $limit ?: static::getCommentsPerPage(), $offset, ( isset( $class::$databaseColumnMap[ $order ] ) ? ( $class::$databasePrefix . $class::$databaseColumnMap[ $order ] ) : $order ) . ' ' . $orderDirection, $member, $includeHiddenComments, $cutoff, $includeWarnings, $extraWhereClause );
|
||||
|
||||
/* Restore comment class now */
|
||||
if( $commentClass )
|
||||
{
|
||||
static::$commentClass = $commentClass;
|
||||
}
|
||||
return $comments[ $_hash ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resync the comments/unapproved comment counts
|
||||
*
|
||||
* @param string $commentClass
|
||||
* @param string $commentClass Override comment class to use
|
||||
* @return void
|
||||
*/
|
||||
public function resyncCommentCounts( $commentClass=NULL )
|
||||
@@ -1569,7 +1602,7 @@ class _Topic extends \IPS\Content\Item implements
|
||||
$title = static::$title;
|
||||
if
|
||||
(
|
||||
$member->modPermission( $containerClass::$modPerm ) === 0
|
||||
$member->modPermission( $containerClass::$modPerm ) === -1
|
||||
or
|
||||
(
|
||||
is_array( $member->modPermission( $containerClass::$modPerm ) )
|
||||
|
||||
@@ -82,26 +82,27 @@ class _archive extends \IPS\Task
|
||||
try
|
||||
{
|
||||
/* Get the topic */
|
||||
$inProgress = \IPS\Db::i()->select( 'tid', 'forums_topics', array( 'topic_archive_status=?', \IPS\forums\Topic::ARCHIVE_WORKING ) )->first();
|
||||
$topic = \IPS\forums\Topic::constructFromData( \IPS\Db::i()->select( '*', 'forums_topics', array( 'topic_archive_status=?', \IPS\forums\Topic::ARCHIVE_WORKING ) )->first() );
|
||||
|
||||
/* Do as many posts as we can */
|
||||
$offset = $this->storage->select( 'MAX(archive_id)', 'forums_archive_posts', array( 'archive_topic_id=?', $inProgress ) )->first();
|
||||
$posts = \IPS\Db::i()->select( 'forums_posts.*,forums_topics.forum_id', 'forums_posts', array( 'pid>? AND topic_id=?', intval( $offset ), $inProgress ), 'pid ASC', static::PROCESS_PER_BATCH, NULL, NULL, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS )->join( 'forums_topics', 'tid=topic_id' );
|
||||
$offset = $this->storage->select( 'MAX(archive_id)', 'forums_archive_posts', array( 'archive_topic_id=?', $topic->tid ) )->first();
|
||||
$posts = \IPS\Db::i()->select( 'forums_posts.*,forums_topics.forum_id', 'forums_posts', array( 'pid>? AND topic_id=?', intval( $offset ), $topic->tid ), 'pid ASC', static::PROCESS_PER_BATCH, NULL, NULL, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS )->join( 'forums_topics', 'tid=topic_id' );
|
||||
foreach ( $posts as $post )
|
||||
{
|
||||
$this->archive( $post, $post['forum_id'] );
|
||||
$postsProcessed++;
|
||||
}
|
||||
|
||||
/* If we did them all, mark that this topic is done */
|
||||
/* If we did them all, mark that this topic is done and remove from search index */
|
||||
if ( $postsProcessed == $posts->count( TRUE ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'forums_topics', array( 'topic_archive_status' => \IPS\forums\Topic::ARCHIVE_DONE ), array( 'tid=?', $inProgress ) );
|
||||
{
|
||||
$topic->topic_archive_status = \IPS\forums\Topic::ARCHIVE_DONE;
|
||||
$topic->save();
|
||||
|
||||
\IPS\Db::i()->delete( 'forums_posts', array( 'topic_id=?', $inProgress ) );
|
||||
|
||||
\IPS\Content\Search\Index::i()->removeFromSearchIndex( $topic );
|
||||
}
|
||||
|
||||
/* Update search index */
|
||||
\IPS\Db::i()->update( 'core_search_index', array( 'index_class' => 'IPS\forums\Topic\Post' ), array( 'index_item_id=? AND index_class=?', $inProgress, 'IPS\forums\Topic\ArchivedPost' ) );
|
||||
}
|
||||
catch ( \UnderflowException $e ) { }
|
||||
}
|
||||
@@ -110,13 +111,14 @@ class _archive extends \IPS\Task
|
||||
if ( $postsProcessed < static::PROCESS_PER_BATCH )
|
||||
{
|
||||
/* Loop topics */
|
||||
foreach ( \IPS\Db::i()->select( 'tid', 'forums_topics', array( 'topic_archive_status=?', \IPS\forums\Topic::ARCHIVE_RESTORE ), 'tid ASC', 250 ) as $topic )
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'forums_topics', array( 'topic_archive_status=?', \IPS\forums\Topic::ARCHIVE_RESTORE ), 'tid ASC', 250 ), 'IPS\forums\Topic' ) as $topic )
|
||||
{
|
||||
/* Do as many posts as we can */
|
||||
$offset = \IPS\Db::i()->select( 'MAX(pid)', 'forums_posts', array( 'topic_id=?', $topic ) )->first();
|
||||
foreach ( $this->storage->select( '*', 'forums_archive_posts', array( 'archive_id>? AND archive_topic_id=?', intval( $offset ), $topic ), 'archive_id ASC', static::PROCESS_PER_BATCH - $postsProcessed ) as $post )
|
||||
$offset = \IPS\Db::i()->select( 'MAX(pid)', 'forums_posts', array( 'topic_id=?', $topic->tid ) )->first();
|
||||
foreach ( $this->storage->select( '*', 'forums_archive_posts', array( 'archive_id>? AND archive_topic_id=?', intval( $offset ), $topic->tid ), 'archive_id ASC', static::PROCESS_PER_BATCH - $postsProcessed ) as $post )
|
||||
{
|
||||
$this->unarchive( $post );
|
||||
\IPS\Content\Search\Index::i()->index( \IPS\forums\Topic\Post::load( $post['archive_id'] ) );
|
||||
$postsProcessed++;
|
||||
if ( $postsProcessed >= static::PROCESS_PER_BATCH )
|
||||
{
|
||||
@@ -125,11 +127,8 @@ class _archive extends \IPS\Task
|
||||
}
|
||||
|
||||
/* Set that it's done */
|
||||
\IPS\Db::i()->update( 'forums_topics', array( 'topic_archive_status' => \IPS\forums\Topic::ARCHIVE_EXCLUDE ), array( 'tid=?', $topic ) );
|
||||
$this->storage->delete( 'forums_archive_posts', array( 'archive_topic_id=?', $topic ) );
|
||||
|
||||
/* Update search index */
|
||||
\IPS\Db::i()->update( 'core_search_index', array( 'index_class' => 'IPS\forums\Topic\Post' ), array( 'index_item_id=? AND index_class=?', $topic['tid'], 'IPS\forums\Topic\ArchivedPost' ) );
|
||||
\IPS\Db::i()->update( 'forums_topics', array( 'topic_archive_status' => \IPS\forums\Topic::ARCHIVE_EXCLUDE ), array( 'tid=?', $topic->tid ) );
|
||||
$this->storage->delete( 'forums_archive_posts', array( 'archive_topic_id=?', $topic->tid ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,15 +139,15 @@ class _archive extends \IPS\Task
|
||||
if ( $postsProcessed < static::PROCESS_PER_BATCH )
|
||||
{
|
||||
/* Loop topics */
|
||||
foreach ( \IPS\Db::i()->select( 'tid,forum_id', 'forums_topics', $query, 'tid ASC', 250 ) as $topic )
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'forums_topics', $query, 'tid ASC', 250 ), 'IPS\forums\Topic' ) as $topic )
|
||||
{
|
||||
/* First set it as working */
|
||||
\IPS\Db::i()->update( 'forums_topics', array( 'topic_archive_status' => \IPS\forums\Topic::ARCHIVE_WORKING ), array( 'tid=?', $topic['tid'] ) );
|
||||
\IPS\Db::i()->update( 'forums_topics', array( 'topic_archive_status' => \IPS\forums\Topic::ARCHIVE_WORKING ), array( 'tid=?', $topic->tid ) );
|
||||
|
||||
/* Do as many posts as we can */
|
||||
foreach ( \IPS\Db::i()->select( '*', 'forums_posts', array( 'topic_id=?', $topic['tid'] ), 'pid ASC', static::PROCESS_PER_BATCH - $postsProcessed ) as $post )
|
||||
foreach ( \IPS\Db::i()->select( '*', 'forums_posts', array( 'topic_id=?', $topic->tid ), 'pid ASC', static::PROCESS_PER_BATCH - $postsProcessed ) as $post )
|
||||
{
|
||||
$this->archive( $post, $topic['forum_id'] );
|
||||
$this->archive( $post, $topic->forum_id );
|
||||
$postsProcessed++;
|
||||
if ( $postsProcessed >= static::PROCESS_PER_BATCH )
|
||||
{
|
||||
@@ -157,11 +156,11 @@ class _archive extends \IPS\Task
|
||||
}
|
||||
|
||||
/* Set that it's done */
|
||||
\IPS\Db::i()->update( 'forums_topics', array( 'topic_archive_status' => \IPS\forums\Topic::ARCHIVE_DONE ), array( 'tid=?', $topic['tid'] ) );
|
||||
\IPS\Db::i()->delete( 'forums_posts', array( 'topic_id=?', $topic['tid'] ) );
|
||||
\IPS\Db::i()->update( 'forums_topics', array( 'topic_archive_status' => \IPS\forums\Topic::ARCHIVE_DONE ), array( 'tid=?', $topic->tid ) );
|
||||
\IPS\Db::i()->delete( 'forums_posts', array( 'topic_id=?', $topic->tid ) );
|
||||
|
||||
/* Update search index */
|
||||
\IPS\Db::i()->update( 'core_search_index', array( 'index_class' => 'IPS\forums\Topic\ArchivedPost' ), array( 'index_item_id=? AND index_class=?', $topic['tid'], 'IPS\forums\Topic\Post' ) );
|
||||
/* Remove from search index */
|
||||
\IPS\Content\Search\Index::i()->removeFromSearchIndex( $topic );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -194,8 +193,6 @@ class _archive extends \IPS\Task
|
||||
'archive_added' => time(),
|
||||
'archive_attach_key' => $post['post_key'],
|
||||
'archive_html_mode' => $post['post_htmlstate'],
|
||||
'archive_show_signature' => $post['use_sig'],
|
||||
'archive_show_emoticons' => $post['use_emo'],
|
||||
'archive_show_edited_by' => $post['append_edit'],
|
||||
'archive_edit_time' => intval( $post['edit_time'] ),
|
||||
'archive_edit_name' => (string) $post['edit_name'],
|
||||
@@ -230,8 +227,6 @@ class _archive extends \IPS\Task
|
||||
'post_bwoptions' => $post['archive_bwoptions'],
|
||||
'post_key' => $post['archive_attach_key'],
|
||||
'post_htmlstate' => $post['archive_html_mode'],
|
||||
'use_sig' => $post['archive_show_signature'],
|
||||
'use_emo' => $post['archive_show_emoticons'],
|
||||
'append_edit' => $post['archive_show_edited_by'],
|
||||
'edit_time' => $post['archive_edit_time'],
|
||||
'edit_name' => $post['archive_edit_name'],
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief poll Widget
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage forums
|
||||
* @since 21 Jul 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\forums\widgets;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* poll Widget
|
||||
*/
|
||||
class _poll extends \IPS\Widget\PermissionCache
|
||||
{
|
||||
/**
|
||||
* @brief Widget Key
|
||||
*/
|
||||
public $key = 'poll';
|
||||
|
||||
/**
|
||||
* @brief App
|
||||
*/
|
||||
public $app = 'forums';
|
||||
|
||||
/**
|
||||
* @brief Plugin
|
||||
*/
|
||||
public $plugin = '';
|
||||
|
||||
/**
|
||||
* Initialise this widget
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
// Use this to perform any set up and to assign a template that is not in the following format:
|
||||
// $this->template( array( \IPS\Theme::i()->getTemplate( 'widgets', $this->app, 'front' ), $this->key ) );
|
||||
// If you are creating a plugin, uncomment this line:
|
||||
// $this->template( array( \IPS\Theme::i()->getTemplate( 'plugins', 'core', 'global' ), $this->key ) );
|
||||
// And then create your template at located at plugins/<your plugin>/dev/html/poll.phtml
|
||||
|
||||
|
||||
parent::init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify widget configuration
|
||||
*
|
||||
* @param null|\IPS\Helpers\Form $form Form object
|
||||
* @return null|\IPS\Helpers\Form
|
||||
*/
|
||||
public function configuration( &$form=null )
|
||||
{
|
||||
if ( $form === null )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Item( 'widget_poll_tid', ( isset( $this->configuration['widget_poll_tid'] ) ? $this->configuration['widget_poll_tid'] : NULL ), TRUE, array(
|
||||
'class' => '\IPS\forums\Topic',
|
||||
'maxItems' => 1,
|
||||
'where' => array( array( 'poll_state IS NOT NULL' ) )
|
||||
) ) );
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ran before saving widget configuration
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @return array
|
||||
*/
|
||||
public function preConfig( $values )
|
||||
{
|
||||
$item = array_pop( $values['widget_poll_tid'] );
|
||||
$values['widget_poll_tid'] = $item->tid;
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a widget
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
if ( empty( $this->configuration['widget_poll_tid'] ) )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$topic = \IPS\forums\Topic::loadAndCheckPerms( $this->configuration['widget_poll_tid'] );
|
||||
$poll = $topic->getPoll();
|
||||
$poll->displayTemplate = array( \IPS\Theme::i()->getTemplate( 'widgets', 'forums', 'front' ), 'pollWidget' );
|
||||
$poll->url = $topic->url();
|
||||
|
||||
return $this->output( $topic, $poll );
|
||||
}
|
||||
catch( \Exception $ex )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,9 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
}
|
||||
|
||||
/**
|
||||
* latestTopics Widget
|
||||
* postFeed Widget
|
||||
*/
|
||||
class _postFeed extends \IPS\Widget\PermissionCache
|
||||
class _postFeed extends \IPS\Content\WidgetComment
|
||||
{
|
||||
/**
|
||||
* @brief Widget Key
|
||||
@@ -40,174 +40,22 @@ class _postFeed extends \IPS\Widget\PermissionCache
|
||||
public $plugin = '';
|
||||
|
||||
/**
|
||||
* Specify widget configuration
|
||||
*
|
||||
* @param null|\IPS\Helpers\Form $form Form object
|
||||
* @return \IPS\Helpers\Form
|
||||
* Class
|
||||
*/
|
||||
public function configuration( &$form=null )
|
||||
{
|
||||
if ( $form === null )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'tfb_title', isset( $this->configuration['tfb_title'] ) ? $this->configuration['tfb_title'] : \IPS\Member::loggedIn()->language()->addToStack('block_postFeed_title') ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'tfb_forums', ( isset( $this->configuration['tfb_forums'] ) and is_array( $this->configuration['tfb_forums'] ) ) ? array_keys( $this->configuration['tfb_forums'] ) : 0, FALSE, array(
|
||||
'class' => '\IPS\forums\Forum',
|
||||
'zeroVal' => 'tfb_all_forums',
|
||||
'permissionCheck' => 'view',
|
||||
'multiple' => true
|
||||
) ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'tfb_use_perms', isset( $this->configuration['tfb_use_perms'] ) ? $this->configuration['tfb_use_perms'] : TRUE, FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'tfb_topic_status', isset( $this->configuration['tfb_topic_status'] ) ? $this->configuration['tfb_topic_status'] : array( 'open', 'pinned', 'notpinned', 'visible', 'featured', 'notfeatured' ), FALSE, array(
|
||||
'options' => array(
|
||||
'open' => 'tfb_open_status_open',
|
||||
'closed' => 'tfb_open_status_closed',
|
||||
'pinned' => 'tfb_open_status_pinned',
|
||||
'notpinned' => 'tfb_open_status_notpinned',
|
||||
'visible' => 'tfb_open_status_visible',
|
||||
'hidden' => 'tfb_open_status_hidden',
|
||||
'featured' => 'tfb_open_status_featured',
|
||||
'notfeatured' => 'tfb_open_status_notfeatured'
|
||||
)
|
||||
) ) );
|
||||
|
||||
$author = NULL;
|
||||
|
||||
try
|
||||
{
|
||||
if ( isset( $this->configuration['tfb_author'] ) and is_array( $this->configuration['tfb_author'] ) )
|
||||
{
|
||||
foreach( $this->configuration['tfb_author'] as $id )
|
||||
{
|
||||
$author[ $id ] = \IPS\Member::load( $id );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $ex ) { }
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'tfb_author', $author, FALSE, array( 'multiple' => NULL ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'tfb_min_posts', isset( $this->configuration['tfb_min_posts'] ) ? $this->configuration['tfb_min_posts'] : 0, FALSE, array( 'unlimitedLang' => 'tfb_any_posts', 'unlimited' => 0 ) ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'tfb_show', isset( $this->configuration['tfb_show'] ) ? $this->configuration['tfb_show'] : 5, TRUE ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'tfb_sort_dir', isset( $this->configuration['tfb_sort_dir'] ) ? $this->configuration['tfb_sort_dir'] : 'desc', FALSE, array(
|
||||
'options' => array(
|
||||
'desc' => 'tfb_sort_dir_dsc',
|
||||
'asc' => 'tfb_sort_dir_asc'
|
||||
)
|
||||
) ) );
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust configuration values we are about to save
|
||||
*
|
||||
* @param array $values Values from form submission
|
||||
* @return array
|
||||
*/
|
||||
public function preConfig( $values )
|
||||
{
|
||||
if( isset( $values['tfb_author'] ) AND $values['tfb_author'] )
|
||||
{
|
||||
$values['tfb_author'] = array_keys( $values['tfb_author'] );
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
protected static $class = 'IPS\forums\Topic\Post';
|
||||
|
||||
/**
|
||||
* Render a widget
|
||||
* Get where clause
|
||||
*
|
||||
* @return string
|
||||
* @return array
|
||||
*/
|
||||
public function render()
|
||||
protected function buildWhere()
|
||||
{
|
||||
$where = array();
|
||||
$order = NULL;
|
||||
$limit = isset( $this->configuration['tfb_show'] ) ? $this->configuration['tfb_show'] : 5;
|
||||
$permissionKey = ( !isset( $this->configuration['tfb_use_perms'] ) or $this->configuration['tfb_use_perms'] ) ? 'read' : NULL;
|
||||
$includeHidden = false;
|
||||
|
||||
if ( isset( $this->configuration['tfb_forums'] ) and is_array( $this->configuration['tfb_forums'] ) )
|
||||
{
|
||||
$where['item'][] = array( 'forum_id IN (' . implode( ",", array_keys( $this->configuration['tfb_forums'] ) ) . ')' );
|
||||
}
|
||||
|
||||
if ( isset( $this->configuration['tfb_topic_status'] ) and is_array( $this->configuration['tfb_topic_status'] ) )
|
||||
{
|
||||
$status = $this->configuration['tfb_topic_status'];
|
||||
|
||||
if ( ! in_array( 'open', $status ) or ! in_array( 'closed', $status ) )
|
||||
{
|
||||
if ( ! in_array( 'open', $status ) )
|
||||
{
|
||||
$where['item'][] = array( "state='closed'" );
|
||||
}
|
||||
else if ( ! in_array( 'closed', $status ) )
|
||||
{
|
||||
$where['item'][] = array( "state='open'" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( in_array( 'hidden', $status ) )
|
||||
{
|
||||
$includeHidden = true;
|
||||
}
|
||||
|
||||
if ( ! in_array( 'featured', $status ) or ! in_array( 'notfeatured', $status ) )
|
||||
{
|
||||
if ( ! in_array( 'featured', $status ) )
|
||||
{
|
||||
$where['item'][] = array( 'featured=0' );
|
||||
}
|
||||
else if ( ! in_array( 'notfeatured', $status ) )
|
||||
{
|
||||
$where['item'][] = array( 'featured=1' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! in_array( 'pinned', $status ) or ! in_array( 'notpinned', $status ) )
|
||||
{
|
||||
if ( ! in_array( 'pinned', $status ) )
|
||||
{
|
||||
$where['item'][] = array( 'pinned=0' );
|
||||
}
|
||||
else if ( ! in_array( 'notpinned', $status ) )
|
||||
{
|
||||
$where['item'][] = array( 'pinned=1' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $this->configuration['tfb_author'] ) and is_array( $this->configuration['tfb_author'] ) )
|
||||
{
|
||||
$where[] = array( "starter_id IN(" . implode( ',', $this->configuration['tfb_author'] ) . ")" );
|
||||
}
|
||||
|
||||
if ( isset( $this->configuration['tfb_sort_dir'] ) )
|
||||
{
|
||||
$order = 'post_date ' . $this->configuration['tfb_sort_dir'];
|
||||
}
|
||||
|
||||
if ( $permissionKey )
|
||||
$where = parent::buildWhere();
|
||||
if ( !isset( $this->configuration['widget_feed_use_perms'] ) or $this->configuration['widget_feed_use_perms'] )
|
||||
{
|
||||
$where['container'][] = array( 'forums_forums.password IS NULL AND forums_forums.can_view_others=1' );
|
||||
}
|
||||
|
||||
$posts = \IPS\forums\Topic\Post::getItemsWithPermission( $where, $order, $limit, $permissionKey ?: NULL, $includeHidden );
|
||||
|
||||
if ( count( $posts ) )
|
||||
{
|
||||
return $this->output( $posts, isset( $this->configuration['tfb_title'] ) ? $this->configuration['tfb_title'] : \IPS\Member::loggedIn()->language()->addToStack('block_postFeed_title') );
|
||||
}
|
||||
else
|
||||
{
|
||||
return '';
|
||||
}
|
||||
return $where;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user