├── .editorconfig ├── .gitignore ├── Gemfile ├── LICENSE.md ├── README.md ├── Rakefile ├── lib ├── middleman-php.rb ├── middleman-php │ ├── extension.rb │ ├── injections.rb │ ├── middleware.rb │ └── version.rb └── middleman_extension.rb └── middleman-php.gemspec /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs. 2 | # More information at http://EditorConfig.org 3 | 4 | # No .editorconfig files above the root directory 5 | root = true 6 | 7 | [*] 8 | indent_style = space 9 | indent_size = 2 10 | end_of_line = lf 11 | charset = utf-8 12 | trim_trailing_whitespace = true 13 | insert_final_newline = true 14 | 15 | [*.md] 16 | indent_size = 4 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore bundler lock file 2 | /Gemfile.lock 3 | 4 | # Ignore pkg folder 5 | /pkg -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # If you have OpenSSL installed, we recommend updating 2 | # the following line to use "https" 3 | source 'http://rubygems.org' 4 | 5 | # Specify your gem's dependencies in middleman-php.gemspec 6 | gemspec 7 | 8 | group :development do 9 | gem "rake" 10 | gem "rdoc" 11 | gem "yard" 12 | end 13 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2015 Robert Lord 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # middleman-php 2 | 3 | **middleman-php** allows [Middleman][mm_repo] to execute PHP scripts. So your `source/kittens.php` file will actually render kittens, and not a mess of ` :html 14 | end 15 | 16 | def after_configuration 17 | app.use Middleman::PhpMiddleware, options_for_middleware 18 | end 19 | 20 | private 21 | 22 | def options_for_middleware 23 | options.to_h.merge( 24 | source_dir: app.source_dir, 25 | environment: app.settings.environment 26 | ) 27 | end 28 | 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/middleman-php/injections.rb: -------------------------------------------------------------------------------- 1 | module Middleman 2 | module Php 3 | class Injections 4 | 5 | def initialize(debug=false) 6 | @debug = debug 7 | @injections = [] 8 | end 9 | 10 | def add_server(source_dir, env) 11 | full_path = File.join(source_dir, env['PATH_INFO']) 12 | env.merge!({ 13 | 'PHP_SELF' => env['PATH_INFO'], 14 | 'SCRIPT_NAME' => full_path, 15 | 'SCRIPT_FILENAME' => full_path, 16 | 'DOCUMENT_ROOT' => source_dir, 17 | 'REQUEST_TIME' => Time.now.to_i, 18 | 'REQUEST_TIME_FLOAT' => "%.4f" % Time.now.to_f, 19 | 'SERVER_ADMIN' => 'ruby@middlemanapp.com' 20 | }) 21 | add_parse_str(URI.encode_www_form(env), '$_SERVER') 22 | end 23 | 24 | def add_post(rack_input) 25 | input = rack_input.read 26 | unless input.length == 0 27 | add_parse_str(input.gsub("'", "\\\\'"), '$_POST') 28 | end 29 | end 30 | 31 | def add_get(query_string) 32 | add_parse_str(query_string, '$_GET') 33 | end 34 | 35 | def add_request 36 | # Using default value "EGPCS" for php.ini directive variable_order. 37 | add_raw('$_REQUEST = array_merge($_ENV, $_GET, $_POST, $_COOKIE, $_SERVER);') 38 | end 39 | 40 | def set_current_directory(source_dir, script_path) 41 | dir_path = File.dirname(File.join(source_dir, script_path)) 42 | add_raw("chdir(#{dir_path.inspect});") 43 | end 44 | 45 | def add_include_path(source_dir, path_info) 46 | path = File.dirname(File.join(source_dir, path_info)) 47 | add_raw("set_include_path(get_include_path() . PATH_SEPARATOR . '#{path}');") 48 | end 49 | 50 | def add_default_session 51 | add_raw("session_id('middleman-php-session');") 52 | end 53 | 54 | def generate 55 | if @injections.any? 56 | injections = "" 57 | if @debug 58 | puts '== PHP Injections:' 59 | puts injections 60 | end 61 | end 62 | return injections || '' 63 | end 64 | 65 | private 66 | 67 | def add_parse_str(values, array_name) 68 | @injections << "parse_str('#{values}', #{array_name});" 69 | end 70 | 71 | def add_raw(source) 72 | @injections << source 73 | end 74 | 75 | end 76 | end 77 | end 78 | -------------------------------------------------------------------------------- /lib/middleman-php/middleware.rb: -------------------------------------------------------------------------------- 1 | require 'middleman-php/injections.rb' 2 | 3 | module Middleman 4 | class PhpMiddleware 5 | 6 | def initialize(app, config={}) 7 | @debug = !!config[:show_debug] 8 | @injections = Middleman::Php::Injections.new(@debug) 9 | @app = app 10 | @config = config 11 | @env = [] 12 | end 13 | 14 | def call(env) 15 | status, headers, response = @app.call(env) 16 | 17 | if env['REQUEST_PATH'] =~ /\.php$/ 18 | set_environment(env) 19 | response.body.map! do |item| 20 | execute_php(item) 21 | end 22 | headers['Content-Length'] = ::Rack::Utils.bytesize(response.body.join).to_s 23 | headers['Content-Type'] = 'text/html' 24 | headers['Cache-Control'] = 'no-cache, no-store, must-revalidate' 25 | end 26 | 27 | [status, headers, response] 28 | end 29 | 30 | private 31 | 32 | def set_environment(env) 33 | @env = env 34 | end 35 | 36 | def execute_php(source) 37 | inject_server 38 | inject_script_directory 39 | inject_include_path 40 | inject_get 41 | inject_post 42 | inject_request 43 | inject_default_session 44 | `echo #{Shellwords.escape(@injections.generate + source)} | php` 45 | end 46 | 47 | def inject_server 48 | if @config[:environment] == :development 49 | @injections.add_server(@config[:source_dir], @env) 50 | end 51 | end 52 | 53 | def inject_script_directory 54 | if @config[:environment] == :development 55 | @injections.set_current_directory(@config[:source_dir], @env['REQUEST_PATH']) 56 | end 57 | end 58 | 59 | def inject_include_path 60 | if @config[:environment] == :development 61 | @injections.add_include_path(@config[:source_dir], @env['PATH_INFO']) 62 | end 63 | end 64 | 65 | def inject_get 66 | unless @env['QUERY_STRING'].empty? 67 | @injections.add_get(@env['QUERY_STRING']) 68 | end 69 | end 70 | 71 | def inject_post 72 | if @env['REQUEST_METHOD'] == "POST" 73 | @injections.add_post(@env["rack.input"]) 74 | end 75 | end 76 | 77 | def inject_request 78 | @injections.add_request 79 | end 80 | 81 | def inject_default_session 82 | @injections.add_default_session 83 | end 84 | 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /lib/middleman-php/version.rb: -------------------------------------------------------------------------------- 1 | module Middleman 2 | module Php 3 | VERSION = "0.0.3" 4 | end 5 | end -------------------------------------------------------------------------------- /lib/middleman_extension.rb: -------------------------------------------------------------------------------- 1 | require "middleman-php" 2 | -------------------------------------------------------------------------------- /middleman-php.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | require "middleman-php/version" 4 | 5 | Gem::Specification.new do |s| 6 | s.name = "middleman-php" 7 | s.version = Middleman::Php::VERSION 8 | s.platform = Gem::Platform::RUBY 9 | s.authors = ["Robert Lord"] 10 | s.email = ["robert@lord.io"] 11 | s.homepage = "https://github.com/lord/middleman-php" 12 | s.summary = %q{Use Middleman to build PHP files} 13 | # s.description = %q{A longer description of your extension} 14 | 15 | s.files = `git ls-files`.split("\n") 16 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 17 | s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } 18 | s.require_paths = ["lib"] 19 | 20 | # The version of middleman-core your extension depends on 21 | s.add_runtime_dependency("middleman-core", [">= 3.2.1"]) 22 | 23 | # Additional dependencies 24 | # s.add_runtime_dependency("gem-name", "gem-version") 25 | end 26 | --------------------------------------------------------------------------------