Список всех контекстов

Как можно получить список всех контекстов в снипете/плагине? Буду рад ссылкам, подсказкам и прочим добрым словам ))
Юрий Фомин
23 января 2017, 15:02
modx.pro
4
4 646
+1

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

Павел Романов
23 января 2017, 19:54
1
+2
Как-то так:

<?php
$contexts = $modx->getCollection('modContext', array('key:NOT IN' => array('mgr')));
foreach($contexts as $cx) {
    if($cx->prepare()) {
        echo $cx->key.', ';
    }
}
    Максим Кузнецов
    23 января 2017, 20:38
    1
    +2
    $contexts = $modx->getCollection('modContext', array('key:!=' => 'mgr'));
    
    foreach($contexts as $context) {
    	echo $context->key;
    }
      Сергей Шлоков
      23 января 2017, 22:13
      2
      +2
      Кто короче :)
      collection('modContext')->each(function($context){echo $context['key'];});
        Юрий Фомин
        24 января 2017, 10:33
        +1
        Хлопцы! огромное спасибо, и не надеялся на такую щедрость! Спасибо!!!
          Юрий Фомин
          24 января 2017, 10:44
          0
          Может еще мыслишку подкините, как в контекстах, перебором создать страницы в нужных родителях идентично основному? (во загнул )) создаешь в основном контексте ресурс, он дублируется в остальные. заранее спасибо.
            Максим Кузнецов
            24 января 2017, 12:38
            3
            +1
            Примерно так в плагине, но это решение увеличит время создания основной страницы:

            if ($modx->event->name == 'OnDocFormSave' && $mode == 'new') {
            	$contexts = $modx->getCollection('modContext', array('key:!=' => 'mgr'));
            
            	if ($curr_ctx_key = array_search($resource->get('context'), $contexts)) {
            		unset($contexts[$curr_ctx_key]);
            	}
            
            	foreach ($contexts as $context) {
            		//Создаем ресурс (заполняем все основные не-тв поля)
            		$response = $modx->runProcessor('resource/create', array(
            			'template' => $resource->get('template'),
            			'isfolder' => $resource->get('isfolder'),
            			'published' => $resource->get('published'),
            			'pagetitle' => $resource->get('pagetitle'),
            			'parent' => '', //нужно додумать логику, как связывать родителей из одного контекста с другим
            		));
            		
            		if ($response->isError()) {
            			return $modx->error->failure($response->getMessage());
            		}
            		else {
            			//Получаем id свежесозданной копии
            			$newId = $response->response['object']['id'];
            		
            			//Заполняем тв-поля
            			$newPage = $modx->getObject('modResource', $newId);
            			
            			$newPage->setTVValue('Поле_1', $resource->getTvValue('Поле_1'));
            			$newPage->setTVValue('Поле_2', $resource->getTvValue('Поле_2'));
            			//...
            		
            			$newPage->save();
            		}
            	}
            
            	$modx->cacheManager->clearCache();
            
            }
              Сергей Шлоков
              24 января 2017, 13:38
              0
              А не получится ли бесконечного цикла через процессор? А в процессор не нужно контекст передавать?
                Максим Кузнецов
                24 января 2017, 13:56
                0
                Упс, да, не хватает:
                'context' => $context,

                С циклом… мм… да, пожалуй, необходим доп. флажок (или поле со списком связующих элементов, для синхронизации при редактировании) или срабатывание плагина на создание ресурсов только из одного контекста.
                  Сергей Шлоков
                  24 января 2017, 14:09
                  0
                  Наверно проще через newObject, тогда проблема уходит.
                  Юрий Фомин
                  24 января 2017, 23:06
                  0
                  Сергей вы оказались правы по поводу цикла. Притом создание пошло во втором контексте по счету, до третьего контекста он не добрался, вырубило его. буду копать в сторону newObject.
                  Если можете помогите с newObject советом пожалуйста.
                    Максим Кузнецов
                    24 января 2017, 23:15
                    0
                    //создаем ресурс
                    
                    $newResource = $modx->newObject('modDocument');
                    
                    $newResource->set('pagetitle', 'заголовок');
                    $newResource->set('parent', 'родитель');
                    $newResource->set('template', 'шаблон');
                    $newResource->set('published', 1);
                    $newResource->set('context', 'контекст');
                    //...
                    
                    $newResource->save();
                    
                    //заполняем тв-поля
                    
                    $docId = $newResource->get('id');
                    
                    $for_tvs = $modx->getObject('modResource', $docId);
                    $for_tvs->setTVValue('название_тв_поля', 'значение');
                    //...
                    
                    $for_tvs->save();
                      Сергей Шлоков
                      25 января 2017, 08:49
                      +1
                      if ($modx->event->name == 'OnDocFormSave' && $mode == 'new') {
                      	$contexts = $modx->getCollection('modContext', array('key:NOT IN' => ['mgr','web'])); // если web основной
                      	$data = $resource->toArray();
                      	foreach ($contexts as $context) {
                      		$data['context_key'] = $context->key;
                      		$data['parent'] = 0; // Тут нужно продумать логику, иначе в корень будет сохранен.
                      		//$data['alias'] = ...;  // Алиас возможно также нужно переопределить
                      
                      		$newResource = $modx->newObject('modDocument', $data);
                      		//Если есть ТВ - пример кода выше
                      
                      		$newResource->save();
                      	}
                      }
                      Как-то так. Не пробовал. По идее должно работать.
                    Юрий Фомин
                    24 января 2017, 17:44
                    0
                    а сами контексты не нужно распарсить перед действиями в них?
                  Юрий Фомин
                  24 января 2017, 17:54
                  0
                  так как новые ресурсы будут создаваться/удаляться только в основном контексте то вот такой ваниантик работает на ура:
                  $contexts = $modx->getCollection('modContext', array('key:NOT IN' => array('mgr', 'web')));
                  
                  foreach($contexts as $context) {
                  	
                  	$response = $modx->runProcessor('resource/create', array(
                  	        'context_key' => $context->key,
                  		'pagetitle' => 'new'
                  	));
                  }
                    Юрий Фомин
                    24 января 2017, 22:32
                    0
                    тут странность нарисовалась… один и тот же код в плагине с событием OnDocFormSave и в снипете на странице. Но снипет работете, а вот плагин нет. В логах пусто… в чем может быть проблема???
                      Юрий Фомин
                      24 января 2017, 22:45
                      0
                      плагин автоматом выключает… в общем со снипетами проще ))
                        Юрий Фомин
                        24 января 2017, 22:55
                        0
                        прошу прощения мой недогляд
                      Юрий Фомин
                      25 января 2017, 13:05
                      +1
                      Итак… (барабанная дробь) представляю вашему вниманию очередной велосипед!
                      буду премного благодарен если кто то из сожаления или непомерно бОльших знаний поправит это творение мученика науки. Но во всяком случае плагин работает дублируя ресурсы на остальные контенты кроме web.
                      if ($modx->event->name == 'OnDocFormSave' && $mode == 'new') {
                      	$contexts = $modx->getCollection('modContext', array('key:NOT IN' => ['mgr','web']));
                      	
                      	// получаем родителя
                      	$parent = $resource->get('parent');
                      	if ($parent != '0') {
                              $parentId = $modx->getObject('modResource', $parent);
                              $parentAlias = $parentId->get('alias');
                      	}
                          
                              // проходимся по контекстам
                      	foreach ($contexts as $context) {
                      	    
                      	    $newResource = $modx->newObject('modDocument');
                      	    $newResource->set('context_key', $context->key);
                      	    $newResource->set('pagetitle', $resource->get('pagetitle'));
                      	    $newResource->set('alias', $resource->get('alias'));
                                  // пишем еще различные поля для ресурса
                      	    
                      	    if ($parent != '0') {
                      	        $res = $modx->getObject('modResource', array('context_key'=>$context->key, 'alias'=>$parentAlias));
                      	        $parntId = $res->get('id');
                      	    } else {
                      	        $parntId = $parent;
                      	    }
                      	    $newResource->set('parent', $parntId);
                      
                      		$newResource->save();
                      	}
                      	
                      	$modx->cacheManager->clearCache();
                      }
                        Юрий Фомин
                        25 января 2017, 13:29
                        0
                        А вот с удалением не особо получается, помогите пожалуйста кто может советом

                        if ($modx->event->name == 'OnDocFormDelete' && $mode == 'new') {
                            $contexts = $modx->getCollection('modContext', array('key:NOT IN' => ['mgr','web']));
                            
                            foreach ($contexts as $context) {
                                $newResponse = $modx->getObject('modResource', array('context_key'=>$context->key, 'alias' => $resource->get('alias')));
                                $newResponse->remove();
                            }
                        }
                          Максим Кузнецов
                          25 января 2017, 14:12
                          +1
                          Событие OnDocFormDelete не имеет параметра $mode.
                            Юрий Фомин
                            25 января 2017, 14:21
                            0
                            спасибо! работает, но только он удаляет ресурсы в других контекстах сразу без переноса в конзину, а что для этого механизма надо подскажите пожалуйста?
                          Максим Кузнецов
                          25 января 2017, 14:27
                          0
                          $newResponse->set('deleted', 1);
                          Юрий Фомин
                          27 января 2017, 18:56
                          3
                          +2
                          Таки дописал велосипед про автоматизацию создания/удаления и редактирования ресурсов в контекстах-дублях.

                          <?php
                          if ($modx->event->name == 'OnDocFormSave') {
                              // собираем дублированные контексты (web - оригинальный контекст)
                          	$contexts = $modx->getCollection('modContext', array('key:NOT IN' => ['mgr','web']));
                          	
                          	// получаем родителя создаваемого ресурса
                          	$parent = $resource->get('parent');
                          	if ($parent != '0') {
                                  $parentId = $modx->getObject('modResource', $parent);
                                  $parentAlias = $parentId->get('alias');
                          	}
                              $alias = $resource->get('alias');
                              $id = $resource->get('id');
                              // проходимся по контекстам
                          	foreach ($contexts as $context) {
                          	    
                          	    $response = $modx->getObject('modResource', array('context_key'=>$context->key, 'alias' => $alias));
                          	    // если ресурс уже существует то тогда просто обновляем поля (кроме контента)
                          	    if ($response) {
                              	    $response->set('pagetitle', $resource->get('pagetitle'));
                              	    $response->set('longtitle', $resource->get('longtitle'));
                              	    $response->set('description', $resource->get('description'));
                              	    $response->set('content', '[[!OriginalFields?&id=`'.$id.'`&field=`content`]]');
                                      // ... много остальных полей
                              	    $response->set('deleted', $resource->get('deleted'));
                              	    $response->save();
                          	    } else {
                          	        // создание нового ресурса
                              	    $newResource = $modx->newObject('modDocument');
                              	    // заполняем поля ресурса
                              	    $newResource->set('context_key', $context->key);
                              	    $newResource->set('pagetitle', $resource->get('pagetitle'));
                              	    $newResource->set('longtitle', $resource->get('longtitle'));
                              	    $newResource->set('description', $resource->get('description'));
                              	    $newResource->set('content', '[[!OriginalFields?&id=`'.$id.'`&field=`content`]]');
                                      // ... много остальных полей
                              	    $newResource->set('deleted', $resource->get('deleted'));
                              	    
                              	    // поле родителя для создания дубля в нем а не в корне
                              	    if ($parent != '0') {
                              	        $res = $modx->getObject('modResource', array('context_key'=>$context->key, 'alias'=>$parentAlias));
                              	        $parntId = $res->get('id');
                              	    } else {
                              	        $parntId = $parent;
                              	    }
                              	    $newResource->set('parent', $parntId);
                                      // сохраняем свежеиспеченый ресурс
                              		$newResource->save();
                          	    }
                          	}
                          	// очищаем кеш
                          	$modx->cacheManager->clearCache();
                          }
                          
                          // удаление ресурсов в дублирующих контекстах
                          if ($modx->event->name == 'OnDocFormDelete') {
                              // собираем дублированные контексты (web - оригинальный контекст)
                              $contexts = $modx->getCollection('modContext', array('key:NOT IN' => ['mgr','web']));
                              
                              // проходимся по контекстам
                              foreach ($contexts as $context) {
                                  
                                  // получаем нужные (верней не нужные поэтому и удаляемые) нам ресурсы
                                  $response = $modx->getObject('modResource', array('context_key'=>$context->key, 'alias' => $resource->get('alias')));
                                  
                                  // помечаем как удаленные
                                  $response->set('deleted', $resource->get('deleted'));
                                  $response->save();
                                  
                                  // удаляет полностью
                                  // $response->get('id');
                                  // $response->remove();
                              }
                          	$modx->cacheManager->clearCache();
                          }
                            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                            25