ocPortal Developer's Guide: Feedback (rating and commenting)
» Return to Contents
In ocPortal, feedback is any sort of comments, trackbacks or ratings or notes for any resource.
For ocPortal2+, we have overhauled this system so that you can post feedback on any resource on the website, you can even add it to custom resources!
sources/feedback.php
Global_functions_feedback.php
Function summary
|
void
|
init__feedback ()
|
|
array
|
get_details_behind_feedback_code (ID_TEXT content_type, ID_TEXT content_id)
|
|
boolean
|
may_view_content_behind_feedback_code (MEMBER member_id, ID_TEXT content_type, ID_TEXT content_id)
|
|
array
|
embed_feedback_systems (ID_TEXT page_name, ID_TEXT content_id, BINARY allow_rating, integer allow_comments, BINARY allow_trackbacks, BINARY validated, ?MEMBER submitter, mixed content_url, SHORT_TEXT content_title, ?string forum)
|
|
void
|
post_comment_script ()
|
|
tempcode
|
get_rating_box (mixed content_url, ?string content_title, ID_TEXT content_type, ID_TEXT content_id, boolean allow_rating, ?MEMBER submitter)
|
|
tempcode
|
display_rating (mixed content_url, ?string content_title, ID_TEXT content_type, ID_TEXT content_id, ID_TEXT display_tpl, ?MEMBER submitter)
|
|
?array
|
get_rating_simple_array (mixed content_url, ?string content_title, ID_TEXT content_type, ID_TEXT content_id, ID_TEXT form_tpl, ?MEMBER submitter)
|
|
boolean
|
already_rated (array rating_for_types, ID_TEXT content_id)
|
|
void
|
actualise_rating (boolean allow_rating, ID_TEXT content_type, ID_TEXT content_id, mixed content_url, ?string content_title)
|
|
void
|
actualise_specific_rating (?integer rating, ID_TEXT page_name, MEMBER member_id, ID_TEXT content_type, ID_TEXT type, ID_TEXT content_id, ?string content_url, mixed content_title)
|
|
tempcode
|
get_comments (ID_TEXT content_type, boolean allow_comments, ID_TEXT content_id, boolean invisible_if_no_comments, ?string forum, ?string post_warning, ?mixed _comments, boolean explicit_allow, boolean reverse, ?MEMBER highlight_by_user, boolean allow_reviews)
|
|
string
|
extract_topic_identifier (string full_text)
|
|
boolean
|
actualise_post_comment (boolean allow_comments, ID_TEXT content_type, ID_TEXT content_id, mixed content_url, ?string content_title, ?string forum, boolean avoid_captcha, ?BINARY validated, boolean explicit_allow, boolean no_success_message, boolean private)
|
|
void
|
update_spacer_post (boolean allow_comments, ID_TEXT content_type, ID_TEXT content_id, mixed content_url, ?string content_title, ?string forum, ?AUTO_LINK post_id)
|
|
tempcode
|
get_trackbacks (ID_TEXT content_type, ID_TEXT content_id, boolean allow_trackback, ID_TEXT type)
|
|
boolean
|
actualise_post_trackback (boolean allow_trackbacks, ID_TEXT content_type, ID_TEXT content_id)
|
void init__feedback()
Standard code module initialisation function.
Parameters…
(No return value)
function init__feedback()
{
if (!defined('MAX_LIKES_TO_SHOW'))
{
define('MAX_LIKES_TO_SHOW',20);
}
if (!defined('RATING_TYPE_star_choice'))
{
define('RATING_TYPE_star_choice',0);
define('RATING_TYPE_like_dislike',1);
}
global $RATINGS_STRUCTURE;
$RATINGS_STRUCTURE=array();
global $REVIEWS_STRUCTURE;
$REVIEWS_STRUCTURE=array();
}
array get_details_behind_feedback_code(ID_TEXT content_type, ID_TEXT content_id)
Find who submitted a piece of feedbackable content.
Parameters…
| Name |
content_type |
| Description |
Content type |
| Type |
ID_TEXT |
| Name |
content_id |
| Description |
Content ID |
| Type |
ID_TEXT |
Returns…
| Description |
A tuple: Content title (NULL: unknown), Submitter (NULL: unknown), URL (for use within current browser session), URL (for use in emails / sharing), Content meta aware info array |
| Type |
array |
function get_details_behind_feedback_code($content_type,$content_id)
{
require_code('content');
$cma_hook=convert_ocportal_type_codes('feedback_type_code',$content_type,'cma_hook');
if ($cma_hook!='')
{
require_code('hooks/systems/content_meta_aware/'.$cma_hook);
$cma_ob=object_factory('Hook_content_meta_aware_'.$cma_hook);
$info=$cma_ob->info();
list($content_title,$submitter_id,$cma_info,,$content_url,$content_url_email_safe)=content_get_details($cma_hook,$content_id);
return array($content_title,$submitter_id,$content_url,$content_url_email_safe,$cma_info);
}
return array(NULL,NULL,NULL,NULL,NULL);
}
boolean may_view_content_behind_feedback_code(MEMBER member_id, ID_TEXT content_type, ID_TEXT content_id)
Given a particular bit of feedback content, check if the user may access it.
Parameters…
| Name |
member_id |
| Description |
User to check |
| Type |
MEMBER |
| Name |
content_type |
| Description |
Content type |
| Type |
ID_TEXT |
| Name |
content_id |
| Description |
Content ID |
| Type |
ID_TEXT |
Returns…
| Description |
Whether there is permission |
| Type |
boolean |
function may_view_content_behind_feedback_code($member_id,$content_type,$content_id)
{
require_code('content');
$permission_type_code=convert_ocportal_type_codes('feedback_type_code',$content_type,'permissions_type_code');
$module=convert_ocportal_type_codes('feedback_type_code',$content_type,'module');
if ($module=='') $module=$content_id;
$category_id=mixed();
$award_hook=convert_ocportal_type_codes('feedback_type_code',$content_type,'award_hook');
if ($award_hook!='')
{
require_code('hooks/systems/awards/'.$award_hook);
$award_hook_ob=object_factory('Hook_awards_'.$award_hook);
$info=$award_hook_ob->info();
if (isset($info['category_field']))
{
$cma_hook=convert_ocportal_type_codes('award_hook',$award_hook,'cma_hook');
list(,,,$content)=content_get_details($cma_hook,$content_id);
$category_field=$info['category_field'];
if (is_array($category_field))
{
$category_field=array_pop($category_field);
$category_id=$content[$category_field];
if (($award_hook=='catalogue_entry') && (!has_category_access($member_id,'catalogues_catalogue',$GLOBALS['SITE_DB']->query_value('catalogue_categories','c_name',array('id'=>$category_id)))))
return false;
} else
{
$category_id=$content[$category_field];
}
}
}
return ((has_actual_page_access($member_id,$module)) && (($permission_type_code=='') || (is_null($category_id)) || (has_category_access($member_id,$permission_type_code,$category_id))));
}
array embed_feedback_systems(ID_TEXT page_name, ID_TEXT content_id, BINARY allow_rating, integer allow_comments, BINARY allow_trackbacks, BINARY validated, ?MEMBER submitter, mixed content_url, SHORT_TEXT content_title, ?string forum)
Main wrapper function to embed miscellaneous feedback systems into a module output.
Parameters…
| Name |
page_name |
| Description |
The page name |
| Type |
ID_TEXT |
| Name |
content_id |
| Description |
Content ID |
| Type |
ID_TEXT |
| Name |
allow_rating |
| Description |
Whether rating is allowed |
| Type |
BINARY |
| Name |
allow_comments |
| Description |
Whether comments/reviews is allowed (reviews allowed=2) |
| Type |
integer |
| Values restricted to |
0 1 2 |
| Name |
allow_trackbacks |
| Description |
Whether trackbacks are allowed |
| Type |
BINARY |
| Name |
validated |
| Description |
Whether the content is validated |
| Type |
BINARY |
| Name |
submitter |
| Description |
Content owner (NULL: none) |
| Type |
?MEMBER |
| Name |
content_url |
| Description |
URL to view the content |
| Type |
mixed |
| Name |
content_title |
| Description |
Content title |
| Type |
SHORT_TEXT |
| Name |
forum |
| Description |
Forum to post comments in (NULL: site-wide default) |
| Type |
?string |
Returns…
| Description |
Tuple: Rating details, Comment details, Trackback details |
| Type |
array |
function embed_feedback_systems($page_name,$content_id,$allow_rating,$allow_comments,$allow_trackbacks,$validated,$submitter,$content_url,$content_title,$forum)
{
// Sign up original poster for notifications
if (get_forum_type()=='ocf')
{
$auto_monitor_contrib_content=$GLOBALS['OCF_DRIVER']->get_member_row_field($submitter,'m_auto_monitor_contrib_content');
if ($auto_monitor_contrib_content==1)
{
$test=$GLOBALS['SITE_DB']->query_value_null_ok('notifications_enabled','l_setting',array(
'l_member_id'=>$submitter,
'l_notification_code'=>'comment_posted',
'l_code_category'=>$page_name.'_'.$content_id,
));
if (is_null($test))
{
require_code('notifications');
enable_notifications('comment_posted',$page_name.'_'.$content_id,$submitter);
}
}
}
actualise_rating($allow_rating==1,$page_name,$content_id,$content_url,$content_title);
if ((!is_null(post_param('title',NULL))) || ($validated==1))
actualise_post_comment($allow_comments>=1,$page_name,$content_id,$content_url,$content_title,$forum);
//actualise_post_trackback($allow_trackbacks==1,$page_name,$content_id);
$rating_details=get_rating_box($content_url,$content_title,$page_name,$content_id,$allow_rating==1,$submitter);
$comment_details=get_comments($page_name,$allow_comments==1,$content_id,false,$forum,NULL,NULL,false,false,$submitter,$allow_comments==2);
$trackback_details=get_trackbacks($page_name,$content_id,$allow_trackbacks==1);
if (is_object($content_url)) $content_url=$content_url->evaluate();
$serialized_options=serialize(array($page_name,$content_id,$allow_comments,$submitter,$content_url,$content_title,$forum));
$hash=best_hash($serialized_options,get_site_salt()); // A little security, to ensure $serialized_options is not tampered with
// AJAX support
$comment_details->attach(do_template('COMMENT_AJAX_HANDLER',array(
'OPTIONS'=>$serialized_options,
'HASH'=>$hash,
)));
return array($rating_details,$comment_details,$trackback_details);
}
void post_comment_script()
Do an AJAX comment post
Parameters…
(No return value)
tempcode get_rating_box(mixed content_url, ?string content_title, ID_TEXT content_type, ID_TEXT content_id, boolean allow_rating, ?MEMBER submitter)
Get tempcode for doing ratings (sits above get_rating_simple_array)
Parameters…
| Name |
content_url |
| Description |
The URL to where the commenting will pass back to (to put into the comment topic header) (URLPATH or Tempcode) |
| Type |
mixed |
| Name |
content_title |
| Description |
The title to where the commenting will pass back to (to put into the comment topic header) (NULL: don't know, but not first post so not important) |
| Type |
?string |
| Name |
content_type |
| Description |
The type (download, etc) that this rating is for |
| Type |
ID_TEXT |
| Name |
content_id |
| Description |
The ID of the type that this rating is for |
| Type |
ID_TEXT |
| Name |
allow_rating |
| Description |
Whether this resource allows rating (if not, this function does nothing - but it's nice to move out this common logic into the shared function) |
| Type |
boolean |
| Name |
submitter |
| Description |
Content owner (NULL: none) |
| Default value |
|
| Type |
?MEMBER |
Returns…
| Description |
Tempcode for complete rating box |
| Type |
tempcode |
function get_rating_box($content_url,$content_title,$content_type,$content_id,$allow_rating,$submitter=NULL)
{
if ($allow_rating)
{
return display_rating($content_url,$content_title,$content_type,$content_id,'RATING_BOX',$submitter);
}
return new ocp_tempcode();
}
tempcode display_rating(mixed content_url, ?string content_title, ID_TEXT content_type, ID_TEXT content_id, ID_TEXT display_tpl, ?MEMBER submitter)
Display rating using images
Parameters…
| Name |
content_url |
| Description |
The URL to where the commenting will pass back to (to put into the comment topic header) (URLPATH or Tempcode) |
| Type |
mixed |
| Name |
content_title |
| Description |
The title to where the commenting will pass back to (to put into the comment topic header) (NULL: don't know, but not first post so not important) |
| Type |
?string |
| Name |
content_type |
| Description |
The type (download, etc) that this rating is for |
| Type |
ID_TEXT |
| Name |
content_id |
| Description |
The ID of the type that this rating is for |
| Type |
ID_TEXT |
| Name |
display_tpl |
| Description |
The template to use to display the rating box |
| Default value |
RATING_INLINE_STATIC |
| Type |
ID_TEXT |
| Name |
submitter |
| Description |
Content owner (NULL: none) |
| Default value |
|
| Type |
?MEMBER |
Returns…
| Description |
Tempcode for complete trackback box |
| Type |
tempcode |
function display_rating($content_url,$content_title,$content_type,$content_id,$display_tpl='RATING_INLINE_STATIC',$submitter=NULL)
{
$rating_data=get_rating_simple_array($content_url,$content_title,$content_type,$content_id,'RATING_FORM',$submitter);
if (is_null($rating_data))
return new ocp_tempcode();
return do_template($display_tpl,$rating_data);
}
?array get_rating_simple_array(mixed content_url, ?string content_title, ID_TEXT content_type, ID_TEXT content_id, ID_TEXT form_tpl, ?MEMBER submitter)
Get rating information for the specified resource.
Parameters…
| Name |
content_url |
| Description |
The URL to where the commenting will pass back to (to put into the comment topic header) (URLPATH or Tempcode) |
| Type |
mixed |
| Name |
content_title |
| Description |
The title to where the commenting will pass back to (to put into the comment topic header) (NULL: don't know, but not first post so not important) |
| Type |
?string |
| Name |
content_type |
| Description |
The type (download, etc) that this rating is for |
| Type |
ID_TEXT |
| Name |
content_id |
| Description |
The ID of the type that this rating is for |
| Type |
ID_TEXT |
| Name |
form_tpl |
| Description |
The template to use to display the rating box |
| Default value |
RATING_FORM |
| Type |
ID_TEXT |
| Name |
submitter |
| Description |
Content owner (NULL: none) |
| Default value |
|
| Type |
?MEMBER |
Returns…
| Description |
Current rating information (ready to be passed into a template). RATING is the rating (out of 10), NUM_RATINGS s the number of ratings so far, RATING_FORM is the tempcode of the rating box (NULL: rating disabled) |
| Type |
?array |
function get_rating_simple_array($content_url,$content_title,$content_type,$content_id,$form_tpl='RATING_FORM',$submitter=NULL)
{
if (get_option('is_on_rating')=='1')
{
$liked_by=mixed();
// Work out structure first
global $RATINGS_STRUCTURE;
$all_rating_criteria=array();
if (array_key_exists($content_type,$RATINGS_STRUCTURE))
{
$likes=($RATINGS_STRUCTURE[$content_type][0]==RATING_TYPE_like_dislike);
foreach ($RATINGS_STRUCTURE[$content_type][1] as $r=>$t)
{
$rating_for_type=$content_type;
if ($r!='') $rating_for_type.='_'.$r;
$all_rating_criteria[$rating_for_type]=array('TITLE'=>$t,'TYPE'=>$r,'RATING'=>'0');
}
} else
{
$likes=(get_value('likes')==='1');
$all_rating_criteria[$content_type]=array('TITLE'=>'','TYPE'=>'','NUM_RATINGS'=>'0','RATING'=>'0');
}
// Fill in structure
$has_ratings=false;
$overall_num_ratings=0;
$overall_rating=0.0;
foreach ($all_rating_criteria as $i=>$rating_criteria)
{
$rating_for_type=$content_type;
if ($rating_criteria['TYPE']!='') $rating_for_type.='_'.$rating_criteria['TYPE'];
$_num_ratings=$GLOBALS['SITE_DB']->query_select('rating',array('COUNT(*) AS cnt','SUM(rating) AS compound_rating'),array('rating_for_type'=>$rating_for_type,'rating_for_id'=>$content_id),'',1);
$num_ratings=$_num_ratings[0]['cnt'];
if ($num_ratings>0)
{
$rating=$_num_ratings[0]['compound_rating'];
$overall_num_ratings=max($overall_num_ratings,$num_ratings);
if (($num_ratings<MAX_LIKES_TO_SHOW) && ($likes)) // Show likes
{
if (is_null($liked_by)) $liked_by=array();
if (count($liked_by)<MAX_LIKES_TO_SHOW)
{
$_liked_by=$GLOBALS['SITE_DB']->query_select('rating',array('rating_member'),array('rating_for_type'=>$rating_for_type,'rating_for_id'=>$content_id,'rating'=>10));
foreach ($_liked_by as $l)
{
$username=$GLOBALS['FORUM_DRIVER']->get_username($l['rating_member']);
if (!is_null($username))
{
$liked_by[]=array(
'MEMBER_ID'=>strval($l['rating_member']),
'USERNAME'=>$username,
);
if (count($liked_by)==MAX_LIKES_TO_SHOW) break;
}
}
}
}
$calculated_rating=intval(round($rating/floatval($num_ratings)));
$overall_rating+=$calculated_rating;
$all_rating_criteria[$i]=array('NUM_RATINGS'=>integer_format($num_ratings),'RATING'=>make_string_tempcode(strval($calculated_rating)))+$all_rating_criteria[$i];
$GLOBALS['META_DATA']['rating'.(($rating_criteria['TYPE']=='')?'':('_'.$rating_criteria['TYPE']))]=strval($calculated_rating);
$has_ratings=true;
}
}
// Work out possible errors that mighr prevent rating being allowed
$error=new ocp_tempcode();
$rate_url=new ocp_tempcode();
if (($submitter===get_member()) && (!is_guest()))
{
$error=do_lang_tempcode('RATE_DENIED_OWN');
}
elseif (!has_specific_permission(get_member(),'rate',get_page_name()))
{
$error=do_lang_tempcode('RATE_DENIED');
}
elseif (already_rated(array_keys($all_rating_criteria),$content_id))
{
$error=do_lang_tempcode('NORATE');
} else
{
$rate_url=get_self_url();
}
// Templating
$tpl_params=array(
'CONTENT_URL'=>$content_url,
'CONTENT_TITLE'=>$content_title,
'ERROR'=>$error,
'CONTENT_TYPE'=>$content_type,
'ID'=>$content_id,
'URL'=>$rate_url,
'ALL_RATING_CRITERIA'=>$all_rating_criteria,
'OVERALL_NUM_RATINGS'=>integer_format($overall_num_ratings),
'OVERALL_RATING'=>make_string_tempcode(strval(intval($overall_rating/floatval(count($all_rating_criteria))))),
'HAS_RATINGS'=>$has_ratings,
'SIMPLISTIC'=>(count($all_rating_criteria)==1),
'LIKES'=>$likes,
'LIKED_BY'=>$liked_by,
);
$rating_form=do_template($form_tpl,$tpl_params);
return $tpl_params+array(
'RATING_FORM'=>$rating_form,
);
}
return NULL;
}
boolean already_rated(array rating_for_types, ID_TEXT content_id)
Find whether you have rated the specified resource before.
Parameters…
| Name |
rating_for_types |
| Description |
List of types (download, etc) that this rating is for. All need to be rated for it to return true. |
| Type |
array |
| Name |
content_id |
| Description |
The ID of the type that this rating is for |
| Type |
ID_TEXT |
Returns…
| Description |
Whether the resource has already been rated |
| Type |
boolean |
function already_rated($rating_for_types,$content_id)
{
$more=(!is_guest())?' OR rating_member='.strval((integer)get_member()):'';
$for_types='';
foreach ($rating_for_types as $rating_for_type)
{
if ($for_types!='') $for_types.=' OR ';
$for_types.=db_string_equal_to('rating_for_type',$rating_for_type);
}
$query='SELECT COUNT(*) FROM '.get_table_prefix().'rating WHERE ('.$for_types.') AND '.db_string_equal_to('rating_for_id',$content_id);
$query.=' AND (';
if (!$GLOBALS['IS_ACTUALLY_ADMIN'])
{
$query.='rating_ip=\''.get_ip_address().'\'';
} else
{
$query.='1=0';
}
$query.=$more.')';
$has_rated=$GLOBALS['SITE_DB']->query_value_null_ok_full($query);
return ($has_rated==count($rating_for_types));
}
void actualise_rating(boolean allow_rating, ID_TEXT content_type, ID_TEXT content_id, mixed content_url, ?string content_title)
Actually adds a rating to the specified resource.It performs full checking of inputs, and will log a hackattack if the rating is not between 1 and 10.
Parameters…
| Name |
allow_rating |
| Description |
Whether this resource allows rating (if not, this function does nothing - but it's nice to move out this common logic into the shared function) |
| Type |
boolean |
| Name |
content_type |
| Description |
The type (download, etc) that this rating is for |
| Type |
ID_TEXT |
| Name |
content_id |
| Description |
The ID of the type that this rating is for |
| Type |
ID_TEXT |
| Name |
content_url |
| Description |
The URL to where the commenting will pass back to (to put into the comment topic header) (URLPATH or Tempcode) |
| Type |
mixed |
| Name |
content_title |
| Description |
The title to where the commenting will pass back to (to put into the comment topic header) (NULL: don't know, but not first post so not important) |
| Type |
?string |
(No return value)
function actualise_rating($allow_rating,$content_type,$content_id,$content_url,$content_title)
{
if ((get_option('is_on_rating')=='0') || (!$allow_rating)) return;
global $RATINGS_STRUCTURE;
$all_rating_criteria=array();
if (array_key_exists($content_type,$RATINGS_STRUCTURE))
{
$all_rating_criteria=array_keys($RATINGS_STRUCTURE[$content_type][1]);
} else
{
$all_rating_criteria[]='';
}
foreach ($all_rating_criteria as $type)
{
// Has there actually been any rating?
$rating=post_param_integer('rating__'.$content_type.'__'.$type.'__'.$content_id,NULL);
if (is_null($rating)) return;
actualise_specific_rating($rating,get_page_name(),get_member(),$content_type,$type,$content_id,$content_url,$content_title);
// Ok, so just thank 'em
attach_message(do_lang_tempcode('THANKYOU_FOR_RATING'),'inform');
}
if ((!is_guest()) && (addon_installed('points')))
{
require_code('points');
$_count=point_info(get_member());
$count=array_key_exists('points_gained_rating',$_count)?$_count['points_gained_rating']:0;
$GLOBALS['FORUM_DRIVER']->set_custom_field(get_member(),'points_gained_rating',$count+1);
}
}
void actualise_specific_rating(?integer rating, ID_TEXT page_name, MEMBER member_id, ID_TEXT content_type, ID_TEXT type, ID_TEXT content_id, ?string content_url, mixed content_title)
Implement a rating at the quantum level.
Parameters…
| Name |
rating |
| Description |
Rating given (NULL: unrate) |
| Type |
?integer |
| Value range |
1 10 |
| Name |
page_name |
| Description |
The page name the rating is on |
| Type |
ID_TEXT |
| Name |
member_id |
| Description |
The member doing the rating |
| Type |
MEMBER |
| Name |
content_type |
| Description |
The type (download, etc) that this rating is for |
| Type |
ID_TEXT |
| Name |
type |
| Description |
The second level type (probably blank) |
| Type |
ID_TEXT |
| Name |
content_id |
| Description |
The ID of the type that this rating is for |
| Type |
ID_TEXT |
| Name |
content_url |
| Description |
The title to where the commenting will pass back to (to put into the comment topic header) (NULL: don't know) |
| Type |
?string |
| Name |
content_title |
| Description |
The URL to where the commenting will pass back to (to put into the comment topic header) (URLPATH or Tempcode) |
| Type |
mixed |
(No return value)
function actualise_specific_rating($rating,$page_name,$member_id,$content_type,$type,$content_id,$content_url,$content_title)
{
if (!is_null($rating))
{
if (($rating>10) || ($rating<1)) log_hack_attack_and_exit('VOTE_CHEAT');
}
$rating_for_type=$content_type.(($type=='')?'':('_'.$type));
if (!has_specific_permission($member_id,'rate',$page_name)) return;
if (!is_null($rating))
{
if (already_rated(array($rating_for_type),$content_id))
{
// Delete, in preparation for re-rating
$GLOBALS['SITE_DB']->query_delete('rating',array('rating_for_type'=>$rating_for_type,'rating_for_id'=>$content_id,'rating_member'=>$member_id,'rating_ip'=>get_ip_address()));
}
}
list($_content_title,$submitter,,$safe_content_url,$cma_info)=get_details_behind_feedback_code($content_type,$content_id);
if (is_null($content_title)) $content_title=$_content_title;
if (($member_id===$submitter) && (!is_guest($member_id))) return;
if (!is_null($rating))
{
$GLOBALS['SITE_DB']->query_insert('rating',array('rating_for_type'=>$rating_for_type,'rating_for_id'=>$content_id,'rating_member'=>$member_id,'rating_ip'=>get_ip_address(),'rating_time'=>time(),'rating'=>$rating));
} else
{
$GLOBALS['SITE_DB']->query_delete('rating',array('rating_for_type'=>$rating_for_type,'rating_for_id'=>$content_id,'rating_member'=>$member_id,'rating_ip'=>get_ip_address()));
}
// Top rating / liked
if (($rating===10) && ($type==''))
{
$content_type_title=$content_type;
if ((!is_null($cma_info)) && (isset($cma_info['content_type_label'])))
{
$content_type_title=do_lang($cma_info['content_type_label']);
}
// Special case. Would prefer not to hard-code, but important for usability
if (($content_type=='post') && ($content_title=='') && (get_forum_type()=='ocf'))
{
$content_title=do_lang('POST_IN',$GLOBALS['FORUM_DB']->query_value('f_topics','t_cache_first_title',array('id'=>$GLOBALS['FORUM_DB']->query_value('f_posts','p_topic_id',array('id'=>intval($content_id))))));
}
if ((!is_null($submitter)) && (!is_guest($submitter)))
{
// Give points
if ($member_id!=$submitter)
{
if (addon_installed('points'))
{
require_code('points2');
require_lang('points');
system_gift_transfer(do_lang('CONTENT_LIKED'),intval(get_option('points_if_liked')),$submitter);
}
}
// Notification
require_code('notifications');
$subject=do_lang('CONTENT_LIKED_NOTIFICATION_MAIL_SUBJECT',get_site_name(),($content_title=='')?ocp_mb_strtolower($content_type_title):$content_title);
$rendered_award='';
$award_hook=convert_ocportal_type_codes('feedback_type_code',$content_type,'award_hook');
if ($award_hook!='')
{
require_code('hooks/systems/awards/'.$award_hook);
$award_ob=object_factory('Hook_awards_'.$award_hook);
$award_content_row=content_get_row($content_id,$award_ob->info());
if (!is_null($award_content_row))
{
$rendered_award=preg_replace('#&keep_\w+=[^&]*#','',static_evaluate_tempcode($award_ob->run($award_content_row,'_SEARCH')));
}
}
$mail=do_lang('CONTENT_LIKED_NOTIFICATION_MAIL',comcode_escape(get_site_name()),comcode_escape(($content_title=='')?ocp_mb_strtolower($content_type_title):$content_title),array(comcode_escape(is_object($safe_content_url)?$safe_content_url->evaluate():$safe_content_url),$rendered_award,comcode_escape($GLOBALS['FORUM_DRIVER']->get_username(get_member()))));
dispatch_notification('like',NULL,$subject,$mail,array($submitter));
}
// Put on activity wall / whatever
if (may_view_content_behind_feedback_code($GLOBALS['FORUM_DRIVER']->get_guest_id(),$content_type,$content_id))
{
if (is_null($submitter)) $submitter=$GLOBALS['FORUM_DRIVER']->get_guest_id();
$activity_type=((is_null($submitter)) || (is_guest($submitter)))?'_ACTIVITY_LIKES':'ACTIVITY_LIKES';
if ($content_title=='')
{
syndicate_described_activity($activity_type.'_UNTITLED',ocp_mb_strtolower($content_type_title),$content_type_title,'',url_to_pagelink(is_object($safe_content_url)?$safe_content_url->evaluate():$safe_content_url),'','',convert_ocportal_type_codes('feedback_type_code',$content_type,'addon_name'),1,NULL,false,$submitter);
} else
{
syndicate_described_activity($activity_type,$content_title,ocp_mb_strtolower($content_type_title),$content_type_title,url_to_pagelink(is_object($safe_content_url)?$safe_content_url->evaluate():$safe_content_url),'','',convert_ocportal_type_codes('feedback_type_code',$content_type,'addon_name'),1,NULL,false,$submitter);
}
}
}
// Enter them for a prize draw to win a free jet
// NOT IMPLEMENTED- Anyone want to donate the jet?
}
tempcode get_comments(ID_TEXT content_type, boolean allow_comments, ID_TEXT content_id, boolean invisible_if_no_comments, ?string forum, ?string post_warning, ?mixed _comments, boolean explicit_allow, boolean reverse, ?MEMBER highlight_by_user, boolean allow_reviews)
Get the tempcode containing all the comments posted, and the comments posting form for the specified resource.
Parameters…
| Name |
content_type |
| Description |
The type (download, etc) that this commenting is for |
| Type |
ID_TEXT |
| Name |
allow_comments |
| Description |
Whether this resource allows comments (if not, this function does nothing - but it's nice to move out this common logic into the shared function) |
| Type |
boolean |
| Name |
content_id |
| Description |
The ID of the type that this commenting is for |
| Type |
ID_TEXT |
| Name |
invisible_if_no_comments |
| Description |
Whether the comment box will be invisible if there are not yet any comments (and you're not staff) |
| Default value |
boolean-false |
| Type |
boolean |
| Name |
forum |
| Description |
The name of the forum to use (NULL: default comment forum) |
| Default value |
|
| Type |
?string |
| Name |
post_warning |
| Description |
The default post to use (NULL: standard courtesy warning) |
| Default value |
|
| Type |
?string |
| Name |
_comments |
| Description |
The raw comment array (NULL: lookup). This is useful if we want to pass it through a filter |
| Default value |
|
| Type |
?mixed |
| Name |
explicit_allow |
| Description |
Whether to skip permission checks |
| Default value |
boolean-false |
| Type |
boolean |
| Name |
reverse |
| Description |
Whether to reverse the posts |
| Default value |
boolean-false |
| Type |
boolean |
| Name |
highlight_by_user |
| Description |
User to highlight the posts of (NULL: none) |
| Default value |
|
| Type |
?MEMBER |
| Name |
allow_reviews |
| Description |
Whether to allow ratings along with the comment (like reviews) |
| Default value |
boolean-false |
| Type |
boolean |
Returns…
| Description |
The tempcode for the comment topic |
| Type |
tempcode |
string extract_topic_identifier(string full_text)
Topic titles/descriptions (depending on forum driver) are encoded for both human readable data, and a special ID code: this will extract just the ID code, or return the whole thing if no specific pattern match
Parameters…
| Name |
full_text |
| Description |
Potentially complex topic title |
| Type |
string |
Returns…
| Description |
Simplified topic title |
| Type |
string |
boolean actualise_post_comment(boolean allow_comments, ID_TEXT content_type, ID_TEXT content_id, mixed content_url, ?string content_title, ?string forum, boolean avoid_captcha, ?BINARY validated, boolean explicit_allow, boolean no_success_message, boolean private)
Add comments to the specified resource.
Parameters…
| Name |
allow_comments |
| Description |
Whether this resource allows comments (if not, this function does nothing - but it's nice to move out this common logic into the shared function) |
| Type |
boolean |
| Name |
content_type |
| Description |
The type (download, etc) that this commenting is for |
| Type |
ID_TEXT |
| Name |
content_id |
| Description |
The ID of the type that this commenting is for |
| Type |
ID_TEXT |
| Name |
content_url |
| Description |
The URL to where the commenting will pass back to (to put into the comment topic header) (URLPATH or Tempcode) |
| Type |
mixed |
| Name |
content_title |
| Description |
The title to where the commenting will pass back to (to put into the comment topic header) (NULL: don't know, but not first post so not important) |
| Type |
?string |
| Name |
forum |
| Description |
The name of the forum to use (NULL: default comment forum) |
| Default value |
|
| Type |
?string |
| Name |
avoid_captcha |
| Description |
Whether to not require a captcha |
| Default value |
boolean-false |
| Type |
boolean |
| Name |
validated |
| Description |
Whether the post is validated (NULL: unknown, find whether it needs to be marked unvalidated initially). This only works with the OCF driver (hence is the last parameter). |
| Default value |
|
| Type |
?BINARY |
| Name |
explicit_allow |
| Description |
Whether to force allowance |
| Default value |
boolean-false |
| Type |
boolean |
| Name |
no_success_message |
| Description |
Whether to skip a success message |
| Default value |
boolean-false |
| Type |
boolean |
| Name |
private |
| Description |
Whether posts made should not be shared |
| Default value |
boolean-false |
| Type |
boolean |
Returns…
| Description |
Whether a hidden post has been made |
| Type |
boolean |
void update_spacer_post(boolean allow_comments, ID_TEXT content_type, ID_TEXT content_id, mixed content_url, ?string content_title, ?string forum, ?AUTO_LINK post_id)
Update the spacer post of a comment topic, after an edit.
Parameters…
| Name |
allow_comments |
| Description |
Whether this resource allows comments (if not, this function does nothing - but it's nice to move out this common logic into the shared function) |
| Type |
boolean |
| Name |
content_type |
| Description |
The type (download, etc) that this commenting is for |
| Type |
ID_TEXT |
| Name |
content_id |
| Description |
The ID of the type that this commenting is for |
| Type |
ID_TEXT |
| Name |
content_url |
| Description |
The URL to where the commenting will pass back to (to put into the comment topic header) (URLPATH or Tempcode) |
| Type |
mixed |
| Name |
content_title |
| Description |
The title to where the commenting will pass back to (to put into the comment topic header) (NULL: don't know, but not first post so not important) |
| Type |
?string |
| Name |
forum |
| Description |
The name of the forum to use (NULL: default comment forum) |
| Default value |
|
| Type |
?string |
| Name |
post_id |
| Description |
ID of spacer post (NULL: unknown) |
| Default value |
|
| Type |
?AUTO_LINK |
(No return value)
function update_spacer_post($allow_comments,$content_type,$content_id,$content_url,$content_title,$forum=NULL,$post_id=NULL)
{
if ((get_option('is_on_comments')=='0') || (!$allow_comments)) return;
if (get_forum_type()!='ocf') return;
$home_link=is_null($content_title)?new ocp_tempcode():hyperlink($content_url,escape_html($content_title));
if (is_null($forum)) $forum=get_option('comments_forum_name');
if (!is_integer($forum))
{
$forum_id=$GLOBALS['FORUM_DRIVER']->forum_id_from_name($forum);
if (is_null($forum_id)) return;
}
else $forum_id=(integer)$forum;
$content_title=strip_comcode($content_title);
if (is_null($post_id))
{
$topic_id=$GLOBALS['FORUM_DRIVER']->find_topic_id_for_topic_identifier($forum_id,$content_type.'_'.$content_id);
if (is_null($topic_id)) return;
$post_id=$GLOBALS['FORUM_DB']->query_value_null_ok('f_posts','MIN(id)',array('p_topic_id'=>$topic_id));
if (is_null($post_id)) return;
} else
{
$topic_id=$GLOBALS['FORUM_DB']->query_value('f_posts','p_topic_id',array('id'=>$post_id));
}
$spacer_title=is_null($content_title)?($content_type.'_'.$content_id):($content_title.' (#'.$content_type.'_'.$content_id.')');
$spacer_post='[semihtml]'.do_lang('SPACER_POST',$home_link->evaluate(),'','',get_site_default_lang()).'[/semihtml]';
if (get_forum_type()=='ocf')
{
require_code('ocf_posts_action3');
ocf_edit_post($post_id,1,is_null($content_title)?$spacer_title:$content_title,$spacer_post,0,0,NULL,false,false,'',false);
require_code('ocf_topics_action2');
ocf_edit_topic($topic_id,do_lang('COMMENT').': #'.$content_type.'_'.$content_id,NULL,NULL,NULL,NULL,NULL,NULL,'',NULL,$home_link->evaluate(),false);
}
}
tempcode get_trackbacks(ID_TEXT content_type, ID_TEXT content_id, boolean allow_trackback, ID_TEXT type)
Get the tempcode containing all the trackbacks received, and the trackback posting form for the specified resource.
Parameters…
| Name |
content_type |
| Description |
The type (download, etc) that this trackback is for |
| Type |
ID_TEXT |
| Name |
content_id |
| Description |
The ID of the type that this trackback is for |
| Type |
ID_TEXT |
| Name |
allow_trackback |
| Description |
Whether this resource allows trackback (if not, this function does nothing - but it's nice to move out this common logic into the shared function) |
| Type |
boolean |
| Name |
type |
| Description |
The type of details being fetched (currently: blank or XML) |
| Default value |
|
| Type |
ID_TEXT |
Returns…
| Description |
Tempcode for complete trackback box |
| Type |
tempcode |
function get_trackbacks($content_type,$content_id,$allow_trackback,$type='')
{
if (($type!='') && ($type!='xml')) $type='';
if ((get_option('is_on_trackbacks')=='1') && ($allow_trackback))
{
require_lang('trackbacks');
$trackbacks=$GLOBALS['SITE_DB']->query_select('trackbacks',array('*'),array('trackback_for_type'=>$content_type,'trackback_for_id'=>$content_id),'ORDER BY trackback_time DESC',300);
$content=new ocp_tempcode();
$items=new ocp_tempcode();
global $CURRENT_SCREEN_TITLE;
if (is_null($CURRENT_SCREEN_TITLE)) $CURRENT_SCREEN_TITLE='';
foreach ($trackbacks as $value)
{
if ($type=='')
{
$trackback_rendered=do_template('TRACKBACK',array(
'_GUID'=>'128e21cdbc38a3037d083f619bb311ae',
'ID'=>strval($value['id']),
'TIME_RAW'=>strval($value['trackback_time']),
'TIME'=>get_timezoned_date($value['trackback_time']),
'URL'=>$value['trackback_url'],
'TITLE'=>$value['trackback_title'],
'EXCERPT'=>$value['trackback_excerpt'],
'NAME'=>$value['trackback_name'],
));
$content->attach($trackback_rendered);
} else
{
$trackback_rendered_xml=do_template('TRACKBACK_XML',array(
'_GUID'=>'a3fa8ab9f0e58bf2ad88b0980c186245',
'TITLE'=>$value['trackback_title'],
'LINK'=>$value['trackback_url'],
'EXCERPT'=>$value['trackback_excerpt'],
));
$items->attach($trackback_rendered_xml);
}
}
if ((count($trackbacks)<1) && ($type=='xml'))
{
$trackback_xml_error=do_template('TRACKBACK_XML_ERROR',array(
'_GUID'=>'945e2fcb510816caf323ba3704209430',
'TRACKBACK_ERROR'=>do_lang_tempcode('NO_TRACKBACKS'),
));
$content->attach($trackback_xml_error);
}
if ($type=='')
{
$output=do_template('TRACKBACK_WRAPPER',array(
'_GUID'=>'1bc2c42a54fdf4b0a10e8e1ea45f6e4f',
'TRACKBACKS'=>$content,
'TRACKBACK_PAGE'=>$content_type,
'TRACKBACK_ID'=>$content_id,
'TRACKBACK_TITLE'=>$CURRENT_SCREEN_TITLE,
));
} else
{
$trackback_xml=do_template('TRACKBACK_XML_LISTING',array(
'_GUID'=>'3bff402f15395f4648a2b5af33de8285',
'ITEMS'=>$items,
'LINK_PAGE'=>$content_type,
'LINK_ID'=>$content_id,
));
$content->attach($trackback_xml);
$output=$content;
}
} else
{
$output=new ocp_tempcode();
}
return $output;
}
boolean actualise_post_trackback(boolean allow_trackbacks, ID_TEXT content_type, ID_TEXT content_id)
Add trackbacks to the specified resource.
Parameters…
| Name |
allow_trackbacks |
| Description |
Whether this resource allows trackback (if not, this function does nothing - but it's nice to move out this common logic into the shared function) |
| Type |
boolean |
| Name |
content_type |
| Description |
The type (download, etc) that this trackback is for |
| Type |
ID_TEXT |
| Name |
content_id |
| Description |
The ID of the type that this trackback is for |
| Type |
ID_TEXT |
Returns…
| Description |
Whether trackbacks are on |
| Type |
boolean |
function actualise_post_trackback($allow_trackbacks,$content_type,$content_id)
{
if ((get_option('is_on_trackbacks')=='0') || (!$allow_trackbacks)) return false;
$url=either_param('url',NULL);
if (is_null($url)) return false;
$title=either_param('title',$url);
$excerpt=either_param('excerpt','');
$name=either_param('blog_name',$url);
$GLOBALS['SITE_DB']->query_insert('trackbacks',array('trackback_for_type'=>$content_type,'trackback_for_id'=>$content_id,'trackback_ip'=>get_ip_address(),'trackback_time'=>time(),'trackback_url'=>$url,'trackback_title'=>$title,'trackback_excerpt'=>$excerpt,'trackback_name'=>$name));
return true;
}
Tutorial - Adding Feedback to a Custom Resource
To add ratings, comments, and staff notes to a module, add the following code snippets…
In the install function, in the table creation…
Code (php)
'allow_rating'=>'BINARY',
'allow_comments'=>'BINARY',
'notes'=>'LONG_TEXT',
In the run function…
Code (php)
require_code('feedback');
In the get_X_form_fields function header…
Code (php)
, $allow_rating=true, $allow_comments=true, $notes=''
In the get_X_form_fields function…
Code (php)
$fields->attach(feedback_fields($allow_rating, $allow_comments, $notes));
In the _ad and __ed functions…
Code (php)
$allow_rating=post_param_integer('allow_rating',0);
$allow_comments=post_param_integer('allow_comments',0);
$notes=post_param('notes');
In the _ed function, where the get_X_form_fields function is called…
Code (php)
, $myrow['allow_rating'], $myrow['allow_comments'], $myrow['notes']
In the _ad and __ed functions, where the add/edit backend function is called…
Code (php)
, $allow_rating, $allow_comments, $notes
In the add/edit backend function header…
Code (php)
, $allow_rating, $allow_comments, $notes
In the add/edit backend function query_insert call…
Code (php)
'allow_rating'=>$allow_rating,'allow_comments'=>$allow_comments,'notes'=>$notes,
In the delete backend function…
Code (php)
$GLOBALS['SITE_DB']->query_delete('rating',array('rating_for_type'=>get_page_name
(),'rating_for_id'=>$id));
In the function for the type that can be commented/rated…
Code (php)
do_rating($myrow['allow_rating'],get_page_name(), $id);
do_comments($myrow['allow_comments'],get_page_name(), $id, $self_url, $self_title);
$rating_details=get_rating_text(get_page_name(), $id);
$comment_details=get_comment_details(get_page_name(), $myrow['allow_comments'], $id);
0 reviews: Unrated (average)
There have been no comments yet