Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
  • Sign Up

3 вещи, которых мне больше всего не хватает в OpenCart


sv2109

2,021 views

 Share

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

1. Конструктор форм. 
Что есть сейчас?

Каждый разработчик для каждого своего дополнения вручную пишет горы HTML кода со всеми классами, проверками валидности, javascript и так далее. А когда OpenCart меняет например версию Bootstrap с 4 на 5 то с этим меняются десятки css классов и весь этот HTML код нужно вручную переписывать для каждого модуля..  
А теперь только представьте! Был бы в OpenCart какой-то простой конструктор форм, чтобы формы не создавать, как мартышки, вручную и потом изменять по пол дня каждую форму после очередного обновления. А чтобы форму создавать как-то так:

$form = new Form(array(
  'id' => 'my-module-form'
  'action' => '...',
  'field' => array(
    'type' => 'input',
    'name' => 'title',
    'label' => 'Title'
    'rules' => array (
      'required' => true,
      'min_lenght' => 3
    )
  )
));


и потом делаем например $form->render() и передаем результат в шаблонизатор. Все.  


Что это даст?

  1. Модулю будет вообще все равно на какой версии bootstrap или twig работает админка движка, это все нужно знать только конструктору форм и со сменой версии он сам построит нужную форму со всем новым синтаксисом. То есть, мы можем еще под 1.5 создать в контроллере модуля свою форму и эта форма будет работать даже на OpenCart 4 и 5 версии бутстрапа! А если в каком-то OpenCart 5 появится React то нам и тогда будет все равно, потому что конструктор форм поменяется все за наc и модуль и дальше будет работать! 
  2. В конструктор форм можно добавить событие, напр. form/render/before и перед рендерингом всех! форм любой модуль может получить объект этой формы и изменить его как угодно - например добавить какие-то свои поля или целый новый таб с кучей своих полей итд. То есть любой модуль может легко изменить любую форму в админке и каталоге как самого движка так и любого другого модуля. При чем сделает это не через модификаторы которые особенно при изменении шаблонов добавляют кучу конфликтов, а правильным способом через события и добавление новых полей в объект формы. 
  3. В форму также можно добавить такие приятные плюшки как: автоматическую валидацию полей по заданным правилам, с выводом нужных сообщений об ошибках, причем валидация будет работать даже без перезагрузки страницы через аякс. Плюс будет куча встроенных правил для валидации напр. емейлов, ссылок, длины и так далее, просто добавил в правило поля напр. 'required' => true и все, форма сама создаст поле, проверку, вывод ошибки если условие не соблюдено и так далее. 


2. Конструктор SQL запросов. 
Я не говорю о какой сложной ORM, а об очень простом конструкторе запросов. 


Что есть сейчас?
Каждый разработчик пишет кучу SQL запросов вручную. При этом эти запросы изменить из своего модуля можно разве что через модификаторы, порождая тем самым кучу конфликтов. 
А теперь представьте если бы в движке был конструктор запросов и запросы создавались как-то так:

$query = $this->db->select('*')->from('product')->where(...)->limit(10);
$results = $query->execute();


Что это даст? 

  1. И читать и писать такой код легче и понятнее
  2. Можно в сам конструктор добавить и добавление префикса таблицы и автоматическую обработку данных перед выполнением, не нужно для каждого поля вручную делать $this->db->escape, а это в свою очередь и упростит написание запросов и сделает их надежнее и безопаснее.  
  3. Самое главное! Можно создать событие напр. db/execute/before и со своего модуля получить доступ ко всем! SQL запросам на сайте с возможностью изменить каждый, например добавить свой новый JOIN или условие, сортировку итд. 
  4. Имея конструктор в будущем намного проще перейти на новую базу данных, при этом не нужно будет изменять код всех модулей, а только код самого конструктора, чтобы он по готовым правилам создал другой запрос по правилам другой базы данных. 
  5. Для каких-то сложных запросов или ленивых разработчиков всегда останется возможно написать какой-то запрос вручную по-старому. 


