├── .env
├── .gitignore
├── LICENSE
├── README.md
├── composer.json
├── docker-compose.yml
└── src
├── Api
└── Data
│ └── ManifestInterface.php
├── Block
└── Register.php
├── Controller
├── Index
│ └── Json.php
└── Router.php
├── Helper
└── Config.php
├── Model
├── Config
│ └── Source
│ │ ├── Displaytype.php
│ │ └── Orientation.php
└── Manifest.php
├── etc
├── adminhtml
│ └── system.xml
├── config.xml
├── di.xml
├── frontend
│ ├── di.xml
│ └── routes.xml
└── module.xml
├── registration.php
└── view
└── frontend
└── layout
└── default.xml
/.env:
--------------------------------------------------------------------------------
1 | COMPOSE_PROJECT_NAME=m2_meanbee_webappmanifest
2 |
3 | PROJECT_HOSTNAME=m2-meanbee-webappmanifest.dev.docker
4 | PROJECT_CERT=dev.docker
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /magento
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Meanbee
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Meanbee_WebAppManifest
2 |
3 | A Magento 2 extension that adds a [Web App Manifest](https://developer.mozilla.org/en-US/docs/Web/Manifest) to the store.
4 |
5 | ## Installation
6 |
7 | Install this extension via Composer:
8 |
9 | composer require meanbee/magento2-webappmanifest
10 |
11 | ## Usage
12 |
13 | Configure the information displayed in the manifest and enable it in * Stores > Configuration > General > Web > Web App Manifest Settings *.
14 |
15 | ## Development
16 |
17 | ### Setting up a development environment
18 |
19 | A Docker development environment is included with the project:
20 |
21 | docker-compose run --rm cli magento-extension-installer Meanbee_WebAppManifest \
22 | && docker-compose up -d
23 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "meanbee/magento2-webappmanifest",
3 | "description": "A Magento 2 extension that adds a Web App Manifest to the store.",
4 | "type": "magento2-module",
5 | "version": "1.1.0",
6 | "license": [
7 | "MIT"
8 | ],
9 | "authors": [
10 | {
11 | "name": "Tomas Gerulaitis",
12 | "email": "tomas.gerulaitis@meanbee.com"
13 | }
14 | ],
15 | "repositories": {
16 | "magento": {
17 | "type": "composer",
18 | "url": "https://repo.magento.com/"
19 | }
20 | },
21 | "require": {
22 | "magento/framework": "^101.0.0",
23 | "magento/module-backend": "^100.1.2",
24 | "magento/module-config": "^101.0.0",
25 | "magento/module-store": "^100.1.3"
26 | },
27 | "autoload": {
28 | "files": [
29 | "src/registration.php"
30 | ],
31 | "psr-4": {
32 | "Meanbee\\WebAppManifest\\": "src/"
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "2"
2 | services:
3 | varnish:
4 | image: meanbee/magento2-varnish:latest
5 | hostname: ${PROJECT_HOSTNAME}
6 | ports:
7 | - 80
8 | environment:
9 | VIRTUAL_HOST: ${PROJECT_HOSTNAME}
10 | VIRTUAL_PORT: 80
11 | HTTPS_METHOD: noredirect
12 | CERT_NAME: ${PROJECT_CERT}
13 | links:
14 | - web
15 |
16 | web:
17 | image: meanbee/magento2-nginx:1.9
18 | hostname: web.${PROJECT_HOSTNAME}
19 | ports:
20 | - 80
21 | volumes_from:
22 | - magento
23 | links:
24 | - fpm
25 |
26 | fpm:
27 | image: meanbee/magento2-php:7.0-fpm
28 | hostname: fpm.${PROJECT_HOSTNAME}
29 | ports:
30 | - 9000
31 | volumes_from:
32 | - magento
33 | environment:
34 | ENABLE_SENDMAIL: "true"
35 | PHP_ENABLE_XDEBUG:
36 | links:
37 | - db
38 |
39 | cron:
40 | image: meanbee/magento2-php:7.0-cli
41 | hostname: cron.${PROJECT_HOSTNAME}
42 | command: run-cron
43 | volumes_from:
44 | - magento
45 | environment:
46 | ENABLE_SENDMAIL: "true"
47 | links:
48 | - db
49 |
50 | cli:
51 | image: meanbee/magento2-php:7.0-cli
52 | volumes_from:
53 | - magento
54 | environment:
55 | COMPOSER_HOME: /root/.composer
56 | COMPOSER_ALLOW_SUPERUSER: 1
57 | M2SETUP_INSTALL_DB: "true"
58 | M2SETUP_VERSION: 2.2.*
59 | M2SETUP_USE_SAMPLE_DATA: "true"
60 | M2SETUP_DB_HOST: db
61 | M2SETUP_DB_NAME: magento2
62 | M2SETUP_DB_USER: magento2
63 | M2SETUP_DB_PASSWORD: magento2
64 | M2SETUP_BASE_URL: https://${PROJECT_HOSTNAME}/
65 | M2SETUP_BACKEND_FRONTNAME: admin
66 | M2SETUP_ADMIN_FIRSTNAME: Admin
67 | M2SETUP_ADMIN_LASTNAME: User
68 | M2SETUP_ADMIN_EMAIL: admin@example.com
69 | M2SETUP_ADMIN_USER: admin
70 | M2SETUP_ADMIN_PASSWORD: password123
71 | links:
72 | - db
73 |
74 | db:
75 | image: mariadb:10
76 | ports:
77 | - 3306
78 | volumes:
79 | - dbdata:/var/lib/mysql
80 | environment:
81 | MYSQL_ROOT_PASSWORD: magento2
82 | MYSQL_USER: magento2
83 | MYSQL_PASSWORD: magento2
84 | MYSQL_DATABASE: magento2
85 | TERM: dumb
86 |
87 | magento:
88 | image: meanbee/magento2-data:2.2-sample
89 | volumes:
90 | - .:/extensions/Meanbee_WebAppManifest
91 | environment:
92 | SYNC_DESTINATION: /extensions/Meanbee_WebAppManifest/magento
93 | privileged: true
94 |
95 | volumes:
96 | dbdata:
97 | # Database tables
98 |
99 |
--------------------------------------------------------------------------------
/src/Api/Data/ManifestInterface.php:
--------------------------------------------------------------------------------
1 | config = $config;
27 | $this->template = $template;
28 | }
29 |
30 | /**
31 | * @inheritdoc
32 | */
33 | protected function _toHtml()
34 | {
35 | if ($this->config->isEnabled()) {
36 | return sprintf(
37 | $this->template,
38 | $this->_urlBuilder->getDirectUrl(\Meanbee\WebAppManifest\Controller\Router::MANIFEST_ENDPOINT)
39 | );
40 | } else {
41 | return '';
42 | }
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/Controller/Index/Json.php:
--------------------------------------------------------------------------------
1 | jsonFactory = $jsonFactory;
23 | $this->manifest = $manifest;
24 | }
25 |
26 | /**
27 | * @inheritdoc
28 | */
29 | public function execute()
30 | {
31 | return $this->jsonFactory->create()->setData($this->manifest->getData());
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Controller/Router.php:
--------------------------------------------------------------------------------
1 | actionFactory = $actionFactory;
20 | $this->config = $config;
21 | }
22 |
23 | public function match(\Magento\Framework\App\RequestInterface $request)
24 | {
25 | if ($this->config->isEnabled() && trim($request->getPathInfo(), "/") == static::MANIFEST_ENDPOINT) {
26 | $request
27 | ->setModuleName("webappmanifest")
28 | ->setControllerName("index")
29 | ->setActionName("json");
30 |
31 | return $this->actionFactory->create('Magento\Framework\App\Action\Forward');
32 | }
33 |
34 | return null;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Helper/Config.php:
--------------------------------------------------------------------------------
1 | scopeConfig->isSetFlag(static::XML_PATH_ENABLE, ScopeInterface::SCOPE_STORE, $scope);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Model/Config/Source/Displaytype.php:
--------------------------------------------------------------------------------
1 | toArray() as $value => $label) {
14 | $options[] = ["value" => $value, "label" => $label];
15 | }
16 |
17 | return $options;
18 | }
19 |
20 | /**
21 | * Get options in "key=>value" format.
22 | *
23 | * @return array
24 | */
25 | public function toArray()
26 | {
27 | return [
28 | "browser" => __("Web Page"),
29 | "minimal-ui" => __("Minimal UI"),
30 | "standalone" => __("Standalone App"),
31 | "fullscreen" => __("Fullscreen App"),
32 | ];
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Model/Config/Source/Orientation.php:
--------------------------------------------------------------------------------
1 | toArray() as $value => $label) {
14 | $options[] = ["value" => $value, "label" => $label];
15 | }
16 |
17 | return $options;
18 | }
19 |
20 | /**
21 | * Get options in "key=>value" format.
22 | *
23 | * @return array
24 | */
25 | public function toArray()
26 | {
27 | return [
28 | "any" => __("Any"),
29 | "natural" => __("Natural"),
30 | "portrait" => __("Portrait"),
31 | "landscape" => __("Landscape"),
32 | ];
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Model/Manifest.php:
--------------------------------------------------------------------------------
1 | scopeConfig = $scopeConfig;
36 | $this->urlBuilder = $urlBuilder;
37 | $this->data = [];
38 |
39 | $this->populate();
40 | }
41 |
42 | /**
43 | * @inheritdoc
44 | */
45 | public function getData()
46 | {
47 | return $this->data;
48 | }
49 |
50 | /**
51 | * Populate the Manifest data from configuration.
52 | *
53 | * @return $this
54 | */
55 | public function populate()
56 | {
57 | $this->populateStoreInformation();
58 | $this->populateDisplayOptions();
59 | $this->populateIcons();
60 |
61 | return $this;
62 | }
63 |
64 | /**
65 | * Populate the manifest with store information.
66 | *
67 | * @return $this
68 | */
69 | protected function populateStoreInformation()
70 | {
71 | $this->populateFromConfig("short_name", static::XML_PATH_STORE_INFO_SHORT_NAME);
72 | $this->populateFromConfig("name", static::XML_PATH_STORE_INFO_NAME);
73 | $this->populateFromConfig("description", static::XML_PATH_STORE_INFO_DESCRIPTION, true);
74 |
75 | if ($path = $this->scopeConfig->getValue(static::XML_PATH_STORE_INFO_START_URL, ScopeInterface::SCOPE_STORE)) {
76 | $start_url = $this->urlBuilder->getDirectUrl($path);
77 | } else {
78 | $start_url = $this->urlBuilder->getBaseUrl();
79 | }
80 | $this->data["start_url"] = $start_url;
81 |
82 | return $this;
83 | }
84 |
85 | /**
86 | * Populate the manifest with display settings.
87 | *
88 | * @return $this
89 | */
90 | protected function populateDisplayOptions()
91 | {
92 | $this->populateFromConfig("theme_color", static::XML_PATH_DISPLAY_THEME_COLOR, true);
93 | $this->populateFromConfig("background_color", static::XML_PATH_DISPLAY_BACKGROUND_COLOR, true);
94 | $this->populateFromConfig("display", static::XML_PATH_DISPLAY_DISPLAY_TYPE);
95 | $this->populateFromConfig("orientation", static::XML_PATH_DISPLAY_ORIENTATION);
96 |
97 | return $this;
98 | }
99 |
100 | /**
101 | * Populate the manifest with app icon definitions.
102 | *
103 | * @return $this
104 | */
105 | protected function populateIcons()
106 | {
107 | if ($icon = $this->scopeConfig->getValue(static::XML_PATH_ICONS_ICON, ScopeInterface::SCOPE_STORE)) {
108 | $url = implode("", [
109 | $this->urlBuilder->getBaseUrl(["_type" => UrlInterface::URL_TYPE_MEDIA]),
110 | "webappmanifest/icons/",
111 | $icon,
112 | ]);
113 |
114 | $sizes = $this->scopeConfig->getValue(static::XML_PATH_ICONS_SIZES, ScopeInterface::SCOPE_STORE);
115 |
116 | $this->data["icons"] = [["src" => $url, "sizes" => $sizes]];
117 | }
118 |
119 | return $this;
120 | }
121 |
122 | /**
123 | * Populate a manifest value from System Configration.
124 | *
125 | * @param $key
126 | * @param $config_path
127 | * @param bool $if_exists Only populate the value if it's not empty (default: false)
128 | *
129 | * @return $this
130 | */
131 | protected function populateFromConfig($key, $config_path, $if_exists = false)
132 | {
133 | $value = $this->scopeConfig->getValue($config_path, ScopeInterface::SCOPE_STORE);
134 |
135 | if (!$if_exists || !empty($value)) {
136 | $this->data[$key] = $value;
137 | }
138 |
139 | return $this;
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/src/etc/adminhtml/system.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Magento\Config\Model\Config\Source\Yesno
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | Meanbee\WebAppManifest\Model\Config\Source\Displaytype
36 |
37 |
38 |
39 |
40 | Meanbee\WebAppManifest\Model\Config\Source\Orientation
41 |
42 |
43 |
44 |
45 | Magento\Config\Model\Config\Backend\Image
46 | webappmanifest/icons
47 | webappmanifest/icons
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/src/etc/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | 0
8 | browser
9 | any
10 | 48x48 72x72 128x128 256x256
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/etc/di.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/etc/frontend/di.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | -
7 |
- Meanbee\WebAppManifest\Controller\Router
8 | - false
9 | - 55
10 |
11 |
12 |
13 |
14 |
15 |
16 | ]]>
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/etc/frontend/routes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/etc/module.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/registration.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------