How to read and write into the database (with a page)

xF1 Unmaintained How to read and write into the database (with a page) 1.0

No permission to download
Step 6 - The Controller

We want save and read in our table, right? Yes! Note that these are two actions.

To define actions, we use Controllers . But what is this thing?


Controller (XenForo_Controller) - Handle user interaction, work with the model, and ultimately select a view to render that displays UI. In an MVC application, the view only displays information; the controller handles and responds to user input and interaction. E.G.: the controller handles query-string values, and passes these values to the model, which in turn might use these values to query the database. This is basically what takes the input, decides how to handle it and directs the rest of the system as to what to do next. All controllers in XenForo should implement methods named 'actionX' with no arguments. There are two types: ControllerPublic and ControllerAdmin.
Now we know this, we are able to create our two actions: actionWrite and actionRead.



Create a new folder and a new file and the new scructure will be like this:


forumroot
--library
---SimpleText
-----ControllerPublic - new!
--------SimpleText.php - new!
-----DataWriter
--------SimpleText.php
-----Model
--------SimpleText.php
-----Installer.php
---XenForo



Open the ControllerPublic/SimpleText.php file and let's give a name to the class:


PHP:
<?php
class SimpleText_ControllerPublic_SimpleText extends XenForo_ControllerPublic_Abstract
{
 
}
?>

Now, we create the actionWrite:

PHP:
/**
* Write to the database the text that the user wrote in the textbox.
*/
public function actionWrite()
{
    //Get the text that user wrote in the text box
    $text = $this->_input->filterSingle('simple_text', XenForo_Input::STRING);
 
    //Create a instance of our DataWriter
    $dwSimpleText = XenForo_DataWriter::create('SimpleText_DataWriter_SimpleText');
 
    //Set the field with the data we filtered
    $dwSimpleText->set('simple_text', $text);
 
    //Save in the database, please!
    $dwSimpleText->save();
 
    //Send a response to the user, so he know that everything went fine with this action
    return $this->responseRedirect(
                XenForo_ControllerResponse_Redirect::SUCCESS,
                $this->getDynamicRedirect()
            );
}

Simple, eh? Since I already have commented each line, do not need to explain in here. Your lesson will be to understand each one.




Now, we create the actionRead:
PHP:
/**
* Get all the saved text in our table.
*/
public function actionRead()
{
    //Get all rows from our table and set it to a variable
    $viewParams = array('simpleText' => $this->_getSimpleTextModel()->getAllSimpleText());
 
    //Send a response view, using a template, to show all the data that we get it.
    return $this->responseView('XenForo_ViewPublic_Base', 'simpletext', $viewParams);
 
}

As you can see, we do not created yet the template (simpletext) to use in this response. We'll create it later. Dont worry!


And for the last, we create the common function _getSimpleTextModel:


PHP:
/**
* Get the simple text model.
*
* @return SimpleText_Model_SimpleText
*/
protected function _getSimpleTextModel()
{
    return $this->getModelFromCache ( 'SimpleText_Model_SimpleText' );
}

And this is the final code from the Controller file:


PHP:
<?php
class SimpleText_ControllerPublic_SimpleText extends XenForo_ControllerPublic_Abstract
{
    /**
    * Write to the database the text that the user wrote in the textbox.
    */
    public function actionWrite()
    {
        //Get the text that user wrote in the text box
        $text = $this->_input->filterSingle('simple_text', XenForo_Input::STRING);
 
        //Create a instance of our DataWriter
        $dwSimpleText = XenForo_DataWriter::create('SimpleText_DataWriter_SimpleText');
 
        //Set the field with the data we filtered
        $dwSimpleText->set('simple_text', $text);
 
        //Save in the database, please!
        $dwSimpleText->save();
 
        //Send a response to the user, so he know that everything went fine with this action
        return $this->responseRedirect(
                    XenForo_ControllerResponse_Redirect::SUCCESS,
                    $this->getDynamicRedirect()
                );
    }
 
    /**
    * Get all the saved text in our table.
    */
    public function actionRead()
    {
        //Get all rows from our table and set it to a variable
        $viewParams = array('simpleText' => $this->_getSimpleTextModel()->getAllSimpleText());
 
        //Send a response view, using a template, to show all the data that we get it.
        return $this->responseView('XenForo_ViewPublic_Base', 'simpletext', $viewParams);
 
    }
 
 
    /**
    * Get the simple text model.
    *
    * @return SimpleText_Model_SimpleText
    */
    protected function _getSimpleTextModel()
    {
        return $this->getModelFromCache ( 'SimpleText_Model_SimpleText' );
    }
}
?>

Step 7 - The Route

What is this?

Basic explanation:

Routes are the things which translate a URL into a controller? and action?. They can also define parameters that are available to the controller, such as an ID or other identifier.
Ok, now we have our actions and know (basic) what is a route. But how we can access this actions in XenForo? I mean...take a look at this URL:

Code:
http://xenforo.com/community/watched/threads
Just looking at it, we can tell what is action and what is the route.

Route-> Watched (XenForo_Route_Prefix_Watched)
Controller-> Watched (XenForo_ControllerPublic_Watched)
Action-> actionThreads (XenForo_ControllerPublic_Watched::actionThreads())

Explaining:

Code:
http://xenforo.com/community*1*/watched*2*/threads*3*
*1* - The main site, this is where the XenForo is installed.
*2* - The controller (and with the same name, the route).
*3* - The action.

Why the route it is not in the explanation above? Because each controller has their own route, using the same name.

If you open side by side the the folder forumroot\library\XenForo\Route\Prefix andforumroot\library\XenForo\ControllerPublic you will notice that there is the same number of files (dont count the Abstract.php file) and each controller has the same name of their own route!.

So, we are creating an new add-on. Which in this case will have to use a root to access the our two actions: actionWrite and actionRead.

This time we will have two new folders and one new file:


forumroot
--library
---SimpleText
-----ControllerPublic
--------SimpleText.php
-----DataWriter
--------SimpleText.php
-----Model
--------SimpleText.php
-----Route - new!
--------Prefix - new!
-----------SimpleText.php - new!
-----Installer.php
---XenForo



Open the file Route/Prefix/SimpleText.php and name our class:


PHP:
<?php
class SimpleText_Route_Prefix_SimpleText implements XenForo_Route_Interface
{
 
}
?>

As this is a tutorial about reading and writing in the database, I'll not get any deep explaning how route works. Maybe in another tutorial.

Final Code:

PHP:
<?php
class SimpleText_Route_Prefix_SimpleText implements XenForo_Route_Interface
{
    /**
    * Match a specific route for an already matched prefix.
    *
    * @see XenForo_Route_Interface::match()
    */
    public function match($routePath, Zend_Controller_Request_Http $request, XenForo_Router $router)
    {
        //Please, discover what action the user wants to call!
        $action = $router->resolveActionWithIntegerParam($routePath, $request, 'simple_id');
        //Call the action in the controller SimpleText_ControllerPublic_SimpleText!
        return $router->getRouteMatch('SimpleText_ControllerPublic_SimpleText', $action, 'simpletext');
    }
 
    /**
    * Method to build a link to the specified page/action with the provided
    * data and params.
    *
    * @see XenForo_Route_BuilderInterface
    */
    public function buildLink($originalPrefix, $outputPrefix, $action, $extension, $data, array &$extraParams)
    {
        return XenForo_Link::buildBasicLinkWithIntegerParam($outputPrefix, $action, $extension, $data, 'simple_id');
    }
}
?>


XENXERCISE
XENXERCISE.png
Try to guess the controller, route and action of the following URL:

URL-> http://xenforo.com/community/posts/282438/like
Route-> ?
Controller-> ?
Action-> ?

URL-> http://xenforo.com/community/recent-activity/
Route-> ?
Controller-> ?
Action-> ?


URL-> http://xenforo.com/community/members/kier.2/
Route-> ?
Controller-> ?
Action-> ?


Step 8 - AdminCP

ENOUGH! Our work with php files is done. Now, lets do the easy job (hehe) using the Admin Control Panel.

XenForo is smart, but we have to tell him that we are creating a new addon. So, go to AdminCP -> Development -> Create Add-on and fill with this info:

Add-in ID: simpleText
Title: Simple Text
Add-on is active: Checked!
Version String: 1.0.0
Version ID: 1
Installation Code Class: SimpleText_Installer
Installation Code Method: install
Uninstallation Code Class: SimpleText_Installer
Uninstallation Code Method: uninstall

