├── .gitignore ├── .runway-config.json ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── app ├── config │ ├── config.php │ ├── log_handlers.php │ └── routes.php ├── logger.php └── resources │ ├── scripts │ └── index.ts │ ├── scss │ ├── main.scss │ ├── modules │ │ └── _all.scss │ ├── partials │ │ ├── _base.scss │ │ └── _hello.scss │ └── vendor │ │ ├── .gitkeep │ │ └── _bootstrap.scss │ └── views │ ├── 404.latte │ ├── 404.twig │ ├── index.latte │ ├── index.twig │ ├── layout.latte │ └── layout.twig ├── bin └── .gitkeep ├── composer.json ├── package-lock.json ├── package.json ├── phpcs.xml ├── public ├── .htaccess ├── crossdomain.xml ├── favicon.ico ├── index.php ├── resources │ └── img │ │ └── .gitignore └── robots.txt ├── runway ├── src └── Acme │ └── Demo │ ├── Commands │ ├── .gitkeep │ └── ExampleCommand.php │ ├── Controllers │ ├── API.php │ └── Demo.php │ ├── Exception │ └── .gitkeep │ ├── Model │ └── .gitkeep │ ├── Test │ └── .gitkeep │ ├── Trait │ └── .gitkeep │ └── Util │ └── .gitkeep ├── tsconfig.json ├── var ├── cache │ └── .gitkeep └── logs │ └── .gitkeep └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | composer.lock 3 | node_modules 4 | public/resources/compiled 5 | var/cache 6 | var/logs 7 | dist/ -------------------------------------------------------------------------------- /.runway-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "index_root": "public/index.php", 3 | "app_root": "src/Acme/Demo/", 4 | "root_paths": ["."] 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.tabSize": 4, 3 | "phpcs.ignorePatterns": [ 4 | "vendor/" 5 | ] 6 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013 Daniel Melzer 4 | Copyright (c) 2017 Mark Hughes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Flight Skeleton 2 | 3 | This skeleton provides a quick start for the development of an application with the [Flight](http://flightphp.com) PHP microframework. The 4 | goal here is to get going as fast as possible. 5 | 6 | It also adds support for Runway (CLI), Sass, Twig or Latte, and even TypeScript (it also includes Volta for npm version managing)! 7 | 8 | ## Downloading the skeleton 9 | 10 | First, check that you have installed and configured a web server (such as Nginx) with PHP 8 or higher. 11 | 12 | You can either use this [template on github](https://github.com/markhughes/flight-skeleton/generate), or use git to clone this repo: 13 | 14 | `$ git clone https://github.com/markhughes/flight-skeleton.git my-app-name` 15 | 16 | ## Creating the application 17 | 18 | If you want to define global constants or other settings, you can use the `config.php` in `app/config/`. 19 | 20 | ### Routing 21 | 22 | To define your routes, use the file `app/config/routes.php`: 23 | 24 | ```php 25 | info('hello world!'); 53 | ``` 54 | 55 | ### Webpack 56 | 57 | Compile your scripts using `npm run build` which will throw it all together in `public/dist/main.js` - check the webpack docs on how to use it more effectively. Your entrypoint is located in `app/resources/scripts/index.ts` if you don't want to use TypeScript just rename index.ts to index.js. 58 | 59 | You can also run `npm run dev` to start webpack in watch mode, great for development. 60 | 61 | ### Commands 62 | 63 | Using Runway you can add commands into the application. 64 | 65 | ``` 66 | ./runway example:example-command 67 | ``` 68 | 69 | Will execute the command in src/Acme/Demo/Comands/ExampleCommand.php 70 | 71 | Runway has a few strict restrictions for commands: 72 | 73 | 1. They must be in a directory called "commands" 74 | 2. The file name must end in Command.php 75 | 76 | ## Volta 77 | 78 | This project uses [Volta](https://volta.sh/) to manage the node and npm version, it is optional to setup but it is a great tool to manage your JavaScript toolchain. 79 | 80 | # License 81 | 82 | The skeleton is licensed under the [MIT](https://opensource.org/licenses/MIT) license. 83 | -------------------------------------------------------------------------------- /app/config/config.php: -------------------------------------------------------------------------------- 1 | __DIR__ . "/../resources/views/" 19 | ]); 20 | 21 | // -------------------------------------------------- // 22 | // TWIG CONFIG 23 | // -------------------------------------------------- // 24 | // Not using Twig? Remove this section! 25 | 26 | if (TEMPLATE_ENGINE === "twig") { 27 | define("TWIG_CONFIG", [ 28 | "cache" => __DIR__ . "/../../var/cache/twig/", 29 | "debug" => DEBUG, 30 | ]); 31 | } 32 | 33 | // -------------------------------------------------- // 34 | // LATTE CONFIG 35 | // -------------------------------------------------- // 36 | // Not using Latte? Remove this section! 37 | 38 | if (TEMPLATE_ENGINE === "latte") { 39 | define("LATTE_CACHE_DIR", __DIR__ . "/../../var/cache/latte/"); 40 | } 41 | -------------------------------------------------------------------------------- /app/config/log_handlers.php: -------------------------------------------------------------------------------- 1 | Flight::render("404", [])); 15 | 16 | Flight::map("error", fn(Throwable $exception) => $logger->error($exception)); 17 | -------------------------------------------------------------------------------- /app/logger.php: -------------------------------------------------------------------------------- 1 | pushHandler($logHandler); 7 | } 8 | -------------------------------------------------------------------------------- /app/resources/scripts/index.ts: -------------------------------------------------------------------------------- 1 | // Hello! If you don't want typescript, just rename this file to index.js. 2 | require('bootstrap'); 3 | require('../scss/main.scss') 4 | 5 | console.log('hello world!') 6 | 7 | window.addEventListener('load', async () => { 8 | const result = await fetch('/api/message'); 9 | const data = await result.json(); 10 | 11 | document.getElementById('api-route-payload').innerText = data.message; 12 | }); 13 | -------------------------------------------------------------------------------- /app/resources/scss/main.scss: -------------------------------------------------------------------------------- 1 | // Modules and Variables 2 | @import "partials/base"; 3 | 4 | // Vendor sheets 5 | @import "vendor/bootstrap"; 6 | 7 | // Partials 8 | @import "partials/hello" 9 | -------------------------------------------------------------------------------- /app/resources/scss/modules/_all.scss: -------------------------------------------------------------------------------- 1 | // Load modules here 2 | -------------------------------------------------------------------------------- /app/resources/scss/partials/_base.scss: -------------------------------------------------------------------------------- 1 | // If you don't want compass just remove this next line 2 | //@import "compass"; 3 | 4 | // Variables 5 | $background-colour: #9fa492; 6 | 7 | // Include our modules 8 | @import "../modules/all"; 9 | -------------------------------------------------------------------------------- /app/resources/scss/partials/_hello.scss: -------------------------------------------------------------------------------- 1 | // Just a quick example 2 | body { 3 | background-color: $background-colour; 4 | } 5 | 6 | .hello { 7 | font-size: 24px; 8 | } -------------------------------------------------------------------------------- /app/resources/scss/vendor/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markhughes/flight-skeleton/c2d7b9e5a09afb2ac9275290169684aecde6f137/app/resources/scss/vendor/.gitkeep -------------------------------------------------------------------------------- /app/resources/scss/vendor/_bootstrap.scss: -------------------------------------------------------------------------------- 1 | @import "~bootstrap/scss/bootstrap"; 2 | -------------------------------------------------------------------------------- /app/resources/views/404.latte: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Page Not Found :( 6 | 77 | 78 | 79 |
80 |

