Go Back   vb.org Archive > Community Discussions > Modification Requests/Questions (Unpaid)

Reply
 
Thread Tools Display Modes
  #1  
Old 08-22-2016, 01:29 AM
Necrophyte Necrophyte is offline
 
Join Date: Jul 2014
Posts: 34
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default vBulletin 5 Request - Require (New Thread), (Edit Thread), (New Post), and (Move Post) Functions VB5.2.3

Require (New Thread), (Edit Thread), (New Post), and (Move Thread) Functions
As it says. I've have an external application from VB4 that used to do the above. However VB5 has changed so much. I haven't been able to figure using external code.

Example Function was:
Code:
function writepost($userid, $threadid, $postmsg, $title){
	global $vbulletin;
	
	if (!is_numeric($threadid)){
		return;
	}

	chdir($_SERVER['DOCUMENT_ROOT']."/forum"); 
	require_once './global.php';
	require_once './includes/class_dm.php';
	require_once './includes/class_dm_threadpost.php';
	require_once './includes/functions_databuild.php';
	require_once('./includes/class_wysiwygparser.php');
	chdir($_SERVER['DOCUMENT_ROOT']."/opserv");
		
	$html_parser = new vB_WysiwygHtmlParser($vbulletin);
	$postmsg = html_entity_decode($html_parser->parse_wysiwyg_html_to_bbcode($postmsg, false), ENT_QUOTES, 'UTF-8');
	$userid = (int)$row['userid'];
		
	$postdm = new vB_DataManager_Post($vbulletin, ERRTYPE_STANDARD);
	$threadinfo = fetch_threadinfo($threadid); 
	$foruminfo = fetch_foruminfo($threadinfo['forumid']); 
	$postdm->set_info('forum', $foruminfo); 
	$postdm->set_info('thread', $threadinfo);   
	$postdm->set('userid', $userid);
	$postdm->set('title', $title);
	$postdm->set('threadid', $threadid); 
	$postdm->set('pagetext', $postmsg); 
	$postdm->set('allowsmilie', 1); 
	$postdm->set('visible', 1); 
	$postdm->set('dateline', TIMENOW); 
	$postid = $postdm->save(); 
	build_forum_counters($threadinfo['forumid']);
	unset($postdm);  

	return $postid;
}
I need the same style functions for:
function writepost($userid, $threadid, $postmsg, $title)
Must return post id
function startpost($userid, $forum_id, $postmsg, $title)
Must return Thread id
function editpost($userid, $postid, $postmsg, $title)
Must return Post id
function movethread($threadid, $forumid)
Must return true false

Each one needs to update the forums properly as well ie: Build forum counters or the equivalent in VB5. Startpost was a function that started the initial thread. Not sure if VB5 requires the same. Writepost would write a new post in a current thread. Edit post is where it would edit an existing post, and movethread would move a thread from one forumid to another.

I've honestly Tried. I just can't figure out how VB5 does it, and I don't want to give up on VB5.
I've looked through createcontent.php and I still can't figure out how its done. Someone please help.
Reply With Quote
  #2  
Old 08-22-2016, 03:24 AM
Replicant's Avatar
Replicant Replicant is offline
 
Join Date: Sep 2014
Location: Phoenix, Az. USA
Posts: 485
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Starting a thread and posting to a thread is a simple post operation. Here's a sample JSON string that has the minimum requirements for a post or new thread. The CKEditor uses a multi-part binary postfor uploading pics and what not. A lot more code. Writing to a forum nodeid will return a nodeid for the newly created thread. Writing to a thread nodeid will return a nodeid for the new post in that thread. Writing to a Post nodeid will return the nodeid for the newly created comment. Your json string would by submitted via POST (required) to the /create-content/text url. You can use JS, Jquery, curl, or any other http protocol that is http compliant. I've used the Bash shell in Linux using the POST command.

