Добавление модификаторов Fenom

Задался вопросом добавления своих модификатором в парсер Fenom для modx.
Из этого вышел простой модификатор |days, который правильно склоняет «дней», «дня», «день».
вызывать так:
{$dayscount|days}

Для всего этого перво-наперво создаем файлик в дириктории /core/model/modx/pdotools/pdotoolscustom.class.php с содержимым:
gist.github.com/soulcreate/bf202b14173f5d41717f
Да да, нам придется редактировать папку /core/model/modx/ — святая светых ядра modx. Но так делает и сам pdoTools, тем более мы ничего не удаляем\перезаписываем, а просто расширяем класс pdoTools своей функцией вызова fenom. При обновлении modx/pdoTools ничего не должно затереться.
Затем идем в системные настройки pdoTools и меняем pdoTools.class на
pdotools.pdotoolscustom:

Собственно все!

Таким образом, можно задействовать всю мощь fenom и в modx, не создавая кучу маленьких сниппетов-модификаторов.

Что-то мне подсказывает, это ключ для использования composer в modx. К примеру, можно вызывать там autoload.php и применять как модификаторы для переменных.
Алексей
16 ноября 2015, 12:55
modx.pro
13
4 658
+6

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

Василий Наумкин
16 ноября 2015, 15:59
+6
Прикольно! Только советую переписать код вот так:
public function getFenom() {
	$add = empty($this->fenom);
	$fenom = parent::getFenom();
	if ($add) {
		$this->fenom->addModifier('days', function ($day) {
			$a=substr($day,strlen($day)-1,1);
			if($a==1) $str="день";
			if($a==2 || $a==3 || $a==4) $str="дня";
			if($a==5 || $a==6 || $a==7 || $a==8 || $a==9 || $a==0) $str="дней";
			return $str;
		});
	}

	return $fenom;
}

Надо будет придумать какой-то более удобный способ добавления модификаторов в следующей версии.
    Алексей
    16 ноября 2015, 19:26
    0
    только почему-то в inline чанках не работает. пишет:
    Modifier pricess not found in inline/0fd73cb4e653affba9947feef38d9944 line 1, near '{$price_jackpot|pricess' <- there
      Алексей
      16 ноября 2015, 22:09
      0
      выяснил что pdofetch тоже надо расширять, т.к. он расширяет pdoTools напрямую, не смотря на системную настройку modx «pdoTools.class»
      class pdoFetch extends pdoTools {...
        Василий Наумкин
        17 ноября 2015, 07:45
        +1
        PHP не умеет динамически расширять классы.

        Нужно расширить еще и pdoFetch вот так:
        <?php
        if (!class_exists('pdoToolsCustom')) {
        	require 'pdotoolscustom.class.php';
        }
        class pdoFetchCustom extends pdoToolsCustom {
        }
        И указать его там же, в настройке pdoFetch.class — pdotools.pdofetchcustom.

        В общем, советую переписать заметку и код по нашему обсуждению.
          Алексей
          24 ноября 2015, 21:28
          0
          тогда класс pdoFetchCustom не будет ничего знать о методах класса pdoFetch и будет вылезать ошибка:
          Call to undefined method pdofetchcustom::run()
          Алексей
          24 ноября 2015, 21:54
          0
          в общем какой-то замкнутый круг получается. так и не удалось расширить класс pdoFetch с кустомерными модификаторами для безболезненного обновления pdoTools.
          вот тут кстати советуют использовать композитный паттерн, либо eval:
          <?php
          function dynamic_class_name() {
              if(time() % 60)
                  return "Class_A";
              if(time() % 60 == 0)
                  return "Class_B";
          }
          eval(
              "class MyRealClass extends " . dynamic_class_name() . " {" . 
              # some code string here, possibly read from a file
              . "}"
          );
          ?>
      Алексей
      22 декабря 2015, 14:15
      0
      более удобный способ -задать в системных настройках параметр «ID группы сниппетов для модификаторов» и все сниппеты из этой группы инициализировать как модификаторы fenom
        Алексей
        22 декабря 2015, 16:54
        0
        Заслал Pull-request. Только там ошибка, вот так правильно:
        if($opt = $this->modx->getOption('pdotools_fenom_category_snippet_modiffer', null, null, true)){
        				$snippets = $this->modx->getCollection('modSnippet',['category' => $opt]);
        				foreach($snippets as $snippet){
        					$nameSnippet = $snippet->name;
        					$modx = &$this->modx;
        					$this->fenom->addModifier($snippet->name, function ($input, $settings = []) use ($nameSnippet,&$modx){
        						if(is_array($settings)){
        							$settings = array_merge($settings,['input'=>$input]);
        							return $modx->runSnippet($nameSnippet,$settings);
        						}
        						else return $modx->runSnippet($nameSnippet,['input'=>$input]);
        
        					});
        					//echo $snippet->name."\r\n";
        				}
        			}
        Иначе warning возникает на замыкание
          Василий Наумкин
          22 декабря 2015, 18:30
          0
          Спасибо за PR, но:
          1. если есть ошибка, нужно исправлять её в присланном коммите. Если не получается — удалить и прислать заново.
          2. Комментарии типа
          //echo $snippet->name."\r\n";
          нужно удалять
          3. Очень странно вызывать modX::getCollection() в дополнении, которое его изо всех сил старается не использовать и даже пытается заменить своей версией.

          Ну и сама идея тупо загружать все сниппеты из указанной категории элементов мне не нравится. Гораздо лучше было бы просто указать список сниппетов-фильтров через запятую в системной настройке.

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