3. Нормальная система расширений. 
Для этого:

  1. Полностью выбросить на свалку истории vqmod и ocmod, как причину огромного к-ва конфликтов
  2. Сделать нормальную систему Событий. Писал об этом выше как можно расширить движок при наличии конструктора форм и SQL запросов. Это далеко не все, что нужно для полноценной системы Событий, просто показывает на примере как можно достаточно просто создать огромные возможности для правильного! изменения движка через События.
  3. Добавить другие инструменты такие как валидаторы, хелперы для например создания хлебных крошек, пагинации и десятков других вещей, для которых в движке нужно дублировать кучу кода в каждом модуле. 

 

Конечно, добавить еще можно много всего, но если хотя бы реализовать те 3 пункта что я описал выше мы уже бы получили качественно! другой движок. 
Потому что извините, но в 21 году писать вручную SQL запросы, HTML формы и дублировать тысячи строк кода это.. мне даже слова сложно подобрать, чтобы это описать и никого не обидеть.. одним словом - сюр какой-то.
 

И еще один важный вопрос - усложнят ли все эти нововведения движок? 


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

  • +1 8
 Share

36 Comments


Recommended Comments



Цитата

А чтобы форму создавать как-то так:

ага, еще и по табам разбить

И сделать рендеринг с кучей ифов, которых так не любят в шаблонах, потому как это Логика


$query = $this->db->select('*')->from('product')->where(...)->limit(10);

а где же фильтры?
А как удалять/заменять не нужное из фильтра

Не проблема понять синтаксис любого билдера

Вам удобно? пользуйте свой

Будет в движке? Сильно соменваюсь
 

Цитата

Дублировать тысячи строк кода это..


Кто вам мешает использовать макросы в твиге?
 

Link to comment
Цитата

 так как нужно будет выучить новые инструменты. 

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

  • +1 1
Link to comment

даже не знаю что добавить. вроде все сказано. может быть orm и composer (PSR).

Link to comment
4 часа назад, chukcha сказал:

ага, еще и по табам разбить

именно для табов подобный подход будет исключительно полезен, так как
тот, кому хоть раз приходилось делать форму в которой были табы с двойной или даже тройной вложенностью, те понимают какой это ад, я когда-то создавал с тройной вложенностью, был верхний горизонтальный, потом вертикальный и потом еще табы для разных языков. Эту форму я писал несколько дней. И если в ней вдруг забыть случайно закрыть какой-то див или удалить случайно что-то, то все, можно и пол дня искать причину.. 
В конструкторе же можно легко сделать
'tab' => array(

  'name' => 'Tab1',

  'fields' => (...),

)
или 

'tab' => array(

  'name' => 'Tab1',

  'tabs' => (...)

)

И все работает, и можно делать хоть 2 вложенности хоть 3 хоть даже больше. 
 

4 часа назад, chukcha сказал:

Вам удобно? пользуйте свой

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

 

Link to comment
31 минуту назад, sv2109 сказал:

И все работает, и можно делать хоть 2 вложенности хоть 3 хоть даже больше. 

Не... ведь этот массив надо сформировать..
Это сложнее, чем тупо линейно

Я прекрасно вас понимаю, но это идеология Даниеля

Link to comment

Идея вроде хорошая. Тут главный вопрос: кто это все будет делать и поддерживать. А также публиковать гайды и решать проблемы совместимости с модулями, которые это не используют (к примеру, при необходимости стыковать работу модулей). Вот опубликуйте пару дополнений в таком исполнении, и люди потянутся, наверное.

Стоило бы накидать список задач и раздать каждому желающему (зафиксировав за ним эту задачу). Уверен, что каждый сможет вложить в совокупности не более 3 рабочих дней своего времени на участие в подобное затее. И если в ней не будет четкого плана, то и усилия распылятся в разные стороны.

  • +1 1
Link to comment

С 1 и 2 категорически не согласен в такой реализации. 

1. Достаточно инклюдить готовые наборы (куски) форм, контроллеры (форм), не нужно придумывать интерфейсы и не лишаем гибкости в верстке или уникальных контроллеров UI. Просто обычный include 'common/input_checkbox' или, еще лучше, через closure функцию

<?php echo $input_text($title, 'title', $error_title); ?>

