Skip to content

Instantly share code, notes, and snippets.

@landsman
Last active September 15, 2016 15:14
Show Gist options
  • Save landsman/56a14993964f05a2fe469a629d79639c to your computer and use it in GitHub Desktop.
Save landsman/56a14993964f05a2fe469a629d79639c to your computer and use it in GitHub Desktop.
Prace s obrazkem uvnitr formulare bez manual render
Uvnir formulare:
ImageUpload::AddInput($form, "someImage", "Obrázek", true);
Pri zpracovani:
ImageUpload::Process($values, "someImage", "/img/obrazky/", true);
<?php
namespace Nette\Forms\Controls;
use App\Components\Imager;
use Nette;
use Nette\Http\FileUpload;
use Nette\Utils\Html;
/**
* Text box and browse button that allow users to select a file to upload to the server.
*/
class ImageUploadControl extends BaseControl
{
/**
* @var string
*/
public $value;
/**
* @var int
*/
private $width = 150;
/**
* @var int
*/
private $height = 150;
/**
* @var bool
*/
private $allowDelete;
/**
* ImageUploadControl constructor.
* ImageUploadControl constructor.
* @param null $label
* @param $allowDelete
* @param $width
* @param $height
*/
public function __construct($label = NULL, $allowDelete, $width, $height)
{
parent::__construct($label);
$this->control->type = 'file';
$this->control->multiple = false;
$this->allowDelete = (bool) $allowDelete;
$this->width = $width;
$this->height = $height;
}
/**
* This method will be called when the component (or component's parent)
* becomes attached to a monitored object. Do not call this method yourself.
* @param Nette\ComponentModel\IComponent
* @return void
*/
protected function attached($form)
{
if ($form instanceof Nette\Forms\Form) {
if ($form->getMethod() !== Nette\Forms\Form::POST) {
throw new Nette\InvalidStateException('File upload requires method POST.');
}
$form->getElementPrototype()->enctype = 'multipart/form-data';
}
parent::attached($form);
}
/**
* Loads HTTP data.
* @return void
*/
public function loadHttpData()
{
$this->value = $this->getHttpData(Nette\Forms\Form::DATA_FILE);
if ($this->value === NULL) {
$this->value = new FileUpload(NULL);
}
}
/**
* Returns HTML name of control.
* @return string
*/
public function getHtmlName()
{
return parent::getHtmlName() . ($this->control->multiple ? '[]' : '');
}
/**
* @return self
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* Has been any file uploaded?
* @return bool
*/
public function isFilled()
{
return $this->value instanceof FileUpload ? $this->value->isOk() : (bool) $this->value; // ignore NULL object
}
/**
* Generates control's HTML element.
* @param string
* @return Nette\Utils\Html
*/
public function getControl($caption = NULL)
{
$this->setOption('rendered', TRUE);
$wrapper = Html::el('div', ['class' => 'well iUploader']);
$output = $wrapper->startTag();
// PICTURE IS EXIST
if($this->value)
{
$original = (strpos($this->value, ":") === false ? '.' . $this->value : $this->value);
$thumb = Imager::getThumbnail($this->value, $this->width, $this->height);
$link = Html::el('a',
[
'id' => $this->getHtmlName(),
'href' => $original,
'target' => '_blank',
'class' => 'lightbox'
]
);
if(strpos($this->value, ".svg") !== false) {
$content = file_exists(WWW_DIR . $this->value) && !is_dir(WWW_DIR . $this->value) ? file_get_contents(WWW_DIR . $this->value) : "";
$img = Html::el('div',["class" => "svg-wrappper"])->setHtml($content);
}
else {
$img = Html::el('img',
[
'src' => $thumb,
'class' => 'img-thumbnail'
]
);
}
$output.= $link->startTag() . $img . $link->endTag();
}
// DELETE
if($this->value && $this->allowDelete)
{
$wrapperD = Html::el('div');
$label = Html::el('label',
[
'style' => 'margin-right: 5px'
]
);
$title = Html::el('span')->setText(' Smazat obrázek'); // todo: multilanguage?
$checkbox = Html::el('input',
[
'type' => 'checkbox',
'name' => 'deleteImage_' . $this->getHtmlName(),
'class' => 'styled'
]
);
$output.= $wrapperD->startTag() . $label->startTag() . $checkbox . $title . $label->endTag() . $wrapperD->endTag();
}
$file = Html::el('input',
[
'type' => 'file',
'name' => $this->getHtmlName(),
'class' => 'form-control'
]
);
$output.= $file . $wrapper->endTag();
return $output;
}
}
<?php
namespace App\Components;
use Nette;
/**
* Class ImageUpload
* @package App\Components
*/
class ImageUpload extends Nette\Object
{
/**
* @param $values
* @param $name
* @param $uploadPath
* @param bool $useTimestamp
* @param null $container
*/
public static function Process(&$values, $name, $uploadPath, $useTimestamp = false, $container = null)
{
/**
* checkbox delete
*/
$delete = $container ? $_POST["deleteImage_{$container}"][$name] : $_POST["deleteImage_{$name}"];
if (isset($delete) && $delete)
{
$values[$name] = "";
}
elseif ($values[$name]->name == "")
{
unset($values[$name]);
}
else
{
/**
* upload
*/
$imgUrl = $uploadPath . "/" . ($useTimestamp) ? time() . "_" : "" . $values[$name]->name;
$values[$name]->move(WWW_DIR . "/" . $imgUrl);
$values[$name] = $imgUrl;
}
}
/**
* @param $form
* @param $name
* @param $label
* @param bool $allow_delete
* @param int $width
* @param int $height
* @return Nette\Forms\Controls\BaseControl
*/
public static function AddInput(&$form, $name, $label, $allow_delete = true, $width = 225, $height = 150)
{
$form[$name] = new Nette\Forms\Controls\ImageUploadControl($label, $allow_delete, $width, $height);
return $form[$name];
}
}
<?php
namespace App\Components;
use Doctrine\Common\Util\Debug;
use Nette;
use Nette\Utils\Image;
use Tracy\Debugger;
class Imager
{
/**
* @var string
*/
private static $THUMBS_RELATIVE_PATH = "./img/thumbs";
/**
* @var string
*/
private static $THUMBS_ABSOLUTE_PATH = WWW_DIR . "/img/thumbs";
/**
* @param $end
* @return mixed|null
*/
private static function getType($end)
{
$types = ["png" => Image::PNG, "jpg" => Image::JPEG, "jpeg" => Image::JPEG, "gif" => Image::GIF];
return isset($types[$end]) ? $types[$end] : null;
}
/**
* @param $file
* @param int $width
* @param int $height
* @param bool $reload
* @return string
* @throws Nette\Utils\UnknownImageFileException
* @throws \Exception
*/
public static function getThumbnail($file, $width = 90, $height = 90, $reload = false)
{
if(!file_exists(self::$THUMBS_ABSOLUTE_PATH))
{
mkdir(self::$THUMBS_ABSOLUTE_PATH);
}
if(strpos($file, ":") === false)
{
return self::getLocalThumbnail($file, $width, $height, $reload);
}
else
{
return self::getRemoteThumbnail($file, $width, $height, $reload);
}
}
/**
* @param $file
* @param $width
* @param $height
* @param $reload
* @return string
* @throws Nette\Utils\UnknownImageFileException
* @throws \Exception
*/
private static function getLocalThumbnail($file, $width, $height, $reload)
{
if(!$file) $file = "/img/none.png";
$ext = pathinfo($file)["extension"];
$hash = md5($file) . '_' . ($width."_".$height) . "." . $ext;
$local_file = WWW_DIR . $file;
// if exists original local file
if(file_exists($local_file))
{
if(in_array(strtolower($ext), ["png", "jpg", "jpeg", "gif"])) {
// if not exist thumb
if (!file_exists(self::$THUMBS_ABSOLUTE_PATH . "/" . $hash) || $reload) {
try {
$image = Image::fromFile($local_file);
$image->resize($width, $height, Image::SHRINK_ONLY | Image::STRETCH);
$image->save(self::$THUMBS_ABSOLUTE_PATH . "/" . $hash, 100, self::getType($ext));
}
catch(\Exception $e) {
}
}
}
elseif($ext == "svg") {
}
}
else
{
//throw new \Exception("File in '{$local_file}' not exists!");
return "";
}
// return relative path to file
return self::$THUMBS_RELATIVE_PATH . "/" . $hash;
}
/**
* @param $file
* @param $width
* @param $height
* @param $reload
* @return string
*/
private static function getRemoteThumbnail($file, $width, $height, $reload)
{
if(!$file) $file = "/img/none.png";
$ext = pathinfo($file)["extension"];
$hash = md5($file) . '_' . ($width."_".$height) . "." . $ext;
$local_path = self::$THUMBS_ABSOLUTE_PATH . "/remote/";
$local_file = $local_path . $hash;
// if not exists folder
if (!file_exists($local_path))
{
mkdir($local_path, 0777, true);
}
// if not exists local copy
if(!file_exists($local_file) || $reload)
{
Imager::downloadImage($file, $local_file);
}
// create thumb
return self::getLocalThumbnail("/img/thumbs/remote/" . $hash, $width, $height, $reload);
}
/**
* @param $imageUrl
* @param $imageFile
*/
public static function downloadImage($imageUrl, $imageFile){
if(file_exists($imageFile) && self::compareImages($imageFile, $imageUrl)) {
return;
}
$fp = fopen ($imageFile, 'w+');
$ch = curl_init($imageUrl);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 1000);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0');
curl_exec($ch);
curl_close($ch);
fclose($fp);
}
/**
* @param $localFile
* @param $remoteFile
* @return bool
*/
public static function compareImages($localFile, $remoteFile)
{
$curl = curl_init($remoteFile);
curl_setopt($curl, CURLOPT_NOBODY, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0');
$data = curl_exec($curl);
curl_close($curl);
if ($data) {
$content_length = 0;
$status = 0;
if (preg_match("/^HTTP\/1\.[01] (\d\d\d)/", $data, $matches)) $status = (int)$matches[1];
if (preg_match("/Content-Length: (\d+)/", $data, $matches)) $content_length = (int)$matches[1];
if ($status == 200 || ($status > 300 && $status <= 308)) {
return filesize($localFile) == $content_length;
}
}
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment