Hello,

I am currently researching how to integrate CKFinder with CKEditor using the wysiwyg module. I am getting close to hacking a solution but thought I would start a discussion with the community and the module maintainers for a sub-module.

In the past some of the WYSIWYG editors required you configure a file manager via server-side configuration files. More recently with Ckeditor you are required to register the file manager on the instance of the editor in the DOM of the browser (http://docs.cksource.com/CKEditor_3.x/Developers_Guide/File_Browser_%28U...). This is attractive in that you could in theory use any file manager with the editor.

Proposal:

1. Create a module called wysiwyg_filemanager
2. The purpose of the module is to provide a centralized management interface to registering file managers both 3rd party and provide bridges for Drupal life and media management modules.
3. File managers would be located in a similar manor to editors /sites/all/libraries/.
4. A configuration interface should be provided to register file managers
5. A configuration interface should be provided to assign a file manager to a supported wysiwyg editor

The possiblities for this module would perhaps have one or more drupal modules provided both management and uploading of media. For example providing a bridge between filefield and web file manager (although currently not viable)

Or using CkFinder or other managers to centerally manage all files and media for a Drupal site.

Let's use this issue to discuss the design and perhaps even code samples.

Files: 

Comments

emptyvoid’s picture

Title: wysiwyg_filemanager - Ckfinder integration » wysiwyg_filemanager
Status: Needs work » Active

Perhaps this would just be a plug-in using the Libraries API?

http://drupal.org/project/libraries

.. As a note in order to get the CKFinder to work in Drupal I had to modify the config.php within the source code to become aware of drupal.

/*
To make it easy to configure CKFinder, the $baseUrl and $baseDir can be used.
Those are helper variables used later in this config file.
*/

/*
$baseUrl : the base path used to build the final URL for the resources handled
in CKFinder. If empty, the default value (/userfiles/) is used.

Examples:
	$baseUrl = 'http://example.com/ckfinder/files/';
	$baseUrl = '/userfiles/';

ATTENTION: The trailing slash is required.
*/

 // regexpression validation
    preg_match('(^/([^/]+))',$_SERVER['REQUEST_URI'], $uri_matches);
    
    // app root directory location
    $root_directory = rtrim($_SERVER['DOCUMENT_ROOT'], '/');
    //$root_directory = '';
    // media asset directory location
    $base_directory = $root_directory.'/sites/default/files/';
    
    $header_url = '';
    
    if (empty($_SERVER['HTTPS'])) {
	$header_url = 'http://';
    } else {
	$header_url = 'https://';
    }
    
    $root_url = $header_url.$_SERVER['SERVER_NAME'];
    $base_url = $root_url.'/sites/default/files/';
    
    // if the uri contains a sub-directory
    if(isset($uri_matches[1])){
        $sub_site_dir = '/sites/'.$_SERVER['HTTP_HOST'].'.'.$uri_matches[1];
        $sub_site_path = $root_directory.$sub_site_dir;
        if(is_dir($sub_site_path)) {
            $base_url = $root_url.$sub_site_dir.'/files/';
            $base_directory = $sub_site_path.'/files/';
        }
    }

$baseUrl = $base_url;

/*
$baseDir : the path to the local directory (in the server) which points to the
above $baseUrl URL. This is the path used by CKFinder to handle the files in
the server. Full write permissions must be granted to this directory.

Examples:
	// You may point it to a directory directly:
	$baseDir = '/home/login/public_html/ckfinder/files/';
	$baseDir = 'C:/SiteDir/CKFinder/userfiles/';

	// Or you may let CKFinder discover the path, based on $baseUrl:
	$baseDir = resolveUrl($baseUrl);

ATTENTION: The trailing slash is required.
*/

$baseDir = $base_directory;

Authentication only works if you have set a cookie name for your Drupal website in /sites/default/settings.php.



function CheckAuthentication()
{
	//WARNING : DO NOT simply return "true". By doing so, you are allowing
	//"anyone" to upload and list the files in your server. You must implement
	//some kind of session validation here. Even something very simple as...

	// return isset($_SESSION['IsAuthorized']) && $_SESSION['IsAuthorized'];

	//... where $_SESSION['IsAuthorized'] is set to "true" as soon as the
	//user logs in your system.

	static $authenticated;

	if (!isset($authenticated) && empty($authenticated) == TRUE || $authenticated == FALSE) {
		$drupal_path = "../../../../";
		if(!file_exists($drupal_path . "/includes/bootstrap.inc")) {
			$drupal_path = "../../..";
			do {
				$drupal_path .= "/..";
				$depth = substr_count($drupal_path, "..");
			}
			while(!($bootstrapFileFound = file_exists($drupal_path . "/includes/bootstrap.inc")) && $depth<10);
		}
			if (!isset($bootstrapFileFound) || $bootstrapFileFound) {
				
				$cwd = getcwd();
				chdir($drupal_path);
				require_once "./includes/bootstrap.inc";
				drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
				
				global $user;
				
				if (!is_array($user->session)) {
					$user->session = array();
				}
				if (is_null($user->session['authenticated'])) {
					$user->session['authenticated'] = '';
				}
				
				if (is_array($user->roles) && is_null($user->roles[1])) {
					$user->session['authenticated'] = true;
				} else {
					$user->session['authenticated'] = false;
				}
				
				$authenticated = $user->session['authenticated'];
				
			}
		
		chdir($cwd);
	}
	
	return $authenticated;
}

CheckAuthentication();

Now the last part:

1) Create a module to load the ckfinder js file.