2. Именно из-за чистого SQL запроса мне и нравится этот двиг. Здесь вообще ничего не надо менять, разве что DB_PREFIX я бы добавлял где-то в либе и, может быть, парсил запрос на предмет int|string для автоматического экранирования данных. Все, не надо выдумывать цепочки методов, вы 100 процентов уткнетесь в ограничения при написании сложных запросов и тогда пойдут велосипеды и каша из новых и старых методов исполнения запросов.

  • +1 2
Link to comment
9 минут назад, SooR сказал:

int|string для автоматического экранирования данных.

PDO?

Link to comment
11 минут назад, SooR сказал:

2. Именно из-за чистого SQL запроса мне и нравится этот двиг. Здесь вообще ничего не надо менять, разве что DB_PREFIX я бы добавлял где-то в либе и, может быть, парсил запрос на предмет int|string для автоматического экранирования данных. Все, не надо выдумывать цепочки методов, вы 100 процентов уткнетесь в ограничения при написании сложных запросов и тогда пойдут велосипеды и каша из новых и старых методов исполнения запросов.

А я на вот эту няшку смотрю http://wiki.ubilling.net.ua/doku.php?id=nyanorm

И думаю, ну не няшно ли?

Link to comment
4 минуты назад, chukcha сказал:

PDO?

Можно и через pdo, кому как удобней, но в самом opencart, если мы говорим о моделях, сам API запросов я бы не менял

Link to comment
5 минут назад, Vladzimir сказал:

А я на вот эту няшку смотрю http://wiki.ubilling.net.ua/doku.php?id=nyanorm

И думаю, ну не няшно ли?

Если вам няшно - пожалуйста, я вижу, что из одной строки условно простого запроса сделали 4. В чем упрощение? Не видеть SELECT * FROM?

  • +1 2
Link to comment

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

Второе автоэкранирование данных.

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

Ну и по мелочи. Например читабельность запроса. Особенно если он на десяток строк.

Link to comment
$payments->where('cashtypeid', '=', '1');
$payments->orWhere('cashtypeid','=','4');

Серьезно? Вам проще писать строку с запятыми и кавычками, чем просто строку?

 

Проще же WHERE foo = 'bar' AND baz = 3.

А копировать запрос и делать отладку прямиком в базу? А откорректированный запрос вставить в $this->db->query()? Не проще ли?

  • +1 2
Link to comment
1 минуту назад, SooR сказал:
$payments->where('cashtypeid', '=', '1');
$payments->orWhere('cashtypeid','=','4');

Серьезно? Вам проще писать строку с запятыми и кавычками, чем просто строку?

 

Проще же WHERE foo = 'bar' AND baz = 3.

А копировать запрос и делать отладку прямиком в базу? А откорректированный запрос вставить в $this->db->query()? Не проще ли?

Экономим на запятых?

Link to comment
1 минуту назад, Vladzimir сказал:

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

С этим согласен, но на практике это будет не всегда так.

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

 

2 минуты назад, Vladzimir сказал:

Ну и по мелочи. Например читабельность запроса. Особенно если он на десяток строк.

Ну смотрите. Вы пишите сложный запрос, перед вами запрос в исходном виде, читаете док по мускулу или ищите другую инфу в сети по каким-то частям запроса, везде вы видите чистый запрос, во всех примерах и разборах только чистые запросы, переключаетесь в редактор, а там куча вызовов через php конструктора запросов. Как они работают закулисами? Что добавляют эти методы? Добавляют `` или нет? Каждый раз смотреть в ман по api? При этом держать в голове сам запрос, еще и думать как его расписать) По-моему не совсем удобно.

  • +1 1
Link to comment
3 минуты назад, Vladzimir сказал:

Экономим на запятых?

Сводим к минимуму опечатки. Запятая не всегда на своей клавише, как и '

Link to comment

Но всегда же можно вывести "скомпилированный" запрос.

Link to comment
3 минуты назад, Vladzimir сказал:

Но всегда же можно вывести "скомпилированный" запрос.

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

Link to comment

Как по мне, то проще абстрагироваться от конкретных сущностей и писать именно логику, а не следить за кавычками/скобками/экранированием и тому подобное. Тем более что IDE обычно не могут нормально подсвечивать синтаксис опенкартовских запросов.

