• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

Last DataWriter question (for now) -- Seriously

Jeremy

Well-known member
#1
OK,

I'm certain this is my last DataWriter question. How on earth do I get the inputed data. Using $this->getExisting('fieldname'); seems to return NULL on an add command. $this->getNew() seemed to not work as expected. I honestly am dumb founded at this. I've looked over the files multiple times, attempted multiple functions... added the table name in them... its just not working for me... Help would be appreciated (and I started with getExisting because I saw it in XenForo somewhere). Here's part of my datawriter:

PHP:
<?php

class KingK_BbCodeManager_DataWriter_CustomBbCodes extends XenForo_DataWriter
{
	protected $_existingDataErrorPhrase = 'bbcm_bbCodeNotFound';

	protected function _getFields()
	{
		return array(
			'kingk_bbcm' => array(
				'tag' => array('type' => self::TYPE_STRING, 'required' => true, 'maxLength' => 25,
						'verification' => array('$this', '_verifyBbCodeId'),
						'requiredError' => 'bbcm_errorInvalidId'
				),
				'title'    => array('type' => self::TYPE_STRING, 'required' => true, 'maxLength' => 50,
						 'requiredError' => 'please_enter_valid_title'
				),
				'description'      => array('type' => self::TYPE_STRING, 'required' => true, 'maxLength' => 255,
						'requiredError' => 'bbcm_pleaseEnterValidDesc'
				),
				'replacementBegin'    => array('type' => self::TYPE_STRING, 'default' => '',
				),
				'replacementEnd'    => array('type' => self::TYPE_STRING, 'default' => '',
				),
				'phpcallback_class'    => array('type' => self::TYPE_STRING, 'default' => '', 'maxLength' => 255,
				),
				'phpcallback_method'    => array('type' => self::TYPE_STRING, 'default' => '', 'maxLength' => 255,
				),
				'example'    => array('type' => self::TYPE_STRING, 'required' => true,
						'requiredError' => 'please_enter_embed_html'
				),
				'active'    => array('type' => self::TYPE_UINT, 'default' => 1),
				'requiresOption'    => array('type' => self::TYPE_UINT, 'default' => 0),
			)
		);
	}

	protected function _verifyOnlyOneMethod()
	{
		if($this->get('replacementBegin') && $this->get('phpcallback_method'))
		{
			$this->error(new XenForo_Phrase('bbcm_errorEnterOneReplacementMethod'), 'tag');
			return false;
		}
		if($this->get('replacementBegin') && $this->get('phpcallback_class'))
		{
			$this->error(new XenForo_Phrase('bbcm_errorEnterOneReplacementMethod'), 'tag');
			return false;
		}
		if($this->get('replacementEnd') && $this->get('phpcallback_class'))
		{
			$this->error(new XenForo_Phrase('bbcm_errorEnterOneReplacementMethod'), 'tag');
			return false;
		}
		if($this->get('replacementEnd') && $this->get('phpcallback_method'))
		{
			$this->error(new XenForo_Phrase('bbcm_errorEnterOneReplacementMethod'), 'tag');
			return false;
		}
		return true;
	}
	protected function _verifyAMethod()
	{
		if($this->get('phpcallback_class') == '' && $this->get('phpcallback_method') == '' && $this->get('replacementBegin') == '' && $this->get('replacementEnd') == '')
		{
			$this->error(new XenForo_Phrase('bbcm_errorEnterAReplacementMethod'), 'tag');
			return false;
		}
		return true;
	}
}
And the _verifyAMethod() always gets a TRUE value.
 

Shadab

Well-known member
#2
Edit:

Nvm. It looks like get() just a smarter version of merged getExisting() and getNew(). Can you post what your input data is, the data that you expect to get and what you actually are getting?
 

Kier

XenForo Developer
Staff member
#3
You need to pass a parameter into the validation method:
PHP:
protected function _verifyMooability($input)
{
	if ($input != 'cow')
	{
		$this->error(new XenForo_Phrase('not_a_mooing_animal', $input), 'fieldname');
		return false;
	}

	return true;
}
 

Jaxel

Well-known member
#4
I got a question... Lets say I run this:

Code:
		$dw = XenForo_DataWriter::create('EWRmedio_DataWriter_Media');
		$dw->bulkSet(array(
			'category_id'    => $input['category_id'],
			'service_id' => $input['service_id'],
			'service_value' => $input['service_value'],
			'service_value2' => $input['service_value2'],
			'media_title' => $input['media_title'],
			'media_description' => $input['media_description'],
			'media_duration' => $input['media_seconds'] + ($input['media_minutes'] * 60),
			'media_keywords' => $input['media_keywords'],
		));
		$dw->save();
