How do I add an input field in the Admin CP and create table

My guess is the Installation Code will be the following.

Class: Andy_SmilieCount_Model
Method: Install

And the Uninstallation code will be the following.

Class: Andy_SmilieCount_Model
Method: Uninstall
 
Based on my assumption I created a file called:

library/Andy/SmilieCount/Model/Install.php

PHP:
<?php

class Andy_SmilieCount_Model_Install
{
	public static function install()
	{
		$db = XenForo_Application::get('db');

		$db->query("
		CREATE TABLE IF NOT EXISTS `andy_smilie_count` (
		`max_smilie` int(10) unsigned NOT NULL
		) ENGINE=InnoDB DEFAULT CHARSET=utf8
		");
	}
}

?>
 
Last edited:
I also created a file called:

library/Andy/SmilieCount/Model/Uninstall.php

PHP:
<?php

class Andy_SmilieCount_Model_Install
{
	public static function install()
	{
		$db = XenForo_Application::get('db');

		$db->query("
		CREATE TABLE IF NOT EXISTS `andy_smilie_count` (
		`max_smilie` int(10) unsigned NOT NULL,
		PRIMARY KEY (max_smilie)
		) ENGINE=InnoDB DEFAULT CHARSET=utf8
		");
	}
}

?>
 
Last edited:
I've created a table called andy_smilie_count. In it there's a field called max_count. The field value currently is 7.

With this code in my Tools.php file I'm trying to run this query:

PHP:
$max_count = array();
$db = XenForo_Application::getDb();
return $db->fetchRow('SELECT max_smilie FROM andy_smilie_count WHERE max_smilie = ?', $max_count);

I get the following error:

Mysqli statement execute error : No data supplied for parameters in prepared statement
 
Last edited:
Tools.php

PHP:
<?php

class Andy_SmilieCount_ControllerAdmin_Tools extends XenForo_ControllerAdmin_Tools
{
   public function actionIndex()
   {   
     // get data table andy_smilie_count
     // !!! this does not work yet
     $max_count = array();
     $db = XenForo_Application::getDb();
     return $db->fetchRow('SELECT max_smilie FROM andy_smilie_count WHERE max_smilie = ?', $max_count);   
     
     //return $this->responseError($max_count);
     
     //$max_count = '5';
     // display andy_smiliecount template
     $viewParams = array('post' => $max_count);
     return $this->responseView('Andy_ViewPublic_Post','andy_smiliecount',$viewParams);
   }
     
   public function actionSave()
   {       
     // make sure data comes from $_POST
     $this->_assertPostOnly();
     
     // get new_post_date from overlay     
     $newSmilieCount = $this->_input->filterSingle('new_smilie_count', XenForo_Input::STRING);
     
     //########################################
     // save $newSmilieCount
     
     
     
     
     //########################################
     // response redirect        
       
     return $this->responseRedirect(
       XenForo_ControllerResponse_Redirect::SUCCESS,
       XenForo_Link::buildAdminLink('tools')
     );   
   }
}

?>
 
$max_count shouldn't be an array. It should be the value of what you are searching for in your query (the "?" Gets replaced with it when doing query).
 
Thank you, Shawn. I appreciate the clarification.

I finally got it to work and here's the code.

PHP:
<?php

class Andy_SmilieCount_ControllerAdmin_Tools extends XenForo_ControllerAdmin_Tools
{
   public function actionIndex()
   {   
     // get data from table andy_smilie_count
     $db = XenForo_Application::getDb();   
     $viewParams = $db->fetchRow("select max_smilie from `andy_smilie_count`");

     // pass $viewParams to template and display template
     return $this->responseView('Andy_ViewPublic_Post','andy_smiliecount',$viewParams);
   }
     
