├── .gitignore ├── .travis.yml ├── README.md ├── composer.json ├── phpunit.xml ├── src ├── Providers │ └── WooCommerceServiceProvider.php ├── Publishes │ ├── app │ │ └── woocommerce.php │ └── resources │ │ └── views │ │ └── woocommerce │ │ ├── archive-product.blade.php │ │ ├── single-product.blade.php │ │ ├── taxonomy-product-cat.blade.php │ │ └── taxonomy-product-tag.blade.php └── WooCommerce.php └── tests ├── BaseTestCase.php ├── MainTests └── MainTest.php └── bootstrap.php /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | composer.lock 3 | vendor 4 | .idea -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - 7.2 4 | - 7.3 5 | - 7.4 6 | env: 7 | matrix: 8 | - COMPOSER_FLAGS="--prefer-lowest" 9 | - COMPOSER_FLAGS="" 10 | branches: 11 | only: 12 | - master 13 | before_script: 14 | - travis_retry composer self-update 15 | - travis_retry composer update ${COMPOSER_FLAGS} --no-interaction --prefer-source 16 | script: 17 | - vendor/bin/phpunit 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MIGRATED TO [THIS LIBRARY](https://github.com/generoi/sage-woocommerce) 2 | 3 | This library was developed when the problems of the mentioned library were not fixed and contributions were not allowed, but now, due to the possibility of contributions, use it. 4 | 5 | # Sage Woocommerce 6 | ![CI](https://travis-ci.org/smarteist/sage-woocommerce.svg?branch=master) 7 | 8 | This package enables WooCommerce integration for Sage 10 themes and Blade templates. 9 | 10 | #### Changelog 11 | - Issue #1 fixed, please change your view renderer to ```sage.woocommerce.view```. 12 | 13 | ## Installation 14 | 15 | ``` 16 | composer require hexbit/sage-woocommerce 17 | ``` 18 | 19 | ## Usage 20 | Add ```Hexbit\Woocommerce\Providers\WooCommerceServiceProvider``` to your providers array in ```yourtheme/config/app.php``` 21 | ```php 22 | ... 23 | /* 24 | |-------------------------------------------------------------------------- 25 | | Autoloaded Service Providers 26 | |-------------------------------------------------------------------------- 27 | | 28 | | The service providers listed here will be automatically loaded on the 29 | | request to your application. Feel free to add your own services to 30 | | this array to grant expanded functionality to your applications. 31 | | 32 | */ 33 | 34 | 'providers' => [ 35 | /** 36 | * Package Service Providers 37 | */ 38 | Hexbit\Woocommerce\Providers\WooCommerceServiceProvider::class 39 | ] 40 | ... 41 | ``` 42 | Or you can discover service provider by using wp cli. 43 | ``` 44 | wp acorn package:discover 45 | ``` 46 | Then create ```app/woocommerce.php``` in your ```app``` folder and override default blade files in ```resources/views/woocommerce```, or you can create automatically by running this command 47 | ``` 48 | wp acorn vendor:publish --tag="woocommerce" 49 | ``` 50 | & finally change view renderer in your index file like this: 51 | 52 | ``` 53 | render(); ?> 54 | ``` 55 | 56 | 57 | Done! now you will be able to override woocommerce templates with blade TE in ```yourtheme/resources/views/woocommerce/``` directory. 58 | 59 | 60 | ## Contributing 61 | Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. 62 | 63 | Please make sure to update tests as appropriate. 64 | 65 | ## License 66 | [MIT](https://choosealicense.com/licenses/mit/) 67 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexbit/sage-woocommerce", 3 | "description": "Woocommerce support for sage 10", 4 | "version": "1.0.5", 5 | "keywords": [ 6 | "hexbit", 7 | "smarteist", 8 | "wordpress", 9 | "sage", 10 | "woocommerce", 11 | "blade" 12 | ], 13 | "homepage": "https://github.com/smarteist/sage-woocommerce", 14 | "license": "MIT", 15 | "authors": [ 16 | { 17 | "name": "Ali Hosseini", 18 | "email": "ali.hosseini.sr@gmail.com", 19 | "homepage": "https://hexbit.dev/", 20 | "role": "Developer" 21 | } 22 | ], 23 | "require": { 24 | "php": "^7.2|^8.0", 25 | "roots/acorn": "*" 26 | }, 27 | "require-dev": { 28 | "phpunit/phpunit": "^6.0" 29 | }, 30 | "autoload": { 31 | "psr-4": { 32 | "Hexbit\\Woocommerce\\": "src" 33 | } 34 | }, 35 | "autoload-dev": { 36 | "psr-4": { 37 | "Hexbit\\Woocommerce\\Tests\\": "tests" 38 | } 39 | }, 40 | "scripts": { 41 | "test": "vendor/bin/phpunit" 42 | }, 43 | "minimum-stability": "dev", 44 | "prefer-stable": true, 45 | "config": { 46 | "sort-packages": true 47 | }, 48 | "extra": { 49 | "acorn": { 50 | "providers": [ 51 | "Hexbit\\Woocommerce\\Providers\\WooCommerceServiceProvider" 52 | ] 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | tests/MainTests 15 | tests/MainTests 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/Providers/WooCommerceServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->singleton('sage.woocommerce', WooCommerce::class); 24 | $this->app->singleton('sage.woocommerce.view', function (Application $app) { 25 | return strval($app['sage.woocommerce']); 26 | }); 27 | } 28 | 29 | /** 30 | * Bootstrap any application services. 31 | * 32 | * @return void 33 | */ 34 | public function boot() 35 | { 36 | if (defined('WC_ABSPATH')) { 37 | $this->app['sage.woocommerce']->loadThemeTemplateHooks(); 38 | $this->bindSetupAction(); 39 | $this->bindFilters(); 40 | } 41 | 42 | // publishing command 43 | $this->publishes([ 44 | dirname(__DIR__) . '/Publishes/app/woocommerce.php' => $this->app->path('woocommerce.php'), 45 | dirname(__DIR__) . '/Publishes/resources/views/woocommerce' => $this->app->resourcePath('views/woocommerce'), 46 | ], 'woocommerce'); 47 | 48 | } 49 | 50 | /** 51 | * Appends all filters in wordpress actions 52 | * @hooks template_include 53 | * @hooks comments_template 54 | * @hooks woocommerce_locate_template 55 | * @hooks wc_get_template_part 56 | * @hooks wc_get_template 57 | */ 58 | public function bindFilters() 59 | { 60 | $woocommerce = $this->app['sage.woocommerce']; 61 | 62 | add_filter('template_include', [$woocommerce, 'templateInclude'], 100, 1); 63 | add_filter('comments_template', [$woocommerce, 'templateInclude'], 100, 1); 64 | add_filter('woocommerce_locate_template', [$woocommerce, 'locateTemplate'], PHP_INT_MAX, 2); 65 | add_filter('wc_get_template_part', [$woocommerce, 'templatePart'], PHP_INT_MAX, 1); 66 | add_filter('wc_get_template', [$woocommerce, 'getTemplate'], 100, 3); 67 | 68 | } 69 | 70 | /** 71 | * WooCommerce support for theme 72 | */ 73 | public function bindSetupAction() 74 | { 75 | add_action('after_setup_theme', [$this->app['sage.woocommerce'], 'addThemeSupport']); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/Publishes/app/woocommerce.php: -------------------------------------------------------------------------------- 1 | 24 | 25 | @if ( apply_filters( 'woocommerce_show_page_title', true ) ) 26 | 27 |

@php woocommerce_page_title(); @endphp

28 | 29 | @endif 30 | 31 | 32 | @php 33 | /** 34 | * Hook: woocommerce_archive_description. 35 | * 36 | * @hooked woocommerce_taxonomy_archive_description - 10 37 | * @hooked woocommerce_product_archive_description - 10 38 | */ 39 | do_action( 'woocommerce_archive_description' ); 40 | @endphp 41 | 42 | 43 | @if ( woocommerce_product_loop() ) 44 | 45 | @php 46 | /** 47 | * Hook: woocommerce_before_shop_loop. 48 | * 49 | * @hooked woocommerce_output_all_notices - 10 50 | * @hooked woocommerce_result_count - 20 51 | * @hooked woocommerce_catalog_ordering - 30 52 | */ 53 | do_action( 'woocommerce_before_shop_loop' ); 54 | 55 | woocommerce_product_loop_start(); 56 | @endphp 57 | 58 | @if ( wc_get_loop_prop( 'total' ) ) 59 | @while ( have_posts() ) 60 | @php 61 | the_post(); 62 | 63 | /** 64 | * Hook: woocommerce_shop_loop. 65 | */ 66 | do_action( 'woocommerce_shop_loop' ); 67 | 68 | wc_get_template_part( 'content', 'product' ); 69 | @endphp 70 | @endwhile 71 | @endif 72 | @php 73 | woocommerce_product_loop_end(); 74 | 75 | /** 76 | * Hook: woocommerce_after_shop_loop. 77 | * 78 | * @hooked woocommerce_pagination - 10 79 | */ 80 | do_action( 'woocommerce_after_shop_loop' ); 81 | @endphp 82 | @else 83 | 84 | @php 85 | /** 86 | * Hook: woocommerce_no_products_found. 87 | * 88 | * @hooked wc_no_products_found - 10 89 | */ 90 | do_action( 'woocommerce_no_products_found' ); 91 | @endphp 92 | 93 | @endif 94 | 95 | @php 96 | 97 | /** 98 | * Hook: woocommerce_after_main_content. 99 | * 100 | * @hooked woocommerce_output_content_wrapper_end - 10 (outputs closing divs for the content) 101 | */ 102 | do_action( 'woocommerce_after_main_content' ); 103 | 104 | /** 105 | * Hook: woocommerce_sidebar. 106 | * 107 | * @hooked woocommerce_get_sidebar - 10 108 | */ 109 | do_action( 'woocommerce_sidebar' ); 110 | @endphp 111 | @endsection -------------------------------------------------------------------------------- /src/Publishes/resources/views/woocommerce/single-product.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | /** 3 | * The Template for displaying all single products 4 | * 5 | * This template can be overridden by copying it to yourtheme/woocommerce/single-product.php. 6 | * 7 | * HOWEVER, on occasion WooCommerce will need to update template files and you 8 | * (the theme developer) will need to copy the new files to your theme to 9 | * maintain compatibility. We try to do this as little as possible, but it does 10 | * happen. When this occurs the version of the template file will be bumped and 11 | * the readme will list any important changes. 12 | * 13 | * @see https://docs.woocommerce.com/document/template-structure/ 14 | * @package WooCommerce\Templates 15 | * @version 1.6.4 16 | */ 17 | @endphp 18 | 19 | @extends('layouts.app') 20 | 21 | @section('content') 22 | 23 | @php 24 | /** 25 | * woocommerce_before_main_content hook. 26 | * 27 | * @hooked woocommerce_output_content_wrapper - 10 (outputs opening divs for the content) 28 | * @hooked woocommerce_breadcrumb - 20 29 | */ 30 | do_action( 'woocommerce_before_main_content' ); 31 | @endphp 32 | 33 | 34 | @while ( have_posts() ) 35 | 36 | @php the_post(); @endphp 37 | 38 | @php wc_get_template_part( 'content', 'single-product' ); @endphp 39 | 40 | @endwhile 41 | {{--end of the loop--}} 42 | 43 | @php 44 | /** 45 | * woocommerce_after_main_content hook. 46 | * 47 | * @hooked woocommerce_output_content_wrapper_end - 10 (outputs closing divs for the content) 48 | */ 49 | do_action( 'woocommerce_after_main_content' ); 50 | @endphp 51 | 52 | @php 53 | /** 54 | * woocommerce_sidebar hook. 55 | * 56 | * @hooked woocommerce_get_sidebar - 10 57 | */ 58 | do_action( 'woocommerce_sidebar' ); 59 | @endphp 60 | 61 | @endsection -------------------------------------------------------------------------------- /src/Publishes/resources/views/woocommerce/taxonomy-product-cat.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | /** 3 | * The Template for displaying products in a product category. Simply includes the archive template 4 | * 5 | * This template can be overridden by copying it to yourtheme/woocommerce/taxonomy-product-cat.php. 6 | * 7 | * HOWEVER, on occasion WooCommerce will need to update template files and you 8 | * (the theme developer) will need to copy the new files to your theme to 9 | * maintain compatibility. We try to do this as little as possible, but it does 10 | * happen. When this occurs the version of the template file will be bumped and 11 | * the readme will list any important changes. 12 | * 13 | * @see https://docs.woocommerce.com/document/template-structure/ 14 | * @package WooCommerce\Templates 15 | * @version 4.7.0 16 | */ 17 | @endphp 18 | 19 | @include('woocommerce.archive-product') -------------------------------------------------------------------------------- /src/Publishes/resources/views/woocommerce/taxonomy-product-tag.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | /** 3 | * The Template for displaying products in a product tag. Simply includes the archive template 4 | * 5 | * This template can be overridden by copying it to yourtheme/woocommerce/taxonomy-product-tag.php. 6 | * 7 | * HOWEVER, on occasion WooCommerce will need to update template files and you 8 | * (the theme developer) will need to copy the new files to your theme to 9 | * maintain compatibility. We try to do this as little as possible, but it does 10 | * happen. When this occurs the version of the template file will be bumped and 11 | * the readme will list any important changes. 12 | * 13 | * @see https://docs.woocommerce.com/document/template-structure/ 14 | * @package WooCommerce\Templates 15 | * @version 4.7.0 16 | */ 17 | @endphp 18 | 19 | @include('woocommerce.archive-product') -------------------------------------------------------------------------------- /src/WooCommerce.php: -------------------------------------------------------------------------------- 1 | app = $app; 45 | $this->fileFinder = $fileFinder; 46 | $this->sageFinder = $sageFinder; 47 | } 48 | 49 | /** 50 | * This method allows this class to send the current view name to the blade, 51 | * based on the @return string 52 | * @see $woocommerceTemplate 53 | * @see \Roots\view 54 | */ 55 | public function __toString() 56 | { 57 | if ($this->woocommerceTemplate && realpath($this->woocommerceTemplate)) { 58 | return $this->fileFinder->getPossibleViewNameFromPath($this->woocommerceTemplate); 59 | } 60 | return $this->app['sage.view']; 61 | } 62 | 63 | /** 64 | * Load template hook overrides file if available in app/ folder of theme. 65 | */ 66 | public function loadThemeTemplateHooks() 67 | { 68 | locate_template('app/woocommerce.php', true, true); 69 | } 70 | 71 | /** 72 | * Declare theme support. 73 | */ 74 | public function addThemeSupport() 75 | { 76 | add_theme_support('woocommerce'); 77 | } 78 | 79 | /** 80 | * @hooked template_include 81 | * Support blade templates for the main template include. 82 | * @param string $template 83 | * @return string main page template directory 84 | */ 85 | public function templateInclude(string $template) 86 | { 87 | if ($this->isWooCommerceTemplatePart($template)) { 88 | return $this->templatePart($template); 89 | } 90 | $woocommerceFound = WC_Template_Loader::template_loader($template); 91 | // determine if its a woocommerce page template 92 | if ($woocommerceFound != $template) { 93 | // save this path as a field 94 | $this->woocommerceTemplate = $this->locateThemeTemplate($woocommerceFound); 95 | } 96 | return $template; 97 | } 98 | 99 | 100 | /** 101 | * @hooked wc_get_template 102 | * Add blade templates for the woocommerce status page if user is admin and 103 | * loaded wc status page. 104 | * @param string $template template directory 105 | * @param string $templateName template file name 106 | * @param array $args Arguments. (default: array). 107 | * @return string wc template part 108 | */ 109 | public function getTemplate(string $template, string $templateName, array $args) 110 | { 111 | // return theme filename for status screen 112 | if (is_admin() && 113 | !wp_doing_ajax() && 114 | get_current_screen() && 115 | get_current_screen()->id === 'woocommerce_page_wc-status') { 116 | $themeTemplate = $this->locateThemeTemplate($templateName); 117 | return $themeTemplate ?: $template; 118 | } 119 | 120 | // return default template, output already rendered by "templatePart" method. 121 | return $template; 122 | } 123 | 124 | /** 125 | * @hooked wc_get_template_part 126 | * Filter all template parts that available in overrides and return our blade 127 | * template loaders as needed. 128 | * @param string $template part to find 129 | * @return string loader output 130 | */ 131 | public function templatePart(string $template) 132 | { 133 | return $this->locateTemplate($template, $template); 134 | } 135 | 136 | /** 137 | * @hooked woocommerce_locate_template 138 | * Filter all template parts that available in overrides and return our blade 139 | * template loaders as needed. 140 | * @param string $template part to find 141 | * @return string loader output 142 | */ 143 | public function locateTemplate(string $template, string $template_name) 144 | { 145 | // Locate any matching template within the theme. 146 | $themeTemplate = $this->locateThemeTemplate($template_name); 147 | 148 | // Include directly unless it's a blade file. 149 | if ( 150 | $themeTemplate && 151 | Str::endsWith($themeTemplate, '.blade.php') && 152 | realpath($themeTemplate) 153 | ) { 154 | // We have a template, create a loader file and return it's path. 155 | return view( 156 | $this->fileFinder->getPossibleViewNameFromPath($themeTemplate), 157 | $this->app['sage.data'] ?? [] 158 | )->makeLoader(); 159 | } 160 | 161 | return $template; 162 | } 163 | 164 | /** 165 | * Check if template is a WooCommerce template part. 166 | * @param string $template file directory 167 | * @return bool is file in woocommerce template directory or not. 168 | */ 169 | protected function isWooCommerceTemplatePart(string $template) 170 | { 171 | return strpos($template, \WC_ABSPATH) !== false; 172 | } 173 | 174 | /** 175 | * Locate the theme's WooCommerce blade template when available. 176 | * @param string $template to search 177 | * @return string founded directory path 178 | */ 179 | protected function locateThemeTemplate(string $template) 180 | { 181 | $themeTemplate = WC()->template_path() . str_replace(\WC_ABSPATH . 'templates/', '', $template); 182 | return locate_template($this->sageFinder->locate($themeTemplate)); 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /tests/BaseTestCase.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 21 | } 22 | 23 | protected function tearDown(): void 24 | { 25 | parent::tearDown(); 26 | } 27 | } -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 |