Загрузка фото через Formlister

Всем привет.

Вопрос следущий. Хочу при создании страницы через FormLister загружать фотографии. Несколько.

В форме указываю
<input class="form-control" type="file" name="userpic[]">
<input class="form-control" type="file" name="userpic[]">


&prepareProcess=`userPhoto`


<?php
$files = $FormLister->getFormData('files');//получаем массив с загруженными файлами
if (isset($files['userpic']) && $files['userpic']['error'] === 0) {
$dir = 'test/uploads/'; //задаем папку для хранения пользовательских фото
$j = 0; //Переменная для нумерации загруженных файлов	    
for ($i = 0; $i < count($files['file']['name']); $i++) {//цикл для получения отдельного элемента из массива
$validextensions = array("jpeg", "jpg", "png");  //Extensions which are allowed
$filename = $FormLister->fs->takeFileName($files['userpic']['name']);//имя загруженного файла, без расширения
$ext = $FormLister->fs->takeFileExt($files['userpic']['name']);//расширение отдельно
$filename = $modx->stripAlias($filename).'.'.$ext;//транслитерация названия + расширение
$filename = $FormLister->fs->getInexistantFilename($dir.$filename,true);//получаем предполагаемый путь к файлу, при необходимости переименовываем, чтобы не затереть файл с таким же именем
$FormLister->fs->makeDir($dir) && move_uploaded_file($files['userpic']['tmp_name'],$filename)//пытаемся переместить файл в нужное место
$j = $j + 1;
}
	if (($files["file"]["size"][$i] < 100000) //размер фото
                && in_array($ext, $validextensions)) {
            if (move_uploaded_file($files['file']['tmp_name'][$i], $dir)) {//Если файлы перенесены
                echo $j. ').Фото загружены

';
            } else {//Если фото не перенесены
                echo $j. ').Попробуйте снова

';
            }
        } else {//ели размер болше определенного
            echo $j. ').Фото слишком большое

';
        }
    }
}


Пока не работает. вылезает ошибка
Error : syntax error, unexpected '$j' (T_VARIABLE)

я так понимаю, что где-то нет ";" но не могу понять где

либо я вообще все неверно делаю?

также дальше хочу сделать следующее — при загрузке формы будет создаваться временная папка, куда будут грузиться фотографии и после прохождения валидация формы папка будет переименовываться — название папки будет как id создаваемого документа

Вопросы:
1. почему не загружаются файлы. Я так понимаю я где-то косячку, но не понимаю где
2. логика создания, загрузки и переименовывания папки насколько корректная?

Заранее спасибо

6 комментариев

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

&attachments= `userpic`
&fileRules = `{
	"userpic":{
		"optional":"Не удалось загрузить файл",
		"maxSize" : {
			"params": 5120,
			"message": "Размер файла не должен превышать 5 мб"
		},
		"allowed": {
			"params": [ ["jpg","jpeg","png","gif", "bmp"] ],
			"message" : "Разрешены только картинки"
		},
		"maxCount":{
			"params" : 11,
			"message" : "Не больше 10 картинок"
		}
	}
}`

Дальше уже думать, что сделать с файлами.

$dir = 'assets/images/temporary/';
$files = $FormLister->getFormData('files');

if (isset($files['userpic']) && $files['userpic'][0]['error']===0){
	for($key=0;$key<count($files['userpic']);$key++){
		if($files['userpic'][$key]['error'] === 0){
			//получаем имя загруженного файла, без расширения
			$filename = $FormLister->fs->takeFileName($files['userpic'][$key]['name']);			
			//расширение отдельно
			$ext = $FormLister->fs->takeFileExt($files['userpic'][$key]['name']);
			//делаем транслитерацию имени файла, добавляем к нему расширение
			$filename = $modx->stripAlias($filename).'.'.$ext;
			//получаем предполагаемый путь к файлу, при необходимости переименовываем, чтобы не затереть файл с таким же именем

			$filename = $FormLister->fs->getInexistantFilename($dir.$filename,true);
			//пытаемся переместить файл в нужное место
			if ($FormLister->fs->makeDir($dir) && move_uploaded_file($files['userpic'][$key]['tmp_name'],$filename)) {
			//если всё ок, можно юзать поле. Например так. Или вообще вставить в тв, мультитв...
                        $FormLister->setField('photo',$FormLister->fs->relativePath($filename));
			}
		}
	}


}
return $data;

