<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: toco</title>
    <description>The latest articles on Forem by toco (@shop).</description>
    <link>https://forem.com/shop</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F291244%2F0431bb9c-c615-45a8-83b5-c82869c1efbb.png</url>
      <title>Forem: toco</title>
      <link>https://forem.com/shop</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/shop"/>
    <language>en</language>
    <item>
      <title>PagibleAI CMS: The AI-Powered CMS for Editors and Developers</title>
      <dc:creator>toco</dc:creator>
      <pubDate>Wed, 08 Oct 2025 16:27:30 +0000</pubDate>
      <link>https://forem.com/shop/pagibleai-cms-the-ai-powered-cms-for-editors-and-developers-3aa7</link>
      <guid>https://forem.com/shop/pagibleai-cms-the-ai-powered-cms-for-editors-and-developers-3aa7</guid>
      <description>&lt;p&gt;In the rapidly evolving world of digital content, a Content Management System (CMS) needs to be more than just a place to store text and images. It needs to be intelligent, intuitive, and immensely powerful.&lt;/p&gt;

&lt;p&gt;Enter &lt;a href="https://pagible.com/" rel="noopener noreferrer"&gt;PagibleAI CMS&lt;/a&gt; – a revolutionary platform engineered to delight both content editors and developers, blending cutting-edge AI capabilities with robust, modern architecture. It's the CMS that truly understands your needs, offering the ease of use typically found in platforms like WordPress, combined with the structured power and flexibility reminiscent of Contentful.&lt;/p&gt;

&lt;h2&gt;
  
  
  For Editors: Unleash Your Creativity with AI
&lt;/h2&gt;

&lt;p&gt;Content creation has never been easier or more intelligent. PagibleAI CMS is designed from the ground up to empower editors, putting AI support directly into their hands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AI-Powered Content Generation:&lt;/strong&gt; Bid farewell to writer's block. With PagibleAI, you can generate engaging, SEO-optimized content effortlessly, leveraging advanced AI to kickstart your drafts or refine existing text.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Seamless AI Image Creation:&lt;/strong&gt; Enhance your articles and pages with stunning visuals. Our integrated AI can create suitable, high-quality images directly within the CMS, ensuring your content is always visually appealing and on-brand.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multi-Language Translation with AI:&lt;/strong&gt; Expand your global reach without the hassle. PagibleAI's integrated AI can translate your content into over 35 languages, making your message accessible to a wider audience and significantly streamlining localization efforts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Intuitive WYSIWYG Editor:&lt;/strong&gt; Experience true What You See Is What You Get editing. The full WYSIWYG editor provides an immediate, accurate preview of your content as you create it, eliminating guesswork and ensuring consistency.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Effortless Content Management:&lt;/strong&gt; Organize your digital assets with unparalleled ease. Drag-and-drop functionality for pages and content elements simplifies reordering and restructuring, giving you complete control over your site's layout.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PagibleAI CMS streamlines the entire content lifecycle, allowing editors to focus on crafting compelling stories and rich experiences, not wrestling with complex tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  For Developers: Power, Flexibility, and Modern APIs
&lt;/h2&gt;

&lt;p&gt;While editors are enjoying the intuitive interface, developers will appreciate the deep technical capabilities that make PagibleAI CMS a joy to work with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Robust JSON REST and GraphQL APIs:&lt;/strong&gt; Built API-first, PagibleAI offers extremely fast JSON REST APIs for efficient content delivery and versatile GraphQL APIs for powerful, flexible content administration. Integrate with any frontend framework or application with ease.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Built on Laravel:&lt;/strong&gt; Leveraging the robustness and elegance of the Laravel framework, PagibleAI provides a solid, extensible foundation. This means developers can easily customize, extend, and integrate the CMS into existing Laravel applications, enjoying a familiar and powerful ecosystem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Open Source Freedom:&lt;/strong&gt; Benefit from the transparency, community support, and customization possibilities of an open-source platform. PagibleAI CMS is available as a Laravel package, allowing you to install it seamlessly into your projects and tailor it to your exact specifications.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cloud-Native and Scalable for Every Need
&lt;/h2&gt;

&lt;p&gt;Whether you're running a personal blog or managing content for a multi-national enterprise, PagibleAI CMS scales with you. Its cloud-native architecture ensures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Exceptional Performance:&lt;/strong&gt; Optimized for speed and efficiency, delivering content quickly to your users worldwide.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Infinite Scalability:&lt;/strong&gt; From lightweight SQLite databases for small blogs to distributed database clusters handling billions of requests for large corporations, PagibleAI CMS adapts to your needs without compromise.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reliability and Flexibility:&lt;/strong&gt; Designed to leverage the elasticity and distributed nature of modern cloud platforms, ensuring high availability and resilience.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Future of Content Management is Here
&lt;/h2&gt;

&lt;p&gt;PagibleAI CMS represents a new era in content management – one where artificial intelligence enhances human creativity, developers are empowered by modern tools, and scalability is a given. It's not just a CMS; it's a strategic asset for any organization looking to optimize its digital presence.&lt;/p&gt;

&lt;p&gt;Ready to revolutionize your content workflow? Discover PagibleAI CMS today and experience next-level content management:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pagible.com/" rel="noopener noreferrer"&gt;https://pagible.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cms</category>
      <category>ai</category>
      <category>laravel</category>
      <category>webdev</category>
    </item>
    <item>
      <title>AI revolution in eCommerce</title>
      <dc:creator>toco</dc:creator>
      <pubDate>Wed, 25 Jan 2023 15:59:45 +0000</pubDate>
      <link>https://forem.com/shop/ai-revolution-in-ecommerce-3871</link>
      <guid>https://forem.com/shop/ai-revolution-in-ecommerce-3871</guid>
      <description>&lt;p&gt;Since the availability of &lt;a href="https://openai.com/blog/chatgpt/"&gt;ChatGPT&lt;/a&gt;, a large language machine learning model from OpenAI, artificial intelligence seems to be on the rise. Now, editors writing texts might be seen as a dying species because tools like ChatGPT can do the same in seconds and in almost the same quality. This is similar to how &lt;a href="https://www.deepl.com/"&gt;DeepL&lt;/a&gt;, a translation tool based on machine learning, changed the translation industry before.&lt;/p&gt;