{ "data":{"title":"Sample Title", "securitytoken":"Valid Security Token", "parentid"="Forum or Thread or Post nodeid"}}

Moving a thread can be accopmlished with a POST to /ajax/api/node/movePosts. Data required is
newtitle="Hello World", to_parent=Forum Nodeid , nodeids[] = 9305 (Array is Required), securitytoken=Valid token.

Editing an existing post will be trickier. The post request for editing pulls a ckeditor template. You can make POST nodeid="post-to-be-edited" to /api/node/getNodeContent (permissions required). That will give you a JSON string with all the info about that nodeid including the bbcode held in the rawtext field. You can import that code into your app for editing then save to create-content/Text/. You will need to get the params from the dev environment while saving a edited post. It'll be multipart binary so You'll have to play with it a bit. It's not too difficult.

Most if not all of the functions can also be done in php but I figure why bother? The VB5 api has all the checks, security, and verification in place already and puts everything where it;'s supposed to be in the database.

Good Luck.
Reply With Quote
  #3  
Old 08-22-2016, 01:06 PM
Necrophyte Necrophyte is offline
 
Join Date: Jul 2014
Posts: 34
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Replicant,
First let me thank you for responding.
I get what your saying but here's the issue that I have.
Some of the people don't have the permissions required when these posts are made or edited. They are sent to their command and staff where only they have access to it. But it's an automated post of stuff have done for the day. Sometimes when they redo something. It will go back and edit the post and add to it automatically. Nothing that is in the post is typed by the user. I'm not using ckeditor in any way. Its all an internal script that when someone does a part of a job it writes a new thread once its been marked done.
If it was a user doing something with ckeditor I can totally get where your coming from and it would only make sense to do it that way. But its an automated post.

