Skip to content

Instantly share code, notes, and snippets.

@atsu666
Created April 15, 2021 07:28
Show Gist options
  • Save atsu666/e842126d8f6e4b91bc6594dea9299ab7 to your computer and use it in GitHub Desktop.
Save atsu666/e842126d8f6e4b91bc6594dea9299ab7 to your computer and use it in GitHub Desktop.
<?php
class ACMS_POST_Import_Model_Entry extends ACMS_POST_Import_Model
{
protected $entry;
protected $units;
protected $fields;
protected $importCid;
protected $importBid = BID;
protected $subCategories = array();
protected $geoLat = 0;
protected $geoLng = 0;
protected $geoZoom = 11;
protected $tags = array();
protected $idLabel = 'entry_id';
function setTargetCid($cid)
{
$this->importCid = $cid;
}
function setTargetBid($bid) {
$this->importBid = $bid;
}
function exist()
{
return ACMS_RAM::entryBlog($this->csvId) == $this->importBid && !!ACMS_RAM::entryCode($this->csvId) && ACMS_RAM::entryStatus($this->csvId) !== 'trash';
}
function nextId()
{
$DB = DB::singleton(dsn());
$this->nextId = intval($DB->query(SQL::nextval('entry_id', dsn()), 'seq'));
}
function saveEntry()
{
$this->formatCheck();
$this->updateKey();
$this->build();
if ( $this->isUpdate ) {
return $this->update();
} else {
return $this->insert();
}
}
function formatCheck()
{
foreach ($this->data as $key => $value) {
switch ($key) {
case 'entry_id':
case 'entry_summary_range':
case 'entry_primary_image':
case 'entry_category_id':
case 'entry_user_id':
if (!is_numeric($value)) {
throw new \RuntimeException('数値でない値が設定されています(' . $key . ')');
}
break;
case 'entry_status':
if (!in_array($value, array('open', 'close', 'draft', 'trash'))) {
throw new \RuntimeException('不正な値が設定されています(' . $key . ')');
}
break;
case 'entry_datetime':
case 'entry_updated_datetime':
case 'entry_start_datetime':
case 'entry_end_datetime':
case 'entry_posted_datetime':
if (!preg_match('@^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$@', $value)) {
throw new \RuntimeException('日時のフォーマットが間違っています(' . $key . ')');
}
break;
case 'entry_indexing':
if (!in_array($value, array('on', 'off'))) {
throw new \RuntimeException('on または off 以外の値が設定されています(' . $key . ')');
}
break;
}
}
}
function updateKey()
{
// プロ版以上限定
if ( !editionWithProfessional() ) {
return false;
}
$updateKey = null;
$DB = DB::singleton(dsn());
$SQL = SQL::newSelect('field');
$SQL->addSelect('field_eid');
$SQL->addWhereOpr('field_blog_id', $this->importBid);
foreach ( $this->labels as $key ) {
if ( strpos($key, 'unit@') === 0 ) {
continue;
}
if ( preg_match('/^\*/', $key) ) {
$updateKey = ltrim($key, '*');
break;
}
}
if ( isset($this->data['*'.$updateKey]) ) {
$SQL->addWhereOpr('field_key', $updateKey);
$SQL->addWhereOpr('field_value', $this->data['*'.$updateKey]);
$all = $DB->query($SQL->get(dsn()), 'all');
if ( count($all) === 1 ) {
$eid = $all[0]['field_eid'];
$this->updateEntryId($eid);
$this->isUpdate = true;
} else if ( count($all) > 1 ) {
throw new RuntimeException('重複するキーがあったためこのエントリーのインポートを中止しました。');
}
}
}
function updateEntryId($id)
{
$this->csvId = $id;
if ( is_array($this->units) ) {
foreach ( $this->units as & $unit ) {
$unit['column_entry_id'] = $id;
}
}
if ( is_array($this->fields) ) {
foreach ( $this->fields as & $field ) {
$field['field_eid'] = $id;
}
}
}
function insert()
{
$this->_insertEntry();
$this->_insertSubCategory($this->nextId);
$this->_insertTag($this->nextId);
$this->_insertGeo($this->nextId);
$this->_insertUnit();
$this->_insertField();
Common::saveFulltext('eid', $this->nextId, Common::loadEntryFulltext($this->nextId));
if (HOOK_ENABLE) {
$Hook = ACMS_Hook::singleton();
$Hook->call('saveEntry', array($this->nextId, 0));
}
}
function update()
{
$this->_updateEntry();
$this->_insertSubCategory($this->csvId);
$this->_insertTag($this->csvId);
$this->_insertGeo($this->csvId);
$this->_updateUnit();
$this->_updateField();
Common::saveFulltext('eid', $this->csvId, Common::loadEntryFulltext($this->csvId), ACMS_RAM::entryBlog($this->csvId));
if (HOOK_ENABLE) {
$Hook = ACMS_Hook::singleton();
$Hook->call('saveEntry', array($this->csvId, 0));
}
}
function _insertEntry()
{
$DB = DB::singleton(dsn());
$SQL = SQL::newInsert('entry');
foreach ($this->entry as $key => $val) {
$SQL->addInsert($key, $val);
}
$DB->query($SQL->get(dsn()), 'exec');
}
function _updateEntry()
{
$DB = DB::singleton(dsn());
$eid = $this->csvId;
if ( !ACMS_RAM::entryStatus($eid) ) {
throw new RuntimeException('Not Found Entry.');
}
unset(
$this->entry['entry_id'],
$this->entry['entry_sort'],
$this->entry['entry_user_sort'],
$this->entry['entry_category_sort'],
$this->entry['entry_hash'],
$this->entry['entry_blog_id']
);
if ( !empty($this->entry) ) {
$SQL = SQL::newUpdate('entry');
foreach ( $this->entry as $key => $val ) {
$SQL->addUpdate($key, $val);
}
$SQL->addWhereOpr('entry_id', $eid);
$SQL->addWhereOpr('entry_blog_id', $this->importBid);
$DB->query($SQL->get(dsn()), 'exec');
}
}
function _insertSubCategory($eid)
{
if (empty($this->subCategories)) {
return;
}
$DB = DB::singleton(dsn());
$SQL = SQL::newDelete('entry_sub_category');
$SQL->addWhereOpr('entry_sub_category_eid', $eid);
$DB->query($SQL->get(dsn()), 'exec');
foreach ($this->subCategories as $cid) {
$SQL = SQL::newInsert('entry_sub_category');
$SQL->addInsert('entry_sub_category_eid', $eid);
$SQL->addInsert('entry_sub_category_id', $cid);
$SQL->addInsert('entry_sub_category_blog_id', $this->importBid);
$DB->query($SQL->get(dsn()), 'exec');
}
}
function _insertTag($eid)
{
if (empty($this->tags)) {
return;
}
$DB = DB::singleton(dsn());
$SQL = SQL::newDelete('tag');
$SQL->addWhereOpr('tag_entry_id', $eid);
$DB->query($SQL->get(dsn()), 'exec');
foreach ($this->tags as $sort => $tag) {
$SQL = SQL::newInsert('tag');
$SQL->addInsert('tag_name', $tag);
$SQL->addInsert('tag_sort', $sort + 1);
$SQL->addInsert('tag_entry_id', $eid);
$SQL->addInsert('tag_blog_id', $this->importBid);
$DB->query($SQL->get(dsn()), 'exec');
}
}
function _insertGeo($eid)
{
if (empty($this->geoLat) || empty($this->geoLng)) {
return;
}
$DB = DB::singleton(dsn());
$SQL = SQL::newDelete('geo');
$SQL->addWhereOpr('geo_eid', $eid);
$DB->query($SQL->get(dsn()), 'exec');
$SQL = SQL::newInsert('geo');
$SQL->addInsert('geo_geometry', SQL::newGeometry($this->geoLat, $this->geoLng));
$SQL->addInsert('geo_zoom', intval($this->geoZoom));
$SQL->addInsert('geo_eid', $eid);
$SQL->addInsert('geo_blog_id', $this->importBid);
$DB->query($SQL->get(dsn()), 'exec');
}
function _insertUnit()
{
$DB = DB::singleton(dsn());
if ( !empty($this->units) ) {
foreach ( $this->units as $cval ) {
$SQL = SQL::newInsert('column');
foreach ( $cval as $key => $val) {
if ( $key === 'column_id' ) {
$val = intval($DB->query(SQL::nextval('column_id', dsn()), 'seq'));
}
$SQL->addInsert($key, $val);
}
$DB->query($SQL->get(dsn()), 'exec');
}
}
}
function _updateUnit()
{
$DB = DB::singleton(dsn());
$eid = $this->csvId;
if ( !empty($this->units) ) {
$SQL = SQL::newDelete('column');
$SQL->addWhereOpr('column_entry_id', $eid);
$SQL->addWhereOpr('column_type', 'text');
$DB->query($SQL->get(dsn()), 'exec');
foreach ( $this->units as $cval ) {
$SQL = SQL::newInsert('column');
foreach ( $cval as $key => $val) {
if ( $key === 'column_id' ) {
$val = intval($DB->query(SQL::nextval('column_id', dsn()), 'seq'));
}
$SQL->addInsert($key, $val);
}
$DB->query($SQL->get(dsn()), 'exec');
}
}
}
function _insertField()
{
$DB = DB::singleton(dsn());
$eid = $this->nextId;
if ( !empty($this->fields) ) {
$SQL = SQL::newDelete('field');
$SQL->addWhereOpr('field_eid', $eid);
$DB->query($SQL->get(dsn()), 'exec');
foreach ( $this->fields as $fval ) {
$SQL = SQL::newInsert('field');
foreach ( $fval as $key => $val ) {
$SQL->addInsert($key, $val);
}
$DB->query($SQL->get(dsn()), 'exec');
}
}
}
function _updateField()
{
$DB = DB::singleton(dsn());
$eid = $this->csvId;
if ( !empty($this->fields) ) {
$fkey = array();
$SQL = SQL::newDelete('field');
$SQL->addWhereOpr('field_eid', $eid);
foreach ( $this->fields as $dval ) {
foreach ( $dval as $key => $val ) {
if ( $key === 'field_key' ) {
$fkey[] = $val;
}
}
}
$SQL->addWhereIn('field_key', $fkey);
$DB->query($SQL->get(dsn()), 'exec');
foreach ( $this->fields as $fval ) {
$SQL = SQL::newInsert('field');
foreach ( $fval as $key => $val ) {
$SQL->addInsert($key, $val);
}
$SQL->addInsert('field_eid', $eid);
$SQL->addInsert('field_blog_id', ACMS_RAM::entryBlog($eid));
$DB->query($SQL->get(dsn()), 'exec');
}
}
}
function getPostedDatetime()
{
$posted_datetime = date('Y-m-d H:i:s');
$second = sprintf('%02d', rand(1, 59));
$posted_datetime = preg_replace('@[0-9]{2}$@', $second, $posted_datetime);
return $posted_datetime;
}
function build()
{
$this->entry = $this->entryBase();
$unit = $this->unitBase();
$field = $this->fieldBase();
foreach ( $this->data as $key => $value ) {
if ( $key === 'entry_id' && $this->isUpdate ) {
$this->entry['entry_id'] = $this->csvId;
$unit['column_entry_id'] = $this->csvId;
$field['field_eid'] = $this->csvId;
}
if (array_key_exists($key, $this->entry)) {
$this->buildEntry($key, $value);
} else if ($key === 'entry_sub_category') {
$this->buildSubCategory($value);
} else if ($key === 'entry_tag') {
$this->buildTag($value);
} else if (strpos($key, 'unit@') === 0) {
$this->buildUnit($unit, $key, $value);
} else if (in_array($key, array('geo_lat', 'geo_lng', 'geo_zoom'))) {
$this->buildGeo($key, $value);
} else {
$this->buildField($field, $key, $value);
}
}
// アップデートの場合は余分なベース情報を削除
if ( $this->isUpdate ) {
foreach ( $this->entry as $key => $value ) {
if ( !isset($this->data[$key]) ) {
unset($this->entry[$key]);
}
}
}
}
function buildEntry($key, $value)
{
switch ( $key ) {
case 'entry_id':
break;
case 'entry_datetime':
case 'entry_updated_datetime':
case 'entry_start_datetime':
case 'entry_end_datetime':
if (preg_match('@^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$@', $value)) {
$this->entry[$key] = $value;
}
break;
case 'entry_code':
$value = preg_replace('@\.([^\.]+)$@', '', $value);
$this->entry[$key] = $value . $this->getExtension();
break;
case 'entry_posted_datetime':
if ( preg_match('@^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$@', $value) ) {
$this->entry[$key] = $value;
$this->entry['entry_hash'] = md5(SYSTEM_GENERATED_DATETIME.$value);
}
break;
case 'entry_category_id':
$ccode = ACMS_RAM::categoryCode($value);
if ( empty($ccode) ) {
$this->entry[$key] = null;
} else {
$this->entry[$key] = $value;
}
break;
default :
$this->entry[$key] = $value;
}
}
function buildGeo($key, $value)
{
switch ($key) {
case 'geo_lat':
$this->geoLat = $value;
break;
case 'geo_lng':
$this->geoLng = $value;
break;
case 'geo_zoom':
$this->geoZoom = $value;
break;
}
}
function buildSubCategory($value)
{
$subCategoryIds = explode(',', $value);
if (empty($subCategoryIds)) {
return;
}
foreach ($subCategoryIds as $cid) {
$cid = intval(trim($cid));
if (empty($cid)) {
continue;
}
$this->subCategories[] = $cid;
}
}
function buildTag($value)
{
$tags = Common::getTagsFromString($value);
if (empty($tags)) {
return;
}
foreach ($tags as $sort => $tag) {
$this->tags[] = $tag;
}
}
function buildUnit($unit, $key, $value)
{
$type = substr($key, strlen('unit@'));
$sort = 1;
if ( preg_match('@\[\d+\]$@', $type, $matchs) ) {
$sort = intval(preg_replace('@\[|\]@', '', $matchs[0]));
$type = preg_replace('@\[\d+\]$@', '', $type);
}
$tokens = preg_split('@(#|\.)@', $type, -1, PREG_SPLIT_DELIM_CAPTURE);
$unit['column_field_2'] = array_shift($tokens);
$id = '';
$class = '';
while ( $mark = array_shift($tokens) ) {
if ( !$val = array_shift($tokens) ) continue;
if ( '#' == $mark ) {
$id = $val;
} else {
$class = $val;
}
}
$attr = '';
if ( !empty($id) ) $attr .= ' id="'.$id.'"';
if ( !empty($class) ) $attr .= ' class="'.$class.'"';
if ( !empty($attr) ) $unit['column_attr'] = $attr;
$unit['column_sort'] = $sort;
$unit['column_field_1'] = $value;
$this->units[] = $unit;
}
function buildField($field, $key, $value)
{
$sort = 1;
if ( preg_match('@\[\d+\]$@', $key, $matchs) ) {
$sort = intval(preg_replace('@\[|\]@', '', $matchs[0]));
$key = preg_replace('@\[\d+\]$@', '', $key);
}
$field['field_key'] = ltrim($key, '*');
$field['field_value'] = $value;
$field['field_sort'] = $sort;
$this->fields[] = $field;
}
function entryBase()
{
$posted_datetime = $this->getPostedDatetime();
return array(
'entry_id' => $this->nextId,
'entry_code' => config('entry_code_prefix').$this->nextId . $this->getExtension(),
'entry_status' => 'open',
'entry_sort' => $this->getNextSort(self::SORT_ENTRY),
'entry_user_sort' => $this->getNextSort(self::SORT_USER),
'entry_category_sort' => $this->getNextSort(self::SORT_CATEGORY),
'entry_title' => 'CSV_IMPORT-'.$this->nextId,
'entry_link' => '',
'entry_datetime' => $posted_datetime,
'entry_start_datetime' => '1000-01-01 00:00:00',
'entry_end_datetime' => '9999-12-31 23:59:59',
'entry_posted_datetime' => $posted_datetime,
'entry_updated_datetime'=> $posted_datetime,
'entry_hash' => md5(SYSTEM_GENERATED_DATETIME.$posted_datetime),
'entry_summary_range' => null,
'entry_indexing' => 'on',
'entry_primary_image' => null,
'entry_category_id' => $this->importCid,
'entry_user_id' => SUID,
'entry_blog_id' => $this->importBid,
);
}
function unitBase()
{
return array(
'column_id' => 0,
'column_sort' => 0,
'column_align' => 'auto',
'column_type' => 'text',
'column_attr' => '',
'column_size' => '',
'column_field_1' => '',
'column_field_2' => 'p',
'column_field_3' => '',
'column_field_4' => '',
'column_field_5' => '',
'column_entry_id' => $this->nextId,
'column_blog_id' => $this->importBid,
);
}
function fieldBase()
{
return array(
'field_key' => null,
'field_value' => null,
'field_sort' => 1,
'field_search' => 'on',
'field_eid' => $this->nextId,
'field_blog_id' => $this->importBid,
);
}
protected function getExtension()
{
$extension = config('entry_code_extension');
return empty($extension) ? '' : '.' . $extension;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment