コード例 #1
0
 public function getUrl()
 {
     if (empty($this->arguments['username'])) {
         $userInfo = vB_Api::instanceInternal('user')->fetchProfileInfo($this->arguments['userid']);
         $this->arguments['username'] = $userInfo['username'];
     }
     // the regex contains the url
     $url = '/' . $this->prefix . '/' . $this->arguments['userid'] . '-' . vB_String::getUrlIdent($this->arguments['username']) . '/' . $this->arguments['tab'];
     if (isset($this->arguments['pagenum']) and is_numeric($this->arguments['pagenum']) and $this->arguments['pagenum'] > 1) {
         $url .= '/page' . intval($this->arguments['pagenum']);
     }
     if (strtolower(vB_String::getCharset()) != 'utf-8') {
         $url = vB_String::encodeUtf8Url($url);
     }
     return $url;
 }
コード例 #2
0
 public function __construct($routeInfo, $matches, $queryString = '', $anchor = '')
 {
     if (empty($matches['tab'])) {
         $matches['tab'] = 'profile';
     }
     parent::__construct($routeInfo, $matches, $queryString, $anchor);
     if (empty($this->arguments['userid'])) {
         $userInfo = vB::getCurrentSession()->fetch_userinfo();
         $this->arguments['userid'] = $userInfo['userid'];
         $this->arguments['username'] = $userInfo['username'];
     } else {
         if (empty($this->arguments['username'])) {
             $userInfo = vB_User::fetchUserinfo($this->arguments['userid']);
             $this->arguments['username'] = $userInfo['username'];
         }
     }
     $this->breadcrumbs = array(0 => array('title' => $this->arguments['username'], 'url' => vB5_Route::buildUrl('profile', array('userid' => $this->arguments['userid'], 'username' => vB_String::getUrlIdent($this->arguments['username'])))), 1 => array('phrase' => 'user_settings', 'url' => ''));
 }
