使用 zTree 生成的文件树该怎么存放至数据库 ?

时间:2022-02-07 13:32:16
这是目前前端的显示结果,可供用户选择某些不处理的目录或文件

使用 zTree 生成的文件树该怎么存放至数据库 ?

使用一个隐藏栏位来存放这些 JSON 数据靠谱吗 ? 因为我发现数据量满大的 ..

使用 zTree 生成的文件树该怎么存放至数据库 ?

以下为其相关的源码:

myztree.js

jQuery(document).ready(function () {
// Start: 初始化 jQuery 外掛 - zTree 的設定
var setting = {
async: {
autoParam: ['path'],
dataType: 'json',
enable: true,
otherParam: {
action: 'ztree'
},
url: ajaxurl
},
callback: {
onCheck: zTreeOnCheck,
onClick: zTreeOnClick
},
check: {
autoCheckTrigger: true,
enable: true
},
view: {
dblClickExpand: false,
showLine: false
}
};

var zTree = jQuery.fn.zTree.init(jQuery('#excluded-files'), setting, null);
// End: 初始化 jQuery 外掛 - zTree 的設定

function zTreeOnCheck(event, treeId, treeNode) {
var basedir = treeNode.path;
var checked = treeNode.checked;
var listval = JSON.parse(jQuery('#excluded-list').val());
var in_list = false;
for (var i = 0; i < listval.length; i++) {
if (listval[i]['basedir'] == basedir) {
listval[i]['checked'] = checked;
                 in_list = true;
break;
}
}
        if (!in_list) {
         listval.push({"basedir": basedir, "checked": checked});
        }
        jQuery('#excluded-list').val(JSON.stringify(listval));
};

function zTreeOnClick(event, treeId, treeNode) {
zTree.expandNode(treeNode);
};
});


ztree.php

<?php
# 初始化 node 變數用於儲存所有檔案與資料夾的樹狀結構
$node = array();
# 檢查是否是第一次初始化輸出結構資訊
if ( empty( $_POST['path'] ) ) {
# 設定欲讀取資料夾為 WordPress 的上傳資料夾
$dir = sprintf( '%s/', array_pop( array_slice( wp_upload_dir(), 3, 1 ) ) );
}
# 使用者已選擇次級的資料夾
else {
# 解碼並設定已選擇的次級資料夾名稱
$dir = sprintf( '%s/', urldecode( $_POST['path'] ) );
}
# 讀取目前資料夾底下所有的資訊
$files = scandir( $dir );
# 採用自然排序法排序所有的名稱
natcasesort( $files );
# Start: 走訪本資料夾底下所有的資訊
foreach( $files as $file ) {
# 過濾無用的上層資料夾等資訊
if( $file != '.' && $file != '..' ) {
# 資料夾
if ( is_dir( $dir . $file ) ) {
# 設定本資料夾的資訊
$folder = array(
'iconSkin' => 'folder',
'isParent' => true,
'name'     => $file,
'path'     => $dir . $file
);
# 新增本資料夾至節點變數用以回傳給 zTree 處理
array_push( $node, $folder );
# 檔案
} else {
# 設定本檔案的資訊
$file = array(
'iconSkin' => sprintf( 'file_ico_docu %s', preg_replace( '/^.*\./', '', $file ) ),
'name'     => $file,
'path'     => $dir . $file
);
# 新增本檔案至節點變數用以回傳給 zTree 處理
array_push( $node, $file );
}
} else {
continue;
}
}
# End: 走訪本資料夾底下所有的資訊
# 回傳已編碼的節點資訊
echo json_encode( $node );
?>


ztree.html

<tr>
<th scope="row">
<label for="excluded-files">Exclusion: </label>
</th>
<td>
<!-- Start: 使用 jQuery - ztree 輸出欲排除上傳的檔案清單 -->
<div>
<ul class="ztree" id="excluded-files"></ul>
</div>
<!-- End: 使用 jQuery - ztree 輸出欲排除上傳的檔案清單 -->
</td>
</tr>


未完成的后端处理.php

<?php
function sanitize_values( $input ) {
# 檢查所欲過濾的設定值是否為一個陣列
if ( is_array( $input ) ) {
# 走訪所有的設定名稱與數值
foreach ( $input as $key => $value ) {
# 判斷設定名稱
switch ( $key ) {
# 排除上傳的檔案清單
case 'exclusion':
$list = array(
'folders' => array(),
'files'   => array()
);
$exclusions = json_decode( stripslashes( $input[$key] ), true );
if ( count( $exclusions ) > 0 ) {
foreach ( $exclusions as $exclusion ) {
switch ( is_dir ( $exclusion['basedir'] ) ) {
case true:
if ( $exclusion['checked'] )
array_push( $list['folders'], $exclusion['basedir'] );
break;
case false:
if ( $exclusion['checked'] )
array_push( $list['files'], $exclusion['basedir'] );
break;
default:
break;
}
}
}
$input[$key] = $list;
#exit( print_r( $list ) );
break;
}
}
# 回傳已過濾的設定值
return $input;
}
# 回傳錯誤
return false;
}
?>

10 个解决方案

#1


使用一个隐藏栏位来存放这些 JSON 数据靠谱吗 ? 因为我发现数据量满大的 ..


没关系.尽情使用

#2


引用 1 楼 phpnewnew 的回复:
使用一个隐藏栏位来存放这些 JSON 数据靠谱吗 ? 因为我发现数据量满大的 ..


