Блог антисоциального программиста

phpBB Constructor


Alek$ пт, 12/08/2021 - 19:57

Пришло время представить широкой публике проект, над которым я работал все последнее время. Знакомьтесь,

phpBB Constructor

Вводная

phpBB — один из самых лучших open source движков для создания форумов. На нем работают сотни тысяч конференций, многие из которых обладают впечатляющей функциональностью. И несмотря на то, что в базовой комплектации phpBB3 предоставляет практически все, что может понадобиться для создания форума, его истинная сила в модах, написанных сообществом. В настоящий момент только в его официальном каталоге модификаций зарегистрирован 431 мод разной сложности. И еще больше можно найти на форуме, в разделе бета-версий.

Однако, несмотря на усилия phpBB Group, установка модов по-прежнему является непростой задачей для людей, далеких от IT (снобы от phpBB в этом месте замечают, что это как естественный отбор: не справились с установкой мода — нечего вам вообще администрированием форума заниматься, а фрилансеры начинают тонко намекать на свои услуги). Установка модов вручную требует усидчивости и внимательности, а AutoMOD справляется не со всеми модами (и хорошо, если он сам где-нибудь свалится, хуже, если он мод установит, а проблемы обнаружатся недели через три, когда уже и непонятно, откуда у них корни). Кроме того, поиск нужных модов, при условии, что сам толком не знаешь, что ищешь, остается хитрым и увлекательным квестом.

Эпоха сборок

Проблемы, описанные мною, стары как мир phpBB2. На пике популярности phpBB стали появляться команды энтузиастов, которые вручную делали сборки дистрибутивов phpBB2, включающие в себя более или менее широкий набор модов, совершенно необходимых по мнению авторов сборки. Самым известным проектом из этой серии был, наверное phpBB Plus, впечатлявший новичков симпатичной модификацией subsilver и полусотней модов на борту.

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

С выходом phpBB3 количество активно поддерживаемых сборок существенно сократилось благодаря богатому функционалу базового дистрибутива и скорому релизу официального AutoMOD'a, но несколько проектов все же осталось на плаву.

Сделай сам!

И вот тут-то на сцену выходит phpBB Constructor. Он позволяет самому выбрать состав сборки, которая вам нужна из предлагаемого набора модов, а так же указать нужные вам локализации. После чего эта сборка будет автоматически создана на основе свежайшего дистрибутива phpBB3 и отдана вам :-)

Таким образом, Конструктор выигрывает и у готовых сборок "от умельцев", поскольку вы можете сами выбирать состав сборки, и у упомянутого AutoMOD'a: в него включены моды, решающие наиболее распространенные проблемы, и они заранее протестированы на работоспособность и совместимость. В результате, вы в несколько кликов получаете хороший базовый набор модов, и при желании можете так же расширить его самостоятельно после установки форума.

Я записал небольшой скринкаст, демонстрирующий работу с phpBB Constructor:

 Участие - приветствуется

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

А пока лишь приведу список наиболее интересный фитч, которые я планирую сделать:

  • Собственные профили сборок, с возможностью генерации пакетов автообновлений.
  • Форма предложения модов и сообщения о выходе новой версии мода, чтобы мне было проще поддерживать моды в актуальном состоянии.
  • Разбивка модов по категориям.
  • Рекомендуемые моды.
  • Генерация инструкций по модификации нестандартных стилей.
  • Авотматический скрипт для установки на нестандартные стили.

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

Кроме того, я и сообщество phpBB в целом будем благодарны, если вы примете участие в локализации модов из Конструктора для разных языков.

Open Source

Я давно являюсь сторонником open source, и потому планирую как можно больше наработок, вошедших в phpBB Constructor, передать phpBB-сообществу. Сюда относятся и сердце конструктора — MOD Library, и все правки, которые мне приходится вносить в моды для обеспечения совместимости, и другие вспомогательные инструменты. Кроме того, есть публично доступная Зона 51 зона разработки, в которой каждый может наблюдать за ходом разработки и репортить баги.

PS. Europe — The Final Countdown

Обработка множества исключений: решение


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