function your_module_name_init() {
    // added to enable the ckfinder for the ckeditor in the wysiwyg api module.
    drupal_add_js('sites/all/libraries/ckfinder/ckfinder.js');
   
}


2) Modify the javascript file for the editor in the wysiwyg module /wysiwyg/editors/js/ckeditor-3.0.js


/**
 * Attach this editor to a target element.
 */
Drupal.wysiwyg.editor.attach.ckeditor = function(context, params, settings) {
  // Apply editor instance settings.
  CKEDITOR.config.customConfig = '';
  
  settings.on = {
    instanceReady: function(ev) {
      var editor = ev.editor;
      // Get a list of block, list and table tags from CKEditor's XHTML DTD.
      // @see http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Output_Formatting.
      var dtd = CKEDITOR.dtd;
      var tags = CKEDITOR.tools.extend({}, dtd.$block, dtd.$listItem, dtd.$tableContent);
      // Set source formatting rules for each listed tag except 
.
      // Linebreaks can be inserted before or after opening and closing tags.
      if (settings.apply_source_formatting) {
        // Mimic FCKeditor output, by breaking lines between tags.
        for (var tag in tags) {
          if (tag == 'pre') {
            continue;
          }
          this.dataProcessor.writer.setRules(tag, {
            indent: true,
            breakBeforeOpen: true,
            breakAfterOpen: false,
            breakBeforeClose: false,
            breakAfterClose: true
          });
        }
      }
      else {
        // No indents or linebreaks;
        for (var tag in tags) {
          if (tag == 'pre') {
            continue;
          }
          this.dataProcessor.writer.setRules(tag, {
            indent: false,
            breakBeforeOpen: false,
            breakAfterOpen: false,
            breakBeforeClose: false,
            breakAfterClose: false
          });
        }
      }
    },

    pluginsLoaded: function(ev) {
      // Override the conversion methods to let Drupal plugins modify the data.
      var editor = ev.editor;
      if (editor.dataProcessor && Drupal.settings.wysiwyg.plugins[params.format]) {
        editor.dataProcessor.toHtml = CKEDITOR.tools.override(editor.dataProcessor.toHtml, function(originalToHtml) {
          // Convert raw data for display in WYSIWYG mode.
          return function(data, fixForBody) {
            for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
              if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') {
                data = Drupal.wysiwyg.plugins[plugin].attach(data, Drupal.settings.wysiwyg.plugins.drupal[plugin], editor.name);
                data = Drupal.wysiwyg.instances[params.field].prepareContent(data);
              }
            }
            return originalToHtml.call(this, data, fixForBody);
          };
        });
        editor.dataProcessor.toDataFormat = CKEDITOR.tools.override(editor.dataProcessor.toDataFormat, function(originalToDataFormat) {
          // Convert WYSIWYG mode content to raw data.
          return function(data, fixForBody) {
            data = originalToDataFormat.call(this, data, fixForBody);
            for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
              if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') {
                data = Drupal.wysiwyg.plugins[plugin].detach(data, Drupal.settings.wysiwyg.plugins.drupal[plugin], editor.name);
              }
            }
            return data;
          };
        });
      }
    },
    focus: function(ev) {
      Drupal.wysiwyg.activeId = ev.editor.name;
    }
  };

  // Attach editor.
  editor = CKEDITOR.replace(params.field, settings);
  CKFinder.SetupCKEditor( editor, '/sites/all/libraries/ckfinder/' );

};

