Перейти до вмісту
Пошук в
  • Детальніше...
Шукати результати, які ...
Шукати результати в ...

hook pre render Идея и примерная реализация


Recommended Posts

Приветствую всех. Я занимаюсь опенкартом относительно недавно, до этого работал с Друпалом. Весь Друпал построен на системе хуков (крючков). С помощью которых один модуль может внести изменения в работу другого. Например один модуль может создать меню, а другой добавить к этому меню новый пункт. Или один модуль может создать тип материала, например Товар с полями Название, Описание, Цена, а другой модуль к этому типу добавить свое поле Производитель. Всего есть десятки хуков с помощью которых можно переопределить почти все - меню, типы материалов, пользователей.. можно добавить свой код например после создания нового материала или при запуске крона итд. В результате получается очень гибкая система, в которой с помощью нескольких строк кода без изменения кода ядра можно сделать что угодно.

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

Изучив код опенкарта я понял, что весь рендеринг происходит через метод render класса Controller. До рендерига в массив $data собираются данные для каждого шаблона. То есть если перед ренедерингом дать возможность модулям менять массив $data.. то это даст очень мощный инструмент, с помощью которого можно было бы без изменения кода ядра и использования vqmod менять (добавлять, удалять) очень много всего - меню, ссылки, хлебные крошки, информацию о товарах, категориях.. вообще любую переменную шаблона!

Накинул примерную реализацию:

В методе render() класса Controller:

перед

extract($this->data);
добавить

$this->hookPreRender();

Добавить метод hookPreRender():

	protected function hookPreRender() {
	  $extensions = $this->model_setting_extension->getExtensions('module');

	  foreach ($extensions as $extension) {
		$action = new Action('module/' . $extension['code']);
		$file = $action->getFile();
		$class = $action->getClass();
		$method = 'preRender';
		$action = NULL;
		if (file_exists($file)) {
		  require_once($file);		  
		  $controller = new $class($this->registry);
		  if (is_callable(array($controller, $method))) {		  
			$template = strpos($this->template, $this->config->get('config_template')) !== FALSE ? $this->config->get('config_template') : 'default';
			$template = str_replace(array($template . '/template/', '.tpl'), '', $this->template);
			call_user_func_array(array($controller, $method), array(&$this->data, $template));
		  }
		}
	  }
	}

Все, всего несколько строк кода..

Теперь в своем модуле можно создать метод контроллера

public function preRender(&$data, $template)

например:

public function preRender(&$data, $template) {
	if ($template == 'common/footer' && isset($data['informations'])) {
	  unset($data['informations'][0]);
	}
  }
Этот код удалит первый элемент массива статей в шаблоне футера.

Хочется услышать мнение сообщества насчет подобной инновации. Если вещь стоящая то можно подумать как оптимизировать код и предложить добавить это в оф. релиз движка.

  • +1 5
Надіслати
Поділитися на інших сайтах

вот тут предлагают еще одно решение, посмотри :) может заинтересует

http://www.opencart....icense=0&page=5

мне кажется не решено здравого смысла :)

  • +1 3
Надіслати
Поділитися на інших сайтах


вот тут предлагают еще одно решение, посмотри :) может заинтересует

http://www.opencart....icense=0&page=5

мне кажется не решено здравого смысла :)

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

Бегло просмотрел код. Там вводится еще один слой абстракции - фабрика, с помощью которой можно переопределять методы других классов. Правда переопределяется все через какой-то variable stream, пока не разобрался с этим.

Шаблоны переопределяются через хелпер modifier или через str_replace, короче тот же vqmod только с другой реализацией..

Плюс еще один слой, который серьезно усложняет логику и может конкретно увеличить скорость загрузки страницы.

Короче пока двойственные чувства. С одной стороны классно, то что нужно, с другой слишком сложно и тяжело и местами ничем не отличается от vqmod-a.

  • +1 1
Надіслати
Поділитися на інших сайтах

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

А как быть, если несколько изменений последовательно перехватывают рендер? Те же гоабли, что и vQmod, только менее гибкий, поскольку опять же влияет лишь на данные, а не на логику.

