Skip to content

Commit bdfc5fa

Browse files
committed
init autoloader && composer
1 parent 4e6388d commit bdfc5fa

File tree

12 files changed

+1835
-119
lines changed

12 files changed

+1835
-119
lines changed

.env

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
FORUM_URL='http://forumodua.com/'
2+
3+
USER_AGENT=
4+
5+
AUTH_USERNAME=
6+
AUTH_PASSWORD=
7+
AUTH_URL=
8+
9+
AUTH_FORM_ID='navbar_loginform'
10+
11+
THEME_URL='http://forumodua.com/showthread.php?t=549241&page=11'
12+
13+
LOG_ERROR_FILENAME=
14+
LOG_WARNING_FILENAME=
15+
16+
MESSAGE_POST_CLASS='postbitlegacy'
17+
MESSAGE_DATE_CLASS='postdate'

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,6 @@ Temporary Items
4848
# .nfs files are created when an open file is removed but is still being accessed
4949
.nfs*
5050

51+
vendor/
52+
.env
53+

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
#v0.1
22
Create simple parser
33
#v0.2
4-
Create authorisation
4+
Create authorisation
5+
#v0.3
6+
Init configuration
7+
#v0.4
8+
Init composer etc

app/Logger.php

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
namespace App;
4+
5+
use Exception;
6+
7+
class Logger
8+
{
9+
protected $message = '';
10+
11+
private $logType = 'info';
12+
private $directory = 'logs';
13+
private $logFile = '';
14+
private $logExtension = '.txt';
15+
16+
/**
17+
* @param $message
18+
*
19+
* @throws Exception
20+
*/
21+
public function addError($message)
22+
{
23+
$this->message = $message;
24+
$this->logFile = getenv('LOG_ERROR_FILENAME') ?: 'errors';
25+
$this->logType = 'error';
26+
27+
$this->writeLine();
28+
}
29+
30+
/**
31+
* @param $message
32+
*
33+
* @throws Exception
34+
*/
35+
public function addWarning($message)
36+
{
37+
$this->message = $message;
38+
$this->logFile = getenv('LOG_WARNING_FILENAME') ?: 'errors';
39+
$this->logType = 'warning';
40+
41+
$this->writeLine();
42+
}
43+
44+
/**
45+
* @throws Exception
46+
*/
47+
public function writeLine()
48+
{
49+
$message = PHP_EOL.'['.$this->logType.']::'.date('H:i:s d-m-Y').'::'.$this->message;
50+
51+
file_put_contents($this->filePath(), $message, FILE_APPEND);
52+
53+
return $this;
54+
}
55+
56+
/**
57+
* @return string
58+
* @throws Exception
59+
*/
60+
protected function filePath()
61+
{
62+
$logDirectoryPath = __DIR__.'/../'.$this->directory;
63+
64+
if(!$logDirectoryPath){
65+
throw new Exception('Log directory `'.$logDirectoryPath.'` is empty! Please create it.');
66+
}
67+
68+
return __DIR__.'/../'.$this->directory.'/'.$this->logFile.$this->logExtension;
69+
}
70+
}

app/Parser.php

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
<?php
2+
namespace App;
3+
4+
use Exception;
5+
use simple_html_dom;
6+
use simple_html_dom_node;
7+
8+
class Parser
9+
{
10+
protected $forumURL;
11+
12+
protected $curl;
13+
14+
protected $defaultUserAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 '.
15+
'(KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36';
16+
17+
protected $userAgent;
18+
19+
protected $logger;
20+
21+
protected $htmlDom;
22+
23+
public function __construct()
24+
{
25+
$this->forumURL = getenv('FORUM_URL');
26+
$this->userAgent = getenv('USER_AGENT') ?: $this->defaultUserAgent;
27+
28+
$this->logger = new Logger();
29+
30+
$this->htmlDom = new simple_html_dom();
31+
}
32+
33+
/**
34+
* @throws Exception
35+
*/
36+
public function handle()
37+
{
38+
if(!$this->forumURL){
39+
throw new Exception('Forum URL is empty');
40+
}
41+
42+
#region Auth action
43+
$authAction = $this->authAction();
44+
$cookies = '';
45+
46+
if($authAction){
47+
$this->curl = curl_init($authAction);
48+
curl_setopt($this->curl, CURLOPT_FRESH_CONNECT, true);
49+
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
50+
curl_setopt($this->curl, CURLOPT_COOKIESESSION, false);
51+
curl_setopt($this->curl, CURLOPT_POST, true);
52+
curl_setopt($this->curl, CURLOPT_HEADER, true);
53+
curl_setopt($this->curl, CURLOPT_POSTFIELDS, [
54+
'vb_login_username' => getenv('AUTH_USERNAME'),
55+
'vb_login_md5password' => md5(getenv('AUTH_PASSWORD')),
56+
'vb_login_md5password_utf' => md5(getenv('AUTH_PASSWORD')),
57+
'securitytoken' => 'guest',
58+
'cookieuser' => 1,
59+
'do' => 'login',
60+
'vb_login_password' => ''
61+
]);
62+
63+
curl_setopt($this->curl, CURLOPT_USERAGENT, $this->userAgent);
64+
65+
$result = curl_exec($this->curl);
66+
67+
preg_match_all('/Set-Cookie:\s*([^;]*)/', $result, $matches);
68+
69+
foreach($matches[1] as $item) {
70+
$cookies .= $cookies ? '; '.$item : $item;
71+
}
72+
} else{
73+
$this->logger->addWarning('Auth action is empty');
74+
}
75+
#endregion
76+
77+
if(!getenv('THEME_URL')){
78+
throw new Exception('Theme URL is empty');
79+
}
80+
81+
curl_setopt($this->curl, CURLOPT_URL, getenv('THEME_URL'));
82+
curl_setopt($this->curl, CURLOPT_HTTPGET, true);
83+
curl_setopt($this->curl, CURLOPT_COOKIESESSION, false);
84+
curl_setopt($this->curl, CURLOPT_COOKIE, $cookies);
85+
86+
$result = curl_exec($this->curl);
87+
88+
curl_close($this->curl);
89+
90+
$html = $this->htmlDom->load($result);
91+
92+
if(!getenv('MESSAGE_POST_CLASS')){
93+
throw new Exception('Message post class is empty');
94+
}
95+
96+
$messages = $html->find('.'.getenv('MESSAGE_POST_CLASS'));
97+
98+
$theme = $html->find('title', 0)->text();
99+
100+
if($messages){
101+
/** @var simple_html_dom_node $message */
102+
foreach($messages as $message){
103+
$this->saveMessage($message, $theme);
104+
}
105+
} else{
106+
$this->logger->addWarning('Messages are empty');
107+
}
108+
}
109+
110+
/**
111+
* @return string
112+
* @throws Exception
113+
*/
114+
protected function authAction(): string
115+
{
116+
if(getenv('AUTH_URL')) {
117+
return getenv('AUTH_URL');
118+
}
119+
120+
$curl = curl_init($this->forumURL);
121+
122+
curl_setopt($curl, CURLOPT_FRESH_CONNECT, true);
123+
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
124+
curl_setopt($curl, CURLOPT_USERAGENT, $this->userAgent);
125+
126+
$result = curl_exec($curl);
127+
128+
curl_close($curl);
129+
130+
$html = $this->htmlDom->load($result);
131+
132+
$formID = getenv('AUTH_FORM_ID');
133+
134+
/** @var simple_html_dom_node $form */
135+
$form = $html->find('#'.$formID, 0);
136+
137+
if(!$form){
138+
$this->logger->addError('Form is empty on the page');
139+
140+
return '';
141+
}
142+
143+
return $this->forumURL.$form->attr['action'];
144+
}
145+
146+
protected function postsFolder(): string
147+
{
148+
return __DIR__.'/../posts';
149+
}
150+
151+
protected function saveMessage(simple_html_dom_node $message, string $theme)
152+
{
153+
if(!isset($message->attr['id'])){
154+
return $this;
155+
}
156+
157+
$isMessage = preg_match('/^post/', $message->attr['id']);
158+
159+
if($isMessage === false){
160+
return $this;
161+
}
162+
163+
$postDate = $message->find('.'.getenv('MESSAGE_DATE_CLASS'), 0);
164+
165+
$date = $postDate
166+
? preg_replace('/[&nbsp;]+/', ' ', trim($postDate->find('.date', 0)->text()))
167+
: null;
168+
169+
$clearDate = $postDate
170+
? preg_replace('/[ \.:]+/', '-', trim($date))
171+
: null;
172+
173+
$fileName = $theme.'-'.($clearDate ?: time()).'.txt';
174+
175+
$titleDOM = $message->find('h2.title', 0);
176+
177+
/** @var simple_html_dom_node $userNameDOM */
178+
$userNameDOM = $message->find('.userinfo', 0)->find('.username', 0);
179+
180+
/** @var simple_html_dom_node $postContentDOM */
181+
$postContentDOM = $message->find('.postbody', 0)->find('blockquote.postcontent', 0);
182+
183+
$messageTitle = $titleDOM ? $titleDOM->text() : '';
184+
$messageAuthor = $userNameDOM ? $userNameDOM->text() : '';
185+
$messageText = $postContentDOM ? $postContentDOM->text() : '';
186+
187+
$fileContent = trim($messageTitle).PHP_EOL.$messageAuthor.PHP_EOL.$date.PHP_EOL.trim($messageText);
188+
189+
file_put_contents($this->postsFolder().DIRECTORY_SEPARATOR.$fileName, $fileContent);
190+
191+
return $this;
192+
}
193+
}

bootstrap/Autoload.php

Lines changed: 0 additions & 18 deletions
This file was deleted.

composer.json

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "lutdev/techtask",
3+
"description": "PHP technical task",
4+
"keywords": ["php", "parser"],
5+
"license": "MIT",
6+
"version": "1.0",
7+
"type": "project",
8+
"homepage": "https://github.com/lutdev/techtask",
9+
"readme": "README.MD",
10+
"authors": [
11+
{
12+
"name": "Andrew Lutskevich",
13+
"email": "[email protected]",
14+
"role": "Developer"
15+
}
16+
],
17+
"require": {
18+
"php": "^7.1",
19+
"vlucas/phpdotenv": "^2.5"
20+
},
21+
"require-dev": {
22+
"phpunit/phpunit": "^7.0"
23+
},
24+
"autoload": {
25+
"classmap": [
26+
"simple_html_dom.php"
27+
],
28+
"psr-4": {
29+
"App\\": "app/"
30+
}
31+
},
32+
"autoload-dev": {
33+
"psr-4": {
34+
"Tests\\": "tests/"
35+
}
36+
},
37+
"config": {
38+
"preferred-install": "dist",
39+
"sort-packages": true,
40+
"optimize-autoloader": true
41+
},
42+
"minimum-stability": "dev",
43+
"prefer-stable": true
44+
}

0 commit comments

Comments
 (0)