&lt;p&gt;Especially in eCommerce, search engines like Google require a lot of relevant text before pages show up at the top of search results. This can now be automated in &lt;a href="https://aimeos.org/"&gt;Aimeos&lt;/a&gt;, the first eCommerce framework with direct integration of ChatGPT and DeepL. This allows editors to generate any text in seconds and have it translated into 29 languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate and translate any content
&lt;/h2&gt;

&lt;p&gt;Aimeos admin backend with ChatGPT and DeepL integration&lt;br&gt;
Not only texts based on existing product specifications are possible, but also helpful information for customers. Depending on the prompt entered, ChatGPT also generates, for example, styling tips for fashion or health information for allergy sufferers – everything about which there are already publications on the Internet that have been incorporated into the training of the AI model.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gq_yugCf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dubg0c52mk5th6hqnqkn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gq_yugCf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dubg0c52mk5th6hqnqkn.png" alt="Aimeos admin backend with ChatGPT and DeepL integration" width="880" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Although ChatGPT can generate texts in different languages, the quality is better the more texts are available in the respective language on the topic. Since DeepL can translate good quality texts into less common languages, this will greatly accelerate the professionalization of online stores in these language regions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test yourself
&lt;/h2&gt;

&lt;p&gt;You can try Aimeos and the capabilities of ChatGPT and DeepL yourself in the Aimeos admin demo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://admin.demo.aimeos.org/"&gt;https://admin.demo.aimeos.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aimeos is the ultra-fast, cloud-native, API-first PHP eCommerce framework for building custom online shops, marketplaces and complex B2B applications. It’s available as &lt;a href="https://aimeos.org/Laravel"&gt;Laravel package&lt;/a&gt;, &lt;a href="https://aimeos.org/Symfony"&gt;Symfony bundle&lt;/a&gt; and &lt;a href="https://aimeos.org/TYPO3"&gt;TYPO3 extension&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>chatgpt</category>
      <category>ecommerce</category>
      <category>laravel</category>
    </item>
    <item>
      <title>Aimeos vs. Bagisto : Comparing differences</title>
      <dc:creator>toco</dc:creator>
      <pubDate>Wed, 30 Sep 2020 08:58:12 +0000</pubDate>
      <link>https://forem.com/shop/aimeos-vs-bagisto-comparing-differences-nbo</link>
      <guid>https://forem.com/shop/aimeos-vs-bagisto-comparing-differences-nbo</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqfg1opxpcoynevdhqg7w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqfg1opxpcoynevdhqg7w.jpg" alt="Aimeos vs. Bagisto"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aimeos and Bagisto are the most popular &lt;strong&gt;Laravel ecommerce&lt;/strong&gt; packages. There have been a lot of noise around ecommerce for Laravel lately and this article tries to shed some light into the discussion.&lt;/p&gt;

&lt;h1&gt;
  
  
  Aimeos
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Aimeos&lt;/strong&gt; strongly focuses on performance and scalability so it's suitable for small shops to setups bigger than Amazon with 1+ billion items. The flexibility and extensibility of Aimeos makes it particularly suitable for highly customized online shops, complex B2B applications and custom marketplaces.&lt;/p&gt;

&lt;p&gt;Link: &lt;a href="https://aimeos.org/" rel="noopener noreferrer"&gt;https://aimeos.org/&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Bagisto
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Bagisto&lt;/strong&gt; is suitable for small to medium sized stores. It offers the most important shop features and focuses on simplicity for users so more complex requirements are not its domain. Bagisto uses Vue.js, even in the front-end, and you need to know the tool chain well if you want to customize it.&lt;/p&gt;

&lt;p&gt;Link: &lt;a href="https://bagisto.com/" rel="noopener noreferrer"&gt;https://bagisto.com/&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Comparison
&lt;/h1&gt;

&lt;p&gt;Both are Open Source and share some features which I have left out in this comparison to focus only on the &lt;strong&gt;differences&lt;/strong&gt;. The supported features have been retrieved from their official web sites and other official sources:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Aimeos&lt;/th&gt;
&lt;th&gt;Bagisto&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rating&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.capterra.com/p/181685/Aimeos/" rel="noopener noreferrer"&gt;4.8/5 (18 reviews)&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.capterra.com/p/197572/Bagisto/" rel="noopener noreferrer"&gt;4.3/5 (6 reviews)&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Github Stars&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/aimeos" rel="noopener noreferrer"&gt;17,100+&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/bagisto/bagisto" rel="noopener noreferrer"&gt;5000+&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;very high&lt;/td&gt;
&lt;td&gt;medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Extensibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;very high&lt;/td&gt;
&lt;td&gt;medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Configurability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2500+ options&lt;/td&gt;
&lt;td&gt;a few&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Modularity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;completely modular&lt;/td&gt;
&lt;td&gt;modular approach&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Databases&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;MySQL, PostgreSQL, SQL Server&lt;/td&gt;
&lt;td&gt;MySQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Translations&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;30+&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Payment gateways&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;100+&lt;/td&gt;
&lt;td&gt;PayPal, 10 (paid)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multiple currencies&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;partially&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Block/tier pricing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Customer/group prices&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;extension (paid)&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multiple tax per price&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Basket rule system&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;One-page checkout&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;no (?)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Time based data&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Products bought together&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Promoted products/category&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Last seen products&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Watched products&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Configurable data sets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;XML import/export&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SQL injection protection&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Content Security Policy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Elasticsearch&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;extension (paid)&lt;/td&gt;
&lt;td&gt;cache only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multi-tentant SaaS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;extension (paid)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AI-based text generation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AI-based text translation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AI-based image search&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SEO&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;fully optimized&lt;/td&gt;
&lt;td&gt;no schema.org&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CMS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;full-featured&lt;/td&gt;
&lt;td&gt;minimal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;POS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;extension (paid)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Code quality&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;9/10&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Unit tests&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;6000+&lt;/td&gt;
&lt;td&gt;a few&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Update customized shops&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;easy&lt;/td&gt;
&lt;td&gt;hard&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Bagisto offers more (paid) extensions than Aimeos but that's due to the fact that Bagisto base system hasn't many features included while in Aimeos all major features are part of the Aimeos core and thus available for free.&lt;br&gt;
Nevertheless, Bagisto offers some special extensions like an NTF marketplace builder for $10,000 that are not available for Aimeos.&lt;/p&gt;