The CKFinder section attaches the ckfinder library to an instance of the wysiwyg editor! :)

emptyvoid’s picture

Title: wysiwyg_filemanager » wysiwyg_filemanager - Ckfinder integration

Changing name so people will find the comments on integration.

emptyvoid’s picture

Status: Active » Needs work
mrfelton’s picture

I too am interested in this. CKFinder provides a much slicker interface than IMCE.

klonos’s picture

Title: wysiwyg_filemanager » wysiwyg_filemanager - Ckfinder integration
Status: Active » Needs work

me too... subscribing

sun’s picture

Status: Needs work » Closed (won't fix)

The native file browsers/uploaders are purposively not supported by Wysiwyg module. However, if you really insist on wanting to use this, then feel free to create a contributed module that acts as bridge between Wysiwyg and CKFinder. If anything is needed in Wysiwyg module to make this bridge happen, just let us know.

sentogi’s picture

CheckAuthentication() is ok but I think we should make the baseURL and baseDir vars dynamic for multi-sites structures. you may use file_directory_path() drupal function to realize it.

First ; all we need is drupal common function in ckfinder/config php to be able to use file_directory_path() function
And second ; set the baseURL and baseDir by using file_directory_path() function

require_once $_SERVER['DOCUMENT_ROOT']."/includes/common.inc"; //#1

$baseUrl = "/".file_directory_path()."/"; //#2
$baseDir = $_SERVER['DOCUMENT_ROOT']."/".file_directory_path()."/"; //#2

That's it. you can use your ckfinder for all sites withour any code change..

decibel.places’s picture

subscribe

I heard latest wysiwyg supports ckeditor - but not without all this rigamarole to get the file browser connected!

It's back to using the regular ckeditor module until this works without hacking!

nauthiz693’s picture

I tried the method you proposed in comment #1, and it worked for me, but I was wondering about the line,

drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

If all you want is the current logged in user, wouldn't it work to do:

drupal_bootstrap(DRUPAL_BOOTSTRAP_SESSION);

This would skip like three or four steps of the bootstrap process and would probably be faster.

that0n3guy’s picture

sub...

Fidelix’s picture

Sub

richsky’s picture

Seem not to work.

file_directory_path() is found in file.inc (drupal 6) but it doesn't help

I'd really like to figure out how to have ckfinder using right $base_directory ($baseDir) for each virtual site we may have in a multisite installation.

locomo’s picture

subscribe

emptyvoid’s picture

For those interested I ended up leveraging the IMCE module instead as it provides integrated security and permissions within Drupal.

http://drupal.org/project/imce

http://drupal.org/project/imce_wysiwyg

decibel.places’s picture

At a drupalnyc meetup a few months ago, someone, I think it was jensimmons, noted that CKFinder does not integrate the images with the Drupal image system - they are just uploaded as embedded files, with no imagecache etc. I think nikkiana stated there is a module that will automatically resize enormjous images uploaded by unknowing users http://drupal.org/project/image_resize_filter but that only reduces bandwith.

For knowledgeable admins, CKFinder remains a quick way to embed images in a post..

has anybody tried wysiwyg_imageupload? http://drupal.org/project/wysiwyg_imageupload

jrsinclair’s picture

As suggested by @sun in #6, I've created a bridging module for WYSIWYG, CKEditor and CKFinder, to make this whole process a little easier. We'd love people to try it out and let us know how it goes-- just make sure that you read the installation instructions carefully.

DigitalFrontiersMedia’s picture

jrsinclair YOU...SAVED...MY...BACON! Honestly, I was thinking I don't have time due to my client's timeframe to figure out what would be required for this. I was just starting to get depressed that here it is 2011 and after 4 years with Drupal I'm having WYSIWYG headaches again, and then there you are with your module! I prefer using WYSIWYG & then have a choice of editors if possible. I prefer a system that works well with Better Formats as WYSIWYG does. But wysiwyg_upload_image doesn't work in blocks, IMCE is confusing to my users/clients, I prefer CKEditor over the others if I have a choice, and thus after 4 years of Drupal builds, I'm still left with few to no options for easy image uploads for my users/clients...until now!

I just followed your instructions, and it seems to work well so far. Works in blocks, too! :-)

