Перенос в микроприложение
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
vendor/
 | 
			
		||||
dumps/
 | 
			
		||||
runtime/
 | 
			
		||||
							
								
								
									
										22
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
# YII Dumper
 | 
			
		||||
***
 | 
			
		||||
Parsing HTML pages at a given depth
 | 
			
		||||
```sh
 | 
			
		||||
$ yii dump https://domain.zone/foo $DEPTH $BUFFER $FORCE $EXTERNAL $ANOTHER_PATH
 | 
			
		||||
```
 | 
			
		||||
  - The larger the buffer size, the faster the program runs
 | 
			
		||||
  - Logs are stored in the directory /runtime/logs
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Sample
 | 
			
		||||
```sh
 | 
			
		||||
$ yii dump https://domain.zone/foo 2 50
 | 
			
		||||
```
 | 
			
		||||
## Requirements
 | 
			
		||||
  * **PHP ^7.2**
 | 
			
		||||
  * **CURL**
 | 
			
		||||
 | 
			
		||||
## TODO
 | 
			
		||||
  1. $searchExternal to $depthExterntal
 | 
			
		||||
  2. Fix processing of the link: zakupki.gov.ru/data/common-info.html?regNumber=0816500000619001511
 | 
			
		||||
  3. The construction <base> needs to be modified to check an existing tag
 | 
			
		||||
							
								
								
									
										15
									
								
								composer.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								composer.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
{
 | 
			
		||||
    "require": {
 | 
			
		||||
        "php": "^7.2",
 | 
			
		||||
        "ext-curl": "*",
 | 
			
		||||
        "yiisoft/yii2": "~2.0.0",
 | 
			
		||||
        "linslin/yii2-curl": "*",
 | 
			
		||||
        "omnilight/yii2-scheduling": "*"
 | 
			
		||||
    },
 | 
			
		||||
    "repositories": [
 | 
			
		||||
        {
 | 
			
		||||
            "type": "composer",
 | 
			
		||||
            "url": "https://asset-packagist.org"
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										641
									
								
								composer.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										641
									
								
								composer.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,641 @@
 | 
			
		||||
{
 | 
			
		||||
    "_readme": [
 | 
			
		||||
        "This file locks the dependencies of your project to a known state",
 | 
			
		||||
        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
 | 
			
		||||
        "This file is @generated automatically"
 | 
			
		||||
    ],
 | 
			
		||||
    "content-hash": "6556bad2e96cc66bf6aed5a9fdd8cd57",
 | 
			
		||||
    "packages": [
 | 
			
		||||
        {
 | 
			
		||||
            "name": "bower-asset/inputmask",
 | 
			
		||||
            "version": "3.3.11",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "https://github.com/RobinHerbots/Inputmask.git",
 | 
			
		||||
                "reference": "5e670ad62f50c738388d4dcec78d2888505ad77b"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/RobinHerbots/Inputmask/zipball/5e670ad62f50c738388d4dcec78d2888505ad77b",
 | 
			
		||||
                "reference": "5e670ad62f50c738388d4dcec78d2888505ad77b"
 | 
			
		||||
            },
 | 
			
		||||
            "require": {
 | 
			
		||||
                "bower-asset/jquery": ">=1.7"
 | 
			
		||||
            },
 | 
			
		||||
            "type": "bower-asset",
 | 
			
		||||
            "license": [
 | 
			
		||||
                "http://opensource.org/licenses/mit-license.php"
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "bower-asset/jquery",
 | 
			
		||||
            "version": "3.5.1",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "git@github.com:jquery/jquery-dist.git",
 | 
			
		||||
                "reference": "4c0e4becb8263bb5b3e6dadc448d8e7305ef8215"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/jquery/jquery-dist/zipball/4c0e4becb8263bb5b3e6dadc448d8e7305ef8215",
 | 
			
		||||
                "reference": "4c0e4becb8263bb5b3e6dadc448d8e7305ef8215"
 | 
			
		||||
            },
 | 
			
		||||
            "type": "bower-asset",
 | 
			
		||||
            "license": [
 | 
			
		||||
                "MIT"
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "bower-asset/punycode",
 | 
			
		||||
            "version": "v1.3.2",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "git@github.com:bestiejs/punycode.js.git",
 | 
			
		||||
                "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/bestiejs/punycode.js/zipball/38c8d3131a82567bfef18da09f7f4db68c84f8a3",
 | 
			
		||||
                "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3"
 | 
			
		||||
            },
 | 
			
		||||
            "type": "bower-asset"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "bower-asset/yii2-pjax",
 | 
			
		||||
            "version": "2.0.7.1",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "https://github.com/yiisoft/jquery-pjax.git",
 | 
			
		||||
                "reference": "aef7b953107264f00234902a3880eb50dafc48be"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/aef7b953107264f00234902a3880eb50dafc48be",
 | 
			
		||||
                "reference": "aef7b953107264f00234902a3880eb50dafc48be"
 | 
			
		||||
            },
 | 
			
		||||
            "require": {
 | 
			
		||||
                "bower-asset/jquery": ">=1.8"
 | 
			
		||||
            },
 | 
			
		||||
            "type": "bower-asset",
 | 
			
		||||
            "license": [
 | 
			
		||||
                "MIT"
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "cebe/markdown",
 | 
			
		||||
            "version": "1.2.1",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "https://github.com/cebe/markdown.git",
 | 
			
		||||
                "reference": "9bac5e971dd391e2802dca5400bbeacbaea9eb86"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/cebe/markdown/zipball/9bac5e971dd391e2802dca5400bbeacbaea9eb86",
 | 
			
		||||
                "reference": "9bac5e971dd391e2802dca5400bbeacbaea9eb86",
 | 
			
		||||
                "shasum": ""
 | 
			
		||||
            },
 | 
			
		||||
            "require": {
 | 
			
		||||
                "lib-pcre": "*",
 | 
			
		||||
                "php": ">=5.4.0"
 | 
			
		||||
            },
 | 
			
		||||
            "require-dev": {
 | 
			
		||||
                "cebe/indent": "*",
 | 
			
		||||
                "facebook/xhprof": "*@dev",
 | 
			
		||||
                "phpunit/phpunit": "4.1.*"
 | 
			
		||||
            },
 | 
			
		||||
            "bin": [
 | 
			
		||||
                "bin/markdown"
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "library",
 | 
			
		||||
            "extra": {
 | 
			
		||||
                "branch-alias": {
 | 
			
		||||
                    "dev-master": "1.2.x-dev"
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "autoload": {
 | 
			
		||||
                "psr-4": {
 | 
			
		||||
                    "cebe\\markdown\\": ""
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "notification-url": "https://packagist.org/downloads/",
 | 
			
		||||
            "license": [
 | 
			
		||||
                "MIT"
 | 
			
		||||
            ],
 | 
			
		||||
            "authors": [
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Carsten Brandt",
 | 
			
		||||
                    "email": "mail@cebe.cc",
 | 
			
		||||
                    "homepage": "http://cebe.cc/",
 | 
			
		||||
                    "role": "Creator"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "description": "A super fast, highly extensible markdown parser for PHP",
 | 
			
		||||
            "homepage": "https://github.com/cebe/markdown#readme",
 | 
			
		||||
            "keywords": [
 | 
			
		||||
                "extensible",
 | 
			
		||||
                "fast",
 | 
			
		||||
                "gfm",
 | 
			
		||||
                "markdown",
 | 
			
		||||
                "markdown-extra"
 | 
			
		||||
            ],
 | 
			
		||||
            "time": "2018-03-26T11:24:36+00:00"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "dragonmantank/cron-expression",
 | 
			
		||||
            "version": "v1.2.1",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "https://github.com/dragonmantank/cron-expression.git",
 | 
			
		||||
                "reference": "9504fa9ea681b586028adaaa0877db4aecf32bad"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/9504fa9ea681b586028adaaa0877db4aecf32bad",
 | 
			
		||||
                "reference": "9504fa9ea681b586028adaaa0877db4aecf32bad",
 | 
			
		||||
                "shasum": ""
 | 
			
		||||
            },
 | 
			
		||||
            "require": {
 | 
			
		||||
                "php": ">=5.3.2"
 | 
			
		||||
            },
 | 
			
		||||
            "require-dev": {
 | 
			
		||||
                "phpunit/phpunit": "~4.0|~5.0"
 | 
			
		||||
            },
 | 
			
		||||
            "type": "library",
 | 
			
		||||
            "autoload": {
 | 
			
		||||
                "psr-4": {
 | 
			
		||||
                    "Cron\\": "src/Cron/"
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "notification-url": "https://packagist.org/downloads/",
 | 
			
		||||
            "license": [
 | 
			
		||||
                "MIT"
 | 
			
		||||
            ],
 | 
			
		||||
            "authors": [
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Michael Dowling",
 | 
			
		||||
                    "email": "mtdowling@gmail.com",
 | 
			
		||||
                    "homepage": "https://github.com/mtdowling"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due",
 | 
			
		||||
            "keywords": [
 | 
			
		||||
                "cron",
 | 
			
		||||
                "schedule"
 | 
			
		||||
            ],
 | 
			
		||||
            "time": "2017-01-23T04:29:33+00:00"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "ezyang/htmlpurifier",
 | 
			
		||||
            "version": "v4.13.0",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "https://github.com/ezyang/htmlpurifier.git",
 | 
			
		||||
                "reference": "08e27c97e4c6ed02f37c5b2b20488046c8d90d75"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/08e27c97e4c6ed02f37c5b2b20488046c8d90d75",
 | 
			
		||||
                "reference": "08e27c97e4c6ed02f37c5b2b20488046c8d90d75",
 | 
			
		||||
                "shasum": ""
 | 
			
		||||
            },
 | 
			
		||||
            "require": {
 | 
			
		||||
                "php": ">=5.2"
 | 
			
		||||
            },
 | 
			
		||||
            "require-dev": {
 | 
			
		||||
                "simpletest/simpletest": "dev-master#72de02a7b80c6bb8864ef9bf66d41d2f58f826bd"
 | 
			
		||||
            },
 | 
			
		||||
            "type": "library",
 | 
			
		||||
            "autoload": {
 | 
			
		||||
                "psr-0": {
 | 
			
		||||
                    "HTMLPurifier": "library/"
 | 
			
		||||
                },
 | 
			
		||||
                "files": [
 | 
			
		||||
                    "library/HTMLPurifier.composer.php"
 | 
			
		||||
                ],
 | 
			
		||||
                "exclude-from-classmap": [
 | 
			
		||||
                    "/library/HTMLPurifier/Language/"
 | 
			
		||||
                ]
 | 
			
		||||
            },
 | 
			
		||||
            "notification-url": "https://packagist.org/downloads/",
 | 
			
		||||
            "license": [
 | 
			
		||||
                "LGPL-2.1-or-later"
 | 
			
		||||
            ],
 | 
			
		||||
            "authors": [
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Edward Z. Yang",
 | 
			
		||||
                    "email": "admin@htmlpurifier.org",
 | 
			
		||||
                    "homepage": "http://ezyang.com"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "description": "Standards compliant HTML filter written in PHP",
 | 
			
		||||
            "homepage": "http://htmlpurifier.org/",
 | 
			
		||||
            "keywords": [
 | 
			
		||||
                "html"
 | 
			
		||||
            ],
 | 
			
		||||
            "time": "2020-06-29T00:56:53+00:00"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "linslin/yii2-curl",
 | 
			
		||||
            "version": "1.4.0",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "https://github.com/linslin/Yii2-Curl.git",
 | 
			
		||||
                "reference": "38f2c28efb4c200b7ad1c2decb262806bb6b5cea"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/linslin/Yii2-Curl/zipball/38f2c28efb4c200b7ad1c2decb262806bb6b5cea",
 | 
			
		||||
                "reference": "38f2c28efb4c200b7ad1c2decb262806bb6b5cea",
 | 
			
		||||
                "shasum": ""
 | 
			
		||||
            },
 | 
			
		||||
            "require": {
 | 
			
		||||
                "ext-curl": "*",
 | 
			
		||||
                "ext-json": "*",
 | 
			
		||||
                "yidas/yii2-bower-asset": "^2.0.13.1",
 | 
			
		||||
                "yiisoft/yii2": "^2.0.0"
 | 
			
		||||
            },
 | 
			
		||||
            "require-dev": {
 | 
			
		||||
                "codeception/base": "^2.2.3",
 | 
			
		||||
                "codeception/specify": "~0.4.3",
 | 
			
		||||
                "codeception/verify": "~0.3.1",
 | 
			
		||||
                "codeclimate/php-test-reporter": "dev-master",
 | 
			
		||||
                "guzzlehttp/guzzle": ">=4.1.4 <7.0",
 | 
			
		||||
                "mcustiel/phiremock-codeception-extension": "1.2.4"
 | 
			
		||||
            },
 | 
			
		||||
            "type": "yii2-extension",
 | 
			
		||||
            "autoload": {
 | 
			
		||||
                "psr-4": {
 | 
			
		||||
                    "linslin\\yii2\\curl\\": ""
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "notification-url": "https://packagist.org/downloads/",
 | 
			
		||||
            "license": [
 | 
			
		||||
                "MIT"
 | 
			
		||||
            ],
 | 
			
		||||
            "authors": [
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Nils Gajsek",
 | 
			
		||||
                    "email": "info@linslin.org"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "description": "Easy and nice cURL extension with RESTful support for Yii2",
 | 
			
		||||
            "keywords": [
 | 
			
		||||
                " curl",
 | 
			
		||||
                "extension",
 | 
			
		||||
                "restful",
 | 
			
		||||
                "yii2"
 | 
			
		||||
            ],
 | 
			
		||||
            "time": "2020-05-03T11:44:34+00:00"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "omnilight/yii2-scheduling",
 | 
			
		||||
            "version": "1.1.4",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "https://github.com/omnilight/yii2-scheduling.git",
 | 
			
		||||
                "reference": "c7ffcd3b26143d47455ddd8e0cdf1611dbd9b74c"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/omnilight/yii2-scheduling/zipball/c7ffcd3b26143d47455ddd8e0cdf1611dbd9b74c",
 | 
			
		||||
                "reference": "c7ffcd3b26143d47455ddd8e0cdf1611dbd9b74c",
 | 
			
		||||
                "shasum": ""
 | 
			
		||||
            },
 | 
			
		||||
            "require": {
 | 
			
		||||
                "dragonmantank/cron-expression": "1.*",
 | 
			
		||||
                "php": ">=5.4.0",
 | 
			
		||||
                "symfony/process": "2.6.* || 3.* || 4.*",
 | 
			
		||||
                "yiisoft/yii2": "2.0.*"
 | 
			
		||||
            },
 | 
			
		||||
            "require-dev": {
 | 
			
		||||
                "phpunit/phpunit": "4.8.36"
 | 
			
		||||
            },
 | 
			
		||||
            "suggest": {
 | 
			
		||||
                "guzzlehttp/guzzle": "Required to use the thenPing method on schedules (~5.0)."
 | 
			
		||||
            },
 | 
			
		||||
            "type": "yii2-extension",
 | 
			
		||||
            "extra": {
 | 
			
		||||
                "bootstrap": "omnilight\\scheduling\\Bootstrap"
 | 
			
		||||
            },
 | 
			
		||||
            "autoload": {
 | 
			
		||||
                "psr-4": {
 | 
			
		||||
                    "omnilight\\scheduling\\": "src"
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "notification-url": "https://packagist.org/downloads/",
 | 
			
		||||
            "authors": [
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Pavel Agalecky",
 | 
			
		||||
                    "email": "pavel.agalecky@gmail.com"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "description": "Scheduling extension for Yii2 framework",
 | 
			
		||||
            "keywords": [
 | 
			
		||||
                "cron",
 | 
			
		||||
                "scheduling",
 | 
			
		||||
                "yii"
 | 
			
		||||
            ],
 | 
			
		||||
            "time": "2020-03-31T21:02:32+00:00"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "symfony/process",
 | 
			
		||||
            "version": "v4.4.13",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "https://github.com/symfony/process.git",
 | 
			
		||||
                "reference": "65e70bab62f3da7089a8d4591fb23fbacacb3479"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/symfony/process/zipball/65e70bab62f3da7089a8d4591fb23fbacacb3479",
 | 
			
		||||
                "reference": "65e70bab62f3da7089a8d4591fb23fbacacb3479",
 | 
			
		||||
                "shasum": ""
 | 
			
		||||
            },
 | 
			
		||||
            "require": {
 | 
			
		||||
                "php": ">=7.1.3"
 | 
			
		||||
            },
 | 
			
		||||
            "type": "library",
 | 
			
		||||
            "extra": {
 | 
			
		||||
                "branch-alias": {
 | 
			
		||||
                    "dev-master": "4.4-dev"
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "autoload": {
 | 
			
		||||
                "psr-4": {
 | 
			
		||||
                    "Symfony\\Component\\Process\\": ""
 | 
			
		||||
                },
 | 
			
		||||
                "exclude-from-classmap": [
 | 
			
		||||
                    "/Tests/"
 | 
			
		||||
                ]
 | 
			
		||||
            },
 | 
			
		||||
            "notification-url": "https://packagist.org/downloads/",
 | 
			
		||||
            "license": [
 | 
			
		||||
                "MIT"
 | 
			
		||||
            ],
 | 
			
		||||
            "authors": [
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Fabien Potencier",
 | 
			
		||||
                    "email": "fabien@symfony.com"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Symfony Community",
 | 
			
		||||
                    "homepage": "https://symfony.com/contributors"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "description": "Symfony Process Component",
 | 
			
		||||
            "homepage": "https://symfony.com",
 | 
			
		||||
            "funding": [
 | 
			
		||||
                {
 | 
			
		||||
                    "url": "https://symfony.com/sponsor",
 | 
			
		||||
                    "type": "custom"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "url": "https://github.com/fabpot",
 | 
			
		||||
                    "type": "github"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
 | 
			
		||||
                    "type": "tidelift"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "time": "2020-07-23T08:31:43+00:00"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "yidas/yii2-bower-asset",
 | 
			
		||||
            "version": "2.0.13.1",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "https://github.com/yidas/yii2-bower-asset.git",
 | 
			
		||||
                "reference": "056dd55087e0b945c01c91c99eb346ef6e28a42e"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/yidas/yii2-bower-asset/zipball/056dd55087e0b945c01c91c99eb346ef6e28a42e",
 | 
			
		||||
                "reference": "056dd55087e0b945c01c91c99eb346ef6e28a42e",
 | 
			
		||||
                "shasum": ""
 | 
			
		||||
            },
 | 
			
		||||
            "provide": {
 | 
			
		||||
                "bower-asset/bootstrap": "*",
 | 
			
		||||
                "bower-asset/inputmask": "*",
 | 
			
		||||
                "bower-asset/jquery": "*",
 | 
			
		||||
                "bower-asset/punycode": "*",
 | 
			
		||||
                "bower-asset/typeahead.js": "*",
 | 
			
		||||
                "bower-asset/yii2-pjax": "*"
 | 
			
		||||
            },
 | 
			
		||||
            "type": "yii2-extension",
 | 
			
		||||
            "autoload": {
 | 
			
		||||
                "psr-4": {
 | 
			
		||||
                    "yidas\\yii2BowerAsset\\": ""
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "notification-url": "https://packagist.org/downloads/",
 | 
			
		||||
            "license": [
 | 
			
		||||
                "MIT"
 | 
			
		||||
            ],
 | 
			
		||||
            "description": "Bower Assets for Yii 2 app provided via Composer repository",
 | 
			
		||||
            "keywords": [
 | 
			
		||||
                "bower",
 | 
			
		||||
                "bower asset",
 | 
			
		||||
                "framework",
 | 
			
		||||
                "yii2"
 | 
			
		||||
            ],
 | 
			
		||||
            "time": "2019-09-19T11:33:03+00:00"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "yiisoft/yii2",
 | 
			
		||||
            "version": "2.0.38",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "https://github.com/yiisoft/yii2-framework.git",
 | 
			
		||||
                "reference": "fd01e747cc66a049ec105048f0ab8dfbdf60bf4b"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/fd01e747cc66a049ec105048f0ab8dfbdf60bf4b",
 | 
			
		||||
                "reference": "fd01e747cc66a049ec105048f0ab8dfbdf60bf4b",
 | 
			
		||||
                "shasum": ""
 | 
			
		||||
            },
 | 
			
		||||
            "require": {
 | 
			
		||||
                "bower-asset/inputmask": "~3.2.2 | ~3.3.5",
 | 
			
		||||
                "bower-asset/jquery": "3.5.*@stable | 3.4.*@stable | 3.3.*@stable | 3.2.*@stable | 3.1.*@stable | 2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable",
 | 
			
		||||
                "bower-asset/punycode": "1.3.*",
 | 
			
		||||
                "bower-asset/yii2-pjax": "~2.0.1",
 | 
			
		||||
                "cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0",
 | 
			
		||||
                "ext-ctype": "*",
 | 
			
		||||
                "ext-mbstring": "*",
 | 
			
		||||
                "ezyang/htmlpurifier": "~4.6",
 | 
			
		||||
                "lib-pcre": "*",
 | 
			
		||||
                "php": ">=5.4.0",
 | 
			
		||||
                "yiisoft/yii2-composer": "~2.0.4"
 | 
			
		||||
            },
 | 
			
		||||
            "bin": [
 | 
			
		||||
                "yii"
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "library",
 | 
			
		||||
            "extra": {
 | 
			
		||||
                "branch-alias": {
 | 
			
		||||
                    "dev-master": "2.0.x-dev"
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "autoload": {
 | 
			
		||||
                "psr-4": {
 | 
			
		||||
                    "yii\\": ""
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "notification-url": "https://packagist.org/downloads/",
 | 
			
		||||
            "license": [
 | 
			
		||||
                "BSD-3-Clause"
 | 
			
		||||
            ],
 | 
			
		||||
            "authors": [
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Qiang Xue",
 | 
			
		||||
                    "email": "qiang.xue@gmail.com",
 | 
			
		||||
                    "homepage": "http://www.yiiframework.com/",
 | 
			
		||||
                    "role": "Founder and project lead"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Alexander Makarov",
 | 
			
		||||
                    "email": "sam@rmcreative.ru",
 | 
			
		||||
                    "homepage": "http://rmcreative.ru/",
 | 
			
		||||
                    "role": "Core framework development"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Maurizio Domba",
 | 
			
		||||
                    "homepage": "http://mdomba.info/",
 | 
			
		||||
                    "role": "Core framework development"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Carsten Brandt",
 | 
			
		||||
                    "email": "mail@cebe.cc",
 | 
			
		||||
                    "homepage": "http://cebe.cc/",
 | 
			
		||||
                    "role": "Core framework development"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Timur Ruziev",
 | 
			
		||||
                    "email": "resurtm@gmail.com",
 | 
			
		||||
                    "homepage": "http://resurtm.com/",
 | 
			
		||||
                    "role": "Core framework development"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Paul Klimov",
 | 
			
		||||
                    "email": "klimov.paul@gmail.com",
 | 
			
		||||
                    "role": "Core framework development"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Dmitry Naumenko",
 | 
			
		||||
                    "email": "d.naumenko.a@gmail.com",
 | 
			
		||||
                    "role": "Core framework development"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Boudewijn Vahrmeijer",
 | 
			
		||||
                    "email": "info@dynasource.eu",
 | 
			
		||||
                    "homepage": "http://dynasource.eu",
 | 
			
		||||
                    "role": "Core framework development"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "description": "Yii PHP Framework Version 2",
 | 
			
		||||
            "homepage": "http://www.yiiframework.com/",
 | 
			
		||||
            "keywords": [
 | 
			
		||||
                "framework",
 | 
			
		||||
                "yii2"
 | 
			
		||||
            ],
 | 
			
		||||
            "funding": [
 | 
			
		||||
                {
 | 
			
		||||
                    "url": "https://github.com/yiisoft",
 | 
			
		||||
                    "type": "github"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "url": "https://opencollective.com/yiisoft",
 | 
			
		||||
                    "type": "open_collective"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2",
 | 
			
		||||
                    "type": "tidelift"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "time": "2020-09-14T21:52:10+00:00"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "yiisoft/yii2-composer",
 | 
			
		||||
            "version": "2.0.10",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "https://github.com/yiisoft/yii2-composer.git",
 | 
			
		||||
                "reference": "94bb3f66e779e2774f8776d6e1bdeab402940510"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/94bb3f66e779e2774f8776d6e1bdeab402940510",
 | 
			
		||||
                "reference": "94bb3f66e779e2774f8776d6e1bdeab402940510",
 | 
			
		||||
                "shasum": ""
 | 
			
		||||
            },
 | 
			
		||||
            "require": {
 | 
			
		||||
                "composer-plugin-api": "^1.0 | ^2.0"
 | 
			
		||||
            },
 | 
			
		||||
            "require-dev": {
 | 
			
		||||
                "composer/composer": "^1.0 | ^2.0@dev",
 | 
			
		||||
                "phpunit/phpunit": "<7"
 | 
			
		||||
            },
 | 
			
		||||
            "type": "composer-plugin",
 | 
			
		||||
            "extra": {
 | 
			
		||||
                "class": "yii\\composer\\Plugin",
 | 
			
		||||
                "branch-alias": {
 | 
			
		||||
                    "dev-master": "2.0.x-dev"
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "autoload": {
 | 
			
		||||
                "psr-4": {
 | 
			
		||||
                    "yii\\composer\\": ""
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "notification-url": "https://packagist.org/downloads/",
 | 
			
		||||
            "license": [
 | 
			
		||||
                "BSD-3-Clause"
 | 
			
		||||
            ],
 | 
			
		||||
            "authors": [
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Qiang Xue",
 | 
			
		||||
                    "email": "qiang.xue@gmail.com"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Carsten Brandt",
 | 
			
		||||
                    "email": "mail@cebe.cc"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "description": "The composer plugin for Yii extension installer",
 | 
			
		||||
            "keywords": [
 | 
			
		||||
                "composer",
 | 
			
		||||
                "extension installer",
 | 
			
		||||
                "yii2"
 | 
			
		||||
            ],
 | 
			
		||||
            "funding": [
 | 
			
		||||
                {
 | 
			
		||||
                    "url": "https://github.com/yiisoft",
 | 
			
		||||
                    "type": "github"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "url": "https://opencollective.com/yiisoft",
 | 
			
		||||
                    "type": "open_collective"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-composer",
 | 
			
		||||
                    "type": "tidelift"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "time": "2020-06-24T00:04:01+00:00"
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
    "packages-dev": [],
 | 
			
		||||
    "aliases": [],
 | 
			
		||||
    "minimum-stability": "stable",
 | 
			
		||||
    "stability-flags": [],
 | 
			
		||||
    "prefer-stable": false,
 | 
			
		||||
    "prefer-lowest": false,
 | 
			
		||||
    "platform": {
 | 
			
		||||
        "php": "^7.2",
 | 
			
		||||
        "ext-curl": "*"
 | 
			
		||||
    },
 | 
			
		||||
    "platform-dev": [],
 | 
			
		||||
    "plugin-api-version": "1.1.0"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								config/console.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								config/console.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
<?php
 | 
			
		||||
return [
 | 
			
		||||
    'id'                    => 'Dumper',
 | 
			
		||||
    'controllerNamespace'   => 'app\controllers',
 | 
			
		||||
    'basePath'              => dirname(__DIR__),
 | 
			
		||||
    'params' => [
 | 
			
		||||
        'basePath'              => dirname(__DIR__) . '/dumps',
 | 
			
		||||
        'pagesPath'             => '/pages',
 | 
			
		||||
        'docsPath'              => '/data',
 | 
			
		||||
        'imgPath'               => '/img',
 | 
			
		||||
        'cssPath'               => '/css',
 | 
			
		||||
        'jsPath'                => '/js',
 | 
			
		||||
        'externalLinksPath'     => '/sites',
 | 
			
		||||
        'timezone'              => 'Asia/Vladivostok',
 | 
			
		||||
        'useragent'             => 'Dumper',
 | 
			
		||||
        'regBlackList'          => '(instagram|whatsapp|appdv)'
 | 
			
		||||
    ]
 | 
			
		||||
];
 | 
			
		||||
							
								
								
									
										6
									
								
								config/schedule.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								config/schedule.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * @var \omnilight\scheduling\Schedule $schedule
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
$schedule->command('dump http://expertise.27pro.ru// 5 50')->dailyAt('03:00');
 | 
			
		||||
							
								
								
									
										16
									
								
								controllers/DumpController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								controllers/DumpController.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace app\controllers;
 | 
			
		||||
 | 
			
		||||
use \Yii;
 | 
			
		||||
use \app\models\Dump;
 | 
			
		||||
 | 
			
		||||
class DumpController extends \yii\console\Controller
 | 
			
		||||
{
 | 
			
		||||
    public function actionIndex($link, $depth = 0, $buffer = 0, $force = false, $searchExternal = false, $path = '')
 | 
			
		||||
    {
 | 
			
		||||
        (new Dump)->download($link, $depth, $buffer, $force, $searchExternal, $path);
 | 
			
		||||
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										851
									
								
								models/Dump.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										851
									
								
								models/Dump.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,851 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace app\models;
 | 
			
		||||
 | 
			
		||||
use \Exception;
 | 
			
		||||
use \DateTime;
 | 
			
		||||
use \Yii;
 | 
			
		||||
use \linslin\yii2\curl\Curl;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Модель для выгрузки страниц в автономное хранилище
 | 
			
		||||
 * 
 | 
			
		||||
 * Позволяет скачивать, сохранять и оптимизировать под нужную архитектуру
 | 
			
		||||
 * 
 | 
			
		||||
 * @method download(string $link, int $depth = 0, int $buffer = 0, bool $searchExternal = false) Скачивает страницу
 | 
			
		||||
 * @method save() Сохраняет скачанные страницы на диск
 | 
			
		||||
 * @method saveStatistics() Сохранение статистики
 | 
			
		||||
 * @method convertLinks(array $links = null) Конвертер ссылок
 | 
			
		||||
 * @method convertFiles(array $files = null) Конвертер страниц
 | 
			
		||||
 * @method filterLink(string $link) Фильтрация ссылки
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Арсен Мирзаев red@hood.su
 | 
			
		||||
 * 
 | 
			
		||||
 * @todo
 | 
			
		||||
 * 1. $searchExternal переделать в $depthExterntal
 | 
			
		||||
 * 2. Исправить обработку ссылки: zakupki.gov.ru/data/common-info.html?regNumber=0816500000619001511
 | 
			
		||||
 * 4. Конструкцию <base> надо доработать на проверку уже существующего тега
 | 
			
		||||
 */
 | 
			
		||||
class Dump extends \yii\base\Component
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Глубина поиска страниц относительно первичной
 | 
			
		||||
     */
 | 
			
		||||
    protected $depth = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Буфер страниц для скачивания
 | 
			
		||||
     */
 | 
			
		||||
    protected $buffer;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Флаг форсированного выполнения (перезаписи файлов)
 | 
			
		||||
     */
 | 
			
		||||
    protected $force;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Путь для сохранения файлов
 | 
			
		||||
     */
 | 
			
		||||
    protected $path;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Буфер страниц для скачивания
 | 
			
		||||
     */
 | 
			
		||||
    protected $searchExternal;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Регистр обработанных ссылок
 | 
			
		||||
     * 
 | 
			
		||||
     * 'Ссылка' => [
 | 
			
		||||
     *      [0] => 'URN файла'
 | 
			
		||||
     *      [1] => 'URL файла'
 | 
			
		||||
     *      [2] => 'URI файла для конвертации страниц'
 | 
			
		||||
     * ]
 | 
			
		||||
     */
 | 
			
		||||
    protected $links = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Буфер скачанных файлов
 | 
			
		||||
     * 
 | 
			
		||||
     * 'Файл (URN)' => [
 | 
			
		||||
     *      [0] => 'Тип'
 | 
			
		||||
     *      [1] => 'Данные'
 | 
			
		||||
     * ]
 | 
			
		||||
     * 
 | 
			
		||||
     * Типы:
 | 
			
		||||
     * [0] - HTML страница
 | 
			
		||||
     * [1] - документ ('.css', '.js', '.png'...)
 | 
			
		||||
     */
 | 
			
		||||
    protected $filesBuffer = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Регистр сохранённых файлов
 | 
			
		||||
     * 
 | 
			
		||||
     * 'Файл (URN)' => [
 | 
			
		||||
     *      [0] => 'Тип'
 | 
			
		||||
     *      [1] => 'Данные'
 | 
			
		||||
     * ]
 | 
			
		||||
     * 
 | 
			
		||||
     * Типы:
 | 
			
		||||
     * [0] - HTML страница
 | 
			
		||||
     * [1] - документ ('.css', '.js', '.png'...)
 | 
			
		||||
     */
 | 
			
		||||
    protected $files = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Блокировка циклов
 | 
			
		||||
     * 
 | 
			
		||||
     * Указывает работает основное скачивание или рекурсивное
 | 
			
		||||
     */
 | 
			
		||||
    protected $subdownload = false;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Количество новых найденных ссылок
 | 
			
		||||
     */
 | 
			
		||||
    protected $linksNew = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Запрашиваемая ссылка
 | 
			
		||||
     */
 | 
			
		||||
    protected $target;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * SCHEME/PROTOCOL запроса
 | 
			
		||||
     */
 | 
			
		||||
    public $connectionProtocol;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * HOST запроса
 | 
			
		||||
     */
 | 
			
		||||
    public $connectionHost;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Собранная информация о выполнении
 | 
			
		||||
     * 
 | 
			
		||||
     * [0] => 'Запрошенный URI'
 | 
			
		||||
     * [1] => 'Статус выполнения (завершен или ошибка)'
 | 
			
		||||
     * [2] => [
 | 
			
		||||
     *     [0] => 'Количество найденных ссылок'
 | 
			
		||||
     *     [1] => 'Количество найденных ссылок без дубликатов'
 | 
			
		||||
     *     [2] => 'Количество обработанных ссылок'
 | 
			
		||||
     * ]
 | 
			
		||||
     * [3] => [
 | 
			
		||||
     *     [0] => 'Количество найденных HTML страниц'
 | 
			
		||||
     *     [1] => 'Количество конвертированных страниц'
 | 
			
		||||
     * ]
 | 
			
		||||
     * [4] => [
 | 
			
		||||
     *     [0] => 'Количество найденных документов (.png, .css, .pdf)'
 | 
			
		||||
     *     [1] => 'удалено'
 | 
			
		||||
     *     [2] => 'Найдено: Изображения',
 | 
			
		||||
     *     [3] => 'Найдено: Видеозаписи',
 | 
			
		||||
     *     [4] => 'Найдено: Аудиозаписи',
 | 
			
		||||
     *     [5] => 'Найдено: CSS',
 | 
			
		||||
     *     [6] => 'Найдено: JS',
 | 
			
		||||
     *     [7] => 'Найдено: Не опознано',
 | 
			
		||||
     * ]
 | 
			
		||||
     */
 | 
			
		||||
    public $statistics = [
 | 
			
		||||
        '',
 | 
			
		||||
        1,
 | 
			
		||||
        [
 | 
			
		||||
            0,
 | 
			
		||||
            0,
 | 
			
		||||
            0
 | 
			
		||||
        ],
 | 
			
		||||
        [
 | 
			
		||||
            0,
 | 
			
		||||
            0,
 | 
			
		||||
            0
 | 
			
		||||
        ],
 | 
			
		||||
        [
 | 
			
		||||
            0,
 | 
			
		||||
            0,
 | 
			
		||||
            0,
 | 
			
		||||
            0,
 | 
			
		||||
            0,
 | 
			
		||||
            0,
 | 
			
		||||
            0,
 | 
			
		||||
            0,
 | 
			
		||||
        ]
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Время начала выполнения скрипта
 | 
			
		||||
     * 
 | 
			
		||||
     * Используется для вычисления времени выполнения и записи в статистику
 | 
			
		||||
     */
 | 
			
		||||
    public $timeStart;
 | 
			
		||||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        // Начало отсчёта синтетического теста времени выполнеия для записи в статистику
 | 
			
		||||
        $this->timeStart = microtime(true);
 | 
			
		||||
 | 
			
		||||
        // if (YII_DEBUG) {
 | 
			
		||||
            register_shutdown_function(array(&$this, 'saveStatistics'));
 | 
			
		||||
        // }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Скачивание страницы
 | 
			
		||||
     * 
 | 
			
		||||
     * @param string $link Ссылка
 | 
			
		||||
     * @param int $depth Глубина скачивания вложенных ссылок
 | 
			
		||||
     * @param int $buffer Буфер файлов
 | 
			
		||||
     * @param bool $force Флаг форсированного выполнения (с перезаписью существующих файлов)
 | 
			
		||||
     * @param string $path Свой путь для сохранения
 | 
			
		||||
     * @param bool $searchExternal Флаг поиска ссылок во внешних сайтах
 | 
			
		||||
     * 
 | 
			
		||||
     * @return Dump
 | 
			
		||||
     */
 | 
			
		||||
    public function download($link, $depth = 0, $buffer = 0, $force = false, $searchExternal = false, $path = '')
 | 
			
		||||
    {
 | 
			
		||||
        if (!$link = $this->filterLink($link)) {
 | 
			
		||||
            // Если ссылка не прошла фильтрацию
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Инициализация свойств
 | 
			
		||||
        if (!isset($this->buffer)) {
 | 
			
		||||
            $this->buffer = $buffer;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!isset($this->force)) {
 | 
			
		||||
            $this->force = $force;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!isset(Yii::$app->params['basePath'])) {
 | 
			
		||||
            Yii::$app->params['basePath'] = $path;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!isset($this->searchExternal)) {
 | 
			
		||||
            $this->searchExternal = $searchExternal;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!isset($this->connectionProtocol)) {
 | 
			
		||||
            // Проверка наличия domain.zone в ссылке на подобие: 'https://domain.zone/foo/bar'
 | 
			
		||||
            preg_match_all('/(.*)?:?(\/\/|\\\\)(.*)((\/|\\\|$).*$)/U', $link, $linkMatch);
 | 
			
		||||
 | 
			
		||||
            $this->connectionProtocol = $linkMatch[1][0] ?? $_SERVER['REQUEST_SCHEME'] ?? $_SERVER['HTTP_X_FORWARDED_PROTO'] ?? 'http';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!isset($this->connectionHost)) {
 | 
			
		||||
            // Проверка наличия domain.zone в ссылке на подобие: 'https://domain.zone/foo/bar'
 | 
			
		||||
            preg_match_all('/(.*)?:?(\/\/|\\\\)(.*)((\/|\\\|$).*$)/U', $link, $linkMatch);
 | 
			
		||||
 | 
			
		||||
            // Проверка наличия domain.zone в ссылке на подобие: 'domain.zone/' или 'domain.zone' или 'subdomain.domain.zone'
 | 
			
		||||
            preg_match_all('/^([^\\\|\/|\\s]+\.[^\\\|\/|\\s]+)(\\\|\/)?$/', $link, $domainMatch);
 | 
			
		||||
 | 
			
		||||
            $this->connectionHost = $linkMatch[3][0] ?? $domainMatch[1][0] ?? $_SERVER['REQUEST_HOST'] ?? $_SERVER['HTTP_HOST'] ?? '127.0.0.1';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Обработка буфера (это весь его код)
 | 
			
		||||
        if (count($this->filesBuffer) >= $this->buffer) {
 | 
			
		||||
            $this->save();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Если скачивание является первым (ручной запрос)
 | 
			
		||||
        if (!isset($this->target)) {
 | 
			
		||||
            // Инициализация стартовой ссылки
 | 
			
		||||
            $this->target = $link;
 | 
			
		||||
 | 
			
		||||
            // Добавление стартовой ссылки в регистр
 | 
			
		||||
            array_unshift($this->links, $link);
 | 
			
		||||
 | 
			
		||||
            // Инициализация цели в статистике
 | 
			
		||||
            // if (YII_DEBUG) {
 | 
			
		||||
                $this->statistics[0] = $this->target;
 | 
			
		||||
            // }
 | 
			
		||||
 | 
			
		||||
            // Прибавление стартовой ссылки для вывода в статистике
 | 
			
		||||
            // if (YII_DEBUG) {
 | 
			
		||||
                // if (!isset($this->statistics[2][1])) {
 | 
			
		||||
                //     $this->statistics[2][1] = 0;
 | 
			
		||||
                // }
 | 
			
		||||
                // $this->statistics[2][1]++;
 | 
			
		||||
                $this->statistics[2][1] = 1;
 | 
			
		||||
            // }
 | 
			
		||||
        } else if ($this->subdownload && $depth === 0) {
 | 
			
		||||
            // Иначе если это дополнительное скачивание и глубина равна нулю
 | 
			
		||||
 | 
			
		||||
            $this->linksNew++;
 | 
			
		||||
            // Добавление стартовой ссылки в регистр
 | 
			
		||||
            array_unshift($this->links, $link);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Обработка стартовой ссылки
 | 
			
		||||
        if (isset($this->target)) {
 | 
			
		||||
            // Внимание: $targetMatch не очищается и используется в коде ниже
 | 
			
		||||
            preg_match_all('/(.*)?:?(\/\/|\\\\)(.*)((\/|\\\|$).*$)/U', $this->target, $targetMatch);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (preg_match('/^[^\/|\\\]+\..+$/', $link)) {
 | 
			
		||||
            // Паттерн: 'domain.zone', 'domain.zone/foo/bar/index.html'
 | 
			
		||||
            $request = ($this->connectionProtocol ?? 'http') . '://' . $link;
 | 
			
		||||
        } else if (preg_match_all('/(^http.*(\/\/|\\\\)|^(\/\/|\\\\))(.*)(\/|\\\|$)(.*$)/iU', $link, $match)) {
 | 
			
		||||
            // Паттерн: 'https://domain.zone/foo/index.html', '//domain.zone/foo'
 | 
			
		||||
            $request = ($this->connectionProtocol ?? 'http') . '://' . $match[4][0] . '/' . $match[6][0];
 | 
			
		||||
        } else if (preg_match('/(^\/[^\/\\\\\s]+[^\s]*$|^\\\[^\/\\\\\s]+[^\\s]*$|^\/$|^\\\$)/', $link)) {
 | 
			
		||||
            // Паттерн: '/', '/foo/bar', '/foo/bar/index.html'
 | 
			
		||||
            $request = ($this->connectionProtocol ?? 'http') . '://' . ($targetMatch[3][0] ?? $this->connectionHost) . $link;
 | 
			
		||||
        } else if (preg_match('/(^[^\/\\\\\s\.]+(\/|\\\|$)([^\/\\\\\s]*$|[^\/\\\\\s]+(\/|\\\).*))/', $link)) {
 | 
			
		||||
            // Паттерн: 'foo/index.html', 'foo/bar/index.html', 'foo', 'foo/'
 | 
			
		||||
            // Не помню почему регулярное выражение такое сложное, разбираться сейчас не стал, так как главное, что работает
 | 
			
		||||
            $request = ($this->connectionProtocol ?? 'http') . '://' . ($targetMatch[3][0] ?? $this->connectionHost) . '/' . $link;
 | 
			
		||||
        } else {
 | 
			
		||||
            unset($this->links[$link]);
 | 
			
		||||
            // throw new Exception('Не удалось идентифицировать запрос');
 | 
			
		||||
            return $this;
 | 
			
		||||
        }
 | 
			
		||||
        unset($match); // Очистка на всякий случай, так как переменные остаются
 | 
			
		||||
 | 
			
		||||
        // Выполнение запроса
 | 
			
		||||
        $this->filesBuffer[$link][1] = (new Curl())->setOption(CURLOPT_RETURNTRANSFER, true)
 | 
			
		||||
            ->setOption(CURLOPT_FOLLOWLOCATION, true)
 | 
			
		||||
            ->setOption(CURLOPT_SSL_VERIFYPEER, true)
 | 
			
		||||
            ->setOption(CURLOPT_USERAGENT, Yii::$app->params['useragent'])
 | 
			
		||||
            ->get($request);
 | 
			
		||||
 | 
			
		||||
        if (preg_match('/(https?:(\/\/|\\\\).+(\/|\\\).+|^(\/|\\\).+)(\.(?!php|htm)[A-z0-9]+)[^\/\\\s]*$/i', $link)) {
 | 
			
		||||
            // Если ссылка является документом ('.css', '.js', '.png'...)
 | 
			
		||||
            $this->filesBuffer[$link][0] = 1;
 | 
			
		||||
        } else {
 | 
			
		||||
            // Иначе расценивается как HTML страница для продолжения поиска
 | 
			
		||||
            preg_match_all('/(.*)?:?(\/\/|\\\\)(.*)((\/|\\\|$).*$)/U', $link, $linkMatch);
 | 
			
		||||
 | 
			
		||||
            // Если это внутренний URL или domain.zone цели сходится с domain.zone обрабатываемой ссылки или есть разрешение на проход внешних ссылок
 | 
			
		||||
            if (empty($linkMatch[3][0]) || $targetMatch[3][0] === $linkMatch[3][0] || $this->searchExternal === true) {
 | 
			
		||||
                $this->filesBuffer[$link][0] = 0;
 | 
			
		||||
                $file = $this->filesBuffer[$link][1];
 | 
			
		||||
            } else {
 | 
			
		||||
                $this->filesBuffer[$link][0] = 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        unset($targetMatch, $linkMatch, $link); // Очистка на всякий случай, так как переменные остаются
 | 
			
		||||
 | 
			
		||||
        // Извлечение ссылок из страницы по свойствам href='' и src=''
 | 
			
		||||
        // Единственное место где добавляются найденные ссылки
 | 
			
		||||
        if (!empty($file) && $depth > 0 && preg_match_all('/(href|src)\\s?=\\s*[\"\']?((?!(\"|\'))(?!tel)(?!mailto)[^\"\']+)[\"\']/i', $file, $match)) {
 | 
			
		||||
            // Если файл скачан, глубина больше нуля и были найдены ссылки
 | 
			
		||||
 | 
			
		||||
            // Прибавление количества новых ссылок для обработки
 | 
			
		||||
            $this->linksNew += count($match[2]);
 | 
			
		||||
 | 
			
		||||
            // Прибавление количества новых ссылок для вывода в статистике
 | 
			
		||||
            // if (YII_DEBUG) {
 | 
			
		||||
                $this->statistics[2][0] += count($match[2]);
 | 
			
		||||
            // }
 | 
			
		||||
 | 
			
		||||
            // Добавление ссылок в общий регистр
 | 
			
		||||
            foreach ($match[2] as $link) {
 | 
			
		||||
                if (!$link = $this->filterLink($link)) {
 | 
			
		||||
                    // Если ссылка не прошла фильтрацию
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                array_unshift($this->links, $link);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        unset($link, $file, $match); // Очистка на всякий случай, так как переменные остаются
 | 
			
		||||
 | 
			
		||||
        // Конвертация ссылок
 | 
			
		||||
        if (isset($this->links) && $this->linksNew) {
 | 
			
		||||
            // Если глубина больше ноля, ссылки существуют и счетчик новых ссылок больше ноля
 | 
			
		||||
 | 
			
		||||
            $this->convertLinks();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!$this->subdownload) {
 | 
			
		||||
            // Если это не дополнительное скачивание и текущая глубина не равна нулю
 | 
			
		||||
 | 
			
		||||
            // Устанавливается для того, чтобы работать в цикле
 | 
			
		||||
            $this->depth = $depth;
 | 
			
		||||
 | 
			
		||||
            // Скачиваем найденные страницы по установленной глубине поиска
 | 
			
		||||
            while ($this->depth-- > 0) {
 | 
			
		||||
                foreach ($this->links as $link => $type) {
 | 
			
		||||
                    $this->subdownload = true;
 | 
			
		||||
                    $this->download($link, $this->depth);
 | 
			
		||||
                    $this->subdownload = false;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                $this->convertFiles($this->save(), true);
 | 
			
		||||
            }
 | 
			
		||||
            unset($link, $type);
 | 
			
		||||
        } 
 | 
			
		||||
 | 
			
		||||
        // Сохранение остатков ссылок после обработки
 | 
			
		||||
        $this->save();
 | 
			
		||||
 | 
			
		||||
        // Конвертация сохранённых файлов
 | 
			
		||||
        $this->convertFiles();
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Сохранение страницы
 | 
			
		||||
     * 
 | 
			
		||||
     * Получает на вход файлы из буфера и сохраняет на диске
 | 
			
		||||
     * На выходе будут перенесены в массив $this->files
 | 
			
		||||
     * 
 | 
			
		||||
     * @return array
 | 
			
		||||
     */
 | 
			
		||||
    public function save($files = null)
 | 
			
		||||
    {
 | 
			
		||||
        if (empty($files)) {
 | 
			
		||||
            $files = &$this->filesBuffer;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (isset($this->links)) {
 | 
			
		||||
            $this->convertLinks();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $savedFiles = [];
 | 
			
		||||
 | 
			
		||||
        foreach ($files as $link => $file) {
 | 
			
		||||
            if (!empty($this->links[$link][1]) && !preg_match('/^(\/|\\\)/', $this->links[$link][1])) {
 | 
			
		||||
                // Если в начале ссылки нет слеша и ссылка не, то добавить слеш
 | 
			
		||||
                $this->links[$link][1] = '/' . $this->links[$link][1];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // if (!isset($this->links[$link])) {
 | 
			
		||||
            //     $this->convertLinks();
 | 
			
		||||
            // }
 | 
			
		||||
 | 
			
		||||
            // Проверка существования каталога и его создание 
 | 
			
		||||
            if (/** isset($this->links[$link] && */ !file_exists(Yii::$app->params['basePath'] . $this->links[$link][1])) {
 | 
			
		||||
                if (!mkdir(Yii::$app->params['basePath'] . $this->links[$link][1], 0755, true)) {
 | 
			
		||||
                    // throw new Exception('Не удалось создать каталог');
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Сохранение файла
 | 
			
		||||
            if (!file_exists(Yii::$app->params['basePath'] . $this->links[$link][1] . $this->links[$link][0]) || $this->force) {
 | 
			
		||||
                if (file_put_contents(Yii::$app->params['basePath'] . $this->links[$link][1] . $this->links[$link][0], $file[1])) {
 | 
			
		||||
                    $this->files[$link][0] = $file[0];
 | 
			
		||||
                    $this->files[$link][1] = $file[1];
 | 
			
		||||
                } else {
 | 
			
		||||
                    // throw new Exception('Не удалось сохранить файл');
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            $savedFiles[$link] = $files[$link];
 | 
			
		||||
            unset($files[$link]);
 | 
			
		||||
        }
 | 
			
		||||
        unset($link, $file); // Очистка на всякий случай, так как переменные остаются
 | 
			
		||||
 | 
			
		||||
        // Указание сборщику статистики, что парсер успешно завершил свою работу
 | 
			
		||||
        // if (YII_DEBUG) {
 | 
			
		||||
            $this->statistics[1] = 0;
 | 
			
		||||
        // }
 | 
			
		||||
 | 
			
		||||
        return $savedFiles;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Сохранить статистику
 | 
			
		||||
     * 
 | 
			
		||||
     * Возвращает статус сохранения (true/false)
 | 
			
		||||
     * 
 | 
			
		||||
     * @return bool
 | 
			
		||||
     */
 | 
			
		||||
    public function saveStatistics()
 | 
			
		||||
    {
 | 
			
		||||
        // Запись времени окончания работы скрипта
 | 
			
		||||
        $timeFinish = microtime(true);
 | 
			
		||||
 | 
			
		||||
        $i = new DateTime(Yii::$app->params['timezone'] ?? 'Europe/Moscow');
 | 
			
		||||
 | 
			
		||||
        $date = date_format($i, 'Y-m-d');
 | 
			
		||||
        $dateFull = date_format($i, 'Y.m.d H:i:s');
 | 
			
		||||
 | 
			
		||||
        $request            = $this->statistics[0]                ?? 'Ошибка';
 | 
			
		||||
        $time               = ($timeFinish - $this->timeStart)    ?? 'Ошибка';
 | 
			
		||||
        $status             = $this->statistics[1] === 0 ? 'Успех' : 'Ошибка';
 | 
			
		||||
 | 
			
		||||
        $linksCount         = $this->statistics[2][0]             ?? 'Ошибка';
 | 
			
		||||
        $linksProcessed     = $this->statistics[2][1]             ?? 'Ошибка';
 | 
			
		||||
        $linksProcessedReal = $this->statistics[2][2]             ?? 'Ошибка';
 | 
			
		||||
 | 
			
		||||
        $pagesCount         = $this->statistics[3][0]             ?? 'Ошибка';
 | 
			
		||||
        $pagesProcessed     = $this->statistics[3][1]             ?? 'Ошибка';
 | 
			
		||||
 | 
			
		||||
        $filesCount         = $this->statistics[4][0]             ?? 'Ошибка';
 | 
			
		||||
 | 
			
		||||
        $imagesCount        = $this->statistics[4][2]             ?? 'Ошибка';
 | 
			
		||||
        $videosCount        = $this->statistics[4][3]             ?? 'Ошибка';
 | 
			
		||||
        $audiosCount        = $this->statistics[4][4]             ?? 'Ошибка';
 | 
			
		||||
        $cssCount           = $this->statistics[4][5]             ?? 'Ошибка';
 | 
			
		||||
        $jsCount            = $this->statistics[4][6]             ?? 'Ошибка';
 | 
			
		||||
        $unidentifiedCount  = $this->statistics[4][7]             ?? 'Ошибка';
 | 
			
		||||
 | 
			
		||||
        if (!file_exists(Yii::getAlias('@runtime/logs'))) {
 | 
			
		||||
            if (!mkdir(Yii::getAlias('@runtime/logs'), 0755, true)) {
 | 
			
		||||
                // throw new Exception('Не удалось создать каталог');
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        $file = fopen(Yii::getAlias('@runtime/logs') . '/' . $date . uniqid('_DUMPER_', true) . '.log', 'a+');
 | 
			
		||||
 | 
			
		||||
        if (!fwrite($file, <<<EOT
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
///                Статистика выполнения                ///
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
                       Дата:   $dateFull
 | 
			
		||||
 | 
			
		||||
                     Запрос:   $request
 | 
			
		||||
           Время выполнения:   $time секунд
 | 
			
		||||
          Статус выполнения:   $status
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
             Найдено ссылок:   $linksCount
 | 
			
		||||
          Обработано ссылок:   $linksProcessed
 | 
			
		||||
      Из них без дубликатов:   $linksProcessedReal
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
            Найдено страниц:   $pagesCount
 | 
			
		||||
     Конвертировано страниц:   $pagesProcessed
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
         Найдено документов:   $filesCount
 | 
			
		||||
 | 
			
		||||
                Изображения:   $imagesCount
 | 
			
		||||
                Видеозаписи:   $videosCount
 | 
			
		||||
                Аудиозаписи:   $audiosCount
 | 
			
		||||
                CSS скрипты:   $cssCount
 | 
			
		||||
                 JS скрипты:   $jsCount
 | 
			
		||||
                Не опознано:   $unidentifiedCount
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
EOT
 | 
			
		||||
)) {
 | 
			
		||||
            // throw new Exception('Не удалось записать статистику');
 | 
			
		||||
        }
 | 
			
		||||
        fclose($file);
 | 
			
		||||
 | 
			
		||||
        unset($i, $date, $dateFull, $file); // Очистка на всякий случай, так как переменные остаются
 | 
			
		||||
 | 
			
		||||
        // return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Конвертер ссылок
 | 
			
		||||
     * 
 | 
			
		||||
     * Приводит ссылки к заданному архитектурой виду
 | 
			
		||||
     * 
 | 
			
		||||
     * @return array
 | 
			
		||||
     */
 | 
			
		||||
    private function convertLinks($links = null)
 | 
			
		||||
    {
 | 
			
		||||
        if (empty($links)) {
 | 
			
		||||
            $links = &$this->links;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        while ($this->linksNew >= 0) {
 | 
			
		||||
            // Инициализация ссылки и копии для будущего поиска в файлах
 | 
			
		||||
            if (!array_key_exists($this->linksNew, $links)) {
 | 
			
		||||
                // Подготовка к следующей итерации цикла
 | 
			
		||||
                $this->linksNew--;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            $link = $rawLink = $links[$this->linksNew];
 | 
			
		||||
 | 
			
		||||
            if (is_array($link)) {
 | 
			
		||||
                // Если это уже конвертированная ссылка
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $uri = $this->initLink($link);
 | 
			
		||||
 | 
			
		||||
            // !!!!!!!!!!!!!!!!!!!!!!!
 | 
			
		||||
            preg_match_all('/\/\/(.*)((\/|$).*$)/U', $uri, $uriMatch);
 | 
			
		||||
            preg_match_all('/\/\/(.*)((\/|$).*$)/U', $this->target, $targetMatch);
 | 
			
		||||
 | 
			
		||||
            if ($targetMatch[1][0] === $uriMatch[1][0]) {
 | 
			
		||||
                $location = '';
 | 
			
		||||
            } else {
 | 
			
		||||
                $location = Yii::$app->params['externalLinksPath'] . '/' . $uriMatch[1][0];
 | 
			
		||||
            }
 | 
			
		||||
            unset($uriMatch, $targetMatch);
 | 
			
		||||
 | 
			
		||||
            // Инициализация ссылки
 | 
			
		||||
            if ($uri === $this->target || $uri . '/' === $this->target || $uri === $this->target . '/' || $uri . '\\' === $this->target || $uri === $this->target . '\\' || $uri === '/' || $uri === '\\') {
 | 
			
		||||
                // Если это первый запуск (запрошенная, главная ссылка)
 | 
			
		||||
 | 
			
		||||
                // Создание ссылки
 | 
			
		||||
                $links[$rawLink][0] = '/index.html';
 | 
			
		||||
                $links[$rawLink][1] = '';
 | 
			
		||||
                $links[$rawLink][2] = '/index.html';
 | 
			
		||||
            } else if (preg_match('/\\.css/i', $uri)) {
 | 
			
		||||
                // Если это CSS файл
 | 
			
		||||
 | 
			
		||||
                // Получение последнего каталога (имени файла с расширением), например: '/index.html'
 | 
			
		||||
                if (preg_match_all('/[^\/\\\\\s]+$/', $uri, $file)) {
 | 
			
		||||
                    // Создание ссылки
 | 
			
		||||
                    $links[$rawLink][0] = '/' . $file[0][0];
 | 
			
		||||
                    $links[$rawLink][1] = $location . Yii::$app->params['cssPath'];
 | 
			
		||||
                    $links[$rawLink][2] = $links[$rawLink][1] . $links[$rawLink][0];
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Обновление статистики
 | 
			
		||||
                // if (YII_DEBUG) {
 | 
			
		||||
                    $this->statistics[4][0]++;
 | 
			
		||||
                    $this->statistics[4][5]++;
 | 
			
		||||
                // }
 | 
			
		||||
            } else if (preg_match('/\\.js/i', $uri)) {
 | 
			
		||||
                // Если это JS файл
 | 
			
		||||
 | 
			
		||||
                // Получение последнего каталога (имени файла с расширением), например: '/index.html'
 | 
			
		||||
                if (preg_match_all('/[^\/\\\\\s]+$/', $uri, $file)) {
 | 
			
		||||
                    // Создание ссылки
 | 
			
		||||
                    $links[$rawLink][0] = '/' . $file[0][0];
 | 
			
		||||
                    $links[$rawLink][1] = $location . Yii::$app->params['jsPath'];
 | 
			
		||||
                    $links[$rawLink][2] = $links[$rawLink][1] . $links[$rawLink][0];
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Обновление статистики
 | 
			
		||||
                // if (YII_DEBUG) {
 | 
			
		||||
                    $this->statistics[4][0]++;
 | 
			
		||||
                    $this->statistics[4][6]++;
 | 
			
		||||
                // }
 | 
			
		||||
            } else if (preg_match('/(\\.png|\\.jpeg|\\.jpg|\\.webp|\\.gif|\\.svg|\\.ico)/i', $uri)) {
 | 
			
		||||
                // Если это изображение
 | 
			
		||||
 | 
			
		||||
                // Получение последнего каталога (имени файла с расширением), например: '/index.html'
 | 
			
		||||
                if (preg_match_all('/[^\/\\\\\s]+$/', $uri, $file)) {
 | 
			
		||||
                    // Создание ссылки
 | 
			
		||||
                    $links[$rawLink][0] = '/' . $file[0][0];
 | 
			
		||||
                    $links[$rawLink][1] = $location . Yii::$app->params['imgPath'];
 | 
			
		||||
                    $links[$rawLink][2] = $links[$rawLink][1] . $links[$rawLink][0];
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Обновление статистики
 | 
			
		||||
                // if (YII_DEBUG) {
 | 
			
		||||
                    $this->statistics[4][0]++;
 | 
			
		||||
                    $this->statistics[4][2]++;
 | 
			
		||||
                // }
 | 
			
		||||
            } else if (preg_match('/(https?:(\/\/|\\\\).+(\/|\\\).+|^(\/|\\\).+)(\.(?!php|htm)[A-z0-9]+)[^\/\\\s]*$/i', $uri)) {
 | 
			
		||||
                // Если это неопознанный документ (очень затратное выражение, но по другому никак)
 | 
			
		||||
 | 
			
		||||
                // Получение последнего каталога (имени файла с расширением), например: '/index.html'
 | 
			
		||||
                if (preg_match_all('/[^\/\\\\\s]+$/', $uri, $file)) {
 | 
			
		||||
                    // Создание ссылки
 | 
			
		||||
                    $links[$rawLink][0] = '/' . $file[0][0];
 | 
			
		||||
                    $links[$rawLink][1] = $location . Yii::$app->params['docsPath'];
 | 
			
		||||
                    $links[$rawLink][2] = $links[$rawLink][1] . $links[$rawLink][0];
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Обновление статистики
 | 
			
		||||
                // if (YII_DEBUG) {
 | 
			
		||||
                    $this->statistics[4][0]++;
 | 
			
		||||
                    $this->statistics[4][7]++;
 | 
			
		||||
                // }
 | 
			
		||||
            } else if (preg_match_all('/(\/\/|\\\\)(.*)((\/|\\|$).*$)/U', $uri, $uriMatch)) {
 | 
			
		||||
                // Иначе, если это обрабатывается универсально или как HTML документ
 | 
			
		||||
 | 
			
		||||
                if (isset($uriMatch[3][0])) {
 | 
			
		||||
                     // Если есть путь к файлу, например 'https://domain.zone/это/обязательно/index.html'
 | 
			
		||||
                    if (preg_match_all('/^([^\/\\\\\s\.]*[^\\s\.]+)([^\/\\\]*\.html|[^\/\\\]*\.php|[^\/\\\]*\.htm)?$/U', $uriMatch[3][0], $uriSplit)) {
 | 
			
		||||
                        // Если в URI не найден URN (файл с расширением, например: 'index.php')
 | 
			
		||||
 | 
			
		||||
                        if (empty($uriSplit[2][0])) {
 | 
			
		||||
                            $uriSplit[2][0] = '/index.html';
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // Создание ссылки
 | 
			
		||||
                        $links[$rawLink][0] = $uriSplit[2][0];
 | 
			
		||||
                        $links[$rawLink][1] = $location . Yii::$app->params['pagesPath'] . $uriSplit[1][0];
 | 
			
		||||
                        $links[$rawLink][2] = $links[$rawLink][1] . $links[$rawLink][0];
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    // Иначе обрабатывается как пустая ссылка, например 'https://domain.zone'
 | 
			
		||||
 | 
			
		||||
                    // Создание ссылки
 | 
			
		||||
                    $links[$rawLink][0] = '/index.html';
 | 
			
		||||
                    $links[$rawLink][1] = $location . Yii::$app->params['pagesPath'] . '/' . $uriMatch[1][0];
 | 
			
		||||
                    $links[$rawLink][2] = $links[$rawLink][1] . '/index.html';
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Прибавление количеству найденных страниц
 | 
			
		||||
                // if (YII_DEBUG) {
 | 
			
		||||
                    $this->statistics[3][0]++;
 | 
			
		||||
                // }
 | 
			
		||||
            } else {
 | 
			
		||||
                // Иначе, ссылку не удалось инициализировать, пропуск
 | 
			
		||||
 | 
			
		||||
                // throw new Exception('Не удалось идентифицировать сохранённую ссылку: '.$link)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Удаление обработанной ссылки и оставшихся переменных
 | 
			
		||||
            unset($links[$this->linksNew], $rawLink, $location, $uriSplit, $match, $file, $uri);
 | 
			
		||||
 | 
			
		||||
            // Прибавление количеству обработанных ссылок
 | 
			
		||||
            // if (YII_DEBUG) {
 | 
			
		||||
                $this->statistics[2][1]++;
 | 
			
		||||
            // }
 | 
			
		||||
 | 
			
		||||
            // Подготовка к следующей итерации цикла
 | 
			
		||||
            $this->linksNew--;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Количество обработанных ссылок без дубликатов
 | 
			
		||||
        // if (YII_DEBUG) {
 | 
			
		||||
            // Количество обработанных ссылок без дубликатов
 | 
			
		||||
            $this->statistics[2][2] = count($this->links);
 | 
			
		||||
        // }
 | 
			
		||||
 | 
			
		||||
        return $links;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Конвертер страниц
 | 
			
		||||
     * 
 | 
			
		||||
     * Преобразует ссылки в тексте (HTML документе)
 | 
			
		||||
     * Возвращает массив не найденных файлов
 | 
			
		||||
     * 
 | 
			
		||||
     * @param array $files Файлы для конвертации
 | 
			
		||||
     * 
 | 
			
		||||
     * @return array
 | 
			
		||||
     */
 | 
			
		||||
    private function convertFiles($files = null)
 | 
			
		||||
    {
 | 
			
		||||
        if (empty($files)) {
 | 
			
		||||
            $files = &$this->files;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        foreach ($files as $link => &$file) {
 | 
			
		||||
            if ($file[0] === 0 && isset($this->links[$link]) && file_exists(Yii::$app->params['basePath'] . $this->links[$link][1] . $this->links[$link][0]) && $content = file_get_contents(Yii::$app->params['basePath'] . $this->links[$link][1] . $this->links[$link][0])) {
 | 
			
		||||
                // Если метаданные файла указывают, что он является HTML документом
 | 
			
		||||
 | 
			
		||||
                if (preg_match_all('/(href|src)\\s?=\\s*[\"\']?((?!(\"|\'))(?!tel)(?!mailto)[^\"\']+)[\"\']/i', $content, $match)) {
 | 
			
		||||
                    // Если найдены ссылки
 | 
			
		||||
 | 
			
		||||
                    // Конвертация
 | 
			
		||||
                    foreach ($match[2] as $rawLink) {
 | 
			
		||||
                        if (!$rawLink = $this->filterLink($rawLink)) {
 | 
			
		||||
                            // Если ссылка не прошла фильтрацию
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (!array_key_exists($rawLink, $this->links)) {
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        $content = preg_replace('/(\"|\')' . preg_quote($rawLink, '/') . '(\"|\')/', '".' . $this->links[$rawLink][2] . '"', $content);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // Инъекция тега <base> в страницу, чтобы работали относительные пути
 | 
			
		||||
                    if (preg_match_all('/(.*<head>)(.*)/si', $content, $contentMatch)) {
 | 
			
		||||
                        // Если удалось найти <head> в странице
 | 
			
		||||
 | 
			
		||||
                        // Определяем вложенность страницы
 | 
			
		||||
                        if (preg_match_all('/([^\\\|\/|\\s]+)/', $this->links[$link][1], $urlMatch)) {
 | 
			
		||||
                            $catalogsDepth = count($urlMatch[1]);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            // throw new Exception('Ошибка при инъекции <base>: не удалось посчитать вложенность страницы');
 | 
			
		||||
                        }
 | 
			
		||||
                        
 | 
			
		||||
                        $content = $contentMatch[1][0] . "\n<base href=\"" . str_repeat('../', $catalogsDepth ?? 0) . '">'. $contentMatch[2][0];
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // Сохранение файла
 | 
			
		||||
                    if (file_put_contents(Yii::$app->params['basePath'] . $this->links[$link][1] . $this->links[$link][0], $content)) {
 | 
			
		||||
                        unset($this->files[$link]);
 | 
			
		||||
 | 
			
		||||
                        // Прибавление количеству конвертированных страниц
 | 
			
		||||
                        // if (YII_DEBUG) {
 | 
			
		||||
                            $this->statistics[3][1]++;
 | 
			
		||||
                        // }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        // throw new Exception('Не удалось сохранить файл');
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else if ($file[0] !== 0) {
 | 
			
		||||
                // Если файл не является HTML документом
 | 
			
		||||
 | 
			
		||||
                unset($this->files[$link]);
 | 
			
		||||
            } else {
 | 
			
		||||
                // Иначе воспринимается как не HTML документ, который не требует конвертацию
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        unset($link, $file); // Очистка на всякий случай, так как переменные остаются
 | 
			
		||||
 | 
			
		||||
        return $files;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Фильтрация ссылки
 | 
			
		||||
     * 
 | 
			
		||||
     * Перед инициализацией ссылка проверяется фильтрами
 | 
			
		||||
     * 
 | 
			
		||||
     * @return ?string
 | 
			
		||||
     */
 | 
			
		||||
    private function filterLink($link)
 | 
			
		||||
    {
 | 
			
		||||
        // Проверка существования URL в чёрном списке
 | 
			
		||||
        if (!empty(Yii::$app->params['regBlackList']) && preg_match('/' . Yii::$app->params['regBlackList'] . '/', $link)) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Преобразование слешей в Unix стиль, унификация
 | 
			
		||||
        $link = preg_replace('/\\\/', '/', $link);
 | 
			
		||||
 | 
			
		||||
        return $link;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Инициализация ссылки
 | 
			
		||||
     * 
 | 
			
		||||
     * Подготовка к конвертации
 | 
			
		||||
     * 
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    private function initLink($link)
 | 
			
		||||
    {
 | 
			
		||||
        // Подготовка ссылок перед обработкой
 | 
			
		||||
        // Разбиение ссылки на каталоги: 'https://domain.zone/foo/bar/index.html' на 'https:', 'domain.zone', 'foo', 'bar', 'index.html'
 | 
			
		||||
        if (preg_match_all('/([^\\\|\/|\\s]+)/', $link, $uriMatch)) {
 | 
			
		||||
            // Определение того, что URI является полноценным и имеет протокол подключения, например: 'https:', 'ssh:', 'mail:'
 | 
			
		||||
            if (preg_match('/^.*:$/', $uriMatch[0][0])) {
 | 
			
		||||
                $uri = $uriMatch[0][0] . '//' . $uriMatch[0][1];
 | 
			
		||||
                $uriMatch[0] = array_slice($uriMatch[0], 2);
 | 
			
		||||
            } else {
 | 
			
		||||
                $uri = $this->connectionProtocol . ':' . '//' . $this->connectionHost;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Замена всех фрагментов URI от символов, которые Windows не даёт записывать в именах файлов и каталогов на '@'
 | 
			
		||||
            // На данный момент достаточно заменять все символы на один, так как обратная конвертация не потребуется, а шанс конфликта имён минимален
 | 
			
		||||
            foreach ($uriMatch[0] as &$piece) {
 | 
			
		||||
                $piece = preg_replace('/(\\\|\/|\:|\*|\?|\"|\<|\>|\|)/', '@', $piece);
 | 
			
		||||
            }
 | 
			
		||||
            unset($piece);
 | 
			
		||||
 | 
			
		||||
            // Сборка новой ссылки из фрагментов оригинальной
 | 
			
		||||
            foreach ($uriMatch[0] as $piece) {
 | 
			
		||||
                $uri .= '/' . $piece;
 | 
			
		||||
            }
 | 
			
		||||
            unset($piece);
 | 
			
		||||
 | 
			
		||||
        } else if ($link === '/' || $link === '\\') {
 | 
			
		||||
            // Иначе, если ссылка ведёт на главную страницу сайта
 | 
			
		||||
 | 
			
		||||
            // [!!!] Это надо переработать, так как ссылка '/' можеть быть и на стороннем хосте [!!!]
 | 
			
		||||
            $uri = $this->connectionProtocol . ':' . '//' . $this->connectionHost;
 | 
			
		||||
 | 
			
		||||
            // Иначе всё обрабатывается как ссылка на текущего хоста
 | 
			
		||||
        } else {
 | 
			
		||||
            if (!preg_match('/^(\/|\\\)/', $link)) {
 | 
			
		||||
                $link = '/' . $link;
 | 
			
		||||
            }
 | 
			
		||||
            $link = preg_replace('/(\/|\\\)$/', '', $link);
 | 
			
		||||
 | 
			
		||||
            $uri = $this->connectionProtocol . ':' . '//' . $this->connectionHost . $link;
 | 
			
		||||
        }
 | 
			
		||||
        unset($link, $uriMatch, $site);
 | 
			
		||||
 | 
			
		||||
        return $uri;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								yii
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								yii
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
#!/usr/bin/env php
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
defined('YII_DEBUG') or define('YII_DEBUG', true);
 | 
			
		||||
defined('YII_ENV') or define('YII_ENV', 'dev');
 | 
			
		||||
 | 
			
		||||
require __DIR__ . '/vendor/autoload.php';
 | 
			
		||||
require __DIR__ . '/vendor/yiisoft/yii2/Yii.php';
 | 
			
		||||
 | 
			
		||||
$config = require __DIR__ . '/config/console.php';
 | 
			
		||||
 | 
			
		||||
$application = new yii\console\Application($config);
 | 
			
		||||
$exitCode = $application->run();
 | 
			
		||||
exit($exitCode);
 | 
			
		||||
		Reference in New Issue
	
	Block a user