MODx Revo: Редактирование ресурса из фронтенда сайта

Добрый день, друзья! Представляю вам вторую часть видео по созданию доски объявлений на MODx REVO.

По-моему, я делаю успехи по крайней мере, на этот раз картинка получилась лучше. Вообще, мне очень понравилось это занятие, и я планирую записать еще как минимум одну серию видеороликов, о создании сайтов на MODx REVO. Если вам интересная эта тема, не забудьте подписаться на обновления блога.

Напомню, что в прошлый раз мы создали два новых сниппета, и настроили публикацию объявлений и загрузку файлов из фронтенда.

В этом ролике я расскажу, как создать сниппет, который позволит пользователям редактировать объявления на сайте, и что сделать, чтобы посетители могли изменять только свои ресурсы.

Код сниппета resource2formit
<?php
if (isset($_GET['resId'])){
    if ($doc=$modx->getObject('modResource',array('id'=>$_GET['resId']))){
        $docarray=$doc->toArray();
        $fields = explode(',',$scriptProperties['resource2formitfields']);
        $fields[] = 'id';
 
        foreach ($fields as $field){
        
            if ($doc->getFieldName($field) === null) {
                /* if field isnt defined, look for TV value */
                $tvValue = $doc->getTVValue($field);
                if ($tvValue !== null) {
                    $hook->setValue($field,$tvValue);
                }
            } else {
                /* otherwise get field value */
                $hook->setValue($field,$docarray[$field]);
            }   
        }
    }
 
}
 
 
return true;   
Вызов FormIt для формы редактирования
[[!FormIt? 
&hooks=`formit2file,formit2resource,redirect` 
&preHooks=`resource2formit`
&resource2formitfields=`parent,pagetitle,ваши-TV-параметры-через-запятую,content,createdby`
&redirectTo=`2` 
&template=`2` 
&validate=`nospam:blank,
           pagetitle:required,
           content:required:stripTags`]]    
Пример формы редактирования
<p>[[+fi.error.error_message]]</p>
<form class="form" action="/edit.html&resId=[[+fi.id]]" method="post" enctype="multipart/form-data" >
    <input name="nospam:blank" type="hidden" />
    <input name="resource_id" type="hidden" value="[[+fi.id]]" />
    <input id="parent" name="parent" type="hidden" type="text" value="[[+fi.parent]]" /> 

<div>
    <label>Заголовок:</label>
    <span class="error">[[+fi.error.pagetitle]]</span>
    <input name="pagetitle" type="text" value="[[+fi.pagetitle]]" />
</div>  
<div>  
    <label>Телефон:</label>
    <span class="error">[[+fi.error.phone]]</span>
    <input id="price" name="phone" type="text" value="[[+fi.phone]]" />
</div>
<div>    
    <label>Город:</label>
    <span class="error">[[+fi.error.city]]</span>
    <input id="price" name="city" type="text" value="[[+fi.city]]" />
</div>
<div>     
    <label>Текст объявления:</label>
    <span class="error">[[+fi.error.content]]</span>
    <textarea id="content" cols="55" rows="7" name="content">[[+fi.content]]</textarea>
</div>
<div>
    <div class="label">Фото</div>
    <br />
    <span class="error">[[+fi.error.img]]
    <input id="file" name="img" type="file" value="[[+fi.img]]" maxlength="100000" /> 
</div>

<br class="clear" />
<div class="form-buttons">
        <input type="submit" value="Отправить на модерацию" />
Условие для вывода формы редактирования
[[!+fi.createdby:is=`[[!+modx.user.id]]`:then=`[[$form_edit]]`:else=`Вы не можете редактировать эту запись`]]    
Условие для вывода ссылки в шаблоне объявления
[[*createdby:is=`[[!+modx.user.id]]`:then=`<div class="edit">Редактировать</div>`]]   

