├── .modman
├── .basedir
└── Hackathon_React
│ ├── src
│ └── app
│ │ ├── etc
│ │ └── modules
│ │ │ └── Hackathon_React.xml
│ │ ├── code
│ │ ├── community
│ │ │ └── Hackathon
│ │ │ │ └── React
│ │ │ │ ├── Block
│ │ │ │ └── Catalog
│ │ │ │ │ └── Product
│ │ │ │ │ └── List.php
│ │ │ │ └── etc
│ │ │ │ └── config.xml
│ │ └── local
│ │ │ └── Mage
│ │ │ └── Core
│ │ │ └── Block
│ │ │ └── Template.php
│ │ └── design
│ │ └── frontend
│ │ └── base
│ │ └── default
│ │ └── layout
│ │ └── react.xml
│ └── modman
├── .gitignore
├── frontend
├── Paypal.js
├── index.js
├── Header.js
├── Product.js
└── ProductList.js
├── .editorconfig
├── README.md
├── docker-compose.yml
├── config
└── docker
│ ├── Dockerfile
│ └── bin
│ └── set-base-url
├── package.json
├── webpack.config.js
├── composer.json
├── Makefile
└── composer.lock
/.modman/.basedir:
--------------------------------------------------------------------------------
1 | htdocs/
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor
2 | htdocs
3 | .idea
4 | Magento-react.iml
5 | node_modules
6 | npm-debug.log
--------------------------------------------------------------------------------
/frontend/Paypal.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | class Paypal extends React.Component {
4 | render() {
5 | return (
6 |
Salut {this.props.name}
7 | )
8 | }
9 | }
10 |
11 | export default Paypal;
--------------------------------------------------------------------------------
/frontend/index.js:
--------------------------------------------------------------------------------
1 | require("expose?React!react");
2 | import Paypal from './Paypal';
3 | import Header from './Header';
4 | import ProductList from './ProductList';
5 |
6 | module.exports = {
7 | Paypal: Paypal,
8 | Header: Header,
9 | ProductList: ProductList
10 | };
11 |
--------------------------------------------------------------------------------
/frontend/Header.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import React, { Component } from 'react';
4 |
5 | export default class Header extends Component {
6 | render() {
7 | return (
8 |
9 | {this.props.welcome}
10 |

11 |
12 | );
13 | }
14 | }
--------------------------------------------------------------------------------
/.modman/Hackathon_React/src/app/etc/modules/Hackathon_React.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | true
6 | community
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.modman/Hackathon_React/modman:
--------------------------------------------------------------------------------
1 | src/app/code/community/Hackathon/React app/code/community/Hackathon/React
2 | src/app/code/local/Mage/Core/Block/Template.php app/code/local/Mage/Core/Block/Template.php
3 | src/app/design/frontend/base/default/layout/react.xml app/design/frontend/base/default/layout/react.xml
4 | src/app/etc/modules/* app/etc/modules/
5 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | ; This file is for unifying the coding style for different editors and IDEs.
2 | ; More information at http://editorconfig.org
3 |
4 | root = true
5 |
6 | [*]
7 | indent_style = space
8 | indent_size = 4
9 | end_of_line = lf
10 | insert_final_newline = true
11 | trim_trailing_whitespace = true
12 |
13 | [*.js]
14 | indent_style = space
15 | indent_size = 2
16 |
17 | [Makefile]
18 | indent_style=tab
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #Magento-React
2 |
3 | Use React components as rendering library for Magento
4 |
5 | ## Installation
6 | * Get [Composer](https://getcomposer.org/)
7 | * Get [Docker](https://docs.docker.com/)
8 | * Get [docker-compose](https://docs.docker.com/compose/)
9 | * Get [npm](https://www.npmjs.com/)
10 | * then
11 | ```
12 | make install
13 | ```
14 |
15 | ## Helpers
16 | * Launch docker containers
17 | ```
18 | make docker_run
19 | ```
20 | * Install composer dependencies
21 | ```
22 | make composer_install
23 | ```
24 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | web:
2 | build: ./config/docker
3 | ports:
4 | - "80"
5 | - "443"
6 | links:
7 | - db
8 | - mail
9 | volumes:
10 | - ".:/var/www"
11 |
12 | db:
13 | image: mysql
14 | ports:
15 | - 3306
16 | environment:
17 | MYSQL_ROOT_PASSWORD: "root"
18 | MYSQL_DATABASE: "magento"
19 |
20 | phpmyadmin:
21 | image: maxexcloo/phpmyadmin
22 | ports:
23 | - 80
24 | links:
25 | - db:mariadb
26 |
27 | mail:
28 | image: chadrien/mailcatcher:0.5.12
29 | ports:
30 | - 1080
--------------------------------------------------------------------------------
/frontend/Product.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | export default class Product extends Component {
4 | render() {
5 | console.error(this.props.product.price_html);
6 | return (
7 |
8 |
9 | {this.props.product.name}
10 |
11 |
12 |
13 |
14 | );
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/frontend/ProductList.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import Product from './Product'
3 |
4 | export default class ProductList extends Component {
5 | render() {
6 | const list = this.props.products.map((product) => {
7 | return (
8 |
9 | );
10 | });
11 | return (
12 |
17 | );
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/config/docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM occitech/magento:php5.4-apache
2 |
3 | MAINTAINER occitech
4 |
5 | COPY ./bin/set-base-url /usr/local/bin/set-base-url
6 |
7 | RUN curl -sS http://getcomposer.org/installer | php -- --install-dir=/usr/local/bin/ --filename=composer
8 |
9 | RUN apt-get update && \
10 | apt-get install -y libv8-dev g++&& \
11 | rm -rf /var/lib/apt/lists/*
12 |
13 | RUN pecl install v8js-0.1.3 \
14 | && echo "extension=v8js.so" > /usr/local/etc/php/conf.d/ext-v8js.ini
15 | RUN pecl install zip \
16 | && echo "extension=zip.so" > /usr/local/etc/php/conf.d/ext-zip.ini
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "magento-react",
3 | "version": "0.0.1",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "webpack",
8 | "watch": "webpack --progress --colors --inline --watch"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "babel-core": "^5.5.8",
14 | "babel-loader": "^5.1.4",
15 | "expose-loader": "^0.7.0",
16 | "react": "^0.13.3"
17 | },
18 | "devDependencies": {
19 | "node-libs-browser": "^0.5.2",
20 | "webpack": "^1.9.11",
21 | "webpack-dev-server": "^1.9.0"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/.modman/Hackathon_React/src/app/code/community/Hackathon/React/Block/Catalog/Product/List.php:
--------------------------------------------------------------------------------
1 | _getProductCollection() as $product) {
8 | $product->setImage($this->helper('catalog/image')->init($product, 'small_image')->keepFrame(false)->resize(200)->__toString());
9 | $product->setPriceHtml($this->getPriceHtml($product));
10 | $products[] = $product->getData();
11 | }
12 | return $products;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var webpack = require('webpack');
3 | var node_modules = path.resolve(__dirname, 'node_modules');
4 |
5 | module.exports = {
6 | entry: {
7 | app: ['./frontend/index.js'],
8 | vendor: ['react']
9 | },
10 | output: {
11 | path: "./htdocs/js",
12 | library: 'FooApp',
13 | filename: "bundle.js"
14 | },
15 | plugins: [
16 | new webpack.optimize.CommonsChunkPlugin("vendor", "vendor.bundle.js")
17 | ],
18 | module: {
19 | loaders: [
20 | { test: /\.jsx?$/, exclude: node_modules, loader: "babel-loader" }
21 | ]
22 | },
23 | devServer: {
24 | contentBase: "./htdocs"
25 | }
26 | };
--------------------------------------------------------------------------------
/config/docker/bin/set-base-url:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | if test -z "$1"; then
4 | echo "You must provide a port"
5 | exit 1
6 | fi
7 |
8 | BASE_URL="http://127.0.0.1:$1/"
9 | if test -z "$2"; then
10 | SECURE_BASE_URL=$BASE_URL
11 | else
12 | SECURE_BASE_URL="http://127.0.0.1:$2/"
13 | fi
14 |
15 | while getopts "c" option; do
16 | case $option in
17 | c)
18 | shift
19 | BASE_URL="$1"
20 | ;;
21 | esac
22 | done
23 |
24 | n98-magerun --root-dir=/var/www/html config:set web/unsecure/base_url $BASE_URL >/dev/null 2>&1
25 | n98-magerun --root-dir=/var/www/html config:set web/secure/base_url $BASE_URL >/dev/null 2>&1
26 |
27 | echo "Base URL set to ${BASE_URL}"
28 | echo "Secure base URL set to ${SECURE_BASE_URL}"
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "root/magento3",
3 | "minimum-stability": "dev",
4 | "authors": [
5 | {
6 | "name": "Adrien Louis-Rossignol",
7 | "email": "adrien.louis.r@gmail.com"
8 | }
9 | ],
10 | "repositories": [
11 | {
12 | "type": "composer",
13 | "url": "http://packages.firegento.com"
14 | }
15 | ],
16 | "require": {
17 | "bragento/magento-composer-installer": "~1",
18 | "magento/core": "1.9.1.*",
19 | "colinmollenhour/modman": "*",
20 | "reactjs/react-php-v8js": "dev-master"
21 | },
22 | "scripts": {
23 | "modman": "vendor/bin/modman deploy-all --force"
24 | },
25 | "extra": {
26 | "magento-root-dir": "htdocs",
27 | "magento-force": 1,
28 | "magento-deploystrategy": "copy"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/.modman/Hackathon_React/src/app/code/community/Hackathon/React/etc/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 1.0.0
6 |
7 |
8 |
9 |
10 |
11 | Hackathon_React_Model
12 |
13 |
14 |
15 |
16 |
17 | Hackathon_React_Block_Catalog_Product_List
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | react.xml
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/.modman/Hackathon_React/src/app/design/frontend/base/default/layout/react.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | vendor.bundle.js
6 | bundle.js
7 |
8 |
9 |
10 | FooApp.Navbar
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | FooApp.ProductList
19 |
20 |
21 | products
22 | productsForReactComponent
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | SHELL = /bin/bash
2 |
3 | MAGERUN = docker-compose run --rm web n98-magerun
4 | COMPOSER = docker-compose run --rm web composer -d="../"
5 |
6 | dev_setup: mage_symlinks modman_deploy
7 |
8 | install:
9 | @if [ ! -d "htdocs/app/etc/" ]; then mkdir -p htdocs/app/etc/; fi
10 | @docker-compose up -d
11 | @sleep 5
12 | @make composer_install
13 | @npm install
14 | @make mage_local_xml
15 | @make mage_base_url
16 | @make open_web
17 |
18 | composer_install:
19 | @${COMPOSER} install --prefer-dist -n
20 | @make modman_deploy
21 |
22 | modman_deploy:
23 | @${COMPOSER} modman
24 |
25 | open_web:
26 | @make open container=web port=80
27 |
28 | open:
29 | @URL="http://127.0.0.1"$$(docker-compose port $(container) $(port) 2>/dev/null | sed s/0.0.0.0//); \
30 | $$(if [ $$(uname) != 'Darwin' ]; then echo 'xdg-'; fi)open $$URL
31 |
32 | mage_symlinks:
33 | @docker-compose run --rm web n98-magerun dev:symlinks --on --global
34 |
35 | mage_local_xml:
36 | @if test -f htdocs/app/etc/local.xml; then rm htdocs/app/etc/local.xml; fi
37 | @docker-compose run --rm web /bin/bash -c 'n98-magerun local-config:generate $${DB_1_PORT_3306_TCP_ADDR} root $${DB_1_ENV_MYSQL_ROOT_PASSWORD} magento files admin';
38 |
39 | mage_base_url:
40 | @docker-compose run --rm web set-base-url $$(docker-compose port web 80 2>/dev/null | sed s/0.0.0.0://) $$(docker-compose port web 443 2>/dev/null | sed s/0.0.0.0://);
41 |
42 | docker_run:
43 | @docker-compose up -d
44 | @sleep 5
45 | @make mage_local_xml
46 | @make mage_base_url
47 | @make open_web
48 | @npm run watch
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 | "This file is @generated automatically"
6 | ],
7 | "hash": "41b9d5c3ebb56ec6103c12de71f657d8",
8 | "packages": [
9 | {
10 | "name": "bragento/magento-composer-installer",
11 | "version": "1.1.1",
12 | "source": {
13 | "type": "git",
14 | "url": "https://github.com/bragento/bragento-composer-installer.git",
15 | "reference": "e185d188425238a2d078bd79f9116a3926a75673"
16 | },
17 | "dist": {
18 | "type": "zip",
19 | "url": "https://api.github.com/repos/bragento/bragento-composer-installer/zipball/e185d188425238a2d078bd79f9116a3926a75673",
20 | "reference": "e185d188425238a2d078bd79f9116a3926a75673",
21 | "shasum": ""
22 | },
23 | "require": {
24 | "composer-plugin-api": "~1",
25 | "symfony/filesystem": "~2"
26 | },
27 | "replace": {
28 | "magento-hackathon/magento-composer-installer": "*"
29 | },
30 | "require-dev": {
31 | "codeclimate/php-test-reporter": "*",
32 | "composer/composer": "*@dev",
33 | "mikey179/vfsstream": "*",
34 | "phpunit/phpunit": "*"
35 | },
36 | "type": "composer-plugin",
37 | "extra": {
38 | "class": "Bragento\\Magento\\Composer\\Installer\\Plugin",
39 | "branch-alias": {
40 | "dev-develop": "1.2.x-dev"
41 | }
42 | },
43 | "autoload": {
44 | "psr-4": {
45 | "Bragento\\Magento\\Composer\\Installer\\": "src"
46 | }
47 | },
48 | "notification-url": "https://packagist.org/downloads/",
49 | "license": [
50 | "OSL-3.0"
51 | ],
52 | "authors": [
53 | {
54 | "name": "David Verholen",
55 | "email": "david.verholen@brandung.de",
56 | "homepage": "http://www.agentur-brandung.de"
57 | }
58 | ],
59 | "description": "Composer installer for Magento modules",
60 | "homepage": "https://github.com/bragento/bragento-composer-installer",
61 | "keywords": [
62 | "bragento",
63 | "brandung",
64 | "composer",
65 | "installer",
66 | "magento"
67 | ],
68 | "time": "2015-02-28 14:42:03"
69 | },
70 | {
71 | "name": "colinmollenhour/modman",
72 | "version": "1.10",
73 | "source": {
74 | "type": "git",
75 | "url": "https://github.com/colinmollenhour/modman.git",
76 | "reference": "df531dd29f10e9b0611763eb6d96a8417eef43d2"
77 | },
78 | "dist": {
79 | "type": "zip",
80 | "url": "https://api.github.com/repos/colinmollenhour/modman/zipball/df531dd29f10e9b0611763eb6d96a8417eef43d2",
81 | "reference": "df531dd29f10e9b0611763eb6d96a8417eef43d2",
82 | "shasum": ""
83 | },
84 | "bin": [
85 | "modman"
86 | ],
87 | "type": "library",
88 | "license": [
89 | "Apache-2.0"
90 | ],
91 | "authors": [
92 | {
93 | "name": "Colin Mollenhour"
94 | }
95 | ],
96 | "description": "Module Manager",
97 | "homepage": "https://github.com/colinmollenhour/modman",
98 | "support": {
99 | "source": "https://github.com/colinmollenhour/modman/tree/1.10",
100 | "issues": "https://github.com/colinmollenhour/modman/issues"
101 | },
102 | "time": "2014-12-29 22:16:51"
103 | },
104 | {
105 | "name": "magento/core",
106 | "version": "1.9.1.1-patch1",
107 | "source": {
108 | "type": "git",
109 | "url": "https://github.com/bragento/magento-core.git",
110 | "reference": "6c31124a7acdf3f0c1e20d5ffe5ce5fcc4f205fb"
111 | },
112 | "dist": {
113 | "type": "zip",
114 | "url": "https://api.github.com/repos/bragento/magento-core/zipball/6c31124a7acdf3f0c1e20d5ffe5ce5fcc4f205fb",
115 | "reference": "6c31124a7acdf3f0c1e20d5ffe5ce5fcc4f205fb",
116 | "shasum": ""
117 | },
118 | "type": "magento-core",
119 | "extra": {
120 | "map": [
121 | [
122 | "app",
123 | "app"
124 | ],
125 | [
126 | "downloader",
127 | "downloader"
128 | ],
129 | [
130 | "errors",
131 | "errors"
132 | ],
133 | [
134 | "includes",
135 | "includes"
136 | ],
137 | [
138 | "js",
139 | "js"
140 | ],
141 | [
142 | "lib",
143 | "lib"
144 | ],
145 | [
146 | "media",
147 | "media"
148 | ],
149 | [
150 | "pkginfo",
151 | "pkginfo"
152 | ],
153 | [
154 | "shell",
155 | "shell"
156 | ],
157 | [
158 | "skin",
159 | "skin"
160 | ],
161 | [
162 | "var",
163 | "var"
164 | ],
165 | [
166 | ".htaccess",
167 | ".htaccess"
168 | ],
169 | [
170 | "api.php",
171 | "api.php"
172 | ],
173 | [
174 | "cron.php",
175 | "cron.php"
176 | ],
177 | [
178 | "cron.sh",
179 | "cron.sh"
180 | ],
181 | [
182 | "favicon.ico",
183 | "favicon.ico"
184 | ],
185 | [
186 | "get.php",
187 | "get.php"
188 | ],
189 | [
190 | "index.php",
191 | "index.php"
192 | ],
193 | [
194 | "install.php",
195 | "install.php"
196 | ],
197 | [
198 | "mage",
199 | "mage"
200 | ]
201 | ]
202 | },
203 | "license": [
204 | "OSL-3.0"
205 | ],
206 | "description": "Magento Core",
207 | "homepage": "http://www.magentocommerce.com",
208 | "support": {
209 | "source": "https://github.com/bragento/magento-core/tree/1.9.1.1-patch1",
210 | "issues": "https://github.com/bragento/magento-core/issues"
211 | },
212 | "time": "2015-05-15 08:14:35"
213 | },
214 | {
215 | "name": "reactjs/react-php-v8js",
216 | "version": "dev-master",
217 | "source": {
218 | "type": "git",
219 | "url": "https://github.com/reactjs/react-php-v8js.git",
220 | "reference": "6bfbf166cdca7c6ef640ceb450d8ecc59ed2aeba"
221 | },
222 | "dist": {
223 | "type": "zip",
224 | "url": "https://api.github.com/repos/reactjs/react-php-v8js/zipball/6bfbf166cdca7c6ef640ceb450d8ecc59ed2aeba",
225 | "reference": "6bfbf166cdca7c6ef640ceb450d8ecc59ed2aeba",
226 | "shasum": ""
227 | },
228 | "require": {
229 | "ext-v8js": ">=0.1.3"
230 | },
231 | "type": "library",
232 | "autoload": {
233 | "classmap": [
234 | "ReactJS.php"
235 | ]
236 | },
237 | "notification-url": "https://packagist.org/downloads/",
238 | "license": [
239 | "BSD-3-Clause"
240 | ],
241 | "description": "PHP library that renders React components on the server",
242 | "time": "2015-05-26 17:55:07"
243 | },
244 | {
245 | "name": "symfony/filesystem",
246 | "version": "v2.7.0",
247 | "source": {
248 | "type": "git",
249 | "url": "https://github.com/symfony/Filesystem.git",
250 | "reference": "ae4551fd6d4d4f51f2e7390fbc902fbd67f3b7ba"
251 | },
252 | "dist": {
253 | "type": "zip",
254 | "url": "https://api.github.com/repos/symfony/Filesystem/zipball/ae4551fd6d4d4f51f2e7390fbc902fbd67f3b7ba",
255 | "reference": "ae4551fd6d4d4f51f2e7390fbc902fbd67f3b7ba",
256 | "shasum": ""
257 | },
258 | "require": {
259 | "php": ">=5.3.9"
260 | },
261 | "require-dev": {
262 | "symfony/phpunit-bridge": "~2.7"
263 | },
264 | "type": "library",
265 | "extra": {
266 | "branch-alias": {
267 | "dev-master": "2.7-dev"
268 | }
269 | },
270 | "autoload": {
271 | "psr-4": {
272 | "Symfony\\Component\\Filesystem\\": ""
273 | }
274 | },
275 | "notification-url": "https://packagist.org/downloads/",
276 | "license": [
277 | "MIT"
278 | ],
279 | "authors": [
280 | {
281 | "name": "Fabien Potencier",
282 | "email": "fabien@symfony.com"
283 | },
284 | {
285 | "name": "Symfony Community",
286 | "homepage": "https://symfony.com/contributors"
287 | }
288 | ],
289 | "description": "Symfony Filesystem Component",
290 | "homepage": "https://symfony.com",
291 | "time": "2015-05-15 13:33:16"
292 | }
293 | ],
294 | "packages-dev": [],
295 | "aliases": [],
296 | "minimum-stability": "dev",
297 | "stability-flags": {
298 | "reactjs/react-php-v8js": 20
299 | },
300 | "prefer-stable": false,
301 | "prefer-lowest": false,
302 | "platform": [],
303 | "platform-dev": []
304 | }
305 |
--------------------------------------------------------------------------------
/.modman/Hackathon_React/src/app/code/local/Mage/Core/Block/Template.php:
--------------------------------------------------------------------------------
1 |
35 | */
36 | class Mage_Core_Block_Template extends Mage_Core_Block_Abstract
37 | {
38 | const XML_PATH_DEBUG_TEMPLATE_HINTS = 'dev/debug/template_hints';
39 | const XML_PATH_DEBUG_TEMPLATE_HINTS_BLOCKS = 'dev/debug/template_hints_blocks';
40 | const XML_PATH_TEMPLATE_ALLOW_SYMLINK = 'dev/template/allow_symlink';
41 |
42 | private $_dynamicValues = [];
43 |
44 | /**
45 | * View scripts directory
46 | *
47 | * @var string
48 | */
49 | protected $_viewDir = '';
50 |
51 | /**
52 | * Assigned variables for view
53 | *
54 | * @var array
55 | */
56 | protected $_viewVars = array();
57 |
58 | protected $_baseUrl;
59 |
60 | protected $_jsUrl;
61 |
62 | /**
63 | * Is allowed symlinks flag
64 | *
65 | * @var bool
66 | */
67 | protected $_allowSymlinks = null;
68 |
69 | protected static $_showTemplateHints;
70 | protected static $_showTemplateHintsBlocks;
71 |
72 | /**
73 | * Path to template file in theme.
74 | *
75 | * @var string
76 | */
77 | protected $_template;
78 |
79 | /**
80 | * Internal constructor, that is called from real constructor
81 | *
82 | */
83 | protected function _construct()
84 | {
85 | parent::_construct();
86 |
87 | /*
88 | * In case template was passed through constructor
89 | * we assign it to block's property _template
90 | * Mainly for those cases when block created
91 | * not via Mage_Core_Model_Layout::addBlock()
92 | */
93 | if ($this->hasData('template')) {
94 | $this->setTemplate($this->getData('template'));
95 | }
96 | }
97 |
98 | /**
99 | * Get relevant path to template
100 | *
101 | * @return string
102 | */
103 | public function getTemplate()
104 | {
105 | return $this->_template;
106 | }
107 |
108 | /**
109 | * Set path to template used for generating block's output.
110 | *
111 | * @param string $template
112 | * @return Mage_Core_Block_Template
113 | */
114 | public function setTemplate($template)
115 | {
116 | $this->_template = $template;
117 | return $this;
118 | }
119 |
120 | /**
121 | * Get absolute path to template
122 | *
123 | * @return string
124 | */
125 | public function getTemplateFile()
126 | {
127 | $params = array('_relative'=>true);
128 | $area = $this->getArea();
129 | if ($area) {
130 | $params['_area'] = $area;
131 | }
132 | $templateName = Mage::getDesign()->getTemplateFilename($this->getTemplate(), $params);
133 | return $templateName;
134 | }
135 |
136 | /**
137 | * Get design area
138 | * @return string
139 | */
140 | public function getArea()
141 | {
142 | return $this->_getData('area');
143 | }
144 |
145 | /**
146 | * Assign variable
147 | *
148 | * @param string|array $key
149 | * @param mixed $value
150 | * @return Mage_Core_Block_Template
151 | */
152 | public function assign($key, $value=null)
153 | {
154 | if (is_array($key)) {
155 | foreach ($key as $k=>$v) {
156 | $this->assign($k, $v);
157 | }
158 | }
159 | else {
160 | $this->_viewVars[$key] = $value;
161 | }
162 | return $this;
163 | }
164 |
165 | public function addDynamicValue($key, $method, $args=[])
166 | {
167 | $this->_dynamicValues[$key] = new Varien_Object(compact('method', 'args'));
168 | }
169 |
170 | protected function assignDynamicValue()
171 | {
172 | foreach($this->_dynamicValues as $key => $valueGenerator) {
173 | $this->assign($key, call_user_func_array(
174 | [$this, $valueGenerator->getMethod()],
175 | $valueGenerator->getArgs()
176 | )
177 | );
178 | }
179 | }
180 |
181 | /**
182 | * Set template location directory
183 | *
184 | * @param string $dir
185 | * @return Mage_Core_Block_Template
186 | */
187 | public function setScriptPath($dir)
188 | {
189 | $scriptPath = realpath($dir);
190 | if (strpos($scriptPath, realpath(Mage::getBaseDir('design'))) === 0 || $this->_getAllowSymlinks()) {
191 | $this->_viewDir = $dir;
192 | } else {
193 | Mage::log('Not valid script path:' . $dir, Zend_Log::CRIT, null, null, true);
194 | }
195 | return $this;
196 | }
197 |
198 | /**
199 | * Check if direct output is allowed for block
200 | *
201 | * @return bool
202 | */
203 | public function getDirectOutput()
204 | {
205 | if ($this->getLayout()) {
206 | return $this->getLayout()->getDirectOutput();
207 | }
208 | return false;
209 | }
210 |
211 | public function getShowTemplateHints()
212 | {
213 | if (is_null(self::$_showTemplateHints)) {
214 | self::$_showTemplateHints = Mage::getStoreConfig(self::XML_PATH_DEBUG_TEMPLATE_HINTS)
215 | && Mage::helper('core')->isDevAllowed();
216 | self::$_showTemplateHintsBlocks = Mage::getStoreConfig(self::XML_PATH_DEBUG_TEMPLATE_HINTS_BLOCKS)
217 | && Mage::helper('core')->isDevAllowed();
218 | }
219 | return self::$_showTemplateHints;
220 | }
221 |
222 | /**
223 | * Retrieve block view from file (template)
224 | *
225 | * @param string $fileName
226 | * @return string
227 | */
228 | public function fetchView($fileName)
229 | {
230 | Varien_Profiler::start($fileName);
231 |
232 | $this->assignDynamicValue();
233 | // EXTR_SKIP protects from overriding
234 | // already defined variables
235 | extract ($this->_viewVars, EXTR_SKIP);
236 | $do = $this->getDirectOutput();
237 |
238 | if (!$do) {
239 | ob_start();
240 | }
241 | if ($this->getShowTemplateHints()) {
242 | echo <<
244 | {$fileName}
247 | HTML;
248 | if (self::$_showTemplateHintsBlocks) {
249 | $thisClass = get_class($this);
250 | echo <<{$thisClass}
254 | HTML;
255 | }
256 | }
257 |
258 | try {
259 | if ($component = $this->getReactComponent()) {
260 | echo $this->fetchReactComponent($component, $this->_viewVars);
261 | } else {
262 | $includeFilePath = realpath($this->_viewDir . DS . $fileName);
263 | if (strpos($includeFilePath, realpath($this->_viewDir)) === 0 || $this->_getAllowSymlinks()) {
264 | include $includeFilePath;
265 | } else {
266 | Mage::log('Not valid template file:'.$fileName, Zend_Log::CRIT, null, null, true);
267 | }
268 | }
269 | } catch (Exception $e) {
270 | ob_get_clean();
271 | throw $e;
272 | }
273 |
274 | if ($this->getShowTemplateHints()) {
275 | echo '';
276 | }
277 |
278 | if (!$do) {
279 | $html = ob_get_clean();
280 | } else {
281 | $html = '';
282 | }
283 | Varien_Profiler::stop($fileName);
284 | return $html;
285 | }
286 |
287 | protected function fetchReactComponent($componentName, $props)
288 | {
289 | $bundle_source = file_get_contents(BP . DS . 'js/bundle.js');
290 | $react_source = file_get_contents(BP . DS . 'js/vendor.bundle.js');
291 | $rjs = new ReactJS($react_source, $bundle_source);
292 | $rjs->setComponent($componentName, $props);
293 | echo '' . $rjs->getMarkup() . '
';
294 | printf('', $rjs->getJS('#' . $componentName));
295 | }
296 | /**
297 | * Render block
298 | *
299 | * @return string
300 | */
301 | public function renderView()
302 | {
303 | $this->setScriptPath(Mage::getBaseDir('design'));
304 | $html = $this->fetchView($this->getTemplateFile());
305 | return $html;
306 | }
307 |
308 | /**
309 | * Render block HTML
310 | *
311 | * @return string
312 | */
313 | protected function _toHtml()
314 | {
315 | if (!$this->getTemplate()) {
316 | return '';
317 | }
318 | $html = $this->renderView();
319 | return $html;
320 | }
321 |
322 | /**
323 | * Get base url of the application
324 | *
325 | * @return string
326 | */
327 | public function getBaseUrl()
328 | {
329 | if (!$this->_baseUrl) {
330 | $this->_baseUrl = Mage::getBaseUrl();
331 | }
332 | return $this->_baseUrl;
333 | }
334 |
335 | /**
336 | * Get url of base javascript file
337 | *
338 | * To get url of skin javascript file use getSkinUrl()
339 | *
340 | * @param string $fileName
341 | * @return string
342 | */
343 | public function getJsUrl($fileName='')
344 | {
345 | if (!$this->_jsUrl) {
346 | $this->_jsUrl = Mage::getBaseUrl('js');
347 | }
348 | return $this->_jsUrl.$fileName;
349 | }
350 |
351 | /**
352 | * Get data from specified object
353 | *
354 | * @param Varien_Object $object
355 | * @param string $key
356 | * @return mixed
357 | */
358 | public function getObjectData(Varien_Object $object, $key)
359 | {
360 | return $object->getDataUsingMethod((string)$key);
361 | }
362 |
363 | /**
364 | * Get cache key informative items
365 | *
366 | * @return array
367 | */
368 | public function getCacheKeyInfo()
369 | {
370 | return array(
371 | 'BLOCK_TPL',
372 | Mage::app()->getStore()->getCode(),
373 | $this->getTemplateFile(),
374 | 'template' => $this->getTemplate()
375 | );
376 | }
377 |
378 | /**
379 | * Get is allowed symliks flag
380 | *
381 | * @return bool
382 | */
383 | protected function _getAllowSymlinks()
384 | {
385 | if (is_null($this->_allowSymlinks)) {
386 | $this->_allowSymlinks = Mage::getStoreConfigFlag(self::XML_PATH_TEMPLATE_ALLOW_SYMLINK);
387 | }
388 | return $this->_allowSymlinks;
389 | }
390 | }
391 |
--------------------------------------------------------------------------------