コード例 #3
0
ファイル: node.php プロジェクト: cedwards-reisys/nexus-web
 /**
  * Moves nodes to a new parent
  *
  * @param	array	Node ids
  * @param	int	New parent node id
  * @param	bool	Make topic
  * @param	bool	New title
  * @param	bool	Mod log
  * @param	array	Information to leave a thread redirect. If empty, no redirect is created.
  *			If not empty, should contain these items:
  *				redirect (string) - perm|expires	Permanent or expiring redirect
  *				frame (string) - h|d|w|m|y	Hours, days, weeks, months, years (valid only for expiring redirects)
  *				period (int) - 1-10	How many hours, days, weeks etc, for the expiring redirect
  *
  * @return
  */
 public function moveNodes($nodeids, $to_parent, $makeTopic = false, $newtitle = false, $modlog = true, array $leaveRedirectData = array())
 {
     $movedNodes = array();
     $oldnodeInfo = array();
     $to_parent = $this->assertNodeidStr($to_parent);
     $userContext = vB::getUserContext();
     $currentUserid = vB::getCurrentSession()->get('userid');
     $channelAPI = vB_Api::instanceInternal('content_channel');
     $newparent = $this->getNode($to_parent);
     // If all the nodes to be moved are content nodes and are currently in the same
     // channel, then we are only merging posts/topics and need to check different permissions.
     // To detemine this, we iterate through all the nodes to be moved and get all the "starter"
     // nodeids. We then iterate through all the starters and check if they all have the same
     // parentid, which is the channel they are in.
     $isTopicMerge = false;
     $checkNodes = $this->getNodes(array_merge((array) $nodeids, (array) $to_parent));
     $skipCheck = false;
     $checkStarterIds = array();
     foreach ($checkNodes as $checkNode) {
         if (empty($checkNode['starter'])) {
             // we can skip this check because one of the nodes is a channel
             $skipCheck = true;
             break;
         } else {
             $checkStarterIds[] = $checkNode['starter'];
         }
     }
     if (!$skipCheck) {
         $checkStarters = $this->getNodes($checkStarterIds);
         $starterParents = array();
         foreach ($checkStarters as $checkStarter) {
             $starterParents[$checkStarter['parentid']] = $checkStarter['parentid'];
         }
         if (count($starterParents) === 1) {
             // the parent node of all the starters is the same, so we are
             // only moving topics / posts around inside the same channel,
             // this is likely a topic merge request and we can check a separate
             // permission below
             $isTopicMerge = true;
         }
         unset($checkStarters, $checkStarter, $starterParents);
     }
     unset($checkNode, $checkStarterIds, $skipCheck);
     //If the current user has can moderator canmove on the current nodes, or if the user can create in
     //the new channel and is the owner of the moved nodes and has forum canmove, then they can move
     if (!$userContext->getChannelPermission('forumpermissions', 'canmove', $to_parent) and !$userContext->getChannelPermission('moderatorpermissions', 'canmassmove', $to_parent) and (!$isTopicMerge or !$userContext->getChannelPermission('moderatorpermissions', 'canmanagethreads', $to_parent))) {
         throw new vB_Exception_Api('no_permission');
     }
     $nodes = vB::getDbAssertor()->getRows('vBForum:node', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, 'nodeid' => $nodeids), array('field' => array('publishdate'), 'direction' => array(vB_dB_Query::SORT_ASC)), 'nodeid');
     $needRebuild = false;
     $firstTitle = false;
     $loginfo = array();
     $parent = $this->getNodeFullContent($to_parent);
     $parent = $parent[$to_parent];
     $cacheEvents = array($to_parent);
     $oldparents = array();
     $channelTypeid = vB_Types::instance()->getContentTypeId('vBForum_Channel');
     $infractionTypeid = vB_Types::instance()->getContentTypeId('vBForum_Infraction');
     foreach ($nodes as $node) {
         if ($node['contenttypeid'] == $infractionTypeid) {
             throw new vB_Exception_Api('cannot_move_infraction_nodes');
         }
         if ($node['contenttypeid'] == $channelTypeid) {
             // If any of the moved nodes are channels, the target must be a channel.
             if ($newparent['contenttypeid'] != $channelTypeid) {
                 throw new vB_Exception_Api('invalid_request');
             }
             // We should not allow the moving of channels from one root channel to another.
             if ($channelAPI->getTopLevelChannel($newparent['nodeid']) != $channelAPI->getTopLevelChannel($node['nodeid'])) {
                 throw new vB_Exception_Api('cant_change_top_level');
             }
         }
         //Only channels can be moved to categories, UI shouldn't allow this
         if ($parent['contenttypeid'] == $channelTypeid) {
             $newrouteid = vB_Api::instanceInternal('route')->getChannelConversationRoute($to_parent);
             if ($node['contenttypeid'] != $channelTypeid and (empty($newrouteid) or !empty($parent['category']))) {
                 // The node we want to move is not a channel and the parent cannot have conversations
                 // (e.g. categories, the root blog channel, the root forum channel)
                 throw new vB_Exception_Api('invalid_request');
             }
         }
         if ($node['contenttypeid'] == vB_Types::instance()->getContentTypeID('vBForum_Channel')) {
             $needRebuild = true;
         }
         if ($userContext->getChannelPermission('moderatorpermissions', 'canmassmove', $node['nodeid']) or $currentUserid == $node['userid'] and $userContext->getChannelPermission('forumpermissions', 'canmove', $node['nodeid'], false, $node['parentid']) or $isTopicMerge and $userContext->getChannelPermission('moderatorpermissions', 'canmanagethreads', $to_parent)) {
             if (empty($movedNodes)) {
                 if (empty($node['title']) and !empty($node['starter'])) {
                     $starter = vB_Library::instance('node')->getNodeBare($node['starter']);
                     $firstTitle = $starter['title'];
                 } else {
                     $firstTitle = $node['title'];
                 }
             }
             $movedNodes[] = $node['nodeid'];
             $oldnodeInfo[$node['nodeid']] = $node;
             $oldparents[$node['nodeid']] = $node['parentid'];
             $this->contentLibs[$node['nodeid']] = vB_Library::instance('Content_' . vB_Types::instance()->getContentTypeClass($node['contenttypeid']));
             if ($modlog) {
                 $oldparent = $this->getNode($node['parentid']);
                 $extra = array('fromnodeid' => $oldparent['nodeid'], 'fromtitle' => $oldparent['title'], 'tonodeid' => $newparent['nodeid'], 'totitle' => $newparent['title']);
                 $loginfo[] = array('nodeid' => $node['nodeid'], 'nodetitle' => $node['title'], 'nodeusername' => $node['authorname'], 'nodeuserid' => $node['userid'], 'action' => $extra);
             }
             if (!in_array($node['parentid'], $cacheEvents)) {
                 $cacheEvents[] = $node['parentid'];
             }
             if (!in_array($node['starter'], $cacheEvents) and intval($node['starter'])) {
                 $cacheEvents[] = $node['starter'];
             }
         } else {
             throw new vB_Exception_Api('no_permission');
         }
     }
     if (empty($movedNodes)) {
         return false;
     }
     //can't move a node to its decendant, we like proper trees.
     $db = vB::getDbAssertor();
     $row = $db->getRow('vBForum:closure', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, 'parent' => $movedNodes, 'child' => $to_parent, vB_Db_Query::PARAM_LIMIT => 1));
     if (!empty($row)) {
         throw new vB_Exception_Api('move_node_to_child');
     }
     //back out counts for the nodes about to be moved.
     //keep track of the parentids to so we can update the last content after
     //we've moved things around.
     $lastContentParents = array();
     foreach ($movedNodes as $nodeid) {
         $node = $this->getNode($nodeid);
         $movedNodeParents = $this->getParents($nodeid);
         $parentids = array();
         foreach ($movedNodeParents as $movedNodeParent) {
             if ($movedNodeParent['nodeid'] != $nodeid) {
                 $parentids[] = $movedNodeParent['nodeid'];
                 $lastContentParents[] = $movedNodeParent['nodeid'];
             }
         }
         $this->updateAddRemovedNodeParentCounts($node, $node, $node['showpublished'], false, $parentids);
     }
     if ($parent['contenttypeid'] == $channelTypeid and $makeTopic) {
         if (empty($newtitle)) {
             if (!empty($firstTitle)) {
                 $newtitle = $firstTitle;
             } else {
                 throw new vB_Exception_Api('notitle');
             }
         }
         $newchildid = $movedNodes[0];
         $this->moveNodesInternal(array($newchildid), $newparent);
         // We need to promote give the new node the correct title
         vB::getDbAssertor()->assertQuery('vBForum:node', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_UPDATE, 'routeid' => vB_Api::instanceInternal('route')->getChannelConversationRoute($to_parent), 'title' => $newtitle, 'htmltitle' => vB_String::htmlSpecialCharsUni(vB_String::stripTags($newtitle), false), 'urlident' => vB_String::getUrlIdent($newtitle), 'description' => $newtitle, vB_dB_Query::CONDITIONS_KEY => array('nodeid' => $movedNodes[0])));
         if (count($movedNodes) > 1) {
             $grandchildren = array_slice($movedNodes, 1);
             $this->moveNodesInternal($grandchildren, $checkNodes[$newchildid]);
         }
         //moving the grandchildren under the first node may have changed it's last child info
         $db->assertQuery('vBForum:updateLastData', array('parentid' => $newchildid, 'timenow' => vB::getRequest()->getTimeNow()));
         $node = $this->getNode($newchildid);
         $this->updateSubTreePublishStatus($node, $newparent['showpublished']);
     } else {
         $this->moveNodesInternal($movedNodes, $newparent);
         foreach ($movedNodes as $nodeid) {
             $node = $this->getNode($nodeid);
             $this->updateSubTreePublishStatus($node, $newparent['showpublished']);
         }
     }
     //dedup the array (so we don't update a node more than once) but we need to
     //do so in a particular way.  We always want to keep the *last* occurance
     //of any id in the array.  This ensures that a node is not updated before
     //any of its decendants (which could cause bad results).
     $seen = array();
     foreach ($lastContentParents as $key => $parentid) {
         if (isset($seen[$parentid])) {
             unset($lastContentParents[$seen[$parentid]]);
         }
         $seen[$parentid] = $key;
     }
     //we can't do this before we move the nodes because the parent/child relationships haven't
     //changed yet.
     foreach ($lastContentParents as $parentid) {
         $this->fixNodeLast($parentid);
     }
     $userid = vB::getCurrentSession()->get('userid');
     // afterMove requires some ancestors info which we just changed above, let's clear cache before updating
     $searchAPI = vB_Api::instanceInternal('search');
     foreach ($movedNodes as $nodeid) {
         vB_Cache::instance()->allCacheEvent('nodeChg_' . $nodeid);
         //some search information may have changed, let's check
         $searchAPI->attributeChanged($nodeid);
     }
     // Leave a thread redirect if required
     // Note: UI only allows leaving a redirect when moving a thread which is one node
     if (!empty($leaveRedirectData) and count($movedNodes) == 1 and count($nodes) == 1) {
         $node = reset($nodes);
         $redirectData = array('title' => $node['title'], 'urlident' => $node['urlident'], 'parentid' => $node['parentid'], 'tonodeid' => $node['nodeid'], 'userid' => $node['userid'], 'publishdate' => $node['publishdate'], 'created' => $node['created']);
         // handle expiring redirects
         if (isset($leaveRedirectData['redirect']) and $leaveRedirectData['redirect'] == 'expires') {
             $period = (int) isset($leaveRedirectData['period']) ? $leaveRedirectData['period'] : 1;
             $frame = (string) isset($leaveRedirectData['frame']) ? $leaveRedirectData['frame'] : 'm';
             $period = max(min($period, 10), 1);
             $frame = in_array($frame, array('h', 'd', 'w', 'm', 'y'), true) ? $frame : 'm';
             $frames = array('h' => 3600, 'd' => 86400, 'w' => 86400 * 7, 'm' => 86400 * 30, 'y' => 86400 * 365);
             $redirectData['unpublishdate'] = vB::getRequest()->getTimeNow() + $period * $frames[$frame];
         }
         // skip any text spam checks, because a redirect has no text to check.
         vB_Library::instance('content_redirect')->add($redirectData, array('skipSpamCheck' => true));
     }
     vB_Api::instance('Search')->purgeCacheForCurrentUser();
     vB_Library_Admin::logModeratorAction($loginfo, 'node_moved_by_x');
     $cacheEvents = array_unique(array_merge($movedNodes, $cacheEvents, array($to_parent)));
     $this->clearChildCache($cacheEvents);
     $this->clearCacheEvents($cacheEvents);
     if ($needRebuild) {
         vB::getUserContext()->rebuildGroupAccess();
         vB_Channel::rebuildChannelTypes();
     }
     return $movedNodes;
 }
