Full-stack web developer, love Open Source
–0,1
рейтинг
7 апреля 2015 в 12:09

Разработка → Cобрать лучшее из двух миров — фреймворков и CMS (часть 2)

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

Для чего


Из прошлой статьи не всем было понятно, для чего всё это создается, конкретная проблема, которую решает продукт.
Проще всего объяснять такие вещи на примере. CleverStyle CMS не подойдет если:

  • Под вашу задачу есть CMS, которая решает задачу полностью
  • Под вашу задачу есть CMS, которая почти подходит, вы её подпилите, обновления вас особо не беспокоят
  • У вас Enterprise проект

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

Singleton




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

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

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

$Session = \cs\Session::instance();

Всё что клиентскому коду нужно знать — он получит объект сессии с предсказуемым публичным интерфейсом, но это может быть не совсем оригинальный системный объект, либо даже совсем не он.
Так же это позволяет без каких либо плагинов и дополнительных аннотаций генерировать подсказки в IDE по всем публичным методам и свойствам системных объектов, что чрезвычайно удобно.
Аналогия из Laravel:

$Session = $app->make('session')

Вот только здесь для подсказок IDE нужно писать аннотации.

А ещё подмененный Singleton для тестов позволяет вместо возвращаемого объекта подсовывать что угодно, и это активно используется.

Composer




Было много комментариев о Composer, PSR4 и с этим связанным. Если немного углубиться в подробности того, как устанавливаются компоненты и на что влияют их зависимости, становится понятно, что Composer мягко говоря не самое подходящее решение для упаковки компонентов.
«Но ведь он так удобен для установки библиотек!» скажете вы, и будете несомненно правы.
Подключать одну и ту же библиотеку несколько раз в составе разных компонентов и страдать из-за разных версий не кошерно.
Поэтому дополнительно к поддержке composer.json, composer.lock и vendor в корне проекта появился отдельный компонент с неожиданным названием Composer!
В процессе использования взаимодействие с самим Composer при условии что зависимости не конфликтуют сводится в нулю.
Для того, чтобы воспользоваться этой прелестью нужно добавить зависимость от composer в meta.json компонента, и прописать сами зависимости, пример для модуля WebSockets:

{
	"package"          : "WebSockets",
	"category"         : "modules",
	"version"          : "0.29.0+build-45",
	"description"      : "WebSockets server based on Ratchet and React with client-side bindings as well",
	"author"           : "Nazar Mokrynskyi",
	"website"          : "cleverstyle.org/cms",
	"license"          : "MIT License",
	"db"               : [
		"pool"
	],
	"db_support"       : [
		"MySQLi"
	],
	"provide"          : "websockets",
	"require"          : [
		"System>=2.1",
		"System<=3.0",
		"composer"
	],
	"require_composer" : {
		"cboden/ratchet" : "0.3.*",
		"ratchet/pawl"   : "0.1.*"
	},
	"multilingual"     : [
		"interface"
	],
	"hide_in_menu"     : 1
}

В процессе установки компонента будут собраны Composer зависимости всех компонентов, составлен финальный composer.json, и если не возникнет конфликтов — всё установится само, если возникнут — консольный вывод Composer будет переформатирован в HTML, и предоставлен пользователю, пусть решает что с этим делать.

Вот такой composer.json генерирует модуль для установки всех зависимостей:

{
	"repositories" : [
		{
			"type"    : "package",
			"package" : {
				"name"    : "modules\/Http_server",
				"version" : "0.8.0+build-13",
				"require" : {"react\/http" : "0.4.*"},
				"dist"    : {
					"url"  : "\/web\/cscms.org\/www\/components\/modules\/Composer\/empty.zip",
					"type" : "zip"
				}
			}
		},
		{
			"type"    : "package",
			"package" : {
				"name"    : "modules\/WebSockets",
				"version" : "0.24.0+build-38",
				"require" : {
					"cboden\/ratchet" : "0.3.*",
					"ratchet\/pawl"   : "0.1.*"
				},
				"dist"    : {
					"url"  : "\/web\/cscms.org\/www\/components\/modules\/Composer\/empty.zip",
					"type" : "zip"
				}
			}
		}
	],
	"require"      : {
		"modules\/Http_server" : "0.8.0+build-13",
		"modules\/WebSockets"  : "0.24.0+build-38"
	}
}

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

Разделение логики и представления




В идеале на сервере никакого представления.
Пока готово как пример в клиентской части модуля магазина (ниже), хотя и будет обновляться с использованием JSON-LD для минимального объема серверного кода и лучшей индексации.
Сейчас страничка товара магазина в коде выглядит так:

<section data-date="0" data-id="1" data-in_stock="24" data-price="20" data-soon="0" is="cs-shop-item">
	<div id="images">
		<img alt="" src="http://cscms.org/storage/public/Plupload/2015-01-03/18/2_031854a812c6b264b.jpg">
		<img alt="" src="http://cscms.org/storage/public/Plupload/2015-01-03/18/2_035654a812ec26d24.jpg">
		<img alt="" src="http://cscms.org/storage/public/Plupload/2015-01-03/18/2_035654a812ec1c834.jpg">
	</div>
	<div id="videos">
		<a href="https://www.youtube.com/watch?v=rHBxJCq99jA"> </a>
		<a href="https://www.youtube.com/watch?v=bmtbg5b7_Aw"> </a>
	</div>
	<h1>Boots</h1>
	<div id="description">
		<p>Nice boots</p>
	</div>
	<div id="attributes">
		<table>
			<tr>
				<td>Size</td>
				<td>2</td>
			</tr>
		</table>
	</div>
</section>

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

Стиль кодирования




То, что предлагают PSR мне не очень нравится, поэтому стиль кодирования был немного обновлен в wiki, дополнительно теперь в репозитории лежат файлы конфигурации стиля кодирования и инспекций PhpStorm, при открытии проекта он сразу будет сконфигурирован должным образом.
Все новые файлы форматируются этим стилем, старые файлы при редактировании тоже.
Просьба уважать стиль автора проекта)

Рефакторинг




В промежутке от версии 1.0 в порядок приводилось ядро, в результате обширного рефакторинга система стала существенно понятнее и более предсказуемая, а так же стали возможными некоторые функции, как то работа в Request/Response режиме (о чём далее).