Not found :(

81 |

Sorry, but the page you were trying to view does not exist.

82 |
83 | 84 | -------------------------------------------------------------------------------- /app/resources/views/404.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Page Not Found :( 6 | 77 | 78 | 79 |
80 |

Not found :(

81 |

Sorry, but the page you were trying to view does not exist.

82 |
83 | 84 | -------------------------------------------------------------------------------- /app/resources/views/index.latte: -------------------------------------------------------------------------------- 1 | {layout 'layout.latte'} 2 | 3 | 4 | {block content} 5 | 6 | 7 | 8 |
9 |

{$introduction_title}

10 |

{$introduction_text}

11 | It comes configured ready to go with: 12 | 20 | 21 | and you can even optionally use: 22 | 26 |
27 | 28 | 29 | {/block} 30 | -------------------------------------------------------------------------------- /app/resources/views/index.twig: -------------------------------------------------------------------------------- 1 | {% extends "layout.twig" %} 2 | 3 | {% block content %} 4 | 5 | 6 | 7 |
8 |

{{ introduction_title }}

9 |

{{ introduction_text }}

10 | It comes configured ready to go with: 11 | 19 | 20 | and you can even optionally use: 21 | 25 |
26 | 27 | 28 | {% endblock %} 29 | -------------------------------------------------------------------------------- /app/resources/views/layout.latte: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Hello world! 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | {block content}{/block} 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/resources/views/layout.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Hello world! 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | {% block content %}{% endblock %} 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /bin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markhughes/flight-skeleton/c2d7b9e5a09afb2ac9275290169684aecde6f137/bin/.gitkeep -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "markhughes/flight-skeleton", 3 | "description": "Skeleton for applications based on the Flight PHP microframework.", 4 | "license": "MIT", 5 | "version": "1.0.0", 6 | "keywords": [ 7 | "flight", 8 | "skeleton" 9 | ], 10 | "authors": [ 11 | { 12 | "name": "Mark Hughes", 13 | "email": "m@rkhugh.es", 14 | "homepage": "https://ma.rkhugh.es" 15 | }, 16 | { 17 | "name": "Daniel Melzer", 18 | "email": "daniel@melzer.ws", 19 | "homepage": "http://daniel.melzer.ws" 20 | } 21 | ], 22 | "require": { 23 | "php": ">=8.0", 24 | "mikecao/flight": "~3.12", 25 | "monolog/monolog": "^3.7.0", 26 | "twig/twig": "~3.14", 27 | "flightphp/runway": "^1.1", 28 | "latte/latte": "^3.0" 29 | }, 30 | "autoload": { 31 | "psr-0": { 32 | "": "src/" 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flight-skeleton", 3 | "version": "1.2.0-alt", 4 | "description": "This skeleton provides you a quick start for the development of an application with the [Flight](http://flightphp.com) PHP microframework.", 5 | "private": "true", 6 | "scripts": { 7 | "build": "webpack", 8 | "dev": "webpack --watch --progress", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/markhughes/flight-skeleton.git" 14 | }, 15 | "author": "", 16 | "license": "MIT", 17 | "bugs": { 18 | "url": "https://github.com/markhughes/flight-skeleton/issues" 19 | }, 20 | "homepage": "https://github.com/markhughes/flight-skeleton#readme", 21 | "devDependencies": { 22 | "autoprefixer": "^10.4.13", 23 | "css-loader": "^6.7.2", 24 | "postcss-loader": "^7.2.4", 25 | "sass": "^1.50.1", 26 | "sass-loader": "^12.6.0", 27 | "style-loader": "^3.3.1", 28 | "ts-loader": "^9.4.1", 29 | "typescript": "^4.9.3", 30 | "webpack": "^5.94.0", 31 | "webpack-cli": "^4.0.0" 32 | }, 33 | "dependencies": { 34 | "bootstrap": "^5.2.3", 35 | "popper.js": "^1.16.1" 36 | }, 37 | "volta": { 38 | "node": "18.12.1", 39 | "npm": "9.1.2" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /phpcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | The PSR-12 coding standard. 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 44 | 45 | 46 | 0 47 | 48 | 49 | 0 50 | 51 | 52 | 0 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | error 159 | Method name "%s" must not be prefixed with an underscore to indicate visibility 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 0 206 | 207 | 208 | 0 209 | 210 | 211 | 212 | 213 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 0 234 | 235 | 236 | 0 237 | 238 | 239 | 240 | 241 | 242 | 243 | 0 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 0 295 | 296 | 297 | 0 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | # Flight rewrite rules 2 | RewriteEngine On 3 | RewriteCond %{REQUEST_FILENAME} !-f 4 | RewriteCond %{REQUEST_FILENAME} !-d 5 | RewriteRule ^(.*)$ index.php [QSA,L] 6 | 7 | # Apache Server Configs v1.1.0 | MIT License 8 | # https://github.com/h5bp/server-configs-apache 9 | 10 | # (!) Using `.htaccess` files slows down Apache, therefore, if you have access 11 | # to the main server config file (usually called `httpd.conf`), you should add 12 | # this logic there: http://httpd.apache.org/docs/current/howto/htaccess.html. 13 | 14 | # ############################################################################## 15 | # # CROSS-ORIGIN RESOURCE SHARING (CORS) # 16 | # ############################################################################## 17 | 18 | # ------------------------------------------------------------------------------ 19 | # | Cross-domain AJAX requests | 20 | # ------------------------------------------------------------------------------ 21 | 22 | # Enable cross-origin AJAX requests. 23 | # http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity 24 | # http://enable-cors.org/ 25 | 26 | # 27 | # Header set Access-Control-Allow-Origin "*" 28 | # 29 | 30 | # ------------------------------------------------------------------------------ 31 | # | CORS-enabled images | 32 | # ------------------------------------------------------------------------------ 33 | 34 | # Send the CORS header for images when browsers request it. 35 | # https://developer.mozilla.org/en/CORS_Enabled_Image 36 | # http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html 37 | # http://hacks.mozilla.org/2011/11/using-cors-to-load-webgl-textures-from-cross-domain-images/ 38 | 39 | 40 | 41 | 42 | SetEnvIf Origin ":" IS_CORS 43 | Header set Access-Control-Allow-Origin "*" env=IS_CORS 44 | 45 | 46 | 47 | 48 | # ------------------------------------------------------------------------------ 49 | # | Web fonts access | 50 | # ------------------------------------------------------------------------------ 51 | 52 | # Allow access from all domains for web fonts 53 | 54 | 55 | 56 | Header set Access-Control-Allow-Origin "*" 57 | 58 | 59 | 60 | 61 | # ############################################################################## 62 | # # ERRORS # 63 | # ############################################################################## 64 | 65 | # ------------------------------------------------------------------------------ 66 | # | 404 error prevention for non-existing redirected folders | 67 | # ------------------------------------------------------------------------------ 68 | 69 | # Prevent Apache from returning a 404 error for a rewrite if a directory 70 | # with the same name does not exist. 71 | # http://httpd.apache.org/docs/current/content-negotiation.html#multiviews 72 | # http://www.webmasterworld.com/apache/3808792.htm 73 | 74 | Options -MultiViews 75 | 76 | # ------------------------------------------------------------------------------ 77 | # | Custom error messages / pages | 78 | # ------------------------------------------------------------------------------ 79 | 80 | # You can customize what Apache returns to the client in case of an error (see 81 | # http://httpd.apache.org/docs/current/mod/core.html#errordocument), e.g.: 82 | 83 | ErrorDocument 404 /404.html 84 | 85 | 86 | # ############################################################################## 87 | # # INTERNET EXPLORER # 88 | # ############################################################################## 89 | 90 | # ------------------------------------------------------------------------------ 91 | # | Better website experience | 92 | # ------------------------------------------------------------------------------ 93 | 94 | # Force IE to render pages in the highest available mode in the various 95 | # cases when it may not: http://hsivonen.iki.fi/doctype/ie-mode.pdf. 96 | 97 | 98 | Header set X-UA-Compatible "IE=edge" 99 | # `mod_headers` can't match based on the content-type, however, we only 100 | # want to send this header for HTML pages and not for the other resources 101 | 102 | Header unset X-UA-Compatible 103 | 104 | 105 | 106 | # ------------------------------------------------------------------------------ 107 | # | Cookie setting from iframes | 108 | # ------------------------------------------------------------------------------ 109 | 110 | # Allow cookies to be set from iframes in IE. 111 | 112 | # 113 | # Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"" 114 | # 115 | 116 | # ------------------------------------------------------------------------------ 117 | # | Screen flicker | 118 | # ------------------------------------------------------------------------------ 119 | 120 | # Stop screen flicker in IE on CSS rollovers (this only works in 121 | # combination with the `ExpiresByType` directives for images from below). 122 | 123 | # BrowserMatch "MSIE" brokenvary=1 124 | # BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1 125 | # BrowserMatch "Opera" !brokenvary 126 | # SetEnvIf brokenvary 1 force-no-vary 127 | 128 | 129 | # ############################################################################## 130 | # # MIME TYPES AND ENCODING # 131 | # ############################################################################## 132 | 133 | # ------------------------------------------------------------------------------ 134 | # | Proper MIME types for all files | 135 | # ------------------------------------------------------------------------------ 136 | 137 | 138 | 139 | # Audio 140 | AddType audio/mp4 m4a f4a f4b 141 | AddType audio/ogg oga ogg 142 | 143 | # JavaScript 144 | # Normalize to standard type (it's sniffed in IE anyways): 145 | # http://tools.ietf.org/html/rfc4329#section-7.2 146 | AddType application/javascript js 147 | AddType application/json json 148 | 149 | # Video 150 | AddType video/mp4 mp4 m4v f4v f4p 151 | AddType video/ogg ogv 152 | AddType video/webm webm 153 | AddType video/x-flv flv 154 | 155 | # Web fonts 156 | AddType application/font-woff woff 157 | AddType application/vnd.ms-fontobject eot 158 | 159 | # Browsers usually ignore the font MIME types and sniff the content, 160 | # however, Chrome shows a warning if other MIME types are used for the 161 | # following fonts. 162 | AddType application/x-font-ttf ttc ttf 163 | AddType font/opentype otf 164 | 165 | # Make SVGZ fonts work on iPad: 166 | # https://twitter.com/FontSquirrel/status/14855840545 167 | AddType image/svg+xml svg svgz 168 | AddEncoding gzip svgz 169 | 170 | # Other 171 | AddType application/octet-stream safariextz 172 | AddType application/x-chrome-extension crx 173 | AddType application/x-opera-extension oex 174 | AddType application/x-shockwave-flash swf 175 | AddType application/x-web-app-manifest+json webapp 176 | AddType application/x-xpinstall xpi 177 | AddType application/xml atom rdf rss xml 178 | AddType image/webp webp 179 | AddType image/x-icon ico 180 | AddType text/cache-manifest appcache manifest 181 | AddType text/vtt vtt 182 | AddType text/x-component htc 183 | AddType text/x-vcard vcf 184 | 185 | 186 | 187 | # ------------------------------------------------------------------------------ 188 | # | UTF-8 encoding | 189 | # ------------------------------------------------------------------------------ 190 | 191 | # Use UTF-8 encoding for anything served as `text/html` or `text/plain`. 192 | AddDefaultCharset utf-8 193 | 194 | # Force UTF-8 for certain file formats. 195 | 196 | AddCharset utf-8 .atom .css .js .json .rss .vtt .webapp .xml 197 | 198 | 199 | 200 | # ############################################################################## 201 | # # URL REWRITES # 202 | # ############################################################################## 203 | 204 | # ------------------------------------------------------------------------------ 205 | # | Rewrite engine | 206 | # ------------------------------------------------------------------------------ 207 | 208 | # Turning on the rewrite engine and enabling the `FollowSymLinks` option is 209 | # necessary for the following directives to work. 210 | 211 | # If your web host doesn't allow the `FollowSymlinks` option, you may need to 212 | # comment it out and use `Options +SymLinksIfOwnerMatch` but, be aware of the 213 | # performance impact: http://httpd.apache.org/docs/current/misc/perf-tuning.html#symlinks 214 | 215 | # Also, some cloud hosting services require `RewriteBase` to be set: 216 | # http://www.rackspace.com/knowledge_center/frequently-asked-question/why-is-mod-rewrite-not-working-on-my-site 217 | 218 | 219 | Options +FollowSymlinks 220 | # Options +SymLinksIfOwnerMatch 221 | RewriteEngine On 222 | # RewriteBase / 223 | 224 | 225 | # ------------------------------------------------------------------------------ 226 | # | Suppressing / Forcing the "www." at the beginning of URLs | 227 | # ------------------------------------------------------------------------------ 228 | 229 | # The same content should never be available under two different URLs especially 230 | # not with and without "www." at the beginning. This can cause SEO problems 231 | # (duplicate content), therefore, you should choose one of the alternatives and 232 | # redirect the other one. 233 | 234 | # By default option 1 (no "www.") is activated: 235 | # http://no-www.org/faq.php?q=class_b 236 | 237 | # If you'd prefer to use option 2, just comment out all the lines from option 1 238 | # and uncomment the ones from option 2. 239 | 240 | # IMPORTANT: NEVER USE BOTH RULES AT THE SAME TIME! 241 | 242 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 243 | 244 | # Option 1: rewrite www.example.com → example.com 245 | 246 | 247 | RewriteCond %{HTTPS} !=on 248 | RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] 249 | RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L] 250 | 251 | 252 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 253 | 254 | # Option 2: rewrite example.com → www.example.com 255 | 256 | # Be aware that the following might not be a good idea if you use "real" 257 | # subdomains for certain parts of your website. 258 | 259 | # 260 | # RewriteCond %{HTTPS} !=on 261 | # RewriteCond %{HTTP_HOST} !^www\..+$ [NC] 262 | # RewriteCond %{HTTP_HOST} !=localhost [NC] 263 | # RewriteCond %{HTTP_HOST} !=127.0.0.1 264 | # RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] 265 | # 266 | 267 | 268 | # ############################################################################## 269 | # # SECURITY # 270 | # ############################################################################## 271 | 272 | # ------------------------------------------------------------------------------ 273 | # | Content Security Policy (CSP) | 274 | # ------------------------------------------------------------------------------ 275 | 276 | # You can mitigate the risk of cross-site scripting and other content-injection 277 | # attacks by setting a Content Security Policy which whitelists trusted sources 278 | # of content for your site. 279 | 280 | # The example header below allows ONLY scripts that are loaded from the current 281 | # site's origin (no inline scripts, no CDN, etc). This almost certainly won't 282 | # work as-is for your site! 283 | 284 | # To get all the details you'll need to craft a reasonable policy for your site, 285 | # read: http://html5rocks.com/en/tutorials/security/content-security-policy (or 286 | # see the specification: http://w3.org/TR/CSP). 287 | 288 | # 289 | # Header set Content-Security-Policy "script-src 'self'; object-src 'self'" 290 | # 291 | # Header unset Content-Security-Policy 292 | # 293 | # 294 | 295 | # ------------------------------------------------------------------------------ 296 | # | File access | 297 | # ------------------------------------------------------------------------------ 298 | 299 | # Block access to directories without a default document. 300 | # Usually you should leave this uncommented because you shouldn't allow anyone 301 | # to surf through every directory on your server (which may includes rather 302 | # private places like the CMS's directories). 303 | 304 | 305 | Options -Indexes 306 | 307 | 308 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 309 | 310 | # Block access to hidden files and directories. 311 | # This includes directories used by version control systems such as Git and SVN. 312 | 313 | 314 | RewriteCond %{SCRIPT_FILENAME} -d [OR] 315 | RewriteCond %{SCRIPT_FILENAME} -f 316 | RewriteRule "(^|/)\." - [F] 317 | 318 | 319 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 320 | 321 | # Block access to backup and source files. 322 | # These files may be left by some text editors and can pose a great security 323 | # danger when anyone has access to them. 324 | 325 | 326 | Order allow,deny 327 | Deny from all 328 | Satisfy All 329 | 330 | 331 | # ------------------------------------------------------------------------------ 332 | # | Secure Sockets Layer (SSL) | 333 | # ------------------------------------------------------------------------------ 334 | 335 | # Rewrite secure requests properly to prevent SSL certificate warnings, e.g.: 336 | # prevent `https://www.example.com` when your certificate only allows 337 | # `https://secure.example.com`. 338 | 339 | # 340 | # RewriteCond %{SERVER_PORT} !^443 341 | # RewriteRule ^ https://example-domain-please-change-me.com%{REQUEST_URI} [R=301,L] 342 | # 343 | 344 | # ------------------------------------------------------------------------------ 345 | # | HTTP Strict Transport Security (HSTS) | 346 | # ------------------------------------------------------------------------------ 347 | 348 | # Force client-side SSL redirection. 349 | 350 | # If a user types "example.com" in his browser, the above rule will redirect 351 | # him to the secure version of the site. That still leaves a window of oppor- 352 | # tunity (the initial HTTP connection) for an attacker to downgrade or redirect 353 | # the request. The following header ensures that browser will ONLY connect to 354 | # your server via HTTPS, regardless of what the users type in the address bar. 355 | # http://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec-14#section-6.1 356 | # http://www.html5rocks.com/en/tutorials/security/transport-layer-security/ 357 | 358 | # (!) Remove the `includeSubDomains` optional directive if the subdomains are 359 | # not using HTTPS. 360 | 361 | # 362 | # Header set Strict-Transport-Security "max-age=16070400; includeSubDomains" 363 | # 364 | 365 | # ------------------------------------------------------------------------------ 366 | # | Server software information | 367 | # ------------------------------------------------------------------------------ 368 | 369 | # Avoid displaying the exact Apache version number, the description of the 370 | # generic OS-type and the information about Apache's compiled-in modules. 371 | 372 | # ADD THIS DIRECTIVE IN THE `httpd.conf` AS IT WILL NOT WORK IN THE `.htaccess`! 373 | 374 | # ServerTokens Prod 375 | 376 | 377 | # ############################################################################## 378 | # # WEB PERFORMANCE # 379 | # ############################################################################## 380 | 381 | # ------------------------------------------------------------------------------ 382 | # | Compression | 383 | # ------------------------------------------------------------------------------ 384 | 385 | 386 | 387 | # Force compression for mangled headers. 388 | # http://developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping 389 | 390 | 391 | SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding 392 | RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding 393 | 394 | 395 | 396 | # Compress all output labeled with one of the following MIME-types 397 | # (for Apache versions below 2.3.7, you don't need to enable `mod_filter` 398 | # and can remove the `` and `` lines 399 | # as `AddOutputFilterByType` is still in the core directives). 400 | 401 | AddOutputFilterByType DEFLATE application/atom+xml \ 402 | application/javascript \ 403 | application/json \ 404 | application/rss+xml \ 405 | application/vnd.ms-fontobject \ 406 | application/x-font-ttf \ 407 | application/x-web-app-manifest+json \ 408 | application/xhtml+xml \ 409 | application/xml \ 410 | font/opentype \ 411 | image/svg+xml \ 412 | image/x-icon \ 413 | text/css \ 414 | text/html \ 415 | text/plain \ 416 | text/x-component \ 417 | text/xml 418 | 419 | 420 | 421 | 422 | # ------------------------------------------------------------------------------ 423 | # | Content transformations | 424 | # ------------------------------------------------------------------------------ 425 | 426 | # Prevent some of the mobile network providers from modifying the content of 427 | # your site: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.5. 428 | 429 | # 430 | # Header set Cache-Control "no-transform" 431 | # 432 | 433 | # ------------------------------------------------------------------------------ 434 | # | ETag removal | 435 | # ------------------------------------------------------------------------------ 436 | 437 | # Since we're sending far-future expires headers (see below), ETags can 438 | # be removed: http://developer.yahoo.com/performance/rules.html#etags. 439 | 440 | # `FileETag None` is not enough for every server. 441 | 442 | Header unset ETag 443 | 444 | 445 | FileETag None 446 | 447 | # ------------------------------------------------------------------------------ 448 | # | Expires headers (for better cache control) | 449 | # ------------------------------------------------------------------------------ 450 | 451 | # The following expires headers are set pretty far in the future. If you don't 452 | # control versioning with filename-based cache busting, consider lowering the 453 | # cache time for resources like CSS and JS to something like 1 week. 454 | 455 | 456 | 457 | ExpiresActive on 458 | ExpiresDefault "access plus 1 month" 459 | 460 | # CSS 461 | ExpiresByType text/css "access plus 1 year" 462 | 463 | # Data interchange 464 | ExpiresByType application/json "access plus 0 seconds" 465 | ExpiresByType application/xml "access plus 0 seconds" 466 | ExpiresByType text/xml "access plus 0 seconds" 467 | 468 | # Favicon (cannot be renamed!) 469 | ExpiresByType image/x-icon "access plus 1 week" 470 | 471 | # HTML components (HTCs) 472 | ExpiresByType text/x-component "access plus 1 month" 473 | 474 | # HTML 475 | ExpiresByType text/html "access plus 0 seconds" 476 | 477 | # JavaScript 478 | ExpiresByType application/javascript "access plus 1 year" 479 | 480 | # Manifest files 481 | ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds" 482 | ExpiresByType text/cache-manifest "access plus 0 seconds" 483 | 484 | # Media 485 | ExpiresByType audio/ogg "access plus 1 month" 486 | ExpiresByType image/gif "access plus 1 month" 487 | ExpiresByType image/jpeg "access plus 1 month" 488 | ExpiresByType image/png "access plus 1 month" 489 | ExpiresByType video/mp4 "access plus 1 month" 490 | ExpiresByType video/ogg "access plus 1 month" 491 | ExpiresByType video/webm "access plus 1 month" 492 | 493 | # Web feeds 494 | ExpiresByType application/atom+xml "access plus 1 hour" 495 | ExpiresByType application/rss+xml "access plus 1 hour" 496 | 497 | # Web fonts 498 | ExpiresByType application/font-woff "access plus 1 month" 499 | ExpiresByType application/vnd.ms-fontobject "access plus 1 month" 500 | ExpiresByType application/x-font-ttf "access plus 1 month" 501 | ExpiresByType font/opentype "access plus 1 month" 502 | ExpiresByType image/svg+xml "access plus 1 month" 503 | 504 | 505 | 506 | # ------------------------------------------------------------------------------ 507 | # | Filename-based cache busting | 508 | # ------------------------------------------------------------------------------ 509 | 510 | # If you're not using a build process to manage your filename version revving, 511 | # you might want to consider enabling the following directives to route all 512 | # requests such as `/css/style.12345.css` to `/css/style.css`. 513 | 514 | # To understand why this is important and a better idea than `*.css?v231`, read: 515 | # http://stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring 516 | 517 | # 518 | # RewriteCond %{REQUEST_FILENAME} !-f 519 | # RewriteRule ^(.+)\.(\d+)\.(js|css|png|jpg|gif)$ $1.$3 [L] 520 | # 521 | 522 | # ------------------------------------------------------------------------------ 523 | # | File concatenation | 524 | # ------------------------------------------------------------------------------ 525 | 526 | # Allow concatenation from within specific CSS and JS files, e.g.: 527 | # Inside of `script.combined.js` you could have 528 | # 529 | # 530 | # and they would be included into this single file. 531 | 532 | # 533 | # 534 | # Options +Includes 535 | # AddOutputFilterByType INCLUDES application/javascript application/json 536 | # SetOutputFilter INCLUDES 537 | # 538 | # 539 | # Options +Includes 540 | # AddOutputFilterByType INCLUDES text/css 541 | # SetOutputFilter INCLUDES 542 | # 543 | # 544 | 545 | # ------------------------------------------------------------------------------ 546 | # | Persistent connections | 547 | # ------------------------------------------------------------------------------ 548 | 549 | # Allow multiple requests to be sent over the same TCP connection: 550 | # http://httpd.apache.org/docs/current/en/mod/core.html#keepalive. 551 | 552 | # Enable if you serve a lot of static content but, be aware of the 553 | # possible disadvantages! 554 | 555 | # 556 | # Header set Connection Keep-Alive 557 | # 558 | -------------------------------------------------------------------------------- /public/crossdomain.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markhughes/flight-skeleton/c2d7b9e5a09afb2ac9275290169684aecde6f137/public/favicon.ico -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | $value) { 19 | Flight::set($key, $value); 20 | } 21 | 22 | 23 | // -------------------------------------------------- // 24 | // TWIG 25 | // -------------------------------------------------- // 26 | // Not using Twig? Remove this section! 27 | 28 | if (TEMPLATE_ENGINE === "twig") { 29 | // Configure Twig with Flight 30 | $twig_loader = new \Twig\Loader\FilesystemLoader(Flight::get("flight.views.path")); 31 | 32 | Flight::register("view", "Twig\Environment", [$twig_loader, TWIG_CONFIG], function ($twig) { 33 | if (DEBUG) { 34 | $twig->addExtension(new \Twig\Extension\DebugExtension()); 35 | } 36 | }); 37 | 38 | Flight::map('render', function (string $template, array $data): void { 39 | echo Flight::view()->render($template . ".twig", $data); 40 | }); 41 | } 42 | 43 | // -------------------------------------------------- // 44 | // LATTE 45 | // -------------------------------------------------- // 46 | // Not using Latte? Remove this section! 47 | if (TEMPLATE_ENGINE === "latte") { 48 | // Configure Latte with Flight 49 | Flight::register('view', Latte\Engine::class, [], function (Latte\Engine $latte) { 50 | $latte->setTempDirectory(LATTE_CACHE_DIR); 51 | 52 | // Tell Latte where the root directory for your views will be at. 53 | $latte->setLoader(new \Latte\Loaders\FileLoader(Flight::get("flight.views.path"))); 54 | }); 55 | 56 | Flight::map('render', function (string $template, array $data): void { 57 | echo Flight::view()->render($template . ".latte", $data); 58 | }); 59 | } 60 | // Lets go! 61 | Flight::start(); 62 | -------------------------------------------------------------------------------- /public/resources/img/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markhughes/flight-skeleton/c2d7b9e5a09afb2ac9275290169684aecde6f137/public/resources/img/.gitignore -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # robotstxt.org/ 2 | 3 | User-agent: * 4 | -------------------------------------------------------------------------------- /runway: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | $config JSON config from .runway-config.json 11 | */ 12 | public function __construct(array $config) 13 | { 14 | parent::__construct('example:example-command', 'This is a sample command.', $config); 15 | } 16 | 17 | /** 18 | * Executes the function 19 | * 20 | * @return void 21 | */ 22 | public function execute() 23 | { 24 | $io = $this->app()->io(); 25 | 26 | $io->info('This is an example... '); 27 | 28 | $io->info('remember to pass `true` in the $io functions to add a new line at the end of the message.', true); 29 | 30 | // ... do something here ... 31 | 32 | $io->ok('Example completed!', true); 33 | } 34 | } -------------------------------------------------------------------------------- /src/Acme/Demo/Controllers/API.php: -------------------------------------------------------------------------------- 1 | 'An example API route!' 14 | ]); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Acme/Demo/Controllers/Demo.php: -------------------------------------------------------------------------------- 1 | "Hello world!", 13 | "introduction_text" => "This is the skeleton for a Flight app." 14 | ]; 15 | 16 | Flight::render("index", $context); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Acme/Demo/Exception/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markhughes/flight-skeleton/c2d7b9e5a09afb2ac9275290169684aecde6f137/src/Acme/Demo/Exception/.gitkeep -------------------------------------------------------------------------------- /src/Acme/Demo/Model/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markhughes/flight-skeleton/c2d7b9e5a09afb2ac9275290169684aecde6f137/src/Acme/Demo/Model/.gitkeep -------------------------------------------------------------------------------- /src/Acme/Demo/Test/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markhughes/flight-skeleton/c2d7b9e5a09afb2ac9275290169684aecde6f137/src/Acme/Demo/Test/.gitkeep -------------------------------------------------------------------------------- /src/Acme/Demo/Trait/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markhughes/flight-skeleton/c2d7b9e5a09afb2ac9275290169684aecde6f137/src/Acme/Demo/Trait/.gitkeep -------------------------------------------------------------------------------- /src/Acme/Demo/Util/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markhughes/flight-skeleton/c2d7b9e5a09afb2ac9275290169684aecde6f137/src/Acme/Demo/Util/.gitkeep -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./public/dist/", 4 | "noImplicitAny": false, 5 | "sourceMap": true, 6 | "module": "es6", 7 | "target": "es5", 8 | "jsx": "react", 9 | "allowJs": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /var/cache/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markhughes/flight-skeleton/c2d7b9e5a09afb2ac9275290169684aecde6f137/var/cache/.gitkeep -------------------------------------------------------------------------------- /var/logs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markhughes/flight-skeleton/c2d7b9e5a09afb2ac9275290169684aecde6f137/var/logs/.gitkeep -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | entry: './app/resources/scripts/index', 5 | devtool: 'source-map', 6 | module: { 7 | rules: [ 8 | { 9 | test: /\.tsx?$/, 10 | use: 'ts-loader', 11 | exclude: /node_modules/, 12 | }, 13 | { 14 | test: /\.(scss)$/, 15 | use: [{ 16 | loader: 'style-loader', // inject CSS to page 17 | }, { 18 | loader: 'css-loader', // translates CSS into CommonJS modules 19 | }, { 20 | loader: 'postcss-loader', // Run post css actions 21 | options: { 22 | postcssOptions: { 23 | plugins: [ 24 | require('autoprefixer') 25 | ] 26 | } 27 | } 28 | }, { 29 | loader: 'sass-loader' // compiles Sass to CSS 30 | }] 31 | }, 32 | 33 | ], 34 | }, 35 | resolve: { 36 | extensions: ['.ts', '.js', '.tsx', '.jsx'], 37 | }, 38 | output: { 39 | filename: 'main.js', 40 | path: path.resolve(__dirname, 'public', 'dist'), 41 | }, 42 | mode: 'production', 43 | }; 44 | --------------------------------------------------------------------------------