コード例 #4
0
 public function getUrl()
 {
     if (empty($this->arguments['title'])) {
         $node = vB_Library::instance('node')->getNodeBare($this->arguments['nodeid']);
         if (empty($node) or !empty($node['errors'])) {
             return FALSE;
         }
         if ($node['urlident']) {
             $this->arguments['title'] = $node['urlident'];
         } else {
             $this->arguments['title'] = vB_String::getUrlIdent($node['title']);
         }
     }
     if (empty($this->arguments['userid'])) {
         if (!isset($node['nodeid'])) {
             $node = vB_Library::instance('node')->getNodeBare($this->arguments['nodeid']);
         }
         if ($node['setfor']) {
             $user = vB_User::fetchUserinfo($node['setfor']);
             $this->arguments['userid'] = $user['userid'];
             $this->arguments['username'] = $user['username'];
         }
     }
     $url = '/member/' . $this->arguments['userid'] . '-' . vB_String::getUrlIdent($this->arguments['username']) . '/visitormessage/' . $this->arguments['nodeid'] . '-' . vB_String::vBStrToLower(vB_String::htmlSpecialCharsUni(str_replace(' ', '-', $this->arguments['title'])));
     if (strtolower(vB_String::getCharset()) != 'utf-8') {
         $url = vB_String::encodeUtf8Url($url);
     }
     return $url;
 }