The primary data field for EWRmedio_DataWriter_Media is an autoincrement 'media_id'...

Once this is saved... how do I get it to return the new 'media_id'?
 

Jaxel

Well-known member
#7
Hmm... I can't seem to get data verification working...
Code:
'category_id' => array('type' => self::TYPE_UINT, 'required' => true, 'verification' => array('$this', '_verifyCategory')),
Code:
	protected function _verifyCategory($input)
	{
		if ($category = $this->getModelFromCache('EWRmedio_Model_Categories')->getCategoryByID($input))
		{
			$this->error("category does not exist", 'category_id');
			return false;
		}

		return true;
	}
For some reason, it always returns true... even if the category doesn't exist...
 

Kier

XenForo Developer
Staff member
#8
Isn't your logic a bit screwy there?

if (a category with a the specified ID exists)
{
error, category does not exist
}
 

Jaxel

Well-known member
#10
Okay... now I have a real issue... I have this in my datawriter:
Code:
protected function _preSave()
{
	$visitor = XenForo_Visitor::getInstance();
	$this->set('user_id', $visitor['user_id']);
	$this->set('username', ($visitor['user_id'] ? $visitor['username'] : $_SERVER['REMOTE_ADDR']));
	$this->set('media_date', time());
}
Its simple... when the data is created, it sets the user_id and username as the current user... and then sets the media_date as the current time. This works great for when I am creating new database entries. However, when I go back to edit an old entry, it runs this process again.... it will update the time, instead of keeping the old time, and update the user_id and username to the current user, instead of the original user.

In vBulletin, it forced you to manually run preSave, so it was simple enough just to not call it. But now that preSave runs automatically, I can't stop the update. Any ideas?
 

Shadab

Well-known member
#11
You have to check if it's going to do an insert or an update. Try:
PHP:
if ($this->isInsert())
{
    // Code runs only on inserts
}
 

Jeremy

Well-known member
#12
You need to pass a parameter into the validation method:
PHP:
protected function _verifyMooability($input)
{
	if ($input != 'cow')
	{
		$this->error(new XenForo_Phrase('not_a_mooing_animal', $input), 'fieldname');
		return false;
	}

	return true;
}
OK, but how does it assume what to pass? Or doing it in _preSave() is the wrong idea? Would it hurt if I pass in $dwInput?
 

Kier

XenForo Developer
Staff member
#17
Aah, don't do that - put them in individual methods and have them referenced via the verification keys of the array returned by _getFields().

See _verifySiteUrl($url) in XenForo_DataWriter_BbCodeMediaSite for an example.
 

Jeremy

Well-known member
#18
Aah, don't do that - put them in individual methods and have them referenced via the verification keys of the array returned by _getFields().

See _verifySiteUrl($url) in XenForo_DataWriter_BbCodeMediaSite for an example.
Thanks. :) But, if I need it to verify two (or more) items at once, how would I do that? Can I accomplish it via something along the lines of this:
PHP:
<?php

class myDataWriter
{
	var $first, $second, $third, $fourth;
	function _myValidation($callbackmethod)
	{
		$this->first = $callbackmethod;
		return true;
	}
	function _myCompleteValidation()
	{
		if($this->first == '' && $this->second == '')
		{
			// throw error
			return false;
		}
		return true
	}
	function _preSave()
	{
		$this->_myCompleteValidation();
	}
}

?>
 

Kier

XenForo Developer
Staff member
#19
Not entirely sure what your code is trying to achieve here - but individual verification functions can't compare input values, so that's not going to be what you want. Additionally, you can't use the $this->first = $callbackmethod; approach you have there, as $this->first would only ever be set if _myValidation() is called, which you cannot guarantee.

Therefore, you're going to have to do it in _preSave() using $this->get($fieldname) in order to fetch the necessary data after the individual fields have been verified in isolation.

Note that _preSave() does not error by returning false, it needs to have errors thrown explicitly.
PHP:
protected function _preSave()
{
	$f1 = $this->get('f1');
	$f2 = $this->get('f2');

	if ($f1 == $f2)
	{
		$this->error('something went wrong', 'f1');
	}
}
See XenForo_DataWriter_AdminNavigation->_preSave() for an example.
 

Jeremy

Well-known member
#20
I think that's what I needed. More of an explaination:

I am attempting to validate two things:
1. That you only put 1 valid replacement method (there is Simple & PHP)
2. That the PHP Callback is valid.

So, I should be doing my verification in _preSave() using the get() function? I'll be seeing if that works, as I want to get BB Code Manager out into the wild. I have a few things to do first today, but I'll get to it.