没关系.尽情使用


我的确使用得很开心,但想请问 PhpNewnew 前辈 .. 该怎么去处理和储存这些数据 ?

谢谢您拨冗回覆我的困扰 :-)

#3


处理?将json 解成数组 想怎么处理就怎么处理呀
存储?如果需要的话可以写到数据库里。如果是临时的话可以直接保存到memcache
如果是要传递的话 直接post

....


引用 2 楼 chrisfoxylin 的回复:
引用 1 楼 phpnewnew 的回复:

使用一个隐藏栏位来存放这些 JSON 数据靠谱吗 ? 因为我发现数据量满大的 ..


没关系.尽情使用


我的确使用得很开心,但想请问 PhpNewnew 前辈 .. 该怎么去处理和储存这些数据 ?

谢谢您拨冗回覆我的困扰 :-)

#4


引用 3 楼 phpnewnew 的回复:
处理?将json 解成数组 想怎么处理就怎么处理呀
存储?如果需要的话可以写到数据库里。如果是临时的话可以直接保存到memcache
如果是要传递的话 直接post

....


引用 2 楼 chrisfoxylin 的回复:

引用 1 楼 phpnewnew 的回复:

使用一个隐藏栏位来存放这些 JSON 数据靠谱吗 ? 因为我发现数据量满大的 ..


没……


恩,谢谢您的回覆 :-)

我的意思是指,这些数据会储存到数据库的表中。

但我不知道该怎么去处理 "级" 的概念 ..

也就是可能父层全选、子层部分选择等勾选状况。

有一点像是权限树的架构 .. 但更复杂,因为目录可能是无穷级的。

我想实现的处理效果是,上图中所有的文件与目录在预设设置下会被上传。

但假如用户有勾选不想被上传的文件与目录等,就将之写进数据库。

待其他的后端脚本在运行上传的程序时,至数据库中读取这些排除清单并做出处理。

当然,若数据库写的进去了 .. 在 zTree 运行成功时也能连带先行查询再将目前用户所勾选的呈现出来。

#5


能说说看这个是什么应用场景吗?说清楚的话可能比较有针对性的探讨。

如果类似于p2p软件的共享 可能这些数据保存在客户端比较合适.例如cookie什么的,
不过cookie也有它的局限性,会给清理,保存内容有限 等等 不过4kb似乎也够了

这些文件目录是非固定的吧?

#6


数据库最简单的方式是
id title parentid

当然还有两中,可以搜索mysql tree 等等的关键字会找到。

前端用ajax吧。

#7


引用 5 楼 phpnewnew 的回复:
能说说看这个是什么应用场景吗?说清楚的话可能比较有针对性的探讨。

如果类似于p2p软件的共享 可能这些数据保存在客户端比较合适.例如cookie什么的,
不过cookie也有它的局限性,会给清理,保存内容有限 等等 不过4kb似乎也够了

这些文件目录是非固定的吧?


是的,非固定的目录与文件。

有一点像是杀毒软件的架构,它一定会有一个排除扫瞄的清单。

当你没有去更改这些设置时,杀毒默认会扫瞄整个硬盘上的文件,对吧 ?

但假如我从这排除清单中新增了几个文件或目录,那自然在杀毒的扫瞄程序中就会被略过了。

ok, 场景回到目前的状况 ..

前端显示目前目录和文件树的设计目前是可以使用的,后端 PHP 也可以接收到这些来自前端的数据。

但我不知道该怎么去判断某一个文件或目录,他子父层的关系 ?

可能是仅有 2012/02/Chris-150x150.jpg 的文件和 2012/03 的目录被选取;

也可能是仅有 2012 整个目录和 icon/asp.asp 与 jar.jar 被选取等多种状况。

目前正在看一个国外插件的范例,希望可以和大家多多讨论,谢谢你们的热心。

class-file-list.php

<?php
/**
 * A class with functions the perform a backup of WordPress
 *
 * @copyright Copyright (C) 2011 Michael De Wildt. All rights reserved.
 * @author Michael De Wildt (http://www.mikeyd.com.au/)
 * @license This program is free software; you can redistribute it and/or modify
 *          it under the terms of the GNU General Public License as published by
 *          the Free Software Foundation; either version 2 of the License, or
 *          (at your option) any later version.
 *
 *          This program is distributed in the hope that it will be useful,
 *          but WITHOUT ANY WARRANTY; without even the implied warranty of
 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *          GNU General Public License for more details.
 *
 *          You should have received a copy of the GNU General Public License
 *          along with this program; if not, write to the Free Software
 *          Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
 */