&lt;p&gt;The ratings of Aimeos and Bagisto are taken from Capterra, a platform for product ratings where verified users can write detailed high quality reviews for products. Bagisto makes a lot of noise around their Trustpilot rating which is much better than their Capterra rating. But in Trustpilot, users only rate the customer service, not the product itself so the Trustpilot rating is equal to the service sub-category rating in Capterra only.&lt;/p&gt;

&lt;h1&gt;
  
  
  Backend
&lt;/h1&gt;

&lt;p&gt;The administration back-ends of Aimeos and Bagisto differ in layout and handling while the navigation is more or less similar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aimeos
&lt;/h2&gt;

&lt;p&gt;The admin back-end of Aimeos has a card based layout with a light and dark theme. Major attributes are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fully mobile optimized&lt;/li&gt;
&lt;li&gt;Supports right-to-left (RTL) languages like arabic&lt;/li&gt;
&lt;li&gt;Available in several languages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ntiaq0m9tmai3smibnt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ntiaq0m9tmai3smibnt.png" alt="Aimeos back-end"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Bagisto
&lt;/h2&gt;

&lt;p&gt;The back-end of Bagisto tries to resemble the Magento back-end in some way but is very light in terms of colors (only white and grey). Major attributes are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not mobile optimized&lt;/li&gt;
&lt;li&gt;Doesn't support RTL languages&lt;/li&gt;
&lt;li&gt;Only available in English&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqfnbngg0hdy1nh8ay4bk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqfnbngg0hdy1nh8ay4bk.png" alt="Bagisto back-end"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Performance
&lt;/h1&gt;

&lt;p&gt;Aimeos and Bagisto published some performance data but they are not directly comparable. Nevertheless, here are the raw numbers for the product category pages:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Aimeos&lt;/th&gt;
&lt;th&gt;Bagisto&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;App server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Apache: 8 core / 16 GB RAM&lt;/td&gt;
&lt;td&gt;Apache: 2 core / 4 GB RAM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Elasticsearch: 8 core / 32 GB RAM&lt;/td&gt;
&lt;td&gt;MySQL: 1 core / 2 GB RAM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SKUs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1.010 billion (1,010,000,000)&lt;/td&gt;
&lt;td&gt;1.3 million (1,300,000)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Categories&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1111&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Request/sec&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~600&lt;/td&gt;
&lt;td&gt;~100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Response time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;110 - 160 ms&lt;/td&gt;
&lt;td&gt;14,000 - 22,000 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hosting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.profihost.com/" rel="noopener noreferrer"&gt;Profihost&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://aws.amazon.com/" rel="noopener noreferrer"&gt;AWS&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The Aimeos test system has almost 1000x more products and 150x more categories than the Bagisto test system&lt;/li&gt;
&lt;li&gt;The Aimeos app server (they are handling the web requests) is 4x as powerful as the Bagisto one&lt;/li&gt;
&lt;li&gt;The Aimeos app server can handle 6x the requests of the Bagisto one&lt;/li&gt;
&lt;li&gt;The response time for a complete page load of the Aimeos setup is 125x better than the Bagisto one&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What you can see is that the Bagisto test system has been sized way to small for the load because the response time for a complete page load is at least 14sec and up to 22sec. Such response times render every eCommerce site unusable and the Bagisto setup seems to be only good for ~10 concurrent users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Aimeos: &lt;a href="https://aimeos.org/tips/gigacommerce-aimeos-shop-performance-with-1-billion-items/" rel="noopener noreferrer"&gt;#gigacommerce – Aimeos shop performance with 1 billion items&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bagisto: &lt;a href="https://bagisto.com/en/ecommerce-benchmarking-report/" rel="noopener noreferrer"&gt;Bagisto eCommerce Benchmarking Report&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Which one is suited better for your needs depends on your requirements. If you need a scalable system that can be highly customized, you should have a deeper look at &lt;strong&gt;&lt;a href="https://aimeos.org/Laravel" rel="noopener noreferrer"&gt;Aimeos&lt;/a&gt;&lt;/strong&gt;. Bagisto is the right choice if you need one of their special extensions. For simple shop requirements, both will do their job and it depends on personal preferences, e.g. which admin back-end you prefer.&lt;/p&gt;

&lt;p&gt;Demo installations:&lt;br&gt;
Aimeos: &lt;a href="https://demo.aimeos.org/" rel="noopener noreferrer"&gt;https://demo.aimeos.org/&lt;/a&gt;&lt;br&gt;
Bagisto: &lt;a href="https://demo.bagisto.com/" rel="noopener noreferrer"&gt;https://demo.bagisto.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aimeos</category>
      <category>bagisto</category>
      <category>laravel</category>
      <category>ecommerce</category>
    </item>
    <item>
      <title>PHP Map: Advanced collection methods</title>
      <dc:creator>toco</dc:creator>
      <pubDate>Wed, 11 Mar 2020 11:29:25 +0000</pubDate>
      <link>https://forem.com/shop/php-advanced-map-methods-1a9l</link>
      <guid>https://forem.com/shop/php-advanced-map-methods-1a9l</guid>
      <description>&lt;p&gt;The &lt;strong&gt;PHP Map package&lt;/strong&gt; for collections contains many methods to ease your day to day work. They are &lt;strong&gt;extremely helpful&lt;/strong&gt; in a lot of situations where you’ve written custom code up to now. This tutorial explains some of the &lt;strong&gt;most useful ones&lt;/strong&gt; you don’t want to miss any more!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/aimeos/map"&gt;Documentation at Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://packagist.org/packages/aimeos/map"&gt;Composer package on Packagist&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;To use the PHP Map package, you have to add it to your composer based application:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;composer req aimeos/map&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Afterwards, there will be a map() function available, that creates a Map object which offers the methods explained.&lt;/p&gt;

&lt;h2&gt;
  
  
  col(): Map key/value pairs
&lt;/h2&gt;

&lt;p&gt;There are numerous times when you need to transform an existing array into a list of key/value pairs. Think about a list of database records for example which should be indexed by ID instead of a sequencial index. The col() method creates that without the necessity of a loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$rows = [['id' =&amp;gt; 1, 'code' =&amp;gt; 'a'], ['id' =&amp;gt; 3, 'code' =&amp;gt; 'd']];
$result = map( $rows )-&amp;gt;col( 'code', 'id' );

// Result equals:
map( [1 =&amp;gt; 'a', 3 =&amp;gt; 'd'] );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This does also work with objects if they implement the magic PHP &lt;code&gt;__get()&lt;/code&gt; method.&lt;/p&gt;