Решение 1, читерское.

В условии было сказано, что надо обрабатывать исключения в методах init(), run() и shutdown(). И хотя это явно не оговаривалось, по логике функционирования эти методы вызываются подряд. Следовательно, можно сделать так:

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

Достоинства решения:

  • простота;
  • минимум дублирования кода;
  • локальность модификации кода.

Недостатки:

  • жестко привязываемся к сценарию последовательного вызова методов init(), run(), shutdown(), в реальной жизни может потребоваться вызывать их из разных частей приложения в разные моменты времени;
  • метод-обработчик исключений должен очень многое знать обо всех возможных исключениях, при появлении нового исключения придется править метод-обработчик.

Решение 2, логичное.

Следующее решение приходит в голову практически сразу после прочтения условия, и оно действительно хорошо подходит для решения задачи.

Именно его в комментариях предложил Vladimir Rusinov, за что ему спасибо:

Достоинства решения:

  • простота,
  • независимость от мест вызова методов (то есть, их не обязательно вызывать подряд),
  • минимум дублирования кода,
  • локальность правок.

Недостатки решения:

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

Решение 3, хитрое.

Это решение в конечном итоге я и использовал в своем проекте. Сначала я приведу код, а потом дам дополнительные комментарии:

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

В PHP все исключения имеют по умолчанию два поля (есть и другие, но они нас не интересуют): $message = null и $code = 0, сообщение и код ошибки соответственно. Во всех наших исключениях мы переопределяем значение по умолчанию для кода ошибки, чтобы оно соответствовало типу исключения.

Теперь, когда мы создаем исключение, мы можем задать ему сообщение, которое описывает причину его возникновения, и, если надо, можем уточнить и код ошибки. Если же мы сообщение вручную не зададим - оно будет получено через класс Errors. В случае, если мы поймаем "не наше" исключение (типа простого Exception), у него код ошибки будет 0, и класс Errors успешно опишет его как "Unknown exception".

Достоинства решения:

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

Недостатки решения

  • требуется дополнительная логика для прерывания обработки, если упадет init(), либо проброс исключения дальше,
  • нелокальность правок при внедрении решения (надо проставить коды ошибок всем существующим исключениям),
  • менее тривиальное решение,
  • возможны сложности в случае, если есть исключения, которым нельзя переопределить код ошибки.

Итоги

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

Упражнение: обработка множества исключений


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

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

  1. init() — инициализирует, необходимые для обработки запроса объекты.
  2. run() — запускает обработку бизнес-логики.
  3. shutdown() — освободжает ресурсы.

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

Так же будем считать, что нам на любом этапе доступен метод Client::reportError($error_code, $error_message), который обеспечивает вывод клиенту сообщения об ошибке и прекращение работы программы.

Теперь собственно формулировка проблемы: необходимо во всех трех методах обеспечить обработку всех возможных исключений, для каждого из исключений надо выдать код ошибки и ее текстовое описание, а потом вызвать Client::reportError() с соответствующими параметрами. Замечу, что у исключения может быть задан текст описания ошибки, и в таком случае желательно его сохранить, поскольку он скорее всего будет более информативен, чем стандартная заглушка. В принципе, вы можете модифицировать весь код системы, в т. ч. создавать новые классы и менять существующие, если это необходимо.

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

Как бы вы решили такую задачу? Языки решения принимаются любые в пределах разумного: Java, PHP, C++. Не возбраняется использование языко-специфичных конструкций, если они действительно удобны — расширение кругозора никому лишним не будет ;-)

Я нашел два приемлемых решения, и опишу оба завтра, если их никто не назовет до меня.

Три top-подобных утилиты, которые должны быть на каждой Linux-машине


Практически всем пользователям знакома утилита top, показывающая интерактивный список процессов, отсортированный по нагрузке на процессор. История этой утилиты идет от 1984 года, когда Уильям ЛеФевр написал такую утилиту для BSD 4.1. С тех пор top или его аналог есть практически в каждой UNIX-подобной ОС.

Годами доказав свою практичность, top вдохновил многих других программистов на разработку похожих утилит, относящихся к разряду must-have на любой Linux-машине, поскольку они дают возможность быстро оценить ситуацию в системе.

