Incorrect accessYou cannot access this file directly. If you have recently upgraded, make sure you upgraded all the relevant files."; exit(); } class classes_comments_bootstrap { static private $_app; /** * Construct */ static public function controller( $app=null ) { if ( strstr( $app, '-' ) ) { list( $app, $key ) = explode( '-', $app ); } $_file = IPSLib::getAppDir( $app ) . '/extensions/comments/' . $key . '.php'; $_class = 'comments_' . $app . '_' . $key; if ( file_exists( $_file ) ) { require_once( $_file ); if ( class_exists( $_class ) ) { self::$_app = new $_class(); self::$_app->init(); } else { throw new Exception( "No comment class available for $app" ); } } else { throw new Exception( "No comment class available for $app" ); } /* Load up language file */ $registry = ipsRegistry::instance(); $registry->getClass('class_localization')->loadLanguageFile( array( 'public_comments' ), 'core' ); return self::$_app; } } abstract class classes_comments_renderer { /**#@+ * Registry Object Shortcuts * * @var object */ protected $registry; protected $DB; protected $settings; protected $request; protected $lang; protected $member; protected $cache; /**#@-*/ protected $_cache = array(); /** * App object * * @param object */ protected $_app; /** * Local settings object * * @param array */ protected $_settings; /** * Constructor * * @param ipsRegistry $registry * @param string App key to use will use current app if none specified * @return void */ public function init() { $this->lang->loadLanguageFile( array( 'public_topic' ), 'forums' ); /* Init some data */ $this->_settings = $this->settings(); $this->qpids = IPSCookie::get( 'comment_pids' ); $this->request['selectedpids'] = IPSCookie::get( 'commentmodpids' ); $this->request['selectedpidcount'] = intval( count( preg_split( "/,/", $this->request['commentmodpids'], -1, PREG_SPLIT_NO_EMPTY ) ) ); IPSCookie::set('commentmodpids', '', 0); } /** * Fetch setting * * @param string Setting key * @return mixed Setting value OR null */ public function fetchSetting( $k, $parent=array() ) { $setting = ( isset( $this->_settings[ $k ] ) ) ? $this->_settings[ $k ] : null; if ( $setting !== null && is_array( $parent ) && count( $parent ) ) { foreach( $parent as $_k => $_v ) { $setting = str_replace( '#{' . $_k . '}', $_v, $setting ); } } return $setting; } /** * Fetch formatted comments with HTML wrap * * @param mixed INT, parent ID, array, image data * @param array Filters * @return string */ public function fetchFormatted( $parent, $filters=array() ) { /* Check parent */ if ( is_numeric( $parent ) ) { $parent = $this->fetchParent( $parent ); } /* Set filters */ $filters = $this->_setFilters( $filters ); $_remap = $this->remapKeys(); $parent = $this->remapFromLocal( $parent, 'parent' ); $preReply = ''; $data = array( 'counts' => array( 'commentTotal' => 0, 'thisPageCount' => 0, 'perPage' => $filters['limit'], 'curStart' => $filters['offset'] ) ); /* Fetch raw data */ $comments = $this->fetch( $parent, $filters ); if ( $comments === false ) { return false; } /* Can comment */ $parent['_canComment'] = ( $this->can( 'add', array( 'comment_parent_id' => $parent['parent_id'] ) ) === true ) ? true : false; /* Can moderate? */ $parent['_canModerate'] = ( $this->can( 'moderate', array( 'comment_parent_id' => $parent['parent_id'] ) ) === true ) ? true : false; /* Got something? */ if ( is_array( $comments ) AND count( $comments ) ) { $total = $this->count( $parent ); /* Add in addtional data */ if ( $total ) { $data['counts']['commentTotal'] = $total; $data['counts']['thisPageCount'] = count( $comments ); } $pages = $this->registry->output->generatePagination( array( 'totalItems' => $total, 'itemsPerPage' => $filters['limit'], 'currentStartValue' => $filters['offset'], 'baseUrl' => sprintf( $this->fetchSetting('urls-showParent', $parent), $parent['parent_id'] ), 'base' => 'public', 'seoTitle' => $parent['parent_seo_title'], 'seoTemplate' => $this->seoTemplate() ) ); } $data['settings'] = $this->settings(); $data['canModerate'] = ( $parent['_canModerate'] ) ? true : false; $data['fromApp'] = $this->whoAmI(); $data['_app'] = preg_replace( '#^(.+?)(?:-.*|$)#', '\\1', $this->whoAmI() ); /* Got a reply? */ if ( isset( $this->request['_rcid'] ) AND $this->request['_rcid'] ) { $preReply = $this->fetchReply( $parent['parent_id'], $this->request['_rcid'], $this->memberData ); } return $this->registry->output->getTemplate( $this->skin() )->commentsList( $comments, $data, $pages, $parent, $preReply ); } /** * Fetch a total count of comments we can see * * @param mixed parent Id or parent array * @return int */ public function count( $parent ) { /* Check parent */ if ( is_numeric( $parent ) ) { $parent = $this->fetchParent( $parent ); } $_remap = $this->remapKeys(); $parent = $this->remapFromLocal( $parent, 'parent' ); /* Check it out */ $q = ( $this->can( 'moderate', array( 'comment_parent_id' => $parent['parent_id'] ) ) ) ? '' : ' AND ' . $_remap['comment_approved'] . '=1'; /* Fetch a total */ $total = $this->DB->buildAndFetch( array( 'select' => 'count(*) as total', 'from' => $this->table(), 'where' => $_remap['comment_parent_id'] . '=' . $parent['parent_id'] . $q ) ); return $total['total']; } /** * Fetch a single formatted comment. Useful for ajaxish functions. * * @param mixed INT, image ID, array, image data * @param int Comment ID * @return string */ public function fetchFormattedSingle( $parent, $commentId ) { /* Got comment id? */ $filters['comment_id'] = intval( $commentId ); /* Check parent */ if ( is_numeric( $parent ) ) { $parent = $this->fetchParent( $parent ); } /* Set filters */ $filters = $this->_setFilters( $filters ); $parent = $this->remapFromLocal( $parent, 'parent' ); $_remap = $this->remapKeys(); /* Fetch raw data */ $comments = $this->fetch( $parent, $filters ); $comment = array_pop( $comments ); if ( $comment === null ) { return false; } /* Can moderate? */ $parent['_canModerate'] = $this->can( 'moderate', array( 'comment_parent_id' => $parent['parent_id'] ) ); $data['settings'] = $this->settings(); $data['fromApp'] = $this->whoAmI(); $data['_app'] = preg_replace( '#^(.+?)(?:-.*|$)#', '\\1', $this->whoAmI() ); return $this->registry->output->getTemplate( $this->skin() )->comment( $comment, $parent, $data ); } /** * Fetch a comment by ID (no perm checks ( * * @param int Comment ID */ public function fetchById( $commentId ) { $_remap = $this->remapKeys(); if ( ! array_key_exists( $commentId, $this->_cache ) ) { $comment = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => $this->table(), 'where' => $_remap['comment_id'] . '=' . intval( $commentId ) ) ); $comment = $this->remapFromLocal( (array) $comment ); $this->_cache[ $comment['comment_id'] ] = $comment; } return $this->_cache[ $commentId ]; } /** * Fetch raw comments * * @param mixed parent ID * @param array Filters * @return array */ public function fetch( $parent, $filters=array() ) { /* Check parent */ if ( is_numeric( $parent ) ) { $parent = $this->fetchParent( $parent ); } /* Set filters */ $filters = $this->_setFilters( $filters ); $parent = $this->remapFromLocal( $parent, 'parent' ); $comments = array(); $q = array(); $_remap = $this->remapKeys(); /* unpack cache */ $this->_unpackRepCache(); /* Joins */ $_post_joins = array( array( 'type' => 'left', 'select' => 'm.*', 'where' => 'm.member_id=c.' . $_remap['comment_author_id'], 'from' => array( 'members' => 'm' ) ), array( 'type' => 'left', 'select' => 'pc.*', 'where' => 'pc.member_id=m.member_id', 'from' => array( 'pfields_content' => 'pc' ) ), array( 'type' => 'left', 'select' => 'pp.*', 'where' => 'pp.pp_member_id=m.member_id', 'from' => array( 'profile_portal' => 'pp' ) ) ); /* Reputation system enabled? */ if ( $this->settings['reputation_enabled'] ) { /* Add the join to figure out if the user has already rated the post */ $_post_joins[] = $this->registry->repCache->getUserHasRatedJoin( $_remap['comment_id'], 'c.' . $_remap['comment_id'], $this->whoAmI() ); /* Add the join to figure out the total ratings for each post */ if( $this->settings['reputation_show_content'] ) { $_post_joins[] = $this->registry->repCache->getTotalRatingJoin( $_remap['comment_id'], 'c.' . $_remap['comment_id'], $this->whoAmI() ); } } /* Start of query */ $q[] = "c." . $_remap['comment_parent_id'] . "=" . $parent['parent_id']; /* Can moderate? */ if ( ! $this->can( 'moderate', array( 'comment_parent_id' => $parent['parent_id'] ) ) ) { $q[] = $_remap['comment_approved'] . '=1'; } /* Fetching a single comment? */ if ( isset( $filters['comment_id'] ) ) { if ( is_numeric( $filters['comment_id'] ) ) { $q[] = $_remap['comment_id'] . '=' . intval( $filters['comment_id'] ); } else if ( is_array( $filters['comment_id'] ) ) { $q[] = $_remap['comment_id'] . ' IN(' . implode( ",", IPSLib::cleanIntArray( $filters['comment_id'] ) ) . ')'; } } /* Set up parser */ IPSText::getTextClass( 'bbcode' )->parse_html = 0; IPSText::getTextClass( 'bbcode' )->parse_wordwrap = $this->settings['post_wordwrap']; IPSText::getTextClass( 'bbcode' )->parse_nl2br = 1; IPSText::getTextClass( 'bbcode' )->parse_bbcode = 1; IPSText::getTextClass( 'bbcode' )->parsing_section = $this->whoAmI() . '_comment'; /* Fetch the data */ $this->DB->build( array( 'select' => 'c.*', 'from' => array( $this->table() => 'c' ), 'where' => implode( ' AND ', $q ), 'order' => $_remap[ $filters['sortKey'] ] . ' ' . $_remap[ $filters['sortOrder'] ], 'limit' => array( $filters['offset'], $filters['limit'] ), 'add_join' => $_post_joins ) ); $oq = $this->DB->execute(); /* Go get 'em bawss */ while( $row = $this->DB->fetch( $oq ) ) { /* Set up parser */ IPSText::getTextClass( 'bbcode' )->parsing_mgroup = $row['member_group_id']; IPSText::getTextClass( 'bbcode' )->parsing_mgroup_others = $row['mgroup_others']; /* Remap */ $row = $this->remapFromLocal( $row ); /* cache in generic state */ $this->_cache[ $row['comment_id'] ] = $row; /* Preserve original DB formatting */ $row['_db_comment'] = $row['comment_text']; /* Parse for display */ $row['comment_text'] = IPSText::getTextClass('bbcode')->preDisplayParse( $row['comment_text'] ); /* Can moderate? */ if ( $this->can( 'moderate', array( 'comment_parent_id' => $parent['parent_id'] ) ) ) { if ( $this->request['selectedpids'] ) { if ( strstr( ','.$this->request['selectedpids'].',', ','.$row['pid'].',' ) ) { $row['_pidChecked'] = true; } } } /* Ignored users */ foreach( $this->member->ignored_users as $_i ) { if( $_i['ignore_topics'] AND $_i['ignore_ignore_id'] == $row['author_id'] ) { if ( ! strstr( $this->settings['cannot_ignore_groups'], ','.$row['member_group_id'].',' ) ) { $row['_ignored'] = true; break; } } } /* Reputation */ if ( $this->settings['reputation_enabled'] ) { $row['pp_reputation_points'] = $row['pp_reputation_points'] ? $row['pp_reputation_points'] : 0; $row['has_given_rep'] = $row['has_given_rep'] ? $row['has_given_rep'] : 0; $row['rep_points'] = $row['rep_points'] ? $row['rep_points'] : 0; } /* Edit button */ $row['_canEdit'] = $this->can('edit', $row); /* Edit button */ $row['_canDelete'] = $this->can('delete', $row); /* Report link */ if ( $this->fetchSetting('urls-report', $parent) ) { $_parts = substr_count( $this->fetchSetting('urls-report', $parent), '%s' ); switch( $_parts ) { case 1: $row['urls-report'] = sprintf( $this->fetchSetting('urls-report', $parent), $row['comment_id'] ); break; case 2: $row['urls-report'] = sprintf( $this->fetchSetting('urls-report', $parent), $row['comment_id'], $parent['parent_id'] ); break; } } /* Ensure parity */ $row['member_id'] = $row['comment_author_id']; /* Done */ $comments[ $row['comment_id'] ] = array( 'author' => IPSMember::buildDisplayData( $row ), 'comment' => $row ); } return ( is_array( $comments ) ) ? $comments : array(); } /** * Updates a comment * * @param string Action (delete/approve/unapprove) * @param int ID of parent * @param int Comment IDs * @param array Member Data of current member * @reutrn html Does stuff to things. * EXCEPTIONS * MISSING_DATA Ids missing * NO_PERMISSION No permission */ public function moderate( $action, $parentId, $commentIds, $memberData ) { /* Init */ if ( is_numeric( $memberData ) ) { $memberData = IPSMember::load( $memberData, 'all' ); } /* Fetch and check image */ $parent = $this->fetchParent( $parentId ); $_remap = $this->remapKeys(); /* Parent */ $parent = $this->remapFromLocal( $parent, 'parent' ); /* Fetch comment */ $comments = $this->fetch( $parent, array( 'comment_id' => $commentIds ) ); if ( ! count( $comments ) ) { throw new Exception( 'MISSING_DATA' ); } /* Permission test */ $can = $this->can('moderate', array( 'comment_parent_id' => $parentId ) ); if ( $can !== true ) { throw new Exception( $can ); } /* WHAT ARE YOU DOING HERE? */ switch ( $action ) { case 'delete': try { return $this->delete( $parentId, $commentIds, $memberData ); } catch (Exception $e) { throw new Exception('NO_PERMISSION'); } break; case 'approve': try { return $this->visibility( 'on', $parentId, $commentIds, $memberData ); } catch (Exception $e) { throw new Exception('NO_PERMISSION'); } break; case 'unapprove': try { return $this->visibility( 'off', $parentId, $commentIds, $memberData ); } catch (Exception $e) { throw new Exception('NO_PERMISSION' . $e->getMessage() . ' line: ' . $e->getFile() . '.' . $e->getLine()); } break; } } /** * Add a comment * * @param Int Parent ID * @param string Post content * @param array Member ID of author (current member assumed if empty) * @return exception or comment ID * * EXCEPTION CODES * NO_PERMISSION Do not have permission to add comment */ public function add( $parentId, $post, $memberId=null ) { /* Load member */ $memberData = IPSMember::load( ( ( $memberId === null ) ? $this->memberData['member_id'] : $memberId ), 'all' ); /* Permission test */ $can = $this->can('add', array( 'comment_parent_id' => $parentId ) ); if ( $can !== true ) { throw new Exception( $can ); } /* Format comment */ IPSText::getTextClass( 'bbcode' )->parsing_section = $this->whoAmI() . '_comment'; $comment = IPSText::getTextClass( 'editor' )->processRawPost( $post ); $comment = IPSText::getTextClass( 'bbcode' )->preDbParse( $comment ); /* Build insert data */ $array = array( 'comment_author_id' => $memberData['member_id'], 'comment_author_name' => $memberData['members_display_name'], 'comment_ip_address' => $this->member->ip_address, 'comment_date' => time(), 'comment_text' => $comment, 'comment_approved' => 1, 'comment_parent_id' => $parentId ); /* Pre save */ $insert = $this->preSave( 'add', $array ); /* Insert and fetch DB */ $save = $this->remapToLocal( $insert ); $this->DB->insert( $this->table(), $save ); $insert['comment_id'] = $this->DB->getInsertId(); /* Post save */ $this->postSave( 'add', $insert ); /* Send notifications */ $this->sendNotifications( $this->remapFromLocal( $insert ), $comment ); return $insert['comment_id']; } /** * Sends "like" notifications * * @param array Array of GENERIC data (comment_xxxx) * @param string Comment Text * @return nowt lad */ public function sendNotifications( array $array, $comment ) { list( $_app, $_area ) = explode( '-', $this->whoAmI() ); /* Send them if they are approved */ if ( $array['comment_approved'] ) { $this->lang->loadLanguageFile( array( 'public_comments' ), 'core' ); /* Fetch meta data */ $parent = $this->remapFromLocal( $this->fetchParent( $array['comment_parent_id'] ), 'parent' ); $_url = $this->fetchSetting( 'urls-showParent'); $url = $this->registry->output->buildSEOUrl( sprintf( $_url, $parent['parent_id'] ), 'public', $parent['parent_seo_title'], $this->seoTemplate() ); /* Fetch like class */ require_once( IPS_ROOT_PATH . 'sources/classes/like/composite.php' ); $_like = classes_like::bootstrap( $_app, $_area ); $_like->sendNotifications( $parent['parent_id'], array( 'immediate', 'offline' ), array( 'notification_key' => 'new_comment', 'notification_url' => $url, 'email_template' => 'comment_notifications', 'email_subject' => sprintf( $this->lang->words['comment_notice_subject'], $url, $parent['parent_title'] ), 'build_message_array' => array( 'NAME' => '-member:members_display_name-', 'AUTHOR' => $this->memberData['members_display_name'], 'TITLE' => $parent['parent_title'], 'URL' => $url, 'COMMENT' => $comment ) ) ); } } /** * Updates a comment * * @param int ID of parent * @param int Comment ID * @param array Member Data of current member * @reutrn html Content of edited comment ready for printing to screen * EXCEPTIONS * MISSING_DATA Ids missing * NO_PERMISSION No permission */ public function edit( $parentId, $commentId, $post, $memberData ) { /* Init */ if ( is_numeric( $memberData ) ) { $memberData = IPSMember::load( $memberData, 'all' ); } /* Fetch and check image */ $parent = $this->fetchParent( $parentId ); $_remap = $this->remapKeys(); /* Parent */ $parent = $this->remapFromLocal( $parent, 'parent' ); /* Fetch comment */ $_c = $this->fetch( $parent, array( 'comment_id' => $commentId ) ); $comment = array_pop( $_c ); /* Permission test */ $can = $this->can('edit', array( 'comment_id' => $commentId, 'comment_parent_id' => $parentId ) ); if ( $can !== true ) { throw new Exception( $can ); } /* Format post */ IPSText::getTextClass('bbcode')->parse_html = 0; IPSText::getTextClass('bbcode')->parse_nl2br = 1; IPSText::getTextClass('bbcode')->parse_smilies = 1; IPSText::getTextClass('bbcode')->parse_bbcode = 1; IPSText::getTextClass('bbcode')->parsing_section = $this->whoAmI . '_comment'; $comment = IPSText::getTextClass( 'editor' )->processRawPost( $post ); $comment = IPSText::getTextClass( 'bbcode' )->preDbParse( $comment ); /* Update array */ $array = array( 'comment_edit_date' => time(), 'comment_text' => $comment ); /* Pre save */ $update = $this->preSave( 'edit', $array ); /* Insert and fetch DB */ $save = $this->remapToLocal( $update ); /* Update */ $this->DB->update( $this->table(), $save, $_remap['comment_id'] . '=' . intval( $commentId ) ); /* Post save */ $this->postSave( 'edit', $update ); /* Format and return */ return IPSText::getTextClass('bbcode')->preDisplayParse( $comment ); } /** * Deletes a comment * * @param int Image ID of parent * @param mixed Comment ID or array of comment IDs * @param array Member Data of current member * @reutrn html * EXCEPTIONS * MISSING_DATA Ids missing * NO_PERMISSION No permission */ public function delete( $parentId, $commentId, $memberData ) { /* Init */ if ( is_numeric( $memberData ) ) { $memberData = IPSMember::load( $memberData, 'all' ); } /* Check */ if ( ! $memberData['member_id'] OR ! $parentId OR ! $commentId ) { throw new Exception('MISSING_DATA'); } /* Fetch and check image */ $parent = $this->fetchParent( $parentId ); $_remap = $this->remapKeys(); $cids = array(); /* Parent */ $parent = $this->remapFromLocal( $parent, 'parent' ); /* One or many? */ if ( is_numeric( $commentId ) ) { /* Fetch comment */ $_c = $this->fetch( $parent, array( 'comment_id' => $commentId ) ); $comment = array_pop( $_c ); /* Permission test */ $can = $this->can('delete', array( 'comment_id' => $commentId, 'comment_parent_id' => $parentId ) ); if ( $can !== true ) { throw new Exception( $can ); } $cids = array( $commentId ); } else if ( is_array( $commentId ) ) { /* Permission test */ $can = $this->can('moderate', array( 'comment_parent_id' => $parentId ) ); if ( $can !== true ) { throw new Exception( $can ); } /* Finalize comment Ids */ $this->DB->build( array( 'select' => '*', 'from' => $this->table(), 'where' => $_remap['comment_id'] . ' IN (' . implode( ",", IPSLib::cleanIntArray( $commentId ) ) . ') AND ' . $_remap['comment_parent_id'] . '=' . $parent['parent_id'] ) ); $this->DB->execute(); while( $row = $this->DB->fetch() ) { $cids[] = $row[ $_remap['comment_id'] ]; } } /* If we have anything.. */ if ( count( $cids ) ) { /* Pre delete */ $this->preDelete( $cids, $parentId ); /* Delete */ $this->DB->delete( $this->table(), $_remap['comment_id'] . ' IN (' . implode( ",", $cids ) . ')' ); /* Post delete */ $this->postDelete( $cids, $parentId ); } /* Return count deleted */ return count( $cids ); } /** * Toggles visbility a comment * * @param string on/off * @param int Image ID of parent * @param mixed Comment ID or array of comment IDs * @param array Member Data of current member * @reutrn html * EXCEPTIONS * MISSING_DATA Ids missing * NO_PERMISSION No permission */ public function visibility( $toggle, $parentId, $commentId, $memberData ) { /* Init */ if ( is_numeric( $memberData ) ) { $memberData = IPSMember::load( $memberData, 'all' ); } /* Check */ if ( ! $memberData['member_id'] OR ! $parentId OR ! $commentId ) { throw new Exception('MISSING_DATA'); } /* Fetch and check image */ $parent = $this->fetchParent( $parentId ); $_remap = $this->remapKeys(); $cids = array(); /* Parent */ $parent = $this->remapFromLocal( $parent, 'parent' ); /* One or many? */ if ( is_numeric( $commentId ) ) { /* Fetch comment */ $_c = $this->fetch( $parent, array( 'comment_id' => $commentId ) ); $comment = array_pop( $_c ); /* Permission test */ $can = $this->can('visibility', array( 'comment_id' => $commentId, 'comment_parent_id' => $parentId ) ); if ( $can !== true ) { throw new Exception( $can ); } $cids = array( $commentId ); } else if ( is_array( $commentId ) ) { /* Permission test */ $can = $this->can('visibility', array( 'comment_parent_id' => $parentId ) ); if ( $can !== true ) { throw new Exception( $can ); } /* Finalize comment Ids */ $this->DB->build( array( 'select' => '*', 'from' => $this->table(), 'where' => $_remap['comment_id'] . ' IN (' . implode( ",", IPSLib::cleanIntArray( $commentId ) ) . ') AND ' . $_remap['comment_parent_id'] . '=' . $parent['parent_id'] ) ); $this->DB->execute(); while( $row = $this->DB->fetch() ) { $cids[] = $row[ $_remap['comment_id'] ]; } } /* If we have anything.. */ if ( count( $cids ) ) { /* Update array */ $array = array( 'comment_approved' => ( $toggle == 'on' ? 1 : 0 ) ); /* Pre save */ $update = $this->preVisibility( $toggle, $cids, $parentId, $array ); /* Insert and fetch DB */ $save = $this->remapToLocal( $update ); /* Update */ $this->DB->update( $this->table(), $save, $_remap['comment_id'] . ' IN (' . implode( ",", $cids ) . ')' ); /* Post delete */ $this->postVisibility( $toggle, $cids, $parentId ); } /* Return count deleted */ return count( $cids ); } /** * Display a comment edit form suitable for ajax * * @param int Image ID of parent * @param int Comment ID * @param array Member Data of current member * @reutrn html * EXCEPTIONS * MISSING_DATA Ids missing * NO_PERMISSION No permission */ public function fetchReply( $parentId, $commentId, $memberData ) { /* Init */ if ( is_numeric( $memberData ) ) { $memberData = IPSMember::load( $memberData, 'all' ); } /* Check */ if ( ! $memberData['member_id'] OR ! $parentId OR ! $commentId ) { throw new Exception('MISSING_DATA'); } /* Fetch and check image */ $parent = $this->fetchParent( $parentId ); /* Parent */ $parent = $this->remapFromLocal( $parent, 'parent' ); /* Fetch comment */ $_c = $this->fetch( $parent, array( 'comment_id' => $commentId ) ); $comment = array_pop( $_c ); /* Permission test */ $can = $this->can('view', array( 'comment_id' => $commentId, 'comment_parent_id' => $parentId ) ); if ( $can !== true ) { throw new Exception( $can ); } /* Process post ready for use */ if ( IPSText::getTextClass('editor')->method == 'rte' ) { IPSText::getTextClass('bbcode')->parse_wordwrap = 0; IPSText::getTextClass('bbcode')->parse_html = 0; $comment['comment']['comment_text'] = IPSText::getTextClass('bbcode')->convertForRTE( $comment['comment']['_db_comment'] ); } else { IPSText::getTextClass('bbcode')->parse_html = 0; IPSText::getTextClass('bbcode')->parse_nl2br = 1; IPSText::getTextClass('bbcode')->parse_smilies = 1; IPSText::getTextClass('bbcode')->parse_bbcode = 1; IPSText::getTextClass('bbcode')->parsing_section = 'gallery_comment'; $comment['comment']['comment_text'] = IPSText::getTextClass('bbcode')->preEditParse( $comment['comment']['_db_comment'] ); } $reply = "[quote name='" . IPSText::getTextClass( 'bbcode' )->makeQuoteSafe( $comment['author']['members_display_name'] ) . "' timestamp='" . $comment['comment']['comment_date'] . "']
{$comment['comment']['comment_text']}
[/quote]


