Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 48 additions & 2 deletions plugins/baser-core/src/Utility/BcFileUploader.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@
namespace BaserCore\Utility;

use ArrayObject;
use Cake\Core\Configure;
use Cake\Core\Plugin;
use Cake\Http\Session;
use Cake\ORM\Entity;
use Cake\ORM\Table;
use Cake\Routing\Router;
use Cake\Utility\Hash;
use Cake\Utility\Inflector;
use BaserCore\Vendor\Imageresizer;
use Cake\Datasource\EntityInterface;
use BaserCore\Annotation\Note;
Expand Down Expand Up @@ -742,10 +745,17 @@ public function renameToBasenameField($setting, $file, $entity, $copy = false)
$oldSaveDir = '';
if (file_exists($saveDir . $oldName)) {
$oldSaveDir = $saveDir;
} elseif (file_exists($saveDirInTheme . $oldName)) {
} elseif ($saveDirInTheme !== false && file_exists($saveDirInTheme . $oldName)) {
$oldSaveDir = $saveDirInTheme;
} else {
// 管理画面からの操作時など getSaveDir(true) が正しいテーマを参照しない場合に
// コアフロントテーマの files ディレクトリも確認する(初期データ複製対応)
$coreFrontThemeSaveDir = $this->getCoreFrontThemeSaveDir();
if ($coreFrontThemeSaveDir && file_exists($coreFrontThemeSaveDir . $oldName)) {
$oldSaveDir = $coreFrontThemeSaveDir;
}
}
if (!file_exists($oldSaveDir . $oldName)) {
if (!$oldSaveDir || !file_exists($oldSaveDir . $oldName)) {
return '';
}
$newName = $this->getFieldBasename($setting, $file, $entity);
Expand Down Expand Up @@ -937,6 +947,42 @@ public function getUniqueFileName(array $setting, array $file, EntityInterface $
}
}

/**
* コアフロントテーマの files 保存ディレクトリを取得する
*
* 管理画面からファイルを操作する場合など getSaveDir(true) が正しいテーマを
* 参照できないケースのフォールバックとして使用する
* (初期データのアイキャッチはコアフロントテーマ側に保存されているため)
*
* @return string|false
*/
private function getCoreFrontThemeSaveDir(): string|false
{
$frontTheme = Configure::read('BcApp.coreFrontTheme');
if (!$frontTheme) return false;
$basePath = false;
$themeCandidates = array_unique([
$frontTheme,
Inflector::camelize($frontTheme, '-'),
]);
foreach ($themeCandidates as $themeCandidate) {
try {
$candidatePath = Plugin::path($themeCandidate) . 'webroot' . DS . 'files' . DS;
} catch (\Throwable $e) {
continue;
}
if (is_dir($candidatePath)) {
$basePath = $candidatePath;
break;
}
}
if (!$basePath) return false;
if ($this->settings['saveDir']) {
return $basePath . $this->settings['saveDir'] . DS;
}
return $basePath;
}

