### Install Pimcore Demo Application using Docker Source: https://context7.com/pimcore/demo/llms.txt Guide for installing the Pimcore Demo Application within a Docker environment. This method avoids local PHP setup and uses Docker images for deployment. It covers project initialization, service startup, asset installation, and Pimcore setup with database configuration. ```bash # Initialize demo project using Pimcore Docker image docker run -u `id -u`:`id -g` --rm -v `pwd`:/var/www/html pimcore/pimcore:php8.3-latest composer create-project --no-scripts pimcore/demo my-project cd my-project/ # Configure user permissions in docker-compose.yaml (uncomment user: '1000:1000' lines) # Start services docker compose up -d # Install assets docker compose exec php bin/console assets:install --symlink --relative # Install Pimcore with database initialization docker compose exec php vendor/bin/pimcore-install --mysql-host-socket=db --mysql-username=pimcore --mysql-password=pimcore --mysql-database=pimcore # Clear cache docker compose exec php bin/console cache:clear # Access: # Frontend: http://localhost # Admin: http://localhost/admin ``` -------------------------------- ### Install Pimcore Demo Application via Composer Source: https://context7.com/pimcore/demo/llms.txt Instructions for installing the Pimcore Demo Application using Composer. This process involves creating a project, installing dependencies, setting up assets, and running the Pimcore installer for database configuration. It also includes commands for clearing and warming up the cache. ```bash # Create project and install dependencies COMPOSER_MEMORY_LIMIT=-1 composer create-project --no-scripts pimcore/demo my-project cd ./my-project # Install frontend assets with symlinks ./bin/console assets:install --symlink --relative # Run Pimcore installer (interactive - prompts for admin credentials) ./vendor/bin/pimcore-install # Clear and warm up cache ./bin/console cache:clear # Access points after installation: # Frontend: https://your-host/ # Admin: https://your-host/admin ``` -------------------------------- ### Initialize Pimcore Demo Project with Docker Source: https://github.com/pimcore/demo/blob/2025.x/README.md Initializes the Pimcore demo project using a Docker image, then uses Docker Compose to start services, install assets, and initialize Pimcore with a MySQL database. This method avoids the need for a local PHP environment. ```bash docker run -u `id -u`:`id -g` --rm -v `pwd`:/var/www/html pimcore/pimcore:php8.3-latest composer create-project --no-scripts pimcore/demo my-project cd my-project/ # Retrieve your local user and group id: echo `id -u`:`id -g` # Update user/group ids in docker-compose.yaml if necessary docker compose up -d docker compose exec php bin/console assets:install --symlink --relative docker compose exec php vendor/bin/pimcore-install --mysql-host-socket=db --mysql-username=pimcore --mysql-password=pimcore --mysql-database=pimcore docker compose exec php bin/console cache:clear ``` -------------------------------- ### Install Pimcore Demo with Composer Source: https://github.com/pimcore/demo/blob/2025.x/README.md Installs the Pimcore demo project using Composer, sets up assets, installs Pimcore, and clears the cache. This method requires a local PHP environment with Composer. ```bash COMPOSER_MEMORY_LIMIT=-1 composer create-project --no-scripts pimcore/demo my-project cd ./my-project ./bin/console assets:install --symlink --relative ./vendor/bin/pimcore-install ./bin/console cache:clear ``` -------------------------------- ### Custom Areabrick Base Class and Example (PHP) Source: https://context7.com/pimcore/demo/llms.txt Defines a base abstract class for custom areabricks in Pimcore, extending Pimcore's AbstractTemplateAreabrick. It sets global template location and Twig suffix. An example 'Featurette' areabrick is provided, along with a list of available areabricks. ```php getCartManager()->getOrCreateCartByName('cart'); if ($cart->isEmpty()) { return $this->redirectToRoute('shop-cart-detail'); } $checkoutManager = $factory->getCheckoutManager($cart); $paymentProvider = $checkoutManager->getPayment(); // Generate PayPal SDK URL $SDKUrl = ''; if ($paymentProvider instanceof PayPalSmartPaymentButton) { $SDKUrl = $paymentProvider->buildPaymentSDKLink(); } return $this->render('payment/checkout_payment.html.twig', [ 'cart' => $cart, 'SDKUrl' => $SDKUrl ]); } #[Route('/checkout-start-payment', name: 'shop-checkout-start-payment')] public function startPaymentAction(Factory $factory): JsonResponse { $cart = $factory->getCartManager()->getOrCreateCartByName('cart'); $checkoutManager = Factory::getInstance()->getCheckoutManager($cart); // Initialize order payment $paymentInformation = $checkoutManager->initOrderPayment(); $order = $paymentInformation->getObject(); $config = [ 'return_url' => '', 'cancel_url' => 'https://demo.pimcore.fun/payment-error', 'OrderDescription' => 'My Order ' . $order->getOrdernumber() . ' at pimcore.org', 'InternalPaymentId' => $paymentInformation->getInternalPaymentId() ]; $response = $checkoutManager->startOrderPaymentWithPaymentProvider(new AbstractRequest($config)); return new JsonResponse($response->getJsonString(), 200, [], true); } #[Route('/payment-commit-order', name: 'shop-commit-order')] public function commitOrderAction(Request $request, Factory $factory): RedirectResponse { $cart = $factory->getCartManager()->getOrCreateCartByName('cart'); $checkoutManager = $factory->getCheckoutManager($cart); // Handle payment response and commit order $order = $checkoutManager->handlePaymentResponseAndCommitOrderPayment( array_merge($request->query->all(), $request->request->all()) ); // Store order ID in session for confirmation page $request->getSession()->set('last_order_id', $order->getId()); return $this->redirectToRoute('shop-checkout-completed'); } } ``` -------------------------------- ### News Controller: Listing and Detail Pages (PHP) Source: https://context7.com/pimcore/demo/llms.txt Manages the display of news articles, providing both a listing page and individual detail pages with SEO-friendly URLs. It utilizes KnpComponentPager for pagination and Pimcore's DataObject for news retrieval. Dependencies include Request, PaginatorInterface, and HeadTitle. Outputs rendered Twig templates for news listing and detail views. ```php setOrderKey('date'); $newsList->setOrder('DESC'); $paginator = $paginator->paginate($newsList, $request->query->getInt('page', 1), 6); return $this->render('news/listing.html.twig', [ 'news' => $paginator, 'paginationVariables' => $paginator->getPaginationData() ]); } #[Route('{path}/{newstitle}~n{news}', name: 'news-detail')] public function detailAction(Request $request, HeadTitle $headTitleHelper): Response { $news = News::getById($request->attributes->getInt('news')); if (!$news instanceof News || !$news->isPublished()) { throw new NotFoundHttpException('News not found.'); } $headTitleHelper($news->getTitle()); return $this->render('news/detail.html.twig', ['news' => $news]); } } ``` -------------------------------- ### Product Listing by Category with Filters (PHP) Source: https://context7.com/pimcore/demo/llms.txt Displays paginated product listings filtered by category. It integrates with a dynamic filter service and uses Knp Paginator for pagination. Dependencies include Pimcore's Ecommerce Framework Bundle and Knp Paginator. ```php attributes->get('category'); $category = Category::getById($categoryId); // Get product listing for current tenant $productListing = $ecommerceFactory->getIndexService()->getProductListForCurrentTenant(); $productListing->setVariantMode(ProductListInterface::VARIANT_MODE_VARIANTS_ONLY); // Load filter definition from category or fallback $filterDefinition = $category?->getFilterdefinition() ?? Config::getWebsiteConfig()['fallbackFilterdefinition']; // Setup filters $filterService = $ecommerceFactory->getFilterService(); $listHelper->setupProductList($filterDefinition, $productListing, $params, $filterService, true); // Paginate results $paginator = $paginator->paginate( $productListing, $request->query->getInt('page', 1), $filterDefinition->getPageLimit() ); return $this->render('product/listing.html.twig', [ 'results' => $paginator, 'filterService' => $filterService, 'category' => $category ]); } ``` -------------------------------- ### E-Commerce Index Configuration in YAML Source: https://context7.com/pimcore/demo/llms.txt Configures the product index for MySQL-based filtering and search. It defines tenants, search attributes, and specific attribute configurations including field names, types, and interpreters. ```yaml # config/ecommerce/base-ecommerce.yaml pimcore_ecommerce_framework: index_service: tenants: default: config_id: App\Ecommerce\IndexService\Config\MySqlConfig worker_id: Pimcore\Bundle\EcommerceFrameworkBundle\IndexService\Worker\DefaultMysql search_attributes: - name - manufacturer_name - color - carClass attributes: name: fieldname: OSName type: varchar(255) filter_group: string manufacturer_name: fieldname: 'manufacturer' type: varchar(255) interpreter_id: Pimcore\Bundle\EcommerceFrameworkBundle\IndexService\Interpreter\ObjectValue interpreter_options: target: fieldname: name locale: 'en' manufacturer: interpreter_id: Pimcore\Bundle\EcommerceFrameworkBundle\IndexService\Interpreter\DefaultObjects filter_group: relation bodyStyle: interpreter_id: Pimcore\Bundle\EcommerceFrameworkBundle\IndexService\Interpreter\DefaultObjects filter_group: relation color: type: varchar(255) filter_group: multiselect milage: type: double getter_id: Pimcore\Bundle\EcommerceFrameworkBundle\IndexService\Getter\DefaultBrickGetterSequence getter_options: source: - brickfield: saleInformation bricktype: SaleInformation fieldname: milage ``` -------------------------------- ### Car Product Model in PHP Source: https://context7.com/pimcore/demo/llms.txt Extends the Pimcore product model to include image gallery, category, and accessory relationships. It provides methods for retrieving display names, specifications, main images, compatible accessories, and color variants. ```php getManufacturer() ? ($this->getManufacturer()->getName() . ' ') : null) . $this->getName(); } // Get subtitle with specifications public function getSubText(): string { $textParts = []; $textParts[] = $this->getBodyStyle()?->getName() ?? ''; $textParts[] = $this->getProductionYear(); $textParts[] = $this->getAttributes()->getEngine()?->getPower() ?? ''; return implode(', ', array_filter($textParts)); } // Get main gallery image public function getMainImage(): ?Hotspotimage { $gallery = $this->getGallery(); $items = $gallery?->getItems(); return $items ? $items[0] : null; } // Get compatible accessories public function getAccessories(): Listing { $filterIds = ['compatibleTo LIKE "%,' . $this->getId() . ',%"']; // Include parent car IDs for inheritance $parent = $this->getParent(); while ($parent instanceof self) { $filterIds[] = 'compatibleTo LIKE "%,' . $parent->getId() . ',%"'; $parent = $parent->getParent(); } $listing = new \Pimcore\Model\DataObject\AccessoryPart\Listing(); $listing->setCondition(implode(' OR ', $filterIds)); return $listing; } // Get color variants (siblings) public function getColorVariants(): array { if ($this->getObjectType() != self::OBJECT_TYPE_ACTUAL_CAR) { return []; } $carSiblings = []; foreach ($this->getParent()->getChildren() as $sibling) { if ($sibling instanceof self && $sibling->getObjectType() == self::OBJECT_TYPE_ACTUAL_CAR) { $carSiblings[] = $sibling; } } return $carSiblings; } } ``` -------------------------------- ### Pimcore Product Detail Controller Source: https://context7.com/pimcore/demo/llms.txt A Symfony controller for rendering product detail pages in the Pimcore Demo Application. It handles different product types (Car, AccessoryPart), tracks product views and impressions using the E-Commerce Framework's tracking manager, and fetches related products. ```php isPublished()) { throw new NotFoundHttpException('Product not found.'); } // Track product view for analytics $trackingManager = $ecommerceFactory->getTrackingManager(); $trackingManager->trackProductView($product); // Render car detail with accessories cross-sells if ($product instanceof Car) { foreach ($product->getAccessories() as $accessory) { $trackingManager->trackProductImpression($accessory, 'crosssells'); } return $this->render('product/detail.html.twig', ['product' => $product]); } // Render accessory with compatible products if ($product instanceof AccessoryPart) { $productList = $ecommerceFactory->getIndexService()->getProductListForCurrentTenant(); $productList->addCondition('id IN (' . implode(',', $product->getCompatibleToProductIds()) . ')', 'id'); return $this->render('product/detail_accessory.html.twig', [ 'product' => $product, 'compatibleTo' => $productList ]); } throw new NotFoundHttpException('Unsupported Product type.'); } } ``` -------------------------------- ### User Authentication: Registration, Login, and Password Recovery (PHP) Source: https://context7.com/pimcore/demo/llms.txt Handles user registration, login, and password recovery. It uses CustomerManagementFrameworkBundle for customer management and security. Dependencies include AuthenticationUtils, Request, CustomerProviderInterface, LoginManagerInterface, and RegistrationFormHandler. Outputs include responses for login, registration, and account index pages. Redirects users if already logged in during login attempts. ```php getUser() && $this->isGranted('ROLE_USER')) { return $this->redirectToRoute('account-index'); } $error = $authenticationUtils->getLastAuthenticationError(); $lastUsername = $authenticationUtils->getLastUsername(); $form = $this->createForm(LoginFormType::class, ['_username' => $lastUsername], [ 'action' => $this->generateUrl('account-login') ]); return $this->render('account/login.html.twig', [ 'form' => $form->createView(), 'error' => $error ? 'Credentials are not valid.' : '' ]); } #[Route('/account/register', name: 'account-register')] public function registerAction( Request $request, CustomerProviderInterface $customerProvider, LoginManagerInterface $loginManager, RegistrationFormHandler $registrationFormHandler ): Response { // Create new customer instance $customer = $customerProvider->create(); $form = $this->createForm(RegistrationFormType::class, $registrationFormHandler->buildFormData($customer), ['hidePassword' => false] ); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $registrationFormHandler->updateCustomerFromForm($customer, $form); $customer->setCustomerLanguage($request->getLocale()); $customer->setActive(true); try { $customer->save(); // Auto-login after registration $response = $this->redirectToRoute('account-index'); $loginManager->login($customer, $request, $response); return $response; } catch (DuplicateCustomerException $e) { $errors[] = 'Customer already exists'; } } return $this->render('account/register.html.twig', [ 'form' => $form->createView(), 'errors' => $errors ?? [] ]); } #[Route('/account/index', name: 'account-index')] #[IsGranted('ROLE_USER')] public function indexAction(UserInterface $user): Response { // Get customer order history $orderManager = Factory::getInstance()->getOrderManager(); $orderList = $orderManager->createOrderList(); $orderList->addFilter(new CustomerObject($user)); $orderList->setOrder('orderDate DESC'); return $this->render('account/index.html.twig', ['orderList' => $orderList]); } } ``` -------------------------------- ### News Article API Source: https://context7.com/pimcore/demo/llms.txt Provides endpoints for listing news articles and viewing individual article details. ```APIDOC ## News Article Endpoints ### News Listing **Description**: Retrieves a paginated list of published news articles. **Method**: GET **Endpoint**: `/en/news` #### Query Parameters - **page** (integer) - Optional - The page number for pagination. Defaults to 1. ### News Detail **Description**: Retrieves the details of a specific news article. **Method**: GET **Endpoint**: `/en/news/{article-title}~n{news_id}` #### Path Parameters - **article-title** (string) - Required - The title of the news article (used for SEO-friendly URLs). - **news_id** (integer) - Required - The unique identifier of the news article. ``` -------------------------------- ### Checkout Process in PHP Source: https://context7.com/pimcore/demo/llms.txt Implements a multi-step checkout process, handling delivery address input and preparing for payment integration. It uses Pimcore's E-commerce Framework Bundle for managing checkout steps and cart data. The process involves form handling for address input and committing steps to the checkout manager. It redirects to the payment step upon successful address submission. ```php getCartManager()->getOrCreateCartByName('cart'); $checkoutManager = $factory->getCheckoutManager($cart); // Get delivery address step $deliveryAddress = $checkoutManager->getCheckoutStep('deliveryaddress'); // Pre-fill form with customer data if logged in $deliveryAddressData = $this->fillDeliveryAddressFromCustomer($deliveryAddress->getData()); $form = $this->createForm(DeliveryAddressFormType::class, $deliveryAddressData); $form->handleRequest($request); if ($request->getMethod() == Request::METHOD_POST && count($form->getErrors()) === 0) { $address = new \stdClass(); foreach ($form->getData() as $key => $value) { $address->{$key} = $value; } // Commit delivery address step $checkoutManager->commitStep($deliveryAddress, $address); // Commit confirm step and proceed to payment $confirm = $checkoutManager->getCheckoutStep('confirm'); $checkoutManager->commitStep($confirm, true); return $this->redirectToRoute('shop-checkout-payment'); } return $this->render('checkout/checkout_address.html.twig', [ 'cart' => $cart, 'form' => $form->createView() ]); } } ``` -------------------------------- ### User Authentication API Source: https://context7.com/pimcore/demo/llms.txt Provides endpoints for user registration, login, and password recovery functionalities. ```APIDOC ## User Authentication Endpoints ### Login **Description**: Allows users to log in to their accounts. **Method**: GET, POST **Endpoint**: `/account/login` ### Register **Description**: Enables new users to register for an account. **Method**: GET, POST **Endpoint**: `/account/register` ### Password Recovery **Description**: Initiates the password recovery process for users who have forgotten their password. **Method**: POST **Endpoint**: `/account/send-password-recovery` ### Reset Password **Description**: Allows users to reset their password using a recovery token. **Method**: GET, POST **Endpoint**: `/account/reset-password?token=xxx #### Query Parameters - **token** (string) - Required - The password recovery token. ``` -------------------------------- ### Product Search with Elasticsearch and Weighted Scoring (PHP) Source: https://context7.com/pimcore/demo/llms.txt Implements full-text search across products using Elasticsearch. It supports weighted scoring to prioritize certain product types (e.g., cars over accessories) and can return JSON for autocomplete or HTML for full search results. Dependencies include Pimcore's Ecommerce Framework Bundle and Knp Paginator. ```php query->getString('term')); $productListing = $ecommerceFactory->getIndexService()->getProductListForCurrentTenant(); if ($productListing instanceof AbstractElasticSearch) { // Weighted multi-match query - cars score higher than accessories $query = [ 'function_score' => [ 'query' => [ 'multi_match' => [ 'query' => $term, 'type' => 'cross_fields', 'operator' => 'and', 'fields' => [ 'attributes.name^4', 'attributes.manufacturer_name^3', 'attributes.color', 'attributes.carClass' ] ] ], 'functions' => [ ['filter' => ['match' => ['system.classId' => 'AP']], 'weight' => 1], ['filter' => ['match' => ['system.classId' => 'CAR']], 'weight' => 2] ], 'boost_mode' => 'multiply' ] ]; $productListing->addQueryCondition($query, 'searchTerm'); } // Return JSON for autocomplete if ($request->query->has('autocomplete')) { $productListing->setLimit(10); $resultset = []; foreach ($productListing as $product) { $resultset[] = [ 'href' => $productLinkGenerator->generateWithMockup($product, []), 'product' => $product->getOSName() ]; } return $this->json($resultset); } // Return paginated HTML results $paginator = $paginator->paginate($productListing, $request->query->getInt('page', 1), 12); return $this->render('product/search.html.twig', ['results' => $paginator, 'term' => $term]); } ``` -------------------------------- ### Shopping Cart Management in PHP Source: https://context7.com/pimcore/demo/llms.txt Manages shopping cart operations including adding, updating, and removing items, as well as applying voucher codes. It utilizes Pimcore's E-commerce Framework Bundle for cart and tracking functionalities. Input includes product IDs and quantities, with output being redirects or rendered cart views. It has a limit of 100 items per cart. ```php factory->getCartManager()->getOrCreateCartByName(self::DEFAULT_CART_NAME); } #[Route('/cart/add-to-cart', name: 'shop-add-to-cart', methods: ['POST'])] public function addToCartAction(Request $request, Factory $ecommerceFactory): RedirectResponse { // CSRF validation if (!$this->isCsrfTokenValid('addToCart', $request->request->getString('_csrf_token'))) { throw new \Exception('Invalid request'); } $product = AbstractProduct::getById($request->query->getInt('id')); $cart = $this->getCart(); // Limit cart to 100 items if ($cart->getItemCount() > 99) { throw new \Exception('Maximum Cart items limit Reached'); } $cart->addItem($product, 1); $cart->save(); // Track for analytics $trackingManager = $ecommerceFactory->getTrackingManager(); $trackingManager->trackCartProductActionAdd($cart, $product); return $this->redirectToRoute('shop-cart-detail'); } #[Route('/cart', name: 'shop-cart-detail')] public function cartListingAction(Request $request): Response { $cart = $this->getCart(); // Handle quantity updates via POST if ($request->getMethod() == Request::METHOD_POST) { $items = $request->request->all('items'); foreach ($items as $itemKey => $quantity) { $product = AbstractProduct::getById($itemKey); $cart->updateItem($itemKey, $product, floor($quantity), true); } $cart->save(); } return $this->render($cart->isEmpty() ? 'cart/cart_empty.html.twig' : 'cart/cart_listing.html.twig', [ 'cart' => $cart ]); } #[Route('/cart/apply-voucher', name: 'shop-cart-apply-voucher')] public function applyVoucherAction(Request $request, Translator $translator): RedirectResponse { $token = strip_tags($request->request->getString('voucher-code')); $cart = $this->getCart(); try { if ($cart->addVoucherToken($token)) { $this->addFlash('success', $translator->trans('cart.voucher-code-added')); } } catch (VoucherServiceException $e) { $this->addFlash('danger', $translator->trans('cart.error-voucher-code-' . $e->getCode())); } return $this->redirectToRoute('shop-cart-detail'); } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.