Customize CKFinder paths dynamically with JS, can it be done? - javascript

I'm doing an administrative function to work with CKEditor v4.x and need a file/folder view, upload and selection tool. For the time being I'm using CKFinder as I'd like to avoid writing a complete plugin by myself. However for the purpose I need to be able to switch baseDir and baseUrl dynamically.
I tried older code examples like
CKFinder.setupCKEditor(
editor,
{
basePath: '/ckfinder/',
baseUrl: 'http://www.example.com/mydirectory/',
baseDir: '/mydirectory/'
}
);
But this doesn't work. Apparently you need to set the paths by PHP (server side). As I'm having many CKEditor instances on one page, generated dynamically, and all should use different CKFinder paths it is a great deal of work if I need to change the path asynchronously through AJAX calls... I can of course see the security considerations by letting client side code control baseDir. For the record this application, and CKFinder, is only available after login by administrative people.

In our CMS area we use CKFinder.setupCKEditor() and I was unable to pass variables or flags to the config file correctly.
So I simply went to where the 'IsAuthorized' flag is set (that allows access to use CKFinder in their CheckAuthentication() function), and I set two more session variables: 'ckfinder_baseDir' and 'ckfinder_baseUrl'.
*Note that I have a Config class that checks the enviroment, hence Config::isDev(). You can check it any way that makes sense for you.
$_SESSION['IsAuthorized'] = 1;
$_SESSION['ckfinder_baseUrl'] = Config::isDev() ? 'http://devurl.com/' : 'http://produrl.com';
$_SESSION['ckfinder_baseUrl'] = Config::isDev() ? '/path/to/dev/uploads/' : 'path/to/prod/uploads';
Then I simply use these flags when in the CKFinder config.php file.
$baseUrl = $_SESSION['ckfinder_baseUrl'];
$baseDir = $_SESSION['ckfinder_baseDir'];

