Index: branches/5.2.x/units/private_messages/private_message_eh.php =================================================================== --- branches/5.2.x/units/private_messages/private_message_eh.php (revision 16514) +++ branches/5.2.x/units/private_messages/private_message_eh.php (revision 16515) @@ -1,303 +1,303 @@ Array ('self' => true), 'OnCreate' => Array ('self' => true), 'OnDelete' => Array ('self' => true), ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** * Applies folder & message owner filter to message list * * @param kEvent $event * @return void * @access protected * @see kDBEventHandler::OnListBuild() */ protected function SetCustomQuery(kEvent $event) { parent::SetCustomQuery($event); $folder_id = $this->Application->GetVar('folder_id'); if ( $folder_id === false ) { $folder_id = PM_FOLDER_INBOX; $this->Application->SetVar('folder_id', $folder_id); } + /** @var kDBList $object */ $object = $event->getObject(); - /* @var $object kDBList */ $user_id = $this->Application->RecallVar('user_id'); if ( $folder_id == PM_FOLDER_INBOX ) { $object->addFilter('owner_filter', '%1$s.ToId = ' . $user_id); } else { $object->addFilter('owner_filter', '%1$s.FromId = ' . $user_id); } $object->addFilter('folder_filter', '%1$s.FolderId = ' . $folder_id); } /** * Puts message to Sent folder * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemCreate(kEvent $event) { parent::OnBeforeItemCreate($event); + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ if ( $object->GetDBField('FolderId') != PM_FOLDER_SENT ) { // when creating "Inbox" message (from "Sent" message) don't reset folder & status return ; } $user_id = $this->Application->RecallVar('user_id'); $object->SetDBField('FromId', $user_id); $object->SetDBField('FolderId', PM_FOLDER_SENT); $object->SetDBField('Status', PM_STATUS_READ); } /** * Creates 1st post when topic is created * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemCreate(kEvent $event) { parent::OnAfterItemCreate($event); + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ $this->Application->emailUser('PM.ADD', $object->GetDBField('ToId')); if ( $object->GetDBField('FolderId') != PM_FOLDER_SENT ) { // 1. create message in sender's "Sent" folder (this method only for this step) // 2. create message body (shared) // 3. create message copy in recipient's "Inbox" folder return ; } + /** @var kDBItem $message_body */ $message_body = $this->Application->recallObject($event->Prefix . '-body', null, Array ('skip_autoload' => true)); - /* @var $message_body kDBItem */ // 1. create message body (for sender & recipient) $copy_fields = Array ('Subject', 'Body', 'ShowSignatures', 'DisableSmileys', 'DisableBBCodes'); $message_body->SetDBFieldsFromHash($object->GetFieldValues(), $copy_fields); $body_created = $message_body->Create(); if ( $body_created ) { // 2. link body with message $object->SetDBField('PMBodyId', $message_body->GetID()); $object->Update(); // 3. create message in recipient's Inbox folder $object->SetDBField('FolderId', PM_FOLDER_INBOX); $object->SetDBField('Status', PM_STATUS_UNREAD); $object->Create(); } } /** * Sets post options to virtual fields * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemLoad(kEvent $event) { parent::OnAfterItemLoad($event); + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ + /** @var PostHelper $post_helper */ $post_helper = $this->Application->recallObject('PostHelper'); - /* @var $post_helper PostHelper */ $options_map = $post_helper->getOptionsMap(); $post_options = $object->GetDBField('Options'); foreach ($options_map as $option_name => $field_name) { $option_value = $post_helper->GetPostOption($option_name, $post_options); $object->SetDBField($field_name, (int)$option_value); } } /** * Goes to next_template after post creation * * @param kEvent $event * @return void * @access protected */ protected function OnCreate(kEvent $event) { parent::OnCreate($event); if ( $event->status == kEvent::erSUCCESS && !$this->Application->isAdmin ) { $event->SetRedirectParam('opener', 's'); $event->redirect = $this->Application->GetVar('next_template'); } } /** * Prevents user from deleting other user private messages * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemDelete(kEvent $event) { parent::OnBeforeItemDelete($event); + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ $user_id = $this->Application->RecallVar('user_id'); $owner_field = ($object->GetDBField('FolderId') == PM_FOLDER_INBOX) ? 'ToId' : 'FromId'; if ( $object->GetDBField($owner_field) != $user_id ) { $event->status = kEvent::erFAIL; } } /** * Updates reference counter in message body record * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemDelete(kEvent $event) { parent::OnAfterItemDelete($event); + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ $body_idfield = $this->Application->getUnitOption($event->Prefix . '-body', 'IDField'); $body_table = $this->Application->getUnitOption($event->Prefix . '-body', 'TableName'); $sql = 'UPDATE ' . $body_table . ' SET ReferenceCount = ReferenceCount - 1 WHERE ' . $body_idfield . ' = ' . $object->GetDBField('PMBodyId'); $this->Conn->Query($sql); } /** * Sets default values to posting options based on persistent session * * @param kEvent $event * @return void * @access protected */ protected function OnAfterConfigRead(kEvent $event) { parent::OnAfterConfigRead($event); if ( !$this->Application->LoggedIn() ) { return; } $virtual_fields = $this->Application->getUnitOption($event->Prefix, 'VirtualFields'); $virtual_fields['DisableBBCodes']['default'] = (int)!$this->Application->RecallPersistentVar('bbcode'); $virtual_fields['DisableSmileys']['default'] = (int)!$this->Application->RecallPersistentVar('smileys'); $virtual_fields['ShowSignatures']['default'] = (int)$this->Application->RecallPersistentVar('show_sig'); $this->Application->setUnitOption($event->Prefix, 'VirtualFields', $virtual_fields); } /** * Checks, that current user is recipient or sender of viewed message * * @param kEvent $event * @return bool * @access protected */ protected function checkItemStatus(kEvent $event) { + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ if ( !$object->isLoaded() ) { return true; } $user_id = $this->Application->RecallVar('user_id'); return ($object->GetDBField('FromId') == $user_id) || ($object->GetDBField('ToId') == $user_id); } /** * Prepares new reply & new message form * * @param kEvent $event * @return void * @access protected */ protected function OnNew(kEvent $event) { parent::OnNew($event); $reply_to = $this->Application->GetVar('reply_to'); $user_id = $this->Application->GetVar('user_id'); + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ if ( $reply_to > 0 ) { // reply to message + /** @var kDBItem $source_msg */ $source_msg = $this->Application->recallObject($event->Prefix . '.-item', null, Array ('skip_autoload' => true)); - /* @var $source_msg kDBItem */ $source_msg->Load($reply_to); $object->SetDBField('ToId', $source_msg->GetDBField('FromId')); $object->SetDBField('Subject', 'Re: ' . $source_msg->GetDBField('Subject')); } elseif ( $user_id > 0 ) { // send message to any user by id $object->SetDBField('ToId', $user_id); } } } Index: branches/5.2.x/units/private_messages/private_message_tp.php =================================================================== --- branches/5.2.x/units/private_messages/private_message_tp.php (revision 16514) +++ branches/5.2.x/units/private_messages/private_message_tp.php (revision 16515) @@ -1,164 +1,164 @@ getObject($params); - /* @var $object kDBItem */ return $object->GetDBField('Status') < PM_STATUS_READ; } /** * Allows to check what folder is currently active * * @param Array $params * @return bool */ function FolderSelected($params) { $folder_mapping = Array ('inbox' => PM_FOLDER_INBOX, 'sent' => PM_FOLDER_SENT); return (int)$this->Application->GetVar('folder_id') == $folder_mapping[ strtolower($params['folder']) ]; } /** * Creates link to specific private message folder * * @param Array $params * @return string */ function FolderLink($params) { $folder_mapping = Array ('inbox' => PM_FOLDER_INBOX, 'sent' => PM_FOLDER_SENT); $params['folder_id'] = $folder_mapping[ strtolower($params['folder']) ]; unset($params['folder']); return $this->Application->ProcessParsedTag('m', 'Link', $params); } function MessageSubject($params) { + /** @var kDBItem $object */ $object = $this->getObject($params); - /* @var $object kDBItem */ $params['field'] = 'Subject'; $value = $this->Field($params); if (!$value && isset($params['empty_title'])) { return '['.$this->Application->Phrase($params['empty_title']).']'; } return $value; } function MessageBody($params) { $object = $this->getObject($params); + /** @var PostHelper $post_helper */ $post_helper = $this->Application->recallObject('PostHelper'); - /* @var $post_helper PostHelper */ // 2. parse post body $sub_blocks = Array ( 'smileys' => $params['smiley_render_as'], 'bbcode' => $params['bbcode_render_as'], ); return $post_helper->parsePostBody($object->GetDBField('Body'), $object->GetDBField('Options'), $sub_blocks); } function DeleteLink($params) { $params['pass'] = 'm,'.$this->getPrefixSpecial(); $params[$this->getPrefixSpecial().'_event'] = 'OnDelete'; return $this->Application->ProcessParsedTag('m', 'Link', $params); } function ReplyLink($params) { $params['reply_to'] = $this->Application->GetVar($this->getPrefixSpecial().'_id'); return $this->Application->ProcessParsedTag('m', 'Link', $params); } /** * User can reply message only in case, when it is not it's own message * * @param Array $params * @return bool */ function CanReplyMessage($params) { + /** @var kDBItem $object */ $object = $this->getObject($params); - /* @var $object kDBItem */ return $object->GetDBField('FromId') != $this->Application->RecallVar('user_id'); } /** * Marks private message as read * * @param Array $params */ function MarkAsRead($params) { + /** @var kDBItem $object */ $object = $this->getObject($params); - /* @var $object kDBItem */ if ($object->GetDBField('Status') < PM_STATUS_READ) { $object->SetDBField('Status', PM_STATUS_READ); $object->Update(); } } /** * Returns link to private message sender/recipient public profile * * @param Array $params * @return string */ function ProfileLink($params) { $user_field = strtolower($params['type']) == 'from' ? 'FromId' : 'ToId'; unset($params['type']); $object = $this->getObject($params); $params['user_id'] = $object->GetDBField($user_field); return $this->Application->ProcessParsedTag('m', 'Link', $params); } /** * Returns link for sending private message from user's public profile page * * @param Array $params * @return string */ function SendMessageLink($params) { $params['user_id'] = $this->Application->GetVar('user_id'); return $this->Application->ProcessParsedTag('m', 'Link', $params); } } \ No newline at end of file Index: branches/5.2.x/units/topics/topics_tag_processor.php =================================================================== --- branches/5.2.x/units/topics/topics_tag_processor.php (revision 16514) +++ branches/5.2.x/units/topics/topics_tag_processor.php (revision 16515) @@ -1,122 +1,122 @@ ItemLink($params, 'topic'); } function ListTopics($params) { return $this->PrintList2($params); } function PostingLink($params) { $item_id = getArrayValue($params, 'posting_id'); if (!$item_id) { $item_id = $this->Application->GetVar($this->Prefix.'_post_id'); } $params[$this->Prefix.'_post_id'] = $item_id; return $this->TopicLink($params); } function PostingDeleteLink($params) { $params['Action'] = 'bb_post_delete'; return $this->PostingLink($params); } /** * Returns topic replies count * * @param Array $params * @return int */ function TopicReplies($params) { $object = $this->getObject($params); // -1 - don't count post created together with topic return $object->GetDBField('Posts') ? $object->GetDBField('Posts') - 1 : 0; } /** * Returns topic lock statis * * @param Array $params * @return bool */ function IsLocked($params) { $object = $this->getObject($params); return $object->GetDBField('TopicType') == 0; } function LockToggleLink($params) { $params[$this->Prefix.'_event'] = 'OnTopicLockToggle'; $params['pass'] = 'm,'.$this->Prefix; return $this->Application->ProcessParsedTag('m', 'Link', $params); } /** * Detects if current user is subscribed to new topics in this category * * @param Array $params * @return bool */ function SubscribedToCategoryTopics($params) { static $subscribed = null; if ( !isset($subscribed) ) { + /** @var PostHelper $post_helper */ $post_helper = $this->Application->recallObject('PostHelper'); - /* @var $post_helper PostHelper */ $subscribed = $post_helper->getSubscriptionManager('CategoryTopics')->subscribed(); } return $subscribed; } /** * Detects if current user is subscribed to this topic posts * * @param Array $params * @return bool */ function SubscribedToTopicPosts($params) { static $subscribed = null; if ( !isset($subscribed) ) { + /** @var kDBItem $object */ $object = $this->getObject($params); - /* @var $object kDBItem */ + /** @var PostHelper $post_helper */ $post_helper = $this->Application->recallObject('PostHelper'); - /* @var $post_helper PostHelper */ $subscribed = $post_helper->getSubscriptionManager('TopicPosts', Array ($object->GetID()))->subscribed(); } return $subscribed; } } \ No newline at end of file Index: branches/5.2.x/units/topics/topics_event_handler.php =================================================================== --- branches/5.2.x/units/topics/topics_event_handler.php (revision 16514) +++ branches/5.2.x/units/topics/topics_event_handler.php (revision 16515) @@ -1,348 +1,348 @@ Name == 'OnTopicLockToggle' ) { + /** @var kCatDBItem $object */ $object = $event->getObject(); - /* @var $object kCatDBItem */ if ( !$object->isLoaded() ) { $event->status = kEvent::erPERM_FAIL; return false; } $category_id = $object->GetDBField('CategoryId'); $perm_status = $this->Application->CheckPermission('TOPIC.LOCK', 0, $category_id); if ( !$perm_status ) { $event->status = kEvent::erPERM_FAIL; } return $perm_status; } if ( $event->Name == 'OnToogleCategoryTopicsSubscribe' || $event->Name == 'OnToogleTopicPostsSubscribe' ) { return $this->Application->LoggedIn(); } return parent::CheckPermission($event); } /** * Lock or unlock topic * * @param kEvent $event */ function OnToggleLock($event) { + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ $new_type = $object->GetDBField('TopicType') ? 0 : 1; $object->SetDBField('TopicType', $new_type); $object->Update(); } /** * Cache topic owner * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemUpdate(kEvent $event) { parent::OnBeforeItemUpdate($event); $this->cacheItemOwner($event, 'OwnerId', 'PostedBy'); } /** * Cache topic owner * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemCreate(kEvent $event) { parent::OnBeforeItemCreate($event); $this->cacheItemOwner($event, 'OwnerId', 'PostedBy'); + /** @var kCatDBItem $object */ $object = $event->getObject(); - /* @var $object kCatDBItem */ if ( !$object->GetDBField('TodayDate') ) { $object->SetDBField('TodayDate', adodb_date('Y-m-d')); } + /** @var PostHelper $post_helper */ $post_helper = $this->Application->recallObject('PostHelper'); - /* @var $post_helper PostHelper */ $object->SetDBField('TopicText', $post_helper->CensorText($object->GetDBField('TopicText'))); } /** * Creates 1st post when topic is created * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemCreate(kEvent $event) { parent::OnAfterItemCreate($event); if ( $event->Special == '-item' ) { // don't create first post when cloning return ; } + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ + /** @var kDBItem $post */ $post = $this->Application->recallObject($event->Prefix . '-post', null, Array ('skip_autoload' => true)); - /* @var $post kDBItem */ $post->SetDBField('Pending', $object->GetDBField('Status') == STATUS_ACTIVE ? 0 : 1); $post->SetDBField('Subject', ''); $post->SetDBField('PostingText', $object->GetDBField('PostingText')); $post->SetDBField('ShowSignatures', $object->GetDBField('ShowSignatures')); $post->SetDBField('DisableSmileys', $object->GetDBField('DisableSmileys')); $post->SetDBField('DisableBBCodes', $object->GetDBField('DisableBBCodes')); $post->Create(); // need to update category topic count here } /** * Approves 1st post when topic got approved * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemUpdate(kEvent $event) { parent::OnAfterItemUpdate($event); if ( !$this->Application->isAdminUser ) { return; } + /** @var kCatDBItem $object */ $object = $event->getObject(); - /* @var $object kCatDBItem */ if ( $object->GetDBField('Posts') == 1 ) { + /** @var kDBItem $post */ $post = $this->Application->recallObject($event->Prefix . '-post', null, Array ('skip_autoload' => true)); - /* @var $post kDBItem */ $main_status = $object->GetDBField('Status'); $post->Load($object->GetDBField('LastPostId')); if ( $post->isLoaded() ) { $post->SetDBField('Pending', $main_status == STATUS_ACTIVE ? 0 : 1); $post->Update(); } } } /** * Makes first post body field non-required when topic has posts already * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemLoad(kEvent $event) { parent::OnAfterItemLoad($event); + /** @var kCatDBItem $object */ $object = $event->getObject(); - /* @var $object kCatDBItem */ if ( $object->GetDBField('Posts') > 0 || !$this->Application->isAdminUser ) { $object->setRequired('PostingText', false); } } /** * Locks or unlocks topic * * @param kEvent $event */ function OnTopicLockToggle($event) { + /** @var kCatDBItem $object */ $object = $event->getObject(); - /* @var $object kCatDBItem */ $topic_type = $object->GetDBField('TopicType'); $object->SetDBField('TopicType', $topic_type == 1 ? 0 : 1); $object->Update(); } /** * Sets default values to posting options based on persistent session * * @param kEvent $event * @return void * @access protected */ protected function OnAfterConfigRead(kEvent $event) { parent::OnAfterConfigRead($event); if ( !$this->Application->LoggedIn() ) { return; } $fields = $this->Application->getUnitOption($event->Prefix, 'Fields'); $fields['NotifyOwnerOnChanges']['default'] = (int)$this->Application->RecallPersistentVar('owner_notify'); $this->Application->setUnitOption($event->Prefix, 'Fields', $fields); $virtual_fields = $this->Application->getUnitOption($event->Prefix, 'VirtualFields'); $virtual_fields['DisableBBCodes']['default'] = (int)!$this->Application->RecallPersistentVar('bbcode'); $virtual_fields['DisableSmileys']['default'] = (int)!$this->Application->RecallPersistentVar('smileys'); $virtual_fields['ShowSignatures']['default'] = (int)$this->Application->RecallPersistentVar('show_sig'); $this->Application->setUnitOption($event->Prefix, 'VirtualFields', $virtual_fields); } /** * [HOOK] Allows to add cloned subitem to given prefix * * @param kEvent $event * @return void * @access protected */ protected function OnCloneSubItem(kEvent $event) { parent::OnCloneSubItem($event); if ( $event->MasterEvent->Prefix == 'rev' ) { $clones = $this->Application->getUnitOption($event->MasterEvent->Prefix, 'Clones'); $subitem_prefix = $event->Prefix . '-' . $event->MasterEvent->Prefix; $clones[$subitem_prefix]['ConfigMapping'] = Array ( 'PerPage' => 'Perpage_TopicReviews', 'ReviewDelayInterval' => 'topic_ReviewDelay_Interval', 'ReviewDelayValue' => 'topic_ReviewDelay_Value', ); $this->Application->setUnitOption($event->MasterEvent->Prefix, 'Clones', $clones); } } /** * Subscribes/unsubscribes to new topics in given current category * * @param kEvent $event * @return void * @access protected */ protected function OnToogleCategoryTopicsSubscribe(kEvent $event) { + /** @var PostHelper $post_helper */ $post_helper = $this->Application->recallObject('PostHelper'); - /* @var $post_helper PostHelper */ $manager = $post_helper->getSubscriptionManager('CategoryTopics'); if ( $manager->subscribed() ) { $manager->unsubscribe(); } else { $manager->subscribe(); } } /** * Subscribes/unsubscribes to new posts in current topic * * @param kEvent $event * @return void * @access protected */ protected function OnToogleTopicPostsSubscribe(kEvent $event) { + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ + /** @var PostHelper $post_helper */ $post_helper = $this->Application->recallObject('PostHelper'); - /* @var $post_helper PostHelper */ $manager = $post_helper->getSubscriptionManager('TopicPosts', Array ($object->GetID())); if ( $manager->subscribed() ) { $manager->unsubscribe(); } else { $manager->subscribe(); } } /** * Adds fields for forum preferences. * * @param kEvent $event Event. * * @return void */ protected function OnModifyUserProfileConfig(kEvent $event) { $checkbox_field = array( 'type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => array(1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, 'default' => 0, ); $text_field = array('type' => 'string', 'default' => ''); $new_virtual_fields = array( 'show_sig' => $checkbox_field, 'Perpage_Topics' => $text_field, 'Perpage_Postings' => $text_field, 'owner_notify' => $checkbox_field, 'bb_pm_notify' => $checkbox_field, 'bbcode' => $checkbox_field, 'smileys' => $checkbox_field, 'bb_signatures' => $checkbox_field, 'my_signature' => $text_field, ); $virtual_fields = $this->Application->getUnitOption( $event->MasterEvent->Prefix, 'VirtualFields', array() ); $this->Application->setUnitOption( $event->MasterEvent->Prefix, 'VirtualFields', array_merge($virtual_fields, $new_virtual_fields) ); } } Index: branches/5.2.x/units/helpers/post_helper.php =================================================================== --- branches/5.2.x/units/helpers/post_helper.php (revision 16514) +++ branches/5.2.x/units/helpers/post_helper.php (revision 16515) @@ -1,464 +1,464 @@ 128, 'disable_bbcode' => 64, 'disable_smileys' => 32, ); /** * Checks if specific option is set for post * * @param string $option_name * @param Array $options * @return bool */ function GetPostOption($option_name, $options) { if (!isset($this->postOptionBits[$option_name])) { return false; } $option_bit = $this->postOptionBits[$option_name]; return ($options & $option_bit) == $option_bit; } /** * Sets given option bit (by name) to post options * * @param string $option_name * @param int $option_value * @param Array $options * @return bool */ function SetPostOption($option_name, $option_value, &$options) { if (!isset($this->postOptionBits[$option_name])) { return false; } $option_bit = $this->postOptionBits[$option_name]; if ($option_value) { $options |= $option_bit; } else { $options = $options &~ $option_bit; } return true; } /** * Returns post options map to virtual field names * * @return Array */ function getOptionsMap() { $options_map = Array ( 'show_sig' => 'ShowSignatures', 'disable_smileys' => 'DisableSmileys', 'disable_bbcode' => 'DisableBBCodes', ); return $options_map; } /** * @return void * @param int $date * @desc Set any field to category & all it's parent categories */ function PropagateCategoryField($category_id, $field_name, $field_value) { $id_field = $this->Application->getUnitOption('c', 'IDField'); $table_name = $this->Application->getUnitOption('c', 'TableName'); $sql = 'SELECT ParentPath FROM ' . $table_name . ' WHERE ' . $id_field . ' = ' . $category_id; $parent_path = $this->Conn->GetOne($sql); $parent_categories = explode('|', substr($parent_path, 1, -1)); if ( !$parent_categories ) { return; } $fields_hash = Array ($field_name => $field_value); $this->Conn->doUpdate($fields_hash, $table_name, $id_field . ' IN (' . implode(',', $parent_categories) . ')'); } /** * Sets today posts count & today date for topic * * @param kCatDBItem $object * @param int $post_date * @param int $increment_by * @return bool */ function updateTodayPostsCount(&$object, $post_date, $increment_by = 1) { $date_now = adodb_date('Y-m-d'); if (adodb_date('Y-m-d', $post_date) != $date_now) { return true; } // last post update date was today or not $today_posts = ($date_now == $object->GetDBField('TodayDate')) ? $object->GetDBField('TodayPosts') : 0; $object->SetDBField('TodayDate', $date_now); $object->SetDBField('TodayPosts', $today_posts + $increment_by); return $object->Update(); } function updatePostCount($topic_id, $increment = 1) { $id_field = $this->Application->getUnitOption('bb', 'IDField'); $table_name = $this->Application->getUnitOption('bb', 'TableName'); // helps in case, when 2 (or more) users tries to post in same topic at same time $sql = 'UPDATE '.$table_name.' SET Posts = Posts '.($increment > 0 ? '+' : '-').' '.abs($increment).' WHERE '.$id_field.' = '.$topic_id; $this->Conn->Query($sql); // returns new value $sql = 'SELECT Posts FROM '.$table_name.' WHERE '.$id_field.' = '.$topic_id; return $this->Conn->GetOne($sql); } /** * Replaces all special formatting in post before displaing it to user * * @param string $post_body * @param int $post_options bit array of post options * @param Array $sub_blocks block names for rendering smileys & bbcodes * @return string */ function parsePostBody($post_body, $post_options, $sub_blocks) { // 1. escape all html sequences $post_body = htmlspecialchars($post_body, ENT_NOQUOTES, CHARSET); // don't touch quotes in bbcode attribute values // 2. replace censored words $post_body = $this->CensorText($post_body); // 3. replace bb codes if (!$this->GetPostOption('disable_bbcode', $post_options)) { $post_body = $this->replaceBBCodes($post_body, $sub_blocks['bbcode']); } // 4. replace smileys if (!$this->GetPostOption('disable_smileys', $post_options)) { $post_body = $this->replaceSmileys($post_body, $sub_blocks['smileys']); } // 5. add enters (because we don't use HTML in post body) $post_body = nl2br($post_body); // 6. replace quoted text return $this->replacePostQuote($post_body, $sub_blocks['quote']); } function replacePostQuote($text, $render_as) { if (preg_match('/\[quote id=([\d]+)\](.*)\[\/quote\]/s', $text, $regs)) { + /** @var kDBItem $post */ $post = $this->Application->recallObject('bb-post.-item', null, Array ('skip_autoload' => true)); - /* @var $post kDBItem */ $post->Load($regs[1]); $block_params = Array ('name' => $render_as, 'PrefixSpecial' => 'bb-post.-item', 'Prefix' => 'bb-post', 'Special' => '-item', 'strip_nl' => 2); $parsed_quote = $this->Application->ParseBlock($block_params); return str_replace($regs[0], $parsed_quote, $text); } return $text; } /** * Replaces bad words with good words (censorship process) * * @param string $text * @return string */ function CensorText($text) { static $censor_words = null; if (!isset($censor_words)) { $sql = 'SELECT Replacement, BadWord FROM '.TABLE_PREFIX.'Censorship'; $censor_words = $this->Conn->GetCol($sql, 'BadWord'); } foreach ($censor_words as $replace_from => $replace_to) { $text = str_replace($replace_from, $replace_to, $text); } return $text; } function replaceSmileys($text, $smiley_element) { static $smileys = null; if (!isset($smileys)) { $sql = 'SELECT em.EmotionImage, em.KeyStroke FROM '.TABLE_PREFIX.'Emoticon em WHERE em.Enabled = 1 ORDER BY CHAR_LENGTH(em.KeyStroke) DESC'; $smileys = $this->Conn->GetCol($sql, 'KeyStroke'); } $block_params = Array ('name' => $smiley_element, 'smiley_url' => '#SMILEY_URL#'); $smiley_mask = trim($this->Application->ParseBlock($block_params)); $base_url = rtrim($this->Application->BaseURL(),'/'); foreach ($smileys as $key_stoke => $image_url) { if (strpos($text, $key_stoke) === false) { continue; } $smiley_html = str_replace('#SMILEY_URL#', $base_url.SMILEYS_PATH.$image_url, $smiley_mask); $text = str_replace($key_stoke, $smiley_html, $text); } return $text; } /** * Sort params by name and then by length * * @param string $a * @param string $b * @return int * @access private */ function CmpParams($a, $b) { list ($a, ) = explode(':', $a); list ($b, ) = explode(':', $b); $a_len = strlen($a); $b_len = strlen($b); if ($a_len == $b_len) return 0; return $a_len > $b_len ? -1 : 1; } function replaceBBCodes($text, $bbcode_element) { // convert phpbb bbcodes to in-bulletin bbcodes $text = $this->preformatBBCodes($text); $tags_defs = explode(';', $this->Application->ConfigValue('BBTags')); // 'b:;i:;u:;ul:type|align;font:color|face|size;url:href;img:src|border'; usort($tags_defs, Array (&$this, 'CmpParams')); foreach($tags_defs as $tag) { list ($tag_name, $tag_params) = explode(':', $tag); $tag_params = $tag_params ? array_flip(explode('|', $tag_params)) : 0; $text = preg_replace('/\['.$tag_name.'(.*)\](.*)\[\/'.$tag_name.' *\]/Uise','$this->checkBBCodeAttribs("'.$tag_name.'",\'$1\',\'$2\',$tag_params);', $text); } // additional processing for [url], [*], [img] bbcode $text = preg_replace('/(.*)<\/url>/Usi','$1',$text); $text = preg_replace('/(.*)<\/font>/Usi','$1',$text); // skip empty fonts $text = str_replace( Array('','[*]'), Array('','
  • '), $text); // bbcode [code]xxx[/code] processing $text = preg_replace('/\[code\](.*)\[\/code\]/Uise', "\$this->replaceCodeBBCode('$1', '".$bbcode_element."')", $text); return $text; } /** * Convert phpbb url bbcode to valid in-bulletin's format * * @param string $text * @return string */ function preformatBBCodes($text) { // 1. urls $text = preg_replace('/\[url=(.*)\](.*)\[\/url\]/Ui','[url href="$1"]$2[/url]',$text); $text = preg_replace('/\[url\](.*)\[\/url\]/Ui','[url href="$1"]$1[/url]',$text); // 2. images $text = preg_replace('/\[img\](.*)\[\/img\]/Ui','[img src="$1" border="0"][/img]',$text); // 3. color $text = preg_replace('/\[color=(.*)\](.*)\[\/color\]/Ui','[font color="$1"]$2[/font]',$text); // 4. size $text = preg_replace('/\[size=(.*)\](.*)\[\/size\]/Ui','[font size="$1"]$2[/font]',$text); // 5. lists $text = preg_replace('/\[list(.*)\](.*)\[\/list\]/Uis','[ul]$2[/ul]',$text); // 6. email to link $text = preg_replace('/\[email\](.*)\[\/email\]/Ui','[url href="mailto:$1"]$1[/url]',$text); //7. b tag $text = preg_replace('/\[(b|i|u):(.*)\](.*)\[\/(b|i|u):(.*)\]/Ui','[$1]$3[/$4]',$text); //8. code tag $text = preg_replace('/\[code:(.*)\](.*)\[\/code:(.*)\]/Uis','[code]$2[/code]',$text); return $text; } /** * Removes not allowed params from tag and returns result * * @param string $BBCode bbcode to check * @param string $TagParams params string entered by user * @param string $TextInside text between opening and closing bbcode tag * @param string $ParamsAllowed list of allowed parameter names ("|" separated) * @return string */ function checkBBCodeAttribs($BBCode, $TagParams, $TextInside, $ParamsAllowed) { // unescape escaped quotes in tag $TagParams = str_replace('\"', '"', $TagParams); $TextInside = str_replace('\"', '"', $TextInside); $params_extracted = preg_match_all('/ +([^=]*)=["\']?([^ "\']*)["\']?/is', $TagParams, $extracted_params, PREG_SET_ORDER); if ($ParamsAllowed && $params_extracted) { $ret = Array(); foreach ($extracted_params as $param) { $param_name = strtolower(trim( $param[1] )); $param_value = trim($param[2]); // 1. prevent hacking if ($BBCode == 'url' && $param_name == 'href') { if (strpos(strtolower($param_value), 'script:') !== false) { // script tag found in "href" parameter of "url" bbcode (equals to hacking) -> remove bbcode return $TextInside; } } // 2. leave only allowed params & remove all not allowed if (isset($ParamsAllowed[$param_name])) { $ret[] = $param_name.'="'.$param_value.'"'; } } $ret = count($ret) ? ' '.implode(' ', $ret) : ''; return '<'.$BBCode.$ret.'>'.$TextInside.''; } return '<'.$BBCode.'>'.$TextInside.''; } function highlightCode($code, $strip_tabs = 0) { if ($strip_tabs) { $code = preg_replace('/(\t){'.$strip_tabs.'}(.*)/', '\\2', $code); } $code = str_replace( Array('\\', '/') , Array('_no_match_string_', '_n_m_s_'), $code); $code = highlight_string('', true); $code = str_replace( Array('_no_match_string_', '_n_m_s_'), Array('\\', '/'), $code); $code = preg_replace('/<\?(.*)php(.*)\?>/Us', '\\2', $code); $code = preg_replace('/([\r\n]+)/si', '', $code); $code = preg_replace('/([\r\n]+)<\/font>([\r\n]+)<\/code>/si', '', $code); return $code; } /** * Replaces [code]php code[/code] bbcode in post * * @param string $input_string code line to highlight * @param string $bbcode_element block name used for bbcode descoration * @return string * @see parsePostBody about why we unescape here. */ function replaceCodeBBCode($input_string, $bbcode_element) { static $bbcode_mask = null; if (!isset($bbcode_mask)) { $block_params = Array ('name' => $bbcode_element, 'bb_code' => '#BB_CODE#'); $bbcode_mask = trim($this->Application->ParseBlock($block_params)); } $input_string = trim(str_replace('\"', '"', kUtil::unescape($input_string, kUtil::ESCAPE_HTML))); $input_string = $this->highlightCode($input_string); $input_string = preg_replace("/\r
    /s", "\r", $input_string); // undo nl2br added in highlighting $input_string = str_replace('#BB_CODE#', $input_string, $bbcode_mask); return $input_string; } /** * Returns subscription manager by name * * @param string $name * @param array $arguments * @return kSubscriptionManager * @throws InvalidArgumentException */ public function getSubscriptionManager($name, $arguments = Array ()) { if ( $name != 'CategoryTopics' && $name != 'TopicPosts' ) { throw new InvalidArgumentException('Unknown subscription manager "' . $name . '"'); } + /** @var kSubscriptionManager $manager */ $manager = $this->Application->makeClass('kSubscriptionManager'); - /* @var $manager kSubscriptionManager */ $fields_hash = Array (); $user_id = isset($arguments[1]) ? $arguments[1] : $this->Application->RecallVar('user_id'); switch ( $name ) { case 'CategoryTopics': $category_id = isset($arguments[0]) ? $arguments[0] : $this->Application->GetVar('m_cat_id'); $fields_hash = Array ( 'EmailTemplateId' => $manager->getEmailTemplateId('TOPIC.ADD.SUB'), 'UserId' => $user_id, 'CategoryId' => $category_id, ); break; case 'TopicPosts': $fields_hash = Array ( 'EmailTemplateId' => $manager->getEmailTemplateId('POST.ADD.SUB'), 'UserId' => $user_id, 'ParentItemId' => $arguments[0], ); break; } $manager->add($fields_hash); return $manager; } } Index: branches/5.2.x/units/posts/post_eh.php =================================================================== --- branches/5.2.x/units/posts/post_eh.php (revision 16514) +++ branches/5.2.x/units/posts/post_eh.php (revision 16515) @@ -1,453 +1,453 @@ Name, $events) ) { return true; } return parent::CheckPermission($event); } /** * Sets default values * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemCreate(kEvent $event) { parent::OnBeforeItemCreate($event); + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ $user_id = $this->Application->RecallVar('user_id'); $now = adodb_mktime(); $object->SetDBField('CreatedById', $user_id); $object->SetDBField('CreatedOn_date', $now); $object->SetDBField('CreatedOn_time', $now); $object->SetDBField('ModifiedById', $user_id); $object->SetDBField('Modified_date', $now); $object->SetDBField('Modified_time', $now); $object->SetDBField('IPAddress', $this->Application->getClientIp()); $sql = 'SELECT Username FROM ' . TABLE_PREFIX . 'Users WHERE PortalUserId = ' . $user_id; $object->SetDBField('PosterAlias', $this->Conn->GetOne($sql)); // set post options + /** @var PostHelper $post_helper */ $post_helper = $this->Application->recallObject('PostHelper'); - /* @var $post_helper PostHelper */ $options_map = $post_helper->getOptionsMap(); $post_options = $object->GetDBField('Options'); foreach ($options_map as $option_name => $field_name) { $option_value = $object->GetDBField($field_name); $post_helper->SetPostOption($option_name, $option_value, $post_options); } $object->SetDBField('Options', $post_options); $table_info = $object->getLinkedInfo($event->Special, true); $object->SetDBField($table_info['ForeignKey'], $table_info['ParentId']); } /** * Checks if user has permission on post * * @param kEvent $event * @param string $permissions */ function checkPostPermission($event, $permissions) { + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ $sql = 'SELECT ci.CategoryId, p.CreatedById FROM '.$object->TableName.' p LEFT JOIN '.TABLE_PREFIX.'Topic t ON t.TopicId = p.TopicId LEFT JOIN '.TABLE_PREFIX.'CategoryItems ci ON ci.ItemResourceId = t.ResourceId AND ci.PrimaryCat = 1 WHERE p.'.$object->IDField.' = '.$object->GetID(); $post_info = $this->Conn->GetRow($sql); + /** @var kPermissionsHelper $perm_helper */ $perm_helper = $this->Application->recallObject('PermissionsHelper'); - /* @var $perm_helper kPermissionsHelper */ $is_owner = $post_info['CreatedById'] == $this->Application->RecallVar('user_id'); $params['permissions'] = 'TOPIC.REPLY.MODIFY|TOPIC.REPLY.OWNER.MODIFY'; $params['cat_id'] = $post_info['CategoryId']; return $perm_helper->TagPermissionCheck($params, $is_owner); } /** * Sets post options before post update * Ensures, that only user with permission will update topic * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemUpdate(kEvent $event) { parent::OnBeforeItemUpdate($event); + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ $perm_status = $this->checkPostPermission($event, 'TOPIC.REPLY.MODIFY|TOPIC.REPLY.OWNER.MODIFY'); if ( !$perm_status ) { $event->status = kEvent::erFAIL; return; } + /** @var PostHelper $post_helper */ $post_helper = $this->Application->recallObject('PostHelper'); - /* @var $post_helper PostHelper */ $options_map = $post_helper->getOptionsMap(); $post_options = $object->GetDBField('Options'); foreach ($options_map as $option_name => $field_name) { $option_value = $object->GetDBField($field_name); $post_helper->SetPostOption($option_name, $option_value, $post_options); } $object->SetDBField('Options', $post_options); } /** * Notifies admin about post change * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemUpdate(kEvent $event) { parent::OnAfterItemUpdate($event); $this->Application->emailAdmin('POST.MODIFY'); } /** * Checks, that user can delete post * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemDelete(kEvent $event) { parent::OnBeforeItemDelete($event); + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ if ( !$this->checkPostPermission($event, 'TOPIC.REPLY.OWNER.DELETE|TOPIC.REPLY.DELETE') ) { $event->status = kEvent::erFAIL; } } /** * Sets post options to virtual fields * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemLoad(kEvent $event) { parent::OnAfterItemLoad($event); + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ + /** @var PostHelper $post_helper */ $post_helper = $this->Application->recallObject('PostHelper'); - /* @var $post_helper PostHelper */ $options_map = $post_helper->getOptionsMap(); $post_options = $object->GetDBField('Options'); foreach ($options_map as $option_name => $field_name) { $option_value = $post_helper->GetPostOption($option_name, $post_options); $object->SetDBField($field_name, (int)$option_value); } } /** * Updates cached post counter in topic * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemCreate(kEvent $event) { parent::OnAfterItemCreate($event); + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ $parent_prefix = $this->Application->getUnitOption($event->Prefix, 'ParentPrefix'); + /** @var kCatDBItem $main_object */ $main_object = $this->Application->recallObject($parent_prefix); - /* @var $main_object kCatDBItem */ if ( $this->Application->LoggedIn() ) { // Update user posts counter. $user_posts = $this->Application->RecallPersistentVar('bb_posts'); $this->Application->StorePersistentVar('bb_posts', $user_posts + 1); } + /** @var PostHelper $post_helper */ $post_helper = $this->Application->recallObject('PostHelper'); - /* @var $post_helper PostHelper */ $category_id = $this->Application->GetVar('m_cat_id'); $post_helper->PropagateCategoryField($category_id, 'Modified', $object->GetDBField('CreatedOn')); if ( !$this->Application->isAdmin && $main_object->GetDBField('Posts') ) { // don't send any email events when in admin OR new topic just added (0 posts) $user_notified = false; // don't send POST.ADD event twice to same user (in case if owner adds new post) if ( $main_object->GetDBField('NotifyOwnerOnChanges') ) { $user_notified = $main_object->GetDBField('OwnerId'); $this->Application->emailUser('POST.ADD', $user_notified); } $post_owner_id = $object->GetDBField('CreatedById'); if ( ($post_owner_id > 0) && ($user_notified != $post_owner_id) ) { $this->Application->emailUser('POST.ADD', $post_owner_id); } $this->Application->emailAdmin('POST.ADD'); } $post_helper->updateTodayPostsCount($main_object, $object->GetDBField('CreatedOn'), +1); $this->updateTopicInfo($event, $main_object); $topic_id = $object->GetDBField('TopicId'); $posts_count = $post_helper->updatePostCount($topic_id, +1); $main_object->SetDBField('Posts', $posts_count); // auto-lock topic after N number of posts (if option enabled) $auto_lock = $this->Application->ConfigValue('AutoTopicLockPosts'); if ( (int)$auto_lock > 0 ) { if ( $posts_count >= $auto_lock ) { // user has unlocked topic after $auto_lock and posts again -> ensure that topic will be locked again $this->Application->HandleEvent(new kEvent($parent_prefix . ':OnTopicLockToggle')); } } } /** * Update last post info in topic * * @param kEvent $event * @param kCatDBItem $main_object */ function updateTopicInfo($event, &$main_object) { + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ $main_object->SetDBField('Modified_date', $object->GetDBField('Modified')); $main_object->SetDBField('Modified_time', $object->GetDBField('Modified')); $main_object->SetDBField('LastPostId', $object->GetID()); $main_object->SetDBField('LastPostDate_date', $object->GetDBField('CreatedOn')); $main_object->SetDBField('LastPostDate_time', $object->GetDBField('CreatedOn')); $main_object->Update(); } /** * Goes to next_template after post creation * * @param kEvent $event * @return void * @access protected */ protected function OnCreate(kEvent $event) { parent::OnCreate($event); if ( $event->status == kEvent::erSUCCESS && !$this->Application->isAdmin ) { $event->SetRedirectParam('opener', 's'); $event->redirect = $this->Application->GetVar('next_template'); } } /** * Goes to next_template after post editing * * @param kEvent $event * @return void * @access protected */ protected function OnUpdate(kEvent $event) { parent::OnUpdate($event); if ($event->status == kEvent::erSUCCESS && !$this->Application->isAdmin) { $event->SetRedirectParam('opener', 's'); $event->redirect = $this->Application->GetVar('next_template'); $event->SetRedirectParam('pass', 'm,bb'); } } /** * Moves reference to last post in topic, when it is deleted * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemDelete(kEvent $event) { parent::OnAfterItemDelete($event); + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ $topic_id = $object->GetDBField('TopicId'); if ( !$topic_id ) { // deleting post from non-existing topic return; } + /** @var PostHelper $post_helper */ $post_helper = $this->Application->recallObject('PostHelper'); - /* @var $post_helper PostHelper */ // update posts count in topic $post_helper->updatePostCount($topic_id, -1); // update post owner posts counter $sql = 'UPDATE ' . TABLE_PREFIX . 'UserPersistentSessionData SET VariableValue = IF (VariableValue > 0, VariableValue - 1, 0) WHERE (PortalUserId = ' . $object->GetDBField('CreatedById') . ') AND (VariableName = "bb_posts")'; $this->Conn->Query($sql); + /** @var kCatDBItem $main_object */ $main_object = $this->Application->recallObject('bb.-item', null, Array ('skip_autoload' => true)); - /* @var $main_object kCatDBItem */ $main_object->Load($topic_id); if ( !$main_object->isLoaded() ) { // this is topic deletion proccess, when all it's posts are deleted too return; } $post_helper->updateTodayPostsCount($main_object, $object->GetDBField('CreatedOn'), -1); if ( $main_object->GetDBField('LastPostId') == $object->GetID() ) { $sql = 'SELECT PostingId, CreatedOn FROM ' . $object->TableName . ' WHERE TopicId = ' . $topic_id . ' ORDER BY PostingId DESC'; $last_post = $this->Conn->GetRow($sql); $fields_hash = Array ( 'LastPostId' => $last_post['PostingId'], 'LastPostDate' => $last_post['CreatedOn'], ); $this->Conn->doUpdate($fields_hash, $main_object->TableName, $main_object->IDField . ' = ' . $topic_id); } } /** * Sets default values to posting options based on persistent session * * @param kEvent $event * @return void * @access protected */ protected function OnAfterConfigRead(kEvent $event) { parent::OnAfterConfigRead($event); if ( !$this->Application->LoggedIn() ) { return; } $virtual_fields = $this->Application->getUnitOption($event->Prefix, 'VirtualFields'); $virtual_fields['DisableBBCodes']['default'] = (int)!$this->Application->RecallPersistentVar('bbcode'); $virtual_fields['DisableSmileys']['default'] = (int)!$this->Application->RecallPersistentVar('smileys'); $virtual_fields['ShowSignatures']['default'] = (int)$this->Application->RecallPersistentVar('show_sig'); $this->Application->setUnitOption($event->Prefix, 'VirtualFields', $virtual_fields); } /** * Deletes items & preserves clean env * * @param kEvent $event * @return void * @access protected */ protected function OnDelete(kEvent $event) { parent::OnDelete($event); if ( $event->status == kEvent::erSUCCESS && !$this->Application->isAdmin ) { $parent_prefix = $this->Application->getUnitOption($event->Prefix, 'ParentPrefix'); $event->SetRedirectParam('pass', 'm,' . $parent_prefix); } } /** * Prepares new reply form * * @param kEvent $event * @return void * @access protected */ protected function OnNew(kEvent $event) { parent::OnNew($event); $reply_to = $this->Application->GetVar('reply_to'); if ( $reply_to > 0 ) { + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ + /** @var kDBItem $source_post */ $source_post = $this->Application->recallObject($event->Prefix . '.-item', null, Array ('skip_autoload' => true)); - /* @var $source_post kDBItem */ $source_post->Load($reply_to); $object->SetDBField('Subject', 'Re: ' . $source_post->GetDBField('Subject')); $object->SetDBField('PostingText', '[quote id=' . $reply_to . ']' . $source_post->GetDBField('PostingText') . '[/quote]'); } } } Index: branches/5.2.x/units/posts/post_tp.php =================================================================== --- branches/5.2.x/units/posts/post_tp.php (revision 16514) +++ branches/5.2.x/units/posts/post_tp.php (revision 16515) @@ -1,324 +1,326 @@ Application->getUnitOption($this->Prefix, 'ParentPrefix'); + + /** @var kCatDBItem $main_object */ $main_object = $this->Application->recallObject($parent_prefix); - /* @var $main_object kCatDBItem */ if ($main_object->isLoaded()) { $main_object->RegisterHit(); } return $this->PrintList2($params); } /** * Returns link to post author public profile * * @param Array $params * @return string */ function ProfileLink($params) { $object = $this->getObject($params); $params['user_id'] = $object->GetDBField('CreatedById'); return $this->Application->ProcessParsedTag('m', 'Link', $params); } function PosterField($params) { static $posters = null; + /** @var kDBItem $object */ $object = $this->getObject($params); - /* @var $object kDBItem */ + /** @var UsersItem $poster */ $poster = $this->Application->recallObject('u.poster', null, Array('skip_autoload' => true)); - /* @var $poster UsersItem */ if ( !isset($posters) ) { $poster_ids = array_unique( $object->GetCol('CreatedById') ); $sql = $poster->GetSelectSQL() . ' WHERE ' . $poster->TableName . '.' . $poster->IDField . ' IN (' . implode(',', $poster_ids) . ')'; $posters = $this->Conn->Query($sql, $poster->IDField); } $poster_id = $object->GetDBField('CreatedById'); if ($poster_id <= 0) { // guest and root users return ''; } if ($poster->GetID() != $poster_id) { // previous poster differs from requested $poster->LoadFromHash( $posters[$poster_id] ); } return $this->Application->ProcessParsedTag('u.poster', 'Field', $params); } /** * Checks if post is made by real user (not Guest or root) * * @param Array $params * @return bool */ function PosterFound($params) { $object = $this->getObject($params); return $object->GetDBField('CreatedById') > 0; } /** * Posts count created by current poster * * @param Array $params * @return int */ function PosterPostsCount($params) { static $posts_count = null; $object = $this->getObject($params); if (!isset($posts_count)) { $poster_ids = array_unique($object->GetCol('CreatedById')); $sql = 'SELECT VariableValue, PortalUserId FROM '.TABLE_PREFIX.'UserPersistentSessionData WHERE PortalUserId IN ('.implode(',', $poster_ids).') AND VariableName = "bb_posts"'; $posts_count = $this->Conn->GetCol($sql, 'PortalUserId'); } return $posts_count[$object->GetDBField('CreatedById')]; } function PostSubject($params) { $object = $this->getObject($params); + /** @var PostHelper $post_helper */ $post_helper = $this->Application->recallObject('PostHelper'); - /* @var $post_helper PostHelper */ return $post_helper->CensorText( $object->GetDBField('Subject') ); } function PostBody($params) { $object = $this->getObject($params); + /** @var PostHelper $post_helper */ $post_helper = $this->Application->recallObject('PostHelper'); - /* @var $post_helper PostHelper */ $body = $object->GetDBField('PostingText'); // 2. parse post body $sub_blocks = Array ( 'smileys' => $params['smiley_render_as'], 'bbcode' => $params['bbcode_render_as'], 'quote' => $params['quote_render_as'], ); $body = $post_helper->parsePostBody($body, $object->GetDBField('Options'), $sub_blocks); return $body; } /** * Checks if poster signature needs to be shown together with post. * * @param array $params Tag params. * * @return boolean */ protected function ShowPostSignature(array $params) { static $show_signatures; if ( !isset($show_signatures) ) { if ( $this->Application->LoggedIn() ) { $show_signatures = $this->Application->RecallPersistentVar('bb_signatures'); } else { $show_signatures = false; } } if ( !$show_signatures ) { return false; } /** @var kDBItem $object */ $object = $this->getObject($params); /** @var PostHelper $post_helper */ $post_helper = $this->Application->recallObject('PostHelper'); // Show poster signature in this post. if ( $post_helper->GetPostOption('show_sig', $object->GetDBField('Options')) ) { // Don't show signature when it is empty. $signature = $this->getUserSignature($object->GetDBField('CreatedById')); return strlen(trim($signature)) ? true : false; } return false; } /** * Returns parsed poster (from current post) signature * * @param Array $params * @return string */ function PostSignature($params) { $object = $this->getObject($params); + /** @var PostHelper $post_helper */ $post_helper = $this->Application->recallObject('PostHelper'); - /* @var $post_helper PostHelper */ $sub_blocks = Array ( 'smileys' => $params['smiley_render_as'], 'bbcode' => $params['bbcode_render_as'], ); $signature = $this->getUserSignature($object->GetDBField('CreatedById')); return $post_helper->parsePostBody($signature, $object->GetDBField('Options'), $sub_blocks); } /** * Returns user signature (cached for all viewed posts on page) * * @param int $user_id * @return string */ function getUserSignature($user_id) { static $user_signatures = null; $object = $this->getObject(); if (!isset($user_signatures)) { $poster_ids = array_unique($object->GetCol('CreatedById')); $sql = 'SELECT VariableValue, PortalUserId FROM '.TABLE_PREFIX.'UserPersistentSessionData WHERE PortalUserId IN ('.implode(',', $poster_ids).') AND VariableName = "my_signature"'; $user_signatures = $this->Conn->GetCol($sql, 'PortalUserId'); } $poster_id = $object->GetDBField('CreatedById'); return isset($user_signatures[$poster_id]) ? $user_signatures[$poster_id] : ''; } /** * Creates link to individual post in topic * * @param Array $params * @return string */ function PostLink($params) { $params['pass'] = 'm,bb,bb-post'; return $this->Application->ProcessParsedTag('m', 'Link', $params); } function ReplyQuotedLink($params) { $object = $this->getObject($params); $params['pass'] = 'm,bb'; $params['reply_to'] = $object->GetID(); return $this->Application->ProcessParsedTag('m', 'Link', $params); } /** * Checks if user have one of required permissions * * @param Array $params * @return bool */ function HasPermission($params) { static $category_path = null; if (!isset($category_path)) { // get topic category $parent_prefix = $this->Application->getUnitOption($this->Prefix, 'ParentPrefix'); $parent_item = $this->Application->recallObject($parent_prefix, null, Array ('raise_warnings' => 0)); $category_path = $parent_item->isLoaded() ? $parent_item->GetDBField('ParentPath') : $this->Application->GetVar('m_cat_id'); } + /** @var kPermissionsHelper $perm_helper */ $perm_helper = $this->Application->recallObject('PermissionsHelper'); - /* @var $perm_helper kPermissionsHelper */ $params['raise_warnings'] = 0; + + /** @var kDBItem $object */ $object = $this->getObject($params); - /* @var $object kDBItem */ // 1. category restriction $params['cat_id'] = $category_path; // 2. owner restriction $is_owner = $object->GetDBField('CreatedById') == $this->Application->RecallVar('user_id'); return $perm_helper->TagPermissionCheck($params, $is_owner); } function CategoryItemCount($params) { + /** @var kCountHelper $count_helper */ $count_helper = $this->Application->recallObject('CountHelper'); - /* @var $count_helper kCountHelper */ return $count_helper->CategoryItemCount('bb', $params, 'SUM(Posts)'); // - COUNT(TopicId) } function ItemCount($params) { + /** @var kCountHelper $count_helper */ $count_helper = $this->Application->recallObject('CountHelper'); - /* @var $count_helper kCountHelper */ $today_only = isset($params['today']) && $params['today']; return $count_helper->ItemCount('bb', $today_only, 'SUM(Posts)'); // - COUNT(TopicId) } /** * Preserve main item id in subitem pagination url * * @param Array $params * @return string */ function PageLink($params) { + /** @var kDBList $object */ $object = $this->getObject($params); - /* @var kDBList */ $parent_info = $object->getLinkedInfo(); if ($parent_info['ParentId'] > 0) { $params['pass'] = 'm,'.$this->getPrefixSpecial().','.$parent_info['ParentPrefix']; } return parent::PageLink($params); } } Index: branches/5.2.x/units/polls/poll_tp.php =================================================================== --- branches/5.2.x/units/polls/poll_tp.php (revision 16514) +++ branches/5.2.x/units/polls/poll_tp.php (revision 16515) @@ -1,126 +1,126 @@ getObject($params); - /* @var $object kDBItem */ if ( !$object->GetDBField('AllowMultipleVotings') ) { $where_clause = Array ( 'PollId = ' . $object->GetID(), 'CreatedById = ' . $this->Application->RecallVar('user_id'), 'UserIP = ' . $this->Conn->qstr($this->Application->getClientIp()), ); $sql = 'SELECT StatisticsId FROM ' . TABLE_PREFIX . 'PollsStatistics WHERE (' . implode(') AND (', $where_clause) . ')'; return $this->Conn->GetOne($sql) > 0; } return false; } /** * Allows to tell if user from current ip has voted already for current poll * * @param Array $params * @return bool */ function HasCommented($params) { + /** @var kDBItem $object */ $object = $this->getObject($params); - /* @var $object kDBItem */ + /** @var SpamHelper $spam_helper */ $spam_helper = $this->Application->recallObject('SpamHelper'); - /* @var $spam_helper SpamHelper */ $spam_helper->InitHelper($object->GetID(), 'PollComment', 0); // PollId used for SpamControl only return $spam_helper->InSpamControl(); } /** * Prints out only filled in answers of current poll * * @param Array $params * @return string */ function PrintPoll($params) { $object = $this->getObject($params); $sql = 'SELECT COUNT(AnswerNum), AnswerNum FROM '.TABLE_PREFIX.'PollsStatistics WHERE PollId = '.$object->GetID().' GROUP BY AnswerNum'; $statistics = $this->Conn->GetCol($sql, 'AnswerNum'); $total_votes = array_sum($statistics); $block_params = $this->prepareTagParams($params); $block_params['name'] = $params['render_as']; $i = 1; $ret = ''; while ($i < 8) { $answer = $object->GetDBField('Answer'.$i); if ($answer) { $answer_votes = isset($statistics[$i]) ? $statistics[$i] : 0; if ($total_votes > 0) { $block_params['percent'] = round((100 * $answer_votes) / $total_votes, 0); } else { $block_params['percent'] = 0; } $block_params['answer'] = $answer; $block_params['answer_num'] = $i; $ret .= $this->Application->ParseBlock($block_params); } $i++; } return $ret; } /** * Prints link to comments of of current poll * * @param Array $params * @return string */ function CommentsLink($params) { $object = $this->getObject($params); $params['pass'] = 'm,poll'; $params['poll_id'] = $object->GetID(); return $this->Application->ProcessParsedTag('m', 'Link', $params); } } \ No newline at end of file Index: branches/5.2.x/units/polls/poll_eh.php =================================================================== --- branches/5.2.x/units/polls/poll_eh.php (revision 16514) +++ branches/5.2.x/units/polls/poll_eh.php (revision 16515) @@ -1,171 +1,171 @@ Array ('self' => 'edit'), 'OnMakeVote' => Array ('self' => true), 'OnItemBuild' => Array ('self' => true), ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** * Applies special filter, that allows to select all poll from given date range * * @param kEvent $event * @return void * @access protected * @see kDBEventHandler::OnListBuild() */ protected function SetCustomQuery(kEvent $event) { parent::SetCustomQuery($event); if ( $this->Application->isAdminUser ) { return; } + /** @var kDBList $object */ $object = $event->getObject(); - /* @var $object kDBList */ $object->addFilter('poll_range_filter', '(%1$s.StartDate <= ' . adodb_mktime() . ') AND (%1$s.EndDate >= ' . adodb_mktime() . ' OR EndDate IS NULL)'); $object->addFilter('poll_status', '(%1$s.Status = ' . STATUS_ACTIVE . ')'); } /** * Reset votes statistics for current poll * * @param kEvent $event */ function OnResetVotes($event) { + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ $sql = 'DELETE FROM '.TABLE_PREFIX.'PollsStatistics WHERE '.$object->IDField.' = '.$object->GetID(); $this->Conn->Query($sql); $poll_answers_table = $this->Application->getUnitOption('poll-answer', 'TableName'); $poll_answers_table = $this->Application->GetTempName($poll_answers_table); $sql = 'UPDATE '.$poll_answers_table.' SET VotesQty = 0 WHERE '.$object->IDField.' = '.$object->GetID(); $this->Conn->Query($sql); } /** * Sets resource id * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemCreate(kEvent $event) { parent::OnBeforeItemCreate($event); + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ $object->SetDBField('ResourceId', $this->Application->NextResourceId()); } /** * Make vote to current poll * * @param kEvent $event */ function OnMakeVote($event) { + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ $poll_answer_id = $this->Application->GetVar('option_id'); if (!$poll_answer_id) { $event->redirect = false; return ; } $ip_address = $this->Application->getClientIp(); if (!$object->GetDBField('AllowMultipleVotings')) { $sql = 'SELECT StatisticsId FROM '.TABLE_PREFIX.'PollsStatistics WHERE PollId = '.$object->GetID().' AND UserIP = '.$this->Conn->qstr($ip_address); $voted = $this->Conn->GetOne($sql) > 0; } if (!$voted) { $user_id = $this->Application->RecallVar('user_id'); $fields_hash = Array ( 'PollId' => $object->GetID(), 'AnswerId' => $poll_answer_id, 'UserIP' => $ip_address, 'CreatedById' => $user_id, 'AnswerDate' => adodb_mktime(), ); $this->Conn->doInsert($fields_hash, TABLE_PREFIX.'PollsStatistics'); $poll_table = $this->Application->getUnitOption('poll', 'TableName'); $this->Conn->Query('UPDATE '.$poll_table.' SET CachedVotesQty = CachedVotesQty + 1 WHERE PollId = '.$object->GetID()); // update table with answers $poll_answers_table = $this->Application->getUnitOption('poll-answer', 'TableName'); $this->Conn->Query('UPDATE '.$poll_answers_table.' SET VotesQty = VotesQty + 1 WHERE PollId = '.$object->GetID().' AND AnswerId = '.$poll_answer_id); } $event->setEventParam('PollId', $this->Application->GetVar('poll_id')); $event->redirect = false; } /** * Cleanup by removing items from PollStatistics before Poll is deleted * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemDelete(kEvent $event) { parent::OnAfterItemDelete($event); + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ $sql = 'DELETE FROM ' . TABLE_PREFIX . 'PollsStatistics WHERE PollId = ' . $object->GetID(); $this->Conn->Query($sql); } } \ No newline at end of file Index: branches/5.2.x/units/poll_comments/poll_comment_eh.php =================================================================== --- branches/5.2.x/units/poll_comments/poll_comment_eh.php (revision 16514) +++ branches/5.2.x/units/poll_comments/poll_comment_eh.php (revision 16515) @@ -1,176 +1,176 @@ Array ('self' => true, 'subitem' => true,), 'OnItemBuild' => Array ('self' => true, 'subitem' => true,), ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** * Occurs, when config was parsed, allows to change config data dynamically * * @param kEvent $event * @return void * @access protected */ protected function OnAfterConfigRead(kEvent $event) { parent::OnAfterConfigRead($event); if ( $this->Application->RecallVar('user_id') == USER_GUEST ) { // make Guest Name and Email required for guests $fields = $this->Application->getUnitOption($event->Prefix, 'Fields'); $fields['GuestName']['required'] = 1; $fields['GuestEmail']['required'] = 1; $this->Application->setUnitOption($event->Prefix, 'Fields', $fields); } } /** * Applies special filter, that allows to select all commented from current poll * * @param kEvent $event * @return void * @access protected * @see kDBEventHandler::OnListBuild() */ protected function SetCustomQuery(kEvent $event) { parent::SetCustomQuery($event); if ( $this->Application->isAdminUser ) { return; } + /** @var kDBList $object */ $object = $event->getObject(); - /* @var $object kDBList */ $object->addFilter('comment_status', '%1$s.Status = ' . STATUS_ACTIVE); } /** * Occurs before creating item * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemCreate(kEvent $event) { if ( !$this->Application->isAdmin ) { + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ $parent_info = $object->getLinkedInfo($event->Special); $poll_id = $parent_info['ParentId']; if ( $poll_id ) { + /** @var SpamHelper $spam_helper */ $spam_helper = $this->Application->recallObject('SpamHelper'); - /* @var $spam_helper SpamHelper */ $spam_helper->InitHelper($poll_id, 'PollComment', 0); // ResourceId used for SpamControl only if ( $spam_helper->InSpamControl() ) { $event->status = kEvent::erFAIL; $object->SetError('CommentBody', 'too_frequent', 'lu_error_AlreadyCommented'); return ; } $object->SetDBField('PollId', $poll_id); // PollId } $object->SetDBField('CreatedById', $this->Application->RecallVar('user_id')); $object->SetDBField('UserIP', $this->Application->getClientIp()); $object->SetDBField('Status', STATUS_ACTIVE); } parent::OnBeforeItemCreate($event); } /** * Updates item review counter * * @param kEvent $event * @return void * @access protected */ protected function OnCreate(kEvent $event) { parent::OnCreate($event); if ( !$this->Application->isAdmin && $event->status == kEvent::erSUCCESS ) { $event->setRedirectParam('opener', 's'); $event->setRedirectParam('pass', 'm,poll'); } } /** * Wrapper for OnCreate event * * @param kEvent $event * * @return void * @access protected */ protected function OnCreateAjax(kEvent $event) { + /** @var AjaxFormHelper $ajax_form_helper */ $ajax_form_helper = $this->Application->recallObject('AjaxFormHelper'); - /* @var $ajax_form_helper AjaxFormHelper */ $ajax_form_helper->transitEvent($event, 'OnCreate'); } /** * Protects against spam * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemCreate(kEvent $event) { parent::OnAfterItemCreate($event); if ( !$this->Application->isAdminUser ) { + /** @var SpamHelper $spam_helper */ $spam_helper = $this->Application->recallObject('SpamHelper'); - /* @var $spam_helper SpamHelper */ + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ $comment_settings = 'poll_CommentDelay_Value:poll_CommentDelay_Interval'; $spam_helper->InitHelper($object->GetDBField('PollId'), 'PollComment', $comment_settings); $spam_helper->AddToSpamControl(); } } } \ No newline at end of file Index: branches/5.2.x/units/private_message_body/private_message_body_eh.php =================================================================== --- branches/5.2.x/units/private_message_body/private_message_body_eh.php (revision 16514) +++ branches/5.2.x/units/private_message_body/private_message_body_eh.php (revision 16515) @@ -1,64 +1,64 @@ getObject(); - /* @var $object kDBItem */ // set post options + /** @var PostHelper $post_helper */ $post_helper = $this->Application->recallObject('PostHelper'); - /* @var $post_helper PostHelper */ $options_map = $post_helper->getOptionsMap(); $post_options = $object->GetDBField('Options'); foreach ($options_map as $option_name => $field_name) { $option_value = $object->GetDBField($field_name); $post_helper->SetPostOption($option_name, $option_value, $post_options); } $object->SetDBField('Options', $post_options); } /** * Deletes message body only when no message is using it * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemDelete(kEvent $event) { parent::OnBeforeItemDelete($event); + /** @var kDBItem $object */ $object = $event->getObject(); - /* @var $object kDBItem */ if ( $object->GetDBField('ReferenceCount') > 0 ) { $event->status = kEvent::erFAIL; } } } \ No newline at end of file Index: branches/5.2.x/install.php =================================================================== --- branches/5.2.x/install.php (revision 16514) +++ branches/5.2.x/install.php (revision 16515) @@ -1,58 +1,58 @@ toolkit; - /* @var $toolkit kInstallToolkit */ } $application =& kApplication::Instance(); $application->Init(); if ( $application->RecallVar('user_id') != USER_ROOT ) { die('restricted access!'); } $category =& $toolkit->createModuleCategory('Forums', 'Discussion Forums', '#in-bulletin/section_design#', 'in-bulletin/img/menu_topics.gif'); $toolkit->RunSQL('/' . $module_folder . '/install/install_schema.sql'); $toolkit->RunSQL('/' . $module_folder . '/install/install_data.sql', '{TopicCatId}', $category->GetID()); $toolkit->ImportLanguage('/' . $module_folder . '/install/english', isset($constants_file)); $toolkit->SetModuleRootCategory(basename($module_folder), $category->GetID()); //$toolkit->linkCustomFields(basename($module_folder), 'bb', 3); // to create Custom Fields for Topics $toolkit->linkCustomFields('KERNEL', 'c', 1); // to create ItemTemplate custom field $toolkit->setModuleItemTemplate($category, 'bb', '#in-bulletin/item_design#'); $toolkit->finalizeModuleInstall($module_folder, true);