一个多用户的系统,上传图像文件等,希望不同用户的图像上传到它专有的目录里。我最初查到在PHP版的FCKEditor是通过设 置$Config('UserFilesPath')来实现,但Rails版的FCKEditor没有此项设置(搜索UserFilesPath关键字后 做出此判断)。接着,我查看了FCKEditor关键的fckeditor_controller.rb的源代码,似乎它并不支持此项设置。再看 javaeye是怎么用FCKEditor的,发现它放弃了FCKEditor的上传功能。google了半天,除了那些转来转去的相同内容的帖子之外 (搞不懂有了google之后,怎么还会有人费劲去转帖别人的文章),一点营养也没有。在JavaEye发了个求助帖,没人理 :-( 。 传说中高手云集的JavaEye,其Rails版块真是冷清,给人阴飕飕的感觉。没办法,自己改源代码吧。
1.修改fckeditor_controller.rb,把它那几个private方法修改如下:
private
def current_directory_path
base_dir
=
"
#{RAILS_ROOT}/public
"
#TODO 在创建用户时,就建立好目录。这时可以去掉这部份代码,提高运行效率。
(
"
#{params[:uploaded]||UPLOADED}/#{params[:Type]}
"
).split(
'
/
'
).each
do
|
s
|
next
if
s
==
''
base_dir
+=
'
/
'
+
s
Dir.mkdir(base_dir,
0775
) unless File.exists
?
(base_dir)
end
check_path(
"
#{base_dir}#{params[:CurrentFolder]}
"
)
end
def upload_directory_path
uploaded
=
@request.relative_url_root.to_s
+
"
#{params[:uploaded]||UPLOADED}/#{params[:Type]}
"
"
#{uploaded}#{params[:CurrentFolder]}
"
end
def check_file(file)
# check that the file is a tempfile object
unless
"
#{file.class}
"
==
"
Tempfile
"
||
"
#{file.class}
"
==
"
StringIO
"
@errorNumber
=
403
throw
Exception.
new
end
file
end
def check_path(path)
exp_path
=
File.expand_path path
if
exp_path
!~
%
r[
^
#{File.expand_path(RAILS_ROOT)}
/
public
#{params[:uploaded]
||
UPLOADED}]
@errorNumber
=
403
throw
Exception.
new
end
path
end
另外,它前面的常量UPLOADED_ROOT也没用了,可以删掉。
2. 在上面的代码中params[:uploaded] 是关键,它就是我们动态定义的上传目录。该值来自于FCKEditor的一些html页面,它是通过get参数传入的。修改browser.html文件 (如下粗体部份),在它的url请求中把我们定义目录加入到get参数列中,这样它就可以传到fckeditor_controller.rb里了。
var sServerPath
=
GetUrlParam(
'
ServerPath
'
) ;
if
( sServerPath.length
>
0
)
oConnector.ConnectorUrl
+=
'
ServerPath=
'
+
escape( sServerPath )
+
'
&
'
;
var sUploaded
= GetUrlParam( 'uploaded' ) ;
if ( sUploaded.length > 0 )
oConnector.ConnectorUrl += 'uploaded=' + escape( sUploaded ) + '&'
;
oConnector.ResourceType
=
GetUrlParam(
'
Type
'
) ;
oConnector.ShowAllTypes
=
( oConnector.ResourceType.length
==
0
) ;
3. 上面的GetUrlParam( 'uploaded' ) 的值来自于fckcustom.js。修改fckcustom.js(如下粗体部份),把uploaded加入到get参数列中。
//
CHANGE FOR APPS HOSTED IN SUBDIRECTORY
FCKRelativePath
=
''
;
//
DON
'
T CHANGE THESE
FCKConfig.LinkBrowserURL
=
FCKConfig.BasePath
+
'
filemanager/browser/default/browser.html?Connector=
'
+
FCKRelativePath
+
'
/fckeditor/command
'
;
FCKConfig.ImageBrowserURL
=
FCKConfig.BasePath
+
'
filemanager/browser/default/browser.html?uploaded=
'+FCKConfig.uploaded+'
&Type=Image&Connector=
'
+
FCKRelativePath
+
'
/fckeditor/command
'
;
FCKConfig.FlashBrowserURL
=
FCKConfig.BasePath
+
'
filemanager/browser/default/browser.html?uploaded=
'+FCKConfig.uploaded+'
&Type=Flash&Connector=
'
+
FCKRelativePath
+
'
/fckeditor/command
'
;
FCKConfig.LinkUploadURL
=
FCKRelativePath
+
'
/fckeditor/upload
'
;
FCKConfig.ImageUploadURL
=
FCKRelativePath
+
'
/fckeditor/upload?Type=Image&uploaded=
'+
FCKConfig.uploaded;
FCKConfig.FlashUploadURL
=
FCKRelativePath
+
'
/fckeditor/upload?Type=Flash&uploaded=
'+
FCKConfig.uploaded;
FCKConfig.AllowQueryStringDebug
=
false;
FCKConfig.SpellChecker
=
'
SpellerPages
'
;
//
ONLY CHANGE BELOW HERE
FCKConfig.SkinPath
=
FCKConfig.BasePath
+
'
skins/silver/
'
;
FCKConfig.AutoDetectLanguage
=
false ;
FCKConfig.DefaultLanguage
=
'
zh-cn
'
;
FCKConfig.FontNames
=
'
微软雅黑;宋体;黑体;隶书;楷体_GB2312;Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana
'
;
FCKConfig.ToolbarSets[
"
Simple
"
]
=
[
[
'
Source
'
,
'
-
'
,
'
FitWindow
'
,
'
Preview
'
,
'
-
'
,
'
Templates
'
],
[
'
PasteText
'
,
'
PasteWord
'
],
[
'
Undo
'
,
'
Redo
'
,
'
Find
'
,
'
Replace
'
],
'
/
'
,
[
'
RemoveFormat
'
,
'
Bold
'
,
'
Italic
'
,
'
Underline
'
,
'
StrikeThrough
'
],
[
'
OrderedList
'
,
'
UnorderedList
'
,
'
Outdent
'
,
'
Indent
'
],
[
'
JustifyLeft
'
,
'
JustifyCenter
'
,
'
JustifyRight
'
,
'
JustifyFull
'
],
[
'
TextColor
'
,
'
BGColor
'
],
[
'
Link
'
,
'
Unlink
'
,
'
Anchor
'
],
[
'
Image
'
,
'
Flash
'
,
'
Table
'
,
'
Rule
'
,
'
Smiley
'
],
'
/
'
,
[
'
Style
'
,
'
FontFormat
'
,
'
FontName
'
,
'
FontSize
'
]
] ;
4. 上面FCKConfig.uploaded的值来自于fckeditor.rb。在fckeditor.rb中加入一句(如下粗体所示)。
javascript_tag(
"
var oFCKeditor = new FCKeditor('#{id}', '#{width}', '#{height}', '#{toolbarSet}');\n
"
+
"
oFCKeditor.BasePath = \
"
#
{base_path}\"\n"+
"
oFCKeditor.Config['CustomConfigurationsPath'] = 'http://www.cnblogs.com/fckcustom.js';\n
"
+
"oFCKeditor.Config['uploaded'] = '#{options[:path]}';\n"+
"
oFCKeditor.ReplaceTextarea();\n
"
)
5.不 过上面oFCKeditor.Config['uploaded']的值要传到fckcustom.js的FCKConfig.uploaded里,还需 要修改fckeditorcode_gecko.js和fckeditorcode_ie.js(这两个文件对javascript进行了压缩处理,修改 起来较难操作)。我是参考了oFCKeditor.Config['CustomConfigurationsPath'] 这个参数的载入实现,才找到这种鸟不生蛋的地方。搜索这两个文件的关键字CustomConfigurationsPath,找到如下一行,然后加入一个else if判断(如下粗体所示)。
if
(D
==
'
CustomConfigurationsPath
'
) FCKConfig[D]
=
E;
else if (D=='uploaded') FCKConfig[D]=E;
else
if
(E.toLowerCase()
==
"
true
"
)
this
.PageConfig[D]
=
true
;
6.最后在fckeditor.rb里的#{options[:path]}来自于我们前台的view了。如下粗体所示,把标准的fckeditor_textarea新增加了一个参数,其中params[:user_id]是把用户的ID值做为目录名。这样就实现了动态改变FCKEditor的上传目录。
<%=
fckeditor_textarea(:topic, :content, :ajax
=>
true
, :toolbarSet
=>
'
Simple
'
, :height
=>
'
400px
'
, :path
=>
"
/uploads/#{params[:user_id]}
"
)
%>
修 改完后需要重启WEB服务,最后别忘记把public/javascripts/fckeditor和vendor/plugins/fckeditor /public/javascripts同步一下,原因见http://www.blogjava.net/chengang/archive/2007 /09/24/147867.html
转自: http://www.blogjava.net/chengang/archive/2007/09/26/148114.html