When you copy text/images from a webpage and paste it into tinymce, it keeps formatting and everything is cool. However the images are linked externally. Is there any module that will automatically attach all images in the body of a node? If not, can anyone give me some tips on how best to implement this sort of function?

Thanks

Comments

vm’s picture

no. if you copy and paste the code, you would have to change the img anchors by changing the code manually. There is no module to do this. Matter of fact I think it would be difficult to do with a module. would be easier to do by hand.

theiviaxx’s picture

If you pasted in the linked images, couldn't you use a hook to creawl through the body content for Only local images are allowed. tags, download the HREF images to you /files folder, then rewrite the body content to reflect the new location?

Seems possible, but i'm not sure how to access the body content and modify it.

Would this be useful for anyone else?

theiviaxx’s picture

So after some research i got it working. However i had to edit the node.module file a bit.

sicapitan’s picture

Sounds like a nice addition :)

theiviaxx’s picture

This is the function. I have node.module call this when it validates the page. It only works for JPG and GIF and stores them as files/[Node Title]-[Image Name].EXT. I think this will work. I had to do some crazy proxy stuff so i don't quite remember the original function.

function replace_url($string, $title) {
  // Begin parsing and replacing
	if (isset($string) && (stristr($string, '<img'))) {
		// Define pattern for <img> tags
		$pattern = '/<(img)[^>]*src=([\\"\\\']?)([^>]*\.(jpg|gif))\2[^>]*>/i';
		// Get the SRC of all <IMG> tags
		preg_match_all($pattern,$string,$images);
		foreach ($images[3] as $img) {
			if (!(stristr($img, 'files'))) {				
				// Get image info
				list($width, $height, $type) = getimagesize($img);

				// Download a local copy of the image
				// If JPEG
				if ($type == 2) {
					$new_image = imagecreatetruecolor($width, $height);
					$ref_image = imagecreatefromjpeg($img);
					imagecopy($new_image, $ref_image, 0, 0, 0, 0, $width, $height);				
					if (!(file_exists('files/'.$img))) {
						imagejpeg($new_image, 'files/'.$title.'-'.$img);
					}
				}
				// if GIF
				if ($type == 1) {
					$new_image = imagecreate($width, $height);
					$ref_image = imagecreatefromgif($img);
					imagecopy($new_image, $ref_image, 0, 0, 0, 0, $width, $height);
					if (!(file_exists('files'.$img))) {
						imagegif($new_image, 'files/'.$title.'-'.$img);
					}
				}
				// Replace the href to reflect the local file
				$string = str_replace($img, 'files/'.$title.'-'.$img, $string);
			}
		}
	}

	return $string;
}

in node.module in the node_submit() function i use

// Download and convert HREF image to local
  $node->body = replace_url($node->body, $node->title);

And yes I know this is probably not the most efficient way of doing it.

dwees’s picture

Look up how to create an input filter so that hacking the core modules isn't required. This is virtually as straight forward as what you have done so far, except it doesn't require changing any of the core functions.

If you want an example of an extremely simple input filter, look at the Mathfilter.module.

Dave

g051798’s picture

I used the code above, made some tweaks for the filter and created a module called imgpaste. To use, paste code into imgpaste.module file in modules/imgpaste directory, enable, then administer/site config/input formats and enable imgpaste filter. Again, works only for external http references to images (jpg,gif). Here's the code (thanks theiviaxx):

function imgpaste_filter($op, $delta = 0, $format = -1, $text = '') {
  switch ($op) {
    case 'list':
      return array(0 => t('imgpaste: Upload Image filter'));

    case 'description':
      return t('Uploads images on copy - paste');

    case "process":
    if (isset($text) && (stristr($text, '<img'))) {
        // Define pattern for <img> tags
        $pattern = '/<(img)[^>]*src=([\\"\\\']?)(http[^>]*\.(jpg|gif))\2[^>]*>/i';
        // Get the SRC of all <IMG> tags
        preg_match_all($pattern,$text,$images);
        foreach ($images[3] as $img) {
            if (!(stristr($img, 'files'))) {

                $parse=parse_url($img);
                $filename='files/imgpaste-'.$parse[host].'-'.basename($img);

                if (!(file_exists($filename))) {
                  // Get image info
                  list($width, $height, $type) = getimagesize($img);

                  // Download a local copy of the image
                  // If JPEG
                  if ($type == 2) {
                      $new_image = imagecreatetruecolor($width, $height);
                      $ref_image = imagecreatefromjpeg($img);
                      imagecopy($new_image, $ref_image, 0, 0, 0, 0, $width, $height);
                      imagejpeg($new_image, $filename);
                  }

                  // if GIF
                  if ($type == 1) {
                      $new_image = imagecreate($width, $height);
                      $ref_image = imagecreatefromgif($img);
                      imagecopy($new_image, $ref_image, 0, 0, 0, 0, $width, $height);
                      imagegif($new_image, $filename);
                  }
                }

                // Replace the href to reflect the local file
                $text = str_replace($img, $filename, $text);
            }
        }
    }
      return $text;

    default:
      return $text;
  }
}
illuminaut’s picture

