Automation init...1

This commit is contained in:
최준흠 2024-09-05 17:22:34 +09:00
parent 1b55308fd3
commit 752ae5f33a
29 changed files with 675 additions and 359 deletions

View File

@ -130,21 +130,3 @@ define('AUTH', [
],
]
]);
define('MANGBOARD', [
'point' => ['unit' => 1000],
'admin' => ['level' => 10],
'manager' => [
'level' => [
'min' => 6,
'max' => 9,
]
],
'user' => [
'level' => [
'min' => 1,
'max' => 5,
]
],
]);

View File

@ -15,26 +15,31 @@ $routes->addPlaceholder('uuid', '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}
//2. Config/Filters.php -> $aliases = ['authFilter' => AuthFilter::class]
$routes->get('/', 'Home::index');
$routes->group('/user', function ($routes) {
$routes->get('', 'UserController::index');
$routes->get('view', 'UserController::view', ['filter' => 'authFilter:user']);
});
$routes->group('cli', ['namespace' => 'App\Controllers\CLI'], function ($routes) {
$routes->cli('mangboard/level', 'Mangboard::level');
$routes->cli('crawler/yamap', 'Crawler::yamap');
$routes->cli('crawler/yamap/(:any)', 'Crawler::yamap/$1');
$routes->cli('yamap/crawler', 'Yamap::crawler');
$routes->cli('yamap/crawler(:any)', 'Yamap::crawler/$1');
});
$routes->group('admin', ['namespace' => 'App\Controllers\Admin', 'filter' => 'authFilter:manager'], function ($routes) {
$routes->get('/', 'Home::index');
});
$routes->group('mangboard', ['namespace' => 'App\Controllers\Mangboard'], function ($routes) {
$routes->group('/user', function ($routes) {
$routes->get('insert', 'UserController::form_insert');
$routes->post('insert', 'UserController::insert');
$routes->get('update', 'UserController::form_update');
$routes->post('update', 'UserController::upadate');
$routes->get('view', 'UserController::view');
$routes->get('delete/', 'UserController::delete', ['filter' => 'authFilter:master']);
$routes->post('point', 'UserController::form_point');
$routes->post('point', 'UserController::point', ['filter' => 'authFilter:master']);
$routes->get('/', 'UserController::index');
});
$routes->group('admin', ['namespace' => 'App\Controllers\Mangboard\Admin', 'filter' => 'authFilter:manager'], function ($routes) {
$routes->group('/user', function ($routes) {
$routes->get('/', 'UserController::index');
// $routes->get('insert', 'UserController::form_insert');
// $routes->post('insert', 'UserController::insert');
// $routes->get('update', 'UserController::form_update');
// $routes->post('update', 'UserController::upadate');
// $routes->get('view', 'UserController::view');
// $routes->get('delete/', 'UserController::delete', ['filter' => 'authFilter:master']);
$routes->get('point', 'UserController::form_point', ['filter' => 'authFilter:master']);
$routes->post('point', 'UserController::point', ['filter' => 'authFilter:master']);
});
});
});

View File

@ -2,7 +2,9 @@
namespace App\Controllers\Admin;
abstract class AdminController
use App\Controllers\BaseController;
abstract class AdminController extends BaseController
{
private $_datas = [];

View File

@ -0,0 +1,11 @@
<?php
namespace App\Controllers\Admin;
class Home extends AdminController
{
public function index(): string
{
return view('welcome_message');
}
}

View File

@ -1,45 +0,0 @@
<?php
namespace App\Controllers\Admin;
use App\Models\UserModel;
use App\Traits\MangboardTrait;
class UserController extends AdminController
{
use MangboardTrait;
private $_model = null;
public function __construct()
{
$this->_model = new UserModel();
}
public function index(): string
{
return __METHOD__;
}
public function point(): string
{
try {
$id = $this->request->getPost('id');
$entity = is_numeric($id) ? $this->_model->getEntityByPK(intval($id)) : $this->_model->getEntityByID($id);
if (!$entity) {
throw new \Exception("해당 회원[{$id}]이 없습니다.");
}
$point = $this->request->getPost('point');
if (!is_numeric($point)) {
throw new \Exception("포인트 값에 {$point}를 사용할 수 없습니다.");
}
$sign = $this->request->getPost('point') ?: "+";
$entity = $this->setUserPointByMangboard($entity, intval($point), $sign);
return "완료되었습니다.";
} catch (\Exception $e) {
log_message("error", $e->getMessage());
return $e->getMessage();
}
}
}

View File

@ -1,28 +0,0 @@
<?php
namespace App\Controllers\CLI;
use App\Controllers\BaseController;
use App\Libraries\YamapLibrary;
class Crawler extends BaseController
{
public function yamap(...$params): bool
{
try {
$isDebug = in_array("debug", $params);
//1. Yamap 사이트에서에서 자유게시판의 게시물 중 작성자가 관리자가 아닌 게시물 검색후
// 리스트중 1번째것의 게시물 내용에 있는 이미지,비디오 정보를 가져오게 하는 기능
$library = new YamapLibrary(getenv("yamap.host"));
$library->setDebug($isDebug);
$library->execute();
//2. 워드프레스에 로그인 처리 기능
//3. 워드프레스의 자유게시판에 게시물 등록 기능
log_message("notice", "완료되었습니다.");
return true;
} catch (\Exception $e) {
log_message("error", $e->getMessage());
return false;
}
}
}

View File

@ -4,22 +4,18 @@ namespace App\Controllers\CLI;
use App\Controllers\BaseController;
use App\Traits\MangboardTrait;
use App\Models\UserModel;
use App\Libraries\Mangboard\UserLibrary;
class Mangboard extends BaseController
{
use MangboardTrait;
public function level(): bool
public function level(...$params): bool
{
try {
$userModel = new UserModel();
foreach ($userModel->getEntitys() as $entity) {
$entity = $this->setUserLevelByMangboard($entity);
log_message("debug", __FUNCTION__ . "=>[{$entity}] 회원님의 Level은 {$entity->getLevel()} 입니다.");
}
log_message("info", "완료되었습니다.");
$isDebug = in_array("debug", $params);
$user = new UserLibrary();
$user->setDebug($isDebug);
$user->setLevel();
log_message("notice", "완료되었습니다.");
return true;
} catch (\Exception $e) {
log_message("error", $e->getMessage());

View File

@ -0,0 +1,54 @@
<?php
namespace App\Controllers\CLI;
use App\Controllers\BaseController;
use App\Libraries\MyWebLibrary;
use App\Libraries\MyStorage\MyStorageFileLibrary;
use App\Libraries\MyCrawlerLibrary;
use App\Libraries\YamapLibrary;
use App\Libraries\Mangboard\UserLibrary;
class Yamap extends BaseController
{
public function crawler(...$params): bool
{
try {
$isDebug = in_array("debug", $params);
$nickname = getenv("yamap.view.default.nickname");
$datas = [];
//Yamap사이트에서 자유게시판에서 최근 게시물 데이터 가져오기
if (!in_array("skip_build", $params)) {
$yamap = new YamapLibrary();
$yamap->setDebug($isDebug);
$yamap->setMyWeb(new MyWebLibrary(getenv('yamap.host.url')));
$yamap->setMyStorage(new MyStorageFileLibrary(WRITEPATH . "uploads" . DIRECTORY_SEPARATOR . "Yamap"));
$yamap->setMyCrawler(new MyCrawlerLibrary());
list($nickname, $datas) = $yamap->build();
}
//2. 사이트 로그인 처리
if (!in_array("skip_login", $params)) {
$myWeb = new MyWebLibrary(getenv('daemonidc.host.url'));
$myWeb->setDebug($isDebug);
$myWeb->login(
getenv('daemonidc.login.url'),
getenv('daemonidc.login.user_id'),
getenv('daemonidc.login.user_password')
);
}
//3. 망보드 일반게시판에 게시물 등록 처리
if (!in_array("skip_create", $params)) {
$mangboard = new UserLibrary();
$mangboard->setDebug($isDebug);
// $mangboard->create();
}
log_message("notice", "완료되었습니다.");
return true;
} catch (\Exception $e) {
log_message("error", $e->getMessage());
return false;
}
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace App\Controllers\Mangboard\Admin;
use App\Controllers\Admin\AdminController;
use App\Libraries\Mangboard\UserLibrary;
class UserController extends AdminController
{
public function __construct()
{
parent::__construct();
}
public function index(): string
{
return __METHOD__;
}
public function point(): string
{
try {
$id = $this->request->getVar("id");
$point = intval($this->request->getVar("point"));
$sign = $this->request->getVar("point") ?? "+";
$user = new UserLibrary();
$user->setPoint($id, $point, $sign);
return "완료되었습니다.";
} catch (\Exception $e) {
log_message("error", $e->getMessage());
return $e->getMessage();
}
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace App\Controllers\Mangboard;
use App\Controllers\BaseController;
class UserController extends BaseController
{
public function index()
{
return __METHOD__;
}
}

View File

@ -1,11 +0,0 @@
<?php
namespace App\Controllers;
class UserController extends BaseController
{
public function index() {}
}

View File

@ -0,0 +1,21 @@
<?php
namespace App\Entities\Mangboard;
use App\Entities\CommonEntity;
class FreeboardEntity extends CommonEntity
{
public function __toString(): string
{
return "{$this->getPK()}:{$this->getName()}";
}
public function getPK(): int
{
return $this->attributes['pid'];
}
public function getName(): string
{
return $this->attributes['user_name'];
}
}

View File

@ -1,8 +1,8 @@
<?php
namespace App\Entities;
namespace App\Entities\Mangboard;
use CodeIgniter\Entity\Entity;
use App\Entities\CommonEntity;
class UserEntity extends CommonEntity
{

View File

@ -0,0 +1,18 @@
<?php
namespace App\Libraries;
abstract class CommonLibrary
{
private $_debug = false;
protected function __construct() {}
final public function getDebug(): bool
{
return $this->_debug;
}
final public function setDebug(bool $debug): void
{
$this->_debug = $debug;
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace App\Libraries\Mangboard;
use App\Entities\Mangboard\UserEntity;
use App\Models\Mangboard\UserModel;
class FreeboardLibrary extends MangboardLibrary
{
private $_model = null;
public function __construct()
{
parent::__construct();
}
private function getModel(): UserModel
{
if ($this->_model === null) {
$this->_model = new UserModel();
}
return $this->_model;
}
public function create($id, int $point, $sign = '+'): UserEntity
{
$entity = is_numeric($id) ? $this->getModel()->getEntityByPK(intval($id)) : $this->getModel()->getEntityByID($id);
if (!$entity) {
throw new \Exception("해당 회원[{$id}]이 없습니다.");
}
$entity = $this->getModel()->setPoint($entity, $point);
log_message("debug", __FUNCTION__ . "=>[{$entity}] 회원님의 Level은 {$entity->getLevel()} 입니다.");
return $entity;
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace App\Libraries\Mangboard;
use App\Entities\Mangboard\UserEntity;
use App\Libraries\CommonLibrary;
use App\Models\Mangboard\UserModel;
abstract class MangboardLibrary extends CommonLibrary
{
protected function __construct()
{
parent::__construct();
}
}

View File

@ -0,0 +1,129 @@
<?php
namespace App\Libraries\Mangboard;
use App\Entities\Mangboard\UserEntity;
use App\Models\Mangboard\UserModel;
//MANGBOARD_USER_USER 정의
// define('MANGBOARD_USER', [
// 'point' => ['unit' => 1000],
// 'admin' => ['level' => 10],
// 'manager' => [
// 'level' => [
// 'min' => 6,
// 'max' => 9,
// ]
// ],
// 'user' => [
// 'level' => [
// 'min' => 1,
// 'max' => 5,
// ]
// ],
// ]);
class UserLibrary extends MangboardLibrary
{
private $_model = null;
public function __construct()
{
parent::__construct();
}
private function getModel(): UserModel
{
if ($this->_model === null) {
$this->_model = new UserModel();
}
return $this->_model;
}
private function checkLevel(UserEntity $entity): UserEntity
{
//Admin용 Level로는 변경불가
if ($entity->getLevel() == getenv('mangboard.admin.level')) {
// throw new \Exception("Admin용 Level을 변경하실수 없습니다.\n");
return $entity;
}
//사용자 Point별 Level 계산
$level = intval($entity->getPoint() / getenv('mangboard.point.unit') * getenv('mangboard.point.unit') / getenv('mangboard.point.unit'));
//운영자면 7~9
if (getenv('mangboard.manager.level.min') <= $level && $level <= getenv('mangboard.manager.level.max')) {
$level = $level < getenv('mangboard.manager.level.min') ? getenv('mangboard.manager.level.min') : $level;
$level = getenv('mangboard.manager.level.max') < $level ? getenv('mangboard.manager.level.max') : $level;
}
// echo "point:" . $entity->getPoint() . ",level:" . $level . "\n";
//사용자 Level 1~5;
if (getenv('mangboard.user.level.min') <= $level && $level <= getenv('mangboard.user.level.max')) {
$level = $level < getenv('mangboard.user.level.min') ? getenv('mangboard.user.level.min') : $level;
$level = getenv('mangboard.user.level.max') < $level ? getenv('mangboard.user.level.max') : $level;
}
// echo "point:" . $entity->getPoint() . ",level:" . $level . "\n";
return $this->getModel()->setLevel($entity, $level);
}
public function setPoint($id, int $point, $sign = '+'): UserEntity
{
$entity = is_numeric($id) ? $this->getModel()->getEntityByPK(intval($id)) : $this->getModel()->getEntityByID($id);
if (!$entity) {
throw new \Exception("해당 회원[{$id}]이 없습니다.");
}
switch ($sign) {
case '-':
if ($point < $point) {
throw new \Exception("기존포인트:{$point}가 감소 포인트:-{$point} 작습니다.\n");
}
$point = $point - $point;
break;
case '+':
$point = $point + $point;
break;
default:
throw new \Exception(__FUNCTION__ . "에서는 {$sign}은 사용할수 없습니다.\n");
// break;
}
$entity = $this->getModel()->setPoint($entity, $point);
return $this->checkLevel($entity);
}
// private function checkLevel(UserEntity $entity): UserEntity
// {
// //Admin용 Level로는 변경불가
// if ($entity->getLevel() == MANGBOARD_USER['admin']['level']) {
// // throw new \Exception("Admin용 Level을 변경하실수 없습니다.\n");
// return $entity;
// }
// //사용자 Point별 Level 계산
// $level = intval($entity->getPoint() / MANGBOARD_USER['point']['unit'] * MANGBOARD_USER['point']['unit'] / MANGBOARD_USER['point']['unit']);
// //운영자면 7~9
// if (MANGBOARD_USER['manager']['level']['min'] <= $level && $level <= MANGBOARD_USER['manager']['level']['max']) {
// $level = $level < MANGBOARD_USER['manager']['level']['min'] ? MANGBOARD_USER['manager']['level']['min'] : $level;
// $level = MANGBOARD_USER['manager']['level']['max'] < $level ? MANGBOARD_USER['manager']['level']['max'] : $level;
// }
// // echo "point:" . $entity->getPoint() . ",level:" . $level . "\n";
// //사용자 Level 1~5;
// if (MANGBOARD_USER['user']['level']['min'] <= $level && $level <= MANGBOARD_USER['user']['level']['max']) {
// $level = $level < MANGBOARD_USER['user']['level']['min'] ? MANGBOARD_USER['user']['level']['min'] : $level;
// $level = MANGBOARD_USER['user']['level']['max'] < $level ? MANGBOARD_USER['user']['level']['max'] : $level;
// }
// // echo "point:" . $entity->getPoint() . ",level:" . $level . "\n";
// return $this->getModel()->setLevel($entity, $level);
// }
public function setLevel()
{
foreach ($this->getModel()->getEntitys() as $entity) {
$entity = $this->checkLevel($entity);
log_message("debug", __FUNCTION__ . "=>[{$entity}] 회원님의 Level은 {$entity->getLevel()} 입니다.");
}
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace App\Libraries;
use Symfony\Component\DomCrawler\Crawler;
class MyCrawlerLibrary extends CommonLibrary
{
public function __construct()
{
parent::__construct();
}
final public function create($html): Crawler
{
return new Crawler($html);
}
public function getNodes(Crawler $crawler, array $options, $nodes = []): array
{
$crawler->filter($options["tag"])->each(
function (Crawler $node) use (&$options, &$nodes): void {
log_message("debug", sprintf("getNode-> %s", $options["tag"]));
$nodes[] = $node;
}
);
return $nodes;
}
}

View File

@ -0,0 +1,53 @@
<?php
namespace App\Libraries\MyStorage;
use App\Libraries\MyStorage\MyStorageLibrary;
class MyStorageFileLibrary extends MyStorageLibrary
{
private $_defaultPath = "";
private $_path = "";
private $_fileName = "";
private $_savePath = "";
public function __construct($defaultPath)
{
parent::__construct();
$this->_defaultPath = $defaultPath;
}
final public function getDefaultPath(): string
{
return $this->_defaultPath;
}
final public function getPath(): string
{
return $this->_path;
}
final public function setPath(string $path): void
{
$this->_path = $path;
}
final public function getFileName(): string
{
return $this->_fileName;
}
final public function setFileName(string $fileName): void
{
$this->_fileName = $fileName;
}
final public function save($content): bool
{
$fullPath = $this->getDefaultPath() . DIRECTORY_SEPARATOR . $this->getPath();
if (!is_dir($fullPath)) {
if (!mkdir($fullPath)) {
throw new \Exception("Make Directory Error:" . $fullPath);
}
}
$fileName = $fullPath . DIRECTORY_SEPARATOR . $this->getFileName();
log_message("debug", "download:SavePath-> " . $fileName);
return file_put_contents($fileName, $content);
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace App\Libraries\MyStorage;
use App\Libraries\CommonLibrary;
abstract class MyStorageLibrary extends CommonLibrary
{
protected function __construct()
{
parent::__construct();
}
abstract public function save($content): bool;
}

View File

@ -1,26 +1,27 @@
<?php
namespace App\Traits;
namespace App\Libraries;
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Client;
trait MyWebTrait
class MyWebLibrary extends CommonLibrary
{
private $_client = null;
private $_cookieJar = null;
private $_host = null;
final protected function getHostByMyWeb(): string
{
return $this->_host;
}
final protected function setHostByMyWeb(string $host): void
public function __construct(string $host)
{
parent::__construct();
$this->_host = $host;
}
final protected function getClientByMyWeb(): Client
final protected function getHost(): string
{
return $this->_host;
}
final protected function getClient(): Client
{
if ($this->_client === null) {
$this->_client = new Client(['verify' => false]);
@ -28,7 +29,7 @@ trait MyWebTrait
return $this->_client;
}
final protected function getCookieJarByMyWeb()
final protected function getCookieJar()
{
if ($this->_cookieJar === null) {
$this->_cookieJar = new CookieJar();
@ -37,17 +38,17 @@ trait MyWebTrait
}
//url에 http 나 https가 포함되어 있으면 true
final protected function isContainsHttpOrHttpsByMyWeb($url): bool
private function isContainsHttpOrHttps($url): bool
{
return strpos($url, 'http://') !== false || strpos($url, 'https://') !== false;
}
final protected function getContentByMyWeb(string $url, array $options = []): string
public function getContent(string $url, array $options = []): string
{
//url에 http 나 https가 포함되어 있지않으면
if (!($this->isContainsHttpOrHttpsByMyWeb($url))) {
$url = $this->gethostByMyWeb() . $url;
if (!($this->isContainsHttpOrHttps($url))) {
$url = $this->gethost() . $url;
}
$response = $this->getClientByMyWeb()->get($url, $options);
$response = $this->getClient()->get($url, $options);
if ($response->getStatusCode() != 200) {
throw new \Exception("error", "{$url} 접속실패: " . $response->getStatusCode());
}
@ -55,46 +56,46 @@ trait MyWebTrait
}
// 로그인 메서드
final protected function loginByMyWeb($url, $username, $password): void
public function login($url, $username, $password): bool
{
$response = $this->getClientByMyWeb()->post($this->gethost() . $url, [
$response = $this->getClient()->post($this->gethost() . $url, [
'form_params' => [
'username' => $username,
'password' => $password,
],
'cookies' => $this->getCookieJar(),
]);
if ($response->getStatusCode() != 200) {
throw new \Exception("로그인 실패: " . $response->getStatusCode());
if ($response->getStatusCode() == 200) {
log_message("notice", "로그인 성공");
if ($this->getDebug()) {
echo var_dump($response);
}
return true;
} {
log_message("error", "로그인 실패: " . $response->getStatusCode());
return false;
}
}
// 파일 다운로드 메서드
final protected function downloadByMyWeb(string $url, string $fullPath, bool $debug = false)
public function download(string $url): array
{
log_message("debug", "donwload:URL-> " . $url);
$fileNames = explode('/', $url);
if (!is_array($fileNames) || !count($fileNames)) {
throw new \Exception("Download URL Error:" . $url);
}
if (!is_dir($fullPath)) {
if (!mkdir($fullPath)) {
throw new \Exception("Make Directory Error:" . $fullPath);
}
}
$fileName = array_pop($fileNames);
$savePath = $fullPath . DIRECTORY_SEPARATOR . $fileName;
log_message("debug", "download:SavePath-> " . $savePath);
if (!$debug) {
$response = $this->getContentByMyWeb($url, [
'cookies' => $this->getCookieJarByMyWeb(),
if (!$this->getDebug()) {
$content = $this->getContent($url, [
'cookies' => $this->getCookieJar(),
// 'sink' => $savePath,
]);
if (!$response) {
if (!$content) {
throw new \Exception("{$fileName} 파일 다운로드 실패");
}
$this->saveByMyStorage($savePath, $response);
log_message("notice", "{$fileName} 파일이 다운로드되었습니다!");
}
return array($fileName, $content);
}
}

View File

@ -2,98 +2,165 @@
namespace App\Libraries;
use App\Traits\MyCrawlerTrait;
use App\Traits\MyWebTrait;
use App\Traits\MyStorage\MyStorageFileTrait;
use Symfony\Component\DomCrawler\Crawler;
class YamapLibrary
//Yamap
// define('YAMAP', [
// 'host' => ['url' => getenv('yamap.host.url')],
// 'list' => [
// 'url' => getenv('yamap.list.url'),
// 'tag' => getenv('yamap.list.tag'),
// 'item' => [
// 'tag' => getenv('yamap.list.item.tag'),
// 'subject' => [
// 'tag' => getenv('yamap.list.item.subject.tag')
// ],
// 'nickname' => [
// 'tag' => getenv('yamap.list.item.nickname.tag'),
// 'except' => getenv('yamap.list.item.nickname.except'),
// ],
// ],
// ],
// 'view' => [
// 'tag' => getenv('yamap.view.tag'),
// 'content' => [
// 'tag' => getenv('yamap.view.content.tag'),
// ],
// 'test' => [
// 'url' => getenv('yamap.view.test.url'),
// ]
// ],
// ]);
class YamapLibrary extends CommonLibrary
{
use MyWebTrait, MyStorageFileTrait, MyCrawlerTrait;
private $_debug = false;
public function __construct(string $host)
private $_myWeb = null;
private $_myStorage = null;
private $_myCrawler = null;
public function __construct()
{
$this->setHostByMyWeb($host);
$this->setPathByMyStorage(WRITEPATH . "uploads" . DIRECTORY_SEPARATOR . "Yamap");
parent::__construct();
}
final public function getDebug(): bool
public function getMyWeb()
{
return $this->_debug;
if ($this->_myWeb === null) {
throw new \Exception("MyWeb Library가 정의되지 않았습니다.");
}
return $this->_myWeb;
}
final public function setDebug(bool $debug): void
public function setMyWeb($myWeb)
{
$this->_debug = $debug;
$this->_myWeb = $myWeb;
}
protected function getCrawler(string $url, string $tag): Crawler
public function getMyStorage()
{
$response = $this->getContentByMyWeb($url);
if ($this->_myStorage === null) {
throw new \Exception("MyStorage Library가 정의되지 않았습니다.");
}
return $this->_myStorage;
}
public function setMyStorage($myStorage)
{
$this->_myStorage = $myStorage;
}
public function getMyCrawler()
{
if ($this->_myWeb === null) {
throw new \Exception("MyCrawler Library가 정의되지 않았습니다.");
}
return $this->_myCrawler;
}
public function setMyCrawler($myCrawler)
{
$this->_myCrawler = $myCrawler;
}
private function getCrawler(string $url, string $tag): Crawler
{
$response = $this->getMyWeb()->getContent($url);
if (!$response) {
throw new \Exception("getCrawler 실패:{$url}");
}
return $this->createByMyCrawler($response)->filter($tag);
return $this->getMyCrawler()->create($response)->filter($tag);
}
protected function getList(
Crawler $crawler,
string $item_tag,
string $item_subject_tag,
string $item_nickname_tag,
string $item_nickname_skip,
array $results = []
): array {
private function download_process(Crawler $crawler, array $options): array
{
$datas = [];
log_message("debug", "download:{$options["tag"]},{$options["attr"]}");
$nodes = $this->getMyCrawler()->getNodes($crawler, $options);
foreach ($nodes as $node) {
list($fileName, $content) = $this->getMyWeb()->download($node->attr($options["attr"]));
$this->getMyStorage()->setFileName($fileName);
if (!$this->getMyStorage()->save($content)) {
continue;
}
$datas[] = [
"path" => $this->getMyStorage()->getDefaultPath() . DIRECTORY_SEPARATOR . $this->getMyStorage()->getPath(),
"fileName" => $fileName,
"content" => $content
];
}
return $datas;
}
public function mainPage(): array
{
$url = getenv("yamap.list.url");
$crawler = $this->getCrawler($url, getenv("yamap.list.tag"));
$item_tag = getenv("yamap.list.item.tag");
$item_subject_tag = getenv("yamap.list.item.subject.tag");
$item_nickname_tag = getenv("yamap.list.item.nickname.tag");
$item_nickname_except = getenv("yamap.list.item.nickname.except");
$lists = [];
//div.bbs_item를 가진 객체를 찾아서 같은 형식의 객체(sibling)를 배열로 넘김
$crawler->filter($item_tag)->each(
function (Crawler $node) use (
$item_subject_tag,
&$item_nickname_tag,
&$item_nickname_skip,
&$results
&$item_nickname_except,
&$lists
): void {
//bbs_item에서 span.g_nickname 객체를 찾아서 작성자가 "관리자" 아닌지 확인 후 Return Bool
$nickname = $node->filter($item_nickname_tag)->text();
log_message("debug", $item_nickname_tag . ":" . $nickname);
if ($nickname != $item_nickname_skip) {
if ($nickname != $item_nickname_except) {
//작성자가 "관리자"가 아니 게시물이면 해당 bbs_item에서 a.list_subject 객체를 찾아서
$url = $node->filter($item_subject_tag)->attr("href");
$results[] = ['nickname' => $nickname, 'url' => $url];
$lists[] = ['nickname' => $nickname, 'url' => $url];
}
}
);
return $results;
}
protected function download(Crawler $crawler, array $options): void
{
log_message("debug", "download:{$options["tag"]},{$options["attr"]}");
$nodes = $this->getNodesByMyCrawler($crawler, $options);
foreach ($nodes as $node) {
$this->downloadByMyWeb($node->attr($options["attr"]), $this->getPathByMyStorage(), $this->getDebug());
}
}
public function execute(): void
{
//1. MainPage
$url = getenv("yamap.list.url");
$crawler = $this->getCrawler($url, getenv("yamap.list.tag"));
$lists = $this->getList(
$crawler,
getenv("yamap.list.item.tag"),
getenv("yamap.list.item.subject.tag"),
getenv("yamap.list.item.nickname.tag"),
getenv("yamap.list.item.nickname.skip")
);
if (!count($lists)) {
throw new \Exception("Target URL이 없습니다.");
}
//2. TargetPage : div.contents 가진 객체를 찾아서 첫번쨰 요소에서만 참조
$url = $this->getDebug() ? getenv("yamap.view.test.url") : $lists[0]["url"];
return array($lists[0]["nickname"], $lists[0]["url"]);
}
public function detailPage($url): array
{
$crawler = $this->getCrawler($url, getenv("yamap.view.content.tag"));
//3. Image
$this->download($crawler, ["tag" => "img", "attr" => "src"]);
$images = $this->download_process($crawler, ["tag" => "img", "attr" => "src"]);
//4. Video
$this->download($crawler, ["tag" => "video", "attr" => "src"]);
$videos = $this->download_process($crawler, ["tag" => "video", "attr" => "src"]);
return array_merge($images, $videos);
}
public function build(): array
{
//1. 해당사이트 MainPage 처리
if ($this->getDebug()) {
$nickname = getenv("yamap.view.test.nickname");
$detail_url = getenv("yamap.view.test.url");
} else {
list($nickname, $detail_url) = $this->mainPage();
}
//2. DetailPage 처리 : bbs_view > div.contents 가진 객체를 찾아서 처리
$detailDatas = $this->detailPage($detail_url);
return array($nickname, $detailDatas);
}
}

View File

@ -4,7 +4,7 @@ namespace App\Models;
use CodeIgniter\Model;
class CommonModel extends Model
abstract class CommonModel extends Model
{
protected $table = '';
protected $primaryKey = '';
@ -45,6 +45,8 @@ class CommonModel extends Model
protected $beforeDelete = [];
protected $afterDelete = [];
abstract public function getPK(): string;
final public function getEntity()
{
return $this->asObject($this->returnType)->first();

View File

@ -0,0 +1,50 @@
<?php
namespace App\Models\Mangboard;
use App\Entities\Mangboard\FreeboardEntity;
use App\Models\CommonModel;
class FreeboardModel extends CommonModel
{
protected $table = 'mb_board_free;';
protected $primaryKey = 'pid';
protected $useAutoIncrement = true;
protected $returnType = FreeboardEntity::class;
protected $allowedFields = ['pid', 'user_id', 'passwd', 'user_name', 'user_email', 'user_state', 'user_level', 'user_point'];
// Validation
// protected $validationRules = [];
protected $validationRules = [
'pid' => 'if_exist|numeric',
'user_id' => 'if_exist|trim|string',
'passwd' => 'if_exist|trim|string',
// 'confirmpassword' => 'if_exist|trim|matches[passwd]',
'user_name' => 'if_exist|trim|string',
'user_state' => 'if_exist|trim|string',
'user_email' => 'if_exist|trim|valid_email',
'user_level' => 'if_exist|numeric',
'user_point' => 'if_exist|numeric',
// 'proxied' => 'if_exist|in_list[on,off]',
// 'fixed' => 'if_exist|in_list[on,off]',
// 'locked' => 'if_exist|in_list[on,off]',
// 'updated_at' => 'if_exist|valid_date',
// 'created_at' => 'if_exist|valid_date',
];
public function getPK(): string
{
return $this->primaryKey;
}
public function getEntityByPK(int $uid): null|FreeboardEntity
{
$this->where($this->getPK(), $uid);
return $this->getEntity();
}
public function getEntityByID(string $id): null|FreeboardEntity
{
$this->where('user_id', $id);
return $this->getEntity();
}
}

View File

@ -1,8 +1,9 @@
<?php
namespace App\Models;
namespace App\Models\Mangboard;
use App\Entities\UserEntity;
use App\Entities\Mangboard\UserEntity;
use App\Models\CommonModel;
class UserModel extends CommonModel
{
@ -30,10 +31,14 @@ class UserModel extends CommonModel
// 'updated_at' => 'if_exist|valid_date',
// 'created_at' => 'if_exist|valid_date',
];
public function getPK(): string
{
return $this->primaryKey;
}
public function getEntityByPK(int $uid): null|UserEntity
{
$this->where($this->primaryKey, $uid);
$this->where($this->getPK(), $uid);
return $this->getEntity();
}
public function getEntityByID(string $id): null|UserEntity

View File

@ -1,66 +0,0 @@
<?php
namespace App\Traits;
use App\Entities\UserEntity;
use App\Models\UserModel;
trait MangboardTrait
{
private $_userModel = null;
protected function getUserModel(): UserModel
{
if (is_null($this->_userModel)) {
$this->_userModel = new UserModel();
}
return $this->_userModel;
}
protected function setUserPointByMangboard(UserEntity $entity, int $point, $sign = '+'): UserEntity
{
switch ($sign) {
case '-':
if ($point < $point) {
throw new \Exception("기존포인트:{$point}가 감소 포인트:-{$point} 작습니다.\n");
}
$point = $point - $point;
break;
case '+':
$point = $point + $point;
break;
default:
throw new \Exception(__FUNCTION__ . "에서는 {$sign}은 사용할수 없습니다.\n");
// break;
}
$entity = $this->getUserModel()->setPoint($entity, $point);
return $this->setUserLevelByMangboardTrait($entity);
}
protected function setUserLevelByMangboard(UserEntity $entity): UserEntity
{
//Admin용 Level로는 변경불가
if ($entity->getLevel() == MANGBOARD['admin']['level']) {
// throw new \Exception("Admin용 Level을 변경하실수 없습니다.\n");
return $entity;
}
//사용자 Point별 Level 계산
$level = intval($entity->getPoint() / MANGBOARD['point']['unit'] * MANGBOARD['point']['unit'] / MANGBOARD['point']['unit']);
//운영자면 7~9
if (MANGBOARD['manager']['level']['min'] <= $level && $level <= MANGBOARD['manager']['level']['max']) {
$level = $level < MANGBOARD['manager']['level']['min'] ? MANGBOARD['manager']['level']['min'] : $level;
$level = MANGBOARD['manager']['level']['max'] < $level ? MANGBOARD['manager']['level']['max'] : $level;
}
// echo "point:" . $entity->getPoint() . ",level:" . $level . "\n";
//사용자 Level 1~5;
if (MANGBOARD['user']['level']['min'] <= $level && $level <= MANGBOARD['user']['level']['max']) {
$level = $level < MANGBOARD['user']['level']['min'] ? MANGBOARD['user']['level']['min'] : $level;
$level = MANGBOARD['user']['level']['max'] < $level ? MANGBOARD['user']['level']['max'] : $level;
}
// echo "point:" . $entity->getPoint() . ",level:" . $level . "\n";
return $this->getUserModel()->setLevel($entity, $level);
}
}

View File

@ -1,41 +0,0 @@
<?php
namespace App\Traits;
use Symfony\Component\DomCrawler\Crawler;
trait MyCrawlerTrait
{
final protected function createByMyCrawler($html): Crawler
{
return new Crawler($html);
}
public function getNodesByMyCrawler(Crawler $crawler, array $options, $nodes = []): array
{
$crawler->filter($options["tag"])->each(
function (Crawler $node) use (&$options, &$nodes): void {
foreach (array_keys($options) as $key) {
switch ($key) {
case 'find':
if ($node->text() == $options[$key]) {
log_message("debug", sprintf("getNodeByMyCrawler-> %s:%s", $options["tag"], $options[$key]));
$nodes[] = $node;
}
break;
case 'except':
if ($node->text() != $options[$key]) {
log_message("debug", sprintf("getNodeByMyCrawler-> %s:%s", $options["tag"], $options[$key]));
$nodes[] = $node;
}
break;
default:
log_message("debug", sprintf("getNodeByMyCrawler-> %s", $options["tag"]));
$nodes[] = $node;
break;
}
}
}
);
return $nodes;
}
}

View File

@ -1,13 +0,0 @@
<?php
namespace App\Traits\MyStorage;
trait MyStorageFileTrait
{
use MyStorageTrait;
final protected function saveByMyStorage(string $savePath, $content): bool
{
return file_put_contents($savePath, $content);
}
}

View File

@ -1,17 +0,0 @@
<?php
namespace App\Traits\MyStorage;
trait MyStorageTrait
{
private $_path = "";
final protected function getPathByMyStorage(): string
{
return $this->_path;
}
final protected function setPathByMyStorage(string $path): void
{
$this->_path = $path;
}
}