<?php
/* Sandbox v0.5-1.0b
* Copyright (c) 2006-2007
* Sam O'Connor (Kiasyn) http://www.kiasyn.com
*
* Additions to Sandbox after 1.0:
* Copyright (c) 2007-2010
* Roger Libiez [Samson] http://www.iguanadons.net
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from the
* use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it freely,
* subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim
* that you wrote the original software. If you use this software in a product,
* an acknowledgment in the product documentation is required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
* 4. You must make an effort to notify the author (Sam O'Connor) at the email
* address hide@address.com if you plan on publicly distributing a derivative
* of this software, whether by email, download or a form of disk/disc.
*
* Notifying Roger Libiez is not required but would still be appreciated :)
*/
if ( !defined('SANDBOX') || !defined('SANDBOX_ADM') ) {
header('HTTP/1.0 403 Forbidden');
die;
}
class downloads extends module
{
var $folder_array; // Used to generate folder trees
function execute()
{
static $folder_array = false;
$this->folder_array = &$folder_array;
if ( isset($this->get['s']) )
switch( $this->get['s'] )
{
case 'Delete': return $this->show_files( 'Delete' );
case 'Edit': return $this->show_files( 'Edit' );
case 'uploadfile': return $this->upload_file();
case 'Editfile': return $this->edit_file();
case 'Deletefile': return $this->delete_file();
case 'createfolder': return $this->create_folder();
case 'editfolder': return $this->edit_folder();
case 'deletefolder': return $this->delete_folder();
}
return $this->message( 'Downloads', 'Sorry, you need to specify an action to use this module.' );
}
function folder_array()
{
if( $this->folder_array === false ) {
$this->folder_array = array();
$q = $this->db->query( "SELECT * FROM {$this->pre}filefolders ORDER BY folder_name" );
while ($f = $this->db->assoc($q))
{
$this->folder_array[$f['folder_id']] = $f;
}
return $this->folder_array;
}
return $this->folder_array;
}
function build_folder_list( $fd, $action )
{
$folders = $this->folder_array();
$folder_list = "» <a href=\"admin.php?a=downloads&s=$action\">Root</a>";
if( $fd != 0 )
{
$parents = explode( ',', $folders[$fd]['folder_tree'] );
foreach( $parents as $parent )
{
if(!isset($folders[$parent]) || $folders[$parent]['folder_id'] == 0)
continue;
$folder_name = $folders[$parent]['folder_name'];
$folder_list .= "» <a href=\"admin.php?a=downloads&s=$action&f=$parent\">";
$folder_list .= $folder_name . '</a>';
}
$folder_name = $folders[$fd]['folder_name'];
$folder_list .= ' » ' . $folder_name;
}
return $folder_list;
}
function build_file_list( $f, $this_folder, $action )
{
$list[] = array();
$result = $this->db->query( "SELECT f.*, u.user_id, u.user_name, u.user_icon
FROM {$this->pre}filelist f
LEFT JOIN {$this->pre}users u ON u.user_id=f.file_user
WHERE file_folder=$f" );
while( $file = $this->db->assoc( $result ) )
{
$image = null;
if( $file['file_flags'] & POST_HAS_IMAGE ) {
$thumb = $this->settings['site_address'] . $this->thumb_dir . $file['file_md5name'] . '.' . $file['file_img_ext'];
$image = '<img src="' . $thumb . '" alt="" />';
}
$date = date( $this->settings['blog_dateformat'], $file['file_date'] );
$downloads = ' downloads';
if( $file['file_downloaded'] == 1 )
$downloads = ' download';
$list[] = array(
'name' => $file['file_name'],
'class' => 'file',
'link' => "admin.php?a=downloads&s=" . $action . "file&p={$file['file_id']}",
'size' => ceil($file['file_size'] / 1024),
'summary' => $file['file_summary'],
'image' => $image,
'date' => $date,
'user' => $file['user_name'],
'downloads' => $file['file_downcount'] . $downloads,
'icon' => $this->settings['site_address'] . $this->icon_dir . $file['user_icon'] );
}
return $list;
}
function show_files($action)
{
$this->title( 'Show Files' );
$count = 0; $this_folder = null;
$f = isset($this->get['f']) ? intval($this->get['f']) : 0;
$this_folder = $this->db->quick_query( "SELECT * FROM {$this->pre}filefolders WHERE folder_id=$f" );
if ( $f != 0 )
$this->title( $this_folder['folder_name'] );
$xtpl = new XTemplate( './skins/' . $this->skin . '/downloads_folder.xtpl' );
$xtpl->assign( 'tree', $this->build_folder_list($f, $action) );
$xtpl->assign( 'imgsrc', $this->settings['site_address'] . '/skins/' . $this->skin );
$folders = $this->folder_array;
foreach( $folders as $folder )
{
if( $folder['folder_parent'] != $f )
continue;
$id = $folder['folder_id'];
// Don't display a folder link for root
if( $id == 0 )
continue;
if( $this->user['user_id'] != $folder['folder_user'] && $this->user['user_level'] < USER_ADMIN )
continue;
$xtpl->assign( 'name', htmlspecialchars($folder['folder_name']) );
$xtpl->assign( 'parent', "admin.php?a=downloads&s=$action&f={$folder['folder_id']}" );
$xtpl->parse( 'DownloadFolder.Link' );
}
$list = $this->build_file_list( $f, $this_folder, $action );
foreach( $list as $item )
{
if( !isset($item['name']) )
continue;
$xtpl->assign( 'item_name', htmlspecialchars($item['name']) );
$xtpl->assign( 'item_icon', $item['icon'] );
$xtpl->assign( 'item_link', $item['link'] );
$xtpl->assign( 'item_date', $item['date'] );
$xtpl->assign( 'item_user', htmlspecialchars($item['user']) );
$xtpl->assign( 'item_image', $item['image'] );
$xtpl->assign( 'item_summary', htmlspecialchars($item['summary']) );
$xtpl->assign( 'item_size', $item['size'] );
$xtpl->assign( 'item_downloads', $item['downloads'] );
$xtpl->parse( 'DownloadFolder.File' );
}
$xtpl->assign( 'folder_summary', $action . ' which of these files?' ); // Yes, this is legit. Tricking the template into displaying the action text.
$xtpl->assign( 'folder_name', htmlspecialchars($this_folder['folder_name']) );
$xtpl->parse( 'DownloadFolder' );
return $xtpl->text( 'DownloadFolder' );
}
function file_error_message($error_code) {
switch ($error_code) {
case UPLOAD_ERR_INI_SIZE:
return 'Upload size exceeds size allowed by the server php.ini file. Contact your system administrator.';
case UPLOAD_ERR_FORM_SIZE:
return 'Upload size exceeds MAX_FILE_SIZE directive in the HTML form. Verify your HTML code is not specifying a size too small.';
case UPLOAD_ERR_PARTIAL:
return 'Partial file uploaded.';
case UPLOAD_ERR_NO_FILE:
return 'No file was uploaded.';
case UPLOAD_ERR_NO_TMP_DIR:
return 'Temporary folder missing. Contact your system administrator.';
case UPLOAD_ERR_CANT_WRITE:
return 'Server disk is full. Contact your system administrator.';
case UPLOAD_ERR_EXTENSION:
return 'Canceled by a PHP extension.';
default:
return 'An unknown error occured. Check your web server logs for details.';
}
}
function build_foldertree( $folder_id, &$folders )
{
$tree = array();
$orig_f = $folder_id;
do {
$old = $folder_id;
if ( isset($folders[$folder_id]) && $folders[$folder_id]['parent'] != $old )
array_unshift( $tree, htmlspecialchars($folders[$folder_id]['name']) );
}
while( isset($folders[$folder_id]) && ( $folder_id = $folders[$folder_id]['parent'] ) != $old );
if ( isset($folders[$folder_id]) )
array_unshift( $tree, $folders[$folder_id]['name'] );
return implode( ' » ', $tree );
}
function folder_options( $name = 'file_folder', $root = true, $select_id = -1, $exclude = -1 )
{
$out = null; $folders = array();
$f_and = null;
if( $this->user['user_level'] < USER_ADMIN ) {
if( !$root )
$f_and = "AND folder_user={$this->user['user_id']}";
else
$f_and = "WHERE folder_user={$this->user['user_id']} OR folder_id=0";
}
$result = $this->db->query( "
SELECT folder_id, folder_user, folder_name, folder_parent
FROM {$this->pre}filefolders
" . (!$root ? "WHERE folder_id!=0" : null) . "
$f_and
ORDER BY folder_parent" );
while ( $folder = $this->db->assoc($result) )
{
if( $this->user['user_level'] < USER_ADMIN && $folder['folder_user'] != $this->user['user_id'] )
continue;
if ( $folder['folder_id'] != $exclude )
$folders[$folder['folder_id']] = array( "name" => $folder['folder_name'], "parent" => $folder['folder_parent'] );
}
foreach( $folders as $id => $folder )
$out .= "<option value=\"$id\"" . ($id == $select_id ? " selected" : "") . ">" . $this->build_foldertree( $id, $folders ) . "</option>\n";
return "<select name=\"$name\" id=\"$name\">\n$out</select>";
}
function folder_list( $header, $link, $root = true )
{
$folders = array();
$f_and = null;
if( $this->user['user_level'] < USER_ADMIN ) {
if( !$root )
$f_and = "AND folder_user={$this->user['user_id']}";
else
$f_and = "WHERE folder_user={$this->user['user_id']} OR folder_id=0";
}
$result = $this->db->query( "
SELECT folder_id, folder_name, folder_parent
FROM {$this->pre}filefolders
" . (!$root ? "WHERE folder_id!=0" : null) . "
$f_and
ORDER BY folder_parent" );
while ( $folder = $this->db->assoc($result) )
$folders[$folder['folder_id']] = array( 'name' => $folder['folder_name'], 'parent' => $folder['folder_parent'] );
$links = '';
foreach( $folders as $id => $folder )
$links .= "<li><a href=\"{$link}$id\">" . $this->build_foldertree( $id, $folders ) . "</a></li>\n";
$xtpl = new XTemplate( './skins/' . $this->skin . '/AdminCP/downloads.xtpl' );
$xtpl->assign( 'heading', $header );
$xtpl->assign( 'links', $links );
$xtpl->parse( 'FolderPick' );
return $xtpl->text( 'FolderPick' );
}
function file_list( $header, $link, $folder )
{
$out = null; $files = array();
$result = $this->db->query( "SELECT file_id, file_user, file_name, file_size
FROM {$this->pre}filelist
WHERE file_folder=$folder" );
while ( $file = $this->db->assoc($result) )
{
if( $this->user['user_level'] < USER_ADMIN && $file['file_user'] != $this->user['user_id'] )
continue;
$out .= "<li><a href=\"{$link}{$file['file_id']}\">" . htmlspecialchars($file['file_name']) . "</a> (" . ceil($file['file_size'] / 1024) . " KB)</li>\n";
}
return "
<table>
<tr>
<td class=\"header\">" . htmlspecialchars($header) . "</td>
</tr>
<tr>
<td><ul>\n$out</ul></td>
</tr>
</table>";
}
function list_comments( $file_id )
{
$comments = $this->db->query( "SELECT c.*, u.user_name FROM {$this->pre}blogcomments c
LEFT JOIN {$this->pre}users u ON u.user_id=c.comment_user
WHERE comment_post=$file_id AND comment_type=" . COMMENT_FILE );
$xtpl = new XTemplate( './skins/' . $this->skin . '/AdminCP/post_comment_list.xtpl' );
while ( $comment = $this->db->assoc($comments) )
{
$xtpl->assign( 'edit_link', '<a href="admin.php?a=posts&s=edit_comment&p=' . $file_id . '&c='. $comment['comment_id'] . '">Edit Comment</a>' );
$xtpl->assign( 'delete_link', '<a href="admin.php?a=posts&s=del_comment&p='. $file_id . '&c=' . $comment['comment_id'] . '">Delete Comment</a>' );
$xtpl->assign( 'spam_link', '<a href="admin.php?a=posts&s=del_comment&t=spam&p=' . $file_id . '&c=' . $comment['comment_id'] . '">Report Spam</a>' );
$xtpl->assign( 'user_name', htmlspecialchars($comment['user_name']) );
$xtpl->assign( 'user_ip', $comment['comment_ip'] );
$xtpl->assign( 'comment_text', htmlspecialchars($comment['comment_message']) );
$xtpl->parse( 'Comments.Entry' );
}
$xtpl->parse( 'Comments' );
return $xtpl->text( 'Comments' );
}
function file_form( $header, $action_link, $file = array('file_flags' => 4, 'file_name' => null, 'file_description' => null, 'file_summary' => null, 'file_folder' => 0 ) )
{
$xtpl = new XTemplate( './skins/' . $this->skin . '/AdminCP/downloads.xtpl' );
$xtpl->assign( 'token', $this->generate_token() );
$xtpl->assign( 'heading', $header );
$xtpl->assign( 'action_link', $action_link );
$xtpl->assign( 'site_root', $this->settings['site_address'] );
$xtpl->assign( 'folder_options', $this->folder_options( "file_folder", true, $file['file_folder'] ) );
$xtpl->assign( 'filename', htmlspecialchars($file['file_name']) );
$xtpl->assign( 'summary', htmlspecialchars($file['file_summary']) );
$xtpl->assign( 'desc', htmlspecialchars($file['file_description']) );
$xtpl->assign( 'img', POST_HAS_IMAGE );
$xtpl->assign( 'pub', POST_PUBLISHED );
$xtpl->assign( 'cls', POST_CLOSED );
$xtpl->assign( 'ovr', POST_OVERRIDE );
$xtpl->assign( 'mbo', POST_MEMBERSONLY );
$flags = $file['file_flags'];
$xtpl->assign( 'imgbox', $flags & POST_HAS_IMAGE ? " checked=\"checked\"" : null );
$xtpl->assign( 'pubbox', $flags & POST_PUBLISHED ? " checked=\"checked\"" : null );
$xtpl->assign( 'clsbox', $flags & POST_CLOSED ? " checked=\"checked\"" : null );
$xtpl->assign( 'ovrbox', $flags & POST_OVERRIDE ? " checked=\"checked\"" : null );
$xtpl->assign( 'mbobox', $flags & POST_MEMBERSONLY ? " checked=\"checked\"" : null );
$xtpl->assign( 'bbcode_menu', $this->bbcode->get_bbcode_menu() );
if( isset($file['file_id']) )
$xtpl->assign( 'comment_list', $this->list_comments( $file['file_id'] ) );
$xtpl->parse( 'FileForm' );
return $xtpl->text( 'FileForm' );
}
function upload_file()
{
if ( isset( $this->post['submit'] ) )
{
if ( $this->files['file_file']['error'] != UPLOAD_ERR_OK )
return $this->error( 'An error occured while trying to upload that file: ' . $this->file_error_message($this->files['file_file']['error']) );
$skipimage = false;
if( $this->files['file_image']['error'] == UPLOAD_ERR_NO_FILE ) {
$skipimage = true;
} else {
if( $this->files['file_image']['error'] != UPLOAD_ERR_OK )
return $this->error( 'An error occured while trying to upload the image: ' . $this->file_error_message($this->files['file_image']['error']) );
}
$file = $this->files['file_file'];
$folder = intval($this->post['file_folder']);
$f = $this->db->quick_query( "SELECT folder_id, folder_user FROM {$this->pre}filefolders WHERE folder_id=$folder" );
if( $this->user['user_level'] < USER_ADMIN && $f['folder_user'] != $this->user['user_id'] && $f['folder_id'] != 0 )
return $this->error( 'Access Denied: You do not own the folder you are attempting to upload to.' );
$ext = '';
if (strtolower(substr($file['name'], -7)) == '.tar.gz')
$ext = 'tar.gz';
else
$ext = strtolower(substr($file['name'], -3));
$md5name = md5( $file['name'] . microtime() );
$new_fname = $this->file_dir . $md5name;
if ( !move_uploaded_file( $file['tmp_name'], $new_fname ) )
return $this->error( 'File failed to upload!' );
chmod( $new_fname, 0644 );
$filename = basename($file['name']);
$name = $this->db->escape($this->post['file_name']);
$desc = $this->db->escape($this->post['file_description']);
$summary = $this->db->escape($this->post['file_summary']);
$size = intval($file['size']);
$flags = 0;
foreach( $this->post['file_flags'] as $flag)
$flags |= intval($flag);
$img_ext = '';
if( !$skipimage ) {
$flags |= POST_HAS_IMAGE;
$img_file = $this->files['file_image']['tmp_name'];
$system = explode( '.', $this->files['file_image']['name'] );
$system[1] = strtolower($system[1]);
if ( !preg_match( '/jpg|jpeg|png|gif/', $system[1] ) )
return $this->message( 'Upload File Image', 'Invalid file type ' . $system[1] . '. Valid file types are jpg, png and gif.' );
$img_ext = $system[1];
$fname = $this->files['file_image']['tmp_name'];
$img_new_name = $this->thumb_dir . $md5name . '.' . $img_ext;
if ( !move_uploaded_file( $fname, $img_new_name ) )
return $this->message( 'Upload File Image', 'Image failed to upload!' );
$image = $this->createthumb( $img_new_name, $img_new_name, $img_ext, $this->settings['gallery_thumb_w'], $this->settings['gallery_thumb_h'] );
}
$this->db->query(
"INSERT INTO {$this->pre}filelist (file_name,file_user,file_filename,file_description,file_summary,file_img_ext,file_folder,file_md5name,file_size,file_type,file_date,file_flags)
VALUES ('$name', {$this->user['user_id']}, '$filename', '$desc', '$summary', '$img_ext', $folder, '$md5name', $size, '$ext', $this->time, $flags)" );
return $this->message( 'Upload File', 'The file had been uploaded.', 'Continue', 'admin.php' );
}
return $this->file_form( 'Upload File', 'admin.php?a=downloads&s=uploadfile' );
}
function edit_file()
{
if( !isset($this->get['p']) && !isset($this->post['p']) )
return $this->message( 'Edit File', 'No file was specified for editing.' );
$p = isset($this->get['p']) ? intval($this->get['p']) : intval($this->post['p']);
$dbfile = $this->db->quick_query( "SELECT * FROM {$this->pre}filelist WHERE file_id=$p" );
if ( !$dbfile )
return $this->message( 'Edit File', 'No such file.' );
if ( isset( $this->post['submit'] ) )
{
if( !$this->is_valid_token() ) {
return $this->error( 'Invalid or expired security token. Please go back, reload the form, and try again.' );
}
$newupload = false;
$old_filename = $dbfile['file_md5name'];
$md5name = '';
if( $this->files['file_file']['error'] == UPLOAD_ERR_OK )
{
$old_filename = $dbfile['file_md5name'];
$file = $this->files['file_file'];
$ext = explode( '.', $file['name'] );
$ext = strtolower($ext[1]);
if ( !ctype_alnum( $ext ) )
return $this->message( 'Edit File', 'Unknown filetype extension.' );
$md5name = md5( $file['name'] . microtime() );
$new_fname = $this->file_dir . $md5name;
if ( !move_uploaded_file( $file['tmp_name'], $new_fname ) )
return $this->message( 'Edit File', 'File failed to upload!' );
$newupload = true;
chmod( $new_fname, 0644 );
@unlink( $this->file_dir . $old_filename );
$filename = basename($file['name']);
$size = intval( $file['size'] );
// Since you uploaded a new file for this, reset the download counter.
$this->db->query( "UPDATE {$this->pre}filelist SET file_filename='$filename', file_downloaded=0,
file_md5name='$md5name', file_size=$size, file_type='$ext', file_date={$this->time}, file_downcount=0 WHERE file_id=$p" );
}
$folder = intval($this->post['file_folder']);
$name = $this->db->escape($this->post['file_name']);
$desc = $this->db->escape($this->post['file_description']);
$summary = $this->db->escape($this->post['file_summary']);
$img_ext = $dbfile['file_img_ext'];
$flags = 0;
foreach( $this->post['file_flags'] as $flag)
$flags |= intval($flag);
if( $this->files['file_image']['error'] == UPLOAD_ERR_OK )
{
$flags |= POST_HAS_IMAGE;
$old_ext = $dbfile['file_img_ext'];
$img_file = $this->files['file_image']['tmp_name'];
$system = explode( '.', $this->files['file_image']['name'] );
$system[1] = strtolower($system[1]);
if ( !preg_match( '/jpg|jpeg|png|gif/', $system[1] ) )
return $this->message( 'Upload File Image', 'Invalid file type ' . $system[1] . '. Valid file types are jpg, png and gif.' );
$img_ext = $system[1];
$fname = $this->files['file_image']['tmp_name'];
if( $newupload )
$img_new_name = $this->thumb_dir . $md5name . '.' . $img_ext;
else
$img_new_name = $this->thumb_dir . $old_filename . '.' . $img_ext;
if( $old_ext != $img_ext || $newupload )
@unlink( $this->thumb_dir . $old_filename . '.' . $old_ext );
$image = $this->createthumb( $fname, $img_new_name, $img_ext, $this->settings['gallery_thumb_w'], $this->settings['gallery_thumb_h'] );
} elseif( $newupload ) {
if( $flags & POST_HAS_IMAGE ) {
rename( $this->thumb_dir . $old_filename . '.' . $img_ext, $this->thumb_dir . $md5name . '.' . $img_ext );
}
}
$this->db->query( "UPDATE {$this->pre}filelist
SET file_name='$name', file_description='$desc', file_summary='$summary', file_folder=$folder, file_img_ext='$img_ext', file_flags=$flags
WHERE file_id=$p" );
$update = (isset($this->files['file_file']) && $this->files['file_file']['error'] == UPLOAD_ERR_OK ? ' and new file uploaded.' : '.' );
return $this->message( 'Edit File', 'File updated' . $update, 'Continue', 'admin.php' );
}
return $this->file_form( 'Edit File', "admin.php?a=downloads&s=Editfile&p=$p", $dbfile );
}
function do_delete_file( $id )
{
$file = $this->db->quick_query( "SELECT file_id, file_md5name, file_type FROM {$this->pre}filelist WHERE file_id=$id" );
if ( !$file )
return false;
@unlink( "{$this->file_dir}{$file['file_md5name']}" );
$this->db->query( "DELETE FROM {$this->pre}filelist WHERE file_id=$id" );
return true;
}
function delete_file()
{
if ( !isset($this->post['submit']) )
{
$p = intval($this->get['p']);
$file = $this->db->quick_query( "SELECT file_id, file_user, file_name, file_md5name
FROM {$this->pre}filelist
WHERE file_id=$p" );
if ( !$file )
return $this->message( 'Delete File', 'No such file.' );
$xtpl = new XTemplate( './skins/' . $this->skin . '/AdminCP/downloads.xtpl' );
$xtpl->assign( 'token', $this->generate_token() );
$xtpl->assign( 'action_link', 'admin.php?a=downloads&s=Deletefile&p='. $p );
$xtpl->assign( 'file_name', $file['file_name'] );
$xtpl->assign( 'file_id', $p );
$xtpl->parse( 'FileDelete' );
return $xtpl->text( 'FileDelete' );
return $this->message( 'Delete File', "Are you sure you want to delete {$file['file_name']} and all attached comments?", 'Delete', "admin.php?a=downloads&s=Deletefile&p=$p&confirm=1", 0 );
}
if ( isset($this->post['p']) )
{
if( !$this->is_valid_token() ) {
return $this->error( 'Invalid or expired security token. Please go back, reload the form, and try again.' );
}
$p = intval( $this->post['p'] );
$file = $this->db->quick_query( "SELECT file_id, file_user, file_md5name, file_folder, file_img_ext
FROM {$this->pre}filelist WHERE file_id=$p" );
if ( !$file )
return $this->message( 'Delete File', 'No such file.' );
@unlink( $this->thumb_dir . "{$file['file_md5name']}.{$file['file_img_ext']}" );
@unlink( $this->file_dir . $file['file_md5name'] );
$this->db->query( "DELETE FROM {$this->pre}filelist WHERE file_id=$p" );
$this->db->query( "DELETE FROM {$this->pre}blogcomments WHERE comment_post=$p AND comment_type=" . COMMENT_FILE );
$link = 'admin.php?a=downloads&s=Delete&f=' . $file['file_folder'];
return $this->message( 'Delete File', 'File deleted.', 'Continue', $link );
}
return $this->message( 'Delete File', 'No file selected.' );
}
function folder_form( $header, $action, $folder = array('folder_name' => null, 'folder_summary' => null, 'folder_parent' => 0, 'folder_hidden' => 0) )
{
$f = isset($this->get['f']) ? intval($this->get['f']) : null;
$xtpl = new XTemplate( './skins/' . $this->skin . '/AdminCP/downloads.xtpl' );
$xtpl->assign( 'token', $this->generate_token() );
$xtpl->assign( 'action_link', $action );
$xtpl->assign( 'heading', $header );
$xtpl->assign( 'folder_name', htmlspecialchars($folder['folder_name']) );
$xtpl->assign( 'folder_summary', htmlspecialchars($folder['folder_summary']) );
$xtpl->assign( 'folder_options', $this->folder_options( "folder_parent", true, $folder['folder_parent'], $f ) );
$xtpl->assign( 'fchecked', $folder['folder_hidden'] ? 'checked="checked"' : '' );
$xtpl->parse( 'FolderForm' );
return $xtpl->text( 'FolderForm' );
}
function create_folder()
{
if ( isset($this->post['submit']) )
{
if( !$this->is_valid_token() ) {
return $this->error( 'Invalid or expired security token. Please go back, reload the form, and try again.' );
}
$name = $this->db->escape($this->post['folder_name']);
$summary = $this->db->escape($this->post['folder_summary']);
$parent = intval($this->post['folder_parent']);
$hidden = isset($this->post['folder_hidden']) ? 1 : 0;
if ( empty($name) )
return $this->message( 'Create Downloads Folder', 'Specify a folder name.' );
$f = $this->db->quick_query( "SELECT folder_id, folder_user FROM {$this->pre}filefolders WHERE folder_parent=$parent" );
if( $this->user['user_level'] < USER_ADMIN && $f['folder_user'] != $this->user['user_id'] && $f['folder_id'] != 0 )
return $this->error( 'Access Denied: You cannot create a folder in someone else\'s parent folder.' );
$this->db->query( "
INSERT INTO {$this->pre}filefolders (folder_name,folder_user,folder_parent,folder_hidden,folder_summary)
VALUES ('$name', {$this->user['user_id']}, $parent, $hidden, '$summary')" );
$this->update_folder_trees();
return $this->message( 'Create Downloads Folder', 'Folder created.', 'Continue', 'admin.php' );
}
return $this->folder_form( 'Create Downloads Folder', 'admin.php?a=downloads&s=createfolder' );
}
function create_tree($array, $id)
{
foreach ($array as $cat) {
if ($cat['folder_parent'] == $id) {
return preg_replace('/^,/', '', $cat['folder_tree'] . ",$id");
}
}
}
function buildTree($folders, $parent)
{
$tree = '';
if (isset($folders[$parent]) && $folders[$parent]) {
$tree = $this->buildTree($folders, $folders[$parent]);
$tree .= ',';
}
$tree .= $parent;
return $tree;
}
function update_folder_trees()
{
$folders = array();
// Build tree structure of 'id' => 'parent' structure
$q = $this->db->query( "SELECT folder_id, folder_parent FROM {$this->pre}filefolders ORDER BY folder_parent" );
while ($f = $this->db->assoc($q))
{
if ($f['folder_parent']) {
$folders[$f['folder_id']] = $f['folder_parent'];
}
}
// Run through group
$q = $this->db->query( "SELECT folder_parent FROM {$this->pre}filefolders GROUP BY folder_parent" );
while ($f = $this->db->assoc($q))
{
if ($f['folder_parent']) {
$tree = $this->buildTree($folders, $f['folder_parent']);
} else {
$tree = '';
}
$this->db->query( "UPDATE {$this->pre}filefolders SET folder_tree='$tree' WHERE folder_parent={$f['folder_parent']}" );
}
}
function edit_folder()
{
$this->title( 'Edit Downloads Folder' );
if ( !isset($this->get['f']) && !isset($this->post['f']) )
return $this->folder_list( 'Edit which downloads folder?', 'admin.php?a=downloads&s=editfolder&f=', false );
$f = isset($this->get['f']) ? intval($this->get['f']) : intval($this->post['f']);
$folder = $this->db->quick_query(
"SELECT folder_id, folder_user, folder_name, folder_summary, folder_parent, folder_hidden
FROM {$this->pre}filefolders
WHERE folder_id=$f" );
if( $this->user['user_level'] < USER_ADMIN && $folder['folder_user'] != $this->user['user_id'] )
return $this->error( 'Access Denied: You do not own the folder you are trying to edit.' );
if ( isset($this->post['submit']) )
{
if( !$this->is_valid_token() ) {
return $this->error( 'Invalid or expired security token. Please go back, reload the form, and try again.' );
}
$name = $this->db->escape($this->post['folder_name']);
$summary = $this->db->escape($this->post['folder_summary']);
$parent = intval($this->post['folder_parent']);
$hidden = isset($this->post['folder_hidden']) ? 1 : 0;
$this->db->query( "UPDATE {$this->pre}filefolders SET folder_name='$name', folder_parent=$parent, folder_hidden=$hidden, folder_summary='$summary'
WHERE folder_id=$f" );
$this->update_folder_trees();
return $this->message( 'Edit Downloads Folder', 'Folder updated.', 'Continue', 'admin.php' );
}
return $this->folder_form( 'Edit Downloads Folder', "admin.php?a=downloads&s=editfolder&f=$f", $folder );
}
function delete_fold( $f )
{
if ( $f == 0 )
return false;
$result = $this->db->query( "SELECT folder_id FROM {$this->pre}filefolders WHERE folder_parent=$f" );
while ( $folder = $this->db->assoc( $result ) )
$this->delete_fold($folder['folder_id']);
$result = $this->db->query( "SELECT file_id FROM {$this->pre}filelist WHERE file_folder=$f" );
while ( $file = $this->db->assoc($result) )
$this->db->query( "UPDATE {$this->pre}filelist SET file_folder=0 WHERE file_id={$file['file_id']}" );
$this->db->query( "DELETE FROM {$this->pre}filefolders WHERE folder_id=$f" );
return true;
}
function delete_folder()
{
if ( !isset($this->get['f']) && !isset($this->post['f']) )
return $this->folder_list( 'Delete which downloads folder?', 'admin.php?a=downloads&s=deletefolder&f=', false );
$f = isset($this->get['f']) ? intval($this->get['f']) : intval($this->post['f']);
$folder = $this->db->quick_query( "SELECT folder_name, folder_user FROM {$this->pre}filefolders WHERE folder_id=$f" );
if( $this->user['user_level'] < USER_ADMIN && $folder['folder_user'] != $this->user['user_id'] )
return $this->error( 'Access Denied: You do not own the folder you are trying to delete.' );
if ( !isset($this->post['submit']) )
{
$count = $this->db->quick_query( "
SELECT COUNT(file_id) as count
FROM {$this->pre}filelist
WHERE file_folder=$f" );
$xtpl = new XTemplate( './skins/' . $this->skin . '/AdminCP/downloads.xtpl' );
$xtpl->assign( 'token', $this->generate_token() );
$xtpl->assign( 'action_link', 'admin.php?a=downloads&s=deletefolder&f=$f' . $f );
$xtpl->assign( 'folder_name', $folder['folder_name'] );
$xtpl->assign( 'folder_id', $f );
$xtpl->assign( 'count', $count['count'] );
$xtpl->parse( 'FolderDelete' );
return $xtpl->text( 'FolderDelete' );
return $this->message( 'Delete Downloads Folder', "Are you sure you want to delete the {$folder['folder_name']} folder?<br /> {$count['count']} file(s) will be moved to the Root folder.", 'Delete', "admin.php?a=downloads&s=deletefolder&f=$f&confirm=1", 0 );
}
if( !$this->is_valid_token() ) {
return $this->error( 'Invalid or expired security token. Please go back, reload the form, and try again.' );
}
if ( !$this->delete_fold($f) )
return $this->message( 'Delete Downloads Folder', 'Could not delete folder.' );
return $this->message( 'Delete Downloads Folder', 'The folder has been deleted.', 'Continue', 'admin.php' );
}
}
?>