I've tried doing it via PHP. I've at least think I figured out the code to do it:
Code:
define('VB_ENTRY', 1);
		$input = array(
			'title'     => (isset($_POST['title']) ? trim(strval($_POST['title'])) : ''),
			'text'      => (isset($_POST['text']) ? trim(strval($_POST['text'])) : ''),
			'nodeid'    => (isset($_POST['nodeid']) ? trim(intval($_POST['nodeid'])) : 0),
			'parentid'  => (isset($_POST['parentid']) ? trim(intval($_POST['parentid'])) : 0),
			'channelid' => (isset($_POST['channelid']) ? trim(intval($_POST['channelid'])) : 0),
			'ret'       => (isset($_POST['ret']) ? trim(strval($_POST['ret'])) : ''),
			'tags'      => (isset($_POST['tags']) ? $_POST['tags'] : ''),
			'reason'    => (isset($_POST['reason']) ? trim(strval($_POST['reason'])) : ''), //used in editing a post
			'iconid'    => (isset($_POST['iconid']) ? intval($_POST['iconid']) : 0),
			'prefixid'  => (isset($_POST['prefixid']) ? trim(strval($_POST['prefixid'])) : ''),
			'hvinput'   => (isset($_POST['humanverify']) ? $_POST['humanverify'] : ''),
			'subtype'   => (isset($_POST['subtype']) ? trim(strval($_POST['subtype'])) : ''),
			'nl2br'     => (isset($_POST['nl2br']) ? (bool)$_POST['nl2br'] : false),
		);

		$api = Api_InterfaceAbstract::instance();

		if (!empty($_POST['setfor']))
		{
			$input['setfor'] = $_POST['setfor'];
		}

		if (!empty($_POST['recaptcha_challenge_field']))
		{
			// reCaptcha fields
			$input['hvinput']['recaptcha_challenge_field'] = $_POST['recaptcha_challenge_field'];
			$input['hvinput']['recaptcha_response_field'] = $_POST['recaptcha_response_field'];
		}

		// get user info for the currently logged in user
		$user  = $api->callApi('user', 'fetchUserinfo', array());

		$time = vB5_Request::get('timeNow');
		$tagRet = false;

		$textData = array(
			'title'                  => $input['title'],
			'parentid'               => $input['parentid'],
			'prefixid'               => $input['prefixid'],
			'iconid'                 => $input['iconid'],
		);

		if ($input['nodeid'])
		{
			$result = array();
			if ($user['userid'] < 1)
			{
				$result['error'] = 'logged_out_while_editing_post';
				$this->sendAsJson($result);
				exit;
			}

			// when *editing* comments, it uses create-content/text (this function)
			// when *creating* comments, it uses ajax/post-comment (actionPostComment)
			if ($input['subtype'] == 'comment')
			{
				// NOTE: Keep this in sync with
				//       vB5_Frontend_Controller_Ajax:: actionPostComment
				//
				// htmlspecialchars and nl2br puts the text into the same state
				// it is when the text api receives input from ckeditor
				// specifically, newlines are passed as <br /> and any HTML tags
				// that are typed literally into the editor are passed as HTML-escaped
				// because non-escaped HTML that is sent is assumed to be formatting
				// generated by ckeditor and will be parsed & converted to bbcode.
				$textData['rawtext'] = nl2br(htmlspecialchars($input['text'], ENT_NOQUOTES));
			}
			else
			{
				$textData['rawtext'] = $input['text'];
			}

			$textData['reason'] = $input['reason'];

			$textData += $this->getArticleInput();

			$options = array();

			// We need to convert WYSIWYG html here and run the img check
			if (isset($textData['rawtext']))
			{
				$tmpText = $api->callApi('bbcode', 'convertWysiwygTextToBbcode', array($textData['rawtext'], $options));
				// Check Images
				if (($phrase = vB5_Frontend_Controller_Bbcode::verifyImgCheck($tmpText)) !== true)
				{
					$results['error'] = $phrase;
					$this->sendAsJson($results);
					return;
				}
			}

			if ($input['nl2br'])
			{
				// not using ckeditor (on edit, 'nl2br' goes in the data array)
				$textData['nl2br'] = true;
			}

			// add attachment info so update() can do permission checking & add/remove attachments to this node.
			$this->addAttachments($textData);

			$updateRet = $api->callApi('content_text', 'update', array($input['nodeid'], $textData, $options));
			$this->handleErrorsForAjax($result, $updateRet);
			// If the update failed, just return and don't edit tags, attachments etc.
			if (!empty($updateRet['errors']))
			{
				return $this->sendAsJson($result);
			}

			//update tags
			$tags = !empty($input['tags']) ? explode(',', $input['tags']) : array();
			$tagRet = $api->callApi('tags', 'updateUserTags', array($input['nodeid'], $tags));
			$this->handleErrorsForAjax($result, $tagRet);

			$this->sendAsJson($result);
		}
		else
		{
			//not sure why rawtext is different here from the above
			$textData['rawtext'] = $input['text'];
			$textData['userid'] = $user['userid'];
			$textData['authorname'] = $user['username'];
			$textData['created'] = $time;
			$textData['hvinput'] = $input['hvinput'];

			$publish = array(
				'facebook' => !empty($_POST['fbpublish'])
			);

			if (!empty($_POST['setfor']))
			{
				$textData['setfor'] = intval($_POST['setfor']);
			}

			if(!$this->createNewNode('content_text', $textData, $publish, $input))
			{
				return;
			}
		}
However this code keeps asking for more and more includes, I stopped on the 7th one cause it started giving multiple errors that were not related to the code shown. I've got until Sept to figure this out and at the current rate I'll not figure this out in time. I'll have to abandon vBulletin and I'd really rather not do that.
Reply With Quote
  #4  
Old 08-22-2016, 01:42 PM
Replicant's Avatar
Replicant Replicant is offline
 
Join Date: Sep 2014
Location: Phoenix, Az. USA
Posts: 485
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

So this is a guest user post? What is the text input user interface? What are you getting the errors thrown on...editing or posting? Are you using the mapi interface or a web browser interface?
Reply With Quote
  #5  