Thanks for the code, it was just what I needed. In order to make it work for me with the drupal 6 filesystem, I had to make a small modification. First, I changed the $filename to:
$filename = file_directory_path() . '/imgpaste-'.$parse[host].'-'.basename($img);
That ensured it would write the file to the correct files folder within the filesystem as opposed to trying to write it where I installed the module.
Then, when you replace the href to reflect the local file, change the $filename to file_create_url($filename)
That will form a valid URL to the new file.

Not sure if this is the proper way of doing things but it works for me and maybe it helps somebody else.

Ideally, the file location and filenaming convention should be configurable in module configuration to make this universally useful, but I'll leave that for somebody else :)

SkyConstantine’s picture

Thanks everyone for this cool filter, im using the drupal 6 filesystem. and have compiled a working filter. and for convenience sake, here is all the steps. Not sure if they are right but it works for me. So hope it helps somebody else :D

1- create folder imgpaste in drupal\modules

2- create imgpaste.info copy the code below

; $ID$
name = imagePaste
description = Allows users to copy paste image from external http references to images (jpg,gif).
It copies images from external sources and uploads into local directory 'sites\default\files\imgpaste'.
External source has to allow http request/connection. [http://drupal.org/node/107799]

; version information
version = "6.x-1.0"
core = "6.x"
project = "imagePaste"
datestamp = "1190887506"

3- create imgpaste.module copy the code below

function imgpaste_filter($op, $delta = 0, $format = -1, $text = '') {
  switch ($op) {
    case 'list':
      return array(0 => t('imgpaste: Upload Image filter'));

    case 'description':
      return t('Uploads images on copy - paste');

    case "process":
    if (isset($text) && (stristr($text, '<img'))) {
        // Define pattern for <img> tags
        $pattern = '/<(img)[^>]*src=([\\"\\\']?)(http[^>]*\.(jpg|gif))\2[^>]*>/i';
        // Get the SRC of all <IMG> tags
        preg_match_all($pattern,$text,$images);
        foreach ($images[3] as $img) {
            if (!(stristr($img, 'files'))) {

                $parse=parse_url($img);
			//Here if you want to change directory location and file name
                $filename = file_directory_path() . '/imgpaste/auto-'.$parse[host].'-'.basename($img);

                if (!(file_exists($filename))) {
                  // Get image info
                  list($width, $height, $type) = getimagesize($img);

                  // Download a local copy of the image
                  // If JPEG
                  if ($type == 2) {
                      $new_image = imagecreatetruecolor($width, $height);
                      $ref_image = imagecreatefromjpeg($img);
                      imagecopy($new_image, $ref_image, 0, 0, 0, 0, $width, $height);
                      imagejpeg($new_image, $filename);
                  }

                  // if GIF
                  if ($type == 1) {
                      $new_image = imagecreate($width, $height);
                      $ref_image = imagecreatefromgif($img);
                      imagecopy($new_image, $ref_image, 0, 0, 0, 0, $width, $height);
                      imagegif($new_image, $filename);
                  }
                }

                // Replace the href to reflect the local file
                $text = str_replace($img, file_create_url($filename), $text);
            }
        }
    }
      return $text;

    default:
      return $text;
  }
}

4- finally the readme.txt should help with how to install this module :D

DESCRIPTION

Allows users to copy paste image from external http references to images (jpg,gif).
It copies images from external sources and uploads into local directory 'sites\default\files\imgpaste'.
External source has to allow http request/connection.

Assembled by SkyConstantine ( Skychew99@gmail.com)

INSTALL

1 - To enable this module, simply upload it to your modules folder.

2 - create folder called imgpaste in 'sites\default\files\'
( see imgpaste.module if you want to change this folder )

3 - administer/site building/modules

4 - site config/input formats and enable imgpaste filter

CREDITS

This module was Assembled with information from

[http://drupal.org/node/107799]

Thanks theiviaxx for this module
Thanks dwees for suggesting to turn this into input filter
Thanks g051798 for coding it to an input filter
Thanks illuminaut for modding for better directory management

read Src for the saved forum if forum node does not exist

Have fun!

pvanerk’s picture

Is it an idea to drop this as a module on the Drupal Site. Could help other people out I think.

merakli’s picture

Can we also add support to upload the images copied/pasted from a local file? The image would be pointing to a local file location, a javascript function could parse that, detect the local file and initiate an upload.