Created
June 22, 2021 10:24
-
-
Save atsu666/a1857aee3108e1a73eedd58e4c33afeb to your computer and use it in GitHub Desktop.
php/Services/Blog/Import.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Acms\Services\Blog; | |
use SQL; | |
use DB; | |
use Acms\Services\Facades\Common; | |
use Symfony\Component\Yaml\Yaml; | |
class Import | |
{ | |
/** | |
* @var array | |
*/ | |
protected $yaml; | |
/** | |
* @var int | |
*/ | |
protected $bid; | |
/** | |
* @var int | |
*/ | |
protected $uid; | |
/** | |
* @var array | |
*/ | |
protected $ids; | |
/** | |
* @var array | |
*/ | |
protected $errors; | |
/** | |
* @var array | |
*/ | |
protected $mediaFieldFix = array(); | |
/** | |
* Import constructor | |
*/ | |
public function __construct() | |
{ | |
$this->uid = SUID; | |
} | |
/** | |
* import blog data | |
* | |
* @param int $bid | |
* @param string $yaml | |
* | |
* @return array | |
*/ | |
public function run($bid, $yaml) | |
{ | |
$this->bid = $bid; | |
$this->yaml = Yaml::parse($yaml); | |
$this->ids = array(); | |
$this->errors = array(); | |
$this->dropData(); | |
$this->registerNewIDs(); | |
$tables = array( | |
'category', 'entry', 'tag', | |
'module', 'layout_grid', | |
'rule', 'config', 'column', 'config_set', | |
'dashboard', 'field', 'media', 'media_tag', | |
); | |
foreach ( $tables as $table ) { | |
$this->insertData($table); | |
} | |
$this->generateFulltext(); | |
return $this->errors; | |
} | |
private function generateFulltext() | |
{ | |
$DB = DB::singleton(dsn()); | |
foreach (array('category', 'entry') as $type) { | |
$SQL = SQL::newSelect($type); | |
$SQL->addSelect($type.'_id'); | |
$SQL->addWhereOpr($type.'_blog_id', $this->bid); | |
$all = $DB->query($SQL->get(dsn()), 'all'); | |
foreach ( $all as $row ) { | |
$id = $row[$type.'_id']; | |
switch ( $type ) { | |
case 'category': | |
Common::saveFulltext('cid', $id, Common::loadCategoryFulltext($id)); | |
break; | |
case 'entry': | |
Common::saveFulltext('eid', $id, Common::loadEntryFulltext($id)); | |
break; | |
} | |
} | |
} | |
} | |
/** | |
* @param string $table | |
* | |
* @return void | |
*/ | |
private function insertData($table) | |
{ | |
if ( !$this->existsYaml($table) ) { | |
return; | |
} | |
foreach ( $this->yaml[$table] as $record ) { | |
$SQL = SQL::newInsert($table); | |
foreach ( $record as $field => $value ) { | |
$value = $this->fix($table, $field, $value); | |
if ( is_callable(array($this, $table . 'Fix')) ) { | |
$value = call_user_func_array(array($this, $table . 'Fix'), array($field, $value, $record)); | |
} | |
if ( $value !== false ) { | |
$SQL->addInsert($field, $value); | |
} | |
} | |
try { | |
DB::query($SQL->get(dsn()), 'exec'); | |
} catch ( \Exception $e ) { | |
$this->errors[] = $e->getMessage(); | |
} | |
} | |
foreach ($this->mediaFieldFix as $data) { | |
$SQL = SQL::newUpdate('field'); | |
$SQL->addUpdate('field_value', $data['value']); | |
$SQL->addWhereOpr('field_sort', $data['sort']); | |
$SQL->addWhereOpr('field_key', $data['name']); | |
$SQL->addWhereOpr('field_eid', $data['eid']); | |
$SQL->addWhereOpr('field_cid', $data['cid']); | |
$SQL->addWhereOpr('field_uid', $data['uid']); | |
$SQL->addWhereOpr('field_bid', $data['bid']); | |
$SQL->addWhereOpr('field_mid', $data['mid']); | |
DB::query($SQL->get(dsn()), 'exec'); | |
} | |
} | |
/** | |
* @param $table | |
* @param $field | |
* @param $value | |
* | |
* @return int | |
*/ | |
private function fix($table, $field, $value) | |
{ | |
$key = substr($field, strlen($table . '_')); | |
if ( $key === 'id' ) { | |
$value = $this->getNewID($table, $value); | |
} else if ( $key === 'category_id' ) { | |
$value = $this->getNewID('category', $value); | |
} else if ( $key === 'user_id' ) { | |
$value = $this->getNewID('user', $value); | |
} else if ( $key === 'entry_id' ) { | |
$value = $this->getNewID('entry', $value); | |
} else if ( $key === 'rule_id' ) { | |
$value = $this->getNewID('rule', $value); | |
} else if ( $key === 'module_id' ) { | |
$value = $this->getNewID('module', $value); | |
} else if ( $key === 'media_id') { | |
$value = $this->getNewID('media', $value); | |
} else if ( $key === 'set_id' || $key === 'config_set_id' ) { | |
$value = $this->getNewID('config_set', $value); | |
} else if ( $key === 'blog_id' ) { | |
$value = $this->bid; | |
} | |
if ( in_array($key, array( | |
'id', 'category_id', 'user_id', 'entry_id', | |
'rule_id', 'module_id', 'blog_id' | |
)) && empty($value) && $value !== '0' | |
) { | |
$value = null; | |
} | |
return $value; | |
} | |
/** | |
* @param string $field | |
* @param string $value | |
* @param array $record | |
* | |
* @return mixed | |
*/ | |
private function configFix($field, $value, $record) | |
{ | |
if ($record['config_key'] === 'media_banner_mid' && $field === 'config_value') { | |
return $this->getNewID('media', $value); | |
} | |
return $value; | |
} | |
/** | |
* @param string $field | |
* @param string $value | |
* @param array $record | |
* | |
* @return mixed | |
*/ | |
private function entryFix($field, $value, $record) | |
{ | |
if ( $field === 'entry_current_rev_id' ) { | |
$value = 0; | |
} else if ( $field === 'entry_last_update_user_id' ) { | |
$value = $this->uid; | |
} else if ( $field === 'entry_primary_image' && !empty($value) ) { | |
$value = $this->getNewID('column', $value); | |
} | |
return $value; | |
} | |
/** | |
* @param string $field | |
* @param string $value | |
* @param array $record | |
* | |
* @return mixed | |
*/ | |
private function columnFix($field, $value, $record) | |
{ | |
if (strncmp($record['column_type'], 'custom', 6) === 0 && $field === 'column_field_6') { | |
$data = acmsUnserialize($value); | |
if (method_exists($data, 'deleteField')) { | |
$fixMediaField = array(); | |
foreach ($data->listFields() as $fd) { | |
foreach ($data->getArray($fd, true) as $i => $val) { | |
if (strpos($fd, '@media') !== false) { | |
$sourceFd = substr($fd, 0, -6); | |
if (!isset($fixMediaField[$sourceFd])) { | |
$fixMediaField[$sourceFd] = array(); | |
} | |
$val = $this->getNewID('media', $val); | |
$fixMediaField[$sourceFd][] = $val; | |
} else { | |
$val = preg_replace('@([\d]{3})/(.*)\.([^\.]{2,6})@ui', sprintf("%03d", BID) . '/$2.$3', $val, -1); | |
} | |
if ($i === 0) { | |
$data->set($fd, $val); | |
} else { | |
$data->add($fd, $val); | |
} | |
} | |
} | |
// fix media id | |
foreach ($fixMediaField as $fd => $mediaIds) { | |
foreach ($mediaIds as $j => $mid) { | |
if ($j === 0) { | |
$data->set($fd, $mid); | |
} else { | |
$data->add($fd, $mid); | |
} | |
} | |
} | |
return acmsSerialize($data); | |
} | |
} else if (strncmp($record['column_type'], 'media', 5) === 0 && $field === 'column_field_1') { | |
$value = $this->getNewID('media', $value); | |
} else if (strncmp($record['column_type'], 'module', 5) === 0 && $field === 'column_field_1') { | |
$value = $this->getNewID('module', $value); | |
} | |
return $value; | |
} | |
/** | |
* @param string $field | |
* @param string $value | |
* @param array $record | |
* | |
* @return mixed | |
*/ | |
private function categoryFix($field, $value, $record) | |
{ | |
if ( $field === 'category_parent' ) { | |
$value = $this->getNewID('category', $value); | |
} | |
return $value; | |
} | |
/** | |
* @param string $field | |
* @param string $value | |
* @param array $record | |
* | |
* @return mixed | |
*/ | |
private function fulltextFix($field, $value, $record) | |
{ | |
if ( $field === 'fulltext_eid' ) { | |
$value = $this->getNewID('entry', $value); | |
} else if ( $field === 'fulltext_cid' ) { | |
$value = $this->getNewID('category', $value); | |
} else if ( $field === 'fulltext_uid' ) { | |
$value = $this->getNewID('user', $value); | |
} | |
if ( empty($value) ) { | |
if ( $field === 'fulltext_ngram' ) { | |
$value = ''; | |
} else { | |
$value = null; | |
} | |
} | |
if ( $field === 'fulltext_bid' && !empty($value) ) { | |
return false; | |
} | |
return $value; | |
} | |
/** | |
* @param string $field | |
* @param string $value | |
* @param array $record | |
* | |
* @return mixed | |
*/ | |
private function moduleFix($field, $value, $record) | |
{ | |
if ( $field === 'module_eid' ) { | |
$value = $this->getNewID('entry', $value); | |
} else if ( $field === 'module_cid' ) { | |
$value = $this->getNewID('category', $value); | |
} else if ( $field === 'module_uid' ) { | |
$value = $this->getNewID('user', $value); | |
} else if ( $field === 'module_bid' ) { | |
$value = empty($value) ? null : $this->bid; | |
} | |
return $value; | |
} | |
/** | |
* @param string $field | |
* @param string $value | |
* @param array $record | |
* | |
* @return mixed | |
*/ | |
private function layout_gridFix($field, $value, $record) | |
{ | |
if ( $field === 'layout_grid_mid' ) { | |
$value = $this->getNewID('module', $value); | |
} | |
return $value; | |
} | |
/** | |
* @param string $field | |
* @param string $value | |
* @param array $record | |
* | |
* @return mixed | |
*/ | |
private function ruleFix($field, $value, $record) | |
{ | |
if ( $field === 'rule_eid' ) { | |
$value = $this->getNewID('entry', $value); | |
} else if ( $field === 'rule_cid' ) { | |
$value = $this->getNewID('category', $value); | |
} else if ( $field === 'rule_uid' ) { | |
$value = $this->getNewID('user', $value); | |
} else if ( $field === 'rule_aid' ) { | |
$value = $this->getNewID('alias', $value); | |
} | |
return $value; | |
} | |
/** | |
* @param string $field | |
* @param string $value | |
* @param array $record | |
* | |
* @return mixed | |
*/ | |
private function fieldFix($field, $value, $record) | |
{ | |
if ( $field === 'field_eid' ) { | |
$value = $this->getNewID('entry', $value); | |
} else if ( $field === 'field_cid' ) { | |
$value = $this->getNewID('category', $value); | |
} else if ( $field === 'field_uid' ) { | |
$value = $this->getNewID('user', $value); | |
} else if ( $field === 'field_mid' ) { | |
$value = $this->getNewID('module', $value); | |
} else if ( $field === 'field_bid' && !empty($value)) { | |
$value = $this->bid; | |
} else if ($field === 'field_value' && preg_match('/@media$/', $record['field_key'])) { | |
$value = $this->getNewID('media', $value); | |
$this->mediaFieldFix[] = array( | |
'name' => substr($record['field_key'], 0, -6), | |
'value' => $value, | |
'sort' => $record['field_sort'], | |
'eid' => $this->getNewID('entry', $record['field_eid']), | |
'cid' => $this->getNewID('category', $record['field_cid']), | |
'uid' => $this->getNewID('user', $record['field_uid']), | |
'bid' => empty($record['field_bid']) ? null : $this->bid, | |
'mid' => $this->getNewID('module', $record['field_mid']), | |
); | |
} | |
return $value; | |
} | |
/** | |
* @param string $table | |
* @param int $id | |
* | |
* @return int | |
*/ | |
private function getNewID($table, $id) | |
{ | |
if ( !isset($this->ids[$table][$id]) ) { | |
return $id; | |
} | |
return $this->ids[$table][$id]; | |
} | |
/** | |
* @return void | |
*/ | |
private function registerNewIDs() | |
{ | |
$tables = array( | |
'category', 'column', 'alias', | |
'entry', 'fulltext', 'media', | |
'module', 'rule', 'media', 'config_set', | |
); | |
foreach ( $tables as $table ) { | |
$this->registerNewID($table); | |
} | |
} | |
/** | |
* @param string $table | |
* | |
* @return void | |
*/ | |
private function registerNewID($table) | |
{ | |
if ( !$this->existsYaml($table) ) { | |
return; | |
} | |
foreach ( $this->yaml[$table] as $record ) { | |
if ( !isset($record[$table . '_id']) ) { | |
continue; | |
} | |
$id = $record[$table . '_id']; | |
if ( isset($this->ids[$table][$id]) ) { | |
continue; | |
} | |
$this->ids[$table][$id] = DB::query(SQL::nextval($table . '_id', dsn()), 'seq'); | |
} | |
} | |
/** | |
* check yaml data | |
* | |
* @param $table | |
* | |
* @return bool | |
*/ | |
private function existsYaml($table) | |
{ | |
if ( !isset($this->yaml[$table]) ) { | |
return false; | |
} | |
$data = $this->yaml[$table]; | |
if ( !is_array($data) ) { | |
return false; | |
} | |
return true; | |
} | |
/** | |
* drop blog data | |
* | |
* @return void | |
*/ | |
private function dropData() | |
{ | |
$tables = array( | |
'category', 'entry', 'column', 'tag', | |
'fulltext', 'field', 'media', 'media_tag', | |
'approval', 'cache_reserve', 'column_rev', 'entry_rev', | |
'field_rev', 'tag_rev', | |
'dashboard', 'module', 'layout_grid', 'rule', 'config', 'config_set', | |
); | |
foreach ( $tables as $table ) { | |
$this->clearTable($table); | |
} | |
} | |
/** | |
* clear table in database | |
* | |
* @param string $table | |
* | |
* @return void | |
*/ | |
private function clearTable($table) | |
{ | |
$SQL = SQL::newDelete($table); | |
if ( preg_match('/^(.*)\_rev$/', $table, $match) ) { | |
$SQL->addWhereOpr($match[1].'_blog_id', $this->bid); | |
} else { | |
$SQL->addWhereOpr($table.'_blog_id', $this->bid); | |
} | |
if ($table === 'field') { | |
$SQL->addWhereOpr('field_uid', null); | |
} | |
DB::query($SQL->get(dsn()), 'exec'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment