├── dist ├── .gitkeep └── wpsqlite.phar ├── .gitignore ├── box.json ├── composer.json ├── src ├── Extensions │ └── WPSQLiteApplication.php └── Commands │ ├── HelloCommand.php │ ├── StartCommand.php │ └── InstallCommand.php ├── LICENSE ├── bin └── consoleapp └── readme.md /dist/.gitkeep: -------------------------------------------------------------------------------- 1 | .gitkeep -------------------------------------------------------------------------------- /dist/wpsqlite.phar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasinhayder/wpsqlite/HEAD/dist/wpsqlite.phar -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | composer.lock 3 | .DS_Store 4 | .env 5 | dist/*.phar 6 | *.log 7 | node_modules -------------------------------------------------------------------------------- /box.json: -------------------------------------------------------------------------------- 1 | { 2 | "chmod": "0755", 3 | "directories": [ 4 | "src" 5 | ], 6 | "files": [ 7 | "LICENSE" 8 | ], 9 | "finder": [ 10 | { 11 | "name": "*.php", 12 | "exclude": ["Tests"], 13 | "in": "vendor" 14 | } 15 | ], 16 | "git-version": "package_version", 17 | "main": "bin/consoleapp", 18 | "output": "dist/wpsqlite.phar", 19 | "stub": true 20 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hasin/wpsqlite", 3 | "description": "Create WP SQlite Development Server", 4 | "license": "MIT", 5 | "authors": [ 6 | { 7 | "name": "Hasin Hayder", 8 | "email": "countdraculla@gmail.com" 9 | } 10 | ], 11 | "require": { 12 | "symfony/console": "^5.2" 13 | }, 14 | "bin": [ 15 | "bin/consoleapp" 16 | ], 17 | "autoload": { 18 | "psr-4": { 19 | "HasinHayder\\WPSQLite\\": "src/" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Extensions/WPSQLiteApplication.php: -------------------------------------------------------------------------------- 1 | setName('hello') 14 | ->setHidden(true) 15 | ->setDescription(''); 16 | } 17 | 18 | protected function execute(InputInterface $input, OutputInterface $output) 19 | { 20 | $output->writeln(PHP_VERSION_ID); 21 | $output->writeln(PHP_OS); 22 | if (PHP_VERSION_ID > 80000) { 23 | $output->writeln("PHP 8 Detected"); 24 | }else{ 25 | $output->writeln("PHP 5 or 7 Detected"); 26 | } 27 | return 1; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Commands/StartCommand.php: -------------------------------------------------------------------------------- 1 | setName('start') 16 | ->setDescription('Start a WordPress SQLite Site') 17 | ->addArgument("name", InputArgument::REQUIRED, "Site Name"); 18 | } 19 | 20 | protected function execute(InputInterface $input, OutputInterface $output) 21 | { 22 | $siteName = $input->getArgument("name"); 23 | if(file_exists("{$siteName}.json")){ 24 | if (PHP_OS == "WIN32" || PHP_OS == "Windows" || PHP_OS == "WINNT") { 25 | passthru("php -S {$siteName}:80 -t {$siteName}/"); 26 | } else { 27 | passthru("sudo php -S {$siteName}:80 -t {$siteName}/"); 28 | } 29 | }else{ 30 | $output->writeln("This site doesn't exist"); 31 | } 32 | return 1; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Hasin Hayder 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 all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 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 THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /bin/consoleapp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | add(new InstallCommand); 53 | $application->add(new StartCommand); 54 | $application->add(new HelloCommand); 55 | $application->run(); -------------------------------------------------------------------------------- /src/Commands/InstallCommand.php: -------------------------------------------------------------------------------- 1 | setName('install') 24 | ->setDescription('Install WordPress with SQLite Support'); 25 | } 26 | 27 | protected function execute(InputInterface $input, OutputInterface $output) 28 | { 29 | $this->input = $input; 30 | $this->output = $output; 31 | 32 | $subdomain = str_replace('.wplocal.xyz', '', $this->ask('Enter the SubDomain name (*.wplocal.xyz without the .wplocal.xyz part): ', self::WPSQLITE_QUESTION_INPUT, "test")); 33 | $domain = "{$subdomain}.wplocal.xyz"; 34 | 35 | if (file_exists("{$domain}.json")) { 36 | $start = $this->ask('A WordPress site is already installed with this subdomain. Do you want to Start it? (yes/no)', self::WPSQLITE_QUESTION_CONFIRMATION, "yes"); 37 | 38 | if ($start == "yes") { 39 | $this->serve($domain); 40 | } 41 | return 1; 42 | } 43 | 44 | //$phpversion = $this->ask('Select your PHP version (defaults to php7)', self::WPSQLITE_QUESTION_CHOICE, "PHP7", ['PHP7', 'PHP8', 'PHP5.6+']); 45 | $phpversion = (PHP_VERSION_ID >= 80000) ? "PHP8" : "PHP7"; 46 | 47 | $confirmation = $this->ask('This will download 15MB data from https://wordpress.org, do you want to proceed?', self::WPSQLITE_QUESTION_CONFIRMATION, "yes"); 48 | if ("yes" == $confirmation) { 49 | 50 | $output->writeln("Downloading the latest version of WordPress. Please Hold"); 51 | 52 | $fileName = "latest.tar.gz"; 53 | file_put_contents("./latest.tar.gz", $this->file_get_contents_ssl("https://wordpress.org/{$fileName}")); 54 | 55 | if (file_exists($fileName)) { 56 | $output->writeln("Extracting the tarball"); 57 | exec("tar -xf ./{$fileName}"); 58 | unlink("./{$fileName}"); 59 | 60 | if (is_dir("wordpress")) { 61 | if ($phpversion == 'PHP7') { 62 | file_put_contents("./wordpress/wp-content/db.php", $this->file_get_contents_ssl("https://raw.githubusercontent.com/aaemnnosttv/wp-sqlite-db/master/src/db.php")); 63 | } else { 64 | file_put_contents("./wordpress/wp-content/db.php", $this->file_get_contents_ssl("https://raw.githubusercontent.com/hasinhayder/wp-sqlite-db/master/src/db.php")); 65 | } 66 | rename("./wordpress/wp-config-sample.php", "./wordpress/wp-config.php"); 67 | if (PHP_OS == "WIN32" || PHP_OS == "Windows" || PHP_OS == "WINNT") { 68 | file_put_contents("./wordpress/start.bat", "php -S {$domain}:80"); 69 | } else { 70 | file_put_contents("./wordpress/start.sh", "sudo php -S {$domain}:80"); 71 | } 72 | 73 | 74 | rename("./wordpress", "./{$domain}"); 75 | $this->createSiteInfo($domain); 76 | 77 | $confirmation = $this->ask('Your WordPress installation is now ready. Do you want to start it?', self::WPSQLITE_QUESTION_CONFIRMATION, 'yes'); 78 | if ($confirmation == "yes") { 79 | $this->serve($domain); 80 | } 81 | return 1; 82 | } 83 | } 84 | } 85 | return 1; 86 | } 87 | 88 | private function createSiteInfo($domain) 89 | { 90 | $data = [ 91 | "domain" => $domain, 92 | ]; 93 | 94 | file_put_contents("{$domain}.json", json_encode($data, JSON_PRETTY_PRINT)); 95 | } 96 | 97 | private function file_get_contents_ssl($url) 98 | { 99 | $ch = curl_init(); 100 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 101 | curl_setopt($ch, CURLOPT_HEADER, false); 102 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 103 | curl_setopt($ch, CURLOPT_URL, $url); 104 | curl_setopt($ch, CURLOPT_REFERER, $url); 105 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 106 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5000); // 5 sec. 107 | curl_setopt($ch, CURLOPT_TIMEOUT, 100000); // 100 sec. 108 | $result = curl_exec($ch); 109 | curl_close($ch); 110 | return $result; 111 | } 112 | 113 | private function ask($question, $questionType, $default = "", $options = []) 114 | { 115 | $helper = $this->getHelper('question'); 116 | if ($questionType == self::WPSQLITE_QUESTION_INPUT) { 117 | $question = new Question( 118 | $question, 119 | $default 120 | ); 121 | } elseif ($questionType == self::WPSQLITE_QUESTION_CONFIRMATION) { 122 | $question = new ChoiceQuestion( 123 | $question, 124 | ['yes', 'no'], 125 | $default 126 | ); 127 | } elseif ($questionType == self::WPSQLITE_QUESTION_CHOICE) { 128 | $question = new ChoiceQuestion( 129 | $question, 130 | $options, 131 | $default 132 | ); 133 | } 134 | $answer = $helper->ask($this->input, $this->output, $question); 135 | return $answer; 136 | } 137 | 138 | private function serve($domain) 139 | { 140 | if (PHP_OS == "WIN32" || PHP_OS == "Windows" || PHP_OS == "WINNT") { 141 | passthru("php -S {$domain}:80 -t {$domain}/"); 142 | //pclose(popen('start /B cmd /C "php -S {$domain}:80 -t {$domain}/ >NUL 2>NUL"', 'r')); //Open in background and release the current process 143 | } else { 144 | passthru("sudo php -S {$domain}:80 -t {$domain}/"); 145 | //passthru("sudo php -S {$domain}:80 -t {$domain} > /dev/null 2>/dev/null &"); //Open in background and release the current process 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # WPSQLite 2 | 3 | WPSQLite.phar helps you to quickly provision WordPress with SQLite and serve the site using PHP's builtin webserver. No external WebServer like Apache or Nginx and Database Server like MySQL or MariaDB is required. WPSQLite can give you a completely portable installation of WordPress which you can install even in your pendrive and run on *nix based operating systems, or even on Windows. 4 | 5 | WPSQLite is very handy to quickly provision a development setup without worrying much about managing host entries, installing fat dependencies, and allows you to focus more on the development. 6 | 7 | ## Installation & Usage 8 | Just open the [**dist**](https://github.com/hasinhayder/wpsqlite/tree/master/dist) folder, download wpsqlite.phar and put it in your global path or use from local directory, whatever is convenient for you 9 | 10 | ```sh 11 | php wpsqlite.phar install 12 | ``` 13 | 14 | or if you can give execution permission to wpsqlite.phar, rename it as wpsqlite and put it in your global path (like `/usr/sbin/wpsqlite`) and use it like this 15 | 16 | ```sh 17 | wpsqlite install 18 | ``` 19 | 20 | **Very Important: Make sure to stop any running apache/nginx/other process that is listening on your 80 port first** 21 | 22 | That's all :) 23 | 24 | ## Pre Requirement (*nix based OS / Linux or Mac) 25 | Two extensions, pdo_sqlite and curl extension must be enabled. If you're using *nix based operating systems (Linux, Mac) then just open your php.ini and uncomment the line where it says ```;extension=pdo_sqlite```. Uncomment = remove the semicolon from the beginning of that line, so make it look like ```extension=pdo_sqlite```. 26 | 27 | Please also uncomment ```;extension=sqlite3``` and make it look like ```extension=sqlite3```. 28 | 29 | Also enable curl. Look for the line ```;extension=curl``` and enable it like this ```extension=curl``` 30 | 31 | You may need to install sqlite library for your PHP version, for example if you have php8, you may need to install it like this on debian/debian-variants 32 | 33 | ```sh 34 | sudo apt install php8.0-sqlite3 35 | ``` 36 | ## Pre Requirement (Windows) 37 | 38 | If you are using windows, open your php.ini and uncomment the line where it says ```;extension=pdo_sqlite.dll```, just change it to ```extension=pdo_sqlite.dll``` and you're ready. 39 | 40 | Also enable curl, Look for the line ```;extension=curl.dll``` and enable it like this ```extension=curl.dll``` 41 | 42 | Please also uncomment ```;extension=sqlite3.dll``` and make it look like ```extension=sqlite3.dll```. 43 | ## Create a new site 44 | 45 | ```sh 46 | php wpsqlite.phar install 47 | ``` 48 | or 49 | 50 | ```sh 51 | wpsqlite.phar install 52 | ``` 53 | 54 | ## Run a previously installed site 55 | ```sh 56 | php wpsqlite.phar start 57 | php wpsqlite.phar start abcd.wplocal.xyz 58 | ``` 59 | or 60 | 61 | ```sh 62 | wpsqlite.phar start 63 | wpsqlite.phar start abcd.wplocal.xyz 64 | ``` 65 | 66 | ## Post Installation Requirement 67 | **Important** 68 | 69 | If you want to install plugins and themes in your freshly installed WordPress site from the admin panel, just open your `wp-config.php` and add the following line 70 | 71 | ```php 72 | define ('FS_METHOD', 'direct'); 73 | ``` 74 | 75 | ## History 76 | ওয়ার্ডপ্রেস উইথ এস্কিউলাইট (WordPress With SQLite) 77 | 78 | গতকাল সারাদিন আমি একটা ইন্টারেস্টিং প্রজেক্ট নিয়ে কাজ করেছি, সেটা হলো ওয়ার্ডপ্রেস উইথ এস্কিউলাইট। আপনারা জানেন যে ওয়ার্ডপ্রেসের ডেটা স্টোর করতে হলে মাইসিকুয়েল ডেটাবেজ প্রয়োজন ডিফল্টভাবে, সেখানে আপনি চাইলেও অন্য আরডিবিএমএস ব্যবহার করতে পারবেন না। অথচ এস্কিউলাইট ব্যবহার করতে পারলে কত্ত ভালো হতো - আপনার মেশিনে আলাদাভাবে ওয়েবসার্ভার বা মাইসিকুয়েল ইনস্টল করা লাগতো না, হোস্ট কনফিগারেশন করা লাগতো না, আপনার পুরো সেটাপটা পোর্টেবল হয়ে যেত - ইনফ্যাক্ট আপনি পেনড্রাইভে একটা পুরোপুরি ফাংশনাল ওয়ার্ডপ্রেস সেটআপ পকেটে নিয়ে ঘুরে বেড়াতে পারতেন, যেকোনো মেশিনে লাগিয়ে সেখানেই ডেভেলপমেন্টের কাজ করতে পারতেন - সুবিধার শেষ নাই, জাস্ট প্লাগ এন্ড প্লে টাইপের ব্যাপারস্যাপার। 79 | 80 | ফার ফাইল টা গ্লোবাল পাথে রাখেন বা লোকাল পাথে - এরপর কমান্ড দেন এটা ’php wpsqlite.phar install’, ব্যাস আপনার পোর্টেবল ওয়ার্ডপ্রেস সেটআপ উইথ এস্কিউলাইট একদম রেডি। এখন পেনড্রাইভেও ওয়ার্ডপ্রেস ইনস্টলেশন পসিবল। ইনস্টল করবেন, পকেটে নিয়ে ঘুরে বেড়াবেন, যেখানে ইচ্ছা, যেই মেশিনে ইচ্ছা সেখানে বসে কাজ করবেন, কি মজা না? 81 | 82 | তাহলে ঝামেলা কোনখানে, ঐ যে ওয়ার্ডপ্রেসের সাথে এস্কিউলাইটের ডিফল্ট ইন্টিগ্রেশনের কোনো সিস্টেম নাই, হোয়াট এ হার্ট ব্রেকিং নিউজ। ডেভেলপাররা কি আর বসে থাকে? জাপানের কোজিমা তোশিয়াসু একটা চমৎকার ড্রপইন সলুশন তৈরী করেছিলেন যেখানে একটা ফাইল আপনার ওয়ার্ডপ্রেস ইন্স্টলেশনের মধ্যে রেখে দিয়ে একটু কনফিগারেশন করে দিলেই ওয়ার্ডপ্রেসের সাথে এস্কিউলাইট ব্যবহার করা যাবে। এরপরে এটার উপরে বেশ কিছু ইম্প্রুভমেন্ট করেছেন ইভান ম্যাটসন। তবে অনেকদিন ধরে এই রিপোজিটরিতে আপডেট দেয়া হয়নি, সো পিএইচপি এইটের সাথে কম্প্যাটিবল ছিল না এটা, পরে আমি সেটা অ্যাড করে দিয়েছি। 83 | 84 | অ্যাড করতে করতে আমার মনে হলো আমি চাইলেই তো এটাকে সবার জন্য আরো সহজ একটা সলুশন হিসেবে রিলিজ করে দিতে পারি, যেটা দিয়ে টার্মিনালে (লিনাক্স, উইন্ডোজ এবং ম্যাক) একটা কমান্ড দিলেই পুরো সেটআপটা এক নিমিষে রেডি হয়ে যাবে, যা যা কনফিগারেশন প্রয়োজন সেটা অটোমেটিকালি আমার স্ক্রিপ্ট থেকেই করে ফেলব, তাহলে মানুষের জন্য ঝামেলা আরো কমে যাবে তাই না? পাশাপাশি একটা চমৎকার সলুশন রেডি হয়ে যাবে কুইকলি একটা পোর্টেবল ওয়ার্ডপ্রেস সেটআপ তৈরি করার জন্য - কমান্ড দিবেন, কাজ শুরু করবেন :) 85 | 86 | আমি প্রথমে প্রভিশনিং এর জন্য শেলস্ক্রিপ্ট লিখেছিলাম, লিনাক্স আর ম্যাকের জন্য। সেটা উইন্ডোজে পোর্ট করতে গিয়ে দেখলাম অনেক ঝামেলা, লিনাক্স সাবসিস্টেম ইনস্টল্ড না থাকলে রান করা যাবে না। শেষ পর্যন্ত ভাবছিলাম পাওয়ারশেল স্ক্রিপ্ট লিখে দেয়ার জন্য, এমন সময় অবি প্লাবন বললো যে এটাকে ফার ফাইল হিসেবে রিলিজ করে দিলেই তো হয় - আরো সহজ হবে সবার জন্য, আমিও দেখলাম আইডিয়াটা মন্দ না। 87 | 88 | ফার নিয়ে আমি আগে কাজ করি নাই, এখানে প্রজেক্ট লেখা একটু ডিফারেন্ট, বিল্ড করাও হ্যাপা - যাইহোক পরশুদিন সন্ধ্যা থেকে এটার উপরে পড়াশোনা শুরু করেছি, গতকাল সন্ধ্যায় লিনাক্স/ম্যাক/উইন্ডোজের জন্য ফার ফাইলটা তৈরি করে ফেলেছি :) আর হোস্ট কনফিগারেশন যাতে আপনার নিজের না করতে হয় সেজন্য wplocal.xyz একটা ডোমেইন কিনেছি এবং এটাতে ওয়াইল্ডকার্ড ডিএনএস ম্যাপিং করেছি যাতে আপনি *.wplocal.xyz এ পিং করলে সবসময় সেটা আপনার লোকালহোস্টে পয়েন্ট করে, মানে ping anything.wplocal.xyz কমান্ড দিলেই সেটা 127.0.0.1 কে পয়েন্ট করবে। 89 | 90 | কমান্ড লাইনের কাজটা করার জন্য সিম্ফোনি কনসোল কম্পোনেন্ট নিয়ে কাজ করতে হয়েছে, এটা নিয়েও কাজ করি নাই আগে। ফাইলসিস্টেমের ফাংশন গুলো নিয়ে কাজ করতে হয়েছে যেগুলো সাধারণত তেমন ব্যবহার করা হয় না ডেইলি প্রজেক্টে - মোট কথা সেই লেভেলের মজা পেয়েছি পুরো কাজটা করতে গিয়ে 91 | 92 | আজকে এটা সবার জন্য রিলিজ করে দিলাম এখানে https://github.com/hasinhayder/wpsqlite, ব্যবহার কিভাবে করতে হবে বা সোর্স কোড চেক করার জন্য এই রিপোজিটরিতে চলে যাবেন। আপনার অপারেটিং সিস্টেম যাই হোক না কেন, মেশিনে পিএইচপি, পিডিও এস্কিউলাইট এক্সটেনশন আর কার্ল এক্সটেনশন ইনস্টল করা থাকলেই কাজ করবে :) ইউজুয়ালি সবার মেশিনেই এক্সটেনশন গুলো বাই ডিফল্ট থাকেই, জাস্ট এনাবল করে নিতে হয় কারো কারো মেশিনে পিএইচপি আইএনআই (php.ini) ফাইল থেকে। 93 | 94 | ফার ফাইল টা গ্লোবাল পাথে রাখেন বা লোকাল পাথে - এরপর কমান্ড দেন এটা ’php wpsqlite.phar install’, ব্যাস আপনার পোর্টেবল ওয়ার্ডপ্রেস সেটআপ উইথ এস্কিউলাইট একদম রেডি। এখন পেনড্রাইভেও ওয়ার্ডপ্রেস ইনস্টলেশন পসিবল। ইনস্টল করবেন, পকেটে নিয়ে ঘুরে বেড়াবেন, যেখানে ইচ্ছা, যেই মেশিনে ইচ্ছা সেখানে বসে কাজ করবেন, পুরাই বিন্দাস লাইফ আর কি। 95 | 96 | <3 97 | 98 | 99 | 100 | 101 | 102 | --------------------------------------------------------------------------------