"; if ( IPSText::getTextClass('editor')->method != 'rte' ) { $reply = IPSText::br2nl( $reply ); } /* Throw, fetch and wag tail */ return IPSText::raw2form( $reply ); } /** * Display a comment edit form suitable for ajax * * @param int Image ID of parent * @param int Comment ID * @param array Member Data of current member * @param string Type: html or ajax * @reutrn html * EXCEPTIONS * MISSING_DATA Ids missing * NO_PERMISSION No permission */ public function displayEditForm( $parentId, $commentId, $memberData, $type='html' ) { /* Init */ if ( is_numeric( $memberData ) ) { $memberData = IPSMember::load( $memberData, 'all' ); } /* Check */ if ( ! $memberData['member_id'] OR ! $parentId OR ! $commentId ) { throw new Exception('MISSING_DATA'); } /* Fetch and check image */ $parent = $this->fetchParent( $parentId ); /* Parent */ $parent = $this->remapFromLocal( $parent, 'parent' ); /* Fetch comment */ $_c = $this->fetch( $parent, array( 'comment_id' => $commentId ) ); $comment = array_pop( $_c ); /* Permission test */ $can = $this->can('edit', array( 'comment_id' => $commentId, 'comment_parent_id' => $parentId ) ); if ( $can !== true ) { throw new Exception( $can ); } /* Process post ready for use */ if ( IPSText::getTextClass('editor')->method == 'rte' ) { IPSText::getTextClass('bbcode')->parse_wordwrap = 0; IPSText::getTextClass('bbcode')->parse_html = 0; $comment['comment']['comment_text'] = IPSText::getTextClass('bbcode')->convertForRTE( $comment['comment']['_db_comment'] ); } else { IPSText::getTextClass('bbcode')->parse_html = 0; IPSText::getTextClass('bbcode')->parse_nl2br = 1; IPSText::getTextClass('bbcode')->parse_smilies = 1; IPSText::getTextClass('bbcode')->parse_bbcode = 1; IPSText::getTextClass('bbcode')->parsing_section = 'gallery_comment'; $comment['comment']['comment_text'] = IPSText::getTextClass('bbcode')->preEditParse( $comment['comment']['_db_comment'] ); } /* Load langs */ $this->registry->getClass( 'class_localization')->loadLanguageFile( array( 'public_editors' ), 'core' ); /* Ayjacks? */ if ( $type == 'ajax' ) { /* Throw, fetch and wag tail */ return $this->registry->getClass('output')->getTemplate('editors')->ajaxEditBox( $comment['comment']['comment_text'], $commentId, array(), array( 'showEditOptions' => false, 'checkBoxes' => false, 'skipFullButton' => true ) ); } else { /* Need a bit more dudes */ $editor = IPSText::getTextClass('editor')->showEditor( $comment['comment']['comment_text'], 'Post' ); $settings = array( 'fromApp' => $this->whoAmI(), '_app' => preg_replace( '#^(.+?)(?:-.*|$)#', '\\1', $this->whoAmI() ) ); return $this->registry->getClass('output')->getTemplate( $this->skin() )->form( $comment, $parent, $editor, $settings, array(), 'saveEdit' ); } } /** * Display a comment edit form suitable for ajax * * @param int Image ID of parent * @param int Comment ID * @param array Member Data of current member * @reutrn html * EXCEPTIONS * MISSING_DATA Ids missing * NO_PERMISSION No permission */ public function displayAjaxEditForm( $parentId, $commentId, $memberData ) { try { return $this->displayEditForm( $parentId, $commentId, $memberData, 'ajax' ); } catch( Exception $e ) { throw new Exception( $e->getMessage() ); } } /** * Redirects to the latest comment * * @return void [Redirects] */ public function redirectToComment( $commentId, $parentId ) { /* Init */ $parentId = intval( $parentId ); $parent = $this->fetchParent( $parentId ); $_remap = $this->remapKeys(); /* Parent */ $parent = $this->remapFromLocal( $parent, 'parent' ); /* fetch */ $q = ( $this->can( 'moderate', array( 'comment_parent_id' => $parent['parent_id'] ) ) ) ? '' : ' AND ' . $_remap['comment_approved'] . '=1'; /* Fetch comment */ if ( $commentId == 'last' ) { $comment = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => $this->table(), 'where' => $_remap['comment_parent_id'] . '='. $parentId . $q, 'order' => $_remap['comment_id'] . ' DESC', 'limit' => array( 0, 1 ) ) ); } else { $comment = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => $this->table(), 'where' => $_remap['comment_id'] . '='. intval( $commentId ) . $q, 'limit' => array( 0, 1 ) ) ); } /* remap */ $comment = $this->remapFromLocal( $comment ); /* Permission test */ $can = $this->can('view', array( 'comment_id' => $comment['comment_id'], 'comment_parent_id' => $parentId ) ); if ( $can !== true ) { throw new Exception( $can ); } /* Fetch total */ $total = $this->DB->buildAndFetch( array( 'select' => 'count(*) as total', 'from' => $this->table(), 'where' => $_remap['comment_parent_id'] . '=' . $parentId . $q . ' AND ' . $_remap['comment_id'] . '<=' . $comment['comment_id'] ) ); if ( $total['total'] > $this->perPage() ) { if ( $total['total'] % $this->perPage() == 0 ) { $pages = $total['total'] / $this->perPage(); } else { $number = ( $total['total'] / $this->perPage() ); $pages = ceil( $number); } $st = ($pages - 1) * $this->perPage(); $this->registry->output->silentRedirect( $this->settings['base_url'] . sprintf( $this->fetchSetting('urls-showParent', $parent), $parentId ) . "&st=" . $st . '#comment_' . $comment['comment_id'], $parent['parent_seo_title'], false, $this->seoTemplate() ); } else { $this->registry->output->silentRedirect( $this->settings['base_url'] . sprintf( $this->fetchSetting('urls-showParent', $parent), $parentId ) . "#comment_" . $comment['comment_id'], $parent['parent_seo_title'], false, $this->seoTemplate() ); } } /** * Remap for local * Accepts a standard array of data * * @param array Array of GENERIC formatted data * @return void **/ public function remapToLocal( array $array, $type='comment' ) { /* Return */ $return = array(); $_remap = $this->remapKeys( $type ); /* Please; continue */ foreach( $array as $k => $v ) { if ( array_key_exists( $k, $_remap ) ) { $return[ $_remap[ $k ] ] = $v; } else { $return[ $k ] = $v; } } return $return; } /** * Remap for generic * Accepts a standard array of data * * @param array Array of LOCAL data * @return void **/ public function remapFromLocal( array $array, $type='comment' ) { /* Return */ $return = array(); $_remap = array_flip( $this->remapKeys( $type ) ); /* Please; continue */ foreach( $array as $k => $v ) { if ( array_key_exists( $k, $_remap ) ) { $return[ $_remap[ $k ] ] = $v; } else { $return[ $k ] = $v; } } return $return; } /** * Parent SEO template * * @return string */ public function seoTemplate() { return ''; } /** * Number of items per page * * @return int */ public function perPage() { return 10; } /** * Skin class * * @return string */ public function skin() { return 'global_comments'; } /** * Pre save * Accepts an array of GENERIC data and allows manipulation before it's added to DB * * @param string Type of save (edit/add) * @param array Array of GENERIC data (comment_xxxx) * @return array Array of GENERIC data */ public function preSave( $type, array $array ) { return $array; } /** * Post save * Accepts an array of GENERIC data and allows manipulation after it's added to DB * * @param string Type of action (edit/add) * @param array Array of GENERIC data (comment_xxxx) * @return nowt lad */ public function postSave( $type, array $array ) { } /** * Pre Visibility * Pre-DB-save function before visibility is toggled * * @param string on/off * @param array Array of comment IDs to be deleted * @param int Parent ID * @param array Array of db fields => data to be updated */ public function preVisibility( $toggle, $commentIds, $parentId, array $update ) { return $update; } /** * Post Visibility * Pre-DB-save function before visibility is toggled * * @param string on/off * @param array Array of comment IDs to be deleted * @param int Parent ID */ public function postVisibility( $toggle, $commentIds, $parentId ) { } /** * Pre delete. Can do stuff and that * * @param array Array of comment IDs to be deleted * @param int Parent ID * @return nowt lad */ public function preDelete( $commentIds, $parentId ) { } /** * Post delete. Can do stuff and that * * @param array Array of comment IDs to be deleted * @param int Parent ID * @return nowt lad */ public function postDelete( $commentIds, $parentId ) { } /** * Perform a permission check * * @param string Type of check (add/edit/delete/editall/deleteall/approve all) * @param array Array of GENERIC data * @return true or string to be used in exception **/ public function can( $type, array $array ) { /* Default, so return least permissive */ return 'NO_PERMISSION'; } /** * Unpack the repuation cache, yo. * * @return void */ protected function _unpackRepCache() { if ( $this->settings['reputation_enabled'] ) { /* Load the class */ require_once( IPS_ROOT_PATH . 'sources/classes/class_reputation_cache.php' ); $this->registry->setClass( 'repCache', new classReputationCache() ); /* Update the filter? */ if( isset( $this->request['rep_filter'] ) && $this->request['rep_filter'] == 'update' ) { $_mem_cache = IPSMember::unpackMemberCache( $this->memberData['members_cache'] ); if( $this->request['rep_filter_set'] == '*' ) { $_mem_cache['rep_filter'] = '*'; } else { $_mem_cache['rep_filter'] = intval( $this->request['rep_filter_set'] ); } IPSMember::packMemberCache( $this->memberData['member_id'], $_mem_cache ); $this->memberData['_members_cache'] = $_mem_cache; } else { $this->memberData['_members_cache'] = IPSMember::unpackMemberCache( $this->memberData['members_cache'] ); } $this->memberData['_members_cache']['rep_filter'] = isset( $this->memberData['_members_cache']['rep_filter'] ) ? $this->memberData['_members_cache']['rep_filter'] : '*'; } } /** * Set filters * Takes user input and cleans it up a bit * * @param array Incoming filters * @return array */ protected function _setFilters( $filters ) { /* Do some set up */ switch( $filters['sortKey'] ) { default: case 'post_date': case 'date': case 'time': $filters['sortKey'] = 'comment_date'; break; case 'author': case 'author_id': $filters['sortKey'] = 'comment_author_id'; break; } switch( $filters['sortOrder'] ) { case 'desc': case 'descending': case 'z-a': $filters['sortOrder'] = 'desc'; break; default: case 'asc': case 'ascending': case 'a-z': $filters['sortOrder'] = 'asc'; break; } /* Others */ $filters['offset'] = intval( $filters['offset'] ); $filters['limit'] = intval( $filters['limit'] ); $filters['unixCutOff'] = intval( $filters['unixCutOff'] ); /* Make sure we have a limit */ if ( ! $filters['limit'] ) { $filters['limit'] = $this->perPage(); } /* So we don't have to do this twice */ $filters['_cleaned'] = true; return $filters; } }