aVadim
Newbie-
Posts
15 -
Joined
-
Last visited
Content Type
Profiles
Forums
Marketplace
Articles
FAQ
Our New
Store
Blogs
module__dplus_manager
Everything posted by aVadim
-
Да, видел такого рода темы. Опять же удивляюсь нелогичности решения - казалось бы, минорная версия - и вдруг несовместимость. В таких случаях обычно новую мажорную версию выпускают.А что до напильника - я сначала старался аккуратно вносить изменения, а потом плюнул, напильник бросил, и топор в руки взял. Все, обновляться нормально однозначно не смогу. Ну и ... с ним.
-
В целом - да, согласен. Вот мне тоже так думается, но решил спросить на всякий случай. Последнюю версию внимательно не смотрел, но там, как я понимаю, только функционал добавился, а в целом движок (и шаблоны) такой же безбашенный остался
-
Это все верно. Казалось бы. Но это имеет смысл, когда речь идет о загрузке внешних скриптовых файлов! Именно в этом случае имеет место ограничение по параллельной загрузке браузером нескольких файлов. Но когда исполняемый яваскрипт вшивается в тело HTML, то тут это не играет никакой роли - это все равно один файл.
-
Я, мож, отстал от жизни или какую-то очень хитрую фишку не догоняю, так объясните мне: почему в шаблонах яваскрипты втыкаются в конце шаблона, после html-кода? Для меня лично это настолько непривычно, что крышу сносит. Такое впечатление, что писатели шаблонов плохо помнят (или вообще не знают) про конструкцию jQuery $(function() { // cool code here });...и втыкают яваскриптовый код в конец, чтоб иметь возможность работать с dom-деревом.Или там есть более глубокий сакральный смысл, который от меня ускользнул?
-
Разработчикам на заметку: автозагрузка моделей
aVadim replied to aVadim's topic in Модули и дополнения
Не-а, если будет, скажем, model_tool_seo_url (или, например, какой-нибудь model_tool_yet_another_cool_class), то банальная замена не прокатит. Как вариант, можно, поставить explode и добавить дополнительную логику для "склеивания хвостов", но не уверен, что прям резко в быстродействиии мы выиграем, а вот читаемость кода ухудшится.Да и вообще, страхи относительно регулярок обоснованы там, где выражения какие-то очень уж заковыристые, и/или количество итераций с ними - сотни тысяч. А десяток-другой регулярок с довольно простыми выражениями погоды не делают совсем. Хотя, бесспорно, там, где можно заменить регулярку строковой функцией без ущерба для кода - это нужно делать. -
Разработчикам на заметку: универсальная конфигурация движка
aVadim replied to aVadim's topic in Модули и дополнения
Ну ведь не с самого рождения ты их используешь, верно? ;) Когда-то ты и слов таких не знал. А зачем сложно, когда можно просто? В сравнительно небольших проектах, типа такого, что на ocStore сейчас делается, не вижу необходимости тратить время на это. Внес нужные изменения, проверил работоспособность - и льешь себе на продакшн измененные файлы. -
Если вы серьезно занимаетесь разработкой, а не просто "погулять вышли", то один и тот же проект у вас крутится, как минимум, на двух серверах - на девелопер-сервере (где, собственно, вы и занимаетесь кодингом), и на продакшн-сервере - это уже рабочий сервер у хостера, доступный публике, куда вы заливаете результаты своего труда. Понятно, что самый простой способ залить изменения - это сделать сравнение папок (локальных и удаленных) и залить измененные файлы. Но тут часто разработчики наступают на одни и те же грабли с завидной регулярностью: файла конфигурации. Ведь они отличаются на локальном и удаленном серверах - везде прописаны свои папки, свои пути, свои базы и т.д., которые не совпадают на сервере локальном и на удаленном. Поэтому надо следить, чтобы при заливке файлов измененных файлов не трогались файлы конфигурации. Проблема мелкая, но я сам раньше постоянно на это натыкался - сначала зальешь, потом спохватишься, что сайт перестал работать, и давай быстро конфиги в порядок приводить. В общем, я как-то для себя нашел решение, которое использую сейчас и в ocStore. Для начала я создал в корне проекта файл defines.php, где определяю константу LOCALHOST и общие константы, которые используются и в админке, и в клиентской части: <?php // Определение локального сервера if (($_SERVER['SERVER_ADDR'] == '127.0.0.1' AND $_SERVER['REMOTE_ADDR'] == '127.0.0.1') OR (strpos($_SERVER['SERVER_NAME'], 'localhost') !== false) OR (substr($_SERVER['SERVER_NAME'], -6) == '.local') OR (substr($_SERVER['SERVER_NAME'], -4) == '.loc') ) { define('LOCALHOST', 1); } else { define('LOCALHOST', 0); } define('DOCROOT', dirname(__FILE__)); if (LOCALHOST) { // DB define('DB_DRIVER', 'mysql'); define('DB_HOSTNAME', 'localhost'); define('DB_USERNAME', 'user'); define('DB_PASSWORD', 'psw'); define('DB_DATABASE', 'db_name_local'); define('DB_PREFIX', 'oc_'); } else { define('DB_DRIVER', 'mysql'); define('DB_HOSTNAME', 'localhost'); define('DB_USERNAME', 'user'); define('DB_PASSWORD', 'psw'); define('DB_DATABASE', 'db_name_remote'); define('DB_PREFIX', 'oc_'); } // DIRs define('DIR_SYSTEM', DOCROOT . '/system/'); define('DIR_DATABASE', DOCROOT . '/system/database/'); define('DIR_CONFIG', DOCROOT . '/system/config/'); define('DIR_IMAGE', DOCROOT . '/image/'); define('DIR_DOWNLOAD', DOCROOT . '/download/'); define('DIR_CACHE', DOCROOT . '/_cache/_sys/'); define('DIR_TMP', DOCROOT . '/_cache/_tmp/'); define('DIR_DATA', DOCROOT . '/_data/'); // EOF Затем переписал файлы config.php для клиентской части: <?php require_once 'defines.php'; // DIR define('DIR_APPLICATION', DOCROOT . '/catalog/'); define('DIR_LANGUAGE', DOCROOT . '/catalog/language/'); define('DIR_THEME', DOCROOT . '/catalog/view/theme/'); define('DIR_LOGS', DOCROOT . '/system/logs/'); // EOF и то же самое для админки: <?php require_once '../defines.php'; if (LOCALHOST) { define('SITE_NAME', 'my-site.local'); } else { define('SITE_NAME', 'my-site.ru'); } // HTTP define('HTTP_SERVER', 'http://' . SITE_NAME . '/admin/'); define('HTTP_CATALOG', 'http://' . SITE_NAME . '/'); define('HTTP_IMAGE', 'http://' . SITE_NAME . '/image/'); // HTTPS define('HTTPS_SERVER', 'http://' . SITE_NAME . '/admin/'); define('HTTPS_IMAGE', 'http://' . SITE_NAME . '/image/'); // DIR define('DIR_APPLICATION', DOCROOT . '/admin/'); define('DIR_LANGUAGE', DOCROOT . '/admin/language/'); define('DIR_THEME', DOCROOT . '/admin/view/'); define('DIR_TEMPLATE', DOCROOT . '/admin/view/template/'); define('DIR_LOGS', DOCROOT . '/system/logs/'); define('DIR_CATALOG', DOCROOT . '/catalog/'); // EOF И теперь я смело могу лить любые изменения с локального (девелоперского) сервера на удаленный (продакшн), совершенно не задумываясь относительно файлов конфигураций, чем сохраняю себе при обновлениях энное количество нервных клеток, чего и вам желаю.
-
А, ну так это понятно. Я думал, мож, есть какие-то штатные средства. Ведь ЧПУ может быть включен, а может быть и выключен. Плюс, в разных контроллерах ссылки формируются совершенно произвольным образом - где-то через url_seo, а где-то тупо конкатенацией строк через route. Поэтому каждый раз парсить различные варианты - совсем не айс. Но ситуацию понял - придется самому писать нужную функцию. И, так я чувствую, не одну...
-
Есть какие-то стандартные механизмы узнать текущий контроллер и экшен, запрошенные в УРЛе? Или это самому надо парсить?
-
Разработчикам на заметку: автозагрузка моделей
aVadim replied to aVadim's topic in Модули и дополнения
А тут нет прямой связи. Все зависит от разработчика. Важно понимать, что удобство инструмента - это не самоцель, а лишь способ повысить эффективность работы. Но вот для чего и для эта работа делается - вот это всегда нужно помнить. public function get($key) { if (isset($this->data[$key])) { // если объект (в т.ч. и модель) уже загружен, то он просто достается из массива $obj = $this->data[$key]; } else { // если объекта нет, то проверяем, не модель ли это if (preg_match('/^model_([a-z0-9]+)_(.+)$/', $key, $matches)) { // да, модель, и мы делаем попытку ее загрузить // при этом механизм загрузки точно такой же, // как при вызове непосредственно из контроллера $model = $matches[1].'/'.$matches[2]; $this->get('load')->model($model); } // и еще раз пытаемся вынуть модель из списка загруженных // если выше попытка загрузки прошла успешно, то возвращаем модель // если нет - NULL $obj = (isset($this->data[$key]) ? $this->data[$key] : NULL); } return $obj; } Да я и не прошу вносить это в движок. Я понял уже, что на текущем этапе ocStore - это пока лишь локализованная сборка. Но, возможно, мои советы будут интересны тем, кто не ждет у моря погоды, а кромсает движок самостоятельно, как я. Я, конечно, не понимаю совершенно, какой может быть вред от полезных идей, особенно, если они повышают не только скорость разработки, но и быстродействие работы самого движка. Но со своим уставом в чужой монастырь лезть не хочу -
Разработчикам на заметку: автозагрузка моделей
aVadim replied to aVadim's topic in Модули и дополнения
Да, до кеширования я еще не добрался, пока только мельком глянул. Но, чувствую, придется с этим что-то делать. Либо возьму db-библиотеку какую-нибудь с готовым кешированием, либо просто отдельно кеширование рихтовать буду. Посмотрю, что быстрее и проще окажется. Для меня лично сейчас скорость разработки - самый критичный пааметр. -
Разработчикам на заметку: автозагрузка моделей
aVadim replied to aVadim's topic in Модули и дополнения
А я исхожу из другой парадигмы. Популярность любого движка находится в прямой зависимости от скорости и удобства разработки под этим движком. "Тормоза" в разработке однозначно являются тормозами для развития движка. Нет, не на каждый, смотрите внимательнее код - только при первом запросе. При первом запросе происходит загрузка модели, и все остальные запросы отрабатываются обычным образом. А я в курсе, не первый год програмлю. И я вовсе не сторонник пихать их везде и всюду без надобности. Но до фанатизма тоже не стоит доходить. Сто тыщ регулярок при загрузке страницы - это не очень гуд. А несколько десятков сравнительно простых запросов - это вовсе не проблема. Ну, если будет время, можно, конечно, тесты провести, насколько десяток подобных регулярок тормозят. А так это сугубо теоретический спор -
Движок строится на парадигме MVC, поэтому контроллер получат данные из модели, например, так: $this->model_account_address->getAddress(...);Но перед вызовом модели нам необходимо ее загрузить (зарегистрировать) в регистре: $this->load->model('account/address'); Но зачем опять городить лишний код, если такие мелочи, как загрузка нужной модели, можно делать автоматом? Что я и сделал. В классе Registry я изменил метод get(): public function get($key) { if (isset($this->data[$key])) { $obj = $this->data[$key]; } else { if (preg_match('/^model_([a-z0-9]+)_(.+)$/', $key, $matches)) { $model = $matches[1].'/'.$matches[2]; $this->get('load')->model($model); } $obj = (isset($this->data[$key]) ? $this->data[$key] : NULL); } return $obj; }И... Все! Теперь я могу не задавать явно загрузку модели вызовом $this->load->model(), а сразу обращаться в контроллере к методам модели через $this->model_account_address, и если эта модель еще не загружена, то она автоматом подгрузится в момент обращения.
-
Мне нравится структурный подход. И когда несколько классов имеют повторяющийся код, то для меня это повод задуматься - а не стоит ли вынести этот код в общего родителя? И вот что я сделал. Создал класс Object (файл object.php в /system/engine): <?php abstract class Object { protected $registry; public function __construct($registry) { $this->registry = $registry; } public function __get($key) { return $this->registry->get($key); } public function __set($key, $value) { $this->registry->set($key, $value); } } // EOFИ классы Model и Controller наследовал от него: abstract class Model extends Object { } abstract class Controller extends Object { protected $id; protected $template; protected $children = array(); protected $data = array(); protected $output; public function __construct($registry) { parent::__construct($registry); $this->data['charset'] = $this->language->get('charset'); $this->data['lang'] = $this->language->get('code'); $this->data['direction'] = $this->language->get('direction'); $this->data['template'] = $this->config->get('config_template'); $this->data['store'] = $this->config->get('config_name'); $this->data['t'] = $this->language; } }По побльшому счету, на работу это никак не вдияет, но если теперь нам вдруг потребуется как-то иначе построить логику работы с регистром (т.е. как-то иначе обрабатывать геттеры и сеттеры, то мы будем менять только класс Object.
-
Предисловие Решил начать публиковать свои наработки по движку. Ковыряю движок совсем недавно, меньше трех недель. Но в свой проект внес уже немало улучшений, которые: а) ускоряют разработку б) уменьшают объем кода, улучшая, в то же время, его читаемость в) просто облегчают мне жизнь, как разработчику Т.к. эти мои доработки часто касаются непосредственно ядра движка, то маловероятно, что они будут просто внесены в русскую сборку ocStore. Возможно, команда, работающая над ocStore сможет донести мои идеи до основных разработчиков OpenCart, и они будут учтены в последующих версиях. Но если тут есть разработчики, которые самостоятельно активно пилят движок под свои нужды, то они могут внедрять эти фичи уже сейчас. А теперь приступаю к сути первой фичи. Меня очень удручает частая повторяемость одного и того же кода в скриптах. И я всегда стремлюсь этого избежать. И одним из самых раздражающих факторов в этом движке была необходимость языковые тексты в коде контроллера переносить в $this->data[], и только потом их юзать в шаблонах. Т.е. мы в контроллерах пишем тонны строк кода типа: $this->data['text_blablabla'] = $this->language->get('text_blablabla');и все это только для того, чтобы я мог в шаблоне обратиться к этому тексту: <?php echo $text_blablabla;?> И я сделал так: в классе Controller в метод __construct() добавил public function __construct($registry) { /* здесь имеющийся код ... */ $this->data['t'] = $this->language; } А в класс Language добавил "магический" метод __get(): public function __get($key) { if (preg_match('/^_[^_]/', $key)) return $this->get(substr($key, 1)); }И теперь мне не нужно никаких $this->data['text_blablabla']=..., я в любом шаблоне вывод текстовых строк делаю так: <?php echo $t->_text_blablabla; ?>Ну, или можно сокращенную запись использовать: <?=$t->_text_blablabla; ?> Профит, который я при этом получаю: 1) Значительно уменьшается объем кода в контроллерах и уменьшается (пусть и незначительно) объем потребляемой памяти 2) Уменьшается количество ошибок, связанных с тем, что в контроллере забыл в $this->data[] загнать какой-то текст 3) Уменьшается время на разработку - достаточно новый текст в языковом файле добавить, и сразу его можно в шаблоне юзать, в контроллере ничего менять не надо При этом все старые шаблоны работают, как прежде, можно ничего не трогать и не менять. А вот если вам приходится свои шаблоны писать или просто их править основательно, то забудьте про добавление текстов в контроллере - работайте только с файлом локализации и самим шаблоном, и будет вам щастье! :)
- 1 reply
-
- 6
-
Ну, дык, если мои наработки в основную ветку пойдут - я ж разве против! Буду только рад. Я почему и спрашивал в начальном топике про взаимотоношения, т.к. не знаю просто ни ваших планов, ни задач, ни то, взаимодействуете ли вы с разработчиками OpenCart и т.д.
-
Да, работа с базой - это отдельная тема разговора. Сейчас тут используется простейший класс. Конечно, если делать по уму - надо бы взять какую-то более-менее развитую библиотеку. Но тут опять возникает проблема совместимости. А вот и нет! При таком подходе никто не мешает использовать оба метода - старый и мой. У меня, кстати, сейчас так и работает - мне банально влом сидеть и убирать лишние строки из всех контроллеров и переделывать все шаблоны. Старые контроллеры и шаблоны работают, как есть - текстовые переменные загоняются в $this->data[], а в шаблоне юзаются по их имени. А вот новые шаблоны я уже пишу с использованием своего метода. Ведь тут фишка-то в том, что выдергивание текстов из Language происходит не заранее (на уровне контроллера, как сейчас в Opencart), а на лету - по мере обращения к ним из шаблона.Поэтому уже имеющиеся шаблоны для OpenCart (если нужные переменные добавляются в контроллере) будут работать "на ура!". Но вот шаблоны, сделанные с использованием моей методы, конечно, в стандартном OpenCart работать уже не будут. Вопрос, конечно, спорный, как чисто теоретически, так и в данном конкретном случае. :) Но холивары затевать не хотелось бы, скажу лишь, что я лично скорость разработки ставлю значительно выше экономии "на спичках". Более того, чем выше скорость разработки, тем больше (если разработчик грамотный) профита для пользователя, т.к. за тот же промежуток времени больше "плюшек" для юзера можно напечь. Но это теория.Что же касается данного случая, то при моем подходе мы даже получаем некоторую экономию памяти: 1) Вся языковая база не грузится, используется только то, что подгружено явно вызовом $this->language->load() в контроллере 2) При моем подходе в пространство имен не загружается дополнительно большое число новых переменных (при старом подходе каждый элемент текста - это создание отдельной переменной) 3) При старом подходе все загруженные тексты хранятся в двух экземплярах - в регистре и в пространстве имен. В моем случае - все хранится только в регистре, и извлекается из массива без создания доп. переменных и лишних копий. Ок, буду периодически делиться ими В таком случае, это не форк, а всего лишь локализованная сборка. Жаль :( Но я бы советовал серьезно подумать на тему создания реально своей ветки. Ведь может быть и такое условие - совместимость в одну сторону. Т.е. все, что делается для OpenCart должно работать в ocStore. А вот обратно - не обязательно. По одной простой причине - потому что ocStore лучше ;)
-
Я так понял, тот раздел больше для сбора просьб по улучшению движка предназначен. Я же необорот, готов своими наработками делиться. Причем, главным образом, это не дополнительные модули, а изменения именно в ядре. Но такие, которые экономят время разработки и уменьшают общий объем кода. Правда, тут заковыка одна есть - в какой-то момент времени может возникнуть несовместимость с родительским проектом. Я-то на это особо внимание не обращаю, пилю движок для конкретного сайта вдоль и поперек, не думая о совместимости. Но для вас это может быть важно. Переместил код в новую тему в раздел "Дополнения", т.к. показалось, что это более подходящее место: https://opencartforum.com/topic/2707-%D1%80%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%87%D0%B8%D0%BA%D0%B0%D0%BC-%D0%BD%D0%B0-%D0%B7%D0%B0%D0%BC%D0%B5%D1%82%D0%BA%D1%83-%D1%83%D0%BB%D1%83%D1%87%D1%88%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F-%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D1%82/
-
Очень странное впечатление производит движок. С одной стороны - сырой, кривой, непродуманная архитектура и совершенно жуткий код. С другой - впечатляющий для такого рода движка функционал, и весьма неплохие возможности для допиливания для тех, кто владеет напильником. И после недолгих раздумий решил взять движок за основу для одного проекта. Я как-то не очень понял, как соотносятся ocStore и OpenCart, то ли ocStore - это форк от OpenCart, то ли всего лишь локализованная сборка, дополненная некоторыми модулями. Кто-то может просветить на этот счет? Буду признателен, если кто-то расскажет историю проекта или ткнет ссылкой, где почитать можно. Хотелось бы это понять, чтобы знать - имеет ли смысл писать сюда свои соображения относительно оптимизации кода или нет. Если тут занимаются всего лишь сборкой, не трогая ядра - то смысла нет. Если готовы пилить ядро движка - могу давать советы, кое-какие рекомендации и делиться некоторыми фиксами, которые я вношу в движок.