Jump to content
modifiedcontent

Change 'choose file' image source options to include external media gallery?

Recommended Posts

Is there a way to change the input options for the images field?

I am trying to figure out if it would make sense to use an external script like Zenphoto as a central media library/manager. How could I connect that with Processwire?

'Choose File' in the images field would have to be able to open that 3rd party media library or a directory on the server or some cloud service instead of (only) the client file manager.

Could justb3a's field type module Image Extra be part of the solution? I will try that and report back. Other field types/modules?

I know there is a pro module Media Manager that does look very slick, but would prefer to make this work with a mature, tested 3rd party script if a central media gallery is never going to be a core Processwire feature.

Share this post


Link to post
Share on other sites

Hello.

7 hours ago, modifiedcontent said:

'Choose File' in the images field would have to be able to open that 3rd party media library or a directory on the server or some cloud service instead of (only) the client file manager.

There are few possible problems with centralised concept. As example, what to store in that images field? To be more clear, if some image is part of PW page only as reference link, than how can we resize it (eg. "on the fly" in page rendering process)? What would happened when someone delete image on that external point - how would ProcessWire page know that? Etc...

Because of that, if I go to build that module/field type than probably it will copy image from that external central point to ProcessWire page. With that, we can have external Media manager where we can use all it's power (organise files to folders, search etc.). Also, because we have on PW side copy of that file we can use all PW API power to manipulate with it - on PW side.

Here was few discussions why PW by default doesn't have "Media manager" like many others CMS's (I was one with that question too) but very soon undrestand that maybe because of that some other popular CMS's still doesn't have simple solution to store and generate various dimensions intro images. If some CMS's had that option, need to look closely to see how and where they store eg. that intro images... Storing concept is very important (eg. in case when need to do some export or imports).

That what you ask is completly ok, but also it's important to think about possible consequences.
What I like in centralised Media manager idea is 1 central point for file organisations, all other with that idea bring us problems and complicate things.
Regards.

Share this post


Link to post
Share on other sites

OLSA, thanks for your feedback. I personally like how Processwire handles images, but I have a client who wants a central media library.

That is why I want to create an external media library - Zenphoto in my case - and have Processwire "upload" the images from there instead of from a client OS file manager.

How can I modify 'choose file' in the image field to use other source options? Is it possible to have that open a web-based file manager of another script on the server or on a cloud service, AWS, whatever?

 

Share this post


Link to post
Share on other sites

Thanks dragan, but those threads really focus on uploading to AWS. I am looking for a way to download from an external library, instead of the client machine. I don't mind if the images are then stored/uploaded in the regular PW way.

How can I modify 'choose file' in the image field to open a file manager on a URL, instead of a client machine OS file manager?

Share this post


Link to post
Share on other sites

It's a little bit more involved that just "opening a file manager on a URL", since you have to get the necessary information back to PW, tell it to download the image in question and add it to a page field. Here's a small module that can do that, but it's little more than a starting point (no checking of that image is already there, for example, no live updating the image fields in the page editor) and that requires a rest api plugin on Zenphoto's side.

Spoiler

<?php

/**
 * Download photos from your Zenphoto galleries into your PW image fields
 * from within PW's image picker in CKEditor
 *
 * Needs zen_json_rest_api installed in Zenphoto
 * from https://github.com/deanmoses/zenphoto-json-rest-api
 * and URL Rewrite active in Zenphoto.
 *
 * Note: if you run Zenphoto on Windows, you will have to add a fix
 * to zen_json_rest_api. Edit json_rest_api and modify the dateToTimestamp
 * function according to https://github.com/deanmoses/zenphoto-json-rest-api/issues/14
 *
 * Beware: I have no clue if Permissions are honored on Zenphoto's side,
 * and no idea if introducing access control there blows things up.
 *
 * License:
 * This module is released under the WTFPL.
 * Feel free to do with this code whatever you want.
 *
 */
 

class ZenPhoto extends WireData implements Module, ConfigurableModule {

	public static function getModuleInfo() {
		return array(
			'title' => 'Zen Photo',
			'summary' => 'Allow browsing a Zenphoto installation and importing media from there. Zenphoto must have zenphoto_json_rest_api plugin active.',
			'version' => "0.0.4",
			'autoload' => true
		);
	}
	
	public function init() {
		$this->addHook("ProcessPageEditImageSelect::executeZenPicker", $this, "executeZenPicker");
		$this->addHook("ProcessPageEditImageSelect::executeZenDownload", $this, "executeZenDownload");
		$this->addHookAfter("ProcessPageEditImageSelect::execute", $this, "execute_addButton");
	}
	