include_once( 'class-wp-backup.php' );
class File_List {

const EXCLUDED = 0;
const INCLUDED = 1;
const PARTIAL = 2;

/**
 * A list of directories to mark as partial
 * @var null
 */
private $partial_directories = array();

/**
 * A list of files that are not allowed to be backed up
 * @var null
 */
private $excluded_files = array();

/**
 * These files cannot be uploaded to Dropbox
 * @var array
 */
private static $ignored_files = array( '.DS_Store', 'Thumbs.db', 'desktop.ini' );

/**
 * Construct the file list
 * @param $wpdb
 */
public function __construct( $wpdb = null ) {
if ( !$wpdb ) global $wpdb;

$this->database = $wpdb;

$file_list = get_option( 'backup-to-dropbox-file-list' );
if ( $file_list === false ) {
$this->partial_directories = array();
$this->excluded_files = array();
add_option( 'backup-to-dropbox-file-list', array( $this->partial_directories, $this->excluded_files ), null, 'no' );
} else {
list( $this->partial_directories, $this->excluded_files ) = $file_list;
}
}

/**
 * Return the state of a file in the list the SQL dump is always included
 * @param  $path
 * @return bool
 */
public function get_file_state( $path ) {
$parent_path = dirname( $path ) . '/';
if ( $path == dirname( ABSPATH ) . '/' ) {
return self::PARTIAL;
} else if ( strstr( $path, DB_NAME . '-backup.sql' ) ) {
return self::INCLUDED;
} else if ( in_array( $path, $this->excluded_files ) ) {
return self::EXCLUDED;
} else if ( in_array( $path, $this->partial_directories ) ) {
$parent_state = $this->get_file_state( $parent_path );
if ( $parent_state == self::INCLUDED && $parent_path != ABSPATH ) {
$this->remove_from_partial( $path );
$this->remove_from_excluded( $path );
return self::INCLUDED;
}
return self::PARTIAL;
}

$state = $this->get_file_state( $parent_path );
if ( $state == self::PARTIAL ) {
$this->remove_from_partial( $path );
$this->remove_from_excluded( $path );
return self::INCLUDED;
}
return $state;
}

/**
 * @param $full_path string
 * @return string
 */
function get_check_box_class( $full_path ) {
$state = $this->get_file_state( $full_path );
switch ( $state ) {
case self::EXCLUDED:
$class = 'checked';
break;
case self::PARTIAL:
$class = 'partial';
break;
default: //INCLUDED so do not check
$class = '';
break;
}
return $class;
}

/**
 * Adds a file to the excluded list if it does not already exist
 * @param $file
 * @return void
 */
private function add_to_excluded( $file ) {
if ( !in_array( $file, $this->excluded_files ) ) {
$this->excluded_files[] = $file;
}
}

/**
 * Adds a file to the partial list if it does not already exist
 * @param $file
 * @return void
 */
private function add_to_partial( $file ) {
if ( !in_array( $file, $this->partial_directories ) ) {
$this->partial_directories[] = $file;
}
}

/**
 * Accepts a JSON encoded list of files and directories and adds their states to the appropriate lists
 * @param  $json_list
 * @return void
 */
public function set_file_list( $json_list ) {
$new_list = json_decode( stripslashes( $json_list ), true );
foreach ( $new_list as $fl ) {
list ( $file, $state ) = $fl;
if ( $state == self::PARTIAL ) {
$this->add_to_partial( $file );
$this->remove_from_excluded( $file );
} else if ( $state == self::EXCLUDED) {
$this->add_to_excluded( $file );
$this->remove_from_partial( $file );
} else {
$this->remove_from_excluded( $file );
$this->remove_from_partial( $file );
}
}
}

/**
 * Removes a file from the excluded list if it exists
 * @param $file
 * @return void
 */
private function remove_from_excluded( $file ) {
if ( in_array( $file, $this->excluded_files ) ) {
$i = array_search( $file, $this->excluded_files );
unset( $this->excluded_files[$i] );
}
}

/**
 * Removes a file from the partial list if it exists
 * @param $file
 * @return void
 */
private function remove_from_partial( $file ) {
if ( in_array( $file, $this->partial_directories ) ) {
$i = array_search( $file, $this->partial_directories );
unset( $this->partial_directories[$i] );
}
}

/**
 * Saves the file list
 * @return void
 */
public function save() {
update_option( 'backup-to-dropbox-file-list', array( $this->partial_directories, $this->excluded_files ) );
}

/**
 * @param $dir
 * @return int
 */
private function get_directory_state( $dir ) {
$files = scandir( $dir );
natcasesort( $files );
foreach ( $files as $file ) {
$state = $this->get_file_state( $file );
if ( $state == self::PARTIAL || $state == self::EXCLUDED ) {
return self::PARTIAL;
}
}
return self::INCLUDED;
}

/**
 * Some files cannot be uploaded to Dropbox so check them here
 * @static
 * @param $file
 * @return bool
 */
public static function in_ignore_list( $file ) {
return in_array( $file, self::$ignored_files );
}
}

#8


引用 7 楼 chrisfoxylin 的回复:
引用 5 楼 phpnewnew 的回复:

能说说看这个是什么应用场景吗?说清楚的话可能比较有针对性的探讨。

如果类似于p2p软件的共享 可能这些数据保存在客户端比较合适.例如cookie什么的,
不过cookie也有它的局限性,会给清理,保存内容有限 等等 不过4kb似乎也够了

这些文件目录是非固定的吧?


是的,非固定的目录与文件。

有一点像是杀毒软件的架构……


jquert-filetree.js