Но вообще идеальный вариант это аякс-загрузка файлов на этапе заполнения формы. А передавать только айди загруженных файлов (из таблицы, скажем).
  • 1px
  • +2
avatar
большое спасибо! круто

про аякс — я правильно понимаю, что если форма будет заполнена, загружены фото, а потом форма не будет отправлена, то фотки на сайте будут, а страницы не будет?
avatar
Да. Поэтому обычно их грузят в какую-то /tmp/ папку, которую чистят кроном раз в неделю.
avatar
и еще вопрос
правильно ли я понимаю, что при создании документа пользователем:
сначала выводится форма
она заполняется, добавляются файлы (они еще ен грузятся)
затем форма обрабатывается, создается документ в древе документов
затем физически загружаются файлы

если так, то как в сниппет из prepareprocess передать id созданного документа?
$var=$date[id]


основная идея — создавать папку с id создаваемого документа и туда грузить файлы

но я не пойму, что происходит сначала — создается документ или грузятся файлы
avatar
Никогда не задумывался над последовательностью, однако похожую штуку решал.
На событие prepareAfterProcess вешал свой сниппет. В нём получал айди созданного дока через $data['id']. Номера и имена файлов, которые я через аякс заливал, у меня были на этапе обработки формы сунуты в поле через запятую. Некорректно немного, лучше бы сделать массив input'ов.

Соответственно, я получал айди файлов уже по факту в переменной $data['nums']. Делал выборку из таблицы номер=файл, получал путь, имя.
Далее создавал папку с номером дока и копировал туда файлы. Также писал значение этого дела в мультитв у созданного ресурса, чтобы можно было и с бэка редактировать.
Что да как уже не помню (особенно, зачем там $parent), но поглядите и поправьте под себя.


<?php
$upload_path = MODX_BASE_PATH . "assets/images/temporary/";
$tvTable = $modx->getFullTableName('site_tmplvar_contentvalues');
$files_table = $tvTable = $modx->getFullTableName('userfiles');
$id = $data['id'];

if( $id && $data['nums']){
	$dir = 'assets/images/o/id_' . $id . '/';
	if(!is_dir($dir)){
		mkdir($dir, 0755);
	}
	$tvValue = array(
		'fieldValue' => [],
		'fieldSettings' => array("autoincrement" => 1)
	);
	
	$q = $modx->db->query('SELECT * FROM '. $files_table . ' WHERE `id` IN (' . $data['nums'] . ') ORDER BY `sort` ASC');
	
	while ($row = $modx->db->getRow($q)){	
		$temp_file_name = $upload_path . $row['file'];
		$temp_file_name_small = $upload_path . $row['thumb'];
		$new_filename = $dir . $row['file'];
		$new_filename_small = $dir . $row['thumb'];
		if($row['parent']==0){
			if(copy($temp_file_name, MODX_BASE_PATH . $new_filename) && copy($temp_file_name_small, MODX_BASE_PATH . $new_filename_small)){				
				unlink($temp_file_name);
				unlink($temp_file_name_small);
				$fields = array(
					'parent' => $id
				);
				$modx->db->update($fields, $files_table,"id=" . $row['id']);
				$tvValue['fieldValue'][] = array(
					"image" => $new_filename,
					"thumb" => $new_filename_small
				);
			}
		}
		else{
			$tvValue['fieldValue'][] = array(
				"image" => $new_filename,
				"thumb" => $new_filename_small
			);	
		}
	}
	$tvval = json_encode($tvValue, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES );	
	include_once(MODX_BASE_PATH."assets/lib/MODxAPI/modResource.php");
	$doc = new modResource($modx);
	$doc->edit($id);
	$doc->set('ads_multiphotos', $tvval);
	$doc->set('nums', $data['nums']);
	$id = $doc->save(false, true);
}

avatar
Большое спасибо!

я совмести все вместе и решил проблему свою
prepareAfterProcess срабатывает после нажатия кнопки, при этом сначала создается документ, потом можно можно получить id этого документа и уже потом зная id создать папку с этим id и туда загрузить фотографии из этой же формы
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.