	public function execute_addButton(HookEvent $event) {
		$this->initPages($event->object);

		$html = $event->return;
		
		$btn = $this->modules->get('InputfieldButton');
		$btn->href = $this->makeExecLink("picker");
		$btn->value = $this->_('Import ZenPhoto Image');
		$btn->addClass('upload pw-modal-button'); 
		$btn->icon = 'link';

		$out = $btn->render();
		
		$html = preg_replace('~</div>$~', "<p>" . $out . "</p>" . '$1', $html);
		$event->return = $html;
	}
	
	public function executeZenPicker(HookEvent $event) {
		$this->initPages($event->object);

		if(! $this->zenphotoURL) {
			$event->return = "<p><strong>" . $this->_("No Zenphoto URL configured. Go to Modules -> Configure -> Zen Photo and set a valid URL to your Zenphoto installation.");
			return;
		}

		$albumPath = $this->input->get->album;
		$url = $this->zenphotoURL;
		
		if($albumPath) {
			$url .= $albumPath;
		}
		
		$galery = "<div>";
		
		$zenGalery = $this->getJson($url);
		
		if($zenGalery !== FALSE) {
			$galery .= "<h3>" . sprintf($this->_("Albums in %s"), $albumPath ?: "/") . "</h3>" .
					"<div>";
			if($albumPath) {
				$parentAlbum = rtrim(preg_replace('~[^/]+$~', '', $albumPath), "/");
				$galery .= "<div style='width: 160px; height: 160px; display: inline-block; padding: 0.5em; vertical-align: top;'>" .
						"<a href='" . $this->makeExecLink("picker") . "&album={$parentAlbum}'>" .
						"..<br>" .
						$this->_("Return to parent album ") . "</a>" .
						"</div>";
				
			}
			foreach($zenGalery->album->albums as $album) {
				$galery .= "<div style='width: 160px; height: 160px; display: inline-block; padding: 0.5em; vertical-align: top;'>" .
						"<img style='max-width: 120px; max-height: 120px;' src='" . $album->url_thumb . "' alt='" . $album->title . "' title='" . $album->title . "'><br>" .
						"<a href='" . $this->makeExecLink("picker") . "&album={$album->path}'>" .
						$this->_("Browse album: ") . $album->title . "</a>" .
						"</div>";
			}
			if(! $zenGalery->album->albums) {
				$galery .= "<div style='width: 160px; height: 160px; display: inline-block; padding: 0.5em; vertical-align: top;'>" .
						$this->_("No child albums defined") .
						"</div>";
			}
			$galery .= "</div>" .
					"<h3>" . sprintf($this->_("Images in %s"), $albumPath ?: "/") . "</h3>" .
					"<div>";
			foreach($zenGalery->album->images as $image) {
				$galery .= "<div style='width: 160px; height: 180px; display: inline-block; padding: 0.5em; vertical-align: top;'>" .
						"<img style='max-width: 120px; max-height: 120px;' data-url='" . $image->path . "' src='" . $image->url_thumb . "' alt='" . $image->title . "' title='" . $image->title . "'><br>" .
						"<a href='" . $this->makeExecLink("download") . "&image={$image->url_full}&imagename=" . basename($image->path) . "'>" .
						$image->title . " (" . $image->width . "x" . $image->height . ") [" . strftime($this->_("%Y-%m-%d %H:%M"), $image->date) . "]</a>" .
						"</div>";
			}
		}
		$galery .= "</div>" .
				"</div>";
		
		$event->return = $galery;
	}

	private function makeExecLink($action) {
		return "./zen-" . $action . "?modal=1&id={$this->page->id}&edit_page_id={$this->editorPage->id}";
	}