&lt;h2&gt;
  
  
  collapse() and flat(): Transform multi-dimensional arrays
&lt;/h2&gt;

&lt;p&gt;Do you remember the last time when you had a multi-dimensional array and you needed a flat array of all elements? If you know the maximum depth, you can nest several loops but if not, you need to write a recursive function, which is very cumbersome. The Map object offers the flat() method, that can to do that in one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$array = [[1, 2], [3, [4, 5]]];
$result = map( $array )-&amp;gt;flat();

// Result equals:
map( [1, 2, 3, 4, 5] );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There’s a similar method named &lt;code&gt;collapse()&lt;/code&gt;, that does almost the same but keeps the key of each value. Thus, it will overwrite elements with duplicate keys (also numeric keys):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$array = [['a' =&amp;gt; 1, 'b' =&amp;gt; 2], ['c' =&amp;gt; 3, ['a' =&amp;gt; 4, 'b' =&amp;gt; 5]]];
$result = map( $array )-&amp;gt;collapse();

// Result equals:
map( ['a' =&amp;gt; 4, 'b' =&amp;gt; 5, 'c' =&amp;gt; 3] );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both methods accept the number of levels they should collapse or flatten as parameter. That way it’s easy to keep e.g. the third level and above unflattened or uncollapsed.&lt;/p&gt;

&lt;h2&gt;
  
  
  concat(), merge() and union(): Differences in combining arrays
&lt;/h2&gt;

&lt;p&gt;In PHP, you can combine arrays using &lt;code&gt;array_merge()&lt;/code&gt; or the &lt;code&gt;+&lt;/code&gt; operator but their results are different. The PHP map package also offers the &lt;code&gt;concat()&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$one = [0 =&amp;gt; 'a', 'b' =&amp;gt; 2];
$two = ['b' =&amp;gt; 3, 0 =&amp;gt; 4];

$result = map( $one )-&amp;gt;concat( $two );
//equals map( [0 =&amp;gt; 'a', 'b' =&amp;gt; 2, 1 =&amp;gt; 3, 2 =&amp;gt; 4] );

$result = map( $one )-&amp;gt;merge( $two );
//equals map( [0 =&amp;gt; 'a', 'b' =&amp;gt; 3, 1 =&amp;gt; 4] );

$result = map( $one )-&amp;gt;union( $two );
//equals map( [0 =&amp;gt; 'a', 'b' =&amp;gt; 2] );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;concat()&lt;/code&gt; combines the elements of both arrays but doesn’t care about their keys and the resulting list will contain all elements of both arrays. &lt;code&gt;merge()&lt;/code&gt; which uses the &lt;code&gt;array_merge()&lt;/code&gt; function overwrites existing string keys but renumbers numeric keys. &lt;code&gt;union()&lt;/code&gt; is the same as using the &lt;code&gt;+&lt;/code&gt; operator and doesn’t add elements whose keys does already exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  equals(): Test if arrays contains the same elements
&lt;/h2&gt;

&lt;p&gt;To compare arrays, PHP only offers the &lt;code&gt;==&lt;/code&gt; and &lt;code&gt;===&lt;/code&gt; operators. They return only true if both array contains the same elements with the same keys (and the same order in case of &lt;code&gt;===&lt;/code&gt;). Contrary, the &lt;code&gt;equals()&lt;/code&gt; method of the Map object can also test arrays without checking the keys:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$one = ['a', 'b'];
$two = ['b', 'a'];

map( $one )-&amp;gt;equals( $two ); // true
map( $one )-&amp;gt;equals( $two, true ); // false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When passing true as second parameter, &lt;code&gt;equals()&lt;/code&gt; works like the &lt;code&gt;==&lt;/code&gt; operator.&lt;/p&gt;

&lt;h2&gt;
  
  
  find(): Return the first matching element
&lt;/h2&gt;

&lt;p&gt;Sometimes, you need the first element from an array that matches your needs. The Map object offers the find() method which allows you to pass a closure function as parameter. This anonymous function can check whose element matches your needs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;map( ['a', 'c', 'e'] )-&amp;gt;find( function( $value, $key ) {
    return $value &amp;gt;= 'b';
} );

// Result equals 'c'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If no matching value is found, null is returned. If you pass true as second parameter, the search for the matching element will be reversed and you will get the last matching element.&lt;/p&gt;

&lt;h2&gt;
  
  
  first(), last(), get() and pull(): Advanced ways to retrieve an element
&lt;/h2&gt;

&lt;p&gt;Fetching the first, last or any element of a list of elements is very handy and most useful in many cases. But the PHP Map object offers more than that. What if those methods don’t return null if no element is found but throw an exception or execute a closure? Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if( ( $item = map( [] ) )-&amp;gt;first() === null ) {
    throw new \Exception( 'error' );
}

if( ( $item = map( [] ) )-&amp;gt;last() === null ) {
    // fetch and return record from database
}
$id = $item-&amp;gt;getId();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can simply write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$id = map( [] )-&amp;gt;first( new \Exception( 'error' ) )-&amp;gt;getId();

$id = map( [] )-&amp;gt;last( function() {
    // fetch and return record from database
} )-&amp;gt;getId();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All methods (&lt;code&gt;first()&lt;/code&gt;, &lt;code&gt;last()&lt;/code&gt;, &lt;code&gt;get()&lt;/code&gt; and &lt;code&gt;pull()&lt;/code&gt;) methods accept either an exception that’s thrown or a closure that’s executed if no element is available. Thus, it saves you the annoying checks that make you code full of if/else statements.&lt;/p&gt;

&lt;p&gt;If you pass an exception, the exception object is created whether it’s used or not. This is no problem as long as you don’t do that in a loop. Then, create one exception object before the loop and pass only the variable to the methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  in(): Check if several elements are in the list
&lt;/h2&gt;

&lt;p&gt;To test if an value is in a list of elements with &lt;code&gt;in()&lt;/code&gt; isn’t much different than using &lt;code&gt;in_array()&lt;/code&gt;. But what if you need to do that several times with different elements? Then, &lt;code&gt;in()&lt;/code&gt; takes away the burden of doing that within a loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;map( ['a', 'b', 'c'] )-&amp;gt;in( 'b' ); // true
map( ['a', 'b', 'c'] )-&amp;gt;in( ['b', 'a'] ); // true
map( ['a', 'b', 'c'] )-&amp;gt;in( ['d', 'a'] ); // false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;in()&lt;/code&gt; method of the Map object checks if all elements of the passed array are available in the list and only then it returns true.&lt;/p&gt;