// jQuery File Tree Plugin
//
// Version 1.01
//
// Cory S.N. LaViska
// A Beautiful Site (http://abeautifulsite.net/)
// 24 March 2008
//
// Visit http://abeautifulsite.net/notebook.php?article=58 for more information
//
// Usage: $('.fileTreeDemo').fileTree( options, callback )
//
// Options:  root           - root folder to display; default = /
//           script         - location of the serverside AJAX file to use; default = jqueryFileTree.php
//           folderEvent    - event to trigger expand/collapse; default = click
//           expandSpeed    - default = 500 (ms); use -1 for no animation
//           collapseSpeed  - default = 500 (ms); use -1 for no animation
//           expandEasing   - easing function to use on expand (optional)
//           collapseEasing - easing function to use on collapse (optional)
//           multiFolder    - whether or not to limit the browser to one subfolder at a time
//           loadMessage    - Message to display while initial tree loads (can be HTML)
//
// History:
//
// 1.01 - updated to work with foreign characters in directory/file names (12 April 2008)
// 1.00 - released (24 March 2008)
//
// TERMS OF USE
//
// This plugin is dual-licensed under the GNU General Public License and the MIT License and
// is copyright 2008 A Beautiful Site, LLC.
//
if(jQuery) (function($){

$.extend($.fn, {
fileTree: function(o) {
var EXCLUDED = 0;
        var INCLUDED = 1;
        var PARTIAL = 2;

// Defaults
if( !o ) var o = {};
if( o.root == undefined ) o.root = '/';
if( o.script == undefined ) o.script = 'jqueryFileTree.php';
if( o.folderEvent == undefined ) o.folderEvent = 'click';
if( o.expandSpeed == undefined ) o.expandSpeed= 500;
if( o.collapseSpeed == undefined ) o.collapseSpeed= 500;
if( o.expandEasing == undefined ) o.expandEasing = null;
if( o.collapseEasing == undefined ) o.collapseEasing = null;
if( o.multiFolder == undefined ) o.multiFolder = true;
if( o.loadMessage == undefined ) o.loadMessage = 'Loading...';

$(this).each( function() {

function showTree(c, t) {
$(c).addClass('wait');
$(".jqueryFileTree.start").remove();
$.post(o.script, { action: 'file_tree', dir: t }, function(data) {
$(c).find('.start').html('');
$(c).removeClass('wait').append(data);
if( o.root == t ) $(c).find('UL:hidden').show(); else $(c).find('UL:hidden').slideDown({ duration: o.expandSpeed, easing: o.expandEasing });

//Check that the list of files that we got from the server have not already
//been included or excluded in the UI.
$('.checkbox').each(function () {
                            var dir = escape(dirname($(this).attr('rel')));
                            if (dir == t) {
                                var state = get_include_state($(this).attr('rel'));
                                if (state !== false) {
                                    set_checkbox_state(this, state);
                                }
                            }
});
bindTree(c);
});
}

function bindTree(t) {
$(t).find('LI A.tree').bind(o.folderEvent, function() {
if( $(this).parent().hasClass('directory') ) {
if( $(this).parent().hasClass('collapsed') ) {
// Expand
if( !o.multiFolder ) {
$(this).parent().parent().find('UL').slideUp({ duration: o.collapseSpeed, easing: o.collapseEasing });
$(this).parent().parent().find('LI.directory').removeClass('expanded').addClass('collapsed');
}
$(this).parent().find('UL').remove(); // cleanup
showTree( $(this).parent(), escape($(this).attr('rel').match( /.*\// )) );
$(this).parent().removeClass('collapsed').addClass('expanded');
} else {
// Collapse
$(this).parent().find('UL').slideUp({ duration: o.collapseSpeed, easing: o.collapseEasing });
$(this).parent().removeClass('expanded').addClass('collapsed');
}
} else {
var element = $(this).parent().find('.checkbox');
if (element.length) {
checkbox_click(element);
}
}
return false;
});

//Bind our check box clicks
$(t).find('ul').find('.checkbox').bind('click', function() {
checkbox_click(this);
});

// Prevent A from triggering the # on non-click events
if( o.folderEvent.toLowerCase != 'click' ) $(t).find('LI A').bind('click', function() { return false; });
}
// Loading message
$(this).html('<ul class="jqueryFileTree start"><li class="wait">' + o.loadMessage + '<li></ul>');
// Get the initial file list
showTree( $(this), escape(o.root) );
});

/**
 * Updates the tri state check box based on the state hidden element passed
 * @param check_box
 */
function set_checkbox_state(check_box, new_state) {
new_state = parseInt(new_state);
$(check_box).removeClass('checked');
$(check_box).removeClass('partial');
switch(new_state) {
case EXCLUDED:
$(check_box).addClass('checked');
break;
case PARTIAL:
$(check_box).addClass('partial');
break;
default:
break; //INCLUDED - Do nothing
}
}

/**
 * Toggles the hidden list input with what has changed
 * @param element
 */
function set_include_state(element) {
                var file = $(element).attr('rel');
                var state = get_checkbox_state(element);
var file_tree_list = JSON.parse($('#file_tree_list').val());
var in_list = false;
                for (var i = 0; i < file_tree_list.length; i++) {
if (file_tree_list[i][0] == file) {
file_tree_list[i][1] = state;
                        in_list = true;
break;
}
}
                if (!in_list) {
                    file_tree_list.push([file, state])
                }
$('#file_tree_list').val(JSON.stringify(file_tree_list));
}

/**
 * Get the file state from the local list
 * @param file
 * @return int
 */
function get_include_state(file) {
var file_list = JSON.parse($('#file_tree_list').val());
for (var i = 0; i < file_list.length; i++) {
if (file_list[i][0] == file) {
return file_list[i][1];
}
}
return false;
}

/**
 * Just like PHP's dirname
 * @param path
 */
function dirname(path) {
return path.replace(/\/$/, '').replace(/\/[^\/]*$/, '/');
}

/**
 * Toggles the directory check box to ON, OFF or PARTIAL depending on the state of all its children.
 * @param clicked
 */
function toggle_directory_check(clicked) {
//Also check its directory if they are all not checked
var checked_count = 0, total = 0;
var clicked_parent_dir = dirname($(clicked).attr('rel'));
$('.checkbox').each(function () {
if (clicked_parent_dir != o.root) {
var parent_dir = dirname($(this).attr('rel'));
if (parent_dir == clicked_parent_dir) {
var state = get_checkbox_state(this);
if (state == PARTIAL || state == EXCLUDED) {
checked_count++;
}
total++;
}
}
});

//Now that we know that the state of all the directories children we can update the parent dir accordingly
$('.checkbox').each(function () {
if ($(this).attr('rel') == clicked_parent_dir) {
if (checked_count == total) {
set_checkbox_state(this, EXCLUDED);
  } else if (checked_count == 0) {
set_checkbox_state(this, INCLUDED);
} else {
set_checkbox_state(this, PARTIAL);
}
                        set_include_state(this);
toggle_directory_check(this);
}
});
}

/**
 * Return the current state of a clicked check box
 * @param clicked
 */
function get_checkbox_state(clicked) {
var state = INCLUDED;
if ($(clicked).hasClass('partial')) {
state = PARTIAL;
} else if ($(clicked).hasClass('checked')) {
state = EXCLUDED;
}
return state;
}

/**
 * Set all the children of a directory to a state
 * @param parent
 */
function set_directory_children(parent, state) {
//If this is an expanded directory recursively update all its children
if ($(parent).parent().hasClass('expanded') && $(parent).hasClass('directory')) {
$('.checkbox').each(function () {
if (dirname($(this).attr('rel')) == $(parent).attr('rel')) {
set_checkbox_state(this, state);
set_include_state(this);
set_directory_children(this, state);
}
});
}
}

/**
 * The on click function for a file check box. If the user clicks on a directory then all its open children
 * need to be updated accordingly.
 * @param clicked
 */
function checkbox_click(clicked) {
var state = get_checkbox_state(clicked) == EXCLUDED ? INCLUDED : EXCLUDED;

set_checkbox_state(clicked, state);
set_include_state(clicked);

set_directory_children(clicked, state);
                toggle_directory_check(clicked);
}
}
});

})(jQuery);

#9


感觉LZ把简单的问题复杂化了

#10


引用 9 楼 xuzuning 的回复:
感觉LZ把简单的问题复杂化了


哈哈,对啊对啊 .. 请你给我当头棒喝一下 :-D

#1


使用一个隐藏栏位来存放这些 JSON 数据靠谱吗 ? 因为我发现数据量满大的 ..


没关系.尽情使用

#2


引用 1 楼 phpnewnew 的回复:
使用一个隐藏栏位来存放这些 JSON 数据靠谱吗 ? 因为我发现数据量满大的 ..


没关系.尽情使用


我的确使用得很开心,但想请问 PhpNewnew 前辈 .. 该怎么去处理和储存这些数据 ?

谢谢您拨冗回覆我的困扰 :-)

#3


处理?将json 解成数组 想怎么处理就怎么处理呀
存储?如果需要的话可以写到数据库里。如果是临时的话可以直接保存到memcache
如果是要传递的话 直接post

....


引用 2 楼 chrisfoxylin 的回复:
引用 1 楼 phpnewnew 的回复:

使用一个隐藏栏位来存放这些 JSON 数据靠谱吗 ? 因为我发现数据量满大的 ..


没关系.尽情使用


我的确使用得很开心,但想请问 PhpNewnew 前辈 .. 该怎么去处理和储存这些数据 ?

谢谢您拨冗回覆我的困扰 :-)

#4


引用 3 楼 phpnewnew 的回复:
处理?将json 解成数组 想怎么处理就怎么处理呀
存储?如果需要的话可以写到数据库里。如果是临时的话可以直接保存到memcache
如果是要传递的话 直接post

....


引用 2 楼 chrisfoxylin 的回复:

引用 1 楼 phpnewnew 的回复:

使用一个隐藏栏位来存放这些 JSON 数据靠谱吗 ? 因为我发现数据量满大的 ..


没……


恩,谢谢您的回覆 :-)