コード例 #5
0
ファイル: gallery.php プロジェクト: cedwards-reisys/nexus-web
 /**
  * Updates from a web save
  *
  * @param  int The id in the primary table
  *
  * @return int Number of updates-standard save response.
  */
 public function updateFromWeb($nodeid, $postdata, $filedataids = array())
 {
     //First do we have a nodeid?
     if (!$nodeid or !intval($nodeid) or !$this->validate($postdata, parent::ACTION_UPDATE, $nodeid)) {
         throw new Exception('invalid_data');
     }
     $data = array();
     //And are we authorized to make changes?
     if (!$this->validate($data, parent::ACTION_UPDATE, $nodeid)) {
         throw new Exception('no_permission');
     }
     if (isset($postdata['title'])) {
         $postdata['urlident'] = vB_String::getUrlIdent($postdata['title']);
     }
     $existing = $this->getContent($nodeid);
     $existing = $existing[$nodeid];
     $cleaner = vB::getCleaner();
     //clean the gallery data.
     $fields = array('title' => vB_Cleaner::TYPE_STR, 'caption' => vB_Cleaner::TYPE_STR, 'htmltitle' => vB_Cleaner::TYPE_STR, 'rawtext' => vB_Cleaner::TYPE_STR, 'reason' => vB_Cleaner::TYPE_STR, 'keyfields' => vB_Cleaner::TYPE_STR, 'publishdate' => vB_Cleaner::TYPE_UINT, 'unpublishdate' => vB_Cleaner::TYPE_UINT, 'description' => vB_Cleaner::TYPE_STR, 'displayorder' => vB_Cleaner::TYPE_UINT, 'urlident' => vB_Cleaner::TYPE_STR, 'tags' => vB_Cleaner::TYPE_STR, 'enable_comments' => vB_Cleaner::TYPE_BOOL, 'parentid' => vB_Cleaner::TYPE_UINT, 'viewperms' => vB_Cleaner::TYPE_UINT, 'attachments' => vB_Cleaner::TYPE_NOCLEAN, 'removeattachments' => vB_Cleaner::TYPE_NOCLEAN);
     // copy data before they're dropped by the cleaner. These will be cleaned separately just a few lines down.
     $unclean['attachments'] = isset($postdata['attachments']) ? $postdata['attachments'] : array();
     $unclean['removeattachments'] = isset($postdata['removeattachments']) ? $postdata['removeattachments'] : array();
     $cleaned = $cleaner->cleanArray($postdata, $fields);
     // just unset the uncleaned ones. They're cleaned & set again below. I would've just unset them from
     // $postdata before it was tossed into cleanArray(), but there's special logic a few blocks down that
     // requires keys in $fields to be set in both $postdata & $cleaned for it to be sent into update()
     unset($cleaned['attachments']);
     unset($cleaned['removeattachments']);
     if (!empty($unclean['attachments'])) {
         // keep these fields in sync with controller's addAttachments()
         $attachfields = array('filedataid' => vB_Cleaner::TYPE_UINT, 'filename' => vB_Cleaner::TYPE_STR, 'settings' => vB_Cleaner::TYPE_STR);
         foreach ($unclean['attachments'] as $key => $attachdata) {
             $key = (int) $key;
             $cleaned['attachments'][$key] = $cleaner->cleanArray($attachdata, $attachfields);
         }
         unset($unclean['attachments']);
     }
     if (!empty($unclean['removeattachments'])) {
         // keep these fields in sync with controller's addAttachments()
         foreach ($unclean['removeattachments'] as $key => $attachnodeid) {
             $key = (int) $key;
             $cleaned['removeattachments'][$key] = (int) $attachnodeid;
         }
         unset($unclean['removeattachments']);
     }
     $updates = array();
     //viewperms can only be 0, 1, or 2
     if (empty($cleaned['viewperms']) or $cleaned['viewperms'] > 2 or $cleaned['viewperms'] < 0) {
         $cleaned['viewperms'] = 2;
     }
     /*
      *	Okay, I"m pretty sure the below isn't doing what was originally intended,
      *	judging by the comment & the fact that we grab the pre-update node values,
      *	$existing, above.
      *	I'm guessing what was *supposed* to happen is that each $iteam in $cleaned
      *	is compared against $existing's data, and is set to $updates only if it's
      *	different.
      *	However, there's been a lot of changes to the various bits of content
      *	update() code, so I'm afraid to unset things from $updates now.
      *	If anyone is going to edit below, make sure that handling for
      *	$cleaned['attachments']and $cleaned['removeattachments'] are proplery
      *	dealt with, otherwise there will be issues when editing a gallery post
      *	and adding/removing attachments.
      */
     //If nothing has changed we don't need to update the parent.
     foreach (array_keys($fields) as $fieldname) {
         if (isset($postdata[$fieldname]) and isset($cleaned[$fieldname])) {
             $updates[$fieldname] = $cleaned[$fieldname];
         }
     }
     $results = true;
     if (!empty($updates)) {
         $results = $this->update($nodeid, $updates);
     }
     if ($results and (!is_array($results) or empty($results['errors']))) {
         //let's get the current photo information;
         $existing = $this->getContent($nodeid);
         $existing = $existing[$nodeid];
         if (empty($existing['photo'])) {
             $delete = array();
         } else {
             $delete = $existing['photo'];
         }
         //Now we match the submitted data against the photos
         //if they match, we remove from "delete" and do nothing else.
         //if the title is updated we do an immediate update.
         //Otherwise we add.
         if (!empty($filedataids) and is_array($filedataids)) {
             $photoApi = vB_Api::instanceInternal('content_photo');
             foreach ($filedataids as $filedataid => $title) {
                 //it has to be at least a integer.
                 if (intval($filedataid)) {
                     //First see if we have a match.
                     $foundMatch = false;
                     foreach ($delete as $photoNodeid => $photo) {
                         if ($filedataid == $photo['filedataid']) {
                             $foundMatch = $photo;
                             unset($delete[$photoNodeid]);
                             break;
                         }
                     }
                     if ($foundMatch) {
                         if ($title != $foundMatch['title']) {
                             $titles[$foundMatch['nodeid']] = $title;
                         }
                         //unset this record.
                         //Skip to the next record
                         continue;
                     }
                     //If we got here then this is new and must be added.
                     //We do an add.
                     $photoApi->add(array('parentid' => $nodeid, 'caption' => $title, 'title' => $title, 'filedataid' => intval($filedataid)));
                 }
             }
             if (!empty($delete)) {
                 foreach ($delete as $photo) {
                     $photoApi->delete($photo['nodeid']);
                 }
             }
             if (!empty($titles)) {
                 foreach ($titles as $photonodeid => $title) {
                     $photoApi->update($photonodeid, array('caption' => $title, 'title' => $title));
                 }
             }
         }
     }
     return $results;
 }
コード例 #6
0
ファイル: poll.php プロジェクト: cedwards-reisys/nexus-web
 /**
  * Performs the merge of content and updates the node.
  * @param type $data
  * @return type
  */
 public function mergeContent($data)
 {
     // modify tables records (only one record will be modified due to constraints)
     $sources = array_diff($data['mergePosts'], array($data['destnodeid']));
     $db = vB::getDbAssertor();
     $db->update('poll', array('nodeid' => $data['destnodeid']), array(array('field' => 'nodeid', 'value' => $sources)));
     $db->update('vBForum:node', array('contenttypeid' => $this->contenttypeid), array('nodeid' => $data['destnodeid']));
     // get videoitems
     $polloptions = array();
     foreach ($data as $key => $value) {
         if (preg_match('#^polloptions\\[([\\d]+)#', $key, $matches)) {
             $polloptions[] = array('polloptionid' => intval($matches[1]), 'title' => trim($value));
         } else {
             if (preg_match('^polloptions\\[new', $key, $matches)) {
                 foreach ($value as $option) {
                     $polloptions[]['title'] = trim($option);
                 }
             }
         }
     }
     $pollData = array('title' => $data['title'], 'rawtext' => $data['text'], 'userid' => $data['destauthorid'], 'urlident' => vB_String::getUrlIdent($data['title']), 'options' => $polloptions, 'multiple' => $data['multiple'], 'public' => $data['public'], 'parseurl' => $data['parseurl'], 'timeout' => strtotime($data['timeout']));
     return vB_Api::instanceInternal('content_poll')->update($data['destnodeid'], $pollData);
 }
