Как обновить дату редактирования ресурса в котором публикуется цепочка сообщений easyComm при нажатии в админке кнопки сохранить?

Как обновить дату редактирования ресурса в котором публикуется цепочка при публикации отзыва или ответа на вопрос (редактировании ответа на вопрос), в общем при нажатии в админке кнопки сохранить?

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

В каком файле это можно сделать и где именно, или надо сниппет или плагин свой делать?
Дмитрий
09 декабря 2019, 19:10
modx.pro
2
1 191
0

Комментарии: 30

Евгений
09 декабря 2019, 22:50
0
Событие OnEcMessageSave
Повесить на него плагин который будет обновлять дату в ресурсе…
    Дмитрий
    09 декабря 2019, 23:24
    0
    Благодарю. Если не трудно, можно пример привести. Или хотя бы пример получения в таком плагине id ресурса в котором размещается цепочка, сообщение которой редактируем и сохраняем в админке.
      Евгений
      09 декабря 2019, 23:50
      0
      Как то так…
      $id = $object->get('thread');
    Евгений
    09 декабря 2019, 23:49
    0
    Как то так…
    $id = $object->get('thread');
      Дмитрий
      10 декабря 2019, 00:10
      0
      Что-то на главной сработало, а на остальных не срабатывает.

      код плагина такой:
      if ($modx->event->name == 'OnEcMessageSave') {
      
      $id = $object->get('thread');
      
      $res = $modx->getObject('modResource', $id);
      $my_doc = array(
      'id' => $id
      ,'parent' => $res->get('parent')
      ,'pagetitle' => $res->get('pagetitle')
      ,'class_key' => 'modDocument'
      ,'alias' => $res->get('alias')
      ,'context_key' => 'web'
      );
      $modx->runProcessor('resource/update',$my_doc);
      
      //очистка кэша ресурса  
      $res->_contextKey = $res->context_key;
      $cache = $modx->cacheManager->getCacheProvider($modx->getOption('cache_resource_key', null, 'resource'));
      $key = $res->getCacheKey();
      $cache->delete($key, array('deleteTop' => true));
      $cache->delete($key);
      
      }
        Евгений
        10 декабря 2019, 00:26
        0
        Я бы сделал как то так.
        $id = $object->get('thread');
        $res = $modx->getObject('modResource', $id);
        $res = $res->toArray();
        $res['publishedon'] = time();
        //или
        $res['editedon'] = time();
        
        $response = $modx->runProcessor('resource/update', $res);
          Дмитрий
          10 декабря 2019, 00:39
          0
          а зачем
          $res['publishedon'] = time();
          //или
          $res['editedon'] = time();
          Этой же строкой ведь уже обновляется дата редактирования 'editedon'
          $response = $modx->runProcessor('resource/update', $res);
            Евгений
            10 декабря 2019, 00:43
            0
            а, ну без этого… )))
            Работает так?
            Дмитрий
            10 декабря 2019, 00:45
            0
            я еще имел ввиду, что
            $id = $object->get('thread');
            Не определяет id ресурса. Кроме главной нигде не работает, видимо там всегда значение == 1
              Дмитрий
              10 декабря 2019, 00:48
              0
              например, сохраняю сообщение с цепочки ресурса id:8, а меняется 'editedon' у ресурса с id:1, то есть у главной.
        Дмитрий
        10 декабря 2019, 01:56
        0
        Осталось правильно определить id ресурса, в котором размещается цепочка.

        А в остальном вот такой код плагина, вроде работает без ошибок. Благодарю Евгения за правильное (вроде бы) направление решения данной задачи, чем смог, помог.
        if ($modx->event->name == 'OnEcMessageSave') {
        
        $id = 8;// Как динамически определить id ресурса при сохранении сообщения в админке???
        $res = $modx->getObject('modResource', $id);
        
        $my_doc = $res->toArray();
        $modx->runProcessor('resource/update',$my_doc);
        
        //очищаем кэш
        $res->_contextKey = $res->context_key;
        $cache = $modx->cacheManager->getCacheProvider($modx->getOption('cache_resource_key', null, 'resource'));
        $key = $res->getCacheKey();
        $cache->delete($key, array('deleteTop' => true));
        $cache->delete($key);
        }

        Помогите определить id ресурса в данном плагине!
          Сергей Шлоков
          10 декабря 2019, 07:28
          +1
          Вы просите помочь с платным пакетом. Соответственно знающих мало. Если Вы его купили, обратитесь в техподдержку магазина. Если стырили, то…

          По поводу кода плагина. Это треш.
          Во-первых, может быть в плагине уже доступен нужный объект. Автор подскажет.
          Во-вторых, зачем ради изменения одного поля менять весь объект через тяжелый процессор.
          $res->set('publishedon', time());
          $res->save();
          В-третьих, очистить кэш ресурса можно одной строкой
          $res->clearCache();
            Дмитрий
            10 декабря 2019, 09:15
            0
            Сергей, обратился в тех поддержку магазина к автору.

            Сделал так как ты написал, но не работает это
            if ($modx->event->name == 'OnEcMessageSave') {
            
            $id = 8;
            $res = $modx->getObject('modResource', $id);
            
            $res->set('editedon', time());
            $res->save();
            $res->clearCache();
            
            }
            Дата редактирования 'editedon' не меняется и кэш не очищается.
          Наумов Алексей
          10 декабря 2019, 09:27
          0
          Я без проверки напишу, может где-то опечатаюсь)
          Еще после методов getOne желательно проверять объекты на null.

          if ($modx->event->name == 'OnEcMessageSave') {
              $thread = $object->getOne('Thread');
              $resource = $thread->getOne('Resource');
              $resource->set('editedon', time());
              $resource->save();
              $resource->clearCache();
          }
          по логике это все.
          Если все равно осталось закешированным, то стоит посмотреть, как генерируется LastModified
            Дмитрий
            10 декабря 2019, 09:44
            0
            Благодарю, так вроде все работает.
            Сейчас не могу проверить все, надо на работу, после посмотрю внимательнее.

            А объекты на null проверять какие?
            Так?
            If($resource !=null){
                $resource->set('editedon', time());
                $resource->save();
                $resource->clearCache();
            }
            Или как?
              Наумов Алексей
              10 декабря 2019, 09:50
              0
              Просто
              if($resource) {...
              каждый раз после getOne.
                Дмитрий
                10 декабря 2019, 09:53
                0
                то есть так
                $thread = $object->getOne('Thread');
                if($thread) {
                    $resource = $thread->getOne('Resource');
                }
                if($resource) {
                    $resource->set('editedon', time());
                    $resource->save();
                    $resource->clearCache();
                }
                  Наумов Алексей
                  10 декабря 2019, 10:10
                  0
                  $thread = $object->getOne('Thread');
                  if($thread) {
                      $resource = $thread->getOne('Resource');
                      if($resource) {
                          $resource->set('editedon', time());
                          $resource->save();
                          $resource->clearCache();
                      }
                  }
                    Сергей Шлоков
                    10 декабря 2019, 10:48
                    0
                    Можно короче
                    $thread = $object->getOne('Thread'); // можно и в нижний if засунуть. Только скобки нужны. Но выглядит не очень.
                    if($thread && $resource = $thread->getOne('Resource')) {
                            $resource->set('editedon', time());
                            $resource->save();
                            $resource->clearCache();
                        }
                    }
                    Можно даже очистить кэш до сохранения и закэшировать в момент сохранения. Но нужно смотреть результат.
                    $resource->clearCache(); // возможно это можно опустить, если при сохранении ниже старый кэш затрётся новым. Но я не уверен.
                    $resource->set('editedon', time());
                    $resource->save(true);  // сохранить и создать кэш.
              Дмитрий
              10 декабря 2019, 20:53
              0
              Почему-то не очищается кэш ни так
              $resource->clearCache();
              ни так
              $resource->save(true);  // не затирается старый кэш новым.

              Еще дело в том, что в компоненте LastModified есть системная настройка lastmodified.update_parent
              «Обновление родителя», поэтому при включенной этой настройке нужно обновлять ресурс через «тяжелый процессор», чтобы обновился родитель, а если выключена то просто менять дату последнего редактирования ресурса.

              Поэтому сделал так, вроде все работает…
              if ($modx->event->name == 'OnEcMessageSave') {
              
              	$thread = $object->getOne('Thread');
              
              	if($thread && $resource = $thread->getOne('Resource')) {
              
              	//очищаем кэш
              	$resource->_contextKey = $resource->context_key;
              	$cache = $modx->cacheManager->getCacheProvider($modx->getOption('cache_resource_key', null, 'resource'));
              	$key = $resource->getCacheKey();
              	$cache->delete($key, array('deleteTop' => true));
              	$cache->delete($key);
              
              		// если в компоненте LastModified включена системная настройка "Обновление родителя" то делаем обновление через процессор
              		if ($modx->getOption('lastmodified.update_parent') == true){
              			$modx->runProcessor('resource/update',$resource->toArray());	
              		} else { // если выключена, то просто обновляем дату последнего редактирования ресурса
              			$resource->set('editedon', time());
              			$resource->save(true);	
              		}
              	}
              }

              Благодарю всех за помощь!
                Сергей Шлоков
                11 декабря 2019, 08:33
                0
                Почему-то не очищается кэш ни так
                $resource->clearCache();
                А, ну да, нужно контекст указать.
                $resource->clearCache('web');
                Дмитрий
                10 декабря 2019, 22:17
                0
                Немного упустил такой момент. Обновление срабатывает даже тогда, когда сообщение не опубликовано.

                В связи с этим вопрос. Как получить значение published сообщения, чтобы сделать проверку: если сообщение опубликовано или в неопубликованном сообщении установлен флажок в чекбокс «Опубликовано:», то только в этом случае обновлять ресурс.
                В общем как сделать такую проверку?
                  Дмитрий
                  11 декабря 2019, 02:51
                  0
                  сделал вот так
                  if ($modx->event->name == 'OnEcMessageSave' || $modx->event->name == 'OnEcMessageUnpublish' || $modx->event->name == 'OnEcMessagePublish') {
                  
                  	$thread = $object->getOne('Thread');
                  
                  	if($thread && $resource = $thread->getOne('Resource')) {
                  
                  		if ($object->get('published') == true && $object->get('publishedon') != null || $modx->event->name == 'OnEcMessageUnpublish' || $modx->event->name == 'OnEcMessagePublish') {
                  			//очищаем кэш
                  			$resource->_contextKey = $resource->context_key;
                  			$cache = $modx->cacheManager->getCacheProvider($modx->getOption('cache_resource_key', null, 'resource'));
                  			$key = $resource->getCacheKey();
                  			$cache->delete($key, array('deleteTop' => true));
                  			$cache->delete($key);
                  
                  				// если в компоненте LastModified включена системная настройка "Обновление родителя" то делаем обновление через процессор
                  			if ($modx->getOption('lastmodified.update_parent') == true) {
                  					$modx->runProcessor('resource/update',$resource->toArray());	
                  				} else { // если выключена, то просто обновляем дату последнего редактирования ресурса
                  					$resource->set('editedon', time());
                  					$resource->save(true);	
                  			}
                  		}		
                  	}
                  }

                  Но опять одно НО!

                  При редактировании ресурса, если поставить галочку «Опубликован» и сохранить, то проверку делаю так
                  if($object->get('published') == true && $object->get('publishedon') != null) {...}

                  Однако при редактировании сообщения, если СНЯТЬ галочку с «Опубликован» и сохранить, то обнуляются значения полей 'published' и 'publishedon', поэтому не знаю за что зацепиться, чтобы сделать проверку. Других подходящих полей в таблице _ec_messages нет. Например, типа поле со значением что ресурс ранее уже публиковался, но снят с публикации.

                  Может что-то упускаю?
                    Сергей Шлоков
                    11 декабря 2019, 08:41
                    0
                    У ресурса есть поле properties. Пишите признак туда при снятии с публикации
                    $resource->properties['was_published'] = true;
                    А потом соответственно проверяйте.
                      Наумов Алексей
                      11 декабря 2019, 09:16
                      0
                      Да, зацепится особо не за что, верно.
                      Как Сергей подметил, можно properties использовать, это поле есть не только у ресурса, но и у комментария.
                      Оно в компоненте нигде не используется.
                      Делайте там пометку нужную вам.
                        Дмитрий
                        11 декабря 2019, 13:02
                        0
                        Что-то в таблице _ec_messages не нашел поле properties.

                        Или в какой-то другой таблице это поле? Как туда записать и проверять находящееся там значение? Просто ни разу не работал с таким полем…
                          Наумов Алексей
                          11 декабря 2019, 15:01
                          0
                          Упс, ошибся. Там есть поле extended, оно не используется, добавлено «на всякий». Поле типа json, по идее работать с ним нужно как с массивом (хотя я ни разу его не использовал).
                          $v = $message->get('extended');
                          $v['some'] = 'test';
                          $message->set('extended', $v);
                          $message->save();
                            Дмитрий
                            11 декабря 2019, 15:51
                            0
                            Ок, благодарю, я уже подумывал использовать это поле, так как там ничего нет ни в одном сообщении, кроме того здесь пишешь: «extended — не используется в текущей версии».
                            Правда сейчас не могу проверить, нет доступа к сайту. Дома буду проверю.

                            Еще вопрос. Если ты указал, что поле сообщения можно получить вот так:
                            $message->get('extended');

                            То наверное в моем коде
                            if($object->get('published') == true && $object->get('publishedon') != null ...
                            
                             //лучше записать так???
                            if($message->get('published') == true && $message->get('publishedon') != null ...
                            И подскажи в чем отличие? Или это одно и тоже?
                              Наумов Алексей
                              11 декабря 2019, 16:19
                              0
                              Не-не. $message это общий случай, у тебя конечно же $object. Именно $object доступен в плагине, $message там нет.
                      Дмитрий
                      11 декабря 2019, 20:56
                      1
                      0
                      Вот такой плагин получился, может кому еще пригодится.
                      Обозвал его "Подружить easyComm с LastModified"

                      /**** Плагин: Подружить easyComm с LastModified ****/
                      
                      if ($modx->event->name == 'OnEcMessageSave' || $modx->event->name == 'OnEcMessageUnpublish' || $modx->event->name == 'OnEcMessagePublish') {
                      
                      	$thread = $object->getOne('Thread');
                      
                      	if($thread && $resource = $thread->getOne('Resource')) {
                       
                      		if ($object->get('published') == true && $object->get('publishedon') != null 
                      		|| $object->get('published') == false && $object->get('publishedon') == null && $object->get('extended')['was_published'] == 1
                      		|| $modx->event->name == 'OnEcMessageUnpublish' 
                      		|| $modx->event->name == 'OnEcMessagePublish') {			
                      			
                      			//очищаем кэш
                      			$resource->_contextKey = $resource->context_key;
                      			$cache = $modx->cacheManager->getCacheProvider($modx->getOption('cache_resource_key', null, 'resource'));
                      			$key = $resource->getCacheKey();
                      			$cache->delete($key, array('deleteTop' => true));
                      			$cache->delete($key);
                      			
                      				// проверка - публиковалось ли сообщение
                      				if ($object->get('extended')['was_published'] != 1 && $object->get('published') == true && $object->get('publishedon') != null) {
                      					$v = $object->get('extended');
                      					$v['was_published'] = 1;
                      					$object->set('extended', $v);
                      					$object->save();
                      				} elseif ($object->get('extended')['was_published'] == 1 && $object->get('published') == false && $object->get('publishedon') == null) {
                      					$v = $object->get('extended');
                      					$v['was_published'] = 0;
                      					$object->set('extended', $v);
                      					$object->save();	
                      				}				
                      				
                      				// если в компоненте LastModified включена системная настройка "Обновление родителя" то делаем обновление через процессор
                      				if ($modx->getOption('lastmodified.update_parent') == true) {
                      						$modx->runProcessor('resource/update',$resource->toArray());	
                      					} else { // если выключена, то просто обновляем дату последнего редактирования ресурса
                      						$resource->set('editedon', time());
                      						$resource->save(true);	
                      				}
                      		}		
                      	}
                      }

                      Вроде все работает как задумано. А именно:

                      1. Если редактировать сообщение, которое еще не публиковалось или снятое с публикации, НО при этом не публиковать его, то дата редактирования ресурса и его родителя не меняется кэш не очищается.

                      2. Если опубликовать/снять с публикации сообщение любым способом (из меню в списке или в модальном окне — чекбокс «Опубликовано»), а также если отредактировать и сохранить опубликованное сообщение, то меняется дата последнего редактирования ресурса и очищается кэш ресурса.

                      Кроме того, если в компоненте LastModified включена системная настройка «Обновление родителя», то обновляется также дата редактирования родителя и очищается его кэш. Если указанная настройка выключена, то меняется дата редактирования ресурса и очищается его кэш. С родителем ничего не происходит.

                      Буду благодарен, за конструктивную критику и за предложения по улучшению.

                      Благодарю за помощь!
                        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                        30