htop

htop — это логическое развитие top. Его интерфейс сделан с помощью ncurses, и благодаря этому он предоставляет гораздо больше возможностей по визуализации процессов и общей загрузки системы, а так же значительно более интуитивный интерфейс настройки всего этого.

iotop

Эта замечательная утилита выручит вас, когда надо выяснить, кто же это так активно пишет на диск, что все остальные процессы едва ли не колом стоят: она выводит список процессов, отсортированный по скорости чтения/записи на диск. Полезно запускать ее с ключом -o, тогда она не будет засорять вывод процессами, которые на диск ничего не пишут.

iftop

Эта утилита аналогична предыдущей, но показывает она загрузку сетевого интерфейса. Надо заметить, что в отличие от двух предыдущих программ, она для работы требует прав root'а, и для запуска ей желательно указать имя интерфейса, который ей надо мониторить с помощью ключа -i.

Итог

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

PS. Star One — Earth That Was

Аспекты реализации нового движка блога


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

Технические требования

  • Язык программирования: PHP 5.1+
    В принципе, я мог бы себе позволить и использовать PHP 5.3, мигрировав блог на мою VPS, но я не вижу в этом большой необходимости, тем более, что хостинг от EOMY за много лет показал себя с лучшей стороны.
  • СУБД: MySQL.
    Здесь выбор тоже практически очевиден: MySQL есть на любом хостинге и мне привычно с ним работать.
  • Фреймворк: Yii Framework
    Выбор фреймворка — тема не простая, так что ее я прокомментирую отдельно.
  • Миграция и обратная совместимость: весь контент должен быть перенесен и адаптирован к новому движку, все ссылки в постах должны остаться действующими, со старых URL постов должен быть редирект на соответствующие новые.

Yii Framework

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

Помимо этого есть еще плюсы в его копилку:

  • Фреймворк сам по себе написан очень хорошо и работает быстро
  • Фреймворк быстро развивается и не отягощает себя поддержкой устаревших технологий (камешек в сторону CakePHP)
  • Есть внушительный централизованный репозиторий расширений, которые реализуют наиболее сложные фитчи "из коробки".
  • Наконец, есть базовый скелет блога на Yii, на написании которого построен официальный тьюториал. Кроме того, я нагуглил довольно много попыток развить эту основу до состояния нормального движка, которые надо внимательно изучить и, возможно, взять за основу.

Этот вечер я посвятил просмотру репозитория расширений и нашел там много полезного для себя и будущего движка :-)

С чего начать?

Перечислю для истории все проекты, которые я рассматриваю как потенциальную базу для движка:

  • Bliig — произвел на меня наиболее положительное впечатление, судя по всему более-менее серьезная разработка.
  • YiiBlog — развитие Yii Blog Demo с официального сайта. Суда по всему, автор, как и я, затачивает его исходя исключительно из собственных пожеланий, которые немного расходятся с моими. Но все же он заслуживает рассмотрения, хотя и во вторую очередь.
  • Yii BlogDemo Extended — другая попытка развить демо-приложение блога. К сожалению, развитие не имеет четкого направления и поэтому в нем появилась такая глупость как флеш-часы. Кроме того, проект уже год никак не развивается, поэтому он пригоден разве что для подсматривания идей решения разных задач, но не как полноценная основа.
  • YiiApp — попытка содать универсальный каркас приложения на Yii. Попытка, судя по всему, достойная, но для меня не очень подходящая.
  • yay-cms — простая CMS на базе Yii. В качестве основы для блога подходит плохо, но в отношении создания обычных сайтов проект интересный, поэтому заслуживает упоминания.

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

Внимательное изучение этих проектов мне, видимо, еще предстоит, но я вижу два наиболее вероятных варианта:

  1. Взять за основу Bliig и танцевать от него.
  2. Взать за основу официальное демо, а найденные проекты использовать как шпаргалки для подсматривания решений.

Open Source

Я до сих пор еще не принял окончательного решения, но скорее всего движок будет приватным по двум причинам:

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