コード例 #7
0
ファイル: profile.php プロジェクト: cedwards-reisys/nexus-web
 public function getUrl()
 {
     if (!empty($this->arguments['userid']) and !empty($this->arguments['username'])) {
         $result = '/' . $this->prefix . '/' . $this->arguments['userid'] . '-' . vB_String::getUrlIdent($this->arguments['username']);
     } else {
         return false;
     }
     // append the tab to URL only if it's a valid tab.
     if (isset($this->arguments['tab'])) {
         if (isset(self::$availableTabs[$this->arguments['tab']])) {
             $result .= '/' . $this->arguments['tab'];
             if (isset(self::$doNotIndexTabs[$this->arguments['tab']])) {
                 $this->arguments['noindex'] = true;
             }
             // append the page number if pagenum argument is set & if a tab with pagination is set
             if (isset($this->arguments['pagenum']) and is_numeric($this->arguments['pagenum']) and $this->arguments['pagenum'] > 1 and isset(self::$tabsWithPagination[$this->arguments['tab']])) {
                 $result .= '/page' . intval($this->arguments['pagenum']);
             }
         } else {
             // invalid tab, unset it
             unset($this->arguments['tab']);
         }
     }
     if (strtolower(vB_String::getCharset()) != 'utf-8') {
         $result = vB_String::encodeUtf8Url($result);
     }
     return $result;
 }
コード例 #8
0
ファイル: content.php プロジェクト: cedwards-reisys/nexus-web
 /**
  * Cleans the input in the $data array, directly updating $data.
  *
  * @param mixed     Array of fieldname => data pairs, passed by reference.
  * @param int|false Nodeid of the node being edited, false if creating new
  */
 public function cleanInput(&$data, $nodeid = false)
 {
     if (isset($data['userid'])) {
         unset($data['userid']);
     }
     if (isset($data['authorname'])) {
         unset($data['authorname']);
     }
     // These fields should be cleaned regardless of the user's canusehtml permission.
     $cleaner = vB::getCleaner();
     foreach (array('title', 'htmltitle', 'description', 'prefixid', 'caption') as $fieldname) {
         if (isset($data[$fieldname])) {
             $data[$fieldname] = $cleaner->clean($data[$fieldname], vB_Cleaner::TYPE_NOHTML);
         }
     }
     foreach (array('open', 'showopen', 'approved', 'showapproved') as $fieldname) {
         if (isset($data[$fieldname])) {
             $data[$fieldname] = $cleaner->clean($data[$fieldname], vB_Cleaner::TYPE_INT);
         }
     }
     if (isset($data['urlident'])) {
         // Let's make sure it's a valid identifier. No spaces, UTF-8 encoded, etc.
         $data['urlident'] = vB_String::getUrlIdent($data['urlident']);
     }
     // These fields are cleaned for people who cannot use html
     foreach (array('pagetext') as $fieldname) {
         if (isset($data[$fieldname])) {
             $data[$fieldname] = $cleaner->clean($data[$fieldname], vB_Cleaner::TYPE_NOHTML);
         }
     }
     if (!empty($data['nodeid'])) {
         $checkNodeid = $data['nodeid'];
     } else {
         if (!empty($data['parentid'])) {
             $checkNodeid = $data['parentid'];
         } else {
             if ($nodeid) {
                 $checkNodeid = $nodeid;
             }
         }
     }
     //Channels are handled a bit differently.
     if (isset($this->contenttype)) {
         $isChannel = $this->contenttype == 'vBForum_Channel';
     } else {
         if (isset($data['contenttypeid'])) {
             $isChannel = $data['contenttypeid'] == vB_Types::instance()->getContentTypeID('vBForum_Channel');
         } else {
             if (!empty($nodeid)) {
                 $node = $this->nodeApi->getNode($nodeid);
                 $isChannel = $node['contenttypeid'] == vB_Types::instance()->getContentTypeID('vBForum_Channel');
             } else {
                 if (!empty($data['nodeid'])) {
                     $node = $this->nodeApi->getNode($data['nodeid']);
                     $isChannel = $node['contenttypeid'] == vB_Types::instance()->getContentTypeID('vBForum_Channel');
                 }
             }
         }
     }
     if (!empty($isChannel)) {
         //if this is an update we do nothing. If publishdate is already set we do nothing.
         if (empty($nodeid) and !isset($data['publishdate'])) {
             $data['publishdate'] = vB::getRequest()->getTimeNow();
         }
     } else {
         if (!empty($checkNodeid)) {
             $checkNode = $this->nodeApi->getNodeFullContent($checkNodeid);
             $checkNode = array_pop($checkNode);
             $limits = vB::getUserContext()->getChannelLimits($checkNode['channelid']);
             // VBV-12342 - If this is a new node & the usergroup requires moderation on this channel, we need to
             // set approved & showapproved to 0. Do not mess with publishdate. If it's not an article, it'll be
             // published immediately in the publishdate handling below.
             if (!empty($limits['require_moderate']) and empty($node)) {
                 $data['approved'] = 0;
                 $data['showapproved'] = 0;
             }
             /* PUBLISHDATE HANDLING */
             // For articles the handling is more complex
             if ($checkNode['channeltype'] == 'article') {
                 $publish = true;
                 if (!empty($nodeid)) {
                     $node = $this->nodeApi->getNode($nodeid);
                     $starter = $node['nodeid'] == $node['starter'];
                 } else {
                     if (!empty($data['nodeid'])) {
                         $node = $this->nodeApi->getNode($data['nodeid']);
                         $starter = $node['nodeid'] == $node['starter'];
                     } else {
                         $node = $this->nodeApi->getNode($data['parentid']);
                         $starter = $node['contenttypeid'] == vB_Types::instance()->getContentTypeID('vBForum_Channel');
                     }
                 }
                 if ($starter) {
                     $canpublish = vB::getUserContext()->getChannelPermission('forumpermissions2', 'canpublish', $checkNode['channelid']);
                     //if this is a add (we don't have a nodeid) AND the user can't publish, we force publishdate to zero
                     if (!$canpublish or isset($data['publish_now']) and $data['publish_now'] === false) {
                         // if the user can't publish, but can create, then we save as a draft.
                         $data['publish_now'] = false;
                         $publish = false;
                         if ($nodeid) {
                             unset($data['publishdate']);
                         } else {
                             $data['publishdate'] = 0;
                         }
                     }
                 }
                 if ($publish) {
                     if (empty($data['publishdate']) or !vB::getUserContext()->getChannelPermission('forumpermissions2', 'canpublish', $checkNode['channelid'])) {
                         $data['publishdate'] = vB::getRequest()->getTimeNow();
                     }
                 }
             } else {
                 if (!$nodeid) {
                     if (empty($data['publishdate']) or !vB::getUserContext()->getChannelPermission('forumpermissions2', 'canpublish', $checkNode['channelid'])) {
                         $data['publishdate'] = vB::getRequest()->getTimeNow();
                     }
                 }
             }
         } else {
             if (!$nodeid) {
                 /*
                  *	I'm not certain what condition this code branch is reached. If this is a new node,
                  *	then $checkNodeid will probably be the parentid. If we don't have the parentid, we
                  *	can't even check the channel limits for require_moderate. As such I'm not making
                  *	any code changes in this area for VBV-12342.
                  */
                 $data['publishdate'] = vB::getRequest()->getTimeNow();
             }
         }
     }
 }
