Jump to content

Recommended Posts

  • Replies 253
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Posted Images

"Обвесы товаров"

 

--------------------------------------

 

"По всей симпле" можно встретить подобный код

 

foreach($this->products->get_products($params) as $p)
	$products[$p->id] = $p;

if(!empty($products))
{
	// id выбраных товаров
	$products_ids = array_keys($products);

	// Выбираем варианты товаров
	$variants = $this->variants->get_variants(array('product_id'=>$products_ids, 'in_stock'=>true));
	
	// Для каждого варианта
	foreach($variants as &$variant)
	{
		// добавляем вариант в соответствующий товар
		$products[$variant->product_id]->variants[] = $variant;
	}
	
	// Выбираем изображения товаров
	$images = $this->products->get_images(array('product_id'=>$products_ids));
	foreach($images as $image)
		$products[$image->product_id]->images[] = $image;

	foreach($products as &$product)
	{
		if(isset($product->variants[0]))
			$product->variant = $product->variants[0];
		if(isset($product->images[0]))
			$product->image = $product->images[0];
	}				
}

 

 

работать не удобно... Хотелось бы упростить работу с товарами примерно так

 

$products = (new ProductsWith($filter))->images()->variants()->get();

 

https://github.com/simpladevru/simpla-namespace/blob/0aeca0b37494d273ff050b424457c528fced3c83/view/ProductsView.php#L141

https://github.com/simpladevru/simpla-namespace/blob/master/api/models/product/ProductsWith.php

 

https://designpatternsphp.readthedocs.io/ru/latest/Structural/FluentInterface/README.html

Edited by DaVinci
Link to post
Share on other sites

Модели сущностей

 

--------------------------

 

Очень не хватает полноценных сущностей. Пример простейшей реализации (в модели только то что понадобилось для примера)

 

Модель

https://github.com/simpladevru/simpla-namespace/blob/master/api/models/category/Category.php

 

Создаем экземпляры модели при выборке из базы

https://github.com/simpladevru/simpla-namespace/blob/20ff4d560067864f8a83e2f60cbbabd1c780914a/api/Categories.php#L206

 

Правки в Database.php

https://github.com/simpladevru/simpla-namespace/blob/20ff4d560067864f8a83e2f60cbbabd1c780914a/api/Database.php#L140

 

Небольшой пример - выносим составное условие в модель сущности, где ему и место. 

https://github.com/simpladevru/simpla-namespace/blob/20ff4d560067864f8a83e2f60cbbabd1c780914a/view/ProductsView.php#L56

 

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

 

-------------

 

Одним словом выносим в сущности все то что относиться к ним.

 

-------------

 

более подробно можно почитать - GRASP Информационный эксперт (Information Expert)

Edited by DaVinci
Link to post
Share on other sites

Еще небольшой пример с моделью изображения

 

----------------------------------------------------------------------


есть "хелпер" resize_modifier который поселился в Design.php

https://github.com/pikusov/Simpla/blob/9fefafa38dc739b4348b4a2940cba8bc8e4363ed/api/Design.php#L208

он создает ссылку на изображение. Конечно в Design можел лежать метод resize для макетов, но все же логики там быть не должно по идее

 

подобный метода не плохо было бы поместить в саму сущность Image

https://github.com/simpladevru/simpla-namespace/blob/master/api/models/product/ProductImage.php

 

теперь этим методом можно воспользоваться в макете и не только

https://github.com/simpladevru/simpla-namespace/blob/6317981f984ef589469b18d77279796c65ea561a/design/default/html/products.tpl

 

{$product->image->resize(200, 200)}

------

 

если метода покажется громоздким можно создать хелпер со статическим методом (положить его в туже директорию), и делегировать ему всю логику

https://github.com/simpladevru/simpla-namespace/blob/master/api/models/product/ImageHelper.php

 

Теперь этим хелпером может воспользоваться как модель так и Design. хотя в resize_modifier больше нет потребности

https://github.com/simpladevru/simpla-namespace/blob/0f7556711f5e19175fd2440bef48ea262bd9d6f9/api/Design.php

 

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

Edited by DaVinci
Link to post
Share on other sites

Расширения Smarty

 

--------------------------------------------

 

Открываем 

 

https://github.com/pikusov/Simpla/blob/9fefafa38dc739b4348b4a2940cba8bc8e4363ed/api/Design.php#L44

https://github.com/pikusov/Simpla/blob/9fefafa38dc739b4348b4a2940cba8bc8e4363ed/view/View.php#L93

 

Видим регистрацию модификаций, функций. Как по мне такой подход не совсем правильный. Почему? Ну к примеру а почему бы все расширения сразу не воткнуть в Design.php или куда вставлять новые расширения в Design.php или View.php? Если появляются новые расширения то об этом можно узнать если пробежаться по этим файлам и визуально найти отличия... Одним словом не удобно это.

 

-------------------------

 

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

 

-------------------------


Пример

 

-------------------------

 

Для начала удалим все расширения Design.php и View.php их там быть не должно

https://github.com/simpladevru/simpla-namespace/blob/master/api/Design.php

https://github.com/simpladevru/simpla-namespace/blob/master/view/View.php

 

Создаем интерфейс для расширений

https://github.com/simpladevru/simpla-namespace/blob/master/api/components/design/smarty/SmartyExtensionInterface.php

 

Создаем базовый класс расширения, помещаем в него конструктор

https://github.com/simpladevru/simpla-namespace/blob/master/api/components/design/smarty/SmartyExtension.php

 

Создаем класс который будет регистрировать расширения, хотя данный метод add($extension) можно поместить и в Design

https://github.com/simpladevru/simpla-namespace/blob/master/api/components/design/smarty/RegisterSmartyExtension.php

 