Excellent work, my friend. You deserve a cookie, but since you're not here, I'll have one for you in celebration of saving me gobs of time sorting this out!

Thank you for sharing this effort!

decibel.places’s picture

jrsinclair - will you be adding the module as a contrib module managed by update and drush (maybe after the Git migration?)

decibel.places’s picture

FileSize
23.65 KB
18.31 KB

I installed the bridge module carefully and I am getting a similar bug in the upload dialog to a problem I had with the wysiwyg_imageupload module #1068984: wysiwyg_imageupload popup dialog broken

Perhaps it is a JavaScript or jQuery problem.

see attached screencap and module list

//addendum//

Further testing, including on clean 6.20 install, I still could not get the bridge working.

In IE8 I got the error:

Webpage error details

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; Flypaper; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; MEGAUPLOAD 3.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C)
Timestamp: Thu, 24 Feb 2011 04:15:29 UTC

Message: Syntax error
Line: 346
Char: 1
Code: 0
URI: http://example.com/sites/all/libraries/ckfinder/ckfinder/core/connector/...

so I moved ckfinder to sites/all/libraries/ckfinder/ckfinder

(top ckfinder directory contains only ckfinder library directory)

and it works - did I miss something in the docs?

jrsinclair’s picture

@decibel.places Where did you have ckfinder installed before?

decibel.places’s picture

I upgraded from using FCKeditor + its file browser in sites/all/modules to using Wysiwyg with CKeditor and CKfinder in sites/all/libraries

I disabled, uninstalled, and removed FCK before upgrading

CKfinder was not found in sites/all/libraries/ckfinder then I noticed the error above looking for it in sites/all/libraries/ckfinder/ckfinder

I noticed that after I moved CKfinder to sites/all/libraries/ckfinder/ckfinder and enabled your module bridge, the config files were created in sites/all/libraries/ckfinder and had to be moved to sites/all/libraries/ckfinder/ckfinder

justsaying

newrooky’s picture

Status: Closed (won't fix) » Needs work

Did you have any luck getting Ckfinder to recognize proper base file directories for multisite installations. It is not good practice to load everything into a single folders from al sites and would present big migration issues when we want to separate sites to different servers.

The fix in #7, as mentioned, doesn't work and will spur and error.

Anyone have ideas?

-b

TwoD’s picture

Status: Needs work » Closed (won't fix)

This is still a "won't fix" from Wysiwyg's perspective, see #6.

I have not used CKFinder so I don't know what it'll take to set it up, but posting the errors you get will make it easier for those who do to help you.

Btw, the code in #16 would be a nice to have as a sandbox project here on drupal.org. Then it'll also get its own issue queue. :)

vaccinemedia’s picture

I used the awesome module by jrsinclair at
http://www.opc.com.au/web-development/wysiwygckeditorckfinder-bridge-mod...

And had the same problem as in #21 and resolved it by changing the paths in the module file wysiwyg_ckeditor_ckfinder_bridge.module by removing the ckfinder part i.e. change line 17 from
. '/ckfinder/core/connector/php/connector.php?' to

. '/core/connector/php/connector.php?'

Makea’s picture

This definitely work with Drupal 5 with the following mod:

In the file /wysiwyg/editors/js/ckeditor-3.0.js:

Change "SetupCKEditor" to "setupCKEditor" (with a lowercase 's')

Read more about it here:
http://cksource.com/blog/CKEditor_for_jQuery

jrsinclair’s picture

@TwoD The bridging module now has its own sandbox on Drupal.org at: http://drupal.org/sandbox/jrsinclair/1348830

jrsinclair’s picture

For anyone who has been following this thread, the bridging module has been released as a full Drupal module on drupal.org. You can find it at http://drupal.org/project/WYSIWYG-CKFinder

edwinyn’s picture

@jrsinclair you're rock.. it's work. I used your bridge download from Github.
Since I use Open Atrium, I just modified the .info file to be able to be recognized on Drupal 6.x.

jrsinclair’s picture

@edwinyn If you're using the module with D6, you may want to take a look at the permissions and double check that they're working as you expect. The permissions model changed between D6 and D7 and the code for one won't work with the other :-(