7 * LICENSE: This source file is licensed under the terms of the GNU General Public License.
9 * @package Magic3 Framework
10 * @author 平田直毅(Naoki Hirata) <naoki@aplo.co.jp>
11 * @copyright Copyright 2006-2018 Magic3 Project.
12 * @license http://www.gnu.org/copyleft/gpl.html GPL License
14 * @link http://www.magic3.org
16 require_once($gEnvManager->getCurrentWidgetContainerPath() . '/admin_mainTempBaseWidgetContainer.php');
17 require_once($gEnvManager->getCurrentWidgetDbPath() . '/admin_mainDb.php');
18 require_once($gEnvManager->getLibPath() . '/pclzip-2-8-2/pclzip.lib.php');
19 require_once($gEnvManager->getCurrentWidgetContainerPath() . '/admin_mainDef.php'); // 定義クラス
20 require_once($gEnvManager->getCommonPath() . '/archive.php');
22 require_once($gEnvManager->getJoomlaRootPath() . '/JParameter.php');
23 require_once($gEnvManager->getJoomlaRootPath() . '/JRender.php');
25 class admin_mainTemplistWidgetContainer extends admin_mainTempBaseWidgetContainer
27 private $db; // DB接続オブジェクト
28 private $serialArray = array(); // 表示されているコンテンツシリアル番号
29 private $newTemplate = array(); // 新規追加テンプレート
30 private $defalutTemplate; // デフォルトのテンプレート
31 private $templateTypeArray; // テンプレートタイプ
32 private $templateType; // 現在のテンプレートタイプ
33 private $isExistsTemplateList; // テンプレートが存在するかどうか
34 // const BREADCRUMB_TITLE = 'テンプレート管理'; // 画面タイトル名(パンくずリスト)
35 const TITLE_INFO_URL = 'テンプレートの情報'; // テンプレート情報URLのタイトル
36 const TEMPLATE_THUMBNAIL_FILENAME = 'template_thumbnail.png'; // テンプレートサムネール
37 const TEMPLATE_THUMBNAIL_FILENAME_WP = 'screenshot'; // テンプレートサムネール(WordPressテンプレート)
38 const previewImageSizeHeight = 27;
39 const previewImageSizeWidth = 42;
40 const imageSizeHeight = 135;
41 const imageSizeWidth = 210;
42 const JOOMLA_CONFIG_FILENAME = 'templateDetails.xml'; // Joomla!のテンプレート設定ファイル名
43 const NOT_FOUND_TEMPLATE_ICON_FILE = '/images/system/notfound32.png'; // テンプレートが見つからないアイコン
44 const DOWNLOAD_ZIP_ICON_FILE = '/images/system/download_zip32.png'; // Zipダウンロード用アイコン
45 // const UPLOAD_ICON_FILE = '/images/system/upload32.png'; // ウィジェットアップロード用アイコン
46 const RELOAD_ICON_FILE = '/images/system/reload32.png'; // 再読み込み用アイコン
47 // const AREA_OPEN_ICON_FILE = '/images/system/area_open32.png'; // 拡張領域表示アイコン
48 const THEMLER_APP_FILENAME = '/app/themler.version'; // Themlerテンプレートかどうかを判断するためのファイル
49 const DEFAULT_IMAGE_DIR = '/images'; // デフォルトの画像格納ディレクトリ
50 const CF_PERMIT_DETAIL_CONFIG = 'permit_detail_config'; // 開発モードかどうか
55 function __construct()
58 parent::__construct();
61 $this->db = new admin_mainDb();
64 $isActiveSitePc = $this->isActiveAccessPoint(0/*PC*/); // PC用サイト有効かどうか
65 $isActiveSiteSmartphone = $this->isActiveAccessPoint(2/*スマートフォン*/); // スマートフォン用サイト有効かどうか
66 $isActiveSiteMobile = $this->isActiveAccessPoint(1/*スマートフォン*/); // 携帯用サイト有効かどうか
67 $this->templateTypeArray = array();
68 if ($isActiveSitePc) $this->templateTypeArray[] = array( 'name' => $this->_('For PC'), 'value' => '0'); // PC用
69 if ($isActiveSiteSmartphone) $this->templateTypeArray[] = array( 'name' => $this->_('For Smartphone'), 'value' => '2'); // スマートフォン用
70 if ($isActiveSiteMobile) $this->templateTypeArray[] = array( 'name' => $this->_('For Mobile'), 'value' => '1'); // 携帯用
75 * _assign()でデータを埋め込むテンプレートファイルのファイル名を返す。
76 * 読み込むディレクトリは、「自ウィジェットディレクトリ/include/template」に固定。
78 * @param RequestManager $request HTTPリクエスト処理クラス
79 * @param object $param 任意使用パラメータ。そのまま_assign()に渡る
80 * @return string テンプレートファイル名。テンプレートライブラリを使用しない場合は空文字列「''」を返す。
82 function _setTemplate($request, &$param)
84 return 'templist.tmpl.html';
89 * ヘルプの設定を行う場合はヘルプIDを返す。
90 * ヘルプデータの読み込むディレクトリは「自ウィジェットディレクトリ/include/help」に固定。
92 * @param RequestManager $request HTTPリクエスト処理クラス
93 * @param object $param 任意使用パラメータ。そのまま_assign()に渡る
94 * @return string ヘルプID。ヘルプデータはファイル名「help_[ヘルプID].php」で作成。ヘルプを使用しない場合は空文字列「''」を返す。
96 function _setHelp($request, &$param)
103 * _setTemplate()で指定したテンプレートファイルにデータを埋め込む。
105 * @param RequestManager $request HTTPリクエスト処理クラス
106 * @param object $param 任意使用パラメータ。_setTemplate()と共有。
109 /* function _postAssign($request, &$param)
111 $this->gPage->setAdminBreadcrumbDef(array(self::BREADCRUMB_TITLE));
116 * _setTemplate()で指定したテンプレートファイルにデータを埋め込む。
118 * @param RequestManager $request HTTPリクエスト処理クラス
119 * @param object $param 任意使用パラメータ。_setTemplate()と共有。
122 function _assign($request, &$param)
124 $act = $request->trimValueOf('act');
125 $selectedItemNo = $request->trimValueOf('no'); // 処理対象の項目番号
126 $userId = $this->gEnv->getCurrentUserId();
127 $templateId = $request->trimValueOf('template'); // テンプレートID
128 $this->templateType = $request->trimValueOf('item_type');// 現在のテンプレートタイプ
129 if ($this->templateType == '') $this->templateType = '0'; // デフォルトはPC用テンプレート
131 if ($act == 'readnew'){ // テンプレート再読み込みのとき
132 $addTemplateCount = 0;
134 if ($this->db->getAllTemplateIdList($rows)){
136 switch ($this->templateType){
137 case '0': // PC用テンプレート
139 $searchPath = $this->gEnv->getTemplatesPath();
141 case '1': // 携帯用テンプレート
142 $searchPath = $this->gEnv->getTemplatesPath() . '/' . M3_DIR_NAME_MOBILE;
144 case '2': // スマートフォン用テンプレート
145 $searchPath = $this->gEnv->getTemplatesPath() . '/' . M3_DIR_NAME_SMARTPHONE;
149 if (is_dir($searchPath)){
150 $dir = dir($searchPath);
151 while (($file = $dir->read()) !== false){
152 $filePath = $searchPath . '/' . $file;
154 if (strncmp($file, '.', 1) != 0 && $file != '..' && is_dir($filePath) &&
155 strncmp($file, '_', 1) != 0 && // 「_」で始まる名前のディレクトリは読み込まない
156 strlen($file) > 1 && // 携帯、スマートフォン用ディレクトリ「m」「s」は読み込まない
157 !($this->templateType == 0 && $file == 'system')){ // PC用Joomla!デフォルトテンプレート「system」は読み込まない
160 switch ($this->templateType){
161 case '0': // PC用テンプレート
165 case '1': // 携帯用テンプレート
166 $templateId = M3_DIR_NAME_MOBILE . '/' . $file;
168 case '2': // スマートフォン用テンプレート
169 $templateId = M3_DIR_NAME_SMARTPHONE . '/' . $file;
174 for ($i = 0; $i < count($rows); $i++){
175 if ($templateId == $rows[$i]['tm_id']) break;
177 if ($i == count($rows)){
179 $ret = $this->addNewTemplate(intval($this->templateType), $templateId);
181 $this->newTemplate[] = $templateId;
182 $addTemplateCount++; // テンプレート追加
192 if ($addTemplateCount > 0){
193 //$msg = '新規テンプレートを追加しました(追加数=' . $addTemplateCount . ')';
194 $msg = sprintf($this->_('New templates added. (templates count=%d)'), $addTemplateCount); // 新規テンプレートを追加しました(追加数=%d)
196 //$msg = '新規テンプレートはありません';
197 $msg = $this->_('No new templates added.'); // 新規テンプレートはありません
199 $this->setMsg(self::MSG_GUIDANCE, $msg);
200 } else if ($act == 'deleteline'){ // テンプレート削除のとき
202 if (empty($templateId)) $this->setMsg(self::MSG_APP_ERR, $this->_('Template not selected.')); // テンプレートが選択されていません
204 if (!$this->isExistsMsg()){ // エラーなしのとき
206 $templatePath = $this->gEnv->getTemplatesPath() . '/' . $templateId;
209 if ((is_dir($templatePath) && rmDirectory($templatePath)) || !is_dir($templatePath)){// 削除成功か、ディレクトリが存在しないとき
210 $ret = $this->db->deleteTemplate($templateId);
211 if ($ret){ // データ更新成功のとき
212 $this->setMsg(self::MSG_GUIDANCE, sprintf($this->_('Template deleted. (template ID: %s)'), $templateId)); // テンプレートを削除しました(テンプレートID:%s)
214 $this->setMsg(self::MSG_APP_ERR, sprintf($this->_('Failed in deleting template. (template ID: %s)'), $templateId)); // テンプレート削除に失敗しました(テンプレートID:%s)
217 $this->setMsg(self::MSG_APP_ERR, sprintf($this->_('Failed in deleting template directory. (directory: %s)'), $templatePath)); // テンプレートのディレクトリが削除できませんでした(ディレクトリ:%s)
220 } else if ($act == 'delete'){ // 項目削除の場合
221 $listedItem = explode(',', $request->trimValueOf('seriallist'));
223 for ($i = 0; $i < count($listedItem); $i++){
225 $itemName = 'item' . $i . '_selected';
226 $itemValue = ($request->trimValueOf($itemName) == 'on') ? 1 : 0;
228 if ($itemValue){ // チェック項目
229 $delItems[] = $listedItem[$i];
232 if (count($delItems) > 0){
234 $delContentInfo = array();
235 for ($i = 0; $i < count($delItems); $i++){
237 $templateId = $delItems[$i];
238 $templatePath = $this->gEnv->getTemplatesPath() . '/' . $templateId;
241 if ((is_dir($templatePath) && rmDirectory($templatePath)) || !is_dir($templatePath)){// 削除成功か、ディレクトリが存在しないとき
242 $ret = $this->db->deleteTemplate($templateId);
243 if ($ret){ // データ更新成功のとき
244 $this->setMsg(self::MSG_GUIDANCE, sprintf($this->_('Template deleted. (template ID: %s)'), $templateId)); // テンプレートを削除しました(テンプレートID:%s)
246 $this->setMsg(self::MSG_APP_ERR, sprintf($this->_('Failed in deleting template. (template ID: %s)'), $templateId)); // テンプレート削除に失敗しました(テンプレートID:%s)
249 $this->setMsg(self::MSG_APP_ERR, sprintf($this->_('Failed in deleting template directory. (directory: %s)'), $templatePath)); // テンプレートのディレクトリが削除できませんでした(ディレクトリ:%s)
253 } else if ($act == 'upload'){ // ファイルアップロードの場合
254 // アップロードされたファイルか?セキュリティチェックする
255 if (is_uploaded_file($_FILES['upfile']['tmp_name'])){
256 $uploadFilename = $_FILES['upfile']['name']; // アップロードされたファイルのファイル名取得
259 $pathParts = pathinfo($uploadFilename);
260 $ext = $pathParts['extension']; // 拡張子
261 $templateName = basename($uploadFilename, '.' . $ext); // 拡張子をはずす
262 $ext = strtolower($ext);
266 //$msg = 'zip圧縮のファイルのみアップロード可能です';
267 $msg = $this->_('Only zip format file is allowed to upload.'); // zip圧縮のファイルのみアップロード可能です
268 $this->setAppErrorMsg($msg);
271 // テンポラリディレクトリの書き込み権限をチェック
272 if (!is_writable($this->gEnv->getWorkDirPath())){
273 //$msg = '一時ディレクトリに書き込み権限がありません。ディレクトリ:' . $this->gEnv->getWorkDirPath();
274 $msg = sprintf($this->_('You are not allowed to write temporary directory. (directory: %s)'), $this->gEnv->getWorkDirPath()); // 一時ディレクトリに書き込み権限がありません。(ディレクトリ:%s)
275 $this->setAppErrorMsg($msg);
278 if ($this->getMsgCount() == 0){ // エラーが発生していないとき
279 // ファイルを保存するサーバディレクトリを指定
280 $tmpFile = tempnam($this->gEnv->getWorkDirPath(), M3_SYSTEM_WORK_UPLOAD_FILENAME_HEAD);
282 // アップされたテンポラリファイルを保存ディレクトリにコピー
283 $ret = move_uploaded_file($_FILES['upfile']['tmp_name'], $tmpFile);
286 $extDir = $this->gEnv->getTempDir();
289 $archiver = new Archive();
290 $ret = $archiver->extract($tmpFile, $extDir, $ext);
293 $fileList = getFileList($extDir);
294 if (count($fileList) == 1 && is_dir($extDir . '/' . $fileList[0])){ // 単一ディレクトリのとき
295 $srcTemplateDir = $extDir . '/' . $fileList[0];
298 $srcTemplateDir = $extDir;
301 $templateId = $this->getTemplateId($srcTemplateDir);
303 // テンプレートIDが取得できないときは、送信されたファイルのファイル名を使用
304 if (empty($templateId)) $templateId = $templateName;
307 switch ($this->templateType){
308 case '0': // PC用テンプレート
311 case '1': // 携帯用テンプレート
312 $templateId = M3_DIR_NAME_MOBILE . '/' . $templateId;
314 case '2': // スマートフォン用テンプレート
315 $templateId = M3_DIR_NAME_SMARTPHONE . '/' . $templateId;
319 // 同IDのテンプレートがないかチェック
320 if ($this->db->getAllTemplateIdList($rows)){
321 for ($i = 0; $i < count($rows); $i++){
322 if ($templateId == $rows[$i]['tm_id']) break;
324 if ($i < count($rows)){
325 //$msg = '同じIDのテンプレートがすでに存在します(テンプレートID:' . $templateId . ')';
326 $msg = sprintf($this->_('The template already exists. (template ID: %s)'), $templateId); // テンプレートがすでに存在します(テンプレートID:%s)
327 $this->setAppErrorMsg($msg);
331 if ($this->getMsgCount() == 0){ // エラーが発生していないとき
333 $destTemplateDir = $this->gEnv->getTemplatesPath() . '/' . $templateId; // テンプレートの移動先
334 if (file_exists($destTemplateDir)){
335 //$msg = '同じIDのテンプレートディレクトリがすでに存在します(テンプレートID:' . $templateId . ')';
336 $msg = sprintf($this->_('The template directory already exists. (directory: %s)'), $destTemplateDir);// テンプレートディレクトリがすでに存在します(ディレクトリ:%s)
337 $this->setAppErrorMsg($msg);
340 $ret = @rename($srcTemplateDir, $destTemplateDir);
341 if (!$ret) $ret = mvDirectory($srcTemplateDir, $destTemplateDir); // 2009/7/17 異なるデバイス間でrenameできなかった問題に対応
344 $ret = $this->addNewTemplate(intval($this->templateType), $templateId);
346 //$msg = 'ファイルのアップロードが完了しました(テンプレートID:' . $templateId . ')';
347 $msg = sprintf($this->_('File uploaded. (template ID: %s)'), $templateId); // ファイルのアップロードが完了しました(テンプレートID: %s)
348 $this->setGuidanceMsg($msg);
349 $this->newTemplate[] = $templateId;
351 // 新規登録失敗の場合はディレクトリを削除
352 rmDirectory($destTemplateDir);
355 //$msg = 'ディレクトリの移動に失敗しました(ディレクトリ:' . $destTemplateDir . ')';
356 $msg = sprintf($this->_('Failed in moving directory. (directory: %s)'), $destTemplateDir);// ディレクトリの移動に失敗しました(ディレクトリ:%s)
357 $this->setAppErrorMsg($msg);
363 if (file_exists($extDir)) rmDirectory($extDir);
365 //$msg = 'ファイルのアップロードに失敗しました';
366 $msg = $this->_('Failed in uploading file.'); // ファイルのアップロードに失敗しました
367 $this->setAppErrorMsg($msg);
373 //$msg = 'アップロードファイルが見つかりません(要因:アップロード可能なファイルのMaxサイズを超えている可能性があります - ' . $this->gSystem->getMaxFileSizeForUpload() . 'バイト)';
374 $msg = sprintf($this->_('Uploded file not found. (detail: The file may be over maximum size to be allowed to upload. Size %s bytes.'), $this->gSystem->getMaxFileSizeForUpload()); // アップロードファイルが見つかりません(要因:アップロード可能なファイルのMaxサイズを超えている可能性があります。%sバイト)
375 $this->setAppErrorMsg($msg);
377 } else if ($act == 'download'){ // ファイルダウンロードのとき
378 switch ($this->templateType){
379 case '0': // PC用テンプレート
381 $templatesDir = $this->gEnv->getTemplatesPath(); // テンプレートディレクトリ
382 $templateDir = $templatesDir . '/' . $templateId; // ダウンロードするテンプレートのディレクトリ
383 $downloadFilename = $templateId . '.zip'; // ダウンロード時のファイル名
385 case '1': // 携帯用テンプレート
386 $templatesDir = $this->gEnv->getTemplatesPath() . '/' . M3_DIR_NAME_MOBILE; // テンプレートディレクトリ
387 $templateDir = $this->gEnv->getTemplatesPath() . '/' . $templateId; // ダウンロードするテンプレートのディレクトリ
388 list($dir, $filename) = explode('/', $templateId); // 先頭の「m/」を削除
389 $downloadFilename = $filename . '.zip'; // ダウンロード時のファイル名
391 case '2': // スマートフォン用テンプレート
392 $templatesDir = $this->gEnv->getTemplatesPath() . '/' . M3_DIR_NAME_SMARTPHONE; // テンプレートディレクトリ
393 $templateDir = $this->gEnv->getTemplatesPath() . '/' . $templateId; // ダウンロードするテンプレートのディレクトリ
394 list($dir, $filename) = explode('/', $templateId); // 先頭の「s/」を削除
395 $downloadFilename = $filename . '.zip'; // ダウンロード時のファイル名
398 $tmpFile = tempnam($this->gEnv->getWorkDirPath(), M3_SYSTEM_WORK_DOWNLOAD_FILENAME_HEAD); // zip処理用一時ファイル
401 $zipFile = new PclZip($tmpFile);
402 $ret = $zipFile->create($templateDir, PCLZIP_OPT_REMOVE_PATH, $templatesDir);
405 $this->gPage->abortPage();
408 $ret = $this->gPage->downloadFile($tmpFile, $downloadFilename, true/*実行後ファイル削除*/);
411 $this->gPage->exitSystem();
413 //$msg = 'ファイルのダウンロードに失敗しました(要因: ' . $zipFile->errorName(true) . ')';
414 $msg = sprintf($this->_('Failed in downloading file. (detail: %s)'), $zipFile->errorName(true)); // ファイルのダウンロードに失敗しました(要因: %s)
415 $this->setAppErrorMsg($msg);
420 } else if ($act == 'changedefault'){ // デフォルトテンプレートの変更のとき
422 if (empty($templateId)) $this->setMsg(self::MSG_APP_ERR, $this->_('Template not selected.')); // テンプレートが選択されていません
424 if (!$this->isExistsMsg()){ // エラーなしのとき
425 switch ($this->templateType){
426 case '0': // PC用テンプレート
429 $this->gSystem->changeDefaultTemplate($templateId);
432 $request->setSessionValue(M3_SESSION_CURRENT_TEMPLATE, $templateId);
434 case '1': // 携帯用テンプレート
436 $this->gSystem->changeDefaultMobileTemplate($templateId);
438 case '2': // スマートフォン用テンプレート
440 $this->gSystem->changeDefaultSmartphoneTemplate($templateId);
444 $this->gCache->clearAllCache();
446 } else if ($act == 'changetype'){ // テンプレートタイプの変更のとき
447 } else if ($act == 'init'){ // テンプレート初期化のとき
448 $ret = $this->initializeTemplate($templateId);
450 $msg = sprintf($this->_('Template initialization completed. (template ID: %s)'), $templateId); // テンプレート初期化完了しました。(テンプレートID: %s)
451 $this->setMsg(self::MSG_GUIDANCE, $msg);
453 $msg = sprintf($this->_('Failed in template initializing. (template ID: %s)'), $templateId); // テンプレート初期化に失敗しました。(テンプレートID: %s)
454 $this->setMsg(self::MSG_APP_ERR, $msg);
459 switch ($this->templateType){
460 case '0': // PC用テンプレート
462 $this->defalutTemplate = $this->gSystem->defaultTemplateId();// デフォルトのテンプレート
463 $installDir = $this->gEnv->getTemplatesPath();// テンプレート格納ディレクトリ
465 case '2': // スマートフォン用テンプレート
466 $this->defalutTemplate = $this->gSystem->defaultSmartphoneTemplateId();// デフォルトのテンプレート
467 $installDir = $this->gEnv->getTemplatesPath() . '/' . M3_DIR_NAME_SMARTPHONE;// テンプレート格納ディレクトリ
470 // デフォルトのテンプレートが存在しない場合はエラーメッセージを表示
471 if ($this->_db->getTemplate($this->defalutTemplate, $row)){
472 $templateDir = $this->gEnv->getTemplatesPath() . '/' . $this->defalutTemplate; // テンプレートのディレクトリ
473 if (!file_exists($templateDir)){
474 $msg = $this->_('Default template directory does not exist.'); // デフォルトテンプレートのディレクトリが存在しません。
475 $this->setAppErrorMsg($msg);
478 $msg = $this->_('Default template is not selected.'); // デフォルトテンプレートが選択されていません。
479 $this->setAppErrorMsg($msg);
483 $this->createTemplateTypeMenu();
486 $this->db->getAllTemplateList(intval($this->templateType), array($this, 'tempListLoop'));
487 if (!$this->isExistsTemplateList) $this->tmpl->setAttribute('templist', 'visibility', 'hidden');// テンプレートがないときは、一覧を表示しない
490 $this->tmpl->addVar("_widget", "install_dir", $installDir);// インストールディレクトリ
491 $this->tmpl->addVar("_widget", "admin_url", $this->getUrl($this->gEnv->getDefaultAdminUrl()));// 管理用URL
492 $this->tmpl->addVar("_widget", "max_file_size", $this->gSystem->getMaxFileSizeForUpload(true/*数値のバイト数*/)); // アップロードファイルの最大サイズ
494 $imageUrl = $this->getUrl($this->gEnv->getRootUrl() . self::UPLOAD_ICON_FILE);
495 $imageTitle = 'テンプレートアップロード';
496 $imageTag = '<img src="' . $imageUrl . '" width="32" height="32" border="0" alt="' . $imageTitle . '" title="' . $imageTitle . '" />';
497 $this->tmpl->addVar("_widget", "upload_image", $imageTag);
499 $imageUrl = $this->getUrl($this->gEnv->getRootUrl() . self::AREA_OPEN_ICON_FILE);
500 $imageTitle = '詳細表示';
501 $imageTag = '<img src="' . $imageUrl . '" width="32" height="32" border="0" alt="' . $imageTitle . '" title="' . $imageTitle . '" />';
502 $this->tmpl->addVar("_widget", "area_open_image", $imageTag);*/
504 $imageUrl = $this->getUrl($this->gEnv->getRootUrl() . self::RELOAD_ICON_FILE);
505 $imageTitle = 'ディレクトリ再読み込み';
506 $imageTag = '<img src="' . $imageUrl . '" width="32" height="32" border="0" alt="' . $imageTitle . '" title="' . $imageTitle . '" />';
507 $this->tmpl->addVar("_widget", "reload_image", $imageTag);
509 $this->tmpl->addVar("_widget", "serial_list", implode($this->serialArray, ','));// 表示項目のシリアル番号を設定
512 $localeText = array();
513 $localeText['msg_update_line'] = $this->_('Update line?'); // 行を更新しますか?
514 $localeText['msg_delete_line'] = $this->_('Delete tmplate?'); // テンプレートを削除しますか?
515 $localeText['msg_no_upload_file'] = $this->_('File not selected.'); // アップロードするファイルが選択されていません
516 $localeText['msg_upload_file'] = $this->_('Upload file.'); // ファイルをアップロードします
517 $localeText['label_template_list'] = $this->_('Template List'); // テンプレート一覧
518 // $localeText['label_template_type'] = $this->_('Template Type:'); // テンプレートタイプ:
519 $localeText['label_install_dir'] = $this->_('Install Directory:'); // インストールディレクトリ:
520 $localeText['label_read_new'] = $this->_('Reload directory'); // ディレクトリ再読み込み
521 $localeText['label_show_detail'] = $this->_('Show detail'); // 詳細表示
522 $localeText['label_template_name'] = $this->_('Name'); // 名前
523 $localeText['label_template_format'] = $this->_('Format'); // 形式
524 $localeText['label_template_creator'] = $this->_('Genarator - Version'); // 生成ソフト - バージョン
525 $localeText['label_template_default'] = $this->_('Default'); // デフォルト
526 $localeText['label_template_date'] = $this->_('Update Date'); // 更新日時
527 $localeText['label_template_operation'] = $this->_('Operation'); // 操作
528 $localeText['label_template_upload'] = $this->_('Template Upload (zip compressed file)'); // テンプレートアップロード(zip圧縮ファイル)
529 $localeText['msg_select_file'] = $this->_('Select file to upload.'); // アップロードするファイルを選択してください
530 $localeText['label_upload'] = $this->_('Upload'); // アップロード
531 $localeText['label_cancel'] = $this->_('Cancel'); // キャンセル
532 $this->setLocaleText($localeText);
535 * テンプレートリスト、取得したデータをテンプレートに設定する
537 * @param int $index 行番号(0~)
538 * @param array $fetchedRow フェッチ取得した行
539 * @param object $param 未使用
540 * @return bool true=処理続行の場合、false=処理終了の場合
542 function tempListLoop($index, $fetchedRow, $param)
544 $genarator = $fetchedRow['tm_generator']; // テンプレート作成アプリケーション
545 $version = $fetchedRow['tm_version']; // テンプレートバージョン
546 $infoUrl = $fetchedRow['tm_info_url']; // テンプレート情報リンク
548 // テンプレートが存在するかどうかチェック
549 $isExistsTemplate = false;
550 $templateId = $fetchedRow['tm_id'];// テンプレートID
551 $templateDir = $this->gEnv->getTemplatesPath() . '/' . $templateId; // テンプレートのディレクトリ
552 if (file_exists($templateDir)) $isExistsTemplate = true;
556 if ($templateId == $this->defalutTemplate){
557 $defaultCheck = 'checked ';
559 if (!$isExistsTemplate) $defaultCheck .= 'disabled'; // テンプレートが存在しないときは使用不可
563 $name = $this->convertToDispString($fetchedRow['tm_name']); // テンプレート名
564 $templateIndexFile = $templateDir . '/index.php'; // テンプレートindex.phpファイル
567 if ($fetchedRow['tm_type'] == 100){ // WordPressテンプレートの場合
569 foreach (array('png', 'gif', 'jpg', 'jpeg') as $ext){
570 $imgPath = $this->gEnv->getTemplatesPath() . '/' . $templateId . '/' . self::TEMPLATE_THUMBNAIL_FILENAME_WP . '.' . $ext;
571 if (file_exists($imgPath)){
572 $imgUrl = $this->gEnv->getTemplatesUrl() . '/' . $templateId . '/' . self::TEMPLATE_THUMBNAIL_FILENAME_WP . '.' . $ext;
577 $imgUrl = $this->gEnv->getTemplatesUrl() . '/' . $templateId . '/' . self::TEMPLATE_THUMBNAIL_FILENAME;
580 // 新規に追加されたテンプレートかチェック
581 $idText = $this->convertToDispString($templateId);
582 for ($i = 0; $i < count($this->newTemplate); $i++){
583 if ($this->newTemplate[$i] == $templateId){
584 $idText = '<b><font color="green">' . $this->convertToDispString($templateId) . '</font></b>';
589 if ($templateId == $this->defalutTemplate){
590 $idText = '<span rel="m3help" data-container="body" title="デフォルトテンプレート"><i class="glyphicon glyphicon-ok-sign"></i></span> ' . $idText;
594 if ($isExistsTemplate){ // テンプレートが存在するとき
595 $imageTag = '<img src="' . $this->getUrl($imgUrl) . '" width="' . self::previewImageSizeWidth . '" height="' . self::previewImageSizeHeight . '" border="0" />';
597 $iconTitle = $this->_('Template not found.'); // テンプレートが見つかりません
598 $iconUrl = $this->gEnv->getRootUrl() . self::NOT_FOUND_TEMPLATE_ICON_FILE;
599 $imageTag = '<img src="' . $this->getUrl($iconUrl) . '" border="0" alt="' . $iconTitle . '" title="' . $iconTitle . '" />';
604 if (!empty($infoUrl)) $infoButtonTag = $this->gDesign->createInfoLink($infoUrl, self::TITLE_INFO_URL);
607 switch ($fetchedRow['tm_type']){
608 case 0: // Joomla!v1.0型
609 $formatType = 'J10'; // テンプレート形式
611 case 1: // Joomla!v1.5型
612 $formatType = 'J15'; // テンプレート形式
614 case 2: // Joomla!v2.5型
615 $formatType = 'J25'; // テンプレート形式
617 case 10: // Bootstrap v3.0型
618 $formatType = 'B30'; // テンプレート形式
620 case 11: // Bootstrap v4.0型
621 $formatType = 'B40'; // テンプレート形式
623 case 100: // WordPress型
624 $formatType = 'W00'; // テンプレート形式
627 $formatType = $this->_('Not Detected'); // 未定
630 $formatType .= ' /<br />';
632 // テンプレートを作成したアプリケーション、バージョンを取得
633 if (empty($genarator)){
634 if (file_exists($templateIndexFile)){
635 $content = file_get_contents($templateIndexFile);
636 $version = $this->getArtVersion($content);
637 if (empty($version)){
638 $formatType .= $this->_('Not Detected'); // 未検出
640 $formatType .= 'artisteer - ' . $version;
644 $formatType .= $genarator . ' - ' . $version;
648 $downloadDisabled = false;// ボタンの状態
649 if (!$isExistsTemplate) $downloadDisabled = true;
650 $eventAttr = 'onclick="downloadTemplate(\'' . $templateId . '\');"';
651 $downloadButtonTag = $this->gDesign->createDownloadButton(''/*同画面*/, $this->_('.zip Download'), ''/*タグID*/, $eventAttr/*クリックイベント時処理*/, $downloadDisabled/*ボタン使用可否*/);
653 $configDisabled = '';// ボタンの状態
654 $configTemplateId = $templateId; // 設定画面用テンプレートID
655 if (!$fetchedRow['tm_has_admin']){
656 $configDisabled = 'disabled'; // 管理画面がなければ使用不可
657 $configTemplateId = '';
660 $editDisabled = '';// ボタンの状態
661 $editUrl = '?task=' . self::TASK_TEMPIMAGE . '&' . M3_REQUEST_PARAM_TEMPLATE_ID . '=' . $templateId; // テンプレート編集画面
662 $imageBasePath = $this->gEnv->getTemplatesPath() . '/' . $templateId . self::DEFAULT_IMAGE_DIR;
663 if (!is_dir($imageBasePath)){ // ディレクトリがない場合はボタンを使用不可にする
664 $editDisabled = 'disabled';
667 // $editButtonTag = $this->gDesign->createEditButton($editUrl, $this->_('Edit Template'), ''/*タグID*/, $editDisabled/*ボタン状態*/);
670 $generateCssUrl = '?task=' . self::TASK_TEMPGENERATECSS . '&' . M3_REQUEST_PARAM_TEMPLATE_ID . '=' . $templateId; // テンプレートCSS生成画面
671 $generateDisabled = '';
672 $canGenerateCss = $this->canGenerateCss($templateId);
673 if (!$canGenerateCss) $generateDisabled = 'class="disabled"';
676 $defaultDisabled = '';
677 if (!$isExistsTemplate || $templateId == $this->defalutTemplate) $defaultDisabled = 'class="disabled"';
680 'index' => $index, // 項目番号
681 'serial' => $this->convertToDispString($fetchedRow['tm_serial']), // シリアル番号
683 'id' => $this->convertToDispString($templateId), // ID
684 'template_id' => $this->convertToDispString($configTemplateId), // 設定画面用テンプレートID
685 'name' => $name, // 名前
686 'info_button' => $infoButtonTag, // テンプレート情報URL
687 'format_type' => $formatType, // テンプレート形式
688 'update_dt' => $this->convertToDispDateTime($fetchedRow['tm_create_dt']), // 更新日時
689 // 'is_default' => $defaultCheck, // デフォルトテンプレートかどうか
690 'image_tag' => $imageTag, // 画像
691 'download_button' => $downloadButtonTag, // ダウンロードボタン
692 'config_disabled' => $configDisabled, // テンプレート設定画面ボタンの使用可否
693 'edit_disabled' => $editDisabled, // テンプレート編集ボタンの使用可否
694 'edit_url' => $editUrl, // テンプレート画像編集用URL
695 'generate_css_url' => $generateCssUrl, // テンプレートCSS生成用URL
696 'generate_disabled' => $generateDisabled, // CSS生成ボタンの使用可否
697 'default_disabled' => $defaultDisabled // デフォルト選択ボタン
699 $this->tmpl->addVars('templist', $row);
700 $this->tmpl->parseTemplate('templist', 'a');
703 $this->serialArray[] = $templateId;
705 $this->isExistsTemplateList = true; // テンプレートが存在する
711 * @param int $type テンプレート種別(0=PC用、1=携帯用, 2=スマートフォン用)
712 * @param string $id テンプレートID(ディレクトリ名)
713 * @param bool true=成功、false=失敗
715 function addNewTemplate($type, $id)
718 $templType = 0; // テンプレートのタイプデフォルト値(Joomla!1.0)
719 $cleanType = 0; // HTMLの出力のクリーニングタイプ
720 $genarator = ''; // テンプレート作成アプリケーション
721 $version = ''; // テンプレートバージョン
722 $infoUrl = ''; // テンプレート情報リンク
723 $templateDir = $this->gEnv->getTemplatesPath() . '/' . $id; // テンプレートディレクトリ
725 // テンプレートかどうかのエラーチェック
726 if (!file_exists($templateDir . '/index.php')){ // index.phpがなければエラー
727 $msg = $this->_('Upload file is not the correct template format.'); // アップロードしたファイルは正しいテンプレートフォーマットではありません。
728 $this->setAppErrorMsg($msg);
734 case '0': // PC用テンプレート
735 case '2': // スマートフォン用テンプレート
736 $configFile = $this->gEnv->getTemplatesPath() . '/' . $id . '/' . self::JOOMLA_CONFIG_FILENAME;
737 if (file_exists($configFile)){
738 if (!function_exists('simplexml_load_file')){
739 $msg = $this->_('SimpleXML module not installed.'); // SimpleXML拡張モジュールがインストールされていません
740 $this->setAppErrorMsg($msg);
743 $xml = simplexml_load_file($configFile);
745 if ($xml->attributes()->type == 'template'){
746 $version = $xml->attributes()->version;
747 $format = $xml->attributes()->format;
748 if (strcasecmp($format, 'bootstrap') == 0){ // Bootstrapタイプのテンプレートの場合
749 $templType = 10; // Bootstrap v3.0型
750 } else { // デフォルトのテンプレート(Joomlaタイプ)
751 if (version_compare($version, '1.6') >= 0){
752 $templType = 2; // Joomla!v2.5テンプレート
753 } else if (version_compare($version, '1.5') >= 0){
754 $templType = 1; // Joomla!v1.5テンプレート
757 $cleanType = $this->checkTemplate($id);
762 if (!empty($xml->infoUrl)) $infoUrl = $xml->infoUrl;
766 // 設定ファイルがない場合はWordPressテンプレートかどうかチェック
767 $content = @file_get_contents($templateDir . '/header.php');
768 if (empty($content)) $content = @file_get_contents($templateDir . '/index.php'); // Themlerテンプレート対応
769 $ret = $this->isWordpressTemplate($content);
770 if ($ret) $templType = 100; // WordPress型
772 // ##### テンプレート作成アプリケーションを取得 #####
773 // Artisteerテンプレートかどうか確認
774 $content = file_get_contents($templateDir . '/index.php');
775 $version = $this->getArtVersion($content);
776 if (!empty($version)){
777 $genarator = 'artisteer'; // テンプレート作成アプリケーション
779 // Themlerテンプレートかどうか確認
780 $ret = $this->isTemlerTemplate($templateDir, $version);
782 $genarator = 'themler';
784 // Themlerテンプレートの修正処理を行う
785 $this->fixThemlerTemplate($templateDir);
792 $ret = $this->db->addNewTemplate($id, $id, $templType, intval($type), $cleanType, $genarator, $version, $infoUrl);
794 // テンプレート登録後、テンプレートを解析してCSSファイルを取得
795 $templateInfoObj = $this->gPage->parseTemplate($id);
798 $updateParam = array();
799 $updateParam['tm_editor_param'] = serialize($templateInfoObj);
800 $ret = $this->_db->updateTemplate($id, $updateParam);
807 * @param string $id テンプレートID
808 * @return bool true=成功、false=失敗
810 function initializeTemplate($id)
812 $templateDir = $this->gEnv->getTemplatesPath() . '/' . $id; // テンプレートディレクトリ
815 if ($this->_db->getTemplate($id, $row)){
816 $genarator = $row['tm_generator']; // テンプレート作成アプリケーション
818 // Themlerテンプレートの修正処理を行う
821 $this->fixThemlerTemplate($templateDir);
825 // テンプレートを解析し、使用しているCSSファイルを取得
826 $templateInfoObj = $this->gPage->parseTemplate($id);
829 $updateParam = array();
830 $updateParam['tm_editor_param'] = serialize($templateInfoObj);
831 $ret = $this->_db->updateTemplate($id, $updateParam);
840 * @param string $dir テンプレートのディレクトリ
841 * @return string テンプレート(取得できないときは空を返す)
843 function getTemplateId($dir)
846 $id = basename($dir);
849 $configFile = $dir . '/' . self::JOOMLA_CONFIG_FILENAME;
850 if (file_exists($configFile)){
851 if (!function_exists('simplexml_load_file')){
852 $msg = $this->_('SimpleXML module not installed.'); // SimpleXML拡張モジュールがインストールされていません
853 $this->setAppErrorMsg($msg);
856 $xml = simplexml_load_file($configFile);
858 $name = trim($xml->name);
859 if (!empty($name)) $id = $name;
867 * @param string $id テンプレートID
868 * @return bool true=CSS生成可能、false=CSS生成不可
870 function canGenerateCss($id)
872 $canGenerate = false; // 生成可否
874 $configFile = $this->gEnv->getTemplatesPath() . '/' . $id . '/' . self::JOOMLA_CONFIG_FILENAME;
875 if (file_exists($configFile)){
876 if (!function_exists('simplexml_load_file')){
877 $msg = $this->_('SimpleXML module not installed.'); // SimpleXML拡張モジュールがインストールされていません
878 $this->setAppErrorMsg($msg);
881 $xml = simplexml_load_file($configFile);
883 if ($xml->attributes()->type == 'template'){
884 $version = $xml->attributes()->version;
885 $format = $xml->attributes()->format;
887 $less = $xml->develop->less;
888 // $sass = $xml->develop->sass;
889 // $scss = $xml->develop->scss;
890 if (!empty($less)) $canGenerate = true;
901 function createTemplateTypeMenu()
903 for ($i = 0; $i < count($this->templateTypeArray); $i++){
904 $value = $this->templateTypeArray[$i]['value'];
905 $name = $this->templateTypeArray[$i]['name'];
908 if ($value == $this->templateType) $selected = 'selected';
911 'value' => $value, // ページID
912 'name' => $name, // ページ名
913 'selected' => $selected // 選択中かどうか
915 $this->tmpl->addVars('item_type_list', $row);
916 $this->tmpl->parseTemplate('item_type_list', 'a');
922 * @param string $templateId テンプレートID
923 * @return int クリーン処理タイプ
925 function checkTemplate($id)
929 // Joomla!テンプレート共通の設定
933 define('JPATH_BASE', dirname(__FILE__));
934 define('DS', DIRECTORY_SEPARATOR);
939 $render = new JRender();
940 $render->setTemplate($id);
941 $contents = $render->getComponentContents('test', 'dummy contents', 'test');
944 $pos = strpos($contents, 'PostHeaderIcons');
945 if ($pos !== false) $cleanType = 1;
952 * テンプレートのindex.phpファイルからArtisteerバージョンを取得
954 * @param string $src 検索するデータ
955 * @return string 検出の場合はバージョン文字列、未検出の場合は空文字列。
957 function getArtVersion($src)
960 // <!-- Created by Artisteer v4.1.0.59688 -->
961 $pattern = '/<!-- Created by Artisteer[^<]*?v([.\d]+)[^<]*?-->/i';
962 $ret = preg_match($pattern, $src, $matches);
963 if ($ret) $version = $matches[1];
967 * WordPressテンプレートかどうかチェック
969 * @param string $src 検索するデータ
970 * @return bool true=WordPressテンプレート、false=WordPressテンプレート以外
972 function isWordpressTemplate($src)
974 $pos = strpos($src, 'wp_head()');
982 * Themlerテンプレートかどうかを判断
984 * @param string $dir テンプレートのディレクトリ
985 * @param string $version Themlerテンプレートの場合、テンプレートのバージョンが返る
986 * @return bool true=Themlerテンプレート、false=Themlerテンプレート以外
988 function isTemlerTemplate($dir, &$version)
990 // Themlerテンプレートを判断するファイル
991 $appFile = $dir . '/' . self::THEMLER_APP_FILENAME;
992 $ret = file_exists($appFile);
995 @require_once($dir . '/functions.php'); // エラーメッセージ抑止
996 $verSrc = addThemeVersion('');
997 list($tmp, $version) = explode('=', $verSrc);
1004 * @param string $templateDir テンプレートのディレクトリ
1005 * @return bool true=成功、false=失敗
1007 function fixThemlerTemplate($templateDir)
1009 $searchDir = $templateDir . '/html/com_content';
1010 $dir = dir($searchDir);
1011 while (($file = $dir->read()) !== false){
1012 $filePath = $searchDir . '/' . $file;
1015 if (strncmp($file, '.', 1) != 0 && $file != '..' && is_dir($filePath)){
1016 $targetFile = $filePath . '/default.php';
1017 $this->fixThemlerTemplateDefaultFile($targetFile);
1023 * Themlerテンプレートのcom_contentディレクトリ以下のdefault.phpファイルの修正を行う
1025 * @param string $filePath 対象ファイルのパス
1026 * @return bool true=成功、false=失敗
1028 function fixThemlerTemplateDefaultFile($filePath)
1031 if (!file_exists($filePath)) return false;
1034 if (!($file = @fopen($filePath, "r"))){
1035 $errMsg = 'ファイルのオープンに失敗しました ファイル=' . $filePath;
1036 $this->gLog->error(__METHOD__, $errMsg);
1040 $content = @fread($file, filesize($filePath));
1044 $content = str_replace('require_once \'default_template.php\';', 'require \'default_template.php\';', $content);
1047 $backupFilePath = dirname($filePath) . '/_' . basename($filePath);
1048 $isOk = writeFile($backupFilePath, $content);
1049 if (!$isOk) return false;
1052 $tmpFilePath = $filePath . '_tmp';
1053 if (!renameFile($filePath, $tmpFilePath)){
1054 $errMsg = 'ファイルを移動できません';
1055 $this->gLog->error(__METHOD__, $errMsg);
1059 unlink($backupFilePath);
1062 if (!renameFile($backupFilePath, $filePath)){
1063 $errMsg = 'ファイルを移動できません';
1064 $this->gLog->error(__METHOD__, $errMsg);
1068 unlink($backupFilePath);
1071 renameFile($tmpFilePath, $filePath);
1074 if (!renameFile($tmpFilePath, $backupFilePath)){
1075 $errMsg = 'ファイルを移動できません';
1076 $this->gLog->error(__METHOD__, $errMsg);
1080 unlink($tmpFilePath);
1088 * @param int $deviceType デバイスタイプ(0=PC,1=携帯,2=スマートフォン)
1089 * @return bool true=有効、false=無効
1091 function isActiveAccessPoint($deviceType)
1094 switch ($deviceType){
1099 $pageId = M3_DIR_NAME_MOBILE . '_index';
1102 $pageId = M3_DIR_NAME_SMARTPHONE . '_index';
1107 $ret = $this->db->getPageIdRecord(0/*アクセスポイント*/, $pageId, $row);
1109 $isActive = $row['pg_active'];