Фотосет - добавить изображение по сылке

Не всега удобно загружать фото в фотосет если фотки например на удаленном сайте. При такой задаче сначала нужно слить фотки на комп а потом уже грузить в фотосет, что не всегда удобно.

Данный хак позволяет сделать загрузку фото в фотосет по URL фотографии (мультизагрузки нет)


Весь пример показан на шаблоне new-jquery, на других шаблонах не проверял

Для начала сделаем нужные js функции.
Открываем файл \templates\skin\new-jquery\js\photoset.js
перед
this.showMainPhoto = function(id) {

добавляем
this.showFormLink = function()
	{
		var $select = $('#photoset-start-upload-link');
		if ($select.length) {
			var pos = $select.offset();
			w = $select.outerWidth();
			h = $select.outerHeight();
			t = pos.top + h - 30  + 'px';
			l = pos.left - 15 + 'px';
			$('#photoset-upload-form-link').css({'top':t,'left':l});
		}
		$('#photoset-upload-form-link').show();
	}

	this.uploadLink = function()
	{
		var img = $('#photoset-upload-link').val();
		ls.photoset.addPhotoEmpty();
		ls.ajax(aRouter['photoset']+'upload/',{img:img},function(data){
			if (data.bStateError) {
				$('#photoset_photo_empty').remove();
				ls.msg.error(data.sMsgTitle,data.sMsg);
			} else {
				ls.photoset.addPhoto(data);
			}
		});
		ls.photoset.closeForm();
	}


после
this.closeForm = function()
	{
		$('#photoset-upload-form').hide();

добавляем
$('#photoset-upload-form-link').hide();

Далее стиль для формы с URL:
в \templates\skin\new-jquery\css\topic.css
добавляем
#photoset-upload-form-link {
	width: 270px; 
	padding: 15px;
	position: absolute;
	top:70%;
	display: none;
	background-color: #fff; 
	border: 1px solid #ccc; 
	-moz-box-shadow: 0 0 10px #ddd;
	-webkit-box-shadow: 0 0 10px #ddd;
	box-shadow: 0 0 10px #ddd;
}

Ну и сама форма для URL изображения:
в \templates\skin\new-jquery\actions\ActionPhotoset\add.tpl
перед
{hook run='add_topic_photoset_begin'}
добавляем
<form id="photoset-upload-form-link" method="POST" enctype="multipart/form-data" onsubmit="return false;">
            <p id="topic-photo-upload-input-link" class="topic-photo-upload-input">
                <label for="">{$aLang.topic_photoset_choose_image}:</label><br />
		<input type="text" name="photoset-upload-link" id="photoset-upload-link" value="" />

		
                <button onclick="ls.photoset.uploadLink();">{$aLang.topic_photoset_upload}</button>
                <button onclick="ls.photoset.closeForm();">{$aLang.topic_photoset_upload_close}</button>
                <input type="hidden" name="is_iframe" value="false" />
                <input type="hidden" name="topic_id" value="{$_aRequest.topic_id}" />
            </p>
        </form>

и перед
<a href="javascript:ls.photoset.showForm()" id="photoset-start-upload">{$aLang.topic_photoset_upload_choose}</a>
добавляем
<a href="#" onclick="ls.photoset.showFormLink(); return false;" id="photoset-start-upload-link">{$aLang.topic_photoset_upload_choose_link}</a>
			<br />{$aLang.or}<br />

И в текстовки добавим пару строк
файл \templates\language\russian.php
'topic_photoset_upload_choose_link' => 'Загрузить фото по ссылке', ////////// new
	'topic_photoset_choose_image_link' => 'Введите ссылку для загрузки', ////////// new
	'topic_photoset_upload' => 'Загрузить', ////////// new

Теперь в модуль топиков добавим функцию загрузки изображения по URL
в файл \classes\modules\topic\Topic.class.php добавляем функцию
/**
	 * Загрузка изображений в фотосет по переданному URL
	 *
	 * @param  string          $sUrl
	 * @param  ModuleUser_EntityUser $oUser
	 * @return (string|bool)
	 */
	public function UploadTopicImagePhotoUrl($sUrl, $oUser) {
		/**
		 * Проверяем, является ли файл изображением
		 */
		if(!@getimagesize($sUrl)) {
			return ModuleImage::UPLOAD_IMAGE_ERROR_TYPE;
		}
		/**
		 * Открываем файловый поток и считываем файл поблочно,
		 * контролируя максимальный размер изображения
		 */
		$oFile=fopen($sUrl,'r');
		if(!$oFile) {
			return ModuleImage::UPLOAD_IMAGE_ERROR_READ;
		}
		
		$iMaxSizeKb=Config::Get('view.img_max_size_url');
		$iSizeKb=0;
		$sContent='';
		while (!feof($oFile) and $iSizeKb<$iMaxSizeKb) {
			$sContent.=fread($oFile ,1024*1);
			$iSizeKb++;
		}

		/**
		 * Если конец файла не достигнут,
		 * значит файл имеет недопустимый размер
		 */
		if(!feof($oFile)) {
			return ModuleImage::UPLOAD_IMAGE_ERROR_SIZE;
		}
		fclose($oFile);

		/**
		 * Создаем tmp-файл, для временного хранения изображения
		 */
		$sFileName = func_generator(10);
		$sFileTmp=Config::Get('sys.cache.dir').func_generator();
		
		
		
		$fp=fopen($sFileTmp,'w');
		fwrite($fp,$sContent);
		fclose($fp);
		
		$sDirSave=Config::Get('path.uploads.images').'/topic/'.date('Y/m/d').'/';//$this->Image_GetIdDir($oUser->getId());
		$aParams=$this->Image_BuildParams('topic');
		
		/**
		 * Передаем изображение на обработку
		 */
		if ($sFile=$this->Image_Resize($sFileTmp,$sDirSave,$sFileName,Config::Get('view.img_max_width'),Config::Get('view.img_max_height'),Config::Get('view.img_resize_width'),null,true,$aParams)) {
			@unlink($sFileTmp);

			$aSizes=Config::Get('module.topic.photoset.size');
			foreach ($aSizes as $aSize) {
				// Для каждого указанного в конфиге размера генерируем картинку
				$sNewFileName = $sFileName.'_'.$aSize['w'];
				$oImage = new LiveImage($sFile);
				if ($aSize['crop']) {
					$this->Image_CropProportion($oImage, $aSize['w'], $aSize['h'], true);
					$sNewFileName .= 'crop';
				}
				$this->Image_Resize($sFile,$sDirSave,$sNewFileName,Config::Get('view.img_max_width'),Config::Get('view.img_max_height'),$aSize['w'],$aSize['h'],true,$aParams,$oImage);
			}
			return $this->Image_GetWebPath($sFile);
		} 		
		
		@unlink($sFileTmp);
		return ModuleImage::UPLOAD_IMAGE_ERROR;
	}
И в заключении нужно внести добавления в экшен загрузки фотосета. Привожу функцию полносью ибо лениво по деталькам расписывать :)
в \classes\actions\ActionPhotoset.class.php функцию protected function EventUpload() { заменяем на
protected function EventUpload() {
		// В зависимости от типа загрузчика устанавливается тип ответа
		if (getRequest('is_iframe')) {
			$this->Viewer_SetResponseAjax('jsonIframe', false);
		} else {
			$this->Viewer_SetResponseAjax('json');
		}
				
		/**
		 * Проверяем авторизован ли юзер
		 */
		if (!$this->User_IsAuthorization()) {
			$this->Message_AddErrorSingle($this->Lang_Get('not_access'),$this->Lang_Get('error'));
			return Router::Action('error');
		}
		
		$sImg = getRequest('img');
	
		if (empty($sImg) and !isset($_FILES['Filedata']['tmp_name'])) {
			$this->Message_AddError($this->Lang_Get('system_error'), $this->Lang_Get('error'));
			return false;
		}

		$iTopicId = getRequest('topic_id');
		$sTargetId = null;
		$iCountPhotos = 0;
		// Если от сервера не пришёл id топика, то пытаемся определить временный код для нового топика. Если и его нет. то это ошибка
		if (!$iTopicId) {
			$sTargetId = empty($_COOKIE['ls_photoset_target_tmp']) ? getRequest('ls_photoset_target_tmp') : $_COOKIE['ls_photoset_target_tmp'];
			if (!$sTargetId) {
				$this->Message_AddError($this->Lang_Get('system_error'), $this->Lang_Get('error'));
				return false;
			}
			$iCountPhotos = $this->Topic_getCountPhotosByTargetTmp($sTargetId);
		} else {
			/**
			 * Загрузка фото к уже существующему топику
			 */
			$oTopic = $this->Topic_getTopicById($iTopicId);
			if (!$oTopic or !$this->ACL_IsAllowEditTopic($oTopic,$this->oUserCurrent)) {
				$this->Message_AddError($this->Lang_Get('system_error'), $this->Lang_Get('error'));
				return false;
			}
			$iCountPhotos = $this->Topic_getCountPhotosByTopicId($iTopicId);
		}
		/**
		 * Максимальное количество фото в топике
		 */
		if ($iCountPhotos >= Config::Get('module.topic.photoset.count_photos_max')) {
			$this->Message_AddError($this->Lang_Get('topic_photoset_error_too_much_photos', array('MAX' => Config::Get('module.topic.photoset.count_photos_max'))), $this->Lang_Get('error'));
			return false;
		}
		/**
		 * Максимальный размер фото
		 */
		if (empty($sImg) and (!empty($_FILES['Filedata']) and filesize($_FILES['Filedata']['tmp_name']) > Config::Get('module.topic.photoset.photo_max_size')*1024)) {
			$this->Message_AddError($this->Lang_Get('topic_photoset_error_bad_filesize', array('MAX' => Config::Get('module.topic.photoset.photo_max_size'))), $this->Lang_Get('error'));
			return false;
		}
		/**
		 * Загружаем файл
		 */
		//print_r($sImg);
		if (empty($sImg)) 
		    $sFile = $this->Topic_UploadTopicPhoto($_FILES['Filedata']);
		elseif ($_REQUEST['img']!='' && $_REQUEST['img']!='http://'){
		    $sFile=$this->Topic_UploadTopicImagePhotoUrl($_REQUEST['img'],$this->oUserCurrent);
			switch (true) {
				case is_string($sFile):

					break;

				case ($sFile==ModuleImage::UPLOAD_IMAGE_ERROR_READ):
					$this->Message_AddErrorSingle($this->Lang_Get('uploadimg_url_error_read'),$this->Lang_Get('error'));
					return;

				case ($sFile==ModuleImage::UPLOAD_IMAGE_ERROR_SIZE):
					$this->Message_AddErrorSingle($this->Lang_Get('uploadimg_url_error_size'),$this->Lang_Get('error'));
					return;

				case ($sFile==ModuleImage::UPLOAD_IMAGE_ERROR_TYPE):
					$this->Message_AddErrorSingle($this->Lang_Get('uploadimg_url_error_type'),$this->Lang_Get('error'));
					return;

				default:
				case ($sFile==ModuleImage::UPLOAD_IMAGE_ERROR):
					$this->Message_AddErrorSingle($this->Lang_Get('uploadimg_url_error'),$this->Lang_Get('error'));
					return;
			}		    
		}

		if ($sFile) {
			/**
			 * Создаем фото
			 */
			$oPhoto = Engine::GetEntity('Topic_TopicPhoto');
			$oPhoto->setPath($sFile);
			if ($iTopicId) {
				$oPhoto->setTopicId($iTopicId);
			} else {
				$oPhoto->setTargetTmp($sTargetId);
			}
			if ($oPhoto = $this->Topic_addTopicPhoto($oPhoto)) {
				// если редактируем топик, то обновляем число фоток в нём
				if (isset($oTopic)) {
					$oTopic->setPhotosetCount($oTopic->getPhotosetCount()+1);
					$this->Topic_UpdateTopic($oTopic);
				}

				$this->Viewer_AssignAjax('file', $oPhoto->getWebPath('80crop'));
				$this->Viewer_AssignAjax('id', $oPhoto->getId());
				$this->Message_AddNotice($this->Lang_Get('topic_photoset_photo_added'), $this->Lang_Get('attention'));
			} else {
				$this->Message_AddError($this->Lang_Get('system_error'), $this->Lang_Get('error'));
			}
		} else {
			$this->Message_AddError($this->Lang_Get('system_error'), $this->Lang_Get('error'));
		}
	}


Собстно все, сбрасываем кеши и радуемся.

PS:: Для желающих упаковать в плагин — на авторство не претендую.

3 комментария

avatar
Спасибо. Проверим. А то действительно фотки только с компа, неудобно иногда!
avatar
давно ждал на такую фишку
  • xlop
  • 0
avatar
собрал с помощью netlanc'a, пока на модерации livestreetcms.com/addons/view/292/
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.