Save it!

If you take a look at your PHPMYADMIN you'll notice that XenForo did not created any of our tables.

To do this, put the mouse above the Controls menu, in the add-on list and hit Export. Save it in any folder that you want.

After, you just need to put the mouse again in the Controls menu but this time hit Upgrade and choose the .xml file exported before. You can check in the PHPMYADMIN if the tables were created.


Remember in the previous step that we created a file for the route? Eh....we need now to create a route in the AdminCP to get things working.


Go to AdminCP -> Development -> Route Prefixes and click in the button "Create New Route Prefix":

Route Prefix: simpletext
Route Type: Public
Route Class: SimpleText_Route_Prefix_SimpleText
Use class to build link: Only when data is provided
Add-on: Simple Text

...aaaand save it!!

Go to http://yoursite.com/forumroot/index.php?simpletext and if all have worked, you'll see a error:

The controller SimpleText_ControllerPublic_SimpleText does not define an action called Index.
If this is the error, so all our work until now is ok! Let's move!


Step 9 - The template

Remember this piece of code in our Controller??

PHP:
return $this->responseView('XenForo_ViewPublic_Base', 'simpletext', $viewParams);
So, we will now create the simpletext template! This template will show all the text that our Model will read from the database!

Go to Admin CP - > Appearence -> Templates and hit the button Create new Template.
The following code we will use to show the all the rows that were get by the Model in our table:


Code:
<ul>
<xen:foreach loop="$simpleText" value="$text">
<fieldset>
<li>
<dl class="ctrlUnit">
<dt><xen:datetime time="$text.simple_date" /></dt>
<dd>
{$text.simple_text}
</dd>
</dl>
<dl class="ctrlUnit"></dl>
</li>
</fieldset>
<br />
</xen:foreach>
</ul>
For each row in the array $simpleText we will echo the date and the text. Simple. Really simple....simple text!

Name of this template: simpletext.


Step 10 - The Page


Our tutorial will be using a page to demonstrate how to write and read into the database. It's easy to create a page:

Go to AdminCp -> Applications -> Create New Page and fill with the info:

URL Portion: SimpleText
Title: Simple Text Tutorial
Description: A page to read and write into the database.

The other options in this tab leave as it is.

Go to the tab Page Options:

We now reached the creation of the template html. We'll use two tabs: the first one to send the data and the second to read.

This is the final template HTML:

HTML:
<ul class="tabs Tabs" data-panes="#simpleTextPanes > li">
<li class="active"><a href="{$requestPaths.requestUri}#write">Write</a></li>
<li><a href="{$requestPaths.requestUri}#read">Read</a></li>
</ul>
<ul id="simpleTextPanes">
<li id="write">
<form action="{xen:link 'simpletext/write'}" method="post" class="xenForm">
<dl class="ctrlUnit">
<dt><label for="ctrl_message">{xen:phrase message}:</label></dt>
<dd><textarea name="simple_text" class="textCtrl Elastic" id="ctrl_message" rows="5"></textarea></dd>
</dl>
<dl class="ctrlUnit submitUnit">
<dt></dt>
<dd><input type="submit" value="{xen:phrase send_message}" accesskey="s" class="button primary" /></dd>
</dl>
</form>
</li>
 
<li id="read" class="profileContent" data-loadUrl="{xen:link simpletext/read}">
<span class="jsOnly">{xen:phrase loading}...</span>
</li>
</ul>
You can see that we are using our two actions:
To write:
HTML:
<form action="{xen:link 'simpletext/write'}"
To read:
HTML:
data-loadUrl="{xen:link simpletext/read}"
Save the page. You are able now to view the page in your node list.

Something like this: http://yourforum.com/forumroot/index.php?pages/SimpleText/


1-png.26047






Step 11 - The Final


Yeah!! We have done all the things necessary for this addon work! Great work guys!


Ok, we will now test.

In the page we've created, write something in the textarea. Hit the button "Send Message"!


2-png.26046


Now, click in the tab Read!
Have you seen the message?

If yes, it works!! Oh my god, so many work just to do this?
Yes...now is with you.

Make some tests, change things....