Category:Extensions -> WYSIWYG
I installed TinyMCE recently and freakin love it, great job to the folks who did the extension for it!
However, it appears that in order to handle file mamagement, folks were installing iBrowser and there was no good way to integrate EE’s file upload and file management into TinyMCE. I did some poking around and found out that there was a way to send an image list to TinyMCE via the external_image_list_url option. This is basically just a javascript array that the TinyMCE image manager will read and if it exists will add in a dropdown box for the /files/images specified in this array.
For this you need the following TinyMCE settings, I’m using relative URL’s for TinyMCE, so I set that up first, go to the EE Extensions manager for TinyMCE and update the settings with these two options:
relative_urls : true,
document_base_url : "/",
For this explanation I’m going to assume that you will be using relative URL’s, if anyone does not then I can provide config info on how to proceed without using relative URL’s.
The next option that needs to get set in the TinyMCE configs is the “external_image_list_url” setting, for this I set it as such:
external_image_list_url : "/site/scripts/imagelist.js/"
Here is where the coolness starts for this little trick, the above just points to an EE template group called “scripts” and template “imagelist.js”, you can name either anything you want. The desire here is to use EE’s file upload management system and as such you can have multiple upload locations and those locations can be restricted by the member group of the person doing the posting. So the assumption for the following code is that if you can’t upload to it then you ain’t supposed to be seeing what’s in any directories that you don’t have access to upload to, with that in mind here’s the code.
To make this work, you will have to have a nested query and thus you’ll actually have two templates due to the nature of in which EE handles nested queries.
imagelist.js source
<?php
print "var tinyMCEImageList = new Array(";
?>
{exp:query sql="SELECT a.upload_id, p.server_path
FROM exp_upload_no_access a
LEFT JOIN exp_upload_prefs p ON p.id = a.upload_id
WHERE a.member_group != '{group_id}'"}
{if server_path}
<?php
$imagepath = substr("{server_path}",2,100);
$PATH = $_SERVER['DOCUMENT_ROOT'];
$d=$PATH.$imagepath; #define which dir you want to read
$dir = opendir($d); #open directory
while ($f = readdir($dir))
{
if (eregi("\.jpg",$f) OR eregi("\.gif",$f))
{
print "[\"$imagepath$f\", \"$imagepath$f\"],";
}
}
closedir($dir);
?>
{/if}
{if no_results}
{/if}
{/exp:query}
<?php
print "[\"\",\"\"]);";
?>
nested-query source
{exp:query sql="SELECT server_path FROM exp_upload_prefs"}
<?php
$imagepath = substr("{server_path}",2,100);
$PATH = $_SERVER['DOCUMENT_ROOT'];
$d=$PATH.$imagepath; #define which dir you want to read
$dir = opendir($d); #open directory
while ($f = readdir($dir))
{
if (eregi("\.jpg",$f) OR eregi("\.gif",$f))
{
print "[\"$imagepath$f\", \"$imagepath$f\"],";
}
}
closedir($dir);
?>
{/exp:query}
I’m going to try to net the above out, in the EE table “exp_upload_no_access” is a list of the groups that don’t have access to particular upload directories, so the code pulls anything from that table that is not equal to current users “group_id” and this query joins to the “exp_upload_prefs table based on those results and outputs the “server_path” field in that table. The second part checks to see if there were no results, this means that either an admin is posting or the current user is allowed to access all upload paths, and if so then we just need to get all the “server_paths” from table “exp_upload_prefs”, thus the entire reason for the nested query.
This code just gets image files that end in “.jpg” and “.gif” so you’ll need to adjust if you want all files or other image files, this is done in the code
if (eregi("\.jpg",$f) OR eregi("\.gif",$f))
For the above code the output is:
var tinyMCEImageList = new Array( [”/images/uploads/smalltreefrog.gif”, “/images/uploads/smalltreefrog.gif”],[”/images/uploads/crane2.jpg”, “/images/uploads/crane2.jpg”], [”/images/uploads/webhosting/smalltreefrog.gif”, “/images/uploads/webhosting/smalltreefrog.gif”],[”/images/uploads/webhosting/newcrane2.jpg”, “/images/uploads/webhosting/newcrane2.jpg”],[”/images/uploads/webhosting/newsmalltreefrog.gif”, “/images/uploads/webhosting/newsmalltreefrog.gif”],[”/images/uploads/webhosting/crane2.jpg”, “/images/uploads/webhosting/crane2.jpg”], [”“,”“]);
This was rendered by me an admin, thus the output is all file upload directories and all images under them for the “/images/uploads” directory and the “/images/uploads/webhosting” directory.
That’s it, it works great, it accesses all of the files from EE’s file upload management system and will even give you a nice preview in the preview pane of TinyMCE’s image dialog and from there you can do anything you like to the image, resize it, align it, add borders, do mouseover image swaps, ets, all based on the files/images in the EE file upload management system, heck, with this code you could even have the images from your gallery accessable right in your weblog publishing area.
Alternative Script — February 2009
(From another Author)
For use with the “Image” button
For the imagelist.js, you have to go into the template group preferences and select “Allow PHP” for this particular template, which of course is a security problem. I tried setting the template as either a “javascript” or a “web page” and both worked once “Allow PHP” was selected. Since tinyMCE needs to see the output as a javascript then the .js extension seems like a good practice for your template name.
Using “View Rendered Template” you can see if the template is generating a valid array variable with the content of your images/uploads directory listed.
The php code in the original example is wrapped inside of an “exp:query” block of code. The stated intention is to control what directories the user has access to. However the sql query does not seem to work. Perhaps the current design of EE makes this sql code no longer correct? At any rate I had to remove the EE portion of the script in order to get a valid array as output.
The variable {server_path} seems to no longer exist in the version of EE that I have. Does anyone know of a replacement? I had to hardcode the “imagepath” variable. “/images/uploads/” is fairly standard now in EE.
I pulled the following script from the moxiecode site on the external_image_list_url page, altered the “directory” variable to what is shown, and it works with EE. Improvements need to be made to filter out non-image files as the script below will list everything in the directory, including the index.html file.
For settings in the EE Extension manager I used the following FULL URL with NO relative URLs setting:
Extension Manager Settings
// Settings to work with EE file upload system.
relative_urls : false,
document_base_url : "http://www.mywebsite.com/index.php/",
external_image_list_url : "http://www.mywebsite.com/index.php/script/imagelist.js",
Also, I turned off the relative URLs setting because if your EE directory is not at the top, root level of your site there seems to be a problem with broken URLs for images.
Following is the source code for the EE template.
imagelist.js source
<?php // this must be the very first line in your PHP file!
// You can't simply echo everything right away because we need to set some headers first!
$output = ''; // Here we buffer the JavaScript code we want to send to the browser.
$delimiter = "\n"; // for eye candy... code gets new lines
$output .= 'var tinyMCEImageList = new Array(';
$directory = "images/uploads"; // Use your correct (relative!) path here
// Since TinyMCE3.x you need absolute image paths in the list...
$abspath = preg_replace('~^/?(.*)/[^/]+$~', '/\\1', $_SERVER['SCRIPT_NAME']);
if (is_dir($directory)) {
$direc = opendir($directory);
while ($file = readdir($direc)) {
if (!preg_match('~^\.~', $file)) { // no hidden files / directories here...
if (is_file("$directory/$file")) {
// We got ourselves a file! Make an array entry:
$output .= $delimiter
. '["'
. utf8_encode($file)
. '", "'
. utf8_encode("$abspath/$directory/$file")
. '"],';
}
}
}
$output = substr($output, 0, -1); // remove last comma from array item list (breaks some browsers)
$output .= $delimiter;
closedir($direc);
}
$output .= ');'; // Finish code: end of array definition. Now we have the JavaScript code ready!
header('Content-type: text/javascript'); // Make output a real JavaScript file!
echo $output; // Now we can send data to the browser because all headers have been set!
?>
For use with the “Link” button
There is also an extension to tinyMCE that allows you to provide a list of files in your upload directory when using the “Link” button. You have to upload the files first using EE’s “File Upload” button (You can’t insert the EE generated URL into a tinyMCE field which is the problem this is meant to work around). To do this use the same setup as the above script but the array name in the javascript template needs to be changed to “external_link_list_url”. So you have the following settings in the Extensions manager in EE:
Extension Manager Settings
// Settings to work with EE file upload system.
relative_urls : false,
document_base_url : "http://www.mywebsite.com/index.php/",
external_image_list_url : "http://www.mywebsite.com/index.php/script/imagelist.js",
external_link_list_url : "http://www.mywebsite.com/index.php/script/filelist.js",
Create another template in EE, as explained above, called filelist.js and duplicate the above PHP code with the slight change of:
$output .= 'var tinyMCELinkList = new Array(';
