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

Built in File Upload Handler?

Jaxel

Well-known member
#1
Okay... as some of you know, I am working on a modular portal/sidebar system. I plan on having sidebar modules controlled by XML files... below is an example of such an XML file:

Code:
<?xml version="1.0" encoding="UTF-8"?>

<module>
	<module_name>facebook</module_name>
	<module_class></module_class>
	<module_template>EWRporta_Sidebar_Facebook</module_template>
	<module_content><![CDATA[<div class="section">
	<div class="secondaryContent" id="facebook" style="padding-right: 0px; padding-bottom: 0px;">
		<script src="http://connect.facebook.net/en_US/all.js#xfbml=1"></script>
		<fb:fan profile_id="{$option.profile_id}" stream="0" connections="8" logobar="0" width="240" height="216" css="{xen:link 'full:js/facebook.css'}?50"></fb:fan>
	</div>
</div>]]></module_content>
	<module_settings>
		<profile_id>144610425559666</profile_id>
	</module_settings>
</module>
I already asked before if XF had a built in XML handler, and as it turns out, XF simply uses the built in SimpleXML feature in PHP... which is fine, but I'll have to learn how it works since I've always just used built in functions from within VB. However, my question is, does XF have a built in file upload handler like VB did?

With VB, I would have just done:

Code:
	$vbulletin->input->clean_array_gpc('f', array(
		'upload'	=> TYPE_FILE,
	));

	$upload = file_get_contents($vbulletin->GPC['upload']['tmp_name']);

	require_once(DIR.'/includes/class_xml.php');
	$xmlobj = new vB_XML_Parser($upload);
	$xmlArray = $xmlobj->parse();
How would I do this same thing in XF? Remember that I don't need to store the file anywhere. It just need to be read into a variable called $xmlArray and then thrown away.
 

Shadab

Well-known member
#2
Try this: (untested :))

PHP:
// See: XenForo_ControllerAdmin_AddOn::actionInstall()

$fileTransfer = new Zend_File_Transfer_Adapter_Http();

if ($fileTransfer->isUploaded('upload_file'))
{
	// For: <input type="file" name="upload_file" />
	$fileInfo = $fileTransfer->getFileInfo('upload_file');
	$fileName = $fileInfo['upload_file']['tmp_name'];

	$xmlDocument = new SimpleXMLElement($fileName, null, true);

	// more processing with the xmldoc
}
 

Jaxel

Well-known member
#3
Hmm... that definately solved my file upload problems... but it doesn't return the data the way I would expect...

Code:
SimpleXMLElement Object
(
    [module_name] => facebook
    [module_class] => SimpleXMLElement Object
        (
        )

    [module_template] => EWRporta_Sidebar_Facebook
    [module_content] => SimpleXMLElement Object
        (
        )

    [module_settings] => SimpleXMLElement Object
        (
            [profile_id] => 144610425559666
        )

)
I would expect the data as follows:

Code:
Array
(
    [module_name] => facebook
    [module_class] =>
    [module_template] => EWRporta_Sidebar_Facebook
    [module_content] => <div class="section">
	<div class="secondaryContent" id="facebook" style="padding-right: 0px; padding-bottom: 0px;">
		<script src="http://connect.facebook.net/en_US/all.js#xfbml=1"></script>
		<fb:fan profile_id="{$option.profile_id}" stream="0" connections="8" logobar="0" width="240" height="216" css="{xen:link 'full:js/facebook.css'}?50"></fb:fan>
	</div>
</div>
    [module_settings] => Array
        (
            [profile_id] => 144610425559666
        )

)
Unfortunately, as it stands, the array is casting module_class, module_content and module_settings into new SimpleXMLElement Objects. Any idea on how to take care of this?
 

Jaxel

Well-known member
#4
Okay... it looks like I can still access module_content using:

$xmlDocument->module_content

However, I am having issues accessing module_settings
Code:
	foreach ($xmlDocument->module_settings AS $setting => $key)
	{
		echo $key." ".$setting."<br />";
	}
I assume this would print out "profile_id 144610425559666", but instead it just prints out "module_settings"
 

Shadab

Well-known member
#5
PHP:
$xmlDocument = new SimpleXMLElement($data);

print_r(array(
	(string) $xmlDocument->module_name,
	(string) $xmlDocument->module_class,
	(string) $xmlDocument->module_template,
	(string) $xmlDocument->module_content,
	(string) $xmlDocument->module_settings->profile_id
));
Remember, "$xmlDocument->module_settings" is an object as well.
 

Jaxel

Well-known member
#6
I can't use $xmlDocument->module_settings->profile_id
In any given instance, there may be several settings, and they probably wont be called "profile_id".
I need to be able to parse through module_settings, and get the name of the field, and it's value...

This works for everything except module_settings
Code:
			echo "Name: ".$module->module_name."<br />";
			echo "Class: ".$module->module_class."<br />";
			echo "Template: ".$module->module_template."<br />";
			echo "Content: ".$module->module_content."<br />";

			foreach ($module->module_settings AS $setting => $key)
			{
				echo $key." ".$setting."<br />";
			}
I just cant get the contents of module_settings, its just not working.
 

Shadab

Well-known member
#7
PHP:
$nodes = $xmlDocument->module_settings->children();

foreach ($nodes as $node)
{
	echo $node->getName() . ' ' . (string) $node;
}
PS: The (string) cast is not really needed when echo/print-ing. It's only required when, for example, you are creating an array where array keys are being sourced from a SimpleXMLElement.
 

Jaxel

Well-known member
#10
Okay... new question... using the following input:
Code:
<module>
	<module_name>facebook</module_name>
	<module_settings>
		<profile_id description"this is a test">144610425559666</profile_id>
	</module_settings>
</module>
I am retrieving the "module_settings" thusly:
Code:
		foreach ($file->module_settings->children() AS $key => $value)
		{
			echo $key." - ".$value."<br />"; exit;
		}
This code properly outputs: profile_id - 144610425559666

You'll notice that in the XML code, there is an attribute called "description". How would I access that value inside of the foreach?
 

Shadab

Well-known member
#11
For accessing node attributes, you can use the array syntax...
PHP:
$xmlDocument = new SimpleXMLElement($data);

foreach($xmlDocument->module_settings->children() as $node)
{
	echo $node['description'] . PHP_EOL;
}