	public function executeZenDownload(HookEvent $event) {
		$this->initPages($event->object);
		
		if(! $this->zenphotoURL) {
			$event->return = "<p><strong>" . $this->_("No Zenphoto URL configured. Go to Modules -> Configure -> Zen Photo and input the URL of your Zenphoto installation.");
			return;
		}

		if(! $this->input->get->assignfile) {
			// Download selected image
			$url = $this->input->get->image;
			$name = $this->input->get->imagename;
			
			if(! strlen($url) || ! strlen($name)) {
				$event->return = "<p><strong>" . $this->_("Missing parameters for image.");
				return;
			}
			
			$tempName = $this->getImage($url, $name);
			
			$toPage = $this->page ?: $this->editPage;
			
			$this->log->message("toPage = " . $toPage->id);
			
			$imageFields = array();
			foreach($toPage->template->fields as $fld) {
				if($fld->type instanceof FieldtypeImage) {
					$imageFields[] = $fld;
				}
			}
			
			$form = $this->modules->get("InputfieldForm");
			$form->label = sprintf($this->_("Add image to page %s"), $toPage->title);
			$form->action = "./zen-download";
			$form->method = "get";
			
			$f = $this->modules->get("InputfieldHidden");
			$f->attr('name', "id");
			$f->attr('value', $this->page->id);
			$form->add($f);
			
			$f = $this->modules->get("InputfieldHidden");
			$f->attr('name', "edit_page_id");
			$f->attr('value', $this->editorPage->id);
			$form->add($f);
			
			$f = $this->modules->get("InputfieldHidden");
			$f->attr('name', "topage");
			$f->attr('value', $toPage->id);
			$form->add($f);
			
			$f = $this->modules->get("InputfieldHidden");
			$f->attr('name', "tempimage");
			$f->attr('value', $tempName);
			$form->add($f);
			
			if(count($imageFields) > 1) {
				// Show a select dropdown if there is more than one possible image field
				$f = $this->modules->get("InputfieldSelect");
				$f->attr('name', 'targetField');
				$f->label = $this->_("Select target image field on page");
				foreach($imageFields as $fld) {
					$f->addOption($fld->name, $fld->label);
				}
				$f->required = true;
			} else {
				$f = $this->modules->get("InputfieldHidden");
				$f->attr('name', 'targetField');
				$f->attr('value', $imageFields[0]->name);
			}
			$form->add($f);
			
			$urlCmp = parse_url($this->zenphotoURL);
			
			$fullUrl = $urlCmp["scheme"] . "://" . $urlCmp["host"] . ":" . $urlCmp["port"] . $url;

			$f = $this->modules->get("InputfieldMarkup");
			$f->attr('value', "<img src='$fullUrl' />");
			$form->add($f);
			
			$btn = $this->modules->get("InputfieldSubmit");
			$btn->attr('name', "assignfile");
			$btn->attr('value', $this->_("Import this image"));
			$form->add($btn);
			
			$event->return = $form->render();
		} else {

			$toPage = $this->pages->get((int)$this->input->get->topage);
			$tempimage = $this->input->get->tempimage;
			$targetField = $this->sanitizer->fieldName($this->input->get->targetField);

			$toPage->of($false);
			$img = new Pageimage($toPage->{$targetField}, $tempimage);
			$toPage->{$targetField}->add($img);
			$toPage->save($targetField);
			
			unlink($tempimage);
			
			$this->session->redirect($this->config->urls->admin . "page/image/edit?modal=1&file={$toPage->id},{$img->name}&id={$toPage->id}&edit_page_id={$this->editorPage->id}");
		}
	}

	private function initPages($imageSelect) {
		$id = (int) $this->input->get->id; 
		$editID = (int) $this->input->get->edit_page_id; 
		if(! $editID) {
			$editID = $this->session->get($imageSelect, 'edit_page_id');
		}
		if($editID) {
			$this->editorPage = $this->wire('pages')->get($editID); 
		}
		if($id) {
			$this->page = $this->wire('pages')->get($id);
		}
	}

	public function getModuleConfigInputfields(array $data) {
		$inputfields = $this->wire(new InputfieldWrapper());

		$f =  $this->wire('modules')->get('InputfieldText');
		$f->attr('name', 'zenphotoURL');
		$f->label = $this->_("Zenphoto URL");
		$f->description = $this->_("Base URL of the Zenphoto installation");
		$f->attr('value', isset($data['zenphotoURL']) ? $data['zenphotoURL'] : '' );
		$inputfields->add($f);
		
		return $inputfields;
	}
	
	public function getJson($url) {

		$url = rtrim($url, "/") . "/";

		$ch = curl_init();

		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_URL, $url . "?json");

		$result = curl_exec($ch);

		curl_close($ch);

		if($result === FALSE) return $result;
		
		$decoded = json_decode($result);
		if($decoded === NULL) {
			$this->log->error(sprintf($this->_("Invalid JSON return in ZenPhoto::getJSON from %s"), $url));
			return FALSE;
		}
		