Дале создаем классы регистрирующие расширения

https://github.com/simpladevru/simpla-namespace/blob/master/api/components/design/smarty/AppExtension.php

https://github.com/simpladevru/simpla-namespace/blob/master/view/SmartyExtensions/ShopExtension.php

 

 

Теперь надо найти место где бы их можно было зарегистрировать. Сперва я воткнул их в View.php для теста, но мне такой подход не особо нравиться, расширения должны быть конфигурируемыми, потому я создал посредник

https://github.com/simpladevru/simpla-namespace/blob/master/middleware/RegisterExtensionsSmartyFromFrontend.php

и зарегистрировал его https://github.com/simpladevru/simpla-namespace/blob/78e8101704bf33d8c6942d9b2160294ffb598f7d/index.php

 

-------------------------

 

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

 

https://github.com/simpladevru/simpla-namespace/tree/master/view/SmartyExtensions

 

-------------------------

 

Можно модифицировать данный пример. Использовать Middleware для регистрации расширений можно но для этого существует иной инструмент - ServiceProvider. О нем чуть позже...


 

Edited by DaVinci
Link to post
Share on other sites

Обнаружил занятную работу https://github.com/SimplaCMS-PRO/Simpla/tree/master/api/smarty-plugins

 

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

 

https://github.com/SimplaCMS-PRO/Simpla/blob/0b208a5050d14b999020d7d78d797658ba3397ca/api/smarty-plugins/function.get_brands.php#L10

 

require_once( dirname(dirname(__FILE__)) . '/Simpla.php');
$simpla = new Simpla(); 

 

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

Edited by DaVinci
Link to post
Share on other sites

"Обвесы товаров"

 

--------------------------------------

 

"По всей симпле" можно встретить подобный код

 

 

foreach($this->products->get_products($params) as $p)
	$products[$p->id] = $p;

if(!empty($products))
{
	// id выбраных товаров
	$products_ids = array_keys($products);

	// Выбираем варианты товаров
	$variants = $this->variants->get_variants(array('product_id'=>$products_ids, 'in_stock'=>true));
	
	// Для каждого варианта
	foreach($variants as &$variant)
	{
		// добавляем вариант в соответствующий товар
		$products[$variant->product_id]->variants[] = $variant;
	}
	
	// Выбираем изображения товаров
	$images = $this->products->get_images(array('product_id'=>$products_ids));
	foreach($images as $image)
		$products[$image->product_id]->images[] = $image;

	foreach($products as &$product)
	{
		if(isset($product->variants[0]))
			$product->variant = $product->variants[0];
		if(isset($product->images[0]))
			$product->image = $product->images[0];
	}				
}
[/code]
 
 
работать не удобно... Хотелось бы упростить работу с товарами примерно так
 
[code=auto:0]
$products = (new ProductsWith($filter))->images()->variants()->get();
 

https://github.com/simpladevru/simpla-namespace/blob/0aeca0b37494d273ff050b424457c528fced3c83/view/ProductsView.php#L141

https://github.com/simpladevru/simpla-namespace/blob/master/api/models/product/ProductsWith.php

 

https://designpatternsphp.readthedocs.io/ru/latest/Structural/FluentInterface/README.html

 

 

Ты забыл про свойства и комментарии.
Link to post
Share on other sites

да, нужно и это прилепить

Скажем если расширить функционал комментариев, в s_comments хранить ID юзера и потом связывать две сущности (юзер=>коммент), как тогда быть?
Link to post
Share on other sites

Скажем если расширить функционал комментариев, в s_comments хранить ID юзера и потом связывать две сущности (юзер=>коммент), как тогда быть?

 

для пользователя создается UserWith->comments()

 

если надо достать комментарии товара, у которых есть сущности пользователя, тогда создаем CommetWith в котором подтягиваем сущность пользователя CommetWith->user()

 

при вызове ProductsWith->comment() возвращаться просто комментарии, а если вызвать 

 

ProductsWith->comment( new CommetWith()->user() )

 

то, теоретически получим список комментариев с пользователями.

 

Но если все же хочется работать максимально комфортно с сущностями просто используем eloquent или любую другую популярную ORM что бы не костылять колесо

 

Eloquent, Propel, ZendDB, Spot2...

 

https://laravel.com/docs/5.7/eloquent-relationships

 

http://propelorm.org

Edited by DaVinci
Link to post
Share on other sites

Кстати работать с популярной ORM куда перспективнее чем работать с голыми запросами симплы



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

 

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

 

 


Но если все же хочется работать максимально комфортно с сущностями просто используем eloquent или любую другую популярную ORM что бы не костылять колесо

 

Eloquent, Propel, ZendDB, Spot2...

 

https://laravel.com/docs/5.7/eloquent-relationships

 

http://propelorm.org

Edited by DaVinci
Link to post
Share on other sites

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

Link to post
Share on other sites

Кстати работать с популярной ORM куда перспективнее чем работать с голыми запросами симплы

Совершенно верно!

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

Чем хуже использовать что-то типа:
$this->products->get_products($filter)->join(array['images','variants','features','comments']);
И реализовать метод join который будет "склеивать" сущности в один объект?

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

Link to post
Share on other sites

 

Совершенно верно!Чем хуже использовать что-то типа:

$this->products->get_products($filter)->join(array['images','variants','features','comments']);
И реализовать метод join который будет "склеивать" сущности в один объект?

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

 

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

 

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

Edited by DaVinci
Link to post
Share on other sites
 

Шторм контейнер не подсвечивает, к примеру Simpla::$container->pages->get_page('404');

 

ага, понял... для этого создаются фасады. секунду...

Edited by DaVinci
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...