Глобально:

  • класс cs\Trigger был переименован в cs\Event, чтобы больше не сбивать с толку, так же был упрощен и появились новые возможности, как то одноразовая подписка на событие, как jQuery.fn.one()
  • дополнительно появился cs.Event на фронтенде с теми же методами, порядком аргументов что и cs\Event на сервере
  • cs\Session образовался после очередного рефакторинга cs\User, позволяет дополнительно ускорить работу в асинхронном режиме
  • cs\Route объединил функциональность, отвечающую за маршрутизацию, которая по историческим причинам была одновременно в cs\Config и cs\Index, что было далеко не очевидно
  • $_SERVER оборачивается в массиво-подобный объект для простоты получения нужной информации независимо от конфигурации, это позволило избавиться от дублирования кода
  • \ExitException используется вместо exit/die в тех редких местах, где они были, сторонние библиотеки легко патчатся автоматическим поиском и заменой для поддержки этой функциональности, критическая фича для режима Request/Response
  • некоторые встроенные функции, работающие с глобальным контекстом, были заменены на обертки (header() -> _header()), сторонние библиотеки легко патчатся автоматическим поиском и заменой для поддержки этой функциональности (либо если используются пространства имен — просто объявляется пользовательская header() в том пространстве), критическая фича для режима Request/Response

Множество других изменений перечислять нет смысла, release-notes.md свыше 480 строчек с детальным описанием ключевых изменений и рекомендациями к плавному обновлению.

Частично отрефакторен системный модуль, но только частично. Больше рефакторинга красивого и разного ещё будет.

Статический анализ




Раньше весь статический анализ заключался в инспекциях IDE PhpStorm, сейчас же каждый коммит дополнительно проверяют SensioLabsInsight и Scrutinizer.
Эти два инструмента творят чудеса статического анализа. На текущий момент исправлены все Major недочеты, которые они понаходили, и частично Minor/Warning.
Инструменты активно используются, их отчёты будут уменьшаться с каждым коммитом.

Релизы




Начиная с 1.110 все сборки автоматизированы, в случае прохождения тестов после каждого коммита ночная сборка улетает на SourceForge в папку nightly, если это релиз — собирается релизная версия и падает в stable/{version} там же.
Это упрощает релизы и убирает все те неудобства, которые возникали с публикацией релизов в виде странички со ссылками на файлы в Dropbox.

Новые фичи




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

Http сервер

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

WebSockets

Тоже было здесь, тесно интегрирует WebSockets с CleverStyle CMS, позволяя отправлять данные клиенту и обратно практически в реальном времени без излишней нагрузки, по принципу устройства похоже на модуль Http сервера.

Магазин

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

Оплата Bitcoin

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

Подсветка синтаксиса

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

Напоследок




Система активно развивается, код становится чище, проще, понятнее, обрастает новой функциональностью, постоянно пополняется и поддерживается актуальной документация.

Обратная совместимость сохранялась всю ветку версий 1.x, версия 1.110 была последней из этой серии.
Устаревший код был недавно удален в связи с переходом на 2.х версии, так же минимальное требование к версии теперь PHP 5.5+.
При условии что все рекомендации по обновлению выполнялись, обновление с 1.110 до 2.x весьма тривиальное.