Old 08-22-2016, 02:22 PM
Necrophyte Necrophyte is offline
 
Join Date: Jul 2014
Posts: 34
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

No sir. It gets the user info from $vbulletin->userinfo.
The text input is a variable generated. Sample is:
Code:
		while ($billetRow = $billetResult->fetch_assoc()){
			$post_text.= "
".($billetRow['opid'] == 30 ? $row['tag']. " - ". $row['officename'] : $billetRow['tag']. " - ". $billetRow['opname'])." " .$billetRow['billetname']. " ([COLOR='#".$billetRow['color_hex']."']".$billetRow['title']."[/COLOR]): ".(get_billet_username($billetRow['billetid']) == "N/A" ? "Vacant" : "."/forum/member.php?".userExists(get_billet_username($billetRow['billetid']))."-".get_billet_username($billetRow['billetid'])."]".get_billet_username($billetRow['billetid'])."")."
"; }
There is a lot more to it than that, however $post_text is auto generated, and that is what is the text. The interface would be a web browser with php coded interface. They just log onto a site (External page, loaded with .global.php) and click a checkbox. Click save. The form submits as post. This goes through all the checked information creating a $post_text then calls the write a new thread function. That writes the post, and he/she is brought back to the screen with all the checkboxes updated, (Clicked or un-clicked). At which point they can then add or remove checked boxes. Submit again. And this will run through the post. See the thread exists, and will replace the data in the above mentioned post.
At a specific time, a php script is run at night and it will move the thread to another forum to be audited later.
Reply With Quote
  #6  
Old 08-22-2016, 02:51 PM
Dragonsys's Avatar
Dragonsys Dragonsys is offline
 
Join Date: Jan 2008
Location: DFW, Texas
Posts: 743
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Can you go back to vb4?
Reply With Quote
  #7  
Old 08-22-2016, 02:52 PM
Replicant's Avatar
Replicant Replicant is offline
 
Join Date: Sep 2014
Location: Phoenix, Az. USA
Posts: 485
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Quote:
Originally Posted by Necrophyte View Post
then calls the write a new thread function.
Instead of calling the function directly, you can use cURL in the php script to submit to create-content. Since it is a web browser interface, JS can be used to retrieve the data and fill the forms for editing and saving. If this is a secure interface keeping anyone from logging in and posting from the net or network, you can add an ip addr check at the beginning of the index() function in the create-content frontend controller so that it can only be posted from that machine (or whitelisted IPs in the list).
Reply With Quote
  #8  
Old 08-22-2016, 03:27 PM
Necrophyte Necrophyte is offline
 
Join Date: Jul 2014
Posts: 34
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

At Dragonsys. Currently there is no undo for the database. I've seen a couple folks that have managed to convert back but at this point I feel it would be easier to get this working.
Oh oh oh.. As I write this I've gotten a working write a new post in an existing thread in php. So its not seeming so bleak. But I need to figure out how to write a new thread. Now that I have figured this out, I'm pretty sure I can get the rest in time. It's not pretty. But it works.
My issue btw was the:
vB5_Autoloader::register(dirname(__FILE__));
dirname(__FILE__) grabs your current working folder so I changed this to be the forums and solved the rest of my issues at least for creating a post.

