Last DataWriter question (for now) -- Seriously

Jeremy

in memoriam 1991-2020
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.
 
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?
 
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;
}
 
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'?
 
Hmm... so obvious... just confused me because of the shortcut for it in vBulletin.
 
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...
 
Isn't your logic a bit screwy there?

if (a category with a the specified ID exists)
{
error, category does not exist
}
 
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?
 
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
}
 
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?
 
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.
 
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();
	}
}

?>
 
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.
 
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.
 
Top Bottom