Проще всего запустить и попробовать с помощью Docker
Весь исходный код на GitHub, там же wiki с документацией.
Назар Мокринский @nazarpc
карма
28,0
рейтинг –0,1
Full-stack web developer, love Open Source
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (56)

  • +3
    То, что предлагают PSR мне не очень нравится...
    Открыл первый попавшийся класс — (https://github.com/nazar-pc/CleverStyle-CMS/blob/master/core/classes/DB.php) (до этого открыл в корне ещё один файлик — там всё ещё хуже). Хм, а может всё же стоит подумать о PSR? Без обид, но это…
    • +1
      Там если помотреть, то знаки = выравниваются табами, в новых файлах, по которым прошелся рефакторинг и реформатирование выглядят лучше, к тому же вместо 4 пробелов на табуляцию GitHub ставит 8, и получается совершенно не читаемо.
      Вот, например, новый отрефакторенный файл: github.com/nazar-pc/CleverStyle-CMS/blob/master/core/classes/Event.php
      Ещё один, более нагруженный, но выглядит тоже читаемо: github.com/nazar-pc/CleverStyle-CMS/blob/master/core/classes/Session.php
      Ну и смотреть лучше в редакторе, клонируйте, откройте в PhpStorm, там подтянется конфигурация и всё будет так, как оно задумывалось.
      В статье должны были быть скриншоты с примером форматирования и рефакторинга, но парсер их скушал, вот они:
      Скрытый текст
      image

      Скрытый текст


      То есть в том конкретном файле основная проблема не PSR, а то, как он написан.
      • +4
        А вот отформатированный по PSR: gist.github.com/SerafimArts/2c8f26e03bc8b9221b5c
        Код хоть и довольно сильно попахивает, но по-моему всё же более читаем.

        Короче, у меня позиция следующая, думаю вполне логичная. Если пишешь на рубях, то кровь из носу используй андер_скор и прочие его прелести, если на пыхе, то PSR. Не важно нравится или нет — код пишется для сообщества и будь терпеливым, но пересиль себя, и напиши как принято, а не как хочется. Пусть даже табы и лучше, не важно, принято другое.
        • +1
          Я немного о другом.
          Хороший код не становится плохим, если используется что-то отличное от PSR, аналогично плохой код не становится хорошим от переформатирования согласно PSR. Он просто визуально немного иначе выглядит, вот и всё.
          • +2
            То что визуально выглядит иначе — уже означает, что читать его сложнее и уж тем более писать под него, т.к. приходится следовать его стандартам, а их опять же придётся учить.

            Так что очень хорошо, что есть автоматический кодстайл для IDE, но это всё равно не панацея, ибо привычки, как минимум именования чего-либо (например переменных) всё же сохраняются, а оно не исправляется IDE.
  • +1
    -̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶-̶
    Тут было много текста по поводу PSR, который «не нравится»; тестов, которые ничего не тестируют; Composer и прочего, но, поскольку вы не воспользовались подсказками из предыдущей серии, текст был выпилен.
  • 0
    к тому же вместо 4 пробелов на табуляцию GitHub ставит 8, и получается совершенно не читаемо

    Да начнется битва!

    Так привык к симфонийскому/psr форматированию, что на тот же use через запятую смотрю с болью.
    К слову, долго не мог понять, зачем прописывать неймспейсы в классе, пока не врубился, что это трейты. Поэтому я за использование суффиксов Interface, Trait, хоть это и считается дурным тоном
    • +1
      Почему считается «дурным тоном»? По-моему это даже входит в стандарт (в какой-то, вроде Zend, в PSR поискал — не нашёл такого): «AbstractClass» (для абстрактных классов префикс), «SomeInterface», «AnyTarit» (для остального постфиксы) и т.д.
      • 0
        Это касается не только PHP, а именования в программировании в общем. Я особо не вчитывался в эти дебаты, просто знаю о существовании таких споров, причем против суффиксов выступают многие авторитетные личности :)
        • 0
          Наверное подобные дебаты корнями уходят в другие языки программирования, например для джавы принято использовать префикс «I» (англ. ай) для интерфейсов, а у VB и Delphi использовать «SomeForm» для форм или «AnyString» для строк. Наверняка подобное есть и в шарпе\плюсах, но точно сказать не берусь.

          В любом случае в их случаях отказ от префиксов вполне обоснован — в нынешнее время типизация определяется на уровне IDE. Хотя и в случае с PHP — обоснование отказа от префиксов, наверняка будет точно таким же. Мда, философский вопросец…
    • +2
      Никакой битвы не будет, в этом нет смысла. Я всегда уважаю стиль проекта, когда отправляю pull request, не важно, PSR он, или какой угодно другой. Для уменьшения дискомфорта в репозиторий добавлен конфиг, который переформатирует по Ctrl+Alt+R всё за вас.
      Это всё не влияет на работу кода, просто дело вкуса, спорить об этом зачастую нет никакого смысла. Если всё же есть желание аргументировано по пунктам пообщаться — пишите в личку.
      • 0
        Не, у меня нет в первую очередь времени, а не желания.
        Мое личное мнение, что большинство разработчиков проходят определенные шаги при написании кода. Примерно как здесь: vk.com/wall-30666517_796260
        Что касается php, ваш код сейчас примерно на шаге yii/ci/kohana. Следующий шаг: zend/symfony/magento. Но разумеется, не все могут/хотят делать следующий шаг, называя такой код излишне перегруженным с кучей ненужного мусора.
        Я когда переходил с CI/Joomla на Zend1 первое время поплевался, но потом несколько месяцев поражался элегантности его кода.
        Это не значит, что я хочу обоср*ть ваш код, исключительно личное наблюдение, и выборка не самая большая.
        Сейчас с приходом psr/composer/github стало намного проще писать хороший код, чем в наше время :D
        • +1
          Вы правильно угадали по поводу перегруженности. Это вытекает в том числе из специфики.

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

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

          Но, если же вам захочется что-то заменить, у вас всё ещё есть такая возможность. Вы можете положить альтернативный класс в пространство имен cs\custom, и реализовать тот же публичный интерфейс, что и у оригинального класса (можно даже унаследовать системный класс, и переопределить часть методов).

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

          Вот так просто мы обошлись без излишних сложностей, поскольку в абсолютном большинстве ситуаций оно вам и правда не нужно.
  • +1
    Composer мягко говоря не самое подходящее решение для упаковки компонентов

    В идеале на сервере никакого представления

    То, что предлагают PSR мне не очень нравится

    модуль, который реализовывает Http сервер на PHP


    Если честно, то первым побуждением было попросить Вас самовыпилиться из профессии.

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

    Сообщите, если хотите сменить работу и готовы к переезду в Москву.
    • 0
      То же самое побуждение возникло. Ваше предложение автору можно воспринимать как благородное намерение.
    • 0
      На счёт «никакого представления» я имел ввиду вот что: github.com/nazar-pc/CleverStyle-CMS/issues/7#issuecomment-93171348
      Обертка в виде веб-компонента, и семантические данные внутри в формате JSON-LD. Больше никакой верстки связанной с представлением сервер не генерирует.

      Если вы не понимаете что за веб-компонентами и семантическими данными будущее — это не повод советовать другим самовыпилиться из профессии, а повод почитать об этих технологиях и заполнить пробелы в знаниях.

      По другим цитатам кроме PSR (который дело вкуса) можно дать такие же комментарии.

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

      seyfer, к вам этот комментарий также относится.
      • 0
        Вам не про то хотели сказать, насколько я понял. Смысл немного в другом — вот вроде сделали функциональную CMS, и на ней много чего полезного можно сделать. Но только Вы это быстро сделаете, потому что знаете всю свою архитектуру, которая отличается от распространенных фреймворков, знаете какие однобуквенные переменные вы используете и т.п. В общем фреймворк, удобный Вам, а не разработчикам. А почему — потому что код нечитаемый, некоторые решения неочевидны, единого стиля нет, а стандартизировать продукт для своей целевой аудитории Вы не хотите, потому что «PSR — дело вкуса»
        • 0
          Я вам так скажу. Если бы была цель сделать Symfony — я бы взял Symfony, если бы была цель сделать WP — я бы взял его и не парился.
          Но у них есть фатальные недостатки (шутка).

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

          Однобуквенные переменные — это, вероятно, об $L, но класс называется cs\Language, и после первого обращения к объявлению переменной вопрос отпадает, скорее всего вы будете делать так же:). Другие подобные вещи исправляются когда обнаруживаются в старом коде во время рефакторинга, прошу конкретные примеры, если вам такое попадалось.

          По поводу стандартизации — яНеМогуБезБолиЧитатьТакойТекст, мне_гораздо_более_читаем_вот_такой_вариант, соответственно я не перейду на camelCase, можете любить его или нет, это правда дело вкуса, и я не сменю его на что-то, что вырвиглазно для меня.
          Менее читаем код от этого не становится, он может быть слегка непривычным поначалу.

          По поводу единого стиля — он есть, зафиксирован в документации, и новый код ему следует полностью, старый рефакторится/реформатируется соответственно, так что заявление не обосновано.
          • 0
            Не очень красиво смотрится
            Еще один пример
            Зачем? Во славу Сатане, конечно!
            Ок, к единому стилю рано или поздно вы придете, что не мешает пока что глазам слегка кровоточить при взгляде на ссылки что я прислал.Да и вроде как в современных IDE есть рекурсивное форматирование, которое сразу весь проект отформатирует согласно настройкам. По крайней мере читабельно будет все и везде
            И хотелось бы узнать, что в вашей системе принципиально новое, что основано только на вашей разработке и идее, а не является результатом перелопачивания под свои нужды уже существующего? Киллер-фичи типа веб-сокетов, семантической разметки, веб-сервера — уже на основе существующего
            И если вам_нравится_такой_текст и табы вместо пробелов, то может на вордпресс что-нибудь годное напишете? И сообществу польза, и вам практика и комфортно.
            • 0
              Если бы вы читали статью — заметили бы, что кроме того что IDE поддерживает автоматическое переформатирование, так ещё и конфиг для оного теперь лежит в репозитории. Указанные ссылки примеры ещё не переформатированного кода, о чём я и писал выше. Он будет переформатирован когда будет подвергаться изменениям, либо просто планово понемногу.

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

              В рамках комментария сложно объяснить, посмотрите хоть по диагонали эту статью, да прошлую. Практически любое решение написанное под CleverStyle CMS по ту же Symfony будет написать дольше и с большими накладными расходами, уже в многих комментариях это доказывалось на примерах, в том числе здесь, ниже в комментариях.
              • 0
                А у меня другая IDE и не нравится ваш стиль. Что теперь?
                Устройство иное, оно не основано на других фреймворках и сделано максимально удобно (а не максимально академически правильно)

                А совместить удобство и «правильность» пробовали?
                Про скорость разработки — кто к чему привык и лучше знает, на том и быстрее напишет. Если вы привыкли к своей системе, то да, естественно напишете что-то быстрее, чем на Zend, к примеру, или на другом любом фреймворке или CMS, которую не знаете. Даже если напишете быстрее, то кто это будет поддерживать? Если же кроме вас никто не сунется в проекты на вашей системе — то вообще не имеет значения как это все работает. Повторюсь, вы позиционируете свое творение как продукт для разработчиков, но не учитываете требования и пожелания своей аудитории, говоря «это мне не нравится», «принципиально новый подход» и подобное
                Удобно может быть и получилось, но только для Вас.
                • 0
                  А совместить удобство и «правильность» пробовали?

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

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

                  Вот честно, на сколько глубоко вы разобрались в системе? А теперь давайте представим вашу реакцию на такое же тщательное изучение WP или Symfony, так, навскидку. Я думаю, вы понимаете о чём я. Разрабатывать не почитав как система устроена безответственно и контрпродуктивно. Документация к системе есть, постоянно расширяется, то, что вы её не читали не позволяет сделать вам сделать полные выводы.

                  А ещё вы переоцениваете важность camelCase vs snake_case в поддерживаемости проекта, очень сильно переоцениваете. Раньше (пару лет назад) не было PSR, и ничего, миллионы проектов успешно развивались и поддерживаются по сей день, а вы (и некоторые другие комментаторы) делаете вид что всё остальное от лукавого, совсем не читаемо и не поддается никакой поддержке. Да что это вообще за бред, а?
                  • 0
                    Немного слоупочу, но все ж отвечу, т.к. не могу не поделиться впечатлениями.
                    Ради интереса установил и потыкал вашу систему. И если уж вы сравниваете свое творение с wordpress, то хочу сказать, что при первом взгяде на него мне показалось, что все очень просто сделано. Да, пусть и говнокод местами, но как инструмент для быстрого создания блога или небольшого сайта он великолепен. Отличная документация в духе «хочешь что-то сделать — читай здесь как надо».
                    В общем установил вашу систему. Вроде красиво, все поставилось и запустилось. Фейл состоялся в том, что может я напутал пароль, потому что при установке пароль админа вводим только 1 раз без подтверждения, или же косяк системы, но войти в админку мне не удалось. Ну это не такая и проблема была бы, если бы согласно документации не нужно было для добавления блоков и модулей залезать в админку.
                    Ну да ладно, давайте отбросим мелочи типа форматирования (просто буду нажимать Alt+Shift+F в каждом файле), косяк с регистрацией нового пользователя (возможно из-за того что из-под винды сижу что-то пошло не так)
                    Давайте немного об упрощении разработки.
                    Как я понял, чтоб создать свою тему/шаблон сайта или как это в вашей терминологии, мне нужно будет создавать подобное ?
                    А имея готовую верстку мне все равно придется дописывать в нее такие фрагменты:
                    github.com/nazar-pc/CleverStyle-CMS/blob/master/themes/CleverStyle/index.html
                    <?php
                    /**
                     * @package		ClevereStyle CMS
                     * @subpackage	CleverStyle theme
                     * @author		Nazar Mokrynskyi <nazar@mokrynskyi.com>
                     * @copyright	Copyright (c) 2014-2015, Nazar Mokrynskyi
                     * @license		MIT License, see license.txt
                     */
                    namespace cs\themes\CleverStyle;
                    use
                    	cs\Menu,
                    	cs\User,
                    	h;
                    include_once __DIR__.'/functions.php';
                    if (!function_exists(__NAMESPACE__.'\\level')) {
                    	function level ($in, $level) {
                    		return trim(h::level($in, $level))."\n";
                    	}
                    }
                    $main_menu	= h::{'ul.uk-navbar-nav[level=0] li[level=0]'}(
                    	get_main_menu()
                    );
                    $submenu	= admin_path() ? Menu::instance()->get_menu() : '';
                    $avatar		= User::instance()->avatar();
                    $body_class	= admin_path() ? ' class="cs-admin-page"' : '';
                    ?><!doctype html>
                    <!--pre_Html--><!--head-->
                    <body unresolved>
                    

                    Почему при выборе темы DarkEnergy у меня эта тема не выбирается (ладно, ладно, я из-под винды сижу, не должно работать ничего) а в папке появляется файл fs.json с подобным содержимым:
                    ["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""]
                    

                    Почему при попытке зарегать еще одного пользователя и фейле нет записей в логах?
                    Мне лень разбираться, может там подтверждение на почту должно приходить, но почему о провальных попытках нет возможности узнать?
                    Почему при нажатии в админке на установку модуля та же история — ничего не устанавливается, а почему — из логов опять же понять не могу, потому что их нет
                    Я не хочу сравнивать ваше творение с православными фреймворками, но вот гляньте на Phalcon — он необычен, т.к. расширение, он действительно быстрый, и вы не тянете кучу кода фреймворка из проекта в проект, а действительно пишете код только тогда, когда он нужен
                    Действительно удобно и эффективно. И нет излишней сложности где она не нужна
                    Совершенно верно, но бывает люди пробуют новое и переключаются на него. Когда они знают два инструмента и один из двух явно удобнее. Я вот об этом говорю.

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

                    Прочитал, от этого косяки никуда не делись.
                    В общем вот мое впечатление. Конечно хорошо что вы много времени уделяете своей системе, как-то пытаетесь расти и расширять функционал, но пока что это продукт для себя, а не для сообщества. Удачи в вашем начинании и постарайтесь исправить недочеты
      • 0
        Это не «представление», это частный шаблон представления. Вьюшка была всегда объектом, если что, а не html кодом.
        • 0
          В коде объектом, но по факту HTML кодом, или любым другим, который потом всё равно кэшировался в виде PHP в перемешку с HTML. Сейчас же сервер шаблон не кэширует, а веб-компоненты минифицируются, жмутся и кэшируются уже самим браузером. Это уже frontend, не backend, то, о чём я и говорил.
          • 0
            Я наверное не достаточно раскрыл своё замечание. Вьюшка (или представление) — это объект с данными, которые накладываются на шаблон лишь в одном частном случае — при использовании серверных шаблонизаторов. По-факту же ей пофигу где находится этот шаблонизатор (если мы говорим про веб), на клиенте или сервере.

            А про json-ld (то замечание выше, что за семантикой будущее) — мечты, которыми никто и никогда не будет пользоваться. Я в своей жизни видел только пару раз сайты со schema.org, и чуть больше с open graph (из которого используются только функции, для шаринга в фейсбук, т.е. он по-факту вообще не используется нормально). На словах это всё замечательно, но на деле…
            • 0
              На деле Google отлично понимает JSON-LD и OpenGraph, а ещё JSON-LD понимают Yandex, Bing, Yahoo и некоторые другие (сморите статьи Yandex здесь, на хабре, о семантической разметке и о бета-версии интерфейса результатов поиска).

              В подтверждение моих слов можете засунуть сниппет разметки из GitHub сюда: developers.google.com/structured-data/testing-tool

              Вот вы не видели, потому что над этим в самом деле мало кто запаривается, а CleverStyle CMS из коробки генерирует Open Graph, а все существующие компоненты перейдут в обозримом будущем на JSON-LD, началось движение с блога.

              Это проще настраивать, понятнее поисковикам и другим машинам.

              То, что не будет семантическим само себе копает яму — потому что вы сами должны быть заинтересованы в том, чтобы поисковик вас правильно понял. Теперь же семантика перестала быть неудобным костылем (вспоминаем тот же RDFa и другие микроформаты).
  • 0
    Лучшее, говорите?
    github.com/nazar-pc/CleverStyle-CMS/blob/master/components/modules/Photo_gallery/edit_images.php

    Я бы от такого «лучшего» бежал, и волосы назад.
    • +1
      Комментарий даже не изменили. Статью-то читали?
      • 0
        Читал. Поэтому и говорю: код все такой же отвратительный.
        • +1
          Ага, ясно, тогда придется всё же повториться:

          В промежутке от версии 1.0 в порядок приводилось ядро, в результате обширного рефакторинга система стала существенно понятнее и более предсказуемая, а так же стали возможными некоторые функции, как то работа в Request/Response режиме (о чём далее).

          Частично отрефакторен системный модуль, но только частично. Больше рефакторинга красивого и разного ещё будет.

          А теперь обратите внимание на путь в вашей ссылке components/modules/Photo_gallery.

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

          Так что оставьте свои колкие фразочки при себе.
          Кстати, статьи вы не пишете, ссылки на GitHub в профиле не видно. Не поделитесь своим исключительно правильным и красивым кодом?
          • 0
            Костыли\велосипеды, без обид. Берёте symfony\httpfoundation и все проблемы с request\response решены ещё в зародыше. Предлагаю не отмахнуться со словами «у нас своё, более крутое», а действительно взять и попробовать. Например просто попытаться отобразить массив текущих хедеров реквеста.

            После этого перестанет хотеться писать что-то своё.
            • +1
              Проблемы с Request/Response, естественно, решены. Но автоматически появляются новые проблемы. Например, несовместимость с кодом, который не писался изначально с использованием symfony\httpfoundation, мой же вариант позволяет прозначно работать в режиме Request/Response ещё и асинхронном, не меняя при этом кода (если только он не делает чего-то слишком странного). То есть ваш клиентский код может использовать $_SERVER напрямую, использовать symfony\httpfoundation — вообще не важно, работать будет в любом случае.
              На счёт отобразить массив заголовков запроса — $_SERVER['HTTP_*'] за исключением некоторых заголовков, которые не имеют префикс HTTP_ содержит всё.

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

              Более конкретно: symfony/http-foundation занимает 3.4 МиБ. При этом ядро CleverStyle CMS имеет размер 1.8 МиБ, и делает существенно больше всего полезного, в том числе содержит целый набор больших JS библиотек.
              Стоит ли говорить что из этого работает быстрее и кушает меньше ресурсов?
              • 0
                А ваш этот Request/Response работает из консоли или выкидывает ошибки отсутствия индекса? А оно умеет нормально синхронизировать порядок передачи хедеров и данных? А он может сам выстраивать заголовки в зависимости от версии Http? А нормально обрабатывает X-Accel-Redirect и X-Accel-Mapping заголовки? И ещё тысячу вопросов могу задать, в 90% которых будет ответ «а зачем?» или «а что это?». Эти 3.4 мибибайта полностью оправдывают свой размер и там нет ни строчки лишнего кода.

                Это надёжное и качественное решение, в отличие от чтения данных из $_SERVER и отправкой заголовков напрямую с header и echo. Для новичков конечно же лучше изучить что-то низкоуровневое, но Вы уже не новичок. В общем решать Вам, но я бы вообще не стал смотреть на такую систему (в частности запрос\ответ), на которую вообще нельзя положиться и которая начинает глючить, как только ей подсунут что-то иное, от стандартных вещей, а объём кода говорит как раз о том, что предусмотрено там намного всего меньше, а решение делалось «в лоб», лишь бы работало.

                Хотя никто не спорит — оно будет меньше кушать, правда зачастую покупка плашки оперативы просто в разы дешевле переписывания половины кода. ;)

                З.Ы. Под попробовать отобразить хедеры — имелось ввиду с помощью symfony\httpfoundation, чтоб просто понять всю прелесть.
                • +1
                  Да, запускается из консоли, php-cli или hhvm, а как ещё?) Самим процессом передачи заголовков и прочего занимается react/http, который по-моему и guzzle, и http-foundation по зависимостях тянет, движок работает уже поверх этого, составляя стандартный $_SERVER и прочие суперглобальные переменные, для клиентского кода всё выглядит как при использовании с mod-php5 или php5-fpm. Конечно, выстраивает заголовки в зависимости от версии HTTP, X-Accel-Redirect и X-Accel-Mapping вообще не понятно к чему тут, их отправить с пустым телом ответа сложно, или принять и проверить путь?

                  То есть ядро работает оптимально, при необходимости подключаются сторонние библиотеки, в том числе, возможно, http-foundation. Но для обычных запросов без встроенного Http сервера это не нужно, если более оптимальные способы достижения целей.
                  • 0
                    О, ну это же просто замечательно. Я просто боюсь опять открывать гитхаб и смотреть реализацию. Подумал что Вы с нуля решили реализовать абсолютно всё, вот и спросил про совершенно очевидные подводные камни. А react\http — да, сам react безумно крутая штука.
                    • +1
                      Нет, я же не потяну чисто физически писать всё с нуля, модуль Http сервера всего 33.5 КиБ с лицензией, документацией, мета-информацией, по сути обертки для передачи данных из одного формата в другой, обертки суперглобальных переменных для асинхронного режима.

                      Я не пишу то, что написано просто и лаконично. Но ставить многомебибайтные библиотеки порой не вижу смысла, проще написать элементарную реализацию самому.
                      • 0
                        Возможно в этих словах есть смысл, но лишь в том случае, когда эти многомегабайтные библиотеки — «монстр-франкенштейн с функциями микроволновки», в противном случае, когда она выполняет свою роль и только её, оно либо написано в стиле лучших_корпоративных_абстрактных_решений_на_java, либо там учтены почти все проблемы пыха так, чтобы оно работало вообще при любой погоде (а это немаловажно).

                        Так что очень спорное решение. Последнее время склоняюсь именно к стороннему опенсорс-коду с многотысячной поддержкой. Чего и Вам желаю.
          • 0
            > Кстати, статьи вы не пишете, ссылки на GitHub в профиле не видно. Не поделитесь своим исключительно правильным и красивым кодом?

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

            > Я мог бы его даже исправить, но вы бы с легкостью нашли другой подобный файл.

            Нашел бы, и сказал об этом.
            Надо все исправить.
            Особенно учитывая пафосный заголовок со словом «лучшее».
            Был бы заголовок: «Моя CMS, которую я пишу для изучения PHP (часть 2)», было бы другое отношение.
            • +1
              А зачем? Я не пишу статьи про мои продукты, поэтому вам не должно быть дело до моего кода.
              Я даже могу не писать его совсем, но это не дает вам права переходить на личности.

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

              Нашел бы, и сказал об этом.
              Надо все исправить.

              Совершенно верно, исправлять надо все недочеты, и переписывать кривые места. К примеру, вчера был переписан класс \cs\DB (кроме последнего метода, он будет отрефакторен вместе с системным модулем). Работает он аналогично, но теперь читабелен и понятен, спасибо SerafimArts.

              Особенно учитывая пафосный заголовок со словом «лучшее».
              Был бы заголовок: «Моя CMS, которую я пишу для изучения PHP (часть 2)», было бы другое отношение.

              Вот здесь есть два аспекта — идея и реализация. Реализация — только пример имплементации идеи. Оно есть, оно работает, но его можно сделать лучше. Тем не менее благодаря тому, как устроена архитектура, прямое следствие идеи, система стала реальной и имеет практическую пользу. Рефакторинг делает код красивым, иногда исправляет потенциальные баги, но не приносит принципиально новые функции сам по себе. Это логично — сделать proof of concept, убедиться что работает, что удобно, а потом переписать красивее и понятнее.
              • 0
                > То есть я тоже могу оценить как-то печатную плату, но так как в этом не разбираюсь, моя оценка не будет экспертной, то есть её ценность стремится к нулю. Вот и хотел уточнить, с кем имею честь общаться.

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

                > Это логично — сделать proof of concept, убедиться что работает, что удобно, а потом переписать красивее и понятнее.
                Писать сразу нормально гораздо продуктивнее. Это слегка дольше вначале, но это гораздо проще в поддержке.
                • +1
                  В прошлой вашей теме я детально описал проблемы, которые есть в вашем коде.

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

                  Писать сразу нормально гораздо продуктивнее.

                  Естественно, вот только с первого раза почти никогда не получается написать именно то, что нужно и красиво. Как минимум из-за того, что если придется выбрасывать код и переписывать (а такое часто случается), расходы, в том числе времени, если мы об Open Source, получаются огромными. Поэтому делают рабочий прототип, и потом проверяют его. Почитайте про Lean Startup, это подход для реального мира, не идеального.
              • 0
                Обычно когда код становится более удобоприятен для использования — его можно начать использовать в каких-то иных местах. Например у доктрины есть класс кеша — оно умеет кешировать данные тяжёлых запросов на N минут. Вроде бы всё логично и других возможностей и не надо. Но благодаря тому, что код пакета кеширования разделён на адптеры, саму реализацию и интерфейс адаптеров — его стало можно применить не только к кешированию данных из БД, но и к кешированию прочих вещей — шаблонов, аннотаций и т.д. При этом удалось просто двумя пинками адаптировать его к совершенно иному фреймворку, конкретно к Laravel, а объём кода, который делает это бридж — ровно 100 строк (при этом больше половины — комменты). И подобные вещи можно реализовать лишь в хорошо организованном коде, организация которого достигается в 80%-90% (написать нормально сразу — это почти миф) благодаря рефакторингу.
                • +1
                  github.com/nazar-pc/CleverStyle-CMS/blob/master/core/classes/Cache.php — комментариев больше половины, адаптировать к любому другому движку, фреймфорку, просто скрипту — элементарно.
                  Движок кэша — на выбор: файловая система, APCu, Memcached, черная дыра для тестирования работы без кэша или с перегруженным, абстрактный класс для произвольной реализации: github.com/nazar-pc/CleverStyle-CMS/tree/master/core/engines/Cache

                  Я понимаю, о чём вы говорите, но почему вы считаете что этого нет в CleverStyle CMS или что двумя пинками вы не сможете подключить кэш доктрины сюда?

                  P.S. Установил doctrine/cache:1.5.*@dеv, 476.6 КиБ. Может, не то поставил, может там и 100 строчек рабочего кода, но как-то не очень похоже сходу.
                  • 0
                    Я про 100 строк адаптера, не хотел постить ссылку, чтоб не захламлять тему, ну да ладно, может кому будет полезно: github.com/jphp-compiler/site/blob/master/app/Annotations/Core/Annotation/LaravelCacheBridge.php

                    github.com/nazar-pc/CleverStyle-CMS/blob/master/core/classes/Cache.php
                    По ссылке я вижу
                    1) Нет интерфейса: Непонятно что надо реализовывать, что бы заработало всё без проблем (но зато я нашёл абстрактный класс github.com/nazar-pc/CleverStyle-CMS/blob/master/core/engines/Cache/_Abstract.php) который всё равно не экстендится в класс Cache
                    2) Нет надёжности, т.е. я могу подсунуть совершенно любой класс, вместо этого (из-за отсутствия интерфейса)
                    3) Его нельзя подменить, т.к. он (а) синглтон и (б) не резолвится (т.е. не содержится в контейнере или не делается алиас).

                    Т.е. если в симфони архитектура следующая: new глобальная_логика(new адаптер_кеша_с_нужным_интерфейсом), то у Вас я не понимаю вообще как всё работает, слишком размазано поведение (в Core и DB я тоже не нашёл упоминание этого класса, чтоб понять где он вызывается и что задействовано, ведь интерфейса нет).
                    • +1
                      1) Интерфейса нет, есть абстрактный класс, наследуете, добавляете реализацию абстрактных методов; что значит «не экстендится в класс Cache»?
                      2) Совершенно верно, можете подсунуть совершенно любой класс, какой именно — определяете в конфигурации (которая базовая в файле, в интерфейса сайта это не настраивается), или хакаете на лету с помощью кастомного cs\Singleton в тестах, это проблема?
                      3) Его можно подменить, если нужно, так как он не совсем синглтон (хотя в рантайме вам это навряд будет нужно, но смотрите статью, там упоминается), нет необходимости в контейнере, он ту ни к чему

                      Вы не найдете ничего кроме его использования. Пока он не используется — класс вообще в память не загружен, БД не занимается кэшированием, СУБД сама не плохо с этим справляется, что-то более конкретное вы кэшируете при необходимости сами, это элементарно реализовывается.

                      При первом использовании вызовется protected метод Cache::construct() и подключит движок кэша в зависимости от системной конфигурации. Всё что вам нужно для его использования — сделать Cache::instance() в любом месте.

                      Да, это кардинально отличается от того, что вы могли ожидать, но это просто несоизмеримо проще. То есть проще уже некуда. Если бы была цель сделать вторую Symfony — я бы просто взял готовую Symfony, но это совершенно другая система с другим подходом.
                      • 0
                        … что значит «не экстендится в класс Cache»?

                        Это значит, что у вас в коде не class Cache extends _Abstract, а просто Cache. Т.е. смотря на его исходники — не понимаешь как его подменить.

                        … это проблема?

                        Ну с одной стороны да, с другой нет. Если я разумный — я смогу вычислить как его подменить, чтоб ничего не поломать. А если я психованная обезьянка, то я не буду искать ваш _Abstract, а сделаю что-то своё, посмотрю, мол работает, а через годик может возникнуть ошибка именно из-за того, что забыл дописать какой-то метод, а он используется лишь в одном очень скрытом месте, но порождает просто невероятнейшую ошибку, если не реализован.

                        Ну и далее по теме. Я понимаю, что проще и как можете заметить — Вам это удалось (т.к. я почти что сразу понял в чём смысл, но не полностью). Вот и предлагаю просто добавить некоторые вещи, чтоб те, кто будет читать исходники после меня — сразу же поняли в чём смысл. Да и если внутри Cache происходит выбор движка, то что будет если я подсуну туда самописный BlackHole2? Зачем внутри привязка к названиям?
                        • 0
                          Это значит, что у вас в коде не class Cache extends _Abstract, а просто Cache. Т.е. смотря на его исходники — не понимаешь как его подменить.

                          cs\Cache не занимается кэшированием сам, он подключает в зависимости от настроек другой класс, и хранит его инстанс в $this->engine_instance, потом просто проксирует вызовы туда. Поменять в рантайме без изменения `\cs\Singleton` его невозможно, и зачастую не нужно. Для частных случаев — частные решения, например, можно использовать для разных наборов ключей разные движки кэширования, но это не общий случай.

                          Ну с одной стороны да, с другой нет. Если я разумный — я смогу вычислить как его подменить, чтоб ничего не поломать. А если я психованная обезьянка, то я не буду искать ваш _Abstract, а сделаю что-то своё, посмотрю, мол работает, а через годик может возникнуть ошибка именно из-за того, что забыл дописать какой-то метод, а он используется лишь в одном очень скрытом месте, но порождает просто невероятнейшую ошибку, если не реализован.

                          Для того, чтобы автозагрузчик подключил ваш класс в качестве движка для кэша вам придется положить его в core/engines/Cache, то есть можно, конечно, положить куда-то ещё, и подключить вручную, но по-моему когда кто-то перед расширением функциональности ядра не читает документацию хотя бы по использованию — тут еже ничего не поделать, а если зайдет в папку — то наверняка увидит, как оно устроено. Я обычно копирую существующий файл, и редактирую. То есть шанс есть всегда, но это совсем печальный случай. \cs\Cache\_Abstract есть в wiki.

                          Ну и далее по теме. Я понимаю, что проще и как можете заметить — Вам это удалось (т.к. я почти что сразу понял в чём смысл, но не полностью). Вот и предлагаю просто добавить некоторые вещи, чтоб те, кто будет читать исходники после меня — сразу же поняли в чём смысл. Да и если внутри Cache происходит выбор движка, то что будет если я подсуну туда самописный BlackHole2? Зачем внутри привязка к названиям?

                          Blackhole — это, видимо, была такая микрооптимизация, удалил и переформатировал класс согласно новому стилю. Спасибо, уже второе ваше замечание попало в репозиторий в виде полезного улучшения.
                          • +1
                            cs\Cache не занимается кэшированием сам, он подключает в зависимости от настроек другой класс, и хранит его инстанс в $this->engine_instance, потом просто проксирует вызовы туда
                            Это всё можно сократить вот до такого класса: gist.github.com/SerafimArts/3ec6326706ed1ad0b446

                            Код небольшой, но сразу понятно что делает:
                            1) Хранит объект драйвера кеша
                            2) Позволяет обращаться к нему через static вызовы (т.е. почти тот же синглтон)
                            3) Позволяет подменить драйвер (адаптер) при желании
                            4) Гарантирует то, что методы у всех адапетров будут одинаковые, т.к. умеет принимать только классы с CacheInterface
                            5) Вообще не зависит ни от какой части системы
                            6) Плюс можно добавить загрузочный класс, который при старте системы берёт этот Cache и вызывает setInstance из конфигов.

                            В результате, просто разделив этот класс (core/classes/Cache) на два — тот, кто просто хранит нужный драйвер и тот, кто загружает туда его из конфигов, мы получаем:
                            1) Совершенно независимый компонент, который можно таскать куда угодно.
                            2) Почти что независимые драйверы\адаптеры, которые можно использовать отдельно.
                            3) Точно такой же объём кода, если не меньше.
                            4) Надёжную систему — мы будем точно быть уверены, что используя Cache вызовы со сторонним пользовательским драйвером — разработчик оного реализовал всё, что потребуется (заодно облегчим ему жизнь, показав какие методы нужны для встраивания).
                            5) Класс, для которого даже документация не нужна, т.к. он совершенно очевидный
                            • 0
                              P.S. Прошу прощения за отсутствие форматирования цитат и неподсвеченные ссылки. Непривычно без тегов работать. Постараюсь впредь следить за собой и как-нибудь иначе оформлять.
                            • +1
                              А теперь посмотрите на то, что есть сейчас:
                              1) Аналогично вашему
                              2) Зачем? То есть в моем варианте это тоже легко можно добавить, даже с помощью модификации cs\Singleton можно в почти все системные объекты добавить такое поведение, но такой цели не стояло. Есть магические __get() __set(), которые в статическом варианте не возможны. Дополнительно в моем случае в режиме отладки кэширование выключается, поддерживается второй параметр $callback в get(), если вы добавите всё то, что есть у меня получится даже больше
                              3) Драйвер и так можно подменить при желании, но только это практически никогда не нужно, а значит нет смысла делать теоретическую прослойку, которую, как показывает практика, использовать не будут почти никогда; сделать можно, но смысл?
                              4) Проблема исчезает исходя из прошлого пункта как класс в принципе
                              5) Значит нужно писать дополнительный код, чтобы интегрировать с конфигурацией системы, то есть в сумме получится то же самое либо больше, но в другом месте, что уже гораздо менее очевидно, тут вы сразу видите откуда всё появилось
                              6) А что если кэширование вообще не будет использоваться? Я предпочитаю запускать всё on demand, а не «давайте всё проинициализируем, авось пригодится»

                              1) Согласен, наверняка уже есть готовое
                              2) То же что и 1)
                              3) Не меньше уж точно, а дополнительный интерфейс и аннотации + слой интеграции с конфигурацией системы только увеличат объем
                              4) В документации описано что и к чему. Не стоит считать людей на сколько тупыми, что при расширении ядра и использовании в реальном проекте они не посмотрят в документацию. А раз посмотрят — унаследуют абстрактный класс, и им в любом случае придется реализовать нужные методы. К тому же, если добавятся новые методы, которые не зависят от движка — их можно добавить в _Abstract, как в примере с драйверами БД, там куча методов, которые просто удобные обертки над низкоуровневыми методами драйвера БД.
                              5) Без аннотаций и документации не совсем, он по сути не делает ничего, он перекладывает из одной руки во вторую, но что именно — не понятно, вот так и получается, что нужно бежать, искать интеграцию с конфигурацией, где инстанс драйвера внедряется, потом искать драйвер, чтобы узнать список доступных методов

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

                              P.S. Я переформатировал код и посмотрел, не проблема.
  • 0
    Я тоже всё вынашивал идею своего модного велосипеда, и даже некоторые вещи из данного продукта писал примерно также. Но поработав сам на пяти-десяти проектах, забил, ибо всё равно под каждый приходится много чего дописывать с нуля, всего не покроешь. А писать очередной толстенный фреймворк, коих и так уже десятки — посчитал глупым. Да и в процессе реализации проектов, всегда приходит какая-то новая мегаидея, от которой хочется всё стереть и написать заново (ну да, я тот ещё гвонокодер).
    upd: ну и да, я тоже не сторонник фреймворков, люблю уровень пониже, мне это кажется быстрее и надёжнее.
  • +1
    То, что предлагают PSR мне не очень нравится

    На то они и стандарты, чтоб им следовать и чтоб другим было понятно. Если бы Вы писали CMS для самообучения, то собственно без разницы, как Вы пишете и насколько это читабельно. Но тут Вы позиционируете свое творение как продукт, которым люди будут пользоваться. Ваша целевая аудитория, судя по статьям — разработчики, а продукт должен быть удобен для целевой аудитории. Если же код нечитабельный, местами индусский и неочевидный, а указанные аудиторией косяки вы не исправляете, то таким продуктом никто кроме Вас пользоваться не будет
  • 0
    Зашел внутрь, открыл рандомно пару файлов.

    Например, github.com/nazar-pc/CleverStyle-CMS/blob/master/components/modules/Shop/Items.php#L98-L215 не нужно так мешать все в кучу, разделяйте, обобщайте код.

    Все остальные файлы ровно также можно удивляться, я бы рекомендовал вам остановится, отдышаться и понять как именно вы хотите спроектировать систему, потому что это фарш.
    • 0
      Да, вы правы. Код хоть и рабочий, но весьма неряшливый. Местами есть хуже, местами есть гораздо лучше.
      В целом посмотрите на вот этот график: https://scrutinizer-ci.com/g/nazar-pc/CleverStyle-CMS/statistics/, можете оценить вектор движения от недели к неделе в плане качества кода и количества потенциальных багов. Можете посмотреть на последний релиз, какое количество упрощений и рефакторинга.

      Я согласен с вами что это фарш, прошу оценить движение и, если у вас есть интерес к системе — указать более приоритетные для вас участки, все пожелания, естественно, учитываются. Pull request-ы были бы тоже очень к стати.

      По поводу выделенного участка — там много каши с запросами в БД и деться от них никуда не получится. На днях планируется надстройка над \cs\CRUD, которая относительно простые связи основной таблицы с вспомагательными (как раз этот случай) будет очень тривиально разруливать сама, как на чтение, так и на запись/удаление, большинство указанного кода заменится лаконичной моделью данных. Если интересно — могу маякнуть как будет готово.

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