├── .gitignore ├── .gitmodules ├── .travis.yml ├── .vscode ├── launch.json └── tasks.json ├── Laravel.AspNetCore ├── EnumerationExtensions.cs ├── Laravel.AspNetCore.csproj └── RequestDelegateExtension.cs ├── Laravel.ComposerDummy ├── composer.json ├── composer.lock └── generate.js ├── Laravel.Sdk ├── AssemblyInfo.cs ├── Laravel.Sdk.csproj ├── LaravelApp.cs ├── LaravelAppExtension.cs └── LaravelLoader.cs ├── Laravel.Tests ├── .gitignore ├── Laravel.Tests.msbuildproj ├── composer.json ├── composer.lock ├── main.php ├── patches │ ├── mockery_complex_arguments.patch │ ├── mockery_peachpie_issue_465_001.patch │ ├── mockery_peachpie_issue_465_002.patch │ ├── mockery_peachpie_issue_502_001.patch │ ├── mockery_require_fix_001.patch │ ├── phpunit_catch_system_exceptions.patch │ ├── phpunit_catch_system_exceptions_002.patch │ ├── phpunit_catch_system_exceptions_003.patch │ ├── phpunit_catch_system_exceptions_004.patch │ ├── phpunit_catch_system_exceptions_005.patch │ ├── phpunit_complex_arguments.patch │ ├── phpunit_empty_file.patch │ ├── phpunit_mock_001.patch │ ├── phpunit_mock_002.patch │ ├── phpunit_mock_003.patch │ ├── phpunit_null_get_file_exception.patch │ ├── phpunit_peachpie_issue_475_001.patch │ ├── phpunit_realpath_bug.patch │ ├── phpunit_test_listener_fix.patch │ └── phpunit_wrong_require_fix_001.patch ├── phpunit.xml └── tests_patches │ └── auth_fix_001.patch ├── Laravel ├── .gitignore ├── .phpunit.result.cache ├── LICENSE.md ├── Laravel.msbuildproj ├── README.md ├── bootstrap │ └── app.php ├── composer.json ├── composer.lock ├── dummy_files │ ├── dummy_browserkit.php │ ├── dummy_network.php │ ├── dummy_network_const.php │ ├── dummy_openssl.php │ └── dummy_peachpie.php ├── helpers.php ├── laravel_patches │ ├── blade_include_001.patch │ ├── exceptions_fix.patch │ ├── filesystem_require_001.patch │ ├── internal_app_start_001.patch │ ├── internal_app_start_002.patch │ ├── openssl_peachpie_issue_402_001.patch │ ├── password_methods_fix_001.patch │ ├── password_methods_fix_002.patch │ ├── request_create_workaround.patch │ ├── rescue_catch_system_exceptions.patch │ └── route_loader.patch ├── patches │ ├── aws_fix_001.patch │ ├── aws_fix_002.patch │ ├── aws_fix_003.patch │ ├── aws_fix_004.patch │ ├── aws_yield_exception_construct_001.patch │ ├── cookie_workaround.patch │ ├── event_dispatcher_001.patch │ └── superclosure_001.patch └── public │ └── index.php ├── app ├── BaseControllerNet.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── TestController.cs ├── app.csproj └── app.csproj.user ├── build ├── Settings.props ├── install_dependencies_ubuntu16.sh └── nuget.config ├── global.json ├── laravel-peachpie-sample.sln ├── readme.md └── website ├── .editorconfig ├── .env ├── .env.example ├── .gitattributes ├── .gitignore ├── _ide_helper.php ├── app ├── Activity.php ├── Console │ └── Kernel.php ├── Exceptions │ └── Handler.php ├── Http │ ├── Controllers │ │ ├── Auth │ │ │ ├── ForgotPasswordController.php │ │ │ ├── LoginController.php │ │ │ ├── RegisterController.php │ │ │ ├── ResetPasswordController.php │ │ │ └── VerificationController.php │ │ ├── Controller.php │ │ ├── HomeController.php │ │ ├── ProjectInvitationsController.php │ │ ├── ProjectTasksController.php │ │ └── ProjectsController.php │ ├── Kernel.php │ ├── Middleware │ │ ├── Authenticate.php │ │ ├── CheckForMaintenanceMode.php │ │ ├── EncryptCookies.php │ │ ├── RedirectIfAuthenticated.php │ │ ├── TrimStrings.php │ │ ├── TrustProxies.php │ │ └── VerifyCsrfToken.php │ └── Requests │ │ └── ProjectInvitationRequest.php ├── Policies │ └── ProjectPolicy.php ├── Project.php ├── Providers │ ├── AppServiceProvider.php │ ├── AuthServiceProvider.php │ ├── BroadcastServiceProvider.php │ ├── EventServiceProvider.php │ └── RouteServiceProvider.php ├── RecordsActivity.php ├── Task.php ├── User.php └── helpers.php ├── artisan ├── composer.json ├── composer.lock ├── config ├── app.php ├── auth.php ├── broadcasting.php ├── cache.php ├── database.php ├── debug-server.php ├── filesystems.php ├── hashing.php ├── logging.php ├── mail.php ├── queue.php ├── services.php ├── session.php ├── tinker.php ├── trustedproxy.php └── view.php ├── database ├── .gitignore ├── factories │ ├── ProjectFactory.php │ ├── TaskFactory.php │ └── UserFactory.php ├── migrations │ ├── 2014_10_12_000000_create_users_table.php │ ├── 2014_10_12_100000_create_password_resets_table.php │ ├── 2018_12_17_150648_create_projects_table.php │ ├── 2019_01_12_191142_create_tasks_table.php │ ├── 2019_01_24_143508_create_activities_table.php │ └── 2019_02_27_181525_create_project_members_table.php └── seeds │ └── DatabaseSeeder.php ├── package-lock.json ├── package.json ├── phpunit.xml ├── public ├── .DS_Store ├── .htaccess ├── favicon.ico ├── mix-manifest.json ├── robots.txt └── svg │ ├── 403.svg │ ├── 404.svg │ ├── 500.svg │ └── 503.svg ├── resources ├── js │ ├── app.js │ ├── bootstrap.js │ └── components │ │ └── ThemeSwitcher.vue ├── lang │ └── en │ │ ├── auth.php │ │ ├── pagination.php │ │ ├── passwords.php │ │ └── validation.php ├── sass │ ├── app.scss │ ├── components │ │ ├── button.scss │ │ └── card.scss │ └── themes │ │ ├── dark.scss │ │ └── light.scss └── views │ ├── auth │ ├── login.blade.php │ ├── passwords │ │ ├── email.blade.php │ │ └── reset.blade.php │ ├── register.blade.php │ └── verify.blade.php │ ├── errors.blade.php │ ├── errors │ ├── 401.blade.php │ ├── 403.blade.php │ ├── 404.blade.php │ ├── 419.blade.php │ ├── 429.blade.php │ ├── 500.blade.php │ ├── 503.blade.php │ ├── illustrated-layout.blade.php │ ├── layout.blade.php │ └── minimal.blade.php │ ├── home.blade.php │ ├── layouts │ └── app.blade.php │ ├── projects │ ├── activity │ │ ├── card.blade.php │ │ ├── completed_task.blade.php │ │ ├── created_project.blade.php │ │ ├── created_task.blade.php │ │ ├── incompleted_task.blade.php │ │ └── updated_project.blade.php │ ├── card.blade.php │ ├── create.blade.php │ ├── edit.blade.php │ ├── form.blade.php │ ├── index.blade.php │ ├── invite.blade.php │ └── show.blade.php │ ├── vendor │ ├── mail │ │ ├── html │ │ │ ├── button.blade.php │ │ │ ├── footer.blade.php │ │ │ ├── header.blade.php │ │ │ ├── layout.blade.php │ │ │ ├── message.blade.php │ │ │ ├── panel.blade.php │ │ │ ├── promotion.blade.php │ │ │ ├── promotion │ │ │ │ └── button.blade.php │ │ │ ├── subcopy.blade.php │ │ │ ├── table.blade.php │ │ │ └── themes │ │ │ │ └── default.css │ │ └── text │ │ │ ├── button.blade.php │ │ │ ├── footer.blade.php │ │ │ ├── header.blade.php │ │ │ ├── layout.blade.php │ │ │ ├── message.blade.php │ │ │ ├── panel.blade.php │ │ │ ├── promotion.blade.php │ │ │ ├── promotion │ │ │ └── button.blade.php │ │ │ ├── subcopy.blade.php │ │ │ └── table.blade.php │ ├── notifications │ │ └── email.blade.php │ └── pagination │ │ ├── bootstrap-4.blade.php │ │ ├── default.blade.php │ │ ├── semantic-ui.blade.php │ │ ├── simple-bootstrap-4.blade.php │ │ └── simple-default.blade.php │ └── welcome.blade.php ├── routes ├── api.php ├── channels.php ├── console.php └── web.php ├── tailwind.js ├── webpack.mix.js └── website.msbuildproj /.gitignore: -------------------------------------------------------------------------------- 1 | website/bin 2 | website/obj 3 | website/node_modules 4 | website/vendor 5 | website/public/js 6 | website/public/css 7 | app/bin 8 | app/obj 9 | Laravel/bin 10 | Laravel/obj 11 | Laravel/tests 12 | Laravel/storage 13 | Laravel.Sdk/bin 14 | Laravel.Sdk/obj 15 | Laravel.AspNetCore/bin 16 | Laravel.AspNetCore/obj 17 | Laravel.Tests/bin 18 | Laravel.Tests/obj 19 | Laravel.Tests/vendor 20 | Laravel.Tests/.phpunit.result.cache 21 | .vs 22 | website/mix-manifest.json 23 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "third-party/framework"] 2 | path = third-party/framework 3 | url = https://github.com/laravel/framework.git 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | dist: xenial 3 | language: php 4 | php: 5 | - '7.3' 6 | 7 | install: 8 | - ./build/install_dependencies_ubuntu16.sh 9 | - git clone https://github.com/peachpiecompiler/peachpie.git third-party/peachpie 10 | - cd ./third-party/peachpie 11 | - dotnet msbuild /t:restore "./Peachpie.sln" /v:m /p:Version=1.0.0-dev,Configuration=Release 12 | - dotnet restore "./src/Peachpie.NET.Sdk" /v:m /p:Version=1.0.0-dev,Configuration=Release 13 | - dotnet msbuild /t:build "./Peachpie.sln" /v:m /p:Version=1.0.0-dev,Configuration=Release || true 14 | - dotnet build ./src/Peachpie.Library.Scripting/ /p:Version=1.0.0-dev,Configuration=Release,TargetFrameworks=netstandard2.0 15 | - cd .nugs 16 | - rm -rf ~/.nuget/NuGet/NuGet.Config 17 | - sed "s~PEACHPIE~`pwd`~g" ../../../build/nuget.config > ~/.nuget/NuGet/NuGet.Config 18 | - nuget sources -configfile ~/.nuget/NuGet/NuGet.Config 19 | - cd ../../../ 20 | - dotnet nuget locals all --clear 21 | - dotnet restore ./Laravel/Laravel.msbuildproj 22 | - dotnet restore ./Laravel.Sdk/Laravel.Sdk.csproj 23 | - dotnet restore ./Laravel.Tests/Laravel.Tests.msbuildproj 24 | - cd ./Laravel 25 | - composer install 26 | - cd ../Laravel.Tests 27 | - composer install 28 | - cd ../ 29 | - dotnet build ./Laravel.Sdk/ 30 | - dotnet build ./Laravel/ 31 | - dotnet build ./Laravel.Tests/ 32 | 33 | script: 34 | - cd Laravel.Tests 35 | - dotnet run 36 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": ".NET Core Launch (App)", 6 | "type": "coreclr", 7 | "request": "launch", 8 | "preLaunchTask": "buildapp", 9 | "program": "${workspaceRoot}/app/bin/Debug/netcoreapp2.1/app.dll", 10 | "args": [], 11 | "cwd": "${workspaceRoot}/app/bin/Debug/netcoreapp2.1", 12 | "stopAtEntry": false, 13 | "justMyCode": false 14 | }, 15 | { 16 | "name": ".NET Core Launch (Tests)", 17 | "type": "coreclr", 18 | "request": "launch", 19 | "preLaunchTask": "buildtests", 20 | "program": "${workspaceRoot}/Laravel.Tests/bin/Debug/netcoreapp2.1/Laravel.Tests.dll", 21 | "args": [], 22 | "cwd": "${workspaceRoot}/Laravel.Tests", 23 | "stopAtEntry": false, 24 | "justMyCode": false, 25 | "externalConsole": false 26 | }, 27 | { 28 | "name": ".NET Core Attach", 29 | "type": "coreclr", 30 | "request": "attach", 31 | "processId": "${command:pickProcess}" 32 | } 33 | ] 34 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "cleanapp", 6 | "command": "dotnet", 7 | "type": "process", 8 | "args": [ 9 | "clean", 10 | "${workspaceFolder}/app/app.csproj" 11 | ], 12 | "problemMatcher": "$msCompile" 13 | }, 14 | { 15 | "label": "buildapp", 16 | "command": "dotnet", 17 | "type": "process", 18 | "args": [ 19 | "build", 20 | "${workspaceFolder}/app/app.csproj" 21 | ], 22 | "problemMatcher": "$msCompile" 23 | }, 24 | { 25 | "label": "cleantests", 26 | "command": "dotnet", 27 | "type": "process", 28 | "args": [ 29 | "clean", 30 | "${workspaceFolder}/Laravel.Tests/Laravel.Tests.msbuildproj" 31 | ], 32 | "problemMatcher": "$msCompile" 33 | }, 34 | { 35 | "label": "buildtests", 36 | "command": "dotnet", 37 | "type": "process", 38 | "args": [ 39 | "build", 40 | "${workspaceFolder}/Laravel.Tests/Laravel.Tests.msbuildproj" 41 | ], 42 | "problemMatcher": "$msCompile" 43 | } 44 | ] 45 | } -------------------------------------------------------------------------------- /Laravel.AspNetCore/EnumerationExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | // copied from https://github.com/iolevel/wpdotnet-sdk/blob/master/PeachPied.WordPress.AspNetCore/Internal/EnumerationExtensions.cs 8 | namespace Laravel.AspNetCore.Internal 9 | { 10 | internal static class EnumerationExtensions 11 | { 12 | /// 13 | /// Gets value indicating whether the enumeration is null or empty for sure. 14 | /// 15 | public static bool IsEmpty(this IEnumerable collection) 16 | { 17 | return collection == null || ((collection is ICollection col) && col.Count == 0); 18 | } 19 | 20 | /// 21 | /// Safely concatenates two enumerations. They both can be null. 22 | /// The method always returns non-null object. 23 | /// 24 | public static IEnumerable/*!*/ConcatSafe(this IEnumerable collection1, IEnumerable collection2) 25 | { 26 | if (IsEmpty(collection2)) 27 | { 28 | return collection1 ?? Array.Empty(); 29 | } 30 | 31 | if (IsEmpty(collection1)) 32 | { 33 | return collection2; 34 | } 35 | 36 | // 37 | return collection1.Concat(collection2); 38 | } 39 | 40 | /// 41 | /// Creates array with concatenation of given item and an enumeration. 42 | /// 43 | public static T[]/*!*/ArrayConcat(this T item, IEnumerable enumeration) 44 | { 45 | if (IsEmpty(enumeration)) 46 | { 47 | return new[] { item }; 48 | } 49 | 50 | // 51 | T[] result; 52 | 53 | if (enumeration is ICollection collection) 54 | { 55 | result = new T[1 + collection.Count]; 56 | result[0] = item; 57 | collection.CopyTo(result, 1); 58 | } 59 | else 60 | { 61 | var list = new List() { item }; 62 | list.AddRange(enumeration); 63 | result = list.ToArray(); 64 | } 65 | 66 | // 67 | return result; 68 | } 69 | } 70 | 71 | } -------------------------------------------------------------------------------- /Laravel.AspNetCore/Laravel.AspNetCore.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | netstandard2.0 6 | $(LaravelVersion) 7 | $(LaravelVersion) 8 | 9 | 10 | 11 | 12 | None 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Laravel.ComposerDummy/composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "fb09be64b2db5593b463ac73455243a1", 8 | "packages": [], 9 | "packages-dev": [], 10 | "aliases": [], 11 | "minimum-stability": "stable", 12 | "stability-flags": [], 13 | "prefer-stable": false, 14 | "prefer-lowest": false, 15 | "platform": { 16 | "php": "^7.2" 17 | }, 18 | "platform-dev": [] 19 | } 20 | -------------------------------------------------------------------------------- /Laravel.ComposerDummy/generate.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const data = fs.readFileSync("../Laravel/composer.lock", { "encoding": "utf-8" }); 3 | const json = JSON.parse(data); 4 | 5 | const set1 = JSON.parse("{" + json.packages.map(item => `"${item.name}": "${item.version}"`).join(",\r\n") + "}"); 6 | 7 | const laravelData = fs.readFileSync("../third-party/framework/composer.json"); 8 | const laravelJson = JSON.parse(laravelData); 9 | 10 | const set2 = laravelJson.replace; 11 | 12 | for (const key in set2) { 13 | if (set2[key] == "self.version") { 14 | set2[key] = "v6.14.0"; 15 | } 16 | 17 | set1[key] = set2[key]; 18 | } 19 | 20 | set1["laravel/framework"] = "v6.14.0"; 21 | 22 | console.log(JSON.stringify(set1, null, 4)); -------------------------------------------------------------------------------- /Laravel.Sdk/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using Pchp.Core; 2 | 3 | // denotates the assembly contains PeachPie extensions: 4 | // global constants and global functions 5 | // https://docs.peachpie.io/api/Libraries-Architecture/ 6 | [assembly: PhpExtension] -------------------------------------------------------------------------------- /Laravel.Sdk/Laravel.Sdk.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | netstandard2.0 6 | $(LaravelVersion) 7 | $(LaravelVersion) 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Laravel.Sdk/LaravelApp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Pchp.Core; 3 | 4 | namespace Laravel.Sdk 5 | { 6 | [PhpType] 7 | public abstract class LaravelApp 8 | { 9 | /// 10 | /// Minimal constructor that initializes runtime context. 11 | /// The .ctor is called implicitly by derived PHP class. 12 | /// 13 | protected LaravelApp(Context ctx) 14 | { 15 | _ctx = ctx; 16 | } 17 | 18 | /// 19 | /// Runtime context of the application. 20 | /// 21 | public Context Context => _ctx; 22 | 23 | /// 24 | /// Runtime context of the application. 25 | /// Special signature recognized by the compiler. 26 | /// 27 | protected readonly Context _ctx; 28 | 29 | public abstract string GetVersion(); 30 | 31 | public abstract void InternalRegisterController(PhpValue controller); 32 | 33 | public abstract void InternalSetUserModel(PhpValue model); 34 | } 35 | } -------------------------------------------------------------------------------- /Laravel.Sdk/LaravelAppExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | using Pchp.Core; 6 | 7 | namespace Laravel.Sdk 8 | { 9 | /// 10 | /// Provides extension functions to instances. 11 | /// 12 | [PhpHidden] 13 | public static class LaravelAppExtension 14 | { 15 | } 16 | } -------------------------------------------------------------------------------- /Laravel.Sdk/LaravelLoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Laravel.Sdk 6 | { 7 | /// 8 | /// Object used to be called from Laravel code, 9 | /// instantiated into a global PHP variable $peachpie_laravel_loader. 10 | /// 11 | public class LaravelLoader 12 | { 13 | public delegate void AppStartedDelegate(LaravelApp app); 14 | public static AppStartedDelegate AppStarted; 15 | 16 | /// 17 | /// Invoked by PHP plugin implementation (peachpie-api.php) to bridge into .NET. 18 | /// 19 | public virtual void InternalAppStarted(LaravelApp app) 20 | { 21 | if (LaravelLoader.AppStarted != null) 22 | { 23 | LaravelLoader.AppStarted(app); 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Laravel.Tests/.gitignore: -------------------------------------------------------------------------------- 1 | tests 2 | src -------------------------------------------------------------------------------- /Laravel.Tests/Laravel.Tests.msbuildproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | exe 6 | netcoreapp3.0 7 | $(LaravelVersion) 8 | $(LaravelVersion) 9 | PHP0125,PHP5011,PHP5008,PHP5006,PHP5014,PHP5015,PHP5026,PHP5028,PHP5025,PHP5007,PHP5022,PHP5018,PHP5012 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Laravel.Tests/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Laravel.Tests", 3 | "repositories": [ 4 | { 5 | "type": "path", 6 | "url": "../Laravel.ComposerDummy" 7 | } 8 | ], 9 | "require": { 10 | "calvinbaart/laravel-sdk": "*", 11 | "phpunit/phpunit": "^8.3", 12 | "mockery/mockery": "^1.2.3", 13 | "orchestra/testbench": "^4.0" 14 | }, 15 | "autoload": { 16 | "psr-4": { 17 | "Illuminate\\Foundation\\Testing\\": "src/Illuminate/Foundation/Testing", 18 | "Illuminate\\Support\\Testing\\": "src/Illuminate/Support/Testing", 19 | "Illuminate\\Http\\Testing\\": "src/Illuminate/Http/Testing", 20 | "Illuminate\\Tests\\": "tests" 21 | } 22 | }, 23 | "scripts": { 24 | "pre-install-cmd": [ 25 | "rm -rf tests", 26 | "rm -rf src", 27 | "cp -rf ../third-party/framework/tests .", 28 | "cp -rf ../third-party/framework/src src", 29 | "find tests_patches -type f -name '*.patch' -print0 | sort -z | xargs -t -0 -n 1 patch -p0 -i" 30 | ], 31 | "post-install-cmd": [ 32 | "find patches -type f -name '*.patch' -print0 | sort -z | xargs -t -0 -n 1 patch -p0 -i" 33 | ] 34 | }, 35 | "minimum-stability": "dev", 36 | "prefer-stable": true 37 | } 38 | -------------------------------------------------------------------------------- /Laravel.Tests/main.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | if (!defined("PEACHPIE_VERSION")) { 13 | require_once(__DIR__ . "/../Laravel/vendor/laravel_autoload.php"); 14 | } else { 15 | require_once(__DIR__ . "/vendor/laravel_autoload.php"); 16 | } 17 | 18 | require_once(__DIR__ . "/vendor/autoload.php"); 19 | 20 | if (!ini_get('date.timezone')) { 21 | ini_set('date.timezone', 'UTC'); 22 | } 23 | 24 | $options = getopt('', array('prepend:')); 25 | if (isset($options['prepend'])) { 26 | require $options['prepend']; 27 | } 28 | unset($options); 29 | 30 | PHPUnit\TextUI\Command::main(); -------------------------------------------------------------------------------- /Laravel.Tests/patches/mockery_complex_arguments.patch: -------------------------------------------------------------------------------- 1 | --- vendor/mockery/mockery/library/Mockery/Generator/Parameter.php 2019-08-07 17:01:07.000000000 +0200 2 | +++ vendor/mockery/mockery/library/Mockery/Generator/Parameter.php 2019-08-17 22:24:32.000000000 +0200 3 | @@ -91,10 +91,7 @@ 4 | */ 5 | public function getName() 6 | { 7 | - $name = $this->rfp->getName(); 8 | - if (!$name || $name == '...') { 9 | - $name = 'arg' . static::$parameterCounter++; 10 | - } 11 | + $name = 'arg' . static::$parameterCounter++; 12 | 13 | return $name; 14 | } 15 | -------------------------------------------------------------------------------- /Laravel.Tests/patches/mockery_peachpie_issue_465_001.patch: -------------------------------------------------------------------------------- 1 | --- vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/MockeryPHPUnitIntegration.php 2019-08-15 17:25:12.000000000 +0200 2 | +++ vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/MockeryPHPUnitIntegration.php 2019-08-15 17:24:59.000000000 +0200 3 | @@ -34,7 +34,7 @@ 4 | */ 5 | trait MockeryPHPUnitIntegration 6 | { 7 | - use MockeryPHPUnitIntegrationAssertPostConditions; 8 | + use MockeryPHPUnitIntegrationAssertPostConditionsForV8; 9 | 10 | protected $mockeryOpen; 11 | 12 | -------------------------------------------------------------------------------- /Laravel.Tests/patches/mockery_peachpie_issue_465_002.patch: -------------------------------------------------------------------------------- 1 | --- vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/MockeryTestCase.php 2019-08-15 17:19:44.000000000 +0200 2 | +++ vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/MockeryTestCase.php 2019-08-15 17:26:41.000000000 +0200 3 | @@ -27,7 +27,7 @@ 4 | } 5 | abstract class MockeryTestCase extends \PHPUnit\Framework\TestCase 6 | { 7 | - use MockeryPHPUnitIntegration, MockeryTestCaseSetUp; 8 | + use MockeryPHPUnitIntegration, MockeryTestCaseSetUpForV8; 9 | 10 | protected function mockeryTestSetUp() 11 | { 12 | -------------------------------------------------------------------------------- /Laravel.Tests/patches/mockery_peachpie_issue_502_001.patch: -------------------------------------------------------------------------------- 1 | --- vendor/mockery/mockery/library/Mockery/Mock.php 2019-08-25 15:11:41.866967300 +0200 2 | +++ vendor/mockery/mockery/library/Mockery/Mock2.php 2019-08-25 21:30:52.303748200 +0200 3 | @@ -725,8 +725,7 @@ 4 | 5 | case 'Traversable': 6 | case 'Generator': 7 | - // Remove eval() when minimum version >=5.5 8 | - $generator = eval('return function () { yield; };'); 9 | + $generator = function () { yield; }; 10 | return $generator(); 11 | 12 | case 'self': 13 | -------------------------------------------------------------------------------- /Laravel.Tests/patches/mockery_require_fix_001.patch: -------------------------------------------------------------------------------- 1 | --- vendor/mockery/mockery/library/Mockery.php 2019-08-25 23:37:50.719230000 +0200 2 | +++ vendor/mockery/mockery/library/Mockery2.php 2019-08-25 23:37:42.195000000 +0200 3 | @@ -931,15 +931,17 @@ 4 | 5 | $targetCode.= "$type $shortName {} "; 6 | 7 | + eval("?>" . $targetCode); 8 | + 9 | /* 10 | * We could eval here, but it doesn't play well with the way 11 | * PHPUnit tries to backup global state and the require definition 12 | * loader 13 | */ 14 | - $tmpfname = tempnam(sys_get_temp_dir(), "Mockery"); 15 | - file_put_contents($tmpfname, $targetCode); 16 | - require $tmpfname; 17 | - \Mockery::registerFileForCleanUp($tmpfname); 18 | + // $tmpfname = tempnam(sys_get_temp_dir(), "Mockery"); 19 | + // file_put_contents($tmpfname, $targetCode); 20 | + // require $tmpfname; 21 | + // \Mockery::registerFileForCleanUp($tmpfname); 22 | } 23 | 24 | /** 25 | -------------------------------------------------------------------------------- /Laravel.Tests/patches/phpunit_catch_system_exceptions_002.patch: -------------------------------------------------------------------------------- 1 | --- vendor/phpunit/phpunit/src/Framework/TestSuite.php 2019-08-19 23:00:32.000000000 +0200 2 | +++ vendor/phpunit/phpunit/src/Framework/TestSuite2.php 2019-08-19 23:01:26.000000000 +0200 3 | @@ -551,6 +551,22 @@ 4 | $result->endTestSuite($this); 5 | 6 | return $result; 7 | + } catch (\System\Exception $ex) { 8 | + $t = new WrappedException($ex); 9 | + 10 | + foreach ($this->tests() as $test) { 11 | + if ($result->shouldStop()) { 12 | + break; 13 | + } 14 | + 15 | + $result->startTest($test); 16 | + $result->addError($test, $t, 0); 17 | + $result->endTest($test, 0); 18 | + } 19 | + 20 | + $result->endTestSuite($this); 21 | + 22 | + return $result; 23 | } 24 | 25 | foreach ($this as $test) { 26 | @@ -586,6 +602,18 @@ 27 | $result->startTest($placeholderTest); 28 | $result->addFailure($placeholderTest, $error, 0); 29 | $result->endTest($placeholderTest, 0); 30 | + } catch (\System\Exception $ex) { 31 | + $t = new WrappedException($ex); 32 | + 33 | + $message = "Exception in {$this->name}::$afterClassMethod" . \PHP_EOL . $t->getMessage(); 34 | + $error = new SyntheticError($message, 0, $t->getFile(), $t->getLine(), $t->getTrace()); 35 | + 36 | + $placeholderTest = clone $test; 37 | + $placeholderTest->setName($afterClassMethod); 38 | + 39 | + $result->startTest($placeholderTest); 40 | + $result->addFailure($placeholderTest, $error, 0); 41 | + $result->endTest($placeholderTest, 0); 42 | } 43 | 44 | $result->endTestSuite($this); 45 | -------------------------------------------------------------------------------- /Laravel.Tests/patches/phpunit_catch_system_exceptions_003.patch: -------------------------------------------------------------------------------- 1 | --- vendor/phpunit/phpunit/src/Framework/TestBuilder.php 2019-08-11 08:56:55.000000000 +0200 2 | +++ vendor/phpunit/phpunit/src/Framework/TestBuilder2.php 2019-08-19 23:02:55.000000000 +0200 3 | @@ -88,6 +88,16 @@ 4 | ); 5 | $message = $this->appendExceptionMessageIfAvailable($t, $message); 6 | $data = new WarningTestCase($message); 7 | + } catch (\System\Exception $ex) { 8 | + $t = new WrappedException($ex); 9 | + 10 | + $message = \sprintf( 11 | + 'The data provider specified for %s::%s is invalid.', 12 | + $className, 13 | + $methodName 14 | + ); 15 | + $message = $this->appendExceptionMessageIfAvailable($t, $message); 16 | + $data = new WarningTestCase($message); 17 | } 18 | 19 | // Test method with @dataProvider. 20 | -------------------------------------------------------------------------------- /Laravel.Tests/patches/phpunit_catch_system_exceptions_004.patch: -------------------------------------------------------------------------------- 1 | --- vendor/phpunit/phpunit/src/Framework/TestCase.php 2019-08-19 22:54:20.000000000 +0200 2 | +++ vendor/phpunit/phpunit/src/Framework/TestCase2.php 2019-08-19 23:04:31.000000000 +0200 3 | @@ -1965,7 +1965,7 @@ 4 | if ($this->prophet !== null) { 5 | try { 6 | $this->prophet->checkPredictions(); 7 | - } catch (\Throwable $t) { 8 | + } catch (\System\Exception $t) { 9 | /* Intentionally left empty */ 10 | } 11 | 12 | -------------------------------------------------------------------------------- /Laravel.Tests/patches/phpunit_catch_system_exceptions_005.patch: -------------------------------------------------------------------------------- 1 | --- vendor/phpunit/phpunit/src/Util/Type.php 2019-08-11 08:56:55.000000000 +0200 2 | +++ vendor/phpunit/phpunit/src/Util/Type2.php 2019-08-19 23:05:52.000000000 +0200 3 | @@ -41,7 +41,7 @@ 4 | { 5 | try { 6 | $clone = clone $object; 7 | - } catch (\Throwable $t) { 8 | + } catch (\System\Exception $t) { 9 | return false; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /Laravel.Tests/patches/phpunit_complex_arguments.patch: -------------------------------------------------------------------------------- 1 | --- vendor/phpunit/phpunit/src/Framework/MockObject/MockMethod.php 2019-08-11 08:56:55.000000000 +0200 2 | +++ vendor/phpunit/phpunit/src/Framework/MockObject/MockMethod2.php 2019-08-17 22:32:14.000000000 +0200 3 | @@ -249,14 +249,7 @@ 4 | $parameters = []; 5 | 6 | foreach ($method->getParameters() as $i => $parameter) { 7 | - $name = '$' . $parameter->getName(); 8 | - 9 | - /* Note: PHP extensions may use empty names for reference arguments 10 | - * or "..." for methods taking a variable number of arguments. 11 | - */ 12 | - if ($name === '$' || $name === '$...') { 13 | - $name = '$arg' . $i; 14 | - } 15 | + $name = '$arg' . $i; 16 | 17 | if ($parameter->isVariadic()) { 18 | if ($forCall) { 19 | -------------------------------------------------------------------------------- /Laravel.Tests/patches/phpunit_empty_file.patch: -------------------------------------------------------------------------------- 1 | --- vendor/phpunit/php-file-iterator/src/Facade.php 2019-08-18 22:13:29.000000000 +0200 2 | +++ vendor/phpunit/php-file-iterator/src/Facade2.php 2019-08-18 22:14:38.000000000 +0200 3 | @@ -34,6 +34,10 @@ 4 | $files = []; 5 | 6 | foreach ($iterator as $file) { 7 | + if (empty($file)) { 8 | + continue; 9 | + } 10 | + 11 | $file = $file->getRealPath(); 12 | 13 | if ($file) { 14 | -------------------------------------------------------------------------------- /Laravel.Tests/patches/phpunit_mock_001.patch: -------------------------------------------------------------------------------- 1 | --- vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_class.tpl 2019-08-11 08:56:55.000000000 +0200 2 | +++ vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_class2.tpl 2019-08-20 14:24:56.000000000 +0200 3 | @@ -1,5 +1,3 @@ 4 | -declare(strict_types=1); 5 | - 6 | {prologue}{class_declaration} 7 | { 8 | use \PHPUnit\Framework\MockObject\Api;{method}{clone} 9 | -------------------------------------------------------------------------------- /Laravel.Tests/patches/phpunit_mock_002.patch: -------------------------------------------------------------------------------- 1 | --- vendor/phpunit/phpunit/src/Framework/MockObject/Generator/trait_class.tpl 2019-08-11 08:56:55.000000000 +0200 2 | +++ vendor/phpunit/phpunit/src/Framework/MockObject/Generator/trait_class2.tpl 2019-08-20 14:25:14.000000000 +0200 3 | @@ -1,5 +1,3 @@ 4 | -declare(strict_types=1); 5 | - 6 | {prologue}class {class_name} 7 | { 8 | use {trait_name}; 9 | -------------------------------------------------------------------------------- /Laravel.Tests/patches/phpunit_mock_003.patch: -------------------------------------------------------------------------------- 1 | --- vendor/phpunit/phpunit/src/Framework/MockObject/Generator/wsdl_class.tpl 2019-08-11 08:56:55.000000000 +0200 2 | +++ vendor/phpunit/phpunit/src/Framework/MockObject/Generator/wsdl_class2.tpl 2019-08-20 14:25:28.000000000 +0200 3 | @@ -1,5 +1,3 @@ 4 | -declare(strict_types=1); 5 | - 6 | {namespace}class {class_name} extends \SoapClient 7 | { 8 | public function __construct($wsdl, array $options) 9 | -------------------------------------------------------------------------------- /Laravel.Tests/patches/phpunit_null_get_file_exception.patch: -------------------------------------------------------------------------------- 1 | --- vendor/phpunit/phpunit/src/Util/Filter.php 2019-08-17 18:45:15.000000000 +0200 2 | +++ vendor/phpunit/phpunit/src/Util/Filter.php 2019-08-17 18:45:36.000000000 +0200 3 | @@ -33,11 +33,11 @@ 4 | 5 | if ($t instanceof SyntheticError) { 6 | $eTrace = $t->getSyntheticTrace(); 7 | - $eFile = $t->getSyntheticFile(); 8 | + $eFile = $t->getSyntheticFile() ?? "__unknown"; 9 | $eLine = $t->getSyntheticLine(); 10 | } elseif ($t instanceof Exception) { 11 | $eTrace = $t->getSerializableTrace(); 12 | - $eFile = $t->getFile(); 13 | + $eFile = $t->getFile() ?? "__unknown"; 14 | $eLine = $t->getLine(); 15 | } else { 16 | if ($t->getPrevious()) { 17 | @@ -45,7 +45,7 @@ 18 | } 19 | 20 | $eTrace = $t->getTrace(); 21 | - $eFile = $t->getFile(); 22 | + $eFile = $t->getFile() ?? "__unknown"; 23 | $eLine = $t->getLine(); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /Laravel.Tests/patches/phpunit_peachpie_issue_475_001.patch: -------------------------------------------------------------------------------- 1 | --- vendor/phpunit/phpunit/src/Util/RegularExpression.php 2019-08-17 20:37:21.000000000 +0200 2 | +++ vendor/phpunit/phpunit/src/Util/RegularExpression.php 2019-08-17 20:37:17.000000000 +0200 3 | @@ -21,7 +21,11 @@ 4 | { 5 | return ErrorHandler::invokeIgnoringWarnings( 6 | static function () use ($pattern, $subject, $matches, $flags, $offset) { 7 | - return \preg_match($pattern, $subject, $matches, $flags, $offset); 8 | + try { 9 | + return \preg_match($pattern, $subject, $matches, $flags, $offset); 10 | + } catch (\System\Exception $e) { 11 | + return false; 12 | + } 13 | } 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /Laravel.Tests/patches/phpunit_realpath_bug.patch: -------------------------------------------------------------------------------- 1 | --- vendor/phpunit/php-file-iterator/src/Factory.php 2019-08-18 22:15:34.000000000 +0200 2 | +++ vendor/phpunit/php-file-iterator/src/Factory2.php 2019-08-18 22:16:14.000000000 +0200 3 | @@ -72,9 +72,9 @@ 4 | 5 | foreach ($paths as $path) { 6 | if ($locals = \glob($path, GLOB_ONLYDIR)) { 7 | - $_paths = \array_merge($_paths, \array_map('\realpath', $locals)); 8 | + $_paths = \array_merge($_paths, $locals); 9 | } else { 10 | - $_paths[] = \realpath($path); 11 | + $_paths[] = $path; 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /Laravel.Tests/patches/phpunit_test_listener_fix.patch: -------------------------------------------------------------------------------- 1 | --- vendor/phpunit/phpunit/src/Runner/Hook/TestListenerAdapter.php 2019-08-20 01:32:05.000000000 +0200 2 | +++ vendor/phpunit/phpunit/src/Runner/Hook/TestListenerAdapter2.php 2019-08-20 01:32:09.000000000 +0200 3 | @@ -51,7 +51,7 @@ 4 | { 5 | foreach ($this->hooks as $hook) { 6 | if ($hook instanceof AfterTestErrorHook) { 7 | - $hook->executeAfterTestError(TestUtil::describeAsString($test), $t->getMessage(), $time); 8 | + $hook->executeAfterTestError(TestUtil::describeAsString($test), $t->getMessage() ?? "__unknown", $time); 9 | } 10 | } 11 | 12 | @@ -62,7 +62,7 @@ 13 | { 14 | foreach ($this->hooks as $hook) { 15 | if ($hook instanceof AfterTestWarningHook) { 16 | - $hook->executeAfterTestWarning(TestUtil::describeAsString($test), $e->getMessage(), $time); 17 | + $hook->executeAfterTestWarning(TestUtil::describeAsString($test), $e->getMessage() ?? "__unknown", $time); 18 | } 19 | } 20 | 21 | @@ -73,7 +73,7 @@ 22 | { 23 | foreach ($this->hooks as $hook) { 24 | if ($hook instanceof AfterTestFailureHook) { 25 | - $hook->executeAfterTestFailure(TestUtil::describeAsString($test), $e->getMessage(), $time); 26 | + $hook->executeAfterTestFailure(TestUtil::describeAsString($test), $e->getMessage() ?? "__unknown", $time); 27 | } 28 | } 29 | 30 | @@ -84,7 +84,7 @@ 31 | { 32 | foreach ($this->hooks as $hook) { 33 | if ($hook instanceof AfterIncompleteTestHook) { 34 | - $hook->executeAfterIncompleteTest(TestUtil::describeAsString($test), $t->getMessage(), $time); 35 | + $hook->executeAfterIncompleteTest(TestUtil::describeAsString($test), $t->getMessage() ?? "__unknown", $time); 36 | } 37 | } 38 | 39 | @@ -95,7 +95,7 @@ 40 | { 41 | foreach ($this->hooks as $hook) { 42 | if ($hook instanceof AfterRiskyTestHook) { 43 | - $hook->executeAfterRiskyTest(TestUtil::describeAsString($test), $t->getMessage(), $time); 44 | + $hook->executeAfterRiskyTest(TestUtil::describeAsString($test), $t->getMessage() ?? "__unknown", $time); 45 | } 46 | } 47 | 48 | @@ -106,7 +106,7 @@ 49 | { 50 | foreach ($this->hooks as $hook) { 51 | if ($hook instanceof AfterSkippedTestHook) { 52 | - $hook->executeAfterSkippedTest(TestUtil::describeAsString($test), $t->getMessage(), $time); 53 | + $hook->executeAfterSkippedTest(TestUtil::describeAsString($test), $t->getMessage() ?? "__unknown", $time); 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /Laravel.Tests/patches/phpunit_wrong_require_fix_001.patch: -------------------------------------------------------------------------------- 1 | --- vendor/phpunit/phpunit/src/TextUI/Command.php 2019-09-18 18:23:37.203244700 +0200 2 | +++ vendor/phpunit/phpunit/src/TextUI/Command2.php 2019-09-18 18:24:10.717294100 +0200 3 | @@ -948,7 +948,7 @@ 4 | 5 | $loaderFile = \stream_resolve_include_path($loaderFile); 6 | 7 | - if ($loaderFile) { 8 | + if ($loaderFile && stripos($loaderFile, ".php") !== false) { 9 | require $loaderFile; 10 | } 11 | } 12 | @@ -1003,7 +1003,7 @@ 13 | 14 | $printerFile = \stream_resolve_include_path($printerFile); 15 | 16 | - if ($printerFile) { 17 | + if ($printerFile && stripos($printerFile, ".php") !== false) { 18 | require $printerFile; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Laravel.Tests/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 17 | tests 18 | 19 | 20 | 21 | 22 | src 23 | 24 | src/ 25 | 26 | 27 | 28 | 29 | 33 | 34 | -------------------------------------------------------------------------------- /Laravel.Tests/tests_patches/auth_fix_001.patch: -------------------------------------------------------------------------------- 1 | --- tests/Auth/AuthGuardTest.php 2019-08-27 23:38:02.487169700 +0200 2 | +++ tests/Auth/AuthGuardTest2.php 2019-08-27 23:37:56.512000000 +0200 3 | @@ -33,7 +33,7 @@ 4 | [$session, $provider, $request, $cookie] = $this->getMocks(); 5 | $guard = m::mock(SessionGuard::class.'[check,attempt]', ['default', $provider, $session]); 6 | $guard->shouldReceive('check')->once()->andReturn(false); 7 | - $guard->shouldReceive('attempt')->once()->with(['email' => 'foo@bar.com', 'password' => 'secret'])->andReturn(true); 8 | + $guard->shouldReceive('attempt')->once()->with(['email' => 'foo@bar.com', 'password' => 'secret'], false)->andReturn(true); 9 | $request = Request::create('/', 'GET', [], [], [], ['PHP_AUTH_USER' => 'foo@bar.com', 'PHP_AUTH_PW' => 'secret']); 10 | $guard->setRequest($request); 11 | 12 | @@ -59,7 +59,7 @@ 13 | [$session, $provider, $request, $cookie] = $this->getMocks(); 14 | $guard = m::mock(SessionGuard::class.'[check,attempt]', ['default', $provider, $session]); 15 | $guard->shouldReceive('check')->once()->andReturn(false); 16 | - $guard->shouldReceive('attempt')->once()->with(['email' => 'foo@bar.com', 'password' => 'secret'])->andReturn(false); 17 | + $guard->shouldReceive('attempt')->once()->with(['email' => 'foo@bar.com', 'password' => 'secret'], false)->andReturn(false); 18 | $request = Request::create('/', 'GET', [], [], [], ['PHP_AUTH_USER' => 'foo@bar.com', 'PHP_AUTH_PW' => 'secret']); 19 | $guard->setRequest($request); 20 | $guard->basic('email'); 21 | @@ -70,7 +70,7 @@ 22 | [$session, $provider, $request, $cookie] = $this->getMocks(); 23 | $guard = m::mock(SessionGuard::class.'[check,attempt]', ['default', $provider, $session]); 24 | $guard->shouldReceive('check')->once()->andReturn(false); 25 | - $guard->shouldReceive('attempt')->once()->with(['email' => 'foo@bar.com', 'password' => 'secret', 'active' => 1])->andReturn(true); 26 | + $guard->shouldReceive('attempt')->once()->with(['email' => 'foo@bar.com', 'password' => 'secret', 'active' => 1], false)->andReturn(true); 27 | $request = Request::create('/', 'GET', [], [], [], ['PHP_AUTH_USER' => 'foo@bar.com', 'PHP_AUTH_PW' => 'secret']); 28 | $guard->setRequest($request); 29 | 30 | @@ -82,7 +82,7 @@ 31 | [$session, $provider, $request, $cookie] = $this->getMocks(); 32 | $guard = m::mock(SessionGuard::class.'[check,attempt]', ['default', $provider, $session]); 33 | $guard->shouldReceive('check')->once()->andReturn(false); 34 | - $guard->shouldReceive('attempt')->once()->with(['email' => 'foo@bar.com', 'password' => 'secret', 'active' => 1, 'type' => [1, 2, 3]])->andReturn(true); 35 | + $guard->shouldReceive('attempt')->once()->with(['email' => 'foo@bar.com', 'password' => 'secret', 'active' => 1, 'type' => [1, 2, 3]], false)->andReturn(true); 36 | $request = Request::create('/', 'GET', [], [], [], ['PHP_AUTH_USER' => 'foo@bar.com', 'PHP_AUTH_PW' => 'secret']); 37 | $guard->setRequest($request); 38 | 39 | -------------------------------------------------------------------------------- /Laravel/.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | node_modules 3 | src -------------------------------------------------------------------------------- /Laravel/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Taylor Otwell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Laravel/Laravel.msbuildproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | netstandard2.0 6 | $(LaravelVersion) 7 | $(LaravelVersion) 8 | PHP0125,PHP5011,PHP5008,PHP5006,PHP5012 9 | Laravel 10 | Laravel project transformed to managed .NET Standard library. 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Laravel/bootstrap/app.php: -------------------------------------------------------------------------------- 1 | singleton( 30 | Illuminate\Contracts\Http\Kernel::class, 31 | App\Http\Kernel::class 32 | ); 33 | 34 | $app->singleton( 35 | Illuminate\Contracts\Console\Kernel::class, 36 | App\Console\Kernel::class 37 | ); 38 | 39 | $app->singleton( 40 | Illuminate\Contracts\Debug\ExceptionHandler::class, 41 | App\Exceptions\Handler::class 42 | ); 43 | 44 | /* 45 | |-------------------------------------------------------------------------- 46 | | Return The Application 47 | |-------------------------------------------------------------------------- 48 | | 49 | | This script returns the application instance. The instance is given to 50 | | the calling script so we can separate the building of the instances 51 | | from the actual running of the application and sending responses. 52 | | 53 | */ 54 | 55 | return $app; 56 | -------------------------------------------------------------------------------- /Laravel/dummy_files/dummy_browserkit.php: -------------------------------------------------------------------------------- 1 | IsValid; 9 | } 10 | } -------------------------------------------------------------------------------- /Laravel/helpers.php: -------------------------------------------------------------------------------- 1 | " . file_get_contents($__path)); 10 | + } else { 11 | + include $__path; 12 | + } 13 | } catch (Exception $e) { 14 | $this->handleViewException($e, $obLevel); 15 | } catch (Throwable $e) { 16 | $this->handleViewException(new FatalThrowableError($e), $obLevel); 17 | + } catch (\System\Exception $systemException) { 18 | + $this->handleViewException(new FatalThrowableError(new Exception($systemException->ToString())), $obLevel); 19 | } 20 | 21 | return ltrim(ob_get_clean()); 22 | -------------------------------------------------------------------------------- /Laravel/laravel_patches/exceptions_fix.patch: -------------------------------------------------------------------------------- 1 | --- src/Illuminate/Foundation/Bootstrap/HandleExceptions.php 2019-08-15 22:42:07.000000000 +0200 2 | +++ src/Illuminate/Foundation/Bootstrap/HandleExceptions.php 2019-08-15 23:19:54.000000000 +0200 3 | @@ -2,6 +2,7 @@ 4 | 5 | namespace Illuminate\Foundation\Bootstrap; 6 | 7 | +use Throwable; 8 | use ErrorException; 9 | use Exception; 10 | use Illuminate\Contracts\Debug\ExceptionHandler; 11 | @@ -83,6 +84,10 @@ 12 | public function handleException($e) 13 | { 14 | if (! $e instanceof Exception) { 15 | + if (! $e instanceof Throwable) { 16 | + $e = new Exception($e->ToString()); 17 | + } 18 | + 19 | $e = new FatalThrowableError($e); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /Laravel/laravel_patches/filesystem_require_001.patch: -------------------------------------------------------------------------------- 1 | --- src/Illuminate/Filesystem/Filesystem.php 2019-10-28 22:34:14.248869100 +0100 2 | +++ src/Illuminate/Filesystem/Filesystem2.php 2019-10-28 22:36:34.954580100 +0100 3 | @@ -92,7 +92,11 @@ 4 | public function getRequire($path) 5 | { 6 | if ($this->isFile($path)) { 7 | - return require $path; 8 | + if (!class_exists("\Pchp\Core\Context") || \PeachPie\Runtime::isScriptCompiled($path)) { 9 | + return require $path; 10 | + } 11 | + 12 | + return eval("?>" . file_get_contents($path)); 13 | } 14 | 15 | throw new FileNotFoundException("File does not exist at path {$path}"); 16 | @@ -106,7 +110,12 @@ 17 | */ 18 | public function requireOnce($file) 19 | { 20 | - require_once $file; 21 | + if (!class_exists("\Pchp\Core\Context") || \PeachPie\Runtime::isScriptCompiled($file)) { 22 | + require_once $file; 23 | + return; 24 | + } 25 | + 26 | + eval("?>" . file_get_contents($file)); 27 | } 28 | 29 | /** 30 | -------------------------------------------------------------------------------- /Laravel/laravel_patches/internal_app_start_001.patch: -------------------------------------------------------------------------------- 1 | --- src/Illuminate/Foundation/Application.php 2019-10-28 22:21:05.124170000 +0100 2 | +++ src/Illuminate/Foundation/Application2.php 2019-10-28 22:22:09.577705600 +0100 3 | @@ -138,6 +138,11 @@ 4 | protected $namespace; 5 | 6 | /** 7 | + * @var LaravelApp 8 | + */ 9 | + protected $laravelApp; 10 | + 11 | + /** 12 | * Create a new Illuminate application instance. 13 | * 14 | * @param string|null $basePath 15 | @@ -152,6 +157,29 @@ 16 | $this->registerBaseBindings(); 17 | $this->registerBaseServiceProviders(); 18 | $this->registerCoreContainerAliases(); 19 | + 20 | + $this->laravelApp = new class extends \Laravel\Sdk\LaravelApp 21 | + { 22 | + public function GetVersion() 23 | + { 24 | + return Application::VERSION; 25 | + } 26 | + 27 | + public function InternalRegisterController($name, $controller) 28 | + { 29 | + app()->bind($name, $controller); 30 | + } 31 | + 32 | + public function InternalSetUserModel($userModel) 33 | + { 34 | + } 35 | + }; 36 | + 37 | + global $peachpie_laravel_loader; 38 | + 39 | + if ($peachpie_laravel_loader) { 40 | + $peachpie_laravel_loader->InternalAppStarted($this->laravelApp); 41 | + } 42 | } 43 | 44 | /** 45 | -------------------------------------------------------------------------------- /Laravel/laravel_patches/internal_app_start_002.patch: -------------------------------------------------------------------------------- 1 | --- src/Illuminate/Foundation/Application.php 2019-10-28 22:24:16.955162900 +0100 2 | +++ src/Illuminate/Foundation/Application2.php 2019-10-28 22:25:01.393104900 +0100 3 | @@ -158,6 +158,10 @@ 4 | $this->registerBaseServiceProviders(); 5 | $this->registerCoreContainerAliases(); 6 | 7 | + if (!class_exists("\\Laravel\\Sdk\\LaravelApp")) { 8 | + return; 9 | + } 10 | + 11 | $this->laravelApp = new class extends \Laravel\Sdk\LaravelApp 12 | { 13 | public function GetVersion() 14 | -------------------------------------------------------------------------------- /Laravel/laravel_patches/openssl_peachpie_issue_402_001.patch: -------------------------------------------------------------------------------- 1 | --- src/Illuminate/Encryption/Encrypter.php 2019-08-15 23:52:54.000000000 +0200 2 | +++ src/Illuminate/Encryption/Encrypter.php 2019-08-16 11:57:37.000000000 +0200 3 | @@ -81,7 +81,7 @@ 4 | */ 5 | public function encrypt($value, $serialize = true) 6 | { 7 | - $iv = random_bytes(openssl_cipher_iv_length($this->cipher)); 8 | + $iv = random_bytes(\openssl_cipher_iv_length($this->cipher)); 9 | 10 | // First we will encrypt the value using OpenSSL. After this is encrypted we 11 | // will proceed to calculating a MAC for the encrypted value so that this 12 | @@ -211,7 +211,7 @@ 13 | protected function validPayload($payload) 14 | { 15 | return is_array($payload) && isset($payload['iv'], $payload['value'], $payload['mac']) && 16 | - strlen(base64_decode($payload['iv'], true)) === openssl_cipher_iv_length($this->cipher); 17 | + strlen(base64_decode($payload['iv'], true)) === \openssl_cipher_iv_length($this->cipher); 18 | } 19 | 20 | /** 21 | -------------------------------------------------------------------------------- /Laravel/laravel_patches/password_methods_fix_001.patch: -------------------------------------------------------------------------------- 1 | --- src/Illuminate/Hashing/ArgonHasher.php 2019-08-22 15:21:16.753188900 +0200 2 | +++ src/Illuminate/Hashing/ArgonHasher2.php 2019-08-22 15:35:31.858339200 +0200 3 | @@ -60,7 +60,7 @@ 4 | */ 5 | public function make($value, array $options = []) 6 | { 7 | - $hash = password_hash($value, $this->algorithm(), [ 8 | + $hash = \password_hash($value, $this->algorithm(), [ 9 | 'memory_cost' => $this->memory($options), 10 | 'time_cost' => $this->time($options), 11 | 'threads' => $this->threads($options), 12 | @@ -109,7 +109,7 @@ 13 | */ 14 | public function needsRehash($hashedValue, array $options = []) 15 | { 16 | - return password_needs_rehash($hashedValue, $this->algorithm(), [ 17 | + return \password_needs_rehash($hashedValue, $this->algorithm(), [ 18 | 'memory_cost' => $this->memory($options), 19 | 'time_cost' => $this->time($options), 20 | 'threads' => $this->threads($options), 21 | -------------------------------------------------------------------------------- /Laravel/laravel_patches/password_methods_fix_002.patch: -------------------------------------------------------------------------------- 1 | --- src/Illuminate/Hashing/BcryptHasher.php 2019-08-22 15:21:16.758175000 +0200 2 | +++ src/Illuminate/Hashing/BcryptHasher2.php 2019-08-22 15:36:36.293907900 +0200 3 | @@ -44,7 +44,7 @@ 4 | */ 5 | public function make($value, array $options = []) 6 | { 7 | - $hash = password_hash($value, PASSWORD_BCRYPT, [ 8 | + $hash = \password_hash($value, PASSWORD_BCRYPT, [ 9 | 'cost' => $this->cost($options), 10 | ]); 11 | 12 | @@ -83,7 +83,7 @@ 13 | */ 14 | public function needsRehash($hashedValue, array $options = []) 15 | { 16 | - return password_needs_rehash($hashedValue, PASSWORD_BCRYPT, [ 17 | + return \password_needs_rehash($hashedValue, PASSWORD_BCRYPT, [ 18 | 'cost' => $this->cost($options), 19 | ]); 20 | } 21 | -------------------------------------------------------------------------------- /Laravel/laravel_patches/request_create_workaround.patch: -------------------------------------------------------------------------------- 1 | --- src/Illuminate/Http/Request.php 2019-08-19 15:12:22.000000000 +0200 2 | +++ src/Illuminate/Http/Request2.php 2019-08-19 15:14:26.000000000 +0200 3 | @@ -698,4 +698,9 @@ 4 | return $this->route($key); 5 | }); 6 | } 7 | + 8 | + public static function create($uri, $method = 'GET', $parameters = [], $cookies = [], $files = [], $server = [], $content = null) 9 | + { 10 | + return static::createFromBase(parent::create($uri, $method, $parameters, $cookies, $files, $server, $content)); 11 | + } 12 | } 13 | -------------------------------------------------------------------------------- /Laravel/laravel_patches/rescue_catch_system_exceptions.patch: -------------------------------------------------------------------------------- 1 | *** src/Illuminate/Foundation/helpers2.php 2020-02-07 19:28:09.782000000 +0100 2 | --- src/Illuminate/Foundation/helpers.php 2020-02-07 19:28:47.677500200 +0100 3 | *************** if (! function_exists('rescue')) { 4 | *** 716,721 **** 5 | --- 716,729 ---- 6 | } 7 | 8 | return $rescue instanceof Closure ? $rescue($e) : $rescue; 9 | + } catch (\System\Exception $systemException) { 10 | + $e = new \Exception($systemException->ToString()); 11 | + 12 | + if ($report) { 13 | + report($e); 14 | + } 15 | + 16 | + return $rescue instanceof Closure ? $rescue($e) : $rescue; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Laravel/laravel_patches/route_loader.patch: -------------------------------------------------------------------------------- 1 | --- src/Illuminate/Routing/RouteFileRegistrar.php 2019-08-19 09:35:19.000000000 +0200 2 | +++ src/Illuminate/Routing/RouteFileRegistrar2.php 2019-08-19 09:35:42.000000000 +0200 3 | @@ -32,6 +32,6 @@ 4 | { 5 | $router = $this->router; 6 | 7 | - require $routes; 8 | + eval("?>" . file_get_contents($routes)); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Laravel/patches/aws_fix_001.patch: -------------------------------------------------------------------------------- 1 | --- vendor/aws/aws-sdk-php/src/S3/S3MultiRegionClient.php 2019-08-24 19:18:13.986783500 +0200 2 | +++ vendor/aws/aws-sdk-php/src/S3/S3MultiRegionClient2.php 2019-08-25 01:11:29.370594200 +0200 3 | @@ -244,8 +244,10 @@ 4 | $command, 5 | $cacheKey 6 | ) { 7 | + $yieldValues = []; 8 | + 9 | try { 10 | - yield $handler($command); 11 | + $yieldValues []= $handler($command); 12 | } catch (PermanentRedirectException $e) { 13 | if (empty($command['Bucket'])) { 14 | throw $e; 15 | @@ -256,13 +258,15 @@ 16 | $region = $result['@metadata']['headers']['x-amz-bucket-region']; 17 | $this->cache->set($cacheKey, $region); 18 | } else { 19 | - $region = (yield $this->determineBucketRegionAsync( 20 | + $region = $this->determineBucketRegionAsync( 21 | $command['Bucket'] 22 | - )); 23 | + ); 24 | + 25 | + $yieldValues []= $region; 26 | } 27 | 28 | $command['@region'] = $region; 29 | - yield $handler($command); 30 | + $yieldValues []= $handler($command); 31 | } catch (AwsException $e) { 32 | if ($e->getAwsErrorCode() === 'AuthorizationHeaderMalformed') { 33 | $region = $this->determineBucketRegionFromExceptionBody( 34 | @@ -272,7 +276,7 @@ 35 | $this->cache->set($cacheKey, $region); 36 | 37 | $command['@region'] = $region; 38 | - yield $handler($command); 39 | + $yieldValues []= $handler($command); 40 | } else { 41 | throw $e; 42 | } 43 | @@ -280,6 +284,10 @@ 44 | throw $e; 45 | } 46 | } 47 | + 48 | + foreach ($yieldValues as $value) { 49 | + yield $value; 50 | + } 51 | }); 52 | }; 53 | }; 54 | -------------------------------------------------------------------------------- /Laravel/patches/aws_fix_002.patch: -------------------------------------------------------------------------------- 1 | --- vendor/aws/aws-sdk-php/src/Credentials/InstanceProfileProvider.php 2019-08-24 19:18:12.136286500 +0200 2 | +++ vendor/aws/aws-sdk-php/src/Credentials/InstanceProfileProvider2.php 2019-08-25 01:13:55.191006800 +0200 3 | @@ -68,8 +68,10 @@ 4 | } 5 | $result = null; 6 | while ($result == null) { 7 | + $yieldValue = null; 8 | + 9 | try { 10 | - $json = (yield $this->request(self::CRED_PATH . $this->profile)); 11 | + $json = $yieldValue = $this->request(self::CRED_PATH . $this->profile); 12 | $result = $this->decodeResult($json); 13 | } catch (InvalidJsonException $e) { 14 | if ($this->attempts < $this->retries) { 15 | @@ -88,6 +90,11 @@ 16 | ); 17 | } 18 | } 19 | + 20 | + if ($yieldValue !== null) { 21 | + yield $yieldValue; 22 | + } 23 | + 24 | $this->attempts++; 25 | } 26 | yield new Credentials( 27 | -------------------------------------------------------------------------------- /Laravel/patches/aws_fix_003.patch: -------------------------------------------------------------------------------- 1 | --- vendor/aws/aws-sdk-php/src/Crypto/DecryptionTrait.php 2019-08-25 12:22:52.157111900 +0200 2 | +++ vendor/aws/aws-sdk-php/src/Crypto/DecryptionTrait2.php 2019-08-25 12:27:03.897201900 +0200 3 | @@ -53,7 +53,7 @@ 4 | * 5 | * @internal 6 | */ 7 | - protected function decrypt( 8 | + public function decrypt( 9 | $cipherText, 10 | MaterialsProvider $provider, 11 | MetadataEnvelope $envelope, 12 | -------------------------------------------------------------------------------- /Laravel/patches/aws_fix_004.patch: -------------------------------------------------------------------------------- 1 | --- vendor/aws/aws-sdk-php/src/Crypto/EncryptionTrait.php 2019-08-25 12:22:52.166111900 +0200 2 | +++ vendor/aws/aws-sdk-php/src/Crypto/EncryptionTrait2.php 2019-08-25 12:26:45.895472800 +0200 3 | @@ -48,7 +48,7 @@ 4 | * 5 | * @internal 6 | */ 7 | - protected function encrypt( 8 | + public function encrypt( 9 | Stream $plaintext, 10 | array $cipherOptions, 11 | MaterialsProvider $provider, 12 | -------------------------------------------------------------------------------- /Laravel/patches/aws_yield_exception_construct_001.patch: -------------------------------------------------------------------------------- 1 | --- vendor/aws/aws-sdk-php/src/Waiter.php 2019-08-14 20:14:46.000000000 +0200 2 | +++ vendor/aws/aws-sdk-php/src/Waiter2.php 2019-08-20 15:55:38.000000000 +0200 3 | @@ -94,15 +94,22 @@ 4 | // Execute the operation. 5 | $args = $this->getArgsForAttempt($attempt); 6 | $command = $this->client->getCommand($name, $args); 7 | + $yieldResult = true; 8 | + 9 | try { 10 | if ($this->config['before']) { 11 | $this->config['before']($command, $attempt); 12 | } 13 | - $result = (yield $this->client->executeAsync($command)); 14 | + $result = $this->client->executeAsync($command); 15 | } catch (AwsException $e) { 16 | + $yieldResult = false; 17 | $result = $e; 18 | } 19 | 20 | + if ($yieldResult) { 21 | + $result = yield $result; 22 | + } 23 | + 24 | // Determine the waiter's state and what to do next. 25 | $state = $this->determineState($result); 26 | if ($state === 'success') { 27 | -------------------------------------------------------------------------------- /Laravel/patches/cookie_workaround.patch: -------------------------------------------------------------------------------- 1 | --- vendor/symfony/http-foundation/Cookie.php 2019-08-16 12:01:23.000000000 +0200 2 | +++ vendor/symfony/http-foundation/Cookie.php 2019-08-16 12:01:35.000000000 +0200 3 | @@ -124,7 +124,7 @@ 4 | if ('' === $sameSite) { 5 | $sameSite = null; 6 | } elseif (null !== $sameSite) { 7 | - $sameSite = strtolower($sameSite); 8 | + $sameSite = strtolower($sameSite ?? self::SAMESITE_NONE); 9 | } 10 | 11 | if (!\in_array($sameSite, [self::SAMESITE_LAX, self::SAMESITE_STRICT, self::SAMESITE_NONE, null], true)) { 12 | -------------------------------------------------------------------------------- /Laravel/patches/superclosure_001.patch: -------------------------------------------------------------------------------- 1 | --- vendor/jeremeamia/superclosure/src/Analyzer/AstAnalyzer.php 2019-08-15 17:06:22.000000000 +0200 2 | +++ vendor/jeremeamia/superclosure/src/Analyzer/AstAnalyzer.php 2019-08-15 17:06:51.000000000 +0200 3 | @@ -139,10 +139,6 @@ 4 | */ 5 | private function getParser() 6 | { 7 | - if (class_exists('PhpParser\ParserFactory')) { 8 | - return (new ParserFactory)->create(ParserFactory::PREFER_PHP7); 9 | - } 10 | - 11 | - return new CodeParser(new EmulativeLexer); 12 | + return (new ParserFactory)->create(ParserFactory::PREFER_PHP7); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Laravel/public/index.php: -------------------------------------------------------------------------------- 1 | handle( 8 | $request = Illuminate\Http\Request::capture() 9 | ); 10 | 11 | $response->send(); 12 | 13 | $__laravelHttpKernel->terminate($request, $response); 14 | -------------------------------------------------------------------------------- /app/BaseControllerNet.cs: -------------------------------------------------------------------------------- 1 | using Pchp.Core; 2 | using Illuminate; 3 | using Illuminate.View; 4 | 5 | namespace App.Http.Controllers 6 | { 7 | [PhpType] 8 | public class BaseControllerNet : Controller 9 | { 10 | protected Context _ctx; 11 | 12 | public BaseControllerNet(Context ctx) : base(ctx) 13 | { 14 | this._ctx = ctx; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /app/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.IO; 7 | 8 | using Laravel.AspNetCore; 9 | using Laravel.Sdk; 10 | using Illuminate; 11 | using Illuminate.Contracts.Http; 12 | using App.Http.Controllers; 13 | 14 | namespace peachserver 15 | { 16 | class Program 17 | { 18 | static void Main(string[] args) 19 | { 20 | var host = new WebHostBuilder() 21 | .UseKestrel() 22 | .UseUrls("http://*:5004/") 23 | .UseStartup() 24 | .UseContentRoot(Directory.GetCurrentDirectory()) 25 | .ConfigureLogging(logging => 26 | { 27 | logging.ClearProviders(); 28 | logging.AddConsole(); 29 | }) 30 | .Build(); 31 | 32 | host.Run(); 33 | } 34 | } 35 | 36 | class Startup 37 | { 38 | public void ConfigureServices(IServiceCollection services) 39 | { 40 | // Adds a default in-memory implementation of IDistributedCache. 41 | services.AddDistributedMemoryCache(); 42 | 43 | services.AddSession(options => 44 | { 45 | options.IdleTimeout = TimeSpan.FromMinutes(30); 46 | options.Cookie.HttpOnly = true; 47 | }); 48 | } 49 | 50 | public void Configure(IApplicationBuilder app) 51 | { 52 | app.UseLaravel(new string[] { 53 | typeof(App.Providers.AppServiceProvider).Assembly.FullName 54 | }); 55 | 56 | LaravelLoader.AppStarted += (laravelApp) => 57 | { 58 | laravelApp.Context.DeclareType(); 59 | }; 60 | 61 | // Type type = typeof(App.Providers.AppServiceProvider).Assembly.GetType("bootstrap.app_php"); 62 | // var method = type.GetMethod("
", BindingFlags.Public | BindingFlags.Static); 63 | // var app = method.Invoke(null, new object[] { 64 | 65 | // }); 66 | 67 | // Kernel app = Helpers.app("\\Illuminate\\Contracts\\Http\\Kernel"); 68 | 69 | // Console.WriteLine("AppStarted!"); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iis": { 6 | "applicationUrl": "http://localhost/app", 7 | "sslPort": 0 8 | }, 9 | "iisExpress": { 10 | "applicationUrl": "http://localhost:5004/", 11 | "sslPort": 0 12 | } 13 | }, 14 | "profiles": { 15 | "IIS Express": { 16 | "commandName": "IISExpress", 17 | "workingDirectory": "C:\\Development\\laravel-peachpie-sample\\app\\bin\\Debug\\netcoreapp2.1", 18 | "launchBrowser": true, 19 | "environmentVariables": { 20 | "APP_BASE_PATH": "C:\\Development\\laravel-peachpie-sample\\app\\bin\\Debug\\netcoreapp2.1", 21 | "ASPNETCORE_ENVIRONMENT": "Development" 22 | }, 23 | "use64Bit": true 24 | }, 25 | "app": { 26 | "commandName": "Project", 27 | "launchBrowser": true, 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | }, 31 | "applicationUrl": "http://localhost:61199/" 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /app/TestController.cs: -------------------------------------------------------------------------------- 1 | using Pchp.Core; 2 | using Illuminate; 3 | using Illuminate.View; 4 | 5 | namespace App.Http.Controllers 6 | { 7 | [PhpType] 8 | public class TestController : BaseControllerNet 9 | { 10 | public TestController(Context ctx) : base(ctx) {} 11 | 12 | public View index() 13 | { 14 | return Helpers.view(this._ctx, "welcome"); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /app/app.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | Exe 4 | netcoreapp3.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | None 17 | 18 | 19 | 20 | None 21 | 22 | 23 | 24 | None 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /app/app.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | IIS Express 5 | 6 | -------------------------------------------------------------------------------- /build/Settings.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 1.0.0 8 | 9 | 1.0.0-dev 10 | 6.14.0 11 | 12 | 13 | true 14 | true 15 | false 16 | false 17 | false 18 | false 19 | true 20 | true 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | git 32 | 35 | https://s.w.org/style/images/about/WordPress-logotype-wmark-white.png 36 | true 37 | 38 | 39 | -------------------------------------------------------------------------------- /build/install_dependencies_ubuntu16.sh: -------------------------------------------------------------------------------- 1 | # Install .NET Core 2 | # https://dotnet.microsoft.com/download/linux-package-manager/ubuntu16-04/sdk-current 3 | 4 | # Register Microsoft key and feed 5 | wget -q https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb 6 | sudo dpkg -i packages-microsoft-prod.deb 7 | 8 | # Install .NET Core SDK 9 | sudo apt-get update 10 | sudo apt-get install apt-transport-https 11 | sudo apt-get update 12 | sudo apt-get install dotnet-sdk-3.0 nuget -y 13 | 14 | # Install Python Pip and icdiff (http://www.jefftk.com/icdiff) 15 | 16 | sudo apt-get -y install python-pip 17 | pip -V 18 | sudo pip install --upgrade icdiff -------------------------------------------------------------------------------- /build/nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## Laravel SDK for PeachPie [![Build Status](https://travis-ci.com/calvinbaart/laravel-peachpie-sample.svg?branch=feature%2Flaravel-sdk)](https://travis-ci.com/calvinbaart/laravel-peachpie-sample) 2 | 3 | This project fetches the latest Laravel and compiles it (with some patches) for PeachPie. 4 | 5 | ## Project Structure 6 | 7 | - ``app``: Main project file for the WebServer. Runs AspNetCore. 8 | - ``Laravel``: Laravel with all its dependencies 9 | - ``Laravel.AspNetCore``: AspNetCore extensions for Laravel 10 | - ``Laravel.ComposerDummy``: Dummy project for composer to override some already compiled dependencies 11 | - ``Laravel.Sdk``: Classes for Laravel <-> C# communication. 12 | - ``Laravel.Tests``: PHPUnit tests for Laravel 13 | - ``website``: All the website-specific files, this would be your root folder in a Laravel project 14 | 15 | ## What does it do? 16 | 17 | The code currently contains two run paths. ``App`` and ``Laravel.Tests``. 18 | 19 | Starting app would run a full webserver just like a regular ``Asp.Net`` project. The Webserver redirects all requests to the code in ``website``. 20 | 21 | Starting Laravel.Tests would run PHPUnit testing, these tests are the standard tests from the laravel repository. 22 | 23 | ## Prerequisites 24 | 25 | - .NET Core 2.0 or newer 26 | - Optionally - Visual Studio Code 27 | 28 | ## How to run the project 29 | 30 | 1. `dotnet run app` 31 | 2. `dotnet run Laravel.Tests` 32 | -------------------------------------------------------------------------------- /website/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 4 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [*.yml] 15 | indent_size = 2 16 | -------------------------------------------------------------------------------- /website/.env: -------------------------------------------------------------------------------- 1 | APP_NAME=Laravel 2 | APP_ENV=local 3 | APP_KEY=8y/B?D(G+KbPeShVmYq3t6w9z$C&F)H@ 4 | APP_DEBUG=true 5 | APP_URL=http://localhost 6 | 7 | LOG_CHANNEL=stack 8 | 9 | DB_CONNECTION=mysql 10 | DB_HOST=127.0.0.1 11 | DB_PORT=3306 12 | DB_DATABASE=laravel 13 | DB_USERNAME=root 14 | DB_PASSWORD=homestead 15 | 16 | BROADCAST_DRIVER=log 17 | CACHE_DRIVER=file 18 | QUEUE_CONNECTION=sync 19 | SESSION_DRIVER=cookie 20 | SESSION_LIFETIME=120 21 | 22 | REDIS_HOST=127.0.0.1 23 | REDIS_PASSWORD=null 24 | REDIS_PORT=6379 25 | 26 | MAIL_DRIVER=smtp 27 | MAIL_HOST=smtp.mailtrap.io 28 | MAIL_PORT=2525 29 | MAIL_USERNAME=null 30 | MAIL_PASSWORD=null 31 | MAIL_ENCRYPTION=null 32 | 33 | PUSHER_APP_ID= 34 | PUSHER_APP_KEY= 35 | PUSHER_APP_SECRET= 36 | PUSHER_APP_CLUSTER=mt1 37 | 38 | MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 39 | MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 40 | -------------------------------------------------------------------------------- /website/.env.example: -------------------------------------------------------------------------------- 1 | APP_NAME=Laravel 2 | APP_ENV=local 3 | APP_KEY= 4 | APP_DEBUG=true 5 | APP_URL=http://localhost 6 | 7 | LOG_CHANNEL=stack 8 | 9 | DB_CONNECTION=mysql 10 | DB_HOST=127.0.0.1 11 | DB_PORT=3306 12 | DB_DATABASE=homestead 13 | DB_USERNAME=homestead 14 | DB_PASSWORD=secret 15 | 16 | BROADCAST_DRIVER=log 17 | CACHE_DRIVER=file 18 | QUEUE_CONNECTION=sync 19 | SESSION_DRIVER=file 20 | SESSION_LIFETIME=120 21 | 22 | REDIS_HOST=127.0.0.1 23 | REDIS_PASSWORD=null 24 | REDIS_PORT=6379 25 | 26 | MAIL_DRIVER=smtp 27 | MAIL_HOST=smtp.mailtrap.io 28 | MAIL_PORT=2525 29 | MAIL_USERNAME=null 30 | MAIL_PASSWORD=null 31 | MAIL_ENCRYPTION=null 32 | 33 | PUSHER_APP_ID= 34 | PUSHER_APP_KEY= 35 | PUSHER_APP_SECRET= 36 | PUSHER_APP_CLUSTER=mt1 37 | 38 | MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 39 | MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 40 | -------------------------------------------------------------------------------- /website/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.css linguist-vendored 3 | *.scss linguist-vendored 4 | *.js linguist-vendored 5 | CHANGELOG.md export-ignore 6 | -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | public/hot 3 | public/storage 4 | storage/*.key 5 | vendor 6 | .env 7 | .phpunit.result.cache 8 | Homestead.json 9 | Homestead.yaml 10 | npm-debug.log 11 | yarn-error.log 12 | .idea 13 | -------------------------------------------------------------------------------- /website/app/Activity.php: -------------------------------------------------------------------------------- 1 | 'array' 23 | ]; 24 | 25 | /** 26 | * Get the subject of the activity. 27 | * 28 | * @return \Illuminate\Database\Eloquent\Relations\MorphTo 29 | */ 30 | public function subject() 31 | { 32 | return $this->morphTo(); 33 | } 34 | 35 | /** 36 | * Get the user who triggered the activity. 37 | * 38 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 39 | */ 40 | public function user() 41 | { 42 | return $this->belongsTo(User::class); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /website/app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('inspire') 28 | // ->hourly(); 29 | } 30 | 31 | /** 32 | * Register the commands for the application. 33 | * 34 | * @return void 35 | */ 36 | protected function commands() 37 | { 38 | $this->load(__DIR__.'/Commands'); 39 | 40 | require base_path('routes/console.php'); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /website/app/Exceptions/Handler.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /website/app/Http/Controllers/Auth/LoginController.php: -------------------------------------------------------------------------------- 1 | middleware('guest')->except('logout'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /website/app/Http/Controllers/Auth/RegisterController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 41 | } 42 | 43 | /** 44 | * Get a validator for an incoming registration request. 45 | * 46 | * @param array $data 47 | * @return \Illuminate\Contracts\Validation\Validator 48 | */ 49 | protected function validator(array $data) 50 | { 51 | return Validator::make($data, [ 52 | 'name' => ['required', 'string', 'max:255'], 53 | 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], 54 | 'password' => ['required', 'string', 'min:6', 'confirmed'], 55 | ]); 56 | } 57 | 58 | /** 59 | * Create a new user instance after a valid registration. 60 | * 61 | * @param array $data 62 | * @return \App\User 63 | */ 64 | protected function create(array $data) 65 | { 66 | return User::create([ 67 | 'name' => $data['name'], 68 | 'email' => $data['email'], 69 | 'password' => Hash::make($data['password']), 70 | ]); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /website/app/Http/Controllers/Auth/ResetPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /website/app/Http/Controllers/Auth/VerificationController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 38 | $this->middleware('signed')->only('verify'); 39 | $this->middleware('throttle:6,1')->only('verify', 'resend'); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /website/app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | first(); 21 | 22 | $project->invite($user); 23 | 24 | return redirect($project->path()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /website/app/Http/Controllers/ProjectTasksController.php: -------------------------------------------------------------------------------- 1 | authorize('update', $project); 20 | 21 | request()->validate(['body' => 'required']); 22 | 23 | $project->addTask(request('body')); 24 | 25 | return redirect($project->path()); 26 | } 27 | 28 | /** 29 | * Update the project. 30 | * 31 | * @param Project $project 32 | * @param Task $task 33 | * @return \Illuminate\Http\RedirectResponse 34 | * @throws \Illuminate\Auth\Access\AuthorizationException 35 | */ 36 | public function update(Project $project, Task $task) 37 | { 38 | $this->authorize('update', $task->project); 39 | 40 | $task->update(request()->validate(['body' => 'required'])); 41 | 42 | request('completed') ? $task->complete() : $task->incomplete(); 43 | 44 | return redirect($project->path()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /website/app/Http/Controllers/ProjectsController.php: -------------------------------------------------------------------------------- 1 | user()->accessibleProjects(); 17 | 18 | return view('projects.index', compact('projects')); 19 | } 20 | 21 | /** 22 | * Show a single project. 23 | * 24 | * @param Project $project 25 | * 26 | * @return \Illuminate\Http\Response 27 | * @throws \Illuminate\Auth\Access\AuthorizationException 28 | */ 29 | public function show(Project $project) 30 | { 31 | $this->authorize('update', $project); 32 | 33 | return view('projects.show', compact('project')); 34 | } 35 | 36 | /** 37 | * Create a new project. 38 | * 39 | * @return \Illuminate\Http\Response 40 | */ 41 | public function create() 42 | { 43 | return view('projects.create'); 44 | } 45 | 46 | /** 47 | * Persist a new project. 48 | * 49 | * @return \Illuminate\Http\RedirectResponse 50 | */ 51 | public function store() 52 | { 53 | $project = auth()->user()->projects()->create($this->validateRequest()); 54 | 55 | return redirect($project->path()); 56 | } 57 | 58 | /** 59 | * Edit the project. 60 | * 61 | * @param Project $project 62 | * @return \Illuminate\Http\Response 63 | */ 64 | public function edit(Project $project) 65 | { 66 | return view('projects.edit', compact('project')); 67 | } 68 | 69 | /** 70 | * Update the project. 71 | * 72 | * @param Project $project 73 | * @return \Illuminate\Http\RedirectResponse 74 | * @throws \Illuminate\Auth\Access\AuthorizationException 75 | */ 76 | public function update(Project $project) 77 | { 78 | $this->authorize('update', $project); 79 | 80 | $project->update($this->validateRequest()); 81 | 82 | return redirect($project->path()); 83 | } 84 | 85 | /** 86 | * Destroy the project. 87 | * 88 | * @param Project $project 89 | * @return \Illuminate\Http\RedirectResponse 90 | * @throws \Illuminate\Auth\Access\AuthorizationException 91 | */ 92 | public function destroy(Project $project) 93 | { 94 | $this->authorize('manage', $project); 95 | 96 | $project->delete(); 97 | 98 | return redirect('/projects'); 99 | } 100 | 101 | /** 102 | * Validate the request attributes. 103 | * 104 | * @return array 105 | */ 106 | protected function validateRequest() 107 | { 108 | return request()->validate([ 109 | 'title' => 'sometimes|required', 110 | 'description' => 'sometimes|required', 111 | 'notes' => 'nullable' 112 | ]); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /website/app/Http/Kernel.php: -------------------------------------------------------------------------------- 1 | [ 31 | \App\Http\Middleware\EncryptCookies::class, 32 | \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, 33 | \Illuminate\Session\Middleware\StartSession::class, 34 | // \Illuminate\Session\Middleware\AuthenticateSession::class, 35 | \Illuminate\View\Middleware\ShareErrorsFromSession::class, 36 | \App\Http\Middleware\VerifyCsrfToken::class, 37 | \Illuminate\Routing\Middleware\SubstituteBindings::class, 38 | ], 39 | 40 | 'api' => [ 41 | 'throttle:60,1', 42 | 'bindings', 43 | ], 44 | ]; 45 | 46 | /** 47 | * The application's route middleware. 48 | * 49 | * These middleware may be assigned to groups or used individually. 50 | * 51 | * @var array 52 | */ 53 | protected $routeMiddleware = [ 54 | 'auth' => \App\Http\Middleware\Authenticate::class, 55 | 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 56 | 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 57 | 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, 58 | 'can' => \Illuminate\Auth\Middleware\Authorize::class, 59 | 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 60 | 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 61 | 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 62 | 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, 63 | ]; 64 | 65 | /** 66 | * The priority-sorted list of middleware. 67 | * 68 | * This forces non-global middleware to always be in the given order. 69 | * 70 | * @var array 71 | */ 72 | protected $middlewarePriority = [ 73 | \Illuminate\Session\Middleware\StartSession::class, 74 | \Illuminate\View\Middleware\ShareErrorsFromSession::class, 75 | \App\Http\Middleware\Authenticate::class, 76 | \Illuminate\Session\Middleware\AuthenticateSession::class, 77 | \Illuminate\Routing\Middleware\SubstituteBindings::class, 78 | \Illuminate\Auth\Middleware\Authorize::class, 79 | ]; 80 | } 81 | -------------------------------------------------------------------------------- /website/app/Http/Middleware/Authenticate.php: -------------------------------------------------------------------------------- 1 | expectsJson()) { 18 | return route('login'); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /website/app/Http/Middleware/CheckForMaintenanceMode.php: -------------------------------------------------------------------------------- 1 | check()) { 21 | return redirect('/home'); 22 | } 23 | 24 | return $next($request); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /website/app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | route('project')); 26 | } 27 | 28 | /** 29 | * Get the validation rules that apply to the request. 30 | * 31 | * @return array 32 | */ 33 | public function rules() 34 | { 35 | return [ 36 | 'email' => ['required', Rule::exists('users', 'email')] 37 | ]; 38 | } 39 | 40 | /** 41 | * Get custom messages for validator errors. 42 | * 43 | * @return array 44 | */ 45 | public function messages() 46 | { 47 | return [ 48 | 'email.exists' => 'The user you are inviting must have a Birdboard account.' 49 | ]; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /website/app/Policies/ProjectPolicy.php: -------------------------------------------------------------------------------- 1 | is($project->owner); 23 | } 24 | 25 | /** 26 | * Determine if the user may update the project. 27 | * 28 | * @param User $user 29 | * @param Project $project 30 | * @return bool 31 | */ 32 | public function update(User $user, Project $project) 33 | { 34 | return $user->is($project->owner) || $project->members->contains($user); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /website/app/Project.php: -------------------------------------------------------------------------------- 1 | id}"; 26 | } 27 | 28 | /** 29 | * The owner of the project. 30 | * 31 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 32 | */ 33 | public function owner() 34 | { 35 | return $this->belongsTo(User::class); 36 | } 37 | 38 | /** 39 | * The tasks associated with the project. 40 | * 41 | * @return \Illuminate\Database\Eloquent\Relations\HasMany 42 | */ 43 | public function tasks() 44 | { 45 | return $this->hasMany(Task::class); 46 | } 47 | 48 | /** 49 | * Add a task to the project. 50 | * 51 | * @param string $body 52 | * @return \Illuminate\Database\Eloquent\Model 53 | */ 54 | public function addTask($body) 55 | { 56 | return $this->tasks()->create(compact('body')); 57 | } 58 | 59 | /** 60 | * Invite a user to the project. 61 | * 62 | * @param \App\User $user 63 | */ 64 | public function invite(User $user) 65 | { 66 | $this->members()->attach($user); 67 | } 68 | 69 | /** 70 | * Get all members that are assigned to the team. 71 | * 72 | * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany 73 | */ 74 | public function members() 75 | { 76 | return $this->belongsToMany(User::class, 'project_members')->withTimestamps(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /website/app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | 'App\Policies\ProjectPolicy', 17 | ]; 18 | 19 | /** 20 | * Register any authentication / authorization services. 21 | * 22 | * @return void 23 | */ 24 | public function boot() 25 | { 26 | $this->registerPolicies(); 27 | 28 | // 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /website/app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | [ 19 | SendEmailVerificationNotification::class, 20 | ], 21 | ]; 22 | 23 | /** 24 | * Register any events for your application. 25 | * 26 | * @return void 27 | */ 28 | public function boot() 29 | { 30 | parent::boot(); 31 | 32 | // 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /website/app/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | mapApiRoutes(); 39 | 40 | $this->mapWebRoutes(); 41 | 42 | // 43 | } 44 | 45 | /** 46 | * Define the "web" routes for the application. 47 | * 48 | * These routes all receive session state, CSRF protection, etc. 49 | * 50 | * @return void 51 | */ 52 | protected function mapWebRoutes() 53 | { 54 | Route::middleware('web') 55 | ->namespace($this->namespace) 56 | ->group(base_path('routes/web.php')); 57 | } 58 | 59 | /** 60 | * Define the "api" routes for the application. 61 | * 62 | * These routes are typically stateless. 63 | * 64 | * @return void 65 | */ 66 | protected function mapApiRoutes() 67 | { 68 | Route::prefix('api') 69 | ->middleware('api') 70 | ->namespace($this->namespace) 71 | ->group(base_path('routes/api.php')); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /website/app/RecordsActivity.php: -------------------------------------------------------------------------------- 1 | recordActivity($model->activityDescription($event)); 22 | }); 23 | 24 | if ($event === 'updated') { 25 | static::updating(function ($model) { 26 | $model->oldAttributes = $model->getOriginal(); 27 | }); 28 | } 29 | } 30 | } 31 | 32 | /** 33 | * Get the description of the activity. 34 | * 35 | * @param string $description 36 | * @return string 37 | */ 38 | protected function activityDescription($description) 39 | { 40 | return "{$description}_" . strtolower(class_basename($this)); 41 | } 42 | 43 | /** 44 | * Fetch the model events that should trigger activity. 45 | * 46 | * @return array 47 | */ 48 | protected static function recordableEvents() 49 | { 50 | if (isset(static::$recordableEvents)) { 51 | return static::$recordableEvents; 52 | } 53 | 54 | return ['created', 'updated']; 55 | } 56 | 57 | /** 58 | * Record activity for a project. 59 | * 60 | * @param string $description 61 | */ 62 | public function recordActivity($description) 63 | { 64 | $this->activity()->create([ 65 | 'user_id' => ($this->project ?? $this)->owner->id, 66 | 'description' => $description, 67 | 'changes' => $this->activityChanges(), 68 | 'project_id' => class_basename($this) === 'Project' ? $this->id : $this->project_id 69 | ]); 70 | } 71 | 72 | /** 73 | * The activity feed for the project. 74 | * 75 | * @return \Illuminate\Database\Eloquent\Relations\MorphMany 76 | */ 77 | public function activity() 78 | { 79 | if (get_class($this) === Project::class) { 80 | return $this->hasMany(Activity::class)->latest(); 81 | } 82 | 83 | return $this->morphMany(Activity::class, 'subject')->latest(); 84 | } 85 | 86 | /** 87 | * Fetch the changes to the model. 88 | * 89 | * @return array|null 90 | */ 91 | protected function activityChanges() 92 | { 93 | if ($this->wasChanged()) { 94 | return [ 95 | 'before' => array_except( 96 | array_diff($this->oldAttributes, $this->getAttributes()), 'updated_at' 97 | ), 98 | 'after' => array_except( 99 | $this->getChanges(), 'updated_at' 100 | ) 101 | ]; 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /website/app/Task.php: -------------------------------------------------------------------------------- 1 | 'boolean' 32 | ]; 33 | 34 | /** 35 | * Model events that should trigger new activity. 36 | * 37 | * @var array 38 | */ 39 | protected static $recordableEvents = ['created', 'deleted']; 40 | 41 | /** 42 | * Mark the task as complete. 43 | */ 44 | public function complete() 45 | { 46 | $this->update(['completed' => true]); 47 | 48 | $this->recordActivity('completed_task'); 49 | } 50 | 51 | /** 52 | * Mark the task as incomplete. 53 | */ 54 | public function incomplete() 55 | { 56 | $this->update(['completed' => false]); 57 | 58 | $this->recordActivity('incompleted_task'); 59 | } 60 | 61 | /** 62 | * Get the owning project. 63 | * 64 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 65 | */ 66 | public function project() 67 | { 68 | return $this->belongsTo(Project::class); 69 | } 70 | 71 | /** 72 | * Get the path to the task. 73 | * 74 | * @return string 75 | */ 76 | public function path() 77 | { 78 | return "/projects/{$this->project->id}/tasks/{$this->id}"; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /website/app/User.php: -------------------------------------------------------------------------------- 1 | hasMany(Project::class, 'owner_id')->latest('updated_at'); 41 | } 42 | 43 | /** 44 | * Get all projects that the user has access to. 45 | * 46 | * @return mixed 47 | */ 48 | public function accessibleProjects() 49 | { 50 | return Project::where('owner_id', $this->id) 51 | ->orWhereHas('members', function ($query) { 52 | $query->where('user_id', $this->id); 53 | }) 54 | ->get(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /website/app/helpers.php: -------------------------------------------------------------------------------- 1 | 60, 15 | 'd' => 'https://s3.amazonaws.com/laracasts/images/default-square-avatar.jpg' 16 | ]); 17 | } 18 | -------------------------------------------------------------------------------- /website/artisan: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | make(Illuminate\Contracts\Console\Kernel::class); 35 | 36 | $status = $kernel->handle( 37 | $input = new Symfony\Component\Console\Input\ArgvInput, 38 | new Symfony\Component\Console\Output\ConsoleOutput 39 | ); 40 | 41 | /* 42 | |-------------------------------------------------------------------------- 43 | | Shutdown The Application 44 | |-------------------------------------------------------------------------- 45 | | 46 | | Once Artisan has finished running, we will fire off the shutdown events 47 | | so that any final work may be done by the application before we shut 48 | | down the process. This is the last thing to happen to the request. 49 | | 50 | */ 51 | 52 | $kernel->terminate($input, $status); 53 | 54 | exit($status); 55 | -------------------------------------------------------------------------------- /website/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laravel/laravel", 3 | "type": "project", 4 | "description": "The Laravel Framework.", 5 | "keywords": [ 6 | "framework", 7 | "laravel" 8 | ], 9 | "repositories": [ 10 | { 11 | "type": "path", 12 | "url": "../Laravel.ComposerDummy" 13 | } 14 | ], 15 | "license": "MIT", 16 | "require": { 17 | "php": "^7.1.3", 18 | "calvinbaart/laravel-sdk": "*", 19 | "barryvdh/laravel-ide-helper": "^2.5" 20 | }, 21 | "config": { 22 | "optimize-autoloader": true, 23 | "preferred-install": "dist", 24 | "sort-packages": true 25 | }, 26 | "extra": { 27 | "laravel": { 28 | "dont-discover": [] 29 | } 30 | }, 31 | "autoload": { 32 | "psr-4": { 33 | "App\\": "app/" 34 | }, 35 | "classmap": [ 36 | "database/seeds", 37 | "database/factories" 38 | ], 39 | "files": [ 40 | "app/helpers.php" 41 | ] 42 | }, 43 | "autoload-dev": { 44 | "psr-4": { 45 | "Tests\\": "tests/" 46 | } 47 | }, 48 | "minimum-stability": "dev", 49 | "prefer-stable": true, 50 | "scripts": { 51 | "post-create-project-cmd": [ 52 | "@php artisan key:generate --ansi" 53 | ] 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /website/config/broadcasting.php: -------------------------------------------------------------------------------- 1 | env('BROADCAST_DRIVER', 'null'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Broadcast Connections 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may define all of the broadcast connections that will be used 26 | | to broadcast events to other systems or over websockets. Samples of 27 | | each available type of connection are provided inside this array. 28 | | 29 | */ 30 | 31 | 'connections' => [ 32 | 33 | 'pusher' => [ 34 | 'driver' => 'pusher', 35 | 'key' => env('PUSHER_APP_KEY'), 36 | 'secret' => env('PUSHER_APP_SECRET'), 37 | 'app_id' => env('PUSHER_APP_ID'), 38 | 'options' => [ 39 | 'cluster' => env('PUSHER_APP_CLUSTER'), 40 | 'encrypted' => true, 41 | ], 42 | ], 43 | 44 | 'redis' => [ 45 | 'driver' => 'redis', 46 | 'connection' => 'default', 47 | ], 48 | 49 | 'log' => [ 50 | 'driver' => 'log', 51 | ], 52 | 53 | 'null' => [ 54 | 'driver' => 'null', 55 | ], 56 | 57 | ], 58 | 59 | ]; 60 | -------------------------------------------------------------------------------- /website/config/cache.php: -------------------------------------------------------------------------------- 1 | env('CACHE_DRIVER', 'file'), 21 | 22 | /* 23 | |-------------------------------------------------------------------------- 24 | | Cache Stores 25 | |-------------------------------------------------------------------------- 26 | | 27 | | Here you may define all of the cache "stores" for your application as 28 | | well as their drivers. You may even define multiple stores for the 29 | | same cache driver to group types of items stored in your caches. 30 | | 31 | */ 32 | 33 | 'stores' => [ 34 | 35 | 'apc' => [ 36 | 'driver' => 'apc', 37 | ], 38 | 39 | 'array' => [ 40 | 'driver' => 'array', 41 | ], 42 | 43 | 'database' => [ 44 | 'driver' => 'database', 45 | 'table' => 'cache', 46 | 'connection' => null, 47 | ], 48 | 49 | 'file' => [ 50 | 'driver' => 'file', 51 | 'path' => storage_path('framework/cache/data'), 52 | ], 53 | 54 | 'memcached' => [ 55 | 'driver' => 'memcached', 56 | 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), 57 | 'sasl' => [ 58 | env('MEMCACHED_USERNAME'), 59 | env('MEMCACHED_PASSWORD'), 60 | ], 61 | 'options' => [ 62 | // Memcached::OPT_CONNECT_TIMEOUT => 2000, 63 | ], 64 | 'servers' => [ 65 | [ 66 | 'host' => env('MEMCACHED_HOST', '127.0.0.1'), 67 | 'port' => env('MEMCACHED_PORT', 11211), 68 | 'weight' => 100, 69 | ], 70 | ], 71 | ], 72 | 73 | 'redis' => [ 74 | 'driver' => 'redis', 75 | 'connection' => 'cache', 76 | ], 77 | 78 | ], 79 | 80 | /* 81 | |-------------------------------------------------------------------------- 82 | | Cache Key Prefix 83 | |-------------------------------------------------------------------------- 84 | | 85 | | When utilizing a RAM based store such as APC or Memcached, there might 86 | | be other applications utilizing the same cache. So, we'll specify a 87 | | value to get prefixed to all our keys so we can avoid collisions. 88 | | 89 | */ 90 | 91 | 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache'), 92 | 93 | ]; 94 | -------------------------------------------------------------------------------- /website/config/debug-server.php: -------------------------------------------------------------------------------- 1 | 'tcp://127.0.0.1:9912', 8 | ]; 9 | -------------------------------------------------------------------------------- /website/config/filesystems.php: -------------------------------------------------------------------------------- 1 | env('FILESYSTEM_DRIVER', 'local'), 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Default Cloud Filesystem Disk 21 | |-------------------------------------------------------------------------- 22 | | 23 | | Many applications store files both locally and in the cloud. For this 24 | | reason, you may specify a default "cloud" driver here. This driver 25 | | will be bound as the Cloud disk implementation in the container. 26 | | 27 | */ 28 | 29 | 'cloud' => env('FILESYSTEM_CLOUD', 's3'), 30 | 31 | /* 32 | |-------------------------------------------------------------------------- 33 | | Filesystem Disks 34 | |-------------------------------------------------------------------------- 35 | | 36 | | Here you may configure as many filesystem "disks" as you wish, and you 37 | | may even configure multiple disks of the same driver. Defaults have 38 | | been setup for each driver as an example of the required options. 39 | | 40 | | Supported Drivers: "local", "ftp", "sftp", "s3", "rackspace" 41 | | 42 | */ 43 | 44 | 'disks' => [ 45 | 46 | 'local' => [ 47 | 'driver' => 'local', 48 | 'root' => storage_path('app'), 49 | ], 50 | 51 | 'public' => [ 52 | 'driver' => 'local', 53 | 'root' => storage_path('app/public'), 54 | 'url' => env('APP_URL').'/storage', 55 | 'visibility' => 'public', 56 | ], 57 | 58 | 's3' => [ 59 | 'driver' => 's3', 60 | 'key' => env('AWS_ACCESS_KEY_ID'), 61 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 62 | 'region' => env('AWS_DEFAULT_REGION'), 63 | 'bucket' => env('AWS_BUCKET'), 64 | 'url' => env('AWS_URL'), 65 | ], 66 | 67 | ], 68 | 69 | ]; 70 | -------------------------------------------------------------------------------- /website/config/hashing.php: -------------------------------------------------------------------------------- 1 | 'bcrypt', 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Bcrypt Options 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may specify the configuration options that should be used when 26 | | passwords are hashed using the Bcrypt algorithm. This will allow you 27 | | to control the amount of time it takes to hash the given password. 28 | | 29 | */ 30 | 31 | 'bcrypt' => [ 32 | 'rounds' => env('BCRYPT_ROUNDS', 10), 33 | ], 34 | 35 | /* 36 | |-------------------------------------------------------------------------- 37 | | Argon Options 38 | |-------------------------------------------------------------------------- 39 | | 40 | | Here you may specify the configuration options that should be used when 41 | | passwords are hashed using the Argon algorithm. These will allow you 42 | | to control the amount of time it takes to hash the given password. 43 | | 44 | */ 45 | 46 | 'argon' => [ 47 | 'memory' => 1024, 48 | 'threads' => 2, 49 | 'time' => 2, 50 | ], 51 | 52 | ]; 53 | -------------------------------------------------------------------------------- /website/config/logging.php: -------------------------------------------------------------------------------- 1 | env('LOG_CHANNEL', 'stack'), 20 | 21 | /* 22 | |-------------------------------------------------------------------------- 23 | | Log Channels 24 | |-------------------------------------------------------------------------- 25 | | 26 | | Here you may configure the log channels for your application. Out of 27 | | the box, Laravel uses the Monolog PHP logging library. This gives 28 | | you a variety of powerful log handlers / formatters to utilize. 29 | | 30 | | Available Drivers: "single", "daily", "slack", "syslog", 31 | | "errorlog", "monolog", 32 | | "custom", "stack" 33 | | 34 | */ 35 | 36 | 'channels' => [ 37 | 'stack' => [ 38 | 'driver' => 'stack', 39 | 'channels' => ['daily'], 40 | ], 41 | 42 | 'single' => [ 43 | 'driver' => 'single', 44 | 'path' => storage_path('logs/laravel.log'), 45 | 'level' => 'debug', 46 | ], 47 | 48 | 'daily' => [ 49 | 'driver' => 'daily', 50 | 'path' => storage_path('logs/laravel.log'), 51 | 'level' => 'debug', 52 | 'days' => 14, 53 | ], 54 | 55 | 'slack' => [ 56 | 'driver' => 'slack', 57 | 'url' => env('LOG_SLACK_WEBHOOK_URL'), 58 | 'username' => 'Laravel Log', 59 | 'emoji' => ':boom:', 60 | 'level' => 'critical', 61 | ], 62 | 63 | 'papertrail' => [ 64 | 'driver' => 'monolog', 65 | 'level' => 'debug', 66 | 'handler' => SyslogUdpHandler::class, 67 | 'handler_with' => [ 68 | 'host' => env('PAPERTRAIL_URL'), 69 | 'port' => env('PAPERTRAIL_PORT'), 70 | ], 71 | ], 72 | 73 | 'stderr' => [ 74 | 'driver' => 'monolog', 75 | 'handler' => StreamHandler::class, 76 | 'formatter' => env('LOG_STDERR_FORMATTER'), 77 | 'with' => [ 78 | 'stream' => 'php://stderr', 79 | ], 80 | ], 81 | 82 | 'syslog' => [ 83 | 'driver' => 'syslog', 84 | 'level' => 'debug', 85 | ], 86 | 87 | 'errorlog' => [ 88 | 'driver' => 'errorlog', 89 | 'level' => 'debug', 90 | ], 91 | ], 92 | 93 | ]; 94 | -------------------------------------------------------------------------------- /website/config/queue.php: -------------------------------------------------------------------------------- 1 | env('QUEUE_CONNECTION', 'sync'), 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Queue Connections 21 | |-------------------------------------------------------------------------- 22 | | 23 | | Here you may configure the connection information for each server that 24 | | is used by your application. A default configuration has been added 25 | | for each back-end shipped with Laravel. You are free to add more. 26 | | 27 | | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null" 28 | | 29 | */ 30 | 31 | 'connections' => [ 32 | 33 | 'sync' => [ 34 | 'driver' => 'sync', 35 | ], 36 | 37 | 'database' => [ 38 | 'driver' => 'database', 39 | 'table' => 'jobs', 40 | 'queue' => 'default', 41 | 'retry_after' => 90, 42 | ], 43 | 44 | 'beanstalkd' => [ 45 | 'driver' => 'beanstalkd', 46 | 'host' => 'localhost', 47 | 'queue' => 'default', 48 | 'retry_after' => 90, 49 | ], 50 | 51 | 'sqs' => [ 52 | 'driver' => 'sqs', 53 | 'key' => env('SQS_KEY', 'your-public-key'), 54 | 'secret' => env('SQS_SECRET', 'your-secret-key'), 55 | 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), 56 | 'queue' => env('SQS_QUEUE', 'your-queue-name'), 57 | 'region' => env('SQS_REGION', 'us-east-1'), 58 | ], 59 | 60 | 'redis' => [ 61 | 'driver' => 'redis', 62 | 'connection' => 'default', 63 | 'queue' => env('REDIS_QUEUE', 'default'), 64 | 'retry_after' => 90, 65 | 'block_for' => null, 66 | ], 67 | 68 | ], 69 | 70 | /* 71 | |-------------------------------------------------------------------------- 72 | | Failed Queue Jobs 73 | |-------------------------------------------------------------------------- 74 | | 75 | | These options configure the behavior of failed queue job logging so you 76 | | can control which database and table are used to store the jobs that 77 | | have failed. You may change them to any database / table you wish. 78 | | 79 | */ 80 | 81 | 'failed' => [ 82 | 'database' => env('DB_CONNECTION', 'mysql'), 83 | 'table' => 'failed_jobs', 84 | ], 85 | 86 | ]; 87 | -------------------------------------------------------------------------------- /website/config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), 21 | ], 22 | 23 | 'ses' => [ 24 | 'key' => env('SES_KEY'), 25 | 'secret' => env('SES_SECRET'), 26 | 'region' => env('SES_REGION', 'us-east-1'), 27 | ], 28 | 29 | 'sparkpost' => [ 30 | 'secret' => env('SPARKPOST_SECRET'), 31 | ], 32 | 33 | 'stripe' => [ 34 | 'model' => App\User::class, 35 | 'key' => env('STRIPE_KEY'), 36 | 'secret' => env('STRIPE_SECRET'), 37 | 'webhook' => [ 38 | 'secret' => env('STRIPE_WEBHOOK_SECRET'), 39 | 'tolerance' => env('STRIPE_WEBHOOK_TOLERANCE', 300), 40 | ], 41 | ], 42 | 43 | ]; 44 | -------------------------------------------------------------------------------- /website/config/tinker.php: -------------------------------------------------------------------------------- 1 | [ 17 | // App\Console\Commands\ExampleCommand::class, 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Alias Blacklist 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Typically, Tinker automatically aliases classes as you require them in 26 | | Tinker. However, you may wish to never alias certain classes, which 27 | | you may accomplish by listing the classes in the following array. 28 | | 29 | */ 30 | 31 | 'dont_alias' => [], 32 | 33 | ]; 34 | -------------------------------------------------------------------------------- /website/config/trustedproxy.php: -------------------------------------------------------------------------------- 1 | null, // [,], '*', ',' 19 | 20 | /* 21 | * To trust one or more specific proxies that connect 22 | * directly to your server, use an array or a string separated by comma of IP addresses: 23 | */ 24 | // 'proxies' => ['192.168.1.1'], 25 | // 'proxies' => '192.168.1.1, 192.168.1.2', 26 | 27 | /* 28 | * Or, to trust all proxies that connect 29 | * directly to your server, use a "*" 30 | */ 31 | // 'proxies' => '*', 32 | 33 | /* 34 | * Which headers to use to detect proxy related data (For, Host, Proto, Port) 35 | * 36 | * Options include: 37 | * 38 | * - Illuminate\Http\Request::HEADER_X_FORWARDED_ALL (use all x-forwarded-* headers to establish trust) 39 | * - Illuminate\Http\Request::HEADER_FORWARDED (use the FORWARDED header to establish trust) 40 | * - Illuminate\Http\Request::HEADER_X_FORWARDED_AWS_ELB (If you are using AWS Elastic Load Balancer) 41 | * 42 | * - 'HEADER_X_FORWARDED_ALL' (use all x-forwarded-* headers to establish trust) 43 | * - 'HEADER_FORWARDED' (use the FORWARDED header to establish trust) 44 | * - 'HEADER_X_FORWARDED_AWS_ELB' (If you are using AWS Elastic Load Balancer) 45 | * 46 | * @link https://symfony.com/doc/current/deployment/proxies.html 47 | */ 48 | 'headers' => Illuminate\Http\Request::HEADER_X_FORWARDED_ALL, 49 | 50 | ]; 51 | -------------------------------------------------------------------------------- /website/config/view.php: -------------------------------------------------------------------------------- 1 | [ 17 | resource_path('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' => env( 32 | 'VIEW_COMPILED_PATH', 33 | realpath(storage_path('framework/views')) 34 | ), 35 | 36 | ]; 37 | -------------------------------------------------------------------------------- /website/database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | -------------------------------------------------------------------------------- /website/database/factories/ProjectFactory.php: -------------------------------------------------------------------------------- 1 | define(App\Project::class, function (Faker $faker) { 6 | return [ 7 | 'title' => $faker->sentence(4), 8 | 'description' => $faker->sentence(4), 9 | 'notes' => 'Foobar notes', 10 | 'owner_id' => factory(App\User::class) 11 | ]; 12 | }); 13 | -------------------------------------------------------------------------------- /website/database/factories/TaskFactory.php: -------------------------------------------------------------------------------- 1 | define(App\Task::class, function (Faker $faker) { 6 | return [ 7 | 'body' => $faker->sentence, 8 | 'project_id' => factory(\App\Project::class), 9 | 'completed' => false 10 | ]; 11 | }); 12 | -------------------------------------------------------------------------------- /website/database/factories/UserFactory.php: -------------------------------------------------------------------------------- 1 | define(App\User::class, function (Faker $faker) { 17 | return [ 18 | 'name' => $faker->name, 19 | 'email' => $faker->unique()->safeEmail, 20 | 'email_verified_at' => now(), 21 | 'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret 22 | 'remember_token' => str_random(10), 23 | ]; 24 | }); 25 | -------------------------------------------------------------------------------- /website/database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->string('name'); 19 | $table->string('email')->unique(); 20 | $table->timestamp('email_verified_at')->nullable(); 21 | $table->string('password'); 22 | $table->rememberToken(); 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('users'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /website/database/migrations/2014_10_12_100000_create_password_resets_table.php: -------------------------------------------------------------------------------- 1 | string('email')->index(); 18 | $table->string('token'); 19 | $table->timestamp('created_at')->nullable(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('password_resets'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /website/database/migrations/2018_12_17_150648_create_projects_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->unsignedInteger('owner_id'); 19 | $table->string('title'); 20 | $table->text('description'); 21 | $table->text('notes')->nullable(); 22 | $table->timestamps(); 23 | 24 | $table->foreign('owner_id')->references('id')->on('users')->onDelete('cascade'); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('projects'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /website/database/migrations/2019_01_12_191142_create_tasks_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->unsignedInteger('project_id'); 19 | $table->text('body'); 20 | $table->boolean('completed')->default(false); 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | * 28 | * @return void 29 | */ 30 | public function down() 31 | { 32 | Schema::dropIfExists('tasks'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /website/database/migrations/2019_01_24_143508_create_activities_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->unsignedInteger('user_id'); 19 | $table->unsignedInteger('project_id'); 20 | $table->nullableMorphs('subject'); 21 | $table->string('description'); 22 | $table->text('changes')->nullable(); 23 | $table->timestamps(); 24 | 25 | $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); 26 | $table->foreign('project_id')->references('id')->on('projects')->onDelete('cascade'); 27 | }); 28 | } 29 | 30 | /** 31 | * Reverse the migrations. 32 | * 33 | * @return void 34 | */ 35 | public function down() 36 | { 37 | Schema::dropIfExists('activities'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /website/database/migrations/2019_02_27_181525_create_project_members_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->unsignedInteger('project_id'); 19 | $table->unsignedInteger('user_id'); 20 | $table->timestamps(); 21 | 22 | $table->index(['project_id', 'user_id']); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('project_members'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /website/database/seeds/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | call(UsersTableSeeder::class); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "npm run development", 5 | "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 6 | "watch": "npm run development -- --watch", 7 | "watch-poll": "npm run watch -- --watch-poll", 8 | "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", 9 | "prod": "npm run production", 10 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" 11 | }, 12 | "devDependencies": { 13 | "axios": "^0.18", 14 | "bootstrap": "^4.0.0", 15 | "cross-env": "^5.1", 16 | "jquery": "^3.2", 17 | "laravel-mix": "^4.0.7", 18 | "laravel-mix-tailwind": "^0.1.0", 19 | "lodash": "^4.17.5", 20 | "popper.js": "^1.12", 21 | "resolve-url-loader": "^2.3.1", 22 | "sass": "^1.15.2", 23 | "sass-loader": "^7.1.0", 24 | "tailwindcss": "^0.7.3", 25 | "vue": "^2.5.17", 26 | "vue-template-compiler": "^2.5.21" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /website/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | ./tests/Unit 14 | 15 | 16 | 17 | ./tests/Feature 18 | 19 | 20 | 21 | 22 | ./app 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /website/public/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinbaart/laravel-peachpie-sample/6f186e73c567bd5d39caece127a8c2755a025cb2/website/public/.DS_Store -------------------------------------------------------------------------------- /website/public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews -Indexes 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Handle Authorization Header 9 | RewriteCond %{HTTP:Authorization} . 10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 11 | 12 | # Redirect Trailing Slashes If Not A Folder... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_URI} (.+)/$ 15 | RewriteRule ^ %1 [L,R=301] 16 | 17 | # Handle Front Controller... 18 | RewriteCond %{REQUEST_FILENAME} !-d 19 | RewriteCond %{REQUEST_FILENAME} !-f 20 | RewriteRule ^ index.php [L] 21 | 22 | -------------------------------------------------------------------------------- /website/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinbaart/laravel-peachpie-sample/6f186e73c567bd5d39caece127a8c2755a025cb2/website/public/favicon.ico -------------------------------------------------------------------------------- /website/public/mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/js/app.js": "/js/app.js", 3 | "/css/app.css": "/css/app.css" 4 | } 5 | -------------------------------------------------------------------------------- /website/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /website/resources/js/app.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * First we will load all of this project's JavaScript dependencies which 4 | * includes Vue and other libraries. It is a great starting point when 5 | * building robust, powerful web applications using Vue and Laravel. 6 | */ 7 | 8 | require('./bootstrap'); 9 | 10 | window.Vue = require('vue'); 11 | 12 | /** 13 | * The following block of code may be used to automatically register your 14 | * Vue components. It will recursively scan this directory for the Vue 15 | * components and automatically register them with their "basename". 16 | * 17 | * Eg. ./components/ExampleComponent.vue -> 18 | */ 19 | 20 | // const files = require.context('./', true, /\.vue$/i) 21 | // files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default)) 22 | 23 | Vue.component('theme-switcher', require('./components/ThemeSwitcher.vue').default); 24 | 25 | /** 26 | * Next, we will create a fresh Vue application instance and attach it to 27 | * the page. Then, you may begin adding components to this application 28 | * or customize the JavaScript scaffolding to fit your unique needs. 29 | */ 30 | 31 | const app = new Vue({ 32 | el: '#app' 33 | }); 34 | -------------------------------------------------------------------------------- /website/resources/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | 2 | window._ = require('lodash'); 3 | 4 | /** 5 | * We'll load jQuery and the Bootstrap jQuery plugin which provides support 6 | * for JavaScript based Bootstrap features such as modals and tabs. This 7 | * code may be modified to fit the specific needs of your application. 8 | */ 9 | 10 | try { 11 | window.Popper = require('popper.js').default; 12 | window.$ = window.jQuery = require('jquery'); 13 | 14 | require('bootstrap'); 15 | } catch (e) {} 16 | 17 | /** 18 | * We'll load the axios HTTP library which allows us to easily issue requests 19 | * to our Laravel back-end. This library automatically handles sending the 20 | * CSRF token as a header based on the value of the "XSRF" token cookie. 21 | */ 22 | 23 | window.axios = require('axios'); 24 | 25 | window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 26 | 27 | /** 28 | * Next we will register the CSRF Token as a common header with Axios so that 29 | * all outgoing HTTP requests automatically have it attached. This is just 30 | * a simple convenience so we don't have to attach every token manually. 31 | */ 32 | 33 | let token = document.head.querySelector('meta[name="csrf-token"]'); 34 | 35 | if (token) { 36 | window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content; 37 | } else { 38 | console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token'); 39 | } 40 | 41 | /** 42 | * Echo exposes an expressive API for subscribing to channels and listening 43 | * for events that are broadcast by Laravel. Echo and event broadcasting 44 | * allows your team to easily build robust real-time web applications. 45 | */ 46 | 47 | // import Echo from 'laravel-echo' 48 | 49 | // window.Pusher = require('pusher-js'); 50 | 51 | // window.Echo = new Echo({ 52 | // broadcaster: 'pusher', 53 | // key: process.env.MIX_PUSHER_APP_KEY, 54 | // cluster: process.env.MIX_PUSHER_APP_CLUSTER, 55 | // encrypted: true 56 | // }); 57 | -------------------------------------------------------------------------------- /website/resources/js/components/ThemeSwitcher.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 37 | -------------------------------------------------------------------------------- /website/resources/lang/en/auth.php: -------------------------------------------------------------------------------- 1 | 'These credentials do not match our records.', 17 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /website/resources/lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 'next' => 'Next »', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /website/resources/lang/en/passwords.php: -------------------------------------------------------------------------------- 1 | 'Passwords must be at least six characters and match the confirmation.', 17 | 'reset' => 'Your password has been reset!', 18 | 'sent' => 'We have e-mailed your password reset link!', 19 | 'token' => 'This password reset token is invalid.', 20 | 'user' => "We can't find a user with that e-mail address.", 21 | 22 | ]; 23 | -------------------------------------------------------------------------------- /website/resources/sass/app.scss: -------------------------------------------------------------------------------- 1 | @tailwind preflight; 2 | 3 | @import 'themes/light'; 4 | @import 'themes/dark'; 5 | 6 | @import 'components/button'; 7 | @import 'components/card'; 8 | 9 | body, 10 | button { 11 | @apply .text-default; 12 | } 13 | 14 | .section { 15 | @apply .px-8; 16 | } 17 | 18 | @tailwind utilities; 19 | -------------------------------------------------------------------------------- /website/resources/sass/components/button.scss: -------------------------------------------------------------------------------- 1 | .button { 2 | @apply .bg-button .no-underline .rounded-lg .text-sm .py-2 .px-5; 3 | color: white; 4 | 5 | .theme-light & { 6 | box-shadow: 0 2px 7px 0 #b0eaff; 7 | } 8 | 9 | .theme-dark & { 10 | box-shadow: 0 2px 7px 0 #00658b; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /website/resources/sass/components/card.scss: -------------------------------------------------------------------------------- 1 | .card { 2 | @apply .bg-card .p-5 .rounded-lg .shadow; 3 | } 4 | -------------------------------------------------------------------------------- /website/resources/sass/themes/dark.scss: -------------------------------------------------------------------------------- 1 | .theme-dark { 2 | --page-background-color: #17181e; 3 | --card-background-color: #1f2027; 4 | --button-background-color: #59b6f9; 5 | --header-background-color: #1f2027; 6 | 7 | --text-default-color: #fff; 8 | --text-muted-color: rgba(255, 255, 255, 0.5); 9 | --text-muted-light-color: rgba(255, 255, 255, 0.3); 10 | --text-accent-color: #47cdff; 11 | --text-accent-light-color: #8ae2fe; 12 | } 13 | -------------------------------------------------------------------------------- /website/resources/sass/themes/light.scss: -------------------------------------------------------------------------------- 1 | .theme-light { 2 | --page-background-color: #f5f6f9; 3 | --card-background-color: white; 4 | --button-background-color: #47cdff; 5 | --header-background-color: white; 6 | 7 | --text-default-color: #222; 8 | --text-accent-color: #47cdff; 9 | --text-accent-light-color: #8ae2fe; 10 | --text-muted-color: rgba(0, 0, 0, 0.3); 11 | --text-muted-light-color: rgba(255, 255, 255, 0.1); 12 | --text-muted-light-color: #e1e6e8; 13 | } 14 | -------------------------------------------------------------------------------- /website/resources/views/auth/login.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
7 | @csrf 8 | 9 |

Login

10 | 11 |
12 | 13 | 14 |
15 | 21 |
22 |
23 | 24 |
25 | 26 | 27 |
28 | 33 |
34 |
35 | 36 |
37 |
38 | 43 | 44 | 47 |
48 |
49 | 50 |
51 |
52 | 55 | 56 | @if (Route::has('password.request')) 57 | 58 | Forgot Your Password? 59 | 60 | @endif 61 |
62 |
63 |
64 | @endsection 65 | -------------------------------------------------------------------------------- /website/resources/views/auth/passwords/email.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |
7 |
8 |
{{ __('Reset Password') }}
9 | 10 |
11 | @if (session('status')) 12 | 15 | @endif 16 | 17 |
18 | @csrf 19 | 20 |
21 | 22 | 23 |
24 | 25 | 26 | @if ($errors->has('email')) 27 | 28 | {{ $errors->first('email') }} 29 | 30 | @endif 31 |
32 |
33 | 34 |
35 |
36 | 39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | @endsection 48 | -------------------------------------------------------------------------------- /website/resources/views/auth/register.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
7 | @csrf 8 | 9 |

Register

10 | 11 |
12 | 13 | 14 |
15 | 22 |
23 |
24 | 25 |
26 | 27 | 28 |
29 | 35 |
36 |
37 | 38 |
39 | 40 | 41 |
42 | 47 |
48 |
49 | 50 |
51 | 52 | 53 |
54 | 59 |
60 |
61 | 62 |
63 |
64 | 65 |
66 |
67 |
68 | @endsection 69 | -------------------------------------------------------------------------------- /website/resources/views/auth/verify.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |
7 |
8 |
{{ __('Verify Your Email Address') }}
9 | 10 |
11 | @if (session('resent')) 12 | 15 | @endif 16 | 17 | {{ __('Before proceeding, please check your email for a verification link.') }} 18 | {{ __('If you did not receive the email') }}, {{ __('click here to request another') }}. 19 |
20 |
21 |
22 |
23 |
24 | @endsection 25 | -------------------------------------------------------------------------------- /website/resources/views/errors.blade.php: -------------------------------------------------------------------------------- 1 | @if ($errors->{ $bag ?? 'default' }->any()) 2 |
    3 | @foreach ($errors->{ $bag ?? 'default' }->all() as $error) 4 |
  • {{ $error }}
  • 5 | @endforeach 6 |
7 | @endif 8 | -------------------------------------------------------------------------------- /website/resources/views/errors/401.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors::minimal') 2 | 3 | @section('title', __('Unauthorized')) 4 | @section('code', '401') 5 | @section('message', __('Unauthorized')) 6 | -------------------------------------------------------------------------------- /website/resources/views/errors/403.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors::minimal') 2 | 3 | @section('title', __('Forbidden')) 4 | @section('code', '403') 5 | @section('message', __($exception->getMessage() ?: 'Forbidden')) 6 | -------------------------------------------------------------------------------- /website/resources/views/errors/404.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors::minimal') 2 | 3 | @section('title', __('Not Found')) 4 | @section('code', '404') 5 | @section('message', __('Not Found')) 6 | -------------------------------------------------------------------------------- /website/resources/views/errors/419.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors::minimal') 2 | 3 | @section('title', __('Page Expired')) 4 | @section('code', '419') 5 | @section('message', __('Page Expired')) 6 | -------------------------------------------------------------------------------- /website/resources/views/errors/429.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors::minimal') 2 | 3 | @section('title', __('Too Many Requests')) 4 | @section('code', '429') 5 | @section('message', __('Too Many Requests')) 6 | -------------------------------------------------------------------------------- /website/resources/views/errors/500.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors::minimal') 2 | 3 | @section('title', __('Server Error')) 4 | @section('code', '500') 5 | @section('message', __('Server Error')) 6 | -------------------------------------------------------------------------------- /website/resources/views/errors/503.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors::minimal') 2 | 3 | @section('title', __('Service Unavailable')) 4 | @section('code', '503') 5 | @section('message', __($exception->getMessage() ?: 'Service Unavailable')) 6 | -------------------------------------------------------------------------------- /website/resources/views/errors/layout.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | @yield('title') 8 | 9 | 10 | 11 | 12 | 13 | 14 | 47 | 48 | 49 |
50 |
51 |
52 | @yield('message') 53 |
54 |
55 |
56 | 57 | 58 | -------------------------------------------------------------------------------- /website/resources/views/errors/minimal.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | @yield('title') 8 | 9 | 10 | 11 | 12 | 13 | 14 | 50 | 51 | 52 |
53 |
54 | @yield('code') 55 |
56 | 57 |
58 | @yield('message') 59 |
60 |
61 | 62 | 63 | -------------------------------------------------------------------------------- /website/resources/views/home.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |
7 |
8 |
Dashboard
9 | 10 |
11 | @if (session('status')) 12 | 15 | @endif 16 | 17 | You are logged in! 18 |
19 |
20 |
21 |
22 |
23 | @endsection 24 | -------------------------------------------------------------------------------- /website/resources/views/projects/activity/card.blade.php: -------------------------------------------------------------------------------- 1 |
2 |
    3 | @foreach ($project->activity as $activity) 4 |
  • 5 | @include ("projects.activity.{$activity->description}") 6 | {{ $activity->created_at->diffForHumans(null, true) }} 7 |
  • 8 | @endforeach 9 |
10 |
11 | -------------------------------------------------------------------------------- /website/resources/views/projects/activity/completed_task.blade.php: -------------------------------------------------------------------------------- 1 | {{ $activity->user->name }} completed "{{ $activity->subject->body }}" 2 | -------------------------------------------------------------------------------- /website/resources/views/projects/activity/created_project.blade.php: -------------------------------------------------------------------------------- 1 | {{ $activity->user->name }} created the project 2 | -------------------------------------------------------------------------------- /website/resources/views/projects/activity/created_task.blade.php: -------------------------------------------------------------------------------- 1 | {{ $activity->user->name }} created "{{ $activity->subject->body }}" 2 | -------------------------------------------------------------------------------- /website/resources/views/projects/activity/incompleted_task.blade.php: -------------------------------------------------------------------------------- 1 | {{ $activity->user->name }} incompleted "{{ $activity->subject->body }}" 2 | -------------------------------------------------------------------------------- /website/resources/views/projects/activity/updated_project.blade.php: -------------------------------------------------------------------------------- 1 | @if (count($activity->changes['after']) == 1) 2 | {{ $activity->user->name }} updated the {{ key($activity->changes['after']) }} of the project 3 | @else 4 | {{ $activity->user->name }} updated the project 5 | @endif -------------------------------------------------------------------------------- /website/resources/views/projects/card.blade.php: -------------------------------------------------------------------------------- 1 |
2 |

3 | {{ $project->title }} 4 |

5 | 6 |
{{ str_limit($project->description, 100) }}
7 | 8 | @can ('manage', $project) 9 |
10 |
11 | @method('DELETE') 12 | @csrf 13 | 14 |
15 |
16 | @endcan 17 |
18 | -------------------------------------------------------------------------------- /website/resources/views/projects/create.blade.php: -------------------------------------------------------------------------------- 1 | @extends ('layouts.app') 2 | 3 | @section('content') 4 |
5 |

6 | Let's start something new 7 |

8 | 9 |
13 | @include ('projects.form', [ 14 | 'project' => new App\Project, 15 | 'buttonText' => 'Create Project' 16 | ]) 17 |
18 |
19 | @endsection 20 | -------------------------------------------------------------------------------- /website/resources/views/projects/edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends ('layouts.app') 2 | 3 | @section('content') 4 |
5 |

6 | Edit Your Project 7 |

8 | 9 |
13 | @method('PATCH') 14 | 15 | @include ('projects.form', [ 16 | 'buttonText' => 'Update Project' 17 | ]) 18 |
19 |
20 | @endsection 21 | -------------------------------------------------------------------------------- /website/resources/views/projects/form.blade.php: -------------------------------------------------------------------------------- 1 | @csrf 2 | 3 |
4 | 5 | 6 |
7 | 14 |
15 |
16 | 17 |
18 | 19 | 20 |
21 | 27 |
28 |
29 | 30 |
31 |
32 | 33 | 34 | Cancel 35 |
36 |
37 | 38 | @include ('errors') 39 | -------------------------------------------------------------------------------- /website/resources/views/projects/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends ('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |

My Projects

7 | 8 | New Project 9 |
10 |
11 | 12 |
13 | @forelse ($projects as $project) 14 |
15 | @include ('projects.card') 16 |
17 | @empty 18 |
No projects yet.
19 | @endforelse 20 |
21 | @endsection 22 | -------------------------------------------------------------------------------- /website/resources/views/projects/invite.blade.php: -------------------------------------------------------------------------------- 1 |
2 |

3 | Invite a User 4 |

5 | 6 |
7 | @csrf 8 | 9 |
10 | 11 |
12 | 13 | 14 |
15 | 16 | @include ('errors', ['bag' => 'invitations']) 17 |
18 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/html/button.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18 | 19 |
4 | 5 | 6 | 15 | 16 |
7 | 8 | 9 | 12 | 13 |
10 | {{ $slot }} 11 |
14 |
17 |
20 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/html/footer.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/html/header.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ $slot }} 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/html/layout.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 25 | 26 | 27 | 28 | 51 | 52 |
29 | 30 | {{ $header ?? '' }} 31 | 32 | 33 | 34 | 46 | 47 | 48 | {{ $footer ?? '' }} 49 |
35 | 36 | 37 | 38 | 43 | 44 |
39 | {{ Illuminate\Mail\Markdown::parse($slot) }} 40 | 41 | {{ $subcopy ?? '' }} 42 |
45 |
50 |
53 | 54 | 55 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/html/message.blade.php: -------------------------------------------------------------------------------- 1 | @component('mail::layout') 2 | {{-- Header --}} 3 | @slot('header') 4 | @component('mail::header', ['url' => config('app.url')]) 5 | {{ config('app.name') }} 6 | @endcomponent 7 | @endslot 8 | 9 | {{-- Body --}} 10 | {{ $slot }} 11 | 12 | {{-- Subcopy --}} 13 | @isset($subcopy) 14 | @slot('subcopy') 15 | @component('mail::subcopy') 16 | {{ $subcopy }} 17 | @endcomponent 18 | @endslot 19 | @endisset 20 | 21 | {{-- Footer --}} 22 | @slot('footer') 23 | @component('mail::footer') 24 | © {{ date('Y') }} {{ config('app.name') }}. @lang('All rights reserved.') 25 | @endcomponent 26 | @endslot 27 | @endcomponent 28 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/html/panel.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 |
4 | 5 | 6 | 9 | 10 |
7 | {{ Illuminate\Mail\Markdown::parse($slot) }} 8 |
11 |
14 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/html/promotion.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 |
4 | {{ Illuminate\Mail\Markdown::parse($slot) }} 5 |
8 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/html/promotion/button.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 |
4 | 5 | 6 | 9 | 10 |
7 | {{ $slot }} 8 |
11 |
14 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/html/subcopy.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 |
4 | {{ Illuminate\Mail\Markdown::parse($slot) }} 5 |
8 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/html/table.blade.php: -------------------------------------------------------------------------------- 1 |
2 | {{ Illuminate\Mail\Markdown::parse($slot) }} 3 |
4 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/text/button.blade.php: -------------------------------------------------------------------------------- 1 | {{ $slot }}: {{ $url }} 2 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/text/footer.blade.php: -------------------------------------------------------------------------------- 1 | {{ $slot }} 2 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/text/header.blade.php: -------------------------------------------------------------------------------- 1 | [{{ $slot }}]({{ $url }}) 2 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/text/layout.blade.php: -------------------------------------------------------------------------------- 1 | {!! strip_tags($header) !!} 2 | 3 | {!! strip_tags($slot) !!} 4 | @isset($subcopy) 5 | 6 | {!! strip_tags($subcopy) !!} 7 | @endisset 8 | 9 | {!! strip_tags($footer) !!} 10 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/text/message.blade.php: -------------------------------------------------------------------------------- 1 | @component('mail::layout') 2 | {{-- Header --}} 3 | @slot('header') 4 | @component('mail::header', ['url' => config('app.url')]) 5 | {{ config('app.name') }} 6 | @endcomponent 7 | @endslot 8 | 9 | {{-- Body --}} 10 | {{ $slot }} 11 | 12 | {{-- Subcopy --}} 13 | @isset($subcopy) 14 | @slot('subcopy') 15 | @component('mail::subcopy') 16 | {{ $subcopy }} 17 | @endcomponent 18 | @endslot 19 | @endisset 20 | 21 | {{-- Footer --}} 22 | @slot('footer') 23 | @component('mail::footer') 24 | © {{ date('Y') }} {{ config('app.name') }}. @lang('All rights reserved.') 25 | @endcomponent 26 | @endslot 27 | @endcomponent 28 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/text/panel.blade.php: -------------------------------------------------------------------------------- 1 | {{ $slot }} 2 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/text/promotion.blade.php: -------------------------------------------------------------------------------- 1 | {{ $slot }} 2 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/text/promotion/button.blade.php: -------------------------------------------------------------------------------- 1 | [{{ $slot }}]({{ $url }}) 2 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/text/subcopy.blade.php: -------------------------------------------------------------------------------- 1 | {{ $slot }} 2 | -------------------------------------------------------------------------------- /website/resources/views/vendor/mail/text/table.blade.php: -------------------------------------------------------------------------------- 1 | {{ $slot }} 2 | -------------------------------------------------------------------------------- /website/resources/views/vendor/notifications/email.blade.php: -------------------------------------------------------------------------------- 1 | @component('mail::message') 2 | {{-- Greeting --}} 3 | @if (! empty($greeting)) 4 | # {{ $greeting }} 5 | @else 6 | @if ($level === 'error') 7 | # @lang('Whoops!') 8 | @else 9 | # @lang('Hello!') 10 | @endif 11 | @endif 12 | 13 | {{-- Intro Lines --}} 14 | @foreach ($introLines as $line) 15 | {{ $line }} 16 | 17 | @endforeach 18 | 19 | {{-- Action Button --}} 20 | @isset($actionText) 21 | 31 | @component('mail::button', ['url' => $actionUrl, 'color' => $color]) 32 | {{ $actionText }} 33 | @endcomponent 34 | @endisset 35 | 36 | {{-- Outro Lines --}} 37 | @foreach ($outroLines as $line) 38 | {{ $line }} 39 | 40 | @endforeach 41 | 42 | {{-- Salutation --}} 43 | @if (! empty($salutation)) 44 | {{ $salutation }} 45 | @else 46 | @lang('Regards'),
{{ config('app.name') }} 47 | @endif 48 | 49 | {{-- Subcopy --}} 50 | @isset($actionText) 51 | @slot('subcopy') 52 | @lang( 53 | "If you’re having trouble clicking the \":actionText\" button, copy and paste the URL below\n". 54 | 'into your web browser: [:actionURL](:actionURL)', 55 | [ 56 | 'actionText' => $actionText, 57 | 'actionURL' => $actionUrl, 58 | ] 59 | ) 60 | @endslot 61 | @endisset 62 | @endcomponent 63 | -------------------------------------------------------------------------------- /website/resources/views/vendor/pagination/bootstrap-4.blade.php: -------------------------------------------------------------------------------- 1 | @if ($paginator->hasPages()) 2 | 44 | @endif 45 | -------------------------------------------------------------------------------- /website/resources/views/vendor/pagination/default.blade.php: -------------------------------------------------------------------------------- 1 | @if ($paginator->hasPages()) 2 | 44 | @endif 45 | -------------------------------------------------------------------------------- /website/resources/views/vendor/pagination/semantic-ui.blade.php: -------------------------------------------------------------------------------- 1 | @if ($paginator->hasPages()) 2 | 36 | @endif 37 | -------------------------------------------------------------------------------- /website/resources/views/vendor/pagination/simple-bootstrap-4.blade.php: -------------------------------------------------------------------------------- 1 | @if ($paginator->hasPages()) 2 | 25 | @endif 26 | -------------------------------------------------------------------------------- /website/resources/views/vendor/pagination/simple-default.blade.php: -------------------------------------------------------------------------------- 1 | @if ($paginator->hasPages()) 2 | 17 | @endif 18 | -------------------------------------------------------------------------------- /website/routes/api.php: -------------------------------------------------------------------------------- 1 | get('/user', function (Request $request) { 17 | return $request->user(); 18 | }); 19 | -------------------------------------------------------------------------------- /website/routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 16 | }); 17 | -------------------------------------------------------------------------------- /website/routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 18 | })->describe('Display an inspiring quote'); 19 | -------------------------------------------------------------------------------- /website/routes/web.php: -------------------------------------------------------------------------------- 1 | name('home_test'); 16 | 17 | Route::group(['middleware' => 'auth'], function () { 18 | Route::resource('projects', 'ProjectsController'); 19 | 20 | Route::post('/projects/{project}/tasks', 'ProjectTasksController@store'); 21 | Route::patch('/projects/{project}/tasks/{task}', 'ProjectTasksController@update'); 22 | 23 | Route::post('/projects/{project}/invitations', 'ProjectInvitationsController@store'); 24 | 25 | Route::get('/home', 'HomeController@index')->name('home'); 26 | }); 27 | 28 | Auth::routes(); 29 | -------------------------------------------------------------------------------- /website/webpack.mix.js: -------------------------------------------------------------------------------- 1 | let mix = require('laravel-mix'); 2 | 3 | require('laravel-mix-tailwind'); 4 | 5 | /* 6 | |-------------------------------------------------------------------------- 7 | | Mix Asset Management 8 | |-------------------------------------------------------------------------- 9 | | 10 | | Mix provides a clean, fluent API for defining some Webpack build steps 11 | | for your Laravel application. By default, we are compiling the Sass 12 | | file for the application as well as bundling up all the JS files. 13 | | 14 | */ 15 | 16 | mix.js('resources/js/app.js', 'public/js') 17 | .sass('resources/sass/app.scss', 'public/css') 18 | .tailwind(); 19 | -------------------------------------------------------------------------------- /website/website.msbuildproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | netstandard2.0 4 | $(LaravelVersion) 5 | $(LaravelVersion) 6 | PHP0125,PHP5011,PHP5008,PHP5006,PHP5012 7 | Laravel 8 | Laravel project transformed to managed .NET Standard library. 9 | PEACHPIE 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 45 | 46 | 47 | 48 | 49 | --------------------------------------------------------------------------------