コード例 #9
0
ファイル: api.php プロジェクト: cedwards-reisys/nexus-web
 /**
  * Replaces special characters in a given string with dashes to make the string SEO friendly
  *
  * @param	string	The string to be converted
  */
 protected function toSeoFriendly($str)
 {
     if (!empty($str)) {
         return vB_String::getUrlIdent($str);
     }
     return $str;
 }
コード例 #10
0
ファイル: content.php プロジェクト: cedwards-reisys/nexus-web
 /**
  * updates a record
  *
  *	@param	mixed		array of nodeid's
  *	@param	mixed		array of permissions that should be checked.
  *
  * 	@return	boolean
  */
 public function update($nodeid, $data)
 {
     $channelContentTypeId = vB_Types::instance()->getContentTypeId('vBForum_Channel');
     // Verify prefixid
     if ($this->contenttypeid != $channelContentTypeId and isset($data['prefixid'])) {
         $this->verifyPrefixid($data['prefixid']);
     } else {
         // Channel can't have a prefix
         unset($data['prefixid']);
     }
     // Verify post iconid
     if ($this->contenttypeid != $channelContentTypeId and isset($data['iconid'])) {
         $this->verifyPostIconid($data['iconid']);
     } else {
         // Channels can't have a post icon
         unset($data['iconid']);
     }
     $timeNow = vB::getRequest()->getTimeNow();
     $userContext = vB::getUserContext();
     //If this user doesn't have the featured permission and they are trying to set it,
     //Let's just quietly unset it.
     if (isset($data['featured'])) {
         if (!$userContext->getChannelPermission('moderatorpermissions', 'cansetfeatured', $data['parentid'])) {
             unset($data['featured']);
         }
     }
     //We can't allow directly setting parentid. That should only happen through the node api move function
     //And there are number of other fields that shouldn't be changed here. We have methods for the ones that can be changed at all.
     foreach (array('open', 'showopen', 'approved', 'showapproved', 'protected') as $field) {
         if (isset($data[$field])) {
             unset($data[$field]);
         }
     }
     if (isset($data['parentid'])) {
         //Only allow for articles.
         $content = $this->nodeApi->getNodeFullContent($nodeid);
         $content = array_pop($content);
         // you can't move it to the category it's already in
         if ($data['parentid'] != $content['parentid']) {
             // only allow this for articles (currently)
             if ($content['channeltype'] == 'article') {
                 if (!$userContext->getChannelPermission('forumpermissions', 'canmove', $data['parentid']) and !$userContext->getChannelPermission('moderatorpermissions', 'canmassmove', $data['parentid'])) {
                     throw new vB_Exception_Api('no_permission');
                 }
                 //If we got here, we're O.K. to move. let's do that now.
                 vB_Library::instance('node')->moveNodes($nodeid, $data['parentid']);
             }
         }
         unset($data['parentid']);
     }
     //We need to see if we need to update.
     $prior = vB_Library::instance('node')->getNodeBare($nodeid);
     if ($this->contenttypeid != $channelContentTypeId) {
         $content = $this->getFullContent($nodeid);
     }
     if (isset($data['publish_now']) and !empty($data['publish_now'])) {
         $data['publishdate'] = vB::getRequest()->getTimeNow();
     }
     if (empty($data['htmltitle']) and !empty($data['title'])) {
         $data['htmltitle'] = vB_String::htmlSpecialCharsUni(vB_String::stripTags($data['title']), false);
     }
     if (empty($data['urlident']) and !empty($data['title'])) {
         $data['urlident'] = vB_String::getUrlIdent($data['title']);
     }
     // Do not change publishdate or showpublished status unless it was explicitly set while calling update().
     if ((!isset($data['publishdate']) or empty($data['publishdate']) and $data['publishdate'] !== 0) and !empty($prior['publishdate'])) {
         $data['publishdate'] = $prior['publishdate'];
     }
     if ($this->isPublished($data)) {
         $published = 1;
     } else {
         $published = 0;
     }
     $nodevals = array();
     if ($published != $prior['showpublished']) {
         $nodevals['showpublished'] = $published;
     }
     // set default node options
     if ((empty($data['nodeoptions']) or !is_numeric($data['nodeoptions'])) and $prior['contenttypeid'] != $channelContentTypeId) {
         $parentFullContent = vB_Library::instance('node')->getNodeFullContent($prior['parentid']);
         if (!empty($parentFullContent[$prior['parentid']]['channeltype'])) {
             $data['nodeoptions'] = self::$defaultNodeOptions[$parentFullContent[$prior['parentid']]['channeltype']];
         } else {
             $data['nodeoptions'] = self::$defaultNodeOptions['default'];
         }
         // Add or remove any nodeoptions that have been explicitly passed in.
         // This would have otherwise happened in updateNodeOptions/setNodeOptions
         // (which is where it happens when adding a node as opposed to updating
         // a node), but since $data['nodeoptions'] is now defined, setNodeOptions
         // won't take care of setting these (it will just apply the int
         // nodeoptions value).
         $baseNodeOptions = vB_Api::instanceInternal('node')->getOptions();
         foreach ($baseNodeOptions as $baseOptionKey => $baseOptionVal) {
             if (isset($data[$baseOptionKey])) {
                 if (intval($data[$baseOptionKey])) {
                     $data['nodeoptions'] = $data['nodeoptions'] | intval($baseOptionVal);
                 } else {
                     $data['nodeoptions'] = $data['nodeoptions'] & ~intval($baseOptionVal);
                 }
             }
         }
     }
     //node table data.
     $data[vB_dB_Query::TYPE_KEY] = vB_dB_Query::QUERY_UPDATE;
     $data['nodeid'] = $nodeid;
     $data['lastupdate'] = $timeNow;
     //If the field passed is in the $nodeFields array then we update the node table.
     foreach ($data as $field => $value) {
         if (in_array($field, $this->nodeFields)) {
             $nodevals[$field] = $value;
         }
     }
     $index = empty($data['noIndex']);
     unset($data['noIndex']);
     // Update the content-type specific data
     if (!is_array($this->tablename)) {
         $tables = array($this->tablename);
     } else {
         $tables = $this->tablename;
     }
     $success = true;
     foreach ($tables as $table) {
         $structure = $this->assertor->fetchTableStructure('vBForum:' . $table);
         if (empty($structure) or empty($structure['structure'])) {
             throw new vB_Exception_Api('invalid_query_parameters');
         }
         $queryData = array();
         $queryData[vB_dB_Query::TYPE_KEY] = vB_dB_Query::QUERY_UPDATE;
         $queryData['nodeid'] = $nodeid;
         foreach ($structure['structure'] as $fieldname) {
             if (isset($data[$fieldname])) {
                 $queryData[$fieldname] = $data[$fieldname];
             }
         }
         //Now we have at least a query type and a nodeid. We put those in above. So if we don't
         //have at least one other value there's no reason to try an update.
         if (count($queryData) > 2) {
             $success = $success and $this->assertor->assertQuery('vBForum:' . $table, $queryData);
         }
     }
     if ($success) {
         // Handle Attachments
         // The text library (and most derivatives) can have attachments,
         // for the others, this is a no-op.
         $this->handleAttachments('update', $nodeid, $data);
         //Clear cached query info that would be significantly impacted
         $events = array('fUserContentChg_' . $prior['userid']);
         if ($prior['starter']) {
             $starterNodeInfo = vB_Library::instance('node')->getNodeBare($prior['starter']);
             $events[] = 'fUserContentChg_' . $starterNodeInfo['userid'];
         } else {
             if ($prior['parentid']) {
                 $starterNodeInfo = vB_Library::instance('node')->getNodeBare($prior['parentid']);
                 $events[] = 'fUserContentChg_' . $starterNodeInfo['userid'];
             }
         }
         $this->nodeApi->clearCacheEvents($nodeid);
         vB_Cache::instance()->allCacheEvent($events);
         if (isset($nodevals['publishdate']) and $nodevals['publishdate'] > $timeNow) {
             if (empty($nodevals['unpublishdate']) or $nodevals['unpublishdate'] > $nodevals['publishdate']) {
                 $nodevals['nextupdate'] = $nodevals['publishdate'];
             }
         } else {
             if (isset($nodevals['unpublishdate']) and $nodevals['unpublishdate'] > $timeNow) {
                 $nodevals['nextupdate'] = $nodevals['unpublishdate'];
             }
         }
         // handle approved
         if (isset($nodevals['approved'])) {
             if ($nodevals['approved']) {
                 $approved = 1;
                 $queryName = 'approveNode';
             } else {
                 $approved = 0;
                 $queryName = 'unapproveNode';
             }
             // set approved to parent...
             $this->assertor->assertQuery('vBForum:node', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_UPDATE, 'nodeid' => $nodeid, 'approved' => $approved));
             // and handle showapproved
             $this->assertor->assertQuery('vBForum:' . $queryName, array('nodeid' => $nodeid));
             unset($nodevals['approved']);
         }
         if (isset($nodevals)) {
             $nodevals[vB_dB_Query::TYPE_KEY] = vB_dB_Query::QUERY_UPDATE;
             $nodevals['nodeid'] = $nodeid;
             $success = $this->assertor->assertQuery('vBForum:node', $nodevals);
         }
         //We need to compare the current publishdate and unpublishdate values against the
         // parent.
         //But we can skip this if neither publish or unpublishdate is set
         $updateParents = false;
         if ($published != $prior['showpublished']) {
             $updateParents = true;
             //We are concerned about two possibilities. It could have gone from published to unpublished.
             //In either case we change by totalcount +1 (for ourselves.
             //Remember that published is always unpublished.
             //From unpublished to published.
             if ($published) {
                 $nodeUpdates = $this->nodeLibrary->publishChildren($nodeid);
                 // if $nodeUpdates is empty, that means no change was made to this node or its descendants,
                 // and no parent count changes are necessary. If it's not empty but doesn't have totalcount set,
                 // that means it possibly failed with a DB error. In such a case, we will just not update the
                 // counts but continue updating the node.
                 if (!empty($nodeUpdates) and isset($nodeUpdates['totalcount'])) {
                     // text-counts only change by 1 (or 0 for non-text types), because it only affects the immediate parent
                     $textChange = $this->textCountChange;
                     $textUnPubChange = -1 * $textChange;
                     // Note, below assumes that a DB had been diligent about
                     // keeping track of the count fields correctly.
                     $totalPubChange = $nodeUpdates['totalcount'] - $prior['totalcount'] + $textChange;
                     // we add the text change because self counts for ancestors' total counts
                     $totalUnPubChange = -1 * $totalPubChange;
                 } else {
                     $updateParents = false;
                 }
             } else {
                 $nodeUpdates = $this->nodeLibrary->unpublishChildren($nodeid);
                 if (!empty($nodeUpdates) and isset($nodeUpdates['totalunpubcount'])) {
                     $textUnPubChange = $this->textCountChange;
                     $textChange = -1 * $textUnPubChange;
                     $totalUnPubChange = $nodeUpdates['totalunpubcount'] - $prior['totalunpubcount'] + $textUnPubChange;
                     $totalPubChange = -1 * $totalUnPubChange;
                 } else {
                     $updateParents = false;
                 }
             }
             vB_Library::instance('node')->clearChildCache($nodeid);
         }
         //update the parent count if necessary
         if ($updateParents) {
             vB_Library::instance('node')->updateParentCounts($nodeid, $textChange, $textUnPubChange, $totalPubChange, $totalUnPubChange, $published);
         }
         //update viewperms from childs if needed, do we want this channel specific?
         if (isset($nodevals['viewperms']) and isset($prior['viewperms']) and $nodevals['viewperms'] != $prior['viewperms']) {
             vB_Api::instanceInternal('node')->setNodePerms($nodeid, array('viewperms' => $nodevals['viewperms']));
         }
         if ($index) {
             vB_Api::instanceInternal('Search')->index($nodeid);
         }
         // update user tags
         $tags = !empty($data['tags']) ? explode(',', $data['tags']) : array();
         $tagRet = vB_Api::instanceInternal('tags')->updateUserTags($nodeid, $tags);
         $this->updateNodeOptions($nodeid, $data);
         // Update childs nodeoptions
         $this->assertor->assertQuery('vBForum:updateChildsNodeoptions', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_STORED, 'parentid' => $nodeid));
         $this->nodeApi->clearCacheEvents(array($nodeid, $prior['parentid']));
         $loginfo = array('nodeid' => $prior['nodeid'], 'nodetitle' => $prior['title'], 'nodeusername' => $prior['authorname'], 'nodeuserid' => $prior['userid']);
         $extra = array();
         if ($nodevals !== null && isset($nodevals['title'])) {
             if ($prior['title'] != $nodevals['title']) {
                 $extra = array('newtitle' => $nodevals['title']);
             }
         }
         vB_Library_Admin::logModeratorAction($loginfo, 'node_edited_by_x', $extra);
         $updateEditLog = true;
         if (!vB::getUserContext()->hasPermission('genericoptions', 'showeditedby') and (isset($content[$nodeid]['edit_reason']) and $data['reason'] == $content[$nodeid]['edit_reason'] or !isset($content[$nodeid]['edit_reason']) and empty($data['reason']))) {
             $updateEditLog = false;
         }
         // Clear autosave table of this items entry
         if (vB::getCurrentSession()->get('userid') and !empty($data['rawtext'])) {
             $this->assertor->delete('vBForum:autosavetext', array('userid' => vB::getCurrentSession()->get('userid'), 'nodeid' => $nodeid, 'parentid' => $content[$nodeid]['parentid']));
         }
         // Log edit by info
         if ($updateEditLog and $this->contenttypeid != $channelContentTypeId and isset($content[$nodeid]['rawtext']) and isset($data['rawtext']) and $content[$nodeid]['rawtext'] != $data['rawtext'] and !empty($data['publishdate']) and $prior['publishdate'] and (!empty($data['reason']) or $data['publishdate'] < vB::getRequest()->getTimeNow() - $this->options['noeditedbytime'] * 60)) {
             $userinfo = vB::getCurrentSession()->fetch_userinfo();
             // save the postedithistory
             if ($this->options['postedithistory']) {
                 $record = $this->assertor->getRow('vBForum:postedithistory', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, 'original' => 1, 'nodeid' => $nodeid));
                 // insert original post on first edit
                 if (empty($record)) {
                     $this->assertor->assertQuery('vBForum:postedithistory', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_INSERT, 'nodeid' => $nodeid, 'userid' => $content[$nodeid]['userid'], 'username' => $content[$nodeid]['authorname'], 'dateline' => $data['publishdate'], 'pagetext' => $content[$nodeid]['rawtext'], 'original' => 1));
                 }
                 // insert the new version
                 $this->assertor->assertQuery('vBForum:postedithistory', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_INSERT, 'nodeid' => $nodeid, 'userid' => $userinfo['userid'], 'username' => $userinfo['username'], 'dateline' => vB::getRequest()->getTimeNow(), 'reason' => isset($data['reason']) ? vB5_String::htmlSpecialCharsUni($data['reason']) : '', 'pagetext' => isset($data['rawtext']) ? $data['rawtext'] : ''));
             }
             $this->assertor->assertQuery('editlog_replacerecord', array('nodeid' => $nodeid, 'userid' => $userinfo['userid'], 'username' => $userinfo['username'], 'timenow' => vB::getRequest()->getTimeNow(), 'reason' => isset($data['reason']) ? vB5_String::htmlSpecialCharsUni($data['reason']) : '', 'hashistory' => intval($this->options['postedithistory'])));
         }
         return true;
     }
     $this->nodeApi->clearCacheEvents(array($nodeid, $prior['parentid']));
     return false;
 }