Надеюсь, информация будет вам полезна, если появятся вопросы, можно задать их в комментариях.

  • https://wpget.ru Тимур

    Можно поинтересоваться, какой плагин так красиво код выводит?

    • Ольга

      Это Enlighter, а если точнее «Enlighter — Javascript based syntax highlighting».

  • Павел

    Ольга, спасибо за статьи!
    Не знаю специально или нет, но у вас в коде сниппета закомментирована строка:
    //$errorMsg = ‘
    и если её не откомментировать, то сниппет не работает.
    Ну или можно закомментировать чуть больше строк.

    • Ольга

      Здравствуйте, Павел! Еще раз скопировала код с рабочего сайта. Спасибо, что сказали об ошибке. WordPress «съел» часть кода и разорвал строку. Убрала эти строки.

  • Павел

    А ещё у этого способа есть безумная дыра в безопастности.
    Например, если ввести вот такой вот адрес:
    ваш_сайт/edit&resId=*например айдишник главной страницы*
    то можно перезаписать содержание.

    Подскажите, как это устранить?

    • Павел

      Хотя я, наверно, погорячился. Эта «уязвимость» доступна только админу, т.е. тому кто создал страницу.
      Ещё раз спасибо!

      • Ольга

        Совершенно верно, редактировать можно только свои ресурсы.

  • Костя

    Если при редактировании нужно убрать значения из полей и оставить их пустыми, то результат не сохраняется.
    Виновник if (!empty($value) && … в formit2resource
    Если убрать это условие, то фотографии при редактировании исчезнут если их не подгрузить заного.
    Как побороть?

    • Ольга

      Здравствуйте! Честно говоря, не было у меня такой задачи, но, если решение найдется, обязательно напишу.

    • Александр

      Переделал немного в конце. Наверняка криво, но теперь и пустые поля сохраняет картинка не исчезает.
      foreach ($allFormFields as $field=>$value)
      {
      if ($tv = $modx->getObject(‘modTemplateVar’, array (‘name’=>$field)))
      {
      if (empty($value) && $field == название tv куда идёт картинка){
      }else{
      /* 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();
      }
      }
      }

  • Екатерина

    Ольга, спасибо за столь полезные уроки! Почти все, что описано в видео получилось.
    Но, так как я раньше работала только с Evolution, то страница с выводом через getResources на моем хостинге, (я предполагаю, что причина в нем —jino.ru, как выяснилось позже, не рекомендуют для Revo), выдала мне 502 Bad Gateway. Потом я перенесла сделанное на Gigahost. И снова эта страница с getResources не вытягивается.
    Вопрос: какой хостинг используете Вы в своем примере на видео? И очень большая просьба выложить архив сделанного на видео сайта с дампом базы, чтобы можно было его поставить у себя и проверить, все ли сделано правильно, не отвлекая Вас лишними вопросами.

    • Ольга

      Здравствуйте, Катя! Тестовый сайт, с которого я записывала скринкаст, был на выделенном сервере. Идея с с архивом хорошая, спасибо! Правда, тот сайт я уже давно удалила, а на новый до января времени точно не будет. Но обязательно возьму ваши слова на заметку.

      Гигахост мне понравился, перенесла на него два небольших проекта. Проблем не возникало ни при установке, ни в работе.

      Не уверена в том, что у вас проблема именно в хостинге. Посмотрите журнал ошибок, что пишут?

      Я бы попробовала создать новую страницу с выводом ресурсов. И в TPL чанке сначала выводить только название ресурса, анонс, а если проблем не будет, постепенно добавлять другие параметры.

      • Екатерина

        Спасибо! Действительно, поэкспериментировала с чанком, и getResorces заработал, причем и на Гигахосте, и на Джино.

  • Екатерина

    Ольга, у меня снова назрел вопрос. На это раз по поводу прав пользователей созданной нами группы Users.
    Дело в том, что ссылка «Редактировать» не отображается, когда я создаю объявление в другом браузере, где не залогинена в админке. Эту ссылку видно только, когда я залогинена в админке, не зависимо от того, где и под каким аккаунтом создано объявление. Может, группе Users необходимо настроить еще какие-то права? Спасибо.

    • Ольга

      Катя, права доступа тут вообще никакой роли не играют. Мы ссылку выводим условием «если id автора ресурса = id пользователя», то есть, группа и роль пользователя не имеют значения.
      Почему у вас ссылку видит только админ, затрудняюсь ответить. Может в условии вы группу пользователя проверяете?

      • Екатерина

        Оля, спасибо за ответ. У меня шаблон для страницы объявления выглядит так:

        [[$head]]

        [[$header]]

        [[*pagetitle]]
        [[Loginza? &groups=`Users` &profileFields=`username,email,fullname`]]

        [[*createdby:is=`[[!+modx.user.id]]`:then=`
        Редактировать
        `]]

        [[*publishedon]]
        [[*city:notempty=`Город:[[*city]]`]]
        [[*phone:notempty=`Телефон:[[*phone]]`]]
        [[*img:notempty=«]]

        [[$footer]]

      • Екатерина

        Так как код съедается, то вот скриншот шаблона для страницы, где выведено объявление: https://lh6.googleusercontent.com/-6c2ApuY_q78/UkRNWRnQXZI/AAAAAAAAHSA/adgG_fpuDP0/w981-h458-no/edit.jpg

        • Ольга

          Катя, с кодом все в порядке. Есть подозрение, что объявления у вас публикуются от имени администратора. Добавьте на страницу [[*createdby]] и проверьте, кто автор объявления.

          • Екатерина

            Оля, спасибо. Добавила [[*createdby]], показывает разные номера пользователей у разных объявлений. У админа — 1, у аккаунтов из соцсетей — 2, 3, 4. То есть, различает. И еще странность: ссылка «Редактировать» даже у админа видна только на странице, где все объявления, если ее добавить в соответствующий чанк, а на странице, где открывается одно объявление, ее не видно ни у админа, ни у остальных. Что-то там не так, может, просто все с самого начала поставить? Возможно ли это по причине не так вызванного getResouces?

            • Ольга

              Конечно на странице рубрики ссылка будет видна админу, вы же ее создавали.

              По этой схеме ссылка показывается только АВТОРУ ресурса, тому. кто ее создал, а не группе. Поэтому и проверить ее можно только из аккаунта автора. Попробуйте создать объявление под админом и посмотрите.

              • Екатерина

                То есть, Вы считаете, так и должно быть? Другие пользователи будут видеть у своих объявлений ссылку для редактирования?

  • /script

    Здравствуйте Оля. Статьи интересно читать, Видео, в том числе. Все просто и понятно. Мега спасибки Вам.

  • Екатерина

    Ольга, здравствуйте! Сейчас попросила друзей создать на моем сайте объявления для теста. К их объявлениям вижу кнопку редактирования опять только я, как админ. А что нужно сделать, чтобы они видели ее рядом со своими объявлениями? Заранее спасибо за ответ.

    • Виктор

      Екатерина, здравствуйте!

      Вставлю свои 5 копеек. Не обязательно просить друзей. В Хроме и Опере есть режим «Инкогнито» CTRL+SHIFT+N — В нем отключаются и кеш и куки и вообще все. Можно логиниться откуда угодно в общем из под этого режима.

      У меня, кстати, тоже били глюки со ссылкой «редактировать». Она может быть видна в данном случае только на странице, где выводятся все объявления.

      это условие заработало когда я заменил * => +

      [[+createdby:is=`[[!+modx.user.id]]`:then=`
      Редактировать
      `]]

    • Виктор

      код срезается, вот скрин:
      https://my.jetscreenshot.com/3230/20130929-9vpw-17kb.jpg

      • Екатерина

        Большое спасибо, Виктор. Вы помогли мне сдвинуть проект с мертвой точки :). Заменила * на +, заработало. Теперь авторы видят эту ссылку возле своего объявления. А почему «Она может быть видна в данном случае только на странице, где выводятся все объявления»? Тут не стоит и пытаться это исправить? В видео, кажется, ссылка была и в общем списке, и на отдельной странице.

        • Виктор

          Это вот как раз у спецов уточнять по мод-иксу. :) Я с админками и мод-иксом знаком всего несколько дней.

          Ща нам Ольга все разрулит)

        • Ольга

          Катя, и в видео, и в статье «Условие для вывода ссылки в шаблоне объявления«.

          Если вы планируете работать с MODX и дальше, запомните раз и навсегда в шаблоне самой страницы стандартные поля и TV-параметры выводятся со звездочкой, на странице рубрики — с плюсом.

          Виктору спасибо за помощь!

          • Екатерина

            Спасибо, запомню. Но из шаблона у меня ссылка редактирования почему-то по-прежнему не выводится ни со звездочкой, ни с плюсом.

            • Виктор

              Решил трабл, Катя. :)

              Опять путаница в *+

              Вот скрин рабочего кода для шаблона:
              https://my.jetscreenshot.com/3230/20130930-sfy2-15kb.jpg

              • Екатерина

                Ура! Спасибо огромное! Виктор, но там не только плюсы и звездочки, как удалось найти информацию, сами догадались или что-то читаете?

            • Виктор

              Там и плюсы и звездочки и восклицательный знак, вернее его отсутствие. :)

              Сложно сказать, что я читаю. Этот сайт читаю. :) А так, просто гуглю, если удается сформировать вопрос. В данном случае вопрос сформировать не удалось, поэтому методом научного тыка удалось разобраться в синтаксисе, который, кстати, не очень логичный (после JS или Action Script). Я, вообще, фронтэнд разработчик + флешер. А вот в пхп и админки только сейчас полез, поскольку решил сделать уникальный ресурс не подключая при этом сторонних людей, у которых, как правило есть особое мнение на счет всего. :)

              • Ольга

                Виктор, теперь рассказывайте, почему убрали восклицательный знак))) У меня как раз без него ничего не работает, сейчас еще раз на своих сайтах проверила.

  • Виктор

    Про восклицательный знак. (в той ветке уже лимит дочерних комментов иссяк)

    Думаю, что все дело в том, что мой сайтец пока еще болтается на Денвере под Виндой. И возможно, меня ждут сюрприцы на Юниксовских серверах.

    Восклицательный знак (судя по документации) указывает, что сниппет некешируемый. (Не знаю, почему это мне мешало, если честно)

    В моем случае, когда в ссылке на редактирование поста стояла конструкция

    [[!+modx.user.id]] — сравнение с [[*createdby]] не происходило

    (попробовал поменять местами + и ! — не помогло)

    А как только оставил один плюс и в целом, конструкция выглядела так:

    [[*createdby:is=`[[+modx.user.id]]`:then=` ссылка edit`:else=`нет ссылки`]]

    то сравнение айдишников стало работать. Может быть это глюки разных версий революшина? У меня стоит последняя на настоящий момент версия MODX Revolution 2.2.9-pl (traditional)

    Еще, хотел у вас, Ольга, поинтересоваться. У вас логинза выдает приветствие после регистрации и ссылку выйти. У меня она почему-то не показывает, хоть и выполняет все остальные функции. Может быть дело в версии? Какая у вас версия?

    Спасибо.

    • Екатерина

      Виктор, по поводу Денвера — мой сайт не на нем, а на Гигахосте, там все заработало.

      • Виктор

        Крутотенюшка! )

    • Ольга

      Виктор, действительно на 2.2.9 работает только без восклицательного знака, а на 2.2.7 — наоборот. Надо будет добавить в пост.

      Про Логинзу ничего внятного сказать не смогу, ставила ее только на один сайт (сейчас он мне уже не принадлежит, посмотреть не могу). Приветствие и ссылка на выход выводились автоматически. Все делала по этой документации https://rtfm.modx.com/extras/revo/loginza

  • Виктор

    Еще тут понатыкался на мелкие моменты, с которыми могут столкнуться юзвери.

    В общем, при редактировании объявления обязательно должны подгружаться параметры pagetitle и content даже если их менять не нужно или если они не используются (у меня, например, content в форме не задействован никаким боком, из-за чего был грандиозный клин добавил в скрытый инпут контент и все пошло как по маслу :) )

  • Александр

    Нашел проблему обоих уроков: если у вас несколько контекстов, и документы на модерацию могут находится в одном и другом, в зависимости от того, какой город выбрал пользователь, то любому документу присваивается в базе контекст WEB. А если пользователь выбрал родительским документом ресурс, находящийся в другом контексте, то новому/редактируемому документу все равно присваеватся контекст WEB и из за этого его не видно в меню. Как исправить пока что не знаю

  • Витя

    Добрый день ) возникла проблемка сделал всё как в уроке , работает ,но переходит не на ресурс с псевдонимом edit , а на главную страницу с id (1). пришлось в неё ставить чанк редактированием , но в этом случае при заходе на сайт перебрасывает сразу на форму редактирования . У меня сайт сейчас на локальном хостинге (denvere) может в этом проблема. .htaccess — изменил название файла на такой и поставил дружественные урл . Подскажите что я сделал не так ?

    • Ольга

      Добрый день! Если вы все делали, как в уроке, у вас и получиться должно как в уроке :) Где-то допустили ошибку, ищите, исправляйте.
      Есть ли у вас вообще ресурс /edit.html ?
      На главную перебрасывает, скорее всего, потому что у вас в настройках не указана страница 404 ошибки.

  • Сергей

    Урок замечательный. Реализовал. Вот только возникла необходимость дополнить. Может сталкивались с такой задачей:
    Требуется организовать облако тегов. TV — авто-метка, что бы не нужно было каждый раз писать тэг, а достаточно было кликнуть на уже имеющиеся в базе. Вот только это реализовано через админку. А как сделать, что бы в фронт-энде при создании или редактировании объявления можно так же, как и в админке оперировать автометками?

  • Вячеслав

    Здравствуйте, Ольга!
    Подскажите пожалуйста, как сделать, что бы пользователь мог удалять свои объявления?

    • Ольга

      Вячеслав, насчет удалить не могу сказать, а вот снять с публикации можно через параметр published. Включите в форму чекбокс.

      • Александр

        Для удаления присутствует параметр deleted вроде бы. Удаляет документ в корзину. Для полного удаления корзину надо почистить

  • https://вразработке Александр

    Добрый день, Ольга! Подскажите пожалуйста как можно осуществить выбор категории объявления из фронтэнда? Спасибо

    • Ольга

      Александр, включите в форму еще один инпут в виде выпадающего списка, где значения будут id рубрик.

      • https://вразработке Александр

        Точно! всё гениально и просто! Спасибо БОЛЬШОЕ, Вы молодец, хорошие статьи, да и бывает на мелочах больше паришься чем с реальной проблемой. Еще раз Спасибо!

  • Александр

    Добрый день, Ольга!
    А подскажите, как сделать, чтобы при редактировании страницы пользователем, администратору приходило письмо о том что страница отредактирована, или есть ли возможность вносить изменения, только после проверки модератором.

  • https://xx-oleg-xx1981.ya.ru Oleg Michailov

    Вот так заработает.
    [[!+modx.user.id:is=`[[*createdby]]`:then=`Редактировать`]]

  • Сергей

    Спасибо за уроки. Ваш сайт оказался для меня очень полезным. Очень жаль, что Вы больше не поддерживаете общение и не добавляете новости по MODx’у. Но, с другой стороны, это Ваш сайт и Вы решаете, что Вам с ним делать. Желаю Вам успехов в бизнесе.

  • https://vk.com/id437195 Андрей Жеребятьев

    Всё просто. В форме редактирования в параметре action вместо edit.html поставьте [[~27]], где 27 — это id ресурса с формой редактирования (у Вас может быть другой номер).

  • https://www.facebook.com/app_scoped_user_id/1088080954537662/ Roman Sozinov

    Благодарю за предложенное решение для фронтенда! Сам не программист, но за 3 дня сам внедрил ваше решение. Столкнулся с тем, что при обновлении ресурса, автоматом менялся псевдоним alias чпу ссылки, что не очень радовало сеошника)) Добавлялось к урлу цифра 1. Может кому будет полезно моё решение, возможно, не совсем правильное, но работающее.

    Надо в сниппете обновления resource2formit в коде после конструкции foreach добавить код:

    /* чтобы не обновлялись чпу при обновлении ресурса */

    $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();

    /* END чтобы не обновлялись чпу при обновлении ресурса */

    Этот код я позаимствовал из сниппета добавления ресурса formit2resource

    Также внедрил редактор TinyMce в текстовое поле. Но никак не могу добиться вставки в текст картинок через него. Может кто уже смог это сделать, буду благодарен за подсказку.

    Всем успехов!