		return $decoded;
	}
	
	public function getImage($url, $name) {
		$http = new WireHTTP();
		
		$tmpname = $this->config->uploadTmpDir . $name;
		
		$urlCmp = parse_url($this->zenphotoURL);
		
		$fullUrl = $urlCmp["scheme"] . "://" . $urlCmp["host"] . ":" . $urlCmp["port"] . $url;
		
		$http->download($fullUrl, $tmpname);
		
		return $tmpname;
	}
}

 

 

  • Like 6

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By picarica
      so hello i am trying to combine my whole ass gallery with custom created watermark, i wanted to combine my images with simple text little opaque but that seemed harder and i couldnt make it work, well i cant make this work either, how are you handling watermarks? i would prefer if it would be plain PHP no imagemagick or some custom plugins scripts, but if neccesary i wont deny.
      so here's my code
      $pa = $pages->find("template=basic-page|art_gallery, images.tags!=''"); /* $pa = $pages->find("has_parent!=2,id!=2|7,status<".Page::statusTrash.",include=all"); */ echo "<div BRUUH class='row gtr-50 gtr-uniform js-filter' id='gal' >"; foreach ($pa as $p) { foreach($p->images as $image) { $obrazok = $image->url; $image = imagecreatefromjpeg($obrazok); $frame = imagecreatefromjpeg($pages->get('/settings/')->watermark->url); /* echo $image; echo $frame; */ # If you know your originals are of type PNG. imagecopymerge($image, $frame, 0, 0, 0, 0, 50, 50, 100); # Output straight to the browser. $img = imagepng($image); $options = array('quality' => 70, 'upscaling' => true, 'cropping' => 'center', 'sharpening'=>'medium'); $thumb = $img->size(400, 300, $options); $large = $img->size(1200, 0, $options); echo "<div class='$image->tags' class='col-4'>"; echo "<span style='overflow:hidden;'class='image fit'>"; echo "<a href='$large->url'>"; echo "<img class='uk-transform-origin-top-right' uk-scrollspy='cls: uk-animation-fade; repeat: false' src='$thumb->url' alt='$image->tags'>"; echo "</a>"; echo "</span>"; echo "</div>"; } };  
    • By Red Minnow
      Our website has a video banner auto loop playing on the homepage, it plays and looks fine on Safari, but in Chrome and Firefox it is running choppy and extremely pixelated. I'm unable to determine what is the root cause and have not found any other sources online that are having this occur. 
      Can be viewed at www.redminnow.com

      If you have a better way of adding video to a banner, please provide the solution or point me in the right direction. I did not develop this site, just a guy looking for a solution to provide to my PW developer. 
      Thanks, Duane
    • By Mats
      BETA: SplashAndGrab
      https://github.com/madebymats/InputfieldSplashAndGrab
      This module attaches a search input to selected image fields that lets you search and download images from Unsplash.
      (Unsplash is a stock photo service where you can download images for free and use as you wish. No strings attached.)   
      You can search by string, colors, orientation/crop and order by relevance or time published
      I find Unsplash useful both for placeholder images when building sites but also as a time saver for editors if they don’t have any images at hand, just search, download and publish.

      Thanks to @apeisa for building the  FlickrInputField Module and @Robin S for AddImageUrls,  took a lot ideas and code from those modules.
    • By horst
      Hi, on a site I want to disable access to original images and only allow to access thumbnails and watermarked image variations.
      EDIT:
      A good solution for protecting original images can be found a bit down in this thread:
       
      Old content of this initial post:
       
    • By Guy Incognito
      I seem to be running into a repeated fatal error in a fresh PW install version 3.0.148. I can't quite put my finger on the pattern but it seems to be around deleting image fields or removing images from certain image fields.
      This is the trace from the log generated by trying to save a page and delete an image from an image field:
      Fatal Error: Uncaught Error: Cannot access protected property Pageimage::$original in /wire/core/PageimageVariations.php:256 Stack trace: 1. /wire/core/Pageimage.php(1327): PageimageVariations->getInfo() 2. /wire/core/Wire.php(386): Pageimage->___isVariation() 3. /wire/core/WireHooks.php(823): Wire->_callMethod() 4. /wire/core/Wire.php(450): WireHooks->runHooks() 5. /wire/core/Pageimage.php(1369): Wire->__call() 6. /wire/core/Pageimage.php(399): Pageimage->getOriginal() 7. /wire/core/WireData.php(333): Pageimage->get() 8. /wire/core/PageimageVariations.php(256): Pro Line 256 of /wire/core/PageimageVariations.php Earlier in the day I was experimenting with custom fields for images for the first time and kept running into this error, thinking it was me using this feature wrong and not having time to read up I deleted the custom image fields template and went about my business. So now I don't know if I triggered an issue or whether it was never related to the custom image fields in the first place?
      Any ideas?
×
×
  • Create New...