コード例 #11
0
ファイル: channel.php プロジェクト: cedwards-reisys/nexus-web
 /** This creates an urlident from a title, and guarantees it will not be a duplicate
  *
  * @param	string	the title
  * @return	string
  **/
 public function getUniqueUrlIdent($title)
 {
     //first see if this is good. Note that we don't care if it's used for a node that isn't a channel.
     $candidate = vB_String::getUrlIdent($title);
     $check = $this->assertor->getRow('vBForum:node', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, 'urlident' => $candidate, 'contenttypeid' => $this->contenttypeid));
     if (empty($check) or !empty($check['errors'])) {
         return $candidate;
     }
     //So now we try adding _a, b, c, etc.  If we get to z we'll throw an exception.
     $charVal = ord('a');
     $charVal2 = ord('a');
     while (true) {
         if ($charVal >= ord('z') and $charVal2 >= ord('z')) {
             throw new vB_Exception_Api('invalid_data' . $candidate . '-' . chr($charVal) . chr($charVal2));
         }
         $check = $this->assertor->getRow('vBForum:node', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, 'urlident' => $candidate . '-' . chr($charVal) . chr($charVal2), 'contenttypeid' => $this->contenttypeid));
         if (empty($check) or !empty($check['errors'])) {
             return $candidate . '-' . chr($charVal) . chr($charVal2);
         }
         $charVal2++;
         if ($charVal2 >= ord('z')) {
             $charVal++;
             $charVal2 = ord('a');
         }
     }
 }