├── config ├── .gitkeep ├── services.php ├── app.php ├── view.php ├── cache.php ├── database.php ├── mail.php └── session.php ├── tests └── .gitkeep ├── resources ├── lang │ ├── .gitkeep │ └── en │ │ └── validation.php ├── views │ └── .gitkeep └── assets │ ├── images │ └── .gitkeep │ ├── scripts │ ├── .gitkeep │ ├── main.js │ ├── admin.js │ └── bootstrap.js │ └── styles │ ├── common │ └── variables.scss │ ├── admin.scss │ └── main.scss ├── src ├── Models │ └── .gitkeep ├── Console │ └── Commands │ │ └── .gitkeep ├── Http │ └── Controllers │ │ └── .gitkeep ├── routes.php └── functions.php ├── storage └── framework │ └── views │ └── .gitkeep ├── .gitignore ├── phpunit.xml ├── composer.json ├── webpack.mix.js ├── CHANGELOG.md ├── package.json ├── readme.txt └── README.md /config/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/lang/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Models/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/assets/images/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/assets/scripts/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Console/Commands/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Http/Controllers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /storage/framework/views/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/assets/scripts/main.js: -------------------------------------------------------------------------------- 1 | require('./bootstrap.js'); -------------------------------------------------------------------------------- /resources/assets/scripts/admin.js: -------------------------------------------------------------------------------- 1 | require('./bootstrap.js'); -------------------------------------------------------------------------------- /resources/assets/scripts/bootstrap.js: -------------------------------------------------------------------------------- 1 | // put code that's comment to both your front-end and admin features here -------------------------------------------------------------------------------- /resources/assets/styles/common/variables.scss: -------------------------------------------------------------------------------- 1 | // Colors 2 | $brand-primary: #27ae60; 3 | 4 | $fa-font-path: "../../../node_modules/font-awesome/fonts/"; -------------------------------------------------------------------------------- /resources/assets/styles/admin.scss: -------------------------------------------------------------------------------- 1 | @import "common/variables"; 2 | 3 | // Import npm dependencies 4 | @import "~bootstrap/scss/bootstrap"; 5 | // @import "~font-awesome/scss/font-awesome"; -------------------------------------------------------------------------------- /resources/assets/styles/main.scss: -------------------------------------------------------------------------------- 1 | @import "common/variables"; 2 | 3 | // Import npm dependencies 4 | @import "~bootstrap/scss/bootstrap"; 5 | // @import "~font-awesome/scss/font-awesome"; -------------------------------------------------------------------------------- /src/routes.php: -------------------------------------------------------------------------------- 1 | get('/plugin-data', function($request) use ($plugin) { 6 | 7 | return $plugin->getPluginData(); 8 | 9 | }); -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Composer 2 | vendor/* 3 | !vendor/.gitkeep 4 | composer.phar 5 | composer.lock 6 | 7 | # Studio 8 | studio.json 9 | 10 | # Other things 11 | .DS_Store 12 | 13 | # Node 14 | node_modules 15 | yarn.lock 16 | 17 | # Built assets 18 | dist 19 | 20 | 21 | -------------------------------------------------------------------------------- /config/services.php: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 16 | ./tests/ 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /config/app.php: -------------------------------------------------------------------------------- 1 | $debug = getenv('APP_DEBUG') ?: ( defined('WP_DEBUG') && WP_DEBUG ), 17 | 18 | 'key' => getenv('AUTH_SALT'), 19 | 20 | 'cipher' => 'AES-256-CBC', 21 | 22 | 'locale' => getenv('APP_LOCALE') ?: 'en', 23 | 24 | 'log' => getenv('APP_LOG') ?: 'daily', 25 | 26 | 'log_max_files' => getenv('APP_LOG_MAX_FILES') ?: 30, 27 | 28 | 'log_level' => getenv('APP_LOG_LEVEL') ?: ( $debug ? 'info' : 'error' ), 29 | 30 | ]; -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "withfatpanda/bamboo", 3 | "description": "Build more with WordPress, faster, using this Plugin framework, based on Laravel.", 4 | "type": "wordpress-plugin", 5 | "license": "(GPLv2 or MIT)", 6 | "version": "1.4.3", 7 | "authors": [ 8 | { 9 | "name": "Aaron Collegeman", 10 | "email": "aaron@withfatpanda.com", 11 | "homepage": "https://withbamboo.com" 12 | } 13 | ], 14 | "autoload": { 15 | "classmap": ["src/"] 16 | }, 17 | "require-dev": { 18 | "phpunit/phpunit": "5.*" 19 | }, 20 | "autoload-dev": { 21 | "classmap": ["tests/"] 22 | }, 23 | "require": { 24 | "php": ">=5.6.4", 25 | "withfatpanda/illuminate-wordpress": "1.4.*", 26 | "composer/installers": "~1.0.12" 27 | }, 28 | "scripts": { 29 | "post-create-project-cmd": [ 30 | "FatPanda\\Illuminate\\WordPress\\Plugin::postCreateProject" 31 | ] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/functions.php: -------------------------------------------------------------------------------- 1 | [ 17 | realpath($this->basePath('resources/views')), 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled View Path 23 | |-------------------------------------------------------------------------- 24 | | 25 | | This option determines where all the compiled Blade templates will be 26 | | stored for your application. Typically, this is within the storage 27 | | directory. However, as usual, you are free to change this value. 28 | | 29 | */ 30 | 31 | 'compiled' => realpath($this->storagePath('framework/views')), 32 | 33 | ]; 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "node node_modules/cross-env/dist/bin/cross-env.js NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 5 | "watch": "node node_modules/cross-env/dist/bin/cross-env.js NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 6 | "production": "node node_modules/cross-env/dist/bin/cross-env.js NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 7 | "rmdist": "rimraf dist" 8 | }, 9 | "engines": { 10 | "node": ">= 6.9.4" 11 | }, 12 | "devDependencies": { 13 | "alertify.js": "^1.0.12", 14 | "animate.css": "^3.5.2", 15 | "axios": "^0.15.2", 16 | "bootstrap": "^4.0.0-alpha.6", 17 | "chart.js": "^2.5.0", 18 | "chosen-js": "^1.6.2", 19 | "font-awesome": "^4.7.0", 20 | "jquery": "^3.1.0", 21 | "laravel-echo": "^1.2.5", 22 | "laravel-mix": "~0.8", 23 | "lodash": "^4.16.2", 24 | "pusher-js": "^4.0.0", 25 | "tether": "^1.4.0", 26 | "tinymce": "^4.5.5", 27 | "vue": "^2.0.1" 28 | } 29 | } -------------------------------------------------------------------------------- /config/cache.php: -------------------------------------------------------------------------------- 1 | env('CACHE_DRIVER', 'memcached'), 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Cache Stores 21 | |-------------------------------------------------------------------------- 22 | | 23 | | Here you may define all of the cache "stores" for your application as 24 | | well as their drivers. You may even define multiple stores for the 25 | | same cache driver to group types of items stored in your caches. 26 | | 27 | */ 28 | 29 | 'stores' => [ 30 | 31 | 'apc' => [ 32 | 'driver' => 'apc', 33 | ], 34 | 35 | 'array' => [ 36 | 'driver' => 'array', 37 | ], 38 | 39 | 'database' => [ 40 | 'driver' => 'database', 41 | 'table' => getenv('CACHE_DATABASE_TABLE') ?: 'cache', 42 | 'connection' => getenv('CACHE_DATABASE_CONNECTION') ?: null, 43 | ], 44 | 45 | 'file' => [ 46 | 'driver' => 'file', 47 | 'path' => $this->storagePath('framework/cache'), 48 | ], 49 | 50 | 'memcached' => [ 51 | 'driver' => 'memcached', 52 | 'servers' => [ 53 | [ 54 | 'host' => getenv('MEMCACHED_HOST') ?: '127.0.0.1', 55 | 'port' => getenv('MEMCACHED_PORT') ?: 11211, 56 | 'weight' => 100, 57 | ], 58 | ], 59 | ], 60 | 61 | 'redis' => [ 62 | 'driver' => 'redis', 63 | 'connection' => getenv('CACHE_REDIS_CONNECTION') ?: 'default', 64 | ], 65 | 66 | ], 67 | 68 | /* 69 | |-------------------------------------------------------------------------- 70 | | Cache Key Prefix 71 | |-------------------------------------------------------------------------- 72 | | 73 | | When utilizing a RAM based store such as APC or Memcached, there might 74 | | be other applications utilizing the same cache. So, we'll specify a 75 | | value to get prefixed to all our keys so we can avoid collisions. 76 | | 77 | */ 78 | 79 | 'prefix' => getenv('CACHE_PREFIX') ?: 'laravel', 80 | 81 | ]; 82 | -------------------------------------------------------------------------------- /config/database.php: -------------------------------------------------------------------------------- 1 | PDO::FETCH_CLASS, 18 | 19 | /* 20 | |-------------------------------------------------------------------------- 21 | | Default Database Connection Name 22 | |-------------------------------------------------------------------------- 23 | | 24 | | Here you may specify which of the database connections below you wish 25 | | to use as your default connection for all database work. Of course 26 | | you may use many connections at once using the Database library. 27 | | 28 | */ 29 | 30 | 'default' => getenv('DB_CONNECTION') ?: 'mysql', 31 | 32 | /* 33 | |-------------------------------------------------------------------------- 34 | | Database Connections 35 | |-------------------------------------------------------------------------- 36 | | 37 | | Here are each of the database connections setup for your application. 38 | | Of course, examples of configuring each database platform that is 39 | | supported by Laravel is shown below to make development simple. 40 | | 41 | | 42 | | All database work in Laravel is done through the PHP PDO facilities 43 | | so make sure you have the driver for your particular database of 44 | | choice installed on your machine before you begin development. 45 | | 46 | */ 47 | 48 | 'connections' => [ 49 | 50 | 'mysql' => [ 51 | 'driver' => 'mysql', 52 | 'host' => getenv('DB_HOST') ?: 'localhost', 53 | 'port' => getenv('DB_PORT') ?: 3306, 54 | 'database' => getenv('DB_NAME') ?: 'forge', 55 | 'username' => getenv('DB_USER') ?: 'forge', 56 | 'password' => getenv('DB_PASSWORD') ?: '', 57 | 'charset' => getenv('DB_CHARSET') ?: 'utf8', 58 | 'collation' => getenv('DB_COLLATE') ?: 'utf8_unicode_ci', 59 | 'prefix' => getenv('DB_PREFIX') ?: $table_prefix, 60 | 'timezone' => getenv('DB_TIMEZONE') ?: '+00:00', 61 | 'strict' => getenv('DB_STRICT_MODE') ?: false, 62 | ], 63 | 64 | ], 65 | 66 | /* 67 | |-------------------------------------------------------------------------- 68 | | Migration Repository Table 69 | |-------------------------------------------------------------------------- 70 | | 71 | | This table keeps track of all the migrations that have already run for 72 | | your application. Using this information, we can determine which of 73 | | the migrations on disk haven't actually been run in the database. 74 | | 75 | */ 76 | 77 | 'migrations' => 'migrations', 78 | 79 | /* 80 | |-------------------------------------------------------------------------- 81 | | Redis Databases 82 | |-------------------------------------------------------------------------- 83 | | 84 | | Redis is an open source, fast, and advanced key-value store that also 85 | | provides a richer set of commands than a typical key-value systems 86 | | such as APC or Memcached. Laravel makes it easy to dig right in. 87 | | 88 | */ 89 | 90 | 'redis' => [ 91 | 92 | 'cluster' => getenv('REDIS_CLUSTER') ?: false, 93 | 94 | 'default' => [ 95 | 'host' => getenv('REDIS_HOST') ?: '127.0.0.1', 96 | 'port' => getenv('REDIS_PORT') ?: 6379, 97 | 'database' => getenv('REDIS_DATABASE') ?: 0, 98 | 'password' => getenv('REDIS_PASSWORD') ?: null 99 | ], 100 | 101 | ], 102 | 103 | ]; 104 | -------------------------------------------------------------------------------- /config/mail.php: -------------------------------------------------------------------------------- 1 | getenv('MAIL_DRIVER') ?: 'smtp', 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | SMTP Host Address 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may provide the host address of the SMTP server used by your 26 | | applications. A default option is provided that is compatible with 27 | | the Mailgun mail service which will provide reliable deliveries. 28 | | 29 | */ 30 | 31 | 'host' => getenv('MAIL_HOST'), 32 | 33 | /* 34 | |-------------------------------------------------------------------------- 35 | | SMTP Host Port 36 | |-------------------------------------------------------------------------- 37 | | 38 | | This is the SMTP port used by your application to deliver e-mails to 39 | | users of the application. Like the host we have set this value to 40 | | stay compatible with the Mailgun e-mail application by default. 41 | | 42 | */ 43 | 44 | 'port' => getenv('MAIL_PORT'), 45 | 46 | /* 47 | |-------------------------------------------------------------------------- 48 | | Global "From" Address 49 | |-------------------------------------------------------------------------- 50 | | 51 | | You may wish for all e-mails sent by your application to be sent from 52 | | the same address. Here, you may specify a name and address that is 53 | | used globally for all e-mails that are sent by your application. 54 | | 55 | */ 56 | 57 | 'from' => ['address' => getenv('MAIL_FROM_ADDRESS'), 'name' => getenv('MAIL_FROM_NAME')], 58 | 59 | /* 60 | |-------------------------------------------------------------------------- 61 | | E-Mail Encryption Protocol 62 | |-------------------------------------------------------------------------- 63 | | 64 | | Here you may specify the encryption protocol that should be used when 65 | | the application send e-mail messages. A sensible default using the 66 | | transport layer security protocol should provide great security. 67 | | 68 | */ 69 | 70 | 'encryption' => getenv('MAIL_ENCRYPTION') ?: 'tls', 71 | 72 | /* 73 | |-------------------------------------------------------------------------- 74 | | SMTP Server Username 75 | |-------------------------------------------------------------------------- 76 | | 77 | | If your SMTP server requires a username for authentication, you should 78 | | set it here. This will get used to authenticate with your server on 79 | | connection. You may also set the "password" value below this one. 80 | | 81 | */ 82 | 83 | 'username' => getenv('MAIL_USERNAME'), 84 | 85 | /* 86 | |-------------------------------------------------------------------------- 87 | | SMTP Server Password 88 | |-------------------------------------------------------------------------- 89 | | 90 | | Here you may set the password required by your SMTP server to send out 91 | | messages from your application. This will be given to the server on 92 | | connection so that the application will be able to send messages. 93 | | 94 | */ 95 | 96 | 'password' => getenv('MAIL_PASSWORD'), 97 | 98 | /* 99 | |-------------------------------------------------------------------------- 100 | | Sendmail System Path 101 | |-------------------------------------------------------------------------- 102 | | 103 | | When using the "sendmail" driver to send e-mails, we will need to know 104 | | the path to where Sendmail lives on this server. A default path has 105 | | been provided here, which will work well on most of your systems. 106 | | 107 | */ 108 | 109 | 'sendmail' => getenv('MAIL_SENDMAIL') ?: '/usr/sbin/sendmail -bs', 110 | 111 | /* 112 | |-------------------------------------------------------------------------- 113 | | Mail "Pretend" 114 | |-------------------------------------------------------------------------- 115 | | 116 | | When this option is enabled, e-mail will not actually be sent over the 117 | | web and will instead be written to your application's logs files so 118 | | you may inspect the message. This is great for local development. 119 | | 120 | */ 121 | 122 | 'pretend' => getenv('MAIL_PRETEND') ?: false, 123 | 124 | ]; 125 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | === Plugin Name === 2 | Contributors: (this should be a list of wordpress.org userid's) 3 | Donate link: http://example.com/ 4 | Tags: comments, spam 5 | Requires at least: 4.6 6 | Tested up to: 4.7 7 | Stable tag: 4.3 8 | License: GPLv2 or later 9 | License URI: https://www.gnu.org/licenses/gpl-2.0.html 10 | 11 | Here is a short description of the plugin. This should be no more than 150 characters. No markup here. 12 | 13 | == Description == 14 | 15 | This is the long description. No limit, and you can use Markdown (as well as in the following sections). 16 | 17 | For backwards compatibility, if this section is missing, the full length of the short description will be used, and 18 | Markdown parsed. 19 | 20 | A few notes about the sections above: 21 | 22 | * "Contributors" is a comma separated list of wordpress.org usernames 23 | * "Tags" is a comma separated list of tags that apply to the plugin 24 | * "Requires at least" is the lowest version that the plugin will work on 25 | * "Tested up to" is the highest version that you've *successfully used to test the plugin*. Note that it might work on 26 | higher versions... this is just the highest one you've verified. 27 | * Stable tag should indicate the Subversion "tag" of the latest stable version, or "trunk," if you use `/trunk/` for 28 | stable. 29 | 30 | Note that the `readme.txt` of the stable tag is the one that is considered the defining one for the plugin, so 31 | if the `/trunk/readme.txt` file says that the stable tag is `4.3`, then it is `/tags/4.3/readme.txt` that'll be used 32 | for displaying information about the plugin. In this situation, the only thing considered from the trunk `readme.txt` 33 | is the stable tag pointer. Thus, if you develop in trunk, you can update the trunk `readme.txt` to reflect changes in 34 | your in-development version, without having that information incorrectly disclosed about the current stable version 35 | that lacks those changes -- as long as the trunk's `readme.txt` points to the correct stable tag. 36 | 37 | If no stable tag is provided, it is assumed that trunk is stable, but you should specify "trunk" if that's where 38 | you put the stable version, in order to eliminate any doubt. 39 | 40 | == Installation == 41 | 42 | This section describes how to install the plugin and get it working. 43 | 44 | e.g. 45 | 46 | 1. Upload the plugin files to the `/wp-content/plugins/plugin-name` directory, or install the plugin through the WordPress plugins screen directly. 47 | 1. Activate the plugin through the 'Plugins' screen in WordPress 48 | 1. Use the Settings->Plugin Name screen to configure the plugin 49 | 1. (Make your instructions match the desired user flow for activating and installing your plugin. Include any steps that might be needed for explanatory purposes) 50 | 51 | 52 | == Frequently Asked Questions == 53 | 54 | = A question that someone might have = 55 | 56 | An answer to that question. 57 | 58 | = What about foo bar? = 59 | 60 | Answer to foo bar dilemma. 61 | 62 | == Screenshots == 63 | 64 | 1. This screen shot description corresponds to screenshot-1.(png|jpg|jpeg|gif). Note that the screenshot is taken from 65 | the /assets directory or the directory that contains the stable readme.txt (tags or trunk). Screenshots in the /assets 66 | directory take precedence. For example, `/assets/screenshot-1.png` would win over `/tags/4.3/screenshot-1.png` 67 | (or jpg, jpeg, gif). 68 | 2. This is the second screen shot 69 | 70 | == Changelog == 71 | 72 | = 1.0 = 73 | * A change since the previous version. 74 | * Another change. 75 | 76 | = 0.5 = 77 | * List versions from most recent at top to oldest at bottom. 78 | 79 | == Upgrade Notice == 80 | 81 | = 1.0 = 82 | Upgrade notices describe the reason a user should upgrade. No more than 300 characters. 83 | 84 | = 0.5 = 85 | This version fixes a security related bug. Upgrade immediately. 86 | 87 | == Arbitrary section == 88 | 89 | You may provide arbitrary sections, in the same format as the ones above. This may be of use for extremely complicated 90 | plugins where more information needs to be conveyed that doesn't fit into the categories of "description" or 91 | "installation." Arbitrary sections will be shown below the built-in sections outlined above. 92 | 93 | == A brief Markdown Example == 94 | 95 | Ordered list: 96 | 97 | 1. Some feature 98 | 1. Another feature 99 | 1. Something else about the plugin 100 | 101 | Unordered list: 102 | 103 | * something 104 | * something else 105 | * third thing 106 | 107 | Here's a link to [WordPress](http://wordpress.org/ "Your favorite software") and one to [Markdown's Syntax Documentation][markdown syntax]. 108 | Titles are optional, naturally. 109 | 110 | [markdown syntax]: http://daringfireball.net/projects/markdown/syntax 111 | "Markdown is what the parser uses to process much of the readme file" 112 | 113 | Markdown uses email style notation for blockquotes and I've been told: 114 | > Asterisks for *emphasis*. Double it up for **strong**. 115 | 116 | `` -------------------------------------------------------------------------------- /config/session.php: -------------------------------------------------------------------------------- 1 | getenv('SESSION_DRIVER') ?: 'wordpress', 20 | 21 | /* 22 | |-------------------------------------------------------------------------- 23 | | Session Lifetime 24 | |-------------------------------------------------------------------------- 25 | | 26 | | Here you may specify the number of minutes that you wish the session 27 | | to be allowed to remain idle before it expires. If you want them 28 | | to immediately expire on the browser closing, set that option. 29 | | 30 | */ 31 | 32 | 'lifetime' => getenv('SESSION_LIFETIME') ?: 120, 33 | 34 | 'expire_on_close' => getenv('SESSION_EXPIRE_ON_CLOSE') ?: false, 35 | 36 | /* 37 | |-------------------------------------------------------------------------- 38 | | Session Encryption 39 | |-------------------------------------------------------------------------- 40 | | 41 | | This option allows you to easily specify that all of your session data 42 | | should be encrypted before it is stored. All encryption will be run 43 | | automatically by Laravel and you can use the Session like normal. 44 | | 45 | */ 46 | 47 | 'encrypt' => getenv('SESSION_ENCRYPT') ?: false, 48 | 49 | /* 50 | |-------------------------------------------------------------------------- 51 | | Session Database Connection 52 | |-------------------------------------------------------------------------- 53 | | 54 | | When using the "database" or "redis" session drivers, you may specify a 55 | | connection that should be used to manage these sessions. This should 56 | | correspond to a connection in your database configuration options. 57 | | 58 | */ 59 | 60 | 'connection' => getenv('SESSION_DB_CONNECTION') ?: 'mysql', 61 | 62 | /* 63 | |-------------------------------------------------------------------------- 64 | | Session Database Table 65 | |-------------------------------------------------------------------------- 66 | | 67 | | When using the "database" session driver, you may specify the table we 68 | | should use to manage the sessions. Of course, a sensible default is 69 | | provided for you; however, you are free to change this as needed. 70 | | 71 | */ 72 | 73 | 'table' => 'sessions', 74 | 75 | /* 76 | |-------------------------------------------------------------------------- 77 | | Session Sweeping Lottery 78 | |-------------------------------------------------------------------------- 79 | | 80 | | Some session drivers must manually sweep their storage location to get 81 | | rid of old sessions from storage. Here are the chances that it will 82 | | happen on a given request. By default, the odds are 2 out of 100. 83 | | 84 | */ 85 | 86 | 'lottery' => [2, 100], 87 | 88 | /* 89 | |-------------------------------------------------------------------------- 90 | | Session Cookie Name 91 | |-------------------------------------------------------------------------- 92 | | 93 | | Here you may change the name of the cookie used to identify a session 94 | | instance by ID. The name specified here will get used every time a 95 | | new session cookie is created by the framework for every driver. 96 | | 97 | */ 98 | 99 | 'cookie' => getenv('SESSION_COOKIE_NAME') ?: 'illuminate_session', 100 | 101 | /* 102 | |-------------------------------------------------------------------------- 103 | | Session Cookie Path 104 | |-------------------------------------------------------------------------- 105 | | 106 | | The session cookie path determines the path for which the cookie will 107 | | be regarded as available. Typically, this will be the root path of 108 | | your application but you are free to change this when necessary. 109 | | 110 | */ 111 | 112 | 'path' => '/', 113 | 114 | /* 115 | |-------------------------------------------------------------------------- 116 | | Session Cookie Domain 117 | |-------------------------------------------------------------------------- 118 | | 119 | | Here you may change the domain of the cookie used to identify a session 120 | | in your application. This will determine which domains the cookie is 121 | | available to in your application. A sensible default has been set. 122 | | 123 | */ 124 | 125 | 'domain' => getenv('SESSION_COOKIE_DOMAIN') ?: null, 126 | 127 | /* 128 | |-------------------------------------------------------------------------- 129 | | HTTPS Only Cookies 130 | |-------------------------------------------------------------------------- 131 | | 132 | | By setting this option to true, session cookies will only be sent back 133 | | to the server if the browser has a HTTPS connection. This will keep 134 | | the cookie from being sent to you if it can not be done securely. 135 | | 136 | */ 137 | 138 | 'secure' => getenv('SESSION_COOKIE_SECURE') ?: false, 139 | 140 | ]; 141 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Better WordPress plugins, faster. 2 | 3 | This is the way Web Artisans write software for WordPress: with elegance, simplicity, and readability. 4 | 5 | *How?* By writing WordPress plugins with [Laravel](https://laravel.com). 6 | 7 | These plugins work just like normal WordPress plugins, except that they're each also Laravel [Service Containers](https://laravel.com/docs/5.3/container). 8 | 9 | This means that in addition to behaving like WordPress plugins, they also behave much like Laravel apps do, and they inherit much of their structure from Laravel's design, which is object-oriented, fluent, and effective. 10 | 11 | Using this framework brings to your plugin projects the power of both the Laravel framework and its community—we think you're going to love what you discover there. 12 | 13 | We want to be able to build complex, custom applications on top of WordPress, and we think this is the best way forward. 14 | 15 | ## Features 16 | 17 | * Use Laravel to build WordPress plugins 18 | * Better organization for plugin files and folders 19 | * Fluent syntax for defining REST API routes and rewrite rules 20 | * Create custom post types, comment types, and taxonomies with inheritance 21 | * Make better use of third-party libraries via [Composer](https://getcomposer.org/) 22 | * Unit testing with PHPUnit and WP-CLI 23 | * Do more with WordPress, faster 24 | 25 | See a complete working example plugin in the [auth-plugin-wordpress repo](https://github.com/withfatpanda/auth-plugin-wordpress). 26 | 27 | ## Before You Get Started 28 | 29 | We've written a primer on Composer, Studio, and Bedrock. You can [read it here](https://withbamboo.com/articles/primer), along with [all of the documentation](https://withbamboo.com) on how to make the most of Bamboo. 30 | 31 | You don't *have* to read it to be able to jump in, but having a better understanding of these tools can't hurt. 32 | 33 | ## Starting a New Plugin Project 34 | 35 | 1. Install [Composer](https://getcomposer.org/doc/00-intro.md#installation-linux-unix-osx). 36 | 37 | 2. Install [Studio](https://github.com/franzliedke/studio). Studio is a utility that allows you to load Composer dependencies from your local filesystem, which in turn allows you to develop your plugins in context (installed and activated in WordPress): 38 | 39 | ``` 40 | composer global require franzl/studio your-plugin-name 41 | ``` 42 | 43 | 3. Use Composer to create a new Plugin project with Bamboo: 44 | 45 | ``` 46 | composer create-project withfatpanda/bamboo 47 | ``` 48 | 49 | 4. Modify your copy of `composer.json` to make your plugin your own (change these settings): 50 | 51 | ```json 52 | { 53 | "name": "your-namespace/your-plugin-name", 54 | "description": "A killer description for your Plugin" 55 | } 56 | ``` 57 | 58 | 5. Switch to your [Bedrock](https://roots.io/bedrock)-based WordPress installation, and use Studio to make Composer aware of your plugin: 59 | 60 | ``` 61 | studio load /path/to/your/plugin 62 | ``` 63 | 64 | 6. Run Composer to install your plugin into Bedrock as a dependency: 65 | 66 | ``` 67 | composer require your-namespace/your-plugin:"~1.0" 68 | ``` 69 | 70 | 7. Activate your plugin (especially easy if you're using WP-CLI): 71 | 72 | ``` 73 | wp plugin activate your-plugin-name 74 | ``` 75 | 76 | ## Folder Structure and Files 77 | 78 | 79 | 80 | ## How Do I Learn More? 81 | 82 | Read the [documentation](https://withbamboo.com). 83 | 84 | ## Before You Distribute Your Plugin 85 | 86 | Before you start distributing your plugin, you **must** make it your own by changing the default namespace and updating your Plugin's metadata. 87 | 88 | 1. Open your copy of `src/plugin.php` and establish a PHP namespace for your plugin: 89 | 90 | ```php 91 | namespace ChangeThisNamespace; // change this... 92 | 93 | class Plugin // ...don't change this. 94 | 95 | extends FatPanda\Illuminate\WordPress\Plugin { } 96 | 97 | ``` 98 | 99 | 2. Open your copy of `bootstrap.php` and update your Plugin's metadata: 100 | 101 | ```php 102 | /* 103 | Plugin Name: @@PLUGIN_NAME@@ 104 | Plugin URI: @@PLUGIN_URI@@ 105 | Description: @@PLUGIN_DESCRIPTION@@ 106 | Version: @@PLUGIN_VERSION@@ 107 | Author: @@PLUGIN_AUTHOR@@ 108 | Author URI: @@PLUGIN_AUTHOR_URI@@ 109 | License: @@PLUGIN_LICENSE@@ 110 | License URI: @@PLUGIN_LICENSE_URI@@ 111 | Text Domain: @@PLUGIN_TEXT_DOMAIN@@ 112 | Domain Path: /resources/lang 113 | */ 114 | ``` 115 | 116 | 3. Tell Composer to update your WordPress' autoloader—from the root of your WordPress installation: 117 | 118 | ``` 119 | composer dumpautoload 120 | wp plugin activate your-plugin-name 121 | ``` 122 | 123 | ## Distributing Your Plugin 124 | 125 | Coming soon. 126 | 127 | ## About This Project 128 | 129 | To learn more about the thinking behind this project, you can [read this blog post](https://www.aaroncollegeman.com/do-more-with-wordpress-faster/). 130 | 131 | Special gratitude goes out to the [Laravel](https://laravel.com) and [Bedrock](https://roots.io/bedrock) projects, without which I never would have had the foundation to make my dreams-in-code a reality. 132 | 133 | And of course, I can't forget to say thank you to the folks behind [WordPress](https://wordpress.org). 134 | 135 | You are all beautiful, and I :heart: you. 136 | 137 | ## About Fat Panda 138 | 139 | [Fat Panda](https://www.withfatpanda.com) is a software product consultancy located in Winchester, VA. We specialize in Laravel, WordPress, and Ionic. No matter where you are in the development of your product, we'll meet you there and work with you to propel you forward. 140 | 141 | ## Contributing 142 | 143 | If you run into a problem using this framework, please [open an issue](https://github.com/withfatpanda/workbench-wordpress/issues). 144 | 145 | If you want to help make this framework amazing, check out the [help wanted](https://github.com/withfatpanda/workbench-wordpress/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) list. 146 | 147 | If you'd like to support this and the other open source projects Fat Panda is building, please join our community of supporters on [Patreon](https://www.patreon.com/withfatpanda). 148 | 149 | -------------------------------------------------------------------------------- /resources/lang/en/validation.php: -------------------------------------------------------------------------------- 1 | 'The :attribute must be accepted.', 17 | 'active_url' => 'The :attribute is not a valid URL.', 18 | 'after' => 'The :attribute must be a date after :date.', 19 | 'alpha' => 'The :attribute may only contain letters.', 20 | 'alpha_dash' => 'The :attribute may only contain letters, numbers, and dashes.', 21 | 'alpha_num' => 'The :attribute may only contain letters and numbers.', 22 | 'array' => 'The :attribute must be an array.', 23 | 'before' => 'The :attribute must be a date before :date.', 24 | 'between' => [ 25 | 'numeric' => 'The :attribute must be between :min and :max.', 26 | 'file' => 'The :attribute must be between :min and :max kilobytes.', 27 | 'string' => 'The :attribute must be between :min and :max characters.', 28 | 'array' => 'The :attribute must have between :min and :max items.', 29 | ], 30 | 'boolean' => 'The :attribute field must be true or false.', 31 | 'confirmed' => 'The :attribute confirmation does not match.', 32 | 'date' => 'The :attribute is not a valid date.', 33 | 'date_format' => 'The :attribute does not match the format :format.', 34 | 'different' => 'The :attribute and :other must be different.', 35 | 'digits' => 'The :attribute must be :digits digits.', 36 | 'digits_between' => 'The :attribute must be between :min and :max digits.', 37 | 'dimensions' => 'The :attribute has invalid image dimensions.', 38 | 'distinct' => 'The :attribute field has a duplicate value.', 39 | 'email' => 'The :attribute must be a valid email address.', 40 | 'exists' => 'The selected :attribute is invalid.', 41 | 'file' => 'The :attribute must be a file.', 42 | 'filled' => 'The :attribute field is required.', 43 | 'image' => 'The :attribute must be an image.', 44 | 'in' => 'The selected :attribute is invalid.', 45 | 'in_array' => 'The :attribute field does not exist in :other.', 46 | 'integer' => 'The :attribute must be an integer.', 47 | 'ip' => 'The :attribute must be a valid IP address.', 48 | 'json' => 'The :attribute must be a valid JSON string.', 49 | 'max' => [ 50 | 'numeric' => 'The :attribute may not be greater than :max.', 51 | 'file' => 'The :attribute may not be greater than :max kilobytes.', 52 | 'string' => 'The :attribute may not be greater than :max characters.', 53 | 'array' => 'The :attribute may not have more than :max items.', 54 | ], 55 | 'mimes' => 'The :attribute must be a file of type: :values.', 56 | 'mimetypes' => 'The :attribute must be a file of type: :values.', 57 | 'min' => [ 58 | 'numeric' => 'The :attribute must be at least :min.', 59 | 'file' => 'The :attribute must be at least :min kilobytes.', 60 | 'string' => 'The :attribute must be at least :min characters.', 61 | 'array' => 'The :attribute must have at least :min items.', 62 | ], 63 | 'not_in' => 'The selected :attribute is invalid.', 64 | 'numeric' => 'The :attribute must be a number.', 65 | 'present' => 'The :attribute field must be present.', 66 | 'regex' => 'The :attribute format is invalid.', 67 | 'required' => 'The :attribute field is required.', 68 | 'required_if' => 'The :attribute field is required when :other is :value.', 69 | 'required_unless' => 'The :attribute field is required unless :other is in :values.', 70 | 'required_with' => 'The :attribute field is required when :values is present.', 71 | 'required_with_all' => 'The :attribute field is required when :values is present.', 72 | 'required_without' => 'The :attribute field is required when :values is not present.', 73 | 'required_without_all' => 'The :attribute field is required when none of :values are present.', 74 | 'same' => 'The :attribute and :other must match.', 75 | 'size' => [ 76 | 'numeric' => 'The :attribute must be :size.', 77 | 'file' => 'The :attribute must be :size kilobytes.', 78 | 'string' => 'The :attribute must be :size characters.', 79 | 'array' => 'The :attribute must contain :size items.', 80 | ], 81 | 'string' => 'The :attribute must be a string.', 82 | 'timezone' => 'The :attribute must be a valid zone.', 83 | 'unique' => 'The :attribute has already been taken.', 84 | 'uploaded' => 'The :attribute failed to upload.', 85 | 'url' => 'The :attribute format is invalid.', 86 | 87 | /* 88 | |-------------------------------------------------------------------------- 89 | | Custom Validation Language Lines 90 | |-------------------------------------------------------------------------- 91 | | 92 | | Here you may specify custom validation messages for attributes using the 93 | | convention "attribute.rule" to name the lines. This makes it quick to 94 | | specify a specific custom language line for a given attribute rule. 95 | | 96 | */ 97 | 98 | 'custom' => [ 99 | 'attribute-name' => [ 100 | 'rule-name' => 'custom-message', 101 | ], 102 | ], 103 | 104 | /* 105 | |-------------------------------------------------------------------------- 106 | | Custom Validation Attributes 107 | |-------------------------------------------------------------------------- 108 | | 109 | | The following language lines are used to swap attribute place-holders 110 | | with something more reader friendly such as E-Mail Address instead 111 | | of "email". This simply helps us make messages a little cleaner. 112 | | 113 | */ 114 | 115 | 'attributes' => [], 116 | 117 | ]; 118 | --------------------------------------------------------------------------------