I've posted this code so that if someone needed something like I did they can use it. Its not cleaned up, as I'm not sure what needs to stay or go yet. But it works, and should get you where you need to go.
Code:
<?PHP
// Attempt for creating thread code
define('VB_ENTRY', 1);
chdir($_SERVER['DOCUMENT_ROOT']."/forum/core"); 
require_once('./global.php');
require_once('../includes/vb5/autoloader.php');
vB5_Autoloader::register($_SERVER['DOCUMENT_ROOT']."/forum");
$app = vB5_Frontend_Application::init('config.php');


		$options = [];
		$input = array(
			'title'        =>    'Posting through the API',
			'rawtext'    =>    'Edited more Change text3',
			'nodeid'    =>    1099448,
			'parentid'    =>    85,
			'channelid'    =>    85,
			'ret'        =>    '',
			'tags'        =>    '',
			'reason'    =>    '',
			'iconid'    =>    '',
			'prefixid'    =>    '',
			'hvinput'    =>    '',
			'subtype'    =>    '',
			'userid'    =>    '1',
			'username'    =>    'User',
			'nl2br'     => (isset($_POST['nl2br']) ? (bool)$_POST['nl2br'] : false),
		);

		$api = Api_InterfaceAbstract::instance();

		if (!empty($_POST['setfor']))
		{
			$input['setfor'] = $_POST['setfor'];
		}

		// get user info for the currently logged in user
		$user  = $api->callApi('user', 'fetchUserinfo', array());

		$time = vB5_Request::get('timeNow');
		$tagRet = false;

		$textData = array(
			'title'                  => $input['title'],
			'parentid'               => $input['parentid'],
			'prefixid'               => $input['prefixid'],
			'iconid'                 => $input['iconid'],
		);

		if ($input['nodeid']){ //If we're here. We are to edit a post.
			$result = array();
			if ($user['userid'] < 1){
				$result['error'] = 'logged_out_while_editing_post';
				echo $result['error'];
				exit;
			}

			$textData['rawtext'] = $input['rawtext'];
			$textData['reason'] = $input['reason'];

//			$textData += $this->getArticleInput();

			$options = array();

			// We need to convert WYSIWYG html here and run the img check
			if (isset($textData['rawtext'])){
				$tmpText = $api->callApi('bbcode', 'convertWysiwygTextToBbcode', array($textData['rawtext'], $options));
				// Check Images
				if (!$phrase = vB5_Frontend_Controller_Bbcode::verifyImgCheck($tmpText)){
					$result['error'] = $phrase;
					echo "Result:".$result['error'];
					exit;
				}
			}

			if ($input['nl2br'])
			{
				// not using ckeditor (on edit, 'nl2br' goes in the data array)
				$textData['nl2br'] = true;
			}

			$nodeId = $api->callApi('content_text', 'update', [$input['nodeid'], $textData, $options]);

			//update tags
			$tags = !empty($input['tags']) ? explode(',', $input['tags']) : array();
			$tagRet = $api->callApi('tags', 'updateUserTags', array($input['nodeid'], $tags));
		}
		else //Here we start a new post/thread
		{
			$nodeId = $api->callApi('content_text', 'add', [$input, $options]);
		}
		
		
if ($nodeId == '1'){
	echo "updated";
}
if(!is_int($nodeId))
{
	echo "Array";
	print_r($nodeId);
    exit;
}
print 'Node '. $nodeId . ' created successfully';
?>
Reply With Quote
  #9  
Old 08-22-2016, 03:29 PM
Replicant's Avatar
Replicant Replicant is offline
 
Join Date: Sep 2014
Location: Phoenix, Az. USA
Posts: 485
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

If you wrote to an existing thread, change the thread nodeid you wrote to to the forum nodeid and it will create a new thread.
Reply With Quote
Благодарность от:
MarkFL
  #10  
Old 08-22-2016, 03:34 PM
Necrophyte Necrophyte is offline
 
Join Date: Jul 2014
Posts: 34
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Replicant. That worked like a charm! This also allows to edit. Its all I need in one function. Pretty amazing.
Thank you for all your help Replicant. In this and the other things you've assisted me with.
You are a gentleman and a scholar, and some day, people will sing songs of your glory!
You most certainly are appreciated. By me at least.

Again. Thank you!

--------------- Added [DATE]1471962005[/DATE] at [TIME]1471962005[/TIME] ---------------

I've come across the dilemma of no permissions when trying to use this which I was afraid of. Is there a trick to bypass this? Or is it way more in depth. I fear for me, that I'm back at square one.
Reply With Quote
2 благодарности(ей) от:
Dragonsys, MarkFL
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 01:52 AM.


