function do_upload($page, $fname, $tmpname, $copyright = FALSE, $pass = NULL, $notouch = FALSE, $options = NULL) { // ページが無ければ空ページを作成(他のプラグインから呼ばれた時のため) if (!$this->func->is_page($page)) { $this->func->make_empty_page($page, false); } $overwrite = !empty($options['overwrite']); $changelog = isset($options['changelog']) ? $options['changelog'] : ''; $add_mes = array(); $has_json_msg = false; // ファイル名の正規化 $fname = str_replace("", '', $fname); $fname = $this->func->basename(str_replace("\\", "/", $fname)); $_action = 'insert'; // style.css if ($fname === 'style.css' && $this->func->is_owner($page)) { if (is_file($tmpname)) { $_pagecss_file = $this->cont['CACHE_DIR'] . $this->func->get_pgid_by_name($page) . ".css"; if (is_file($_pagecss_file)) { unlink($_pagecss_file); } if (is_uploaded_file($tmpname) && move_uploaded_file($tmpname, $_pagecss_file) || @rename($tmpname, $_pagecss_file)) { $this->attach_chmod($_pagecss_file); // 空のファイルの場合はファイル削除 if (!trim(file_get_contents($_pagecss_file))) { unlink($_pagecss_file); return array('result' => TRUE, 'msg' => $this->root->_attach_messages['msg_unset_css'], 'has_json_msg' => TRUE); } else { $_data = file_get_contents($_pagecss_file); // 管理者以外は外部ファイルの参照を禁止するなどの書き換え if (!$this->root->userinfo['admin']) { $_data = preg_replace('#(?:url\\s*\\(\\s*[\'"]?(?:(?:ht|f)tps?:)?//[^\\)]+?\\)|@import[^;\\r\\n]*?;|@import|(?:ht|f)tps?://)#i', '', $_data); } if (file_put_contents($_pagecss_file, $_data)) { $add_mes[] = $this->root->_attach_messages['msg_set_css']; $has_json_msg = true; } // 元ファイルを添付ファイルとして保存 if ($tmpname = tempnam($this->cont['CACHE_DIR'], 'atf')) { file_put_contents($tmpname, $_data); $overwrite = true; } clearstatcache(); } } else { @unlink($tmpname); return array('result' => FALSE, 'msg' => $this->root->_attach_messages['err_exists']); } } } // ページオーナー権限がない場合は拡張子をチェック $allow_extensions = $this->get_allow_extensions(); if (empty($options['asSystem']) && !$overwrite && $allow_extensions && !$this->func->is_owner($page) && !preg_match("/\\.(" . join("|", $allow_extensions) . ")\$/i", $fname)) { return array('result' => FALSE, 'msg' => str_replace('$1', $this->func->htmlspecialchars(preg_replace('/.*\\.([^.]*)$/', "\$1", $fname)), $this->root->_attach_messages['err_extension'])); } $_size = @getimagesize($tmpname); // イメージファイルの内容をチェック if ($_size) { $checkStr = $this->func->file_get_contents($tmpname, FALSE, NULL, 0, 10240); if (preg_match('/<(?:script|\\?php)/i', $checkStr)) { return array('result' => FALSE, 'msg' => 'It isn\'t a image file.'); } // Flashファイルの検査 if ($this->cont['ATTACH_UPLOAD_FLASH_ADMIN_ONLY']) { if (!$this->root->userinfo['admin'] && ($_size[2] === 4 || $_size[2] === 13)) { return array('result' => FALSE, 'msg' => $this->root->_attach_messages['err_isflash']); } } } // オリジナルファイル名 $org_fname = $fname; // 格納ファイル名指定あり if (!empty($this->root->vars['filename'])) { $fname = $this->root->vars['filename']; } // 格納ファイル名文字数チェック(SQL varchar(255) - strlen('_\d\d\d')) $fname = function_exists('mb_strcut') ? mb_strcut($fname, 0, 251) : substr($fname, 0, 251); // ファイル名 文字数のチェック $fname = $this->regularize_fname($fname, $page); if (!$overwrite) { // ファイル名が存在する場合は、数字を付け加える if (preg_match("/^(.+)(\\.[^.]*)\$/", $fname, $match)) { $_fname = $match[1]; $_ext = $match[2]; } else { $_fname = $fname; $_ext = ''; } $fi = 0; do { $obj = new XpWikiAttachFile($this->xpwiki, $page, $fname); $fname = $_fname . '_' . $fi++ . $_ext; } while ($obj->exist); } else { $obj = new XpWikiAttachFile($this->xpwiki, $page, $fname); if (is_file($obj->filename)) { unlink($obj->filename); $_action = "update"; } } if (is_uploaded_file($tmpname)) { if (move_uploaded_file($tmpname, $obj->filename)) { $this->attach_chmod($obj->filename); } else { return array('result' => FALSE, 'msg' => $this->root->_attach_messages['err_noexist']); } } else { if (!is_file($tmpname) || !filesize($tmpname)) { if (is_file($tmpname)) { unlink($tmpname); } return array('result' => FALSE, 'msg' => $this->root->_attach_messages['err_noexist']); } if (rename($tmpname, $obj->filename)) { $this->attach_chmod($obj->filename); } else { unlink($tmpname); return array('result' => FALSE, 'msg' => $this->root->_attach_messages['err_noexist']); } } if ($this->func->is_page($page)) { if (!$notouch) { if (!$changelog) { $changelog = 'Attached file: ' . $this->func->htmlspecialchars($obj->file); } $this->root->rtf['page_touch'][$page][] = $changelog; } $this->func->clear_page_cache($page); } if (!empty($options['asSystem'])) { $_uid = 0; $_ucd = 'SYSTEM'; $_uname = 'System'; $_admins = 0; } else { $_uid = $this->root->userinfo['uid']; $_ucd = $this->root->userinfo['ucd']; $_uname = $this->root->userinfo['uname']; $_admins = (int) $this->func->check_admin($this->root->userinfo['uid']); } if ($_size && version_compare(HypCommonFunc::get_version(), '20150515', '>=')) { // 自動回転を試みる HypCommonFunc::rotateImage($obj->filename, 0, 95, $_size); if (!empty($this->root->vars['rmgps'])) { HypCommonFunc::removeExifGps($obj->filename, $_size); } } $obj->getstatus(); $obj->status['age'] = 0; $obj->status['pass'] = ($pass !== TRUE and $pass !== NULL) ? $pass : ''; $obj->status['copyright'] = $copyright; $obj->status['owner'] = $_uid; $obj->status['ucd'] = $_ucd; $obj->status['uname'] = $_uname; $obj->status['md5'] = md5_file($obj->filename); $obj->status['admins'] = $_admins; $obj->status['org_fname'] = $org_fname; $obj->status['imagesize'] = $obj->getimagesize($obj->filename); $obj->status['mime'] = $this->attach_mime_content_type($obj->filename, $obj->status); $obj->action = $_action; $obj->putstatus(); if (!empty($this->root->vars['refid'])) { $this->ref_replace($page, $this->root->vars['refid'], $obj->file, $obj->status['imagesize']); } return array('result' => TRUE, 'msg' => $add_mes ? join("\n", $add_mes) : $this->root->_attach_messages['msg_uploaded'], 'name' => $obj->file, 'has_json_msg' => $has_json_msg); }
function attach_db_init() { // global $xoopsDB,$vars,$post,$get; if (!$this->func->exist_plugin('attach')) { return; } $attach = $this->func->get_plugin_instance('attach'); if (!$attach) { return; } if ($dir = @opendir($this->cont['UPLOAD_DIR'])) { // 処理済ファイルリストデーター $work = $this->cont['CACHE_DIR'] . "dbsync_a.dat"; $domix = $dones = array(); $done = 0; if (is_file($work)) { $dones = unserialize(file_get_contents($work)); if (!isset($dones[1])) { $dones[1] = array(); } $docnt = count($dones[1]); $domix = array_merge($dones[0], $dones[1]); $done = count($domix); } if ($done) { echo "<div style=\"font-size:14px;\"><b>DB '" . $this->root->mydirname . "_attach' Already converted {$docnt} pages.</b></div>"; } else { $query = "DELETE FROM " . $this->db->prefix($this->root->mydirname . "_attach"); if (!($result = $this->db->queryF($query))) { echo 'SQL Error: ' . $query . '<br />'; } } echo "<div style=\"font-size:14px;\"><b>DB '" . $this->root->mydirname . "_attach' Now converting... </b>( * = 10 Pages)<hr>"; $counter = 0; $page_pattern = '(?:[0-9A-F]{2})+'; $age_pattern = '(?:\\.([0-9]+))?'; $pattern = "/^({$page_pattern})_((?:[0-9A-F]{2})+){$age_pattern}\$/"; $files = array(); while ($file = readdir($dir)) { $files[] = $file; } foreach (array_diff($files, $domix) as $file) { $matches = array(); if (!preg_match($pattern, $file, $matches)) { $dones[0][] = $file; continue; } $page = $this->func->decode($matches[1]); $name = $this->func->decode($matches[2]); $age = array_key_exists(3, $matches) ? $matches[3] : 0; // サムネイルは除外 if (preg_match("/^\\d\\d?%/", $name)) { $dones[0][] = $file; continue; } $obj = new XpWikiAttachFile($this->xpwiki, $page, $name, $age); $obj->getstatus(); $obj->status['md5'] = md5_file($obj->filename); $obj->putstatus(); $data['pgid'] = $this->func->get_pgid_by_name($page); $data['name'] = $name; $data['mtime'] = $obj->time; $data['size'] = $obj->size; $data['type'] = $obj->type; $data['status'] = $obj->status; $data['status']['age'] = $age; // ページが存在しない if (!$data['pgid']) { $dones[0][] = $file; continue; } if ($this->func->attach_db_write($data, "insert")) { //echo "$page::$name;:$age<br >"; $counter++; $dones[1][] = $file; if ($counter / 10 == floor($counter / 10)) { echo "*"; } if ($counter / 100 == floor($counter / 100)) { echo " ( Done " . $counter . " Files !)<br />"; } } else { $dones[0][] = $file; } if ($this->check_time_limit()) { // 処理済ファイルリスト保存 if ($fp = fopen($work, "wb")) { fputs($fp, serialize($dones)); fclose($fp); } closedir($dir); $this->plugin_dbsync_next_do(); } } closedir($dir); echo " ( Done " . $counter . " Files !)<hr />"; echo "</div>"; @unlink($work); } $this->root->post['attach'] = ""; }