&lt;h2&gt;
  
  
  toJson(): Encode everything into JSON
&lt;/h2&gt;

&lt;p&gt;When working with APIs, you almost always need to encode the result into its JSON representation. The PHP map object offers a convenient way to transform all elements to JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;map( ['a', 'b', ['c', 'd'] )-&amp;gt;toJson();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Like the PHP &lt;code&gt;json_encode()&lt;/code&gt; method, it accepts a parameter for passing options that are used during encoding the elements. There are two that you may find extremely useful:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;map( ['a', 'b', ['c', 'd'] )-&amp;gt;toJson( JSON_FORCE_OBJECT|JSON_HEX_QUOT );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;JSON_FORCE_OBJECT&lt;/code&gt; always creates &lt;code&gt;{}&lt;/code&gt;, even for empty lists to avoid being encoded as &lt;code&gt;[]&lt;/code&gt;. If you add JSON output to HTML data attributes for storing something you need for dynamic Javascript features later on, &lt;code&gt;JSON_HEX_QUOT&lt;/code&gt; saves you from generating invalid HTML.&lt;/p&gt;

&lt;h2&gt;
  
  
  walk(): Visit each value in a multi-dimensional array
&lt;/h2&gt;

&lt;p&gt;You receive a multi-dimensional array from an HTML form and want to make sure that all values are of a certain type or doesn’t contain HTML tags? Then, the &lt;code&gt;walk()&lt;/code&gt; method of the PHP Map object is your friend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;map( ['a', 'b', ['c', '&amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;'] )-&amp;gt;walk( function( &amp;amp;$val ) {
    $val = strip_tags( $val );
} );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also create a mapping based on the list you pass as second parameter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$mapping = [1 =&amp;gt; 'one', 2 =&amp;gt; 'two', 3 =&amp;gt; 'three', 4 =&amp;gt; 'four'];

map( [1, 2, [3, 4] )-&amp;gt;walk( function( &amp;amp;$val, $key, $data ) {
    $val = $data[$val] ?? $val;
}, $mapping );

// Result equals
map( ['one', 'two', ['three', 'four']] )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  method(): Register your own methods
&lt;/h2&gt;

&lt;p&gt;The best of all comes last: You can extend the PHP Map object by your own methods! This is extremely handy if you need the same code several times and different places. To register your own method, just do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\Aimeos\Map::method( 'strrev', function( $sep ) {
    return strrev( join( '-', $this-&amp;gt;list ) );
} );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your closure function has access to the internal array of elements using $this-&amp;gt;list and you can read and/or modify that internal array of the Map object. You can use your new method the same way as any other method of the Map object afterwards:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;map( ['a', 'b'] )-&amp;gt;strrev( '-' );
// returns "b-a"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The PHP Map object offers some great methods that can simplify your code drastically and you will never want to miss them any more. Especially the possibility to register own methods to extend the Map object dynamically gives your great power in a few lines of code.&lt;/p&gt;

</description>
      <category>php</category>
      <category>array</category>
      <category>tutoial</category>
      <category>collection</category>
    </item>
    <item>
      <title>PHP Collections: Array to Map</title>
      <dc:creator>toco</dc:creator>
      <pubDate>Tue, 07 Jan 2020 16:34:56 +0000</pubDate>
      <link>https://forem.com/shop/php-array-to-map-o3f</link>
      <guid>https://forem.com/shop/php-array-to-map-o3f</guid>
      <description>&lt;p&gt;&lt;strong&gt;Arrays&lt;/strong&gt; are the working horse of PHP, the programming language used by the vast majority of web applications. An array seems to be incredible simple to use but things get &lt;strong&gt;complicated and ugly&lt;/strong&gt; when PHP functions for &lt;strong&gt;array manipulation&lt;/strong&gt; come into play. Are you tired of hard to read code with excessive error handling too? Then &lt;strong&gt;collections&lt;/strong&gt; can be the answer.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/aimeos/map"&gt;Documentation at Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://packagist.org/packages/aimeos/map"&gt;Composer package on Packagist&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;Here’s a common example of how array manipulation is done in most PHP code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$list = [
    ['id' =&amp;gt; 'one', 'value' =&amp;gt; 'value1'],
    ['id' =&amp;gt; 'two', 'value' =&amp;gt; 'value2'],
    null
];

$list[] = ['id' =&amp;gt; 'three', 'value' =&amp;gt; 'value3'];    // add element
unset( $list[0] );                                   // remove element
$list = array_filter( $list );                       // remove empty values
sort( $list );                                       // sort elements
$pairs = array_column( $list, 'value', 'id' );       // create ['three' =&amp;gt; 'value3']
$value = reset( $pairs ) ?: null;                    // return first value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It adds/removes elements, sorts and transforms the content and retrieves the first element. You can’t write that shorter or more elegant and moreover, you need to check almost all array functions for errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using maps
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://packagist.org/packages/aimeos/map"&gt;map composer package&lt;/a&gt; offers an easy API comparable to jQuery or Laravel collections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer req aimeos/map
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When using the Map object, you can do the same as above more elegant with less code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$list = [
    ['id' =&amp;gt; 'one', 'value' =&amp;gt; 'value1'],
    ['id' =&amp;gt; 'two', 'value' =&amp;gt; 'value2'],
    null
];

$value = map( $list )                                // create Map
    -&amp;gt;push( ['id' =&amp;gt; 'three', 'value' =&amp;gt; 'value3'] ) // add element
    -&amp;gt;remove( 0 )                                    // remove element
    -&amp;gt;filter()                                       // remove empty values
    -&amp;gt;sort()                                         // sort elements
    -&amp;gt;col( 'value', 'id' )                           // create ['three' =&amp;gt; 'value3']
    -&amp;gt;first();                                       // return first value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And contrary to PHP arrays, you don’t have to care about error handling because either, there are no errors possible or the Map object will throw an exception if something is really wrong.&lt;/p&gt;

&lt;p&gt;Of course, you can use the Map object still like a plain PHP array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$map[] = ['id' =&amp;gt; 'three', 'value' =&amp;gt; 'value3'];
$value = $map[0];
count( $map );
foreach( $map as $key =&amp;gt; value );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In addition, Map objects allow you to pass anonymous functions to a lot of methods. Thus, you can process and transform the elements according to your current needs, e.g. using the &lt;code&gt;each()&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$map-&amp;gt;each( function( $val, $key ) {
    echo $key . ': ' . $val;
} );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can even extend Maps dynamically by own methods. This is especially useful if you need a transformation of the Map elements more often and at several places of your code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Map::method( 'strrev', function( $sep ) {
    return strrev( join( '-', $this-&amp;gt;items ) );
} );
Map::from( ['a', 'b'] )-&amp;gt;strrev( '-' );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The best part is using a Map like a jQuery object, where methods are applied to all objects of the Map. Then, you can create expressive code in one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MyClass {
    private $code;
    private $status;

    public function __construct( $code ) { $this-&amp;gt;code = $code; }
    public function setStatus( $s ) { $this-&amp;gt;stat = $s; return $this; }
    public function getCode() { return $this-&amp;gt;code; }
}

$objects = Map::from( ['a' =&amp;gt; new MyClass( 'x' ), 'b' =&amp;gt; new MyClass( 'y' )] );
$result = $objects-&amp;gt;setStatus( 1 )-&amp;gt;getCode()-&amp;gt;toArray();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example will call &lt;code&gt;setStatus(1)&lt;/code&gt; on all objects and creates a new Map with the returned values. Because &lt;code&gt;setStatus()&lt;/code&gt; returns the same object (&lt;code&gt;$this&lt;/code&gt;), we can apply another method on all objects afterwards (&lt;code&gt;getCode()&lt;/code&gt;). The results of &lt;code&gt;getCode()&lt;/code&gt; is wrapped in a Map object again and &lt;code&gt;toArray()&lt;/code&gt; returns a plain PHP array which consists of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;['a' =&amp;gt; 'x', 'b' =&amp;gt; 'y']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Available methods
&lt;/h2&gt;

&lt;p&gt;The Map object contains methods for almost all array functions available and more like &lt;code&gt;collapse()&lt;/code&gt;, &lt;code&gt;flat()&lt;/code&gt;, &lt;code&gt;toJson()&lt;/code&gt; or methods found in the Javascript Array prototype. Here’s a list of its methods and for documentation, have a look at the Map readme at GitHub where you can also check the code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;function map()&lt;/strong&gt; : Creates a new map from elements&lt;br&gt;
&lt;strong&gt;arsort()&lt;/strong&gt; : Reverse sort elements with keys&lt;br&gt;
&lt;strong&gt;asort()&lt;/strong&gt; : Sort elements with keys&lt;br&gt;
&lt;strong&gt;chunk()&lt;/strong&gt; : Splits the map into chunks&lt;br&gt;
&lt;strong&gt;clear()&lt;/strong&gt; : Removes all elements&lt;br&gt;
&lt;strong&gt;col()&lt;/strong&gt; : Creates a key/value mapping&lt;br&gt;
&lt;strong&gt;collapse()&lt;/strong&gt; : Collapses multi-dimensional elements&lt;br&gt;
&lt;strong&gt;concat()&lt;/strong&gt; : Combines the elements&lt;br&gt;
&lt;strong&gt;copy()&lt;/strong&gt; : Creates a new copy&lt;br&gt;
&lt;strong&gt;count()&lt;/strong&gt; : Returns the number of elements&lt;br&gt;
&lt;strong&gt;diff()&lt;/strong&gt; : Returns the missing elements&lt;br&gt;
&lt;strong&gt;diffAssoc()&lt;/strong&gt; : Returns the missing elements and checks keys&lt;br&gt;
&lt;strong&gt;diffKeys()&lt;/strong&gt; : Returns the missing elements by keys&lt;br&gt;
&lt;strong&gt;each()&lt;/strong&gt; : Applies a callback to each element&lt;br&gt;
&lt;strong&gt;empty()&lt;/strong&gt; : Tests if map is empty&lt;br&gt;
&lt;strong&gt;equals()&lt;/strong&gt; : Tests if map contents are equal&lt;br&gt;
&lt;strong&gt;filter()&lt;/strong&gt; : Applies a filter to the map elements&lt;br&gt;
&lt;strong&gt;find()&lt;/strong&gt; : Returns the first matching element&lt;br&gt;
&lt;strong&gt;first()&lt;/strong&gt; : Returns the first element&lt;br&gt;
&lt;strong&gt;flip()&lt;/strong&gt; : Exchanges keys with their values&lt;br&gt;
&lt;strong&gt;flat()&lt;/strong&gt; : Flattens multi-dimensional elements&lt;br&gt;
&lt;strong&gt;from()&lt;/strong&gt; : Creates a new map from passed elements&lt;br&gt;
&lt;strong&gt;get()&lt;/strong&gt; : Returns an element by key&lt;br&gt;
&lt;strong&gt;has()&lt;/strong&gt; : Tests if a key exists&lt;br&gt;
&lt;strong&gt;in()&lt;/strong&gt; : Tests if element is included&lt;br&gt;
&lt;strong&gt;includes()&lt;/strong&gt; : Tests if element is included&lt;br&gt;
&lt;strong&gt;intersect()&lt;/strong&gt; : Returns the shared elements&lt;br&gt;
&lt;strong&gt;intersectAssoc()&lt;/strong&gt; : Returns the shared elements and checks keys&lt;br&gt;
&lt;strong&gt;intersectKeys()&lt;/strong&gt; : Returns the shared elements by keys&lt;br&gt;
&lt;strong&gt;isEmpty()&lt;/strong&gt; : Tests if map is empty&lt;br&gt;
&lt;strong&gt;join()&lt;/strong&gt; : Returns concatenated elements as string&lt;br&gt;
&lt;strong&gt;keys()&lt;/strong&gt; : Returns the keys&lt;br&gt;
&lt;strong&gt;krsort()&lt;/strong&gt; : Reverse sort elements by keys&lt;br&gt;
&lt;strong&gt;ksort()&lt;/strong&gt; : Sort elements by keys&lt;br&gt;
&lt;strong&gt;last()&lt;/strong&gt; : Returns the last element&lt;br&gt;
&lt;strong&gt;map()&lt;/strong&gt; : Applies a callback to each element and returns the results&lt;br&gt;
&lt;strong&gt;merge()&lt;/strong&gt; : Combines elements overwriting existing ones&lt;br&gt;
&lt;strong&gt;method()&lt;/strong&gt; : Registers a custom method&lt;br&gt;
&lt;strong&gt;pipe()&lt;/strong&gt; : Applies a callback to the map&lt;br&gt;
&lt;strong&gt;pop()&lt;/strong&gt; : Returns and removes the last element&lt;br&gt;
&lt;strong&gt;pull()&lt;/strong&gt; : Returns and removes an element by key&lt;br&gt;
&lt;strong&gt;push()&lt;/strong&gt; : Adds an element to the end&lt;br&gt;
&lt;strong&gt;random()&lt;/strong&gt; : Returns random elements&lt;br&gt;
&lt;strong&gt;reduce()&lt;/strong&gt; : Computes a value for the map content&lt;br&gt;
&lt;strong&gt;remove()&lt;/strong&gt; : Removes an element by key&lt;br&gt;
&lt;strong&gt;replace()&lt;/strong&gt; : Replaces elements recursively&lt;br&gt;
&lt;strong&gt;reverse()&lt;/strong&gt; : Reverses the array order&lt;br&gt;
&lt;strong&gt;rsort()&lt;/strong&gt; : Reverse sort elements&lt;br&gt;
&lt;strong&gt;search()&lt;/strong&gt; : Find the key of an element&lt;br&gt;
&lt;strong&gt;set()&lt;/strong&gt; : Overwrites an element&lt;br&gt;
&lt;strong&gt;shift()&lt;/strong&gt; : Returns and removes the first element&lt;br&gt;
&lt;strong&gt;shuffle()&lt;/strong&gt; : Randomizes the element order&lt;br&gt;
&lt;strong&gt;slice()&lt;/strong&gt; : Returns a slice of the map&lt;br&gt;
&lt;strong&gt;sort()&lt;/strong&gt; : Sorts elements&lt;br&gt;
&lt;strong&gt;split()&lt;/strong&gt; : Splits a string into map elements&lt;br&gt;
&lt;strong&gt;splice()&lt;/strong&gt; : Replaces a slice by new elements&lt;br&gt;
&lt;strong&gt;toArray()&lt;/strong&gt; : Returns the plain array&lt;br&gt;
&lt;strong&gt;toJson()&lt;/strong&gt; : Returns the elements in JSON format&lt;br&gt;
&lt;strong&gt;uasort()&lt;/strong&gt; : Sorts elements with keys using callback&lt;br&gt;
&lt;strong&gt;uksort()&lt;/strong&gt; : Sorts elements by keys using callback&lt;br&gt;
&lt;strong&gt;union()&lt;/strong&gt; : Combines the element without overwriting&lt;br&gt;
&lt;strong&gt;unique()&lt;/strong&gt; : Returns unique elements&lt;br&gt;
&lt;strong&gt;unshift()&lt;/strong&gt; : Adds an element at the beginning&lt;br&gt;
&lt;strong&gt;usort()&lt;/strong&gt; : Sorts elements using callback&lt;br&gt;
&lt;strong&gt;values()&lt;/strong&gt; : Returns all elements with new keys&lt;/p&gt;

&lt;p&gt;Again, the &lt;a href="https://github.com/aimeos/map#methods"&gt;Map documentation&lt;/a&gt; offers descriptions, explains parameters/return values and has examples for each method. Some methods are even better documented than the corresponding PHP array function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Map objects are an easy to use and elegant way to handle PHP arrays. After using it for a while you won’t want to remember the times before. If you’ve already worked with jQuery and like it’s simplicity, you will feel like home when using appropriate lists of objects in your application.&lt;/p&gt;

&lt;p&gt;As the Map methods are using the native array functions or are highly optimized, it’s also save to use them in large scale applications. The documentation contains a section about the &lt;a href="https://github.com/aimeos/map#methods"&gt;Map performance&lt;/a&gt; and hints to avoid performance bottlenecks.&lt;/p&gt;

</description>
      <category>php</category>
      <category>array</category>
      <category>tutorial</category>
      <category>collection</category>
    </item>
    <item>
      <title>Laravel E-Commerce - Open Source Top 4</title>
      <dc:creator>toco</dc:creator>
      <pubDate>Thu, 12 Dec 2019 18:54:34 +0000</pubDate>
      <link>https://forem.com/shop/laravel-e-commerce-open-source-top-4-fma</link>
      <guid>https://forem.com/shop/laravel-e-commerce-open-source-top-4-fma</guid>
      <description>&lt;p&gt;&lt;strong&gt;Laravel eCommerce&lt;/strong&gt; describes online shop, marketplace and B2B eCommerce solutions based on the Laravel PHP framework. They can be standalone applications, headless API microservices or packages that can be installed in any Laravel application to add eCommerce features to existing setups.&lt;/p&gt;

&lt;p&gt;Laravel is the &lt;strong&gt;most popular PHP framework&lt;/strong&gt; and that for good reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easy to customize and use&lt;/li&gt;
&lt;li&gt;Really great community&lt;/li&gt;
&lt;li&gt;Fast and scalable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These reasons make Laravel a perfect choice for &lt;strong&gt;building online shops and eCommerce applications&lt;/strong&gt;. For our favorite PHP framework, e-commere packages for different purposes exist. Here's a list of the top Laravel eCommerce packages in their category:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;&lt;a href="https://aimeos.org/Laravel"&gt;Aimeos&lt;/a&gt;&lt;/strong&gt;  (eCommerce framework, headless API &amp;amp; shop system)&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;&lt;a href="https://bagisto.com"&gt;Bagisto&lt;/a&gt;&lt;/strong&gt;  (shop system)&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;&lt;a href="https://getcandy.io"&gt;GetCandy&lt;/a&gt;&lt;/strong&gt;  (API only)&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;&lt;a href="https://github.com/Crinsane/LaravelShoppingcart"&gt;LaravelShoppingcart&lt;/a&gt;&lt;/strong&gt;  (shopping cart)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What packages is best may depend on your own requirements, so let’s have a look which suits best for each case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aimeos
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HhFlgbKS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1125/1%2AWRpLrfLcy2th57KgJlebrg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HhFlgbKS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1125/1%2AWRpLrfLcy2th57KgJlebrg.png" alt="Aimeos" width="880" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aimeos is the &lt;strong&gt;most liked&lt;/strong&gt; eCommerce framework for Laravel and is build for being as &lt;strong&gt;extensible&lt;/strong&gt; as the Laravel PHP framework itself and integrates into existing Laravel 6/7/8 applications. It’s &lt;strong&gt;feature rich&lt;/strong&gt; and you can &lt;strong&gt;adapt everything&lt;/strong&gt; to your needs regardless of what your requirements are.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Homepage:&lt;/strong&gt;  &lt;a href="https://aimeos.org/Laravel"&gt;https://aimeos.org/Laravel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supports:&lt;/strong&gt; Laravel 6.x LTS, 7.x, 8.x&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Positive:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Supports all current Laravel versions&lt;/li&gt;
&lt;li&gt;Multi channel, multi vendor and multi inventory support&lt;/li&gt;
&lt;li&gt;Has multi-tenant SaaS support including custom domains&lt;/li&gt;
&lt;li&gt;Ultra fast render times of 20ms and response times of 100ms&lt;/li&gt;
&lt;li&gt;Has virtual, configurable and custom products incl. bundles&lt;/li&gt;
&lt;li&gt;Sell every product as subscription with recurring payment&lt;/li&gt;
&lt;li&gt;Supports discount rules and vouchers&lt;/li&gt;
&lt;li&gt;100+ payment gateways via Omnipay PHP library&lt;/li&gt;
&lt;li&gt;JSON REST API build on the jsonapi.org standard&lt;/li&gt;
&lt;li&gt;Extension to build own market places available&lt;/li&gt;
&lt;li&gt;Great documentation available&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Negative:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learning curve due to its huge feature set and extensible architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Bagisto
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UsUDplny--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1250/1%2A_GVJ29_sVzExQes0FOxrYg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UsUDplny--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1250/1%2A_GVJ29_sVzExQes0FOxrYg.png" alt="Bagisto" width="880" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bagisto is a &lt;strong&gt;stand-alone&lt;/strong&gt; application that can't be integrated into already existing Laravel applications. It primarily targets &lt;strong&gt;small business&lt;/strong&gt; and the middle east area with native &lt;strong&gt;RTL (right-to-left) support&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Homepage:&lt;/strong&gt;  &lt;a href="https://bagisto.com"&gt;https://bagisto.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supports:&lt;/strong&gt; Laravel 7.x&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Positive:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Has configurable, group, bundle and virtual products&lt;/li&gt;
&lt;li&gt;Has multi channel and multi inventory support&lt;/li&gt;
&lt;li&gt;Supports discount rules&lt;/li&gt;
&lt;li&gt;JSON REST API build on jsonapi.org standard&lt;/li&gt;
&lt;li&gt;Extension to build own market places available&lt;/li&gt;
&lt;li&gt;Lots of videos from the company about Bagisto&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Negative:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not suitable for existing Laravel applications&lt;/li&gt;
&lt;li&gt;No real multi-currency support (fixed conversion only)&lt;/li&gt;
&lt;li&gt;Almost all available payment integrations must be paid for&lt;/li&gt;
&lt;li&gt;~100 tables incl. fixed structures that are hard to extend&lt;/li&gt;
&lt;li&gt;Requires ElasticSearch or Algolia for fast search&lt;/li&gt;
&lt;li&gt;CMS features are too simple for real use&lt;/li&gt;
&lt;li&gt;Limited documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  GetCandy
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XsE7QpbF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1958/0%2Aps8ufspnvERxvv33.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XsE7QpbF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1958/0%2Aps8ufspnvERxvv33.jpg" alt="GetCandy" width="880" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GetCandy is a headless API package that offers a &lt;strong&gt;REST API only&lt;/strong&gt;. There's also an &lt;strong&gt;admin package&lt;/strong&gt; for managing products, customers and orders. &lt;strong&gt;No front-end&lt;/strong&gt; is included because that you need to build on your own.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Homepage:&lt;/strong&gt;  &lt;a href="https://getcandy.io"&gt;https://getcandy.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supports:&lt;/strong&gt; Laravel 5.7&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Positive:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Progressive web applications (PWA) backend&lt;/li&gt;
&lt;li&gt;Should scale because it requires ElasticSearch as storage (no MySQL)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Negative:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unsupported and outdated Laravel version&lt;/li&gt;
&lt;li&gt;No front-end as example available&lt;/li&gt;
&lt;li&gt;Very limited feature set&lt;/li&gt;
&lt;li&gt;Payment integrations are not available&lt;/li&gt;
&lt;li&gt;Slow development (weeks and months between commits)&lt;/li&gt;
&lt;li&gt;Limited documentation&lt;/li&gt;
&lt;li&gt;Still in alpha stage&lt;/li&gt;
&lt;li&gt;Future is uncertain at the moment&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  LaravelShoppingcart (shopping cart)
&lt;/h2&gt;

&lt;p&gt;A shopping cart package is &lt;strong&gt;small, easy to use&lt;/strong&gt; and contains a &lt;strong&gt;limited features&lt;/strong&gt;. The LaravelShoppingcart package consists of a cart/whishlist only and need to be integrated into an existing Laravel 5 application. You have to &lt;strong&gt;implement products and checkout yourself&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Homepage:&lt;/strong&gt;  &lt;a href="https://github.com/Hardevine/LaravelShoppingcart"&gt;https://github.com/Hardevine/LaravelShoppingcart&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supports:&lt;/strong&gt; 5.x, 6.x, 7.x and 8.x&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Positive:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only package that supports all Laravel versions since Laravel 5&lt;/li&gt;
&lt;li&gt;Easy to learn and relative easy to integrate&lt;/li&gt;
&lt;li&gt;If you already have products, it adds the cart features&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Negative:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Feature set is very limited &lt;/li&gt;
&lt;li&gt;A checkout process isn't available&lt;/li&gt;
&lt;li&gt;Won't scale to higher volumes&lt;/li&gt;
&lt;li&gt;No example template is included&lt;/li&gt;
&lt;li&gt;Github account contains lots of unresolved issues&lt;/li&gt;
&lt;li&gt;No support for Laravel 5.8 and later&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://aimeos.org/laravel-ecommerce-package"&gt;Aimeos&lt;/a&gt;&lt;/strong&gt; is the top eCommerce framework for Laravel if you need a highly customizable solution that is able to scale. Bagisto offers a simple shop system based on Laravel if you start from a green field. LaravelShoppingcart is a good choice for a few products you need a cart for while GetCandy is promising if you want a PWA frontend only and build that on your own.&lt;/p&gt;

&lt;p&gt;Let’s discuss your own experiences :-)&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>ecommerce</category>
      <category>shop</category>
      <category>framework</category>
    </item>
  </channel>
</rss>