Link to comment

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

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

  • +1 2
Link to comment
27 минут назад, SooR сказал:
$payments->where('cashtypeid', '=', '1');
$payments->orWhere('cashtypeid','=','4');

Серьезно? Вам проще писать строку с запятыми и кавычками, чем просто строку?

 

Проще же WHERE foo = 'bar' AND baz = 3.

А копировать запрос и делать отладку прямиком в базу? А откорректированный запрос вставить в $this->db->query()? Не проще ли?

не проще. потому что в вашем случае, например, вы строку не экранируете

  • +1 1
Link to comment
38 минут назад, SooR сказал:

Проще же WHERE foo = 'bar' AND baz = 3.

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

Конструкторы усложнят код - да, не сильно но усложняют. 
Но они дают преимущества, которые с лихвой перекрываю это. 
Одно из самых больших преимуществ - возможность использовать систему Событий для изменения любого! запроса в движке. И при системе событий и 2 и 3 и даже больше модулей могут изменить один запрос и конфликтов при этом будет в десятки раз меньше, так как все будет делаться через понятный api а не через str_replace или preg_replace. 

 

  • +1 1
Link to comment
31 минуту назад, lexxkrt сказал:

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

смотрите в 4-ку
По идее почти так, например стандартные модули от опенкарт собраны в

extension\opencart\
 

Link to comment
25 минут назад, lexxkrt сказал:

не проще. потому что в вашем случае, например, вы строку не экранируете

А вы уверены, что обертка экранирует '1' как int, а не string? А как на счет экранирования bigint(20)?

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

 

Спойлер
SELECT * FROM ( 
  SELECT 
    SUM(IF(f.result = 'success', 1, 0)) AS total_forecast_success, 
    SUM(IF(f.result = 'unknown', 1, 0)) AS total_forecast_unknown, 
    ROUND(SUM(IF(f.result = 'success', f.payable, f.amount)) - SUM(f.amount)) AS series_profit, 
    GROUP_CONCAT(f.forecast_id) AS forecasts_id, 
    COUNT(f.forecast_id) as total, 
    MIN(f.date_added) as date_start, 
    MAX(f.date_added) as date_end, 
    c.customer_id 
    
    FROM ( 
      SELECT customer_id, forecast_id, date_added, payable, amount, result, 
        
        IF(customer_id = @customer_id, @sequence, @sequence := @sequence + 1) AS c1, 
        IF(customer_id = @customer_id, @customer_id, @customer_id := customer_id) AS c2, 
        IF(result = 'unknown', @result := 'success', @result := result) AS r2, 
        IF(@result = @previous, @sequence, @sequence := @sequence + 1) as sequence, 
        IF(@result = @previous, @result, @previous := @result) AS r3 
         
        FROM forecast, 
        (SELECT @sequence := 0, @previous := '', @result := '', @customer_id := '') AS init 
          WHERE is_paid = '0' ORDER BY customer_id, forecast_id
     ) f 
     
     LEFT JOIN customer c ON (f.customer_id = c.customer_id) 
     WHERE (f.result = 'success' OR f.result = 'unknown') 
     GROUP BY sequence HAVING total > 1 
     ORDER BY total_forecast_success DESC, total_forecast_unknown ASC, series_profit DESC
) series WHERE date_end >= '2021-05-17'
GROUP BY customer_id 
ORDER BY total_forecast_success DESC, total_forecast_unknown ASC, series_profit DESC

 

 

Link to comment
1 минуту назад, chukcha сказал:

смотрите в 4-ку
По идее почти так, например стандартные модули от опенкарт собраны в

extension\opencart\
 

нет я сосем про другое. там просто папка расширения вынесена, но контроллеры модели а также папки расширений лежат раньше самих файлов. я же предлагаю порядок extensions/author/module_name/{controller,model,language,view}. т.е. модуль целиком в единой папке, а не по разным

  • +1 1
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

On our site, cookies are used and personal data is processed to improve the user interface. To find out what and what personal data we are processing, please go to the link. If you click "I agree," it means that you understand and accept all the conditions specified in this Privacy Notice.