You can specify the parameter on the frontend side in the definition of the filebrowser button as following
{
type: 'button',
label:'Button for filebrowser',
filebrowser: {
action: 'Browse',
params: {
'id': '{someID}'
}
},

With help from the discussion Customize baseUrl and baseDir in CKFinder I got close to the answer with Travis comment.
There is a way to call different server side settings for each instance of CKFinder by just using a GET parameter in the path to CKFinder. I set the id of the filebrowserpath
filebrowserBrowseUrl: '/ckfinder/ckfinder.html?id=testdir'
And then in the config.php:
if ($_GET['id'] && $_GET['id'] == "testdir") {
$baseDir = $baseDir . 'testdir/';
$baseUrl = $baseUrl . 'testdir/';
}
This way each instance of CKeditor can use different basePath and baseUrl settings, and also other specific config.

in config.ascx in setConfig() method
string userName = string.Empty;
if (HttpContext.Current != null)
userName = HttpContext.Current.User.Identity.Name;
else
throw new Exception("User Name is not provided");
BaseUrl = "~/Uploads/Users/" + userName + "/";

Related

How to read a file being saved to Parse server with Cloud Code, before actually saving it?

I'm trying to use Cloud Code to check whether a user-submitted image is in a supported file type and not too big.
I know I need to do this verification server-side and I think I should do it with Cloud Code using beforeSave – the doc even has a specific example about data validation, but it doesn't explain how to handle files and I couldn't figure it out.
I've tried the documented method for saving files, ie.
file = fileUploadControl.files[0];
var parseFile = new Parse.File(name, file);
currentUser.set("picture", parseFile);
currentUser.save();
and in the Cloud Code,
Parse.Cloud.beforeSave(Parse.User, (request, response) => { // code here });
But 1. this still actually saves the file on my server, right? I want to check the file size first to avoid saving too many big files...
And 2. Even then, I don't know what to do in the beforeSave callback. It seems I can only access the URL of the saved image (proof that it has been uploaded), and it seems very counter-intuitive to have to do another https request to check the file size and type before deciding whether to proceed with attaching the file to the User object.
(I'm currently using remote-file-size and file-type to check the size and type of the uploaded file, but no success here either).
I also tried calling a Cloud function, but it feels like I'm not doing the right thing, and besides I'm running into the same issues.
I can call a Cloud function and pass a saved ParseFile as a parameter, and then I know how to save it to the User object from the Cloud Code using the masterkey, but as above it still involves uploading the file to the server and then re-fetching it using its URL.
Am I missing anything here?
Is there no way to do something like a beforeSave on Parse.File, and then stop the file from being saved if it doesn't meet certain criteria?
Cheers.
If you have to do something with files, parse lets you overwrite the file adapter to handle file operations.
You can indicate the file adapter to use in your ParseServer instatiation:
var FSStoreAdapter = require('./file_adapter');
var api = new ParseServer({
databaseURI: databaseUri ,
cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
appId: process.env.APP_ID,
filesAdapter: fs_store_adapter, // YOUR FILE ADAPTER
masterKey: process.env.MASTER_KEY, //Add your master key here. Keep it secret!
serverURL: "https://yourUrl", // Don't forget to change to https if needed
publicServerURL: "https://yourUrl",
liveQuery: {
classNames: ["Posts", "Comments"] // List of classes to support for query subscriptions
}
maxUploadSize: "500mb" //you will now have 500mb limit :)
});
That said, you can also specify a maxUploadSize in your instatiation as you can see in the last line.
you have to use save in background
file = ParseFile("filename", file)
file?.saveInBackground({ e ->
if (e == null) {
} else {
Toast.makeText(applicationContext, "Error: $e", Toast.LENGTH_SHORT).show()
e.printStackTrace()
Log.d("DEBUG", "file " + e.code)
}
}, { percentDone ->
Log.d("DEBUG", "file:" + percentDone!!)
})

TinyMCE how to append baseURL to LINK and base Path for images

I'm using TinyMCE for Editing my site content.
In Local I've different path for my base url and on development server its different and on production its different.
Is there any way to define the something like baseURL for my links and basePath for Images to be linked.
I want to define baseURL to all my links and basePath to my all the Images.
Right now I'm working on my local and I've created few pages. But when I've thought of dev and production It will be difficult to do the path changing task. Please desperately need some solution.
I think you will need to set these three options:
relative_urls : false,
remove_script_host : false,
document_base_url : "http://www.example.com/path1/"
According to the TinyMCE documentation, this will convert all relative urls to fully qualified URLs, based on the base you provide.
function myCustomURLConverter(url, node, on_save, name) {
// Do some custom URL conversion
if (name == "src")
{
url = window.location.origin +"/uploads/" + url
}
// Return new URL
return url;
}
I'm not sure I undestand the question, but wouldn't this provide what you're looking for?
var base = "http://"+window.location.host;
// base = "http://stackoverflow.com"
var img_base = base + "/img"
// img_base = "http://stackoverflow.com/img"

How should I create relative paths in javascript using MVC3?

I am having some difficulty aligning my paths without a hardcode in javascript. I am running an asp.net MVC3 web application.
If my path is of the form
var url = 'http://serverNameHardcode/websiteNameHardcode/service/service?param1=' + param;
Then things work fine when I do
$.get(url,
{},
function (data) {alert('callback success');},'json');
I would like to create a relative path. I tried
var url = 'service/service?param1=' + param;
And this works when I run locally and also in Firefox, but not in IE7. When I publish to the server without the hardcode the callback never fires. I know MVC-3 adds some complexity to routing, but I do not know if it applies to this situation; so, I marked this question as such.
How should I setup my path so I don't need hardcodes?
Just write out the app path as a global js variable from your master view, then compose links as
APPPATH + "path/whatever"
Just had to solve this for one of my jQuery plugins, where it is preferable not to modify anything global (i.e. outside the scope of the plugin use) so I had to disregard the marked answer.
I also found that because I host DEV locally in IIS I could not use a root-relative path (as localhost is not the root).
The solution I came up with extended what I had already started with: a data-controller attribute specifying which controller to use in the element I am applying my plugin to. I find it preferable to data-drive the controller names so the components can be more easily reused.
Previous:
<div data-controller="Section">
Solution:
<div data-controller="#Url.Content("~/Section")">
This injects the server root (e.g. /Test.WindowsAzure.Apr2014/ before the controller name so I wind up with /Test.WindowsAzure.Apr2014/Section which is perfect for then appending actions and other parameters as you have. It also avoids having an absolute path in the output (which takes up extra bytes for no good reason).
In your case use something like:
// Assuming $element points to the element your plugin/code is attached to...
var baseUrl = $element.data('controller');
var url = baseUrl + '/service?param1=' + param;
Update:
Another approach we now use, when we do not mind injecting a global value, is Razor-inject a single global JavaScript variable onto window in the layout file with:
<script>
window.SiteRoot = "#Url.Content("~/")";
</script>
and use it with
var url = window.SiteRoot + '/service?param1=' + param;
One option:
var editLink = '#Url.Action("_EditActivity", "Home")';
$('#activities').load(editLink + "?activityID=" + id);
another example:
var actionURL = '#Url.Action("_DeleteActivity", "Home")';
$('#activities').load(actionURL + "?goalID=" + gID + "&activityID=" + aID);
If you don't need to add to the string:
$('#activities').load('#Url.Action("_Activities", "Home", new { goalID = Model.goalID},null)');
I really need the path to get this to work, maybe its IE7. Who knows. But this worked for me.
Grab the URL and store it somewhere. I chose to implement the data attribute from HTML5.
<div id="websitePath" data-websitePath='#Request.Url.GetLeftPart(System.UriPartial.Authority)#Request.ApplicationPath'></div>
Then when you need to perform some AJAX or otherwise use a URL in javascript you simply refer to the stored value. Also, there are differences in the versions of IIS (not cool if your devbox is IIS5 and your server is IIS7). #Request.ApplicationPath may or may not come back with a '/' appended to the end. So, as a workaround I also trim the last character if it is /. Then include / as part of the url.
var urlprefix = $('#websitePath').data('websitepath');
urlprefix = urlprefix.replace(/\/$/, "");
var url = urlprefix + '/service/service?param1=' + param;
While the accepted answer is correct I would like to add a suggestion (i.e. how I do it).
I am using MVC, and any ajax request goes to a controller. My controllers have services so if a service call is required the controller will take of that.
So what's my point? So if ajax always communicates with a controller, then i would like to let the MVC routing resolve the path for me. So what I write in Javascript for url is something like this:
url: 'controller/action'
This way there is no need for the root path etc...
Also, you can put this in a separate Javascript file and it will also work whereas #Url.Content will need to be called on the view.

FCKeditor Plugin Issues

I am a complete beginner trying to develop for FCKeditor so please bear with me here. I have been tasked with developing a custom plugin that will allow users to browse a specific set of images that the user uploads. Essentially the user first attaches images, then uses the FCKeditor to insert those images.
So I have my plugin directory:
lang
fckplugin.js
img.png (for the toolbar button)
I am looking for some help on strategy for the custom file browser (lets call it mybrowser.asp).
1) Should mybrowser.asp be in the plugin directory? It is dynamic and only applies to one specific area of the site.
2) How should I pass the querystring to mybrowser.asp?
3) Any other recommendations for developing FCKeditor plugins? Any sample plugins that might be helpful to me?
EDIT: The querystring passed to the plugin page will be the exact same as the one on the host page. (This is a very specific plugin that will only be used in one place)
You don't need the lang directory unless you're planning on supporting multiple languages. But even then, I would get the plugin working in one language first.
I would probably put mybrowser.asp in the plugin directory.
Here's some code for fckplugin.js to get you started.
// Register the related command.
// RegisterCommand takes the following arguments: CommandName, DialogCommand
// FCKDialogCommand takes the following arguments: CommandName,
// Dialog Title, Path to HTML file, Width, Height
FCKCommands.RegisterCommand(
'MyBrowser',
new FCKDialogCommand(
'My Browser',
'Select An Image',
FCKPlugins.Items['MyBrowser'].Path + 'mybrowser.asp',
500,
250)
);
// Create the toolbar button.
// FCKToolbarButton takes the following arguments: CommandName, Button Caption
var button = new FCKToolbarButton( 'MyBrowser', 'Select An Image' ) ;
button.IconPath = FCKPlugins.Items['MyBrowser'].Path + 'img.png' ;
FCKToolbarItems.RegisterItem( 'MyBrowser', button ) ;
Edit: I haven't tested this, but you should be able to append the querystring by doing something along these lines.
'Select An Image',
FCKPlugins.Items['MyBrowser'].Path + 'mybrowser.asp' + window.top.location.search,
500,
You might not need to write your own file browser as this functionality is built in. If you check the fckconfig.js file and search for var _FileBrowserLanguage you can specify your server language and it should hopefully use the equivalent file in the editor -> filemanager -> connectors folder.
If you check the docs hopefully that should hopefully keep you on the right track.

Relative urls for Javascript files

I have some code in a javascript file that needs to send queries back to the server. The question is, how do I find the url for the script that I am in, so I can build a proper request url for ajax.
I.e., the same script is included on /, /help, /whatever, and so on, while it will always need to request from /data.json. Additionally, the same site is run on different servers, where the /-folder might be placed differently. I have means to resolve the relative url where I include the Javascript (ez-publish template), but not within the javascript file itself.
Are there small scripts that will work on all browsers made for this?
For this I like to put <link> elements in the page's <head>, containing the URLs to use for requests. They can be generated by your server-side language so they always point to the right view:
<link id="link-action-1" href="${reverse_url ('action_1')}"/>
becomes
<link id="link-action-1" href="/my/web/root/action-1/"/>
and can be retrieved by Javascript with:
document.getElementById ('link-action-1').href;
document.location.href will give you the current URL, which you can then manipulate using JavaScript's string functions.
There's no way that the client can determine the webapp root without being told by the server as it has no knowledge of the server's configuration. One option you can try is to use the base element inside the head element, getting the server to generate it dynamically rather than hardcoding it (so it shows the relevant URL for each server):
<base href="http://path/to/webapp/root/" />
All URLs will then be treated as relative to this. You would therefore simply make your request to /data.json. You do however need to ensure that all other links in the application bear this in mind.
If the script knows its own filename, you can use document.getElementsByTagName(). Iterate through the list until you find the script that matches yours, and extract the full (or relative) url that way.
Here's an example:
function getScriptUrl ( name ) {
var scripts = document.getElementsByTagName('script');
var re = RegExp("(\/|^)" + name + "$");
var src;
for( var i = 0; i < scripts.length; i++){
src = scripts[i].getAttribute('src');
if( src.match(re) )
return src;
}
return null;
}
console.log( 'found ' + getScriptUrl('demo.js') );
Take into consideration that this approach is subject to filename collisions.
I include the following code in my libraries main entry point (main.php):
/**
* Build current url, depending on protocal (http/https),
* port, server name and path suffix
*/
$site_root = 'http';
if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on")
$site_root .= "s";
$site_root .= "://" . $_SERVER["SERVER_NAME"];
if ($_SERVER["SERVER_PORT"] != "80")
$site_root .= ":" . $_SERVER["SERVER_PORT"];
$site_root .= $g_config["paths"]["site_suffix"];
$g_config["paths"]["site_root"] = $site_root;
$g_config is a global array containing configuration options. So site_suffix might look like: "/sites_working/thesite/public_html" on your development box, and just "/" on a server with a virtual host (domain name).
This method is also good, because if somebody types in the IP address of your development box, it will use that same IP address to build the path to the javascript folder instead of something like "localhost," and if you use "localhost" it will use "localhost" to build the URL.
And because it also detects SSL, you wont have to worry about weather your resources will be sent over HTTP or HTTPS if you ever add SSL support to your server.
Then, in your template, either use
<link id="site_root" href="<?php echo $g_config["paths"]["site_root"] ?>"/>
Or
<script type = "text/javascript">
var SiteRoot = "<?php echo $g_config["paths"]["site_root"]; ?>";
</script>
I suppose the latter would be faster.

Categories

Resources