調べてみると、カスタムフィールドの定義を取得するSQLで20秒も掛かってた。
カスタムフィールド使いまくってて、20万行越えてた。
過去のデータ中から、編集画面でプルダウンを作るんだけどそれはちょっと時間かかるよね…
ということで、テーマのfuncitons.phpに以下を追加。テーマディレクトリに tmpディレクトリを作ってパーミション777に。
<?php
class AnonymousTekitou
{
private $cache_lifetime = 8000;
private $cache_dir_level = 2;
@brief
@param
@retval
public static function getInstance($cache_lifetime = null)
{
static $ins ;
if (is_null($ins)){
$ins = new self();
if (!is_null($cache_lifetime)){
$ins->cache_lifetime = $cache_lifetime;
}
}
return $ins;
}
@brief
@param
@param
@retval
private function cache($url, $body = null)
{
$cache_file = sprintf('%s/tmp/cache/%s',
__DIR__, $this->splitString(md5($url), $this->cache_dir_level));
$cache_dir = dirname($cache_file);
if (!is_dir($cache_dir)){
self::mkdir($cache_dir, 0777);
}
chmod($cache_dir, 0777);
if (is_null($body)){
if (file_exists($cache_file)){
$s = stat($cache_file);
if ($s['mtime'] + $this->cache_lifetime > time()){
$file = file($cache_file);
array_shift($file);
return implode("", $file);
}
else {
unlink($cache_file);
return null ;
}
}
return false;
}
else {
file_put_contents($cache_file, $url."\n".$body);
chmod($cache_file, 0666);
}
}
@brief
@param
@param
@retval
private function splitString($str, $num)
{
$ret = "";
for ($i=0; $i< strlen($str) ;$i++){
$ret .= $str{$i};
if ($i<$num){
$ret.= "/";
}
}
return $ret;
}
@access
@param
@param
@return
@static
public static function mkdir($dir, $mode)
{
if (file_exists($dir)) {
return is_dir($dir);
}
$parent = dirname($dir);
if ($dir === $parent) {
return true;
}
if (is_dir($parent) === false) {
if (self::mkdir($parent, $mode) === false) {
return false;
}
}
return mkdir($dir, $mode) && chmod($dir, $mode);
}
@brief
@param
@retval
public function getPostmetaFormKeysCache($post)
{
global $wpdb;
$key_name = md5(__CLASS__ . __METHOD__ . DB_NAME . __FILE__ . $_SERVER['SERVER_NAME']);
if (!is_null($post)) {
return null;
}
if ($cache = $this->cache($key_name)){
$keys = unserialize($cache);
}
else {
$limit = apply_filters( 'postmeta_form_limit', 30 );
$sql = "SELECT DISTINCT meta_key
FROM $wpdb->postmeta
WHERE meta_key NOT BETWEEN '_' AND '_z'
HAVING meta_key NOT LIKE %s
ORDER BY meta_key
LIMIT %d";
$keys = $wpdb->get_col( $wpdb->prepare( $sql, $wpdb->esc_like( '_' ) . '%', $limit ) );
$this->cache($key_name, serialize($keys));
}
return $keys;
}
}
add_filter('postmeta_form_keys', function($p){
$a= AnonymousTekitou::getInstance();
return $a->getPostmetaFormKeysCache($p);
});