我的意思是指,这些数据会储存到数据库的表中。

但我不知道该怎么去处理 "级" 的概念 ..

也就是可能父层全选、子层部分选择等勾选状况。

有一点像是权限树的架构 .. 但更复杂,因为目录可能是无穷级的。

我想实现的处理效果是,上图中所有的文件与目录在预设设置下会被上传。

但假如用户有勾选不想被上传的文件与目录等,就将之写进数据库。

待其他的后端脚本在运行上传的程序时,至数据库中读取这些排除清单并做出处理。

当然,若数据库写的进去了 .. 在 zTree 运行成功时也能连带先行查询再将目前用户所勾选的呈现出来。

#5


能说说看这个是什么应用场景吗?说清楚的话可能比较有针对性的探讨。

如果类似于p2p软件的共享 可能这些数据保存在客户端比较合适.例如cookie什么的,
不过cookie也有它的局限性,会给清理,保存内容有限 等等 不过4kb似乎也够了

这些文件目录是非固定的吧?

#6


数据库最简单的方式是
id title parentid

当然还有两中,可以搜索mysql tree 等等的关键字会找到。

前端用ajax吧。

#7


引用 5 楼 phpnewnew 的回复:
能说说看这个是什么应用场景吗?说清楚的话可能比较有针对性的探讨。