   public function actionSave()
   {       
     // make sure data comes from $_POST
     $this->_assertPostOnly();
     
     // get new_post_date from overlay     
     $newSmilieCount = $this->_input->filterSingle('new_smilie_count', XenForo_Input::STRING);
     
     //########################################
     // save $newSmilieCount
     
     
     
     
     //########################################
     // response redirect        
       
     return $this->responseRedirect(
       XenForo_ControllerResponse_Redirect::SUCCESS,
       XenForo_Link::buildAdminLink('tools')
     );   
   }
}

?>
 
Here's the andy_smiliecount template

Code:
<xen:title>Smilie Count</xen:title>

<form action="{xen:adminlink 'smiliecount/save', $post}" method="post" class="xenForm AutoValidator" data-redirect="on">

<fieldset>

<dl class="ctrlUnit">
  <dt><label>Enter maximum smilie count per post:</label></dt>
  <dd><input type="text" name="new_smilie_count" size="10" value="{$max_smilie}" class="textCtrl titleCtrl"></dd>
</dl>

<dl class="ctrlUnit submitUnit">
  <dt></dt>
  <dd><input type="submit" value="Submit" class="button primary" accesskey="s" /></dd>
</dl>
</fieldset>

<input type="hidden" name="_xfToken" value="{$visitor.csrf_token_page}" />
</form>
 
Okay so far so good. I'm now able to update my custom table with this code:

PHP:
<?php

class Andy_SmilieCount_ControllerAdmin_Tools extends XenForo_ControllerAdmin_Tools
{
   public function actionIndex()
   {   
     // get data from table andy_smilie_count
     $db = XenForo_Application::getDb();   
     $viewParams = $db->fetchRow("select max_smilie from `andy_smilie_count`");

     // pass $viewParams to template and display template
     return $this->responseView('Andy_ViewPublic_Post','andy_smiliecount',$viewParams);
   }
     
   public function actionSave()
   {       
     // make sure data comes from $_POST
     $this->_assertPostOnly();
     
     // get new_post_date from overlay     
     $newSmilieCount = $this->_input->filterSingle('new_smilie_count', XenForo_Input::STRING);
     
     // save $newSmilieCount
     $db = XenForo_Application::getDb();   
     $db->query("
       UPDATE andy_smilie_count
       SET max_smilie = '$newSmilieCount'
       WHERE max_smilie <> ''
     ");       
     
     // response redirect        
     return $this->responseRedirect(
       XenForo_ControllerResponse_Redirect::SUCCESS,
       XenForo_Link::buildAdminLink('tools')
     );   
   }
}

?>
 
However I need to move the UPDATE query to the Model in order to follow the proper xF framework.
 
However I need to move the UPDATE query to the Model in order to follow the proper xF framework.

Negative. You need to be using DataWriter.

PHP:
$dw = XenForo_DataWriter::create('DATAWRITERCLASS');
if ($update)
{
$dw->setExistingData($existingData);
}
$dw->set('field', 'value');
$dw->save();
 
Thank you, Daniel. I was wondering if the DataWriter is the correct way to do this.

Now to figure out how to adjust your example to my code.
 
I'm stuck on the first line.

PHP:
$dw = XenForo_DataWriter::create('DATAWRITERCLASS');

What value do I put in the DATAWRITERCLASS? Remember I'm wanting to update a table I created called andy_smilie_count.
 
Last edited:
You put the path to your class in the datawriter.
Should be something along the lines of

Andy_Smilie_DataWriter_Count
 
You put the path to your class in the datawriter.
Should be something along the lines of

Andy_Smilie_DataWriter_Count

Thank you, Daniel.

So far I have:

PHP:
    $dw = XenForo_DataWriter::create('Andy_SmilieCount_DataWriter_UpdateTable');
     if ($update)
     {
       $dw->setExistingData($existingData);
     }
     $dw->set('max_smilie', $newSmilieCount);
     $dw->save();

What is the purpose of $update if statement?
 
Am I suppose to set up another Code Event Listener? If so I assume the it will need to listen to the load_class_datawriter event?
 
You have to assign $update to true if you want to update a row, otherwise it's going to insert a new one.

No code event listener is needed, you aren't extending; you are making a new table, new datawriter, etc...
 
No code event listener is needed, you aren't extending; you are making a new table, new datawriter, etc...


Do I have to create another file like UpdateTable.php or will this code update my custom table?

The table andy_smilie_count already exists.

PHP:
    $dw = XenForo_DataWriter::create('Andy_SmilieCount_DataWriter_UpdateTable');
     if ($update)
     {
       $dw->setExistingData($existingData);
     }
     $dw->set('max_smilie', $newSmilieCount);
     $dw->save();
 
Top Bottom