', 'file_put_contents_ex('.$filename.') could not write file'); return; } if (flock($fp, LOCK_EX)) { ftruncate($fp, 0); rewind($fp); $written = fwrite($fp, $data); fflush($fp); @chmod($filename, 0600); flock($fp, LOCK_UN); fclose($fp); return $written === strlen($data); } else { Log::text('', 'file_put_contents_ex('.$filename.') could not acquire lock'); } fclose($fp); return false; } static function delete_file($file_name) { unlink($file_name); } static function read_file($file_name) { if(!file_exists($file_name)) return(''); $fsz = filesize($file_name); if($fsz == 0) return(''); $fp = fopen($file_name, "rb+"); if(!$fp) return(''); if (flock($fp, LOCK_SH)) { $content = fread($fp, $fsz); flock($fp, LOCK_UN); } else { Log::text('', 'read_file('.$file_name.') could not acquire lock'); } fclose($fp); return($content); } static function write_data($class, $bucket, $type, $data) { $storage_path = self::storage_path($class, $bucket); if(!file_exists($storage_path)) @mkdir($storage_path, 0774, true); if(!file_exists($storage_path)) @mkdir($storage_path, 0700, true); $json = json_encode($data); if ($json === false) return false; return self::write_file(self::data_filename($class, $bucket, $type), $json); } static function read_data($class, $bucket, $type) { return(json_decode(self::read_file(self::data_filename($class, $bucket, $type)), true)); } static function delete_data($class, $bucket, $type) { return(self::delete_file(self::data_filename($class, $bucket, $type))); } static function get_data_filename($class, $bucket, $type) { return(self::data_filename($class, $bucket, $type)); } static function list_bucket($class, $bucket) { $items = array(); $storage_path = self::storage_path($class, $bucket); if(!is_dir($storage_path)) return($items); foreach(scandir($storage_path) as $name) { if(substr($name, 0, 1) != '_' && trim($name) != '' && $name !== '.' && $name !== '..') $items[] = $name; } return($items); } static function search_bucket($class, $bucket, $q) { $items = array(); $storage_path = self::storage_path($class, $bucket); if(!is_dir($storage_path)) return($items); foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($storage_path, FilesystemIterator::SKIP_DOTS)) as $file) { if(!$file->isFile()) continue; if(substr($file->getFilename(), -5) !== '.json') continue; $content = @file_get_contents($file->getPathname()); if($content === false || strpos($content, $q) === false) continue; $name = substr($file->getPathname(), strlen($storage_path)+1, -5); if(substr($name, 0, 1) != '_' && trim($name) != '') $items[] = $name; } return($items); } static function delete_directory($dir) { if(!is_dir($dir)) return(''); foreach(scandir($dir) as $entry) { if($entry === '.' || $entry === '..') continue; $path = $dir.'/'.$entry; if(is_dir($path) && !is_link($path)) { $error = self::delete_directory($path); if($error !== '') return($error); } else if(!@unlink($path)) { return('could not delete '.$path); } } if(!@rmdir($dir)) return('could not delete '.$dir); return(''); } static function delete_bucket($class, $bucket) { return(self::delete_directory(self::storage_path($class, $bucket))); } static function write_log($class, $bucket, $type, $data) { $storage_path = self::storage_path($class, $bucket); if(!file_exists($storage_path)) @mkdir($storage_path, 0774, true); WriteToFile($storage_path.'/'.self::validate_path_part($type, 'type').'.log', json_encode($data).chr(10)); } static function read_log($class, $bucket, $type, $line_count = 8, $offset = false) { $storage_path = self::storage_path($class, $bucket); return(get_json_tail($storage_path.'/'.self::validate_path_part($type, 'type').'.log', $line_count, $offset)); } static function line_count($class, $bucket, $type) { $storage_path = self::storage_path($class, $bucket); return(intval(trim(shell_exec('wc -l '.escapeshellarg($storage_path.'/'.self::validate_path_part($type, 'type').'.log'))))); } static function get_json_tail($from_file, $line_count = 8, $offset = false) { if($offset > 0) { $lines = trim(shell_exec( 'tail -n '.escapeshellarg($offset+$line_count).' '.escapeshellarg($from_file).' | head -n '.escapeshellarg($line_count))); } else { $lines = trim(shell_exec( 'tail -n '.escapeshellarg($line_count).' '.escapeshellarg($from_file))); } return(json_lines($lines)); } static function get_tail($from_file, $line_count = 8, $offset = false) { $line_count = intval($line_count); if($offset > 0) { $lines = trim(shell_exec( 'tail -n '.escapeshellarg($offset+$line_count).' '.escapeshellarg($from_file).' | head -n '.escapeshellarg($line_count))); } else { $lines = trim(shell_exec( 'tail -n '.escapeshellarg($line_count).' '.escapeshellarg($from_file))); } return(explode(chr(10), $lines)); } static function get_all_lines($from_file) { return(explode(chr(10), trim(file_get_contents($from_file)))); } static function truncate_log($from_file, $lines = 128) { $lines = intval($lines); $tmp = tempnam(sys_get_temp_dir(), 'trunc_'); shell_exec('tail -n '.$lines.' '.escapeshellarg($from_file).' > '.escapeshellarg($tmp).' && cp '.escapeshellarg($tmp).' '.escapeshellarg($from_file)); @unlink($tmp); return true; } static function json_lines($lines) { if($lines == '') { return(array()); } else { $result = array(); foreach(explode(chr(10), $lines) as $line) $result[] = json_decode($line, true); return($result); } } }