如果类似于p2p软件的共享 可能这些数据保存在客户端比较合适.例如cookie什么的,
不过cookie也有它的局限性,会给清理,保存内容有限 等等 不过4kb似乎也够了

这些文件目录是非固定的吧?


是的,非固定的目录与文件。

有一点像是杀毒软件的架构,它一定会有一个排除扫瞄的清单。

当你没有去更改这些设置时,杀毒默认会扫瞄整个硬盘上的文件,对吧 ?

但假如我从这排除清单中新增了几个文件或目录,那自然在杀毒的扫瞄程序中就会被略过了。

ok, 场景回到目前的状况 ..

前端显示目前目录和文件树的设计目前是可以使用的,后端 PHP 也可以接收到这些来自前端的数据。

但我不知道该怎么去判断某一个文件或目录,他子父层的关系 ?

可能是仅有 2012/02/Chris-150x150.jpg 的文件和 2012/03 的目录被选取;

也可能是仅有 2012 整个目录和 icon/asp.asp 与 jar.jar 被选取等多种状况。

目前正在看一个国外插件的范例,希望可以和大家多多讨论,谢谢你们的热心。

class-file-list.php

<?php
/**
 * A class with functions the perform a backup of WordPress
 *
 * @copyright Copyright (C) 2011 Michael De Wildt. All rights reserved.
 * @author Michael De Wildt (http://www.mikeyd.com.au/)
 * @license This program is free software; you can redistribute it and/or modify
 *          it under the terms of the GNU General Public License as published by
 *          the Free Software Foundation; either version 2 of the License, or
 *          (at your option) any later version.
 *
 *          This program is distributed in the hope that it will be useful,
 *          but WITHOUT ANY WARRANTY; without even the implied warranty of
 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *          GNU General Public License for more details.
 *
 *          You should have received a copy of the GNU General Public License
 *          along with this program; if not, write to the Free Software
 *          Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
 */
include_once( 'class-wp-backup.php' );
class File_List {

const EXCLUDED = 0;
const INCLUDED = 1;
const PARTIAL = 2;

/**
 * A list of directories to mark as partial
 * @var null
 */
private $partial_directories = array();

/**
 * A list of files that are not allowed to be backed up
 * @var null
 */
private $excluded_files = array();

/**
 * These files cannot be uploaded to Dropbox
 * @var array
 */
private static $ignored_files = array( '.DS_Store', 'Thumbs.db', 'desktop.ini' );

/**
 * Construct the file list
 * @param $wpdb
 */
public function __construct( $wpdb = null ) {
if ( !$wpdb ) global $wpdb;

$this->database = $wpdb;

$file_list = get_option( 'backup-to-dropbox-file-list' );
if ( $file_list === false ) {
$this->partial_directories = array();
$this->excluded_files = array();
add_option( 'backup-to-dropbox-file-list', array( $this->partial_directories, $this->excluded_files ), null, 'no' );
} else {
list( $this->partial_directories, $this->excluded_files ) = $file_list;
}
}

/**
 * Return the state of a file in the list the SQL dump is always included
 * @param  $path
 * @return bool
 */
public function get_file_state( $path ) {
$parent_path = dirname( $path ) . '/';
if ( $path == dirname( ABSPATH ) . '/' ) {
return self::PARTIAL;
} else if ( strstr( $path, DB_NAME . '-backup.sql' ) ) {
return self::INCLUDED;
} else if ( in_array( $path, $this->excluded_files ) ) {
return self::EXCLUDED;
} else if ( in_array( $path, $this->partial_directories ) ) {
$parent_state = $this->get_file_state( $parent_path );
if ( $parent_state == self::INCLUDED && $parent_path != ABSPATH ) {
$this->remove_from_partial( $path );
$this->remove_from_excluded( $path );
return self::INCLUDED;
}
return self::PARTIAL;
}

$state = $this->get_file_state( $parent_path );
if ( $state == self::PARTIAL ) {
$this->remove_from_partial( $path );
$this->remove_from_excluded( $path );
return self::INCLUDED;
}
return $state;
}

/**
 * @param $full_path string
 * @return string
 */
function get_check_box_class( $full_path ) {
$state = $this->get_file_state( $full_path );
switch ( $state ) {
case self::EXCLUDED:
$class = 'checked';
break;
case self::PARTIAL:
$class = 'partial';
break;
default: //INCLUDED so do not check
$class = '';
break;
}
return $class;
}

/**
 * Adds a file to the excluded list if it does not already exist
 * @param $file
 * @return void
 */
private function add_to_excluded( $file ) {
if ( !in_array( $file, $this->excluded_files ) ) {
$this->excluded_files[] = $file;
}
}

/**
 * Adds a file to the partial list if it does not already exist
 * @param $file
 * @return void
 */
private function add_to_partial( $file ) {
if ( !in_array( $file, $this->partial_directories ) ) {
$this->partial_directories[] = $file;
}
}

/**
 * Accepts a JSON encoded list of files and directories and adds their states to the appropriate lists
 * @param  $json_list
 * @return void
 */
public function set_file_list( $json_list ) {
$new_list = json_decode( stripslashes( $json_list ), true );
foreach ( $new_list as $fl ) {
list ( $file, $state ) = $fl;
if ( $state == self::PARTIAL ) {
$this->add_to_partial( $file );
$this->remove_from_excluded( $file );
} else if ( $state == self::EXCLUDED) {
$this->add_to_excluded( $file );
$this->remove_from_partial( $file );
} else {
$this->remove_from_excluded( $file );
$this->remove_from_partial( $file );
}
}
}

/**
 * Removes a file from the excluded list if it exists
 * @param $file
 * @return void
 */
private function remove_from_excluded( $file ) {
if ( in_array( $file, $this->excluded_files ) ) {
$i = array_search( $file, $this->excluded_files );
unset( $this->excluded_files[$i] );
}
}

/**
 * Removes a file from the partial list if it exists
 * @param $file
 * @return void
 */
private function remove_from_partial( $file ) {
if ( in_array( $file, $this->partial_directories ) ) {
$i = array_search( $file, $this->partial_directories );
unset( $this->partial_directories[$i] );
}
}

/**
 * Saves the file list
 * @return void
 */
public function save() {
update_option( 'backup-to-dropbox-file-list', array( $this->partial_directories, $this->excluded_files ) );
}

/**
 * @param $dir
 * @return int
 */
private function get_directory_state( $dir ) {
$files = scandir( $dir );
natcasesort( $files );
foreach ( $files as $file ) {
$state = $this->get_file_state( $file );
if ( $state == self::PARTIAL || $state == self::EXCLUDED ) {
return self::PARTIAL;
}
}
return self::INCLUDED;
}

/**
 * Some files cannot be uploaded to Dropbox so check them here
 * @static
 * @param $file
 * @return bool
 */
public static function in_ignore_list( $file ) {
return in_array( $file, self::$ignored_files );
}
}

