Aliaksandr
Написал обертку для доклистера в пять строк с построением стандартного фильтра из гет/пост - вот и весь фильтр пользователей:)
Aliaksandr
Aliaksandr
Возможные значения писать не обязательно
Alexey
Если я был в отпуске, это не значит что я не смотрел в чат) есть у нас таких много: смотрят, но ничо не пишут)
Рад был проявлению активности Жени, который для меня светило. Рад был новым тендециям. Разработку 2.0 вообще "на ура" встречаю. Но от меня в разработке мало толку)
Кто я? Что я? Лишь мечтатель, синь очей утративший во мгле,
И модиксер я довольно сранный, заодно с другими на земле)
Alexey
Да и отпуск для меня это почти равно запою. Так что вышел из отпуска = вышел из запоя)
Aliaksandr
У кого под рукой есть сайт с относительно свежей еформ?
RS
Добрый день. Нужна помощь по сайту. На мод х. Вопросы в личку.
Pathologic
/top@Axenia_Bot
Andrey
Aliaksandr
У меня вроде был
Там если на странице с формой нажать ф5 все работает нормально?
Anonymous
Pathologic
😸
Dark
Ага ему 😊
Котиков все любят, вон сколько плюсов у тааврища :)
RS
Прошу прощения. Исправлюсь. Требуется помощь по сайту. На мод х. Версия evo. 1.0 точнее не помню. Загрузила проц. Админ сказал что рассылает спам. С сервера убрал. Нужно почистить от вредоносного кода. Либо закрыть дыры. Логов не осталось. Работа за деньги. Есть сервер. Бэкап сайта.
Dark
Уже лучше.
Вот немного информации по чистке сайта.
http://modx.im/blog/fast-solution/5506.html
Evgeniy
RS
Прошу прощения. Ещё одно уточнение. Сам не сделаю так как не силен в этом. С джумлой ещё как то справляюсь. А это сложно. Поэтому нужен спец.
RS
Найти спеца по работе который выполнет работу за $
Dmytro
Evgeniy
Andrey
Никто не знает библиотечки js, которая могла бы грузить файлы, показывать превьюхи и, самое главное, можно было бы менять их порядок?
Dmytro
dropzone
Dmytro
http://www.dropzonejs.com
Dmytro
Вот на ней делал + simpleGallery
http://velodom.com.ua
Dmytro
Кста тут как раз пользователи в Дереве 🙂
Andrey
На неё и смотрю, но вроде там нет перетаскивания.
Pathologic
FileAPI и sortable
Andrey
Разве что темизировать превьюхи и навешать на него sortable от ойгукн
Andrey
jquery
Andrey
FileAPI и sortable
http://rubaxa.github.io/jquery.fileapi/
Уже кто-то плагин нафигачил похоже.
Pathologic
плагин заброшен, да и без него нормально
Andrey
Загрузку с фронта попросили сделать. С аяксами...
Pathologic
а куда потом эти файлы?
Andrey
Файлы в мультиТВ потом
Andrey
Формлистер там)
Andrey
Ну такая там система. Разницы-то особой нет ведь.
Aliaksandr
Та же фиговина от рубахи https://github.com/mailru/FileAPI вроде не сильно и заброшена:)
Andrey
Пока думаю над временной папкой, файлы в сессию и по событию в формлистере файлы утаскивать на место.
Pathologic
отдельная папка + таблица
Pathologic
сессия не нужна
Andrey
И на prepareAfterProcess?
Pathologic
да
Andrey
Таблица-то зачем?
Pathologic
чтобы удалять файлы не при делах
Pathologic
типа загрузил человек и тут его избили до того как он форму отправил
Pathologic
а файлы-то уже на сервере
Andrey
А... Ну а чем плох способ грузить во вр. папку и удалять кроном?
Pathologic
тем что из таблицы проще выбрать файлы старше какого-то срока
Andrey
Ну и для порядка можно... Типа удалить точно неиспользуемые, или ещё что-то. Заприватить имена файов можно наверное ещё файлы, хотя такой задачи нет
Pathologic
<?php
switch ($name) {
case 'prepare':
if (!empty($photo = $FormLister->getField('photo'))) {
if (!is_array($photo)) $photo = array();
$out = '';
$hashes = array();
foreach ($photo as $item) {
if ($item) $hashes[] = "'{$item}'";
}
if (!empty($hashes)) {
$hashes = implode(',', $hashes);
$q = $modx->db->query("SELECT * FROM {$modx->getFullTableName('userfiles')} WHERE `hash` IN ({$hashes})");
while ($row = $modx->db->getRow($q)) {
$thumb = preg_replace('#(^.*[\\\/])#','${1}thumbs/',$row['file']);
$out .= '<div class="file" style="background:url(\'/'.$thumb.'\') center center no-repeat;"><a href="#" data-id="'.$row['hash'].'" class="btn delete btn-xs btn-danger">Удалить</a><input type="hidden" name="photo[]" value="'.$row['hash'].'"></div>';
}
}
$FormLister->setPlaceholder('photo_files', $out);
}
$modx->regClientScript('assets/js/fileapi/FileAPI/FileAPI.min.js');
$modx->regClientScript('assets/js/fileapi/FileAPI/FileAPI.exif.js');
$modx->regClientScript('assets/snippets/userupload/js/uploader.js');
break;
case 'prepareAfterProcess':
if (!empty($photo = $FormLister->getField('photo'))) {
$fs = \Helpers\FS::getInstance();
if (!is_array($photo)) $photo = array();
$out = '';
$hashes = array();
foreach ($photo as $item) {
if ($item) $hashes[] = "'{$item}'";
}
if (!empty($hashes)) {
include_once(MODX_BASE_PATH . 'assets/plugins/simplegallery/lib/table.class.php');
$sg = new \SimpleGallery\sgData($modx);
$hashes = implode(',', $hashes);
$q = $modx->db->query("SELECT * FROM {$modx->getFullTableName('userfiles')} WHERE `hash` IN ({$hashes})");
while ($row = $modx->db->getRow($q)) {
$sg->upload($row['file'], $data['id'], $fs->takeFileName($row['file']), true);
}
}
}
break;
}
Pathologic
вот как у меня это выглядит
Pathologic
можно было бы даже универсальный компонент сделать
Andrey
FileAPI юзаешь)
Pathologic
да
Andrey
Два события в одном коде? Это на prepare просто или как вызывается?
Pathologic
два события
Pathologic
надо ведь что-то делать если форму с ошибками отправят
Andrey
А, понял. Можно код всей обработки сунуть в один сниппет, а там рулить уже в зависимости от $name
Pathologic
`
function Uploader(options) {
var upload = options.upload;
this.init = function() {
var self = this;
options.placeholder.click(function(e){
var name = 'input[name="'+options.placeholder.data('field')+'[]"';
var uploaded = $(name).length;
if (uploaded < options.maxFiles) {
upload.trigger('click');
}
});
FileAPI.event.on(upload[0], 'change', function (evt){
var files = FileAPI.getFiles(evt); // Retrieve file list
FileAPI.filterFiles(files, function (file, info/**Object*/){
return /jpeg$/.test(file.type) && file.size < 2 * FileAPI.MB;
}, function (files/**Array*/, rejected/**Array*/){
self.upload(files);
});
});
FileAPI.event.dnd(options.placeholder[0], function (over){
if (over) {
options.placeholder.addClass('dnd');
} else {
options.placeholder.removeClass('dnd');
}
}, function (files){
FileAPI.filterFiles(files, function (file, info/**Object*/){
return /jpeg$/.test(file.type) && file.size < 2 * FileAPI.MB;
}, function (files/**Array*/, rejected/**Array*/){
self.upload(files);
});
});
};
this.upload = function(files) {
var self = this;
var name = 'input[name="'+options.placeholder.data('field')+'[]"';
var uploaded = $(name).length;
if( files.length && (uploaded + files.length) <= options.maxFiles ){
var _options = {
url: '/assets/snippets/userupload/ajax.php',
files: { file: files },
data: {
mode: 'upload',
},
imageAutoOrientation: true,
imageTransform: {
maxWidth: 1920,
maxHeight: 1080,
quality: 0.9
},
upload: function() {
options.progress.show();
},
progress: function (evt){
var pr = evt.loaded/evt.total * 100;
options.progress.css('width',pr+'%');
},
filecomplete: function(err, xhr) {
if (!err) {
var response = JSON.parse(xhr.response);
if (response.success !== undefined && response.success == true) {
self.save(response.data);
} else {
alert(response.message);
}
}
},
complete: function (err, xhr){
options.progress.css('width', 0).hide();
self.clear();
}
};
FileAPI.upload(_options);
}
};
this.clear = function() {
upload.wrap('<form>').closest('form').get(0).reset();
upload.unwrap();
};
this.save = function(value) {
options.placeholder.parent().append($('<div class="file" style="background:url(\'/'+value.thumb+'\') center center no-repeat;"><a href="#" data-id="' + value.hash + '" class="btn delete btn-xs btn-danger">Удалить</a><input type="hidden" name="'+options.placeholder.data('field')+'[]" value="'+value.hash+'"></div>'));
}
};
$(document).ready(function(){
var photoUploader = new Uploader({
placeholder: $('#photo'),
upload: $('input[name="photouploader"]'),
progress: $('.progress', '#photo'),
maxFiles:10
});
photoUploader.init();
$('form').on('click', '.delete', function(e){
e.preventDefault();
var item = $(this);
var id = item.data('id');
$.post('/assets/snippets/userupload/ajax.php', {'mode':'delete', 'hash':id}, function(){item.parent().remove()},'json');
});
});
Pathologic
🙃
Pathologic
/top@Axenia_Bot
Andrey
`
function Uploader(options) {
var upload = options.upload;
this.init = function() {
var self = this;
options.placeholder.click(function(e){
var name = 'input[name="'+options.placeholder.data('field')+'[]"';
var uploaded = $(name).length;
if (uploaded < options.maxFiles) {
upload.trigger('click');
}
});
FileAPI.event.on(upload[0], 'change', function (evt){
var files = FileAPI.getFiles(evt); // Retrieve file list
FileAPI.filterFiles(files, function (file, info/**Object*/){
return /jpeg$/.test(file.type) && file.size < 2 * FileAPI.MB;
}, function (files/**Array*/, rejected/**Array*/){
self.upload(files);
});
});
FileAPI.event.dnd(options.placeholder[0], function (over){
if (over) {
options.placeholder.addClass('dnd');
} else {
options.placeholder.removeClass('dnd');
}
}, function (files){
FileAPI.filterFiles(files, function (file, info/**Object*/){
return /jpeg$/.test(file.type) && file.size < 2 * FileAPI.MB;
}, function (files/**Array*/, rejected/**Array*/){
self.upload(files);
});
});
};
this.upload = function(files) {
var self = this;
var name = 'input[name="'+options.placeholder.data('field')+'[]"';
var uploaded = $(name).length;
if( files.length && (uploaded + files.length) <= options.maxFiles ){
var _options = {
url: '/assets/snippets/userupload/ajax.php',
files: { file: files },
data: {
mode: 'upload',
},
imageAutoOrientation: true,
imageTransform: {
maxWidth: 1920,
maxHeight: 1080,
quality: 0.9
},
upload: function() {
options.progress.show();
},
progress: function (evt){
var pr = evt.loaded/evt.total * 100;
options.progress.css('width',pr+'%');
},
filecomplete: function(err, xhr) {
if (!err) {
var response = JSON.parse(xhr.response);
if (response.success !== undefined && response.success == true) {
self.save(response.data);
} else {
alert(response.message);
}
}
},
complete: function (err, xhr){
options.progress.css('width', 0).hide();
self.clear();
}
};
FileAPI.upload(_options);
}
};
this.clear = function() {
upload.wrap('<form>').closest('form').get(0).reset();
upload.unwrap();
};
this.save = function(value) {
options.placeholder.parent().append($('<div class="file" style="background:url(\'/'+value.thumb+'\') center center no-repeat;"><a href="#" data-id="' + value.hash + '" class="btn delete btn-xs btn-danger">Удалить</a><input type="hidden" name="'+options.placeholder.data('field')+'[]" value="'+value.hash+'"></div>'));
}
};
$(document).ready(function(){
var photoUploader = new Uploader({
placeholder: $('#photo'),
upload: $('input[name="photouploader"]'),
progress: $('.progress', '#photo'),
maxFiles:10
});
photoUploader.init();
$('form').on('click', '.delete', function(e){
e.preventDefault();
var item = $(this);
var id = item.data('id');
$.post('/assets/snippets/userupload/ajax.php', {'mode':'delete', 'hash':id}, function(){item.parent().remove()},'json');
});
});
Спасибо!
Pathologic
самое сложное тут js (:
Pathologic
а серверная часть простая
Pathologic
да и все разобрано в SimpleGallery
Камиль
Господа специалисты, в TV значение по умолчанию ведь поддерживает такой формат
@EVAL return $modx->runSnippet('getAttributes', ['category' => '7,9','tovarparams' => '1']);
Камиль
?
Andrey
В теории да.
Камиль
да и в описании тоже написано что работает там, но на деле тупо текст выходит
Камиль
Andrey
Это вообще не то что-то)
Камиль
в смысле?
Andrey
В настройках ТВ совать надо, но не в текст
Камиль
я знаю)) я покал что он просто как текст выходил