Powered by vBulletin® Version 3.8.12 by vBS
Copyright ©2000 - 2024, vBulletin Solutions Inc.
X vBulletin 3.8.12 by vBS Debug Information
  • Page Generation 0.04106 seconds
  • Memory Usage 2,284KB
  • Queries Executed 11 (?)
More Information
Template Usage:
  • (1)SHOWTHREAD
  • (1)ad_footer_end
  • (1)ad_footer_start
  • (1)ad_header_end
  • (1)ad_header_logo
  • (1)ad_navbar_below
  • (1)ad_showthread_beforeqr
  • (1)ad_showthread_firstpost
  • (1)ad_showthread_firstpost_sig
  • (1)ad_showthread_firstpost_start
  • (4)bbcode_code
  • (1)bbcode_quote
  • (1)footer
  • (1)forumjump
  • (1)forumrules
  • (1)gobutton
  • (1)header
  • (1)headinclude
  • (1)navbar
  • (3)navbar_link
  • (120)option
  • (1)pagenav
  • (1)pagenav_curpage
  • (1)pagenav_pagelink
  • (10)post_thanks_box
  • (3)post_thanks_box_bit
  • (10)post_thanks_button
  • (1)post_thanks_javascript
  • (1)post_thanks_navbar_search
  • (2)post_thanks_postbit
  • (10)post_thanks_postbit_info
  • (10)postbit
  • (10)postbit_onlinestatus
  • (10)postbit_wrapper
  • (1)spacer_close
  • (1)spacer_open
  • (1)tagbit_wrapper 

Phrase Groups Available:
  • global
  • inlinemod
  • postbit
  • posting
  • reputationlevel
  • showthread
Included Files:
  • ./showthread.php
  • ./global.php
  • ./includes/init.php
  • ./includes/class_core.php
  • ./includes/config.php
  • ./includes/functions.php
  • ./includes/class_hook.php
  • ./includes/modsystem_functions.php
  • ./includes/functions_bigthree.php
  • ./includes/class_postbit.php
  • ./includes/class_bbcode.php
  • ./includes/functions_reputation.php
  • ./includes/functions_post_thanks.php 

Hooks Called:
  • init_startup
  • init_startup_session_setup_start
  • init_startup_session_setup_complete
  • cache_permissions
  • fetch_threadinfo_query
  • fetch_threadinfo
  • fetch_foruminfo
  • style_fetch
  • cache_templates
  • global_start
  • parse_templates
  • global_setup_complete
  • showthread_start
  • showthread_getinfo
  • forumjump
  • showthread_post_start
  • showthread_query_postids
  • showthread_query
  • bbcode_fetch_tags
  • bbcode_create
  • showthread_postbit_create
  • postbit_factory
  • postbit_display_start
  • post_thanks_function_post_thanks_off_start
  • post_thanks_function_post_thanks_off_end
  • post_thanks_function_fetch_thanks_start
  • fetch_musername
  • post_thanks_function_fetch_thanks_end
  • post_thanks_function_thanked_already_start
  • post_thanks_function_thanked_already_end
  • postbit_imicons
  • bbcode_parse_start
  • bbcode_parse_complete_precache
  • bbcode_parse_complete
  • postbit_display_complete
  • post_thanks_function_can_thank_this_post_start
  • post_thanks_function_fetch_thanks_bit_start
  • post_thanks_function_show_thanks_date_start
  • post_thanks_function_show_thanks_date_end
  • post_thanks_function_fetch_thanks_bit_end
  • post_thanks_function_fetch_post_thanks_template_start
  • post_thanks_function_fetch_post_thanks_template_end
  • pagenav_page
  • pagenav_complete
  • tag_fetchbit_complete
  • forumrules
  • navbits
  • navbits_complete
  • showthread_complete