#8


引用 7 楼 chrisfoxylin 的回复:
引用 5 楼 phpnewnew 的回复:

能说说看这个是什么应用场景吗?说清楚的话可能比较有针对性的探讨。

如果类似于p2p软件的共享 可能这些数据保存在客户端比较合适.例如cookie什么的,
不过cookie也有它的局限性,会给清理,保存内容有限 等等 不过4kb似乎也够了

这些文件目录是非固定的吧?


是的,非固定的目录与文件。

有一点像是杀毒软件的架构……


jquert-filetree.js

// jQuery File Tree Plugin
//
// Version 1.01
//
// Cory S.N. LaViska
// A Beautiful Site (http://abeautifulsite.net/)
// 24 March 2008
//
// Visit http://abeautifulsite.net/notebook.php?article=58 for more information
//
// Usage: $('.fileTreeDemo').fileTree( options, callback )
//
// Options:  root           - root folder to display; default = /
//           script         - location of the serverside AJAX file to use; default = jqueryFileTree.php
//           folderEvent    - event to trigger expand/collapse; default = click
//           expandSpeed    - default = 500 (ms); use -1 for no animation
//           collapseSpeed  - default = 500 (ms); use -1 for no animation
//           expandEasing   - easing function to use on expand (optional)
//           collapseEasing - easing function to use on collapse (optional)
//           multiFolder    - whether or not to limit the browser to one subfolder at a time
//           loadMessage    - Message to display while initial tree loads (can be HTML)
//
// History:
//
// 1.01 - updated to work with foreign characters in directory/file names (12 April 2008)
// 1.00 - released (24 March 2008)
//
// TERMS OF USE
//
// This plugin is dual-licensed under the GNU General Public License and the MIT License and
// is copyright 2008 A Beautiful Site, LLC.
//
if(jQuery) (function($){

$.extend($.fn, {
fileTree: function(o) {
var EXCLUDED = 0;
        var INCLUDED = 1;
        var PARTIAL = 2;

// Defaults
if( !o ) var o = {};
if( o.root == undefined ) o.root = '/';
if( o.script == undefined ) o.script = 'jqueryFileTree.php';
if( o.folderEvent == undefined ) o.folderEvent = 'click';
if( o.expandSpeed == undefined ) o.expandSpeed= 500;
if( o.collapseSpeed == undefined ) o.collapseSpeed= 500;
if( o.expandEasing == undefined ) o.expandEasing = null;
if( o.collapseEasing == undefined ) o.collapseEasing = null;
if( o.multiFolder == undefined ) o.multiFolder = true;
if( o.loadMessage == undefined ) o.loadMessage = 'Loading...';

$(this).each( function() {

function showTree(c, t) {
$(c).addClass('wait');
$(".jqueryFileTree.start").remove();
$.post(o.script, { action: 'file_tree', dir: t }, function(data) {
$(c).find('.start').html('');
$(c).removeClass('wait').append(data);
if( o.root == t ) $(c).find('UL:hidden').show(); else $(c).find('UL:hidden').slideDown({ duration: o.expandSpeed, easing: o.expandEasing });

//Check that the list of files that we got from the server have not already
//been included or excluded in the UI.
$('.checkbox').each(function () {
                            var dir = escape(dirname($(this).attr('rel')));
                            if (dir == t) {
                                var state = get_include_state($(this).attr('rel'));
                                if (state !== false) {
                                    set_checkbox_state(this, state);
                                }
                            }
});
bindTree(c);
});
}

function bindTree(t) {
$(t).find('LI A.tree').bind(o.folderEvent, function() {
if( $(this).parent().hasClass('directory') ) {
if( $(this).parent().hasClass('collapsed') ) {
// Expand
if( !o.multiFolder ) {
$(this).parent().parent().find('UL').slideUp({ duration: o.collapseSpeed, easing: o.collapseEasing });
$(this).parent().parent().find('LI.directory').removeClass('expanded').addClass('collapsed');
}
$(this).parent().find('UL').remove(); // cleanup
showTree( $(this).parent(), escape($(this).attr('rel').match( /.*\// )) );
$(this).parent().removeClass('collapsed').addClass('expanded');
} else {
// Collapse
$(this).parent().find('UL').slideUp({ duration: o.collapseSpeed, easing: o.collapseEasing });
$(this).parent().removeClass('expanded').addClass('collapsed');
}
} else {
var element = $(this).parent().find('.checkbox');
if (element.length) {
checkbox_click(element);
}
}
return false;
});

//Bind our check box clicks
$(t).find('ul').find('.checkbox').bind('click', function() {
checkbox_click(this);
});

// Prevent A from triggering the # on non-click events
if( o.folderEvent.toLowerCase != 'click' ) $(t).find('LI A').bind('click', function() { return false; });
}
// Loading message
$(this).html('<ul class="jqueryFileTree start"><li class="wait">' + o.loadMessage + '<li></ul>');
// Get the initial file list
showTree( $(this), escape(o.root) );
});

/**
 * Updates the tri state check box based on the state hidden element passed
 * @param check_box
 */
function set_checkbox_state(check_box, new_state) {
new_state = parseInt(new_state);
$(check_box).removeClass('checked');
$(check_box).removeClass('partial');
switch(new_state) {
case EXCLUDED:
$(check_box).addClass('checked');
break;
case PARTIAL:
$(check_box).addClass('partial');
break;
default:
break; //INCLUDED - Do nothing
}
}

/**
 * Toggles the hidden list input with what has changed
 * @param element
 */
function set_include_state(element) {
                var file = $(element).attr('rel');
                var state = get_checkbox_state(element);
var file_tree_list = JSON.parse($('#file_tree_list').val());
var in_list = false;
                for (var i = 0; i < file_tree_list.length; i++) {
if (file_tree_list[i][0] == file) {
file_tree_list[i][1] = state;
                        in_list = true;
break;
}
}
                if (!in_list) {
                    file_tree_list.push([file, state])
                }
$('#file_tree_list').val(JSON.stringify(file_tree_list));
}

/**
 * Get the file state from the local list
 * @param file
 * @return int
 */
function get_include_state(file) {
var file_list = JSON.parse($('#file_tree_list').val());
for (var i = 0; i < file_list.length; i++) {
if (file_list[i][0] == file) {
return file_list[i][1];
}
}
return false;
}

/**
 * Just like PHP's dirname
 * @param path
 */
function dirname(path) {
return path.replace(/\/$/, '').replace(/\/[^\/]*$/, '/');
}

/**
 * Toggles the directory check box to ON, OFF or PARTIAL depending on the state of all its children.
 * @param clicked
 */
function toggle_directory_check(clicked) {
//Also check its directory if they are all not checked
var checked_count = 0, total = 0;
var clicked_parent_dir = dirname($(clicked).attr('rel'));
$('.checkbox').each(function () {
if (clicked_parent_dir != o.root) {
var parent_dir = dirname($(this).attr('rel'));
if (parent_dir == clicked_parent_dir) {
var state = get_checkbox_state(this);
if (state == PARTIAL || state == EXCLUDED) {
checked_count++;
}
total++;
}
}
});

//Now that we know that the state of all the directories children we can update the parent dir accordingly
$('.checkbox').each(function () {
if ($(this).attr('rel') == clicked_parent_dir) {
if (checked_count == total) {
set_checkbox_state(this, EXCLUDED);
  } else if (checked_count == 0) {
set_checkbox_state(this, INCLUDED);
} else {
set_checkbox_state(this, PARTIAL);
}
                        set_include_state(this);
toggle_directory_check(this);
}
});
}

/**
 * Return the current state of a clicked check box
 * @param clicked
 */
function get_checkbox_state(clicked) {
var state = INCLUDED;
if ($(clicked).hasClass('partial')) {
state = PARTIAL;
} else if ($(clicked).hasClass('checked')) {
state = EXCLUDED;
}
return state;
}

/**
 * Set all the children of a directory to a state
 * @param parent
 */
function set_directory_children(parent, state) {
//If this is an expanded directory recursively update all its children
if ($(parent).parent().hasClass('expanded') && $(parent).hasClass('directory')) {
$('.checkbox').each(function () {
if (dirname($(this).attr('rel')) == $(parent).attr('rel')) {
set_checkbox_state(this, state);
set_include_state(this);
set_directory_children(this, state);
}
});
}
}

/**
 * The on click function for a file check box. If the user clicks on a directory then all its open children
 * need to be updated accordingly.
 * @param clicked
 */
function checkbox_click(clicked) {
var state = get_checkbox_state(clicked) == EXCLUDED ? INCLUDED : EXCLUDED;

set_checkbox_state(clicked, state);
set_include_state(clicked);

set_directory_children(clicked, state);
                toggle_directory_check(clicked);
}
}
});

})(jQuery);

#9


感觉LZ把简单的问题复杂化了

#10


引用 9 楼 xuzuning 的回复:
感觉LZ把简单的问题复杂化了


哈哈,对啊对啊 .. 请你给我当头棒喝一下 :-D