MODx Revolution: создание ресурсов и загрузка файлов из фронтенда
Добрый день, всем читателям блога WebHow! Наконец-то я нашла отличный плагин для подсветки кода в статьях, и теперь можно заняться серьезными делами. Итак, шутки в сторону, сегодня будет суровый пост для тех, кто мечтает организовать на своем MODx-сайте доску объявлений, каталог или любой другой сервис, где посетители будут сами размещать свой контент.
Все, кто хоть немного знаком с MODx, знают, для того чтобы размещать свой контент, у пользователя должен быть доступ к админ.панели. Раздавать его направо-налево, разумеется, не хочется. Поэтому нужно сделать так, чтобы пользователи могли создавать ресурсы и загружать к ним файлы прямо со страниц сайта.
Я не программист, и когда мне впервые пришлось создать доску объявлений на MODx, все что я могла — поискать готовое решение. Различных вариантов сниппета, который бы позволил публиковать ресурс с фронтенда для MODx Revolution оказалось не мало.
Принцип у всех примерно один: при помощи FormIt создается страница с формой, в вызове которой прописывается имя сниппета. Для каждого типа объявлений создаются свои TV-поля, например, город, телефон, или поле для загрузки изображений. Когда пользователь отправляет форму, создается ресурс.
Однако, практически все сниппеты, которые мне удалось найти, были очень громоздкими: каждый TV-параметр нужно было прописывать в коде сниппета, а это меня не устраивало. Потому что для каждого вида объявлений я задумала как минимум 3 дополнительных поля, и все их прописывать в сниппет… нет, есть способ лучше и проще. Он был найден мною на англоязычной части официального форума MODx.com И если вы не очень хорошо говорите и читаете по английски или вам просто лень искать подходящий вариант из нескольких в теме, я расскажу как им пользоваться.
На эту тему я записала пошаговую видео-инструкцию. Все материалы к ней вы найдете чуть ниже проигрывателя.
<?php $doc = $modx->getObject('modResource',array('id'=>$hook->getValue('resource_id'))); if (empty($doc)){ $doc = $modx->newObject('modResource'); $doc->set('createdby', $modx->user->get('id')); } else{ $doc->set('editedby', $modx->user->get('id')); } $allFormFields = $hook->getValues(); foreach ($allFormFields as $field=>$value) { if ($field !== 'spam' && $field !== 'resource_id'){ $doc->set($field, $value); } } $alias = $doc->cleanAlias($fields['pagetitle']); if($modx->getCount(modResource, array('alias'=>$alias))!= 0) { $count = 1; $newAlias = $alias; while($modx->getCount(modResource, array('alias'=>$newAlias))!= 0) { $newAlias = $alias; $newAlias .= '-' . $count; $count++; } $alias = $newAlias; } $doc->set('alias',$alias); $doc->set('template', $template); $doc->save(); foreach ($allFormFields as $field=>$value) { if (!empty($value) && $tv = $modx->getObject('modTemplateVar', array ('name'=>$field))) { /* handles checkboxes & multiple selects elements */ if (is_array($value)) { $featureInsert = array(); while (list($featureValue, $featureItem) = each($value)) { $featureInsert[count($featureInsert)] = $featureItem; } $value = implode('||',$featureInsert); } $tv->setValue($doc->get('id'), $value); $tv->save(); } } $modx->cacheManager->refresh(); return true;
<?php // initialize output; $output = true; $counter = 1; // valid extensions $ext_array = array('jpg', 'png', 'gif', 'JPG', 'mp3'); $mydir = $modx->user->get('id'); // Path from root that user specifies // create unique path for this form submission $uploadpath = 'assets/uploads/'.$mydir.'/'; // get full path to unique folder $target_path = $modx->config['base_path'] . $uploadpath; // get uploaded file names: $submittedfiles = array_keys($_FILES); // loop through files foreach ($submittedfiles as $sf) { // Get Filename and make sure its good. $filename = basename( $_FILES[$sf]['name'] ); // Get file's extension $ext = pathinfo($filename, PATHINFO_EXTENSION); $ext = mb_strtolower($ext); // case insensitive // is the file name empty (no file uploaded) if($filename != '') { // is this the right type of file? if(in_array($ext, $ext_array)) { // clean up file name and make unique $filename = $counter . '.' . $ext; $filename = str_replace(' ', '_', $filename); // spaces to underscores $filename = date("Y-m-d_G-i-s_") . $filename; // add date & time // full path to new file $myTarget = $target_path . $filename; // create directory to move file into if it doesn't exist mkdir($target_path, 0755, true); // is the file moved to the proper folder successfully? if(move_uploaded_file($_FILES[$sf]['tmp_name'], $myTarget)) { // set a new placeholder with the new full path (if you need it in subsequent hooks) $myFile = $uploadpath . $filename; $hook->setValue($sf,$myFile); // set the permissions on the file if (!chmod($myTarget, 0644)) { /*some debug function*/ } } else { // File not uploaded $errorMsg = 'There was a problem uploading the file.'; $hook->addError($sf, $errorMsg); $output = false; // generate submission error } } else { // File type not allowed $errorMsg = 'Type of file not allowed.'; $hook->addError($sf, $errorMsg); $output = false; // generate submission error } // if no file, don't error, but return blank } else { $hook->setValue($sf, ''); } $counter = $counter + 1; } return $output;
Друзья! Не забывайте подставлять в код формы ваши TV-поля и ID ваших ресурсов. Будьте внимательны, и у вас все получится.
[[!FormIt? &hooks=`formit2file,formit2resource,redirect` &redirectTo=`ID страницы с сообщением` &template=`ID шаблона объявления` ]]
[[!+modx.user.id:is=`0`:then=`Для размещения объявления необходима авторизация [[!Loginza? &groups=`3` &profileFields=`username,email,fullname,photo`]]`:else=`[[$form_add]]`]]
[[+fi.error.error_message]] <form class="cartform" action="[[~[[*id]]]]" enctype="multipart/form-data" method="post"><input type="hidden" name="nospam:blank" /> <input type="hidden" name="resource_id" value="[[+fi.id]]" /> <input id="parent" type="text" name="parent" value="ID контейнера на модерацию" /> <div class="label">Название</div> [[+fi.error.pagetitle]] <input class="field" type="text" name="pagetitle" value="[[+fi.pagetitle]]" /> <div class="star">*</div> <div class="label">Город</div> [[+fi.error.city]] <input class="field" type="text" name="city" value="[[+fi.city]]" /> <div class="star">*</div> <center> <h3>Подробное описание</h3> [[+fi.error.content]] <textarea class="textinput" cols="70" name="content" rows="10">[[+fi.content]]</textarea> </center> <h3>Прикрепить фотографии:</h3> Вы можете разместить в каталоге до пяти фотографий. Допустимые форматы: .jpg, .png, .gif <table class="addform"> <tbody> <tr> <td class="label">Основное фото или логотип<span class="impot">*</span></td> <td class="input"><span class="error">[[+fi.error.img]]</span><input id="file" type="file" maxlength="100000" name="img" value="[[+fi.img]]" /></td> </tr> <tr> <td class="label">Дополнительное фото (1)</td> <td class="input"><span class="error">[[+fi.error.foto1]]</span><input id="foto1" type="file" maxlength="100000" name="foto1" value="[[+fi.foto1]]" /></td> </tr> <tr> <td class="label">Дополнительное фото (2)</td> <td class="input"><span class="error">[[+fi.error.foto2]]</span><input id="foto2" type="file" maxlength="100000" name="foto2" value="[[+fi.foto2]]" /></td> </tr> <tr> <td class="label">Дополнительное фото (3)</td> <td class="input"><span class="error">[[+fi.error.foto3]]</span><input id="foto3" type="file" maxlength="100000" name="foto3" value="[[+fi.foto3]]" /></td> </tr> <tr> <td class="label">Дополнительное фото (4)</td> <td class="input"><span class="error">[[+fi.error.foto4]]</span><input id="foto4" type="file" maxlength="100000" name="foto4" value="[[+fi.foto4]]" /></td> </tr> </tbody> </table> <input class="add-button" type="submit" value="Отправить на модерацию" /> </form>
[[*img:notempty=``]]
Теперь пользователи вашего сайта могут не только размещать объявления, но и дополнять их фотографиями, как и на любой доске объявлений. Но что делать, если во время заполнения формы была допущена ошибка? Например, человек опечатался и указал неверный номер телефона, а может быть, просто захотел дополнить объявление или изменить цену на свой товар.
В следующий раз расскажу, как разрешить пользователям редактировать свои ресурсы с фронтенда сайта. А на сегодня все, надеюсь, эта статья была вам полезна.