/**
* 保存先のフォルダを設定し、取得する
* @param bool $isTheme
Expand Down
227 changes: 155 additions & 72 deletions plugins/bc-blog/tests/TestCase/Model/BlogPostsTableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@
use BcBlog\Test\Factory\BlogContentFactory;
use BcBlog\Test\Factory\BlogPostFactory;
use BcBlog\Test\Scenario\MultiSiteBlogPostScenario;
use Cake\Core\Configure;
use Cake\Core\Plugin;
use Cake\Event\Event;
use Cake\Utility\Inflector;
use CakephpFixtureFactories\Scenario\ScenarioAwareTrait;
use Laminas\Diactoros\UploadedFile;
use ArrayObject;
/**
* Class BlogPostsTableTest
Expand Down Expand Up @@ -649,78 +653,157 @@ public function testCreatePreviewData()
*/
public function testCopyEyeCatch()
{
$this->markTestIncomplete('こちらのテストはまだ未確認です');
if (is_dir(WWW_ROOT . '/files/blog/999')) {
$folder = new BcFolder(WWW_ROOT . '/files/blog/999');
$folder->delete();
}
copy(__DIR__ . '/../../Images/File/test1.png', __DIR__ . '/../../Images/File/test1_.png');
$this->loadFixtureScenario(InitAppScenario::class);
BlogContentFactory::make()->forCopyEyeCatch()->persist();

$this->loginAdmin($this->getRequest());

$this->BlogPostsTable->setupUpload(999);

$data = [
'no' => 1,
'name' => 'test-name',
'blog_content_id' => 999,
'posts_date' => '2022-07-16 00:00:00',
'content' => 'test-content',
'detail' => 'test-detail',
'status' => 0,
'publish_begin' => null,
'publish_end' => null,
'user_id' => 1,
'eye_catch' => [
'name' => 'test.png',
'type' => 'image/png',
'tmp_name' => __DIR__ . '/../../Images/File/test1_.png',
'error' => 0,
'size' => 1,
],
];

// 作成
$blogPost1 = $this->BlogPostsTable->save($this->BlogPostsTable->newEntity($data));
$blogPost1no = $blogPost1->no;
$ym = date('Y/m');
$fileDir = WWW_ROOT . '/files/blog/999/blog_posts/' . $ym;

$this->assertEquals($ym . '/0000000' . $blogPost1no . '_eye_catch.png', $blogPost1->eye_catch);
$this->assertTrue(is_file($fileDir . '/0000000' . $blogPost1no . '_eye_catch.png'));
$this->assertTrue(is_file($fileDir . '/0000000' . $blogPost1no . '_eye_catch__thumb.png'));
$this->assertTrue(is_file($fileDir . '/0000000' . $blogPost1no . '_eye_catch__mobile_thumb.png'));

// コピー
$blogPost2 = $this->BlogPostsTable->copy(null, clone $blogPost1);
$blogPost2no = $blogPost2->no;

// 複製元が影響を受けていないか
$this->assertEquals($ym . '/0000000' . $blogPost1no . '_eye_catch.png', $blogPost1->eye_catch);
$this->assertTrue(is_file($fileDir . '/0000000' . $blogPost1no . '_eye_catch.png'));
$this->assertTrue(is_file($fileDir . '/0000000' . $blogPost1no . '_eye_catch__thumb.png'));
$this->assertTrue(is_file($fileDir . '/0000000' . $blogPost1no . '_eye_catch__mobile_thumb.png'));

// 複製できているか
$this->assertEquals($ym . '/0000000' . $blogPost2no . '_eye_catch.png', $blogPost2->eye_catch);
$this->assertTrue(is_file($fileDir . '/0000000' . $blogPost2no . '_eye_catch.png'));
$this->assertTrue(is_file($fileDir . '/0000000' . $blogPost2no . '_eye_catch__thumb.png'));
$this->assertTrue(is_file($fileDir . '/0000000' . $blogPost2no . '_eye_catch__mobile_thumb.png'));

// 削除
$this->BlogPostsTable->delete($blogPost2);
$blogPost2 = $this->BlogPostsTable->find()->where([
'BlogPosts.id' => $blogPost2->id
])->first();
$this->assertEmpty($blogPost2);
$this->assertFalse(is_file($fileDir . '/0000000' . $blogPost2no . '_eye_catch.png'));
$this->assertFalse(is_file($fileDir . '/0000000' . $blogPost2no . '_eye_catch__thumb.png'));
$this->assertFalse(is_file($fileDir . '/0000000' . $blogPost2no . '_eye_catch__mobile_thumb.png'));

$dir = new BcFolder(WWW_ROOT . '/files/blog/999');
$dir->delete();
$frontTheme = Configure::read('BcApp.coreFrontTheme');
$themeFilesDir = false;
if ($frontTheme) {
$themeCandidates = array_unique([$frontTheme, Inflector::camelize($frontTheme, '-')]);
foreach ($themeCandidates as $themeCandidate) {
try {
$themeFilesDir = Plugin::path($themeCandidate) . 'webroot' . DS . 'files' . DS . 'blog' . DS . '999';
break;
} catch (\Throwable $e) {
continue;
}
}
}

$tmpUploadPath = __DIR__ . '/../../Images/File/test1_.png';

try {
if (is_dir(WWW_ROOT . 'files/blog/999')) {
$folder = new BcFolder(WWW_ROOT . 'files/blog/999');
$folder->delete();
}
if ($themeFilesDir && is_dir($themeFilesDir)) {
$folder = new BcFolder($themeFilesDir);
$folder->delete();
}

copy(__DIR__ . '/../../Images/File/test1.png', $tmpUploadPath);
$this->loadFixtureScenario(InitAppScenario::class);
BlogContentFactory::make()->forCopyEyeCatch()->persist();

$this->loginAdmin($this->getRequest());

$this->BlogPostsTable->setupUpload(999);

$data = [
'no' => 1,
'name' => 'test-name',
'title' => 'Test Blog Post',
'blog_content_id' => 999,
'posted' => '2022-07-16 00:00:00',
'content' => 'test-content',
'detail' => 'test-detail',
'status' => 0,
'publish_begin' => null,
'publish_end' => null,
'user_id' => 1,
'eye_catch' => new UploadedFile(
$tmpUploadPath,
1,
UPLOAD_ERR_OK,
'test.png',
'image/png'
),
];

// 作成
$blogPost1 = $this->BlogPostsTable->save($this->BlogPostsTable->newEntity($data));
$blogPost1no = $blogPost1->no;
$ym = date('Y/m');
$fileDir = WWW_ROOT . 'files/blog/999/blog_posts/' . $ym;

$this->assertEquals($ym . '/0000000' . $blogPost1no . '_eye_catch.png', $blogPost1->eye_catch);
$this->assertTrue(is_file($fileDir . '/0000000' . $blogPost1no . '_eye_catch.png'));
$this->assertTrue(is_file($fileDir . '/0000000' . $blogPost1no . '_eye_catch__thumb.png'));
$this->assertTrue(is_file($fileDir . '/0000000' . $blogPost1no . '_eye_catch__mobile_thumb.png'));

// コピー
$blogPost2 = $this->BlogPostsTable->copy(null, clone $blogPost1);
$blogPost2no = $blogPost2->no;

// 複製元が影響を受けていないか
$this->assertEquals($ym . '/0000000' . $blogPost1no . '_eye_catch.png', $blogPost1->eye_catch);
$this->assertTrue(is_file($fileDir . '/0000000' . $blogPost1no . '_eye_catch.png'));
$this->assertTrue(is_file($fileDir . '/0000000' . $blogPost1no . '_eye_catch__thumb.png'));
$this->assertTrue(is_file($fileDir . '/0000000' . $blogPost1no . '_eye_catch__mobile_thumb.png'));

// 複製できているか
$this->assertEquals($ym . '/0000000' . $blogPost2no . '_eye_catch.png', $blogPost2->eye_catch);
$this->assertTrue(is_file($fileDir . '/0000000' . $blogPost2no . '_eye_catch.png'));
$this->assertTrue(is_file($fileDir . '/0000000' . $blogPost2no . '_eye_catch__thumb.png'));
$this->assertTrue(is_file($fileDir . '/0000000' . $blogPost2no . '_eye_catch__mobile_thumb.png'));

// 削除
$this->BlogPostsTable->delete($blogPost2);
$blogPost2 = $this->BlogPostsTable->find()->where([
'BlogPosts.id' => $blogPost2->id
])->first();
$this->assertEmpty($blogPost2);
$this->assertFalse(is_file($fileDir . '/0000000' . $blogPost2no . '_eye_catch.png'));
$this->assertFalse(is_file($fileDir . '/0000000' . $blogPost2no . '_eye_catch__thumb.png'));
$this->assertFalse(is_file($fileDir . '/0000000' . $blogPost2no . '_eye_catch__mobile_thumb.png'));

// ===== 初期記事(テーマ内 files)のアイキャッチ複製テスト =====
$this->assertNotFalse($themeFilesDir);

// テーマの files ディレクトリに初期データ用のアイキャッチファイルを配置する
$themePostDir = $themeFilesDir . DS . 'blog_posts' . DS . '2023' . DS . '02' . DS;
if (!is_dir($themePostDir)) {
mkdir($themePostDir, 0777, true);
}
$initEyeCatch = '2023/02/00000099_eye_catch.png';
copy(__DIR__ . '/../../Images/File/test1.png', $themePostDir . '00000099_eye_catch.png');
copy(__DIR__ . '/../../Images/File/test1.png', $themePostDir . '00000099_eye_catch__thumb.png');
copy(__DIR__ . '/../../Images/File/test1.png', $themePostDir . '00000099_eye_catch__mobile_thumb.png');

// DB に初期記事を直接作成(eye_catch にはテーマ内のパスをセット)
BlogPostFactory::make([
'no' => 99,
'name' => 'test-initial',
'blog_content_id' => 999,
'title' => 'Initial Test Post',
'content' => '',
'detail' => '',
'status' => 0,
'posted' => '2023-02-01 00:00:00',
'user_id' => 1,
'eye_catch' => $initEyeCatch,
])->persist();
$initialPost = $this->BlogPostsTable->find()->where([
'BlogPosts.blog_content_id' => 999,
'BlogPosts.no' => 99,
])->first();

// 初期記事を複製 → テーマ内ファイルから webroot/files へコピーされる
$copiedInitPost = $this->BlogPostsTable->copy(null, clone $initialPost);

// アイキャッチが webroot/files 配下に複製されているか
$this->assertNotEmpty($copiedInitPost->eye_catch);
$copiedEyeCatch = $copiedInitPost->eye_catch;
$this->assertTrue(is_file(WWW_ROOT . 'files/blog/999/blog_posts/' . $copiedEyeCatch));
$thumbPath = str_replace('_eye_catch.', '_eye_catch__thumb.', $copiedEyeCatch);
$this->assertTrue(is_file(WWW_ROOT . 'files/blog/999/blog_posts/' . $thumbPath));
$mobileThumbPath = str_replace('_eye_catch.', '_eye_catch__mobile_thumb.', $copiedEyeCatch);
$this->assertTrue(is_file(WWW_ROOT . 'files/blog/999/blog_posts/' . $mobileThumbPath));

// 複製元(テーマ内)のファイルは残っているか
$this->assertEquals($initEyeCatch, $initialPost->eye_catch);
$this->assertTrue(is_file($themePostDir . '00000099_eye_catch.png'));
} finally {
if (is_file($tmpUploadPath)) {
unlink($tmpUploadPath);
}
if (is_dir(WWW_ROOT . 'files/blog/999')) {
$dir = new BcFolder(WWW_ROOT . 'files/blog/999');
$dir->delete();
}
if ($themeFilesDir && is_dir($themeFilesDir)) {
$themeDir = new BcFolder($themeFilesDir);
$themeDir->delete();
}
}
}

/**
Expand Down
Loading