Невозможно один хуком поменять и данные и события и вообще все.. В Друпале используется целая система из нескольких десятков хуков, тут же привел пример всего одного, с помощью которого можно поменять все данный в шаблоне, по-моему неплохо как для 20 строк кода.

Насчет "те же грабли что и vqmod" в корне не согласен. Так как с помощью vqmod изменяется код ядра движка, что является очень плохой практикой программирования, есть даже рисунок по этому поводу :) А вариант с хуками вносит изменения без правки кода ядра, изменяя лишь данные или поведение. По-моему разница очевидна.

Насчет того, что несколько модулей могут менять одни данные. Во-первых это не так критично как изменение кода движка, так как меняются только данные и не затрагивается код. Во-вторых можно как-то присвоить приоритет каждому модулю. Можно даже дать пользователю возможность из админки выставлять эти приоритеты для модулей, как сейчас сделан "Порядок сортировки" для модулей.. итд. вариантов масса. Я не привел окончательную реализацию всего механизма, а лишь показал тестовый пример.

Надіслати
Поділитися на інших сайтах

Ну а что мешает в своем модуле не создавать какой-то там preRender, а взять и переопределить render можно с вызовом родительского класса?

Проблема в том, что render нашего модуля будет работать только с данными контроллера этого модуля, а нам нужно изменить данные прежде всего других классов. Тут нужно или как-то переопределить главный контроллер или добавить пре рендер. Другого пути я не вижу.
Надіслати
Поділитися на інших сайтах

Мне кажется, что проблема OpenCart отчасти в том, что слишком много логики перенесено в шаблоны. Из-за этого создание темы слишком сложная штука для рядового верстальщика, да и изменения приходится делать часто какими-то vQmod.

Почти все изменения в логике можно сделать наследованием, тем более, что все там на MVC - проще некуда.

Да.. вроде все на классах, а как переопределить какой-то класс? Например какой-то контроллер или модель? Причем сделать это без правки кода движка?

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

Надіслати
Поділитися на інших сайтах

Что есть код движка? system/* или все файлы оригинального openCart? Добавил свой контроллер, который наследует существующий контроллер и можно в теме URLы поправить

Тут вопрос не в том чтобы сделать так, чтоб работало.. Это можно.. создать кучу своих классов, которые унаследуют существующие, поменять кучу кода движка и все заработает. Вопрос сделать это красиво без изменения кода движка. Причем нужна возможность делать это с помощью модулей. Нужен функционал, который даст модулю возможность без изменения стороннего кода и без использования vqmod и прочих костылей менять логику работы сайта.

Нет нормального способа вести разработку своих модулей параллельно и независимо от разработки основного движка.

Я уже неоднократно наводил пример - Друпал. Там с помощью хуков можно изменить почти все. Причем Друпал это не какая-то левая система, а цмс мирового масштаба, на которой работает огромное количество сайтов.

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

Надіслати
Поділитися на інших сайтах

Кстати, еще один пример, сейчас как раз читаю как круто это все реализовали в Симфони с помощью паттерна Наблюдатель. Статья на Хабре часть1, часть2

  • +1 2
Надіслати
Поділитися на інших сайтах

С удовольствием почитал Ваш спор... Я недавно сам с собой на эту же тему похожу беседу вел.

P.S.

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

Класс для валидации можно слямзить где угодно и использовать как библиотеку.

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

А я бы не отказался от вспомогательно библиотеки для формирования отдельных HTML структур. Когда смотрю на <select> в шаблонах, то слезы на глаза наворачиваются - все равно что заглянуть под капот и увидеть там белку в колесе.
  • +1 2
Надіслати
Поділитися на інших сайтах

Конкретная задача? Да сколько угодно! Берем любой модуль, у которого какой-то функционал реализован через vqmod (а таких процентов наверное 80), нужно реализовать этот функционал без использования vqmoda и правки кода движка. Например, нужно добавить с помощью своего модуля новый пункт меню.

Надіслати
Поділитися на інших сайтах

vQmod вообще ерунда полная.

Да.

А сделать интерфейс для модулей можно кучей способов: хуки, наследование, наблюдатель, свой роутинг...

Все эти способы предполагают так или иначе внесение изменений в базовые функции системы. Я бы не отказался, если бы хоть что-то из списка было предусмотрено как "стандартное решение".

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

Да, статика в админском меню - это пиздец.

если у клиента прошлая версия, где нет этих библиотек?

Поставляем библиотеку с модулемшаблоном. Абсолютно версиянезависимое решение. Уж точно более независимое, чем "...хуки, наследование, наблюдатель, свой роутинг...".
  • +1 1
Надіслати
Поділитися на інших сайтах

Привет всем. Наконец то нашел раздел где можно с вменяемыми людьми пообщаться. На самом деле Механизм оверрайда не подменяет хуки и наоборот. Они только взаимодополняют друг-друга. Оверрайд используется практически повсеместно для наложения кастомизации на базовое ядро без переделок последнего. В Magento, поскольку написана на ZF. В Престе механизм оферайда имеется, что позволяет легко наращивать функционал и более того, легко переносить его при обновлении версий ядра.

В Друпале используются хуки, поскольку при построении ядра до последнего времени там мало использовалось ООП. По крайней мере 6 и 7 Друпал отличаются в этом плане консерватизмом. Хуки это зарезервированные места где вызываются функции, логику которых и возвращаемое содержание может определить кастомизатор. По сути хук это уже готовая вставка в определенных местах, сделанная при разработке движка без vqmod. Собственно vqmod в ОС это уродство, призванное компенсировать отсутствие в движке этих двух мощнейших механизмов, давно и эффективно используемых во всем цивилизованном программистском мире. Именно из-за их отсутствия шаблоны ОС перегружены логикой из-за чего возникают проблемы их переносимости между версиями. Например именно за счет хуков такие движки как Prestashop и Drupal имеют такой колосальный потенциал расширяемости за счет модулей.

Хорошо что хотя бы сейчас некоторые разработчики начали понимать эти недостатки, о чем свидетельствует ссылка на модуль для реализации оверрайда по последнюю версию движка. В общем я за то, чтобы OC вышел наконец из каменного века методов разработки, характерных для PHP4.

Вопрос только как это сделать? Может свою сборку собрать какую-то? Есть мысли на эту тему?

  • +1 2
Надіслати
Поділитися на інших сайтах


В плане архитектуры vQmod действительно уродство, но он позволяет откатиться, если модуль не подошел. Без нормального механизма, который бы позволял вносить обратимые изменения не получится ничего.

OpenCart в плане объектов - это капец. Таких больших методов в контроллерах еще поискать надо. От них наследоваться бессмысленно.

cmd, библиотека давно напрашивается и ее написание здорово ускорит разработку новых дополнений, но не изменит существующей архитектуры. Бесспорно, будет легко плодить формы в админке, будет легко делать новые хитрые шаблоны. Но для добавления нового OpenCart достаточно открыт:

Чтобы добавить какой-то инфоблок в OpenCart уже есть механизм - модули

Чтобы прикрутить способы оплаты, доставки или экспорта - уже есть места, куда их приткнуть

Проблема начинается тогда, когда надо изменить ПОВЕДЕНИЕ т.е. контроллеры у которых методы - портянки кода. Приходится переписывать контроллеры либо полностью, либо vQmod'ами.

ИТОГО

Пока генеральная версия OpenCart не примет волевое решение открыть еще один способ изменений, помимо vQmod-а, мы мало что придумаем с изменением архитектуры. Если только свою сборку и гнаться за оригинальным OpenCart. Но чем больше изменений, тем сложнее будет угнаться. И в итоге полностью откажемся от OpenCart и будем дорабатывать свою сборку отказавшись от тучи платных-бесплатных модулей. И тем смым выйдем из community разработчиков.

А вот над библиотекой полезностей стоит подумать.

Не полностью согласен. Оверайд и есть замена vqmod с легким откатом. Удалил перезаписываемый класс и все. То же самое что удалить файл xml-описания модификаций в vqmod. Разница только в простоте разработки и отладки такого кода и оверайд здесь имеет огромное преимущество, особенное если делаешь что-то серьезное а не тупо шаблоны ляпаешь.

Кроме того, оверайд не обязательно должен заменить полностью vqmod.

Приведенная выше библиотека, реализующая оверайд и есть обновление о котором мы говорим. Фактически это и есть часть библиотеки полезностей :-). Я ее обязательно проверю как появится свободная минутка. Хуки в ОС тоже реализованы по аналогии с той же Престой, только в меньшем объеме. Это лэйауты. В Престе таких крючков больше и понапиханы они везде, поэтому там наращивать функционал за счет модулей проще.

Из библиотек я бы подумал над введением CRUD классов для основных объектов (товаров, заказов, клиентов, атрибутов, опций и т.п), а то получается глупо как-то, когда для админки одни модели, а для фронтофиса другие, хотя работают с одной и той же информацией. Явное дублирование кода. Причем загрузить одновременно одноименные модули админки и фронда не возможно.

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

  • +1 1
Надіслати
Поділитися на інших сайтах


Вот кстати у товарища попалась задачка https://opencartforum.com/topic/13149-%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%86%D0%B8%D1%8F-%D0%BE-token-%D0%B0%D0%B4%D0%BC%D0%B8%D0%BD%D0%B0/, когда из фронтенда нужно загрузить админку, чтобы получить токен, а код построен так, что одновременно запустить по сути два автономных сайта (админки и фронта) не возможно.

Надіслати
Поділитися на інших сайтах


Друзья, Вы безусловно правы. И такой механизм действительно нужен, как его не назови: хуками, наследованием или событиями...

Но на текущий момент, мне кажется, самое слабое звено опенкарта - это его автор, принимающий в штыки всё новое. Интересующиеся могут почитать https://github.com/o...encart/pull/158 и сами сделать выводы. Можно ещё посмотреть сколько пулреквестов отклоняется и какие пулреквесты принимаются (в основном, это исправление неточностей перевода, какие-либо незначительные мелочи) При Даниэле ничего подобного хукам или наследованию в опенкарте не будет. Из этого следует, что нужно либо делать форк опенкарта и дальше его независимо развивать, причём всем желающим, а не только русскоязычному сообществу, либо пытаться такие хаки делать как топикстартер и распространять их вместе со своими модулями, что тоже не сахар.

  • +1 3
Надіслати
Поділитися на інших сайтах

Но на текущий момент, мне кажется, самое слабое звено опенкарта - это его автор, принимающий в штыки всё новое.

У меня сложилось подобное мнение после прочтения темы на оф. форуме OpenCart 1.6.0 Roadmap там народ предлагает разные вещи, которых им не хватает, что бы хотелось видеть в новых версиях. Куча народу предлагало изменить систему модулей и архитектуру.. без толку.. Зато вроде решили добавить vqmod в ядро (фейспалм). То есть для авторов более важным является например добавить поддержку нескольких продавцов для товара (реальный пример с этой темы) или возможность добавлять картинки для товаром с внешних источников (еще один реальный пример) чем что-то поменять в архитектуре. Такое ощущение, что их вообще все устраивает.. а кого не устраивает - добавим вам vqmod в ядро и зачем что-то там выдумывать.. хуки, наследование.. пользуйтесь vqmodом и будет вам щастье!..

Ну неужели так сложно понять элементарную вещь - от разработчиков движка требуется 2 вещи: 1. Создать хорошее ядро 2. Создать нормальную систему модулей Все! Все остальное люди сами допишут.. и несколько продавцов и внешние ссылки для рисунков и еще 100500 других модулей..

  • +1 2
Надіслати
Поділитися на інших сайтах

Если кто-то хочет нажать "fork", то никто не запрещает. Но я не хочу ещё одну ветку. Я хочу одно лаконичное и красивое решение. Давайте устроим конкурс :ugeek: Потом выберем из предложенных вариантов победителя и будет придерживаться этой линии :lol:

  • +1 1
Надіслати
Поділитися на інших сайтах

Как я все вижу. Нужно:

1. Точно сформулировать проблему. Потому что начали с хуков а закончили обработчиками форм.

2. Подтянуть русское сообщество в тему.

3. Найти решение этой проблемы. Тут 2 варианта:

3.1. Пересмотреть уже имеющиеся решения, некоторые ссылки есть в этой теме, изучить их код, соответствие стандартам, идеологии движка итд.

3.2. Если ниодин вариант не устраивает, то совместными усилиями найти решение. Возможно это будет система хуков или механизм наследования или наблюдатель

3.2.1 Написать минимальную реализацию, пусть с багами и минимальным функционалом но чтобы можно было запустить и посмотреть как оно работает.

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

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

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

  • +1 2
Надіслати
Поділитися на інших сайтах

Если удастся создать альтернативную вменяемую сборку, то я за. На самом деле так линукс начинался. Сделали хорошее ядро, а от него пошли разные направления. И ни кто от этого не страдает. Вон в Ubuntu какую конфетку сделали. Например что мешает встроить в новую сборку движок оверайда и vqmod в дистритубив? Я попробовал вчера движок оверайда, заработал на чистом движке сразу и без проблем. В документации сразу говориться что он может быть совместим с vqmod. В доке по движку кстати было упоминание о preRender, но до конца разбираться не было уже сил. Я кое что проверю, но пока по прикидкам возможности оверайда по модификации форм могут быть не малые, если перехватывать выхлоп родительского метода, парсить его как HTML код и на лету добавлять свои фрагменты, а потом отдавать модифицированный.

А голосования результата мне кажется не дадут, если хозяин всего этого дела - твердолобый. Нужно хозяина менять. Спасение утопающих, как говориться дело рук самих утопающих.

  • +1 1
Надіслати
Поділитися на інших сайтах


Как я все вижу. Нужно:

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

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

Надіслати
Поділитися на інших сайтах


Честно говоря, раздражает полный игнор темы со стороны OC Team :unsure:

sv2109, нет сейчас времени испробовать, но даже если где-то накосячино за энтузиазм надо +100 в карму

Надіслати
Поділитися на інших сайтах

  • vQmod - говно! Я когда увидел в коде опенкарта что его встраивают - заплевал весь монитор.
  • Нужен и оверрайд и хуки. Глупо выполнять тяжелые расчеты, а потом изменять/удалять результаты...
  • Для реализации обсуждаемого надо делать свою сборку. Уговаривать Дэниеля на изменения ядра - тупая трата времени...
  • Для поддержки своей сборки нужны не только прогеры. Ещё нужны дизайнеры, верстальщики, переводчики и координатор проекта.
  • Готов поддержать эту движуху, но кому такая сборка нужна? На форуме людей понимающих о чем идёт речь в этой теме - полтора человека... остальных всё устраивает, а vQmod вообще вызывает дикий восторг :(.
  • +1 4
Надіслати
Поділитися на інших сайтах

Yesvik, я тоже как раз думал о проблеме, мол: если делать свою ветку -> нужен супорт. Чтобы был супорт -> своя ветка должна быть популярной.

Я вижу решение в следующем:

Вместо отдельной ветки мы делаем "хак" с зычным названием и source на github. Хак будет модифицировать поведения ядра и он должен быть максимально простой в установке. В идеале это будет одна кнопка "Install" и "Uninstall", соответственно. Сколько строк кода нам надо изменить? Желательно 5-10 в 3-4 файлах - максимум. После этого все аддоны которые мы (=здесь собравшиеся) будем выпускать будут идти в пакете с этим хаком. Таким образом народец постепенно привыкнет, а там глядишь или Даниэль одумается или свою сборку можно будет выпускать.

sv2109, посмотрел Ваш вариант (извиняюсь, что бегло). Это получается, что надо регистрировать много событий в том же system/engine/controller.php? Правильно? Не фен-шуйно... Вот если сделать API для регистрации событий, то это будет другое дело.

  • +1 1
Надіслати
Поділитися на інших сайтах

Створіть аккаунт або увійдіть для коментування

Ви повинні бути користувачем, щоб залишити коментар

Створити обліковий запис

Зареєструйтеся для отримання облікового запису. Це просто!

Зареєструвати аккаунт

Вхід

Уже зареєстровані? Увійдіть тут.

Вхід зараз
  • Зараз на сторінці   0 користувачів

    • Ні користувачів, які переглядиють цю сторінку
×
×
  • Створити...

Important Information

На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність.