Open Monograph Press  1.1
 All Classes Namespaces Functions Variables Groups Pages
copyAccessLogFileTool.php
1 <?php
2 
17 require(dirname(dirname(dirname(dirname(__FILE__)))) . '/tools/bootstrap.inc.php');
18 
19 // Bring in the file loader folder constants.
20 import('lib.pkp.classes.task.FileLoader');
21 
23 
24  var $_usageStatsDir;
25 
26  var $_tmpDir;
27 
28  var $_usageStatsFiles;
29 
30  var $_contextPaths;
31 
32  var $_egrepPath;
33 
34  var $_gunzipPath;
35 
40  function CopyAccessLogFileTool($argv = array()) {
41  parent::CommandLineTool($argv);
42 
43  if (sizeof($this->argv) !== 1) {
44  $this->usage();
45  exit(1);
46  }
47 
48  $plugin =& PluginRegistry::getPlugin('generic', 'usagestatsplugin'); /* @var $plugin UsageStatsPlugin */
49 
50  $this->_usageStatsDir = $plugin->getFilesPath();
51  $this->_tmpDir = $this->_usageStatsDir . DIRECTORY_SEPARATOR . 'tmp';
52 
53  AppLocale::requireComponents(LOCALE_COMPONENT_PKP_ADMIN);
54 
55  // This tool needs egrep and gunzip path configured.
56  $this->_egrepPath = escapeshellarg(Config::getVar('cli', 'egrep'));
57  if ($this->_egrepPath == "''") {
58  printf(__('admin.copyAccessLogFileTool.error.noEgrep') . "\n");
59  exit(1);
60  }
61 
62  $this->_gunzipPath = escapeshellarg(Config::getVar('cli', 'gunzip'));
63  if ($this->_gunzipPath == "''") {
64  printf(__('admin.copyAccessLogFileTool.error.noGunzip') . "\n");
65  exit(1);
66  }
67 
68  // Get a list of files currently inside the usage stats dir.
69  $fileLoaderDirs = array(FILE_LOADER_PATH_STAGING, FILE_LOADER_PATH_PROCESSING,
70  FILE_LOADER_PATH_ARCHIVE, FILE_LOADER_PATH_REJECT);
71 
72  $usageStatsFiles = array();
73  foreach ($fileLoaderDirs as $dir) {
74  $dirFiles = glob($this->_usageStatsDir . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR . '*');
75  if (is_array($dirFiles) && count($dirFiles) > 0) {
76  foreach ($dirFiles as $file) {
77  if (!is_file($file)) continue;
78  $fileBasename = pathinfo($file, PATHINFO_BASENAME);
79  if (pathinfo($file, PATHINFO_EXTENSION) == 'gz') {
80  // Always save the filename without compression extension.
81  $fileBasename = substr($fileBasename, 0, -3);
82  }
83  $usageStatsFiles[] = $fileBasename;
84  }
85  }
86  }
87 
88  $this->_usageStatsFiles = $usageStatsFiles;
89 
90  // Get a list of context paths.
91  $contextDao =& Application::getContextDAO(); /* @var $contextDao ContextDAO */
92  $contextFactory = $contextDao->getAll();
93  $contextPaths = array();
94  while ($context =& $contextFactory->next()) {
95  /* @var $context Context */
96  $contextPaths[] = escapeshellarg($context->getPath());
97  }
98  $contextPaths = implode('/|/', $contextPaths);
99  $this->_contextPaths = $contextPaths;
100  }
101 
105  function usage() {
106  echo "\n" . __('admin.copyAccessLogFileTool.usage', array('scriptName' => $this->scriptName)) . "\n\n";
107  }
108 
114  function execute() {
115  $fileMgr = new FileManager();
116  $filesDir = Config::getVar('files', 'files_dir');
117  $filePath = current($this->argv);
118  $usageStatsDir = $this->_usageStatsDir;
119  $tmpDir = $this->_tmpDir;
120 
121  if ($fileMgr->fileExists($tmpDir, 'dir')) {
122  $fileMgr->rmtree($tmpDir);
123  }
124 
125  if (!$fileMgr->mkdir($tmpDir)) {
126  printf(__('admin.copyAccessLogFileTool.error.creatingFolder', array('tmpDir' => $tmpDir)) . "\n");
127  exit(1);
128  }
129 
130  if ($fileMgr->fileExists($filePath, 'dir')) {
131  // Directory.
132  $filesToCopy = glob($filePath . DIRECTORY_SEPARATOR . '*');
133  foreach ($filesToCopy as $file) {
134  $this->_copyFile($file);
135  }
136  } else {
137  if ($fileMgr->fileExists($filePath)) {
138  // File.
139  $this->_copyFile($filePath);
140  } else {
141  // Can't access.
142  printf(__('admin.copyAccessLogFileTool.error.acessingFile', array('filePath' => $filePath)) . "\n");
143  }
144  }
145 
146  $fileMgr->rmtree($tmpDir);
147  }
148 
149 
150  //
151  // Private helper methods.
152  //
158  function _copyFile($filePath) {
159  $usageStatsFiles = $this->_usageStatsFiles;
160  $usageStatsDir = $this->_usageStatsDir;
161  $tmpDir = $this->_tmpDir;
162  $fileName = pathinfo($filePath, PATHINFO_BASENAME);
163  $fileMgr = new FileManager();
164 
165  $isCompressed = false;
166  $uncompressedFileName = $fileName;
167  if (pathinfo($filePath, PATHINFO_EXTENSION) == 'gz') {
168  $isCompressed = true;
169  $uncompressedFileName = substr($fileName, 0, -3);
170  }
171 
172  if (in_array($uncompressedFileName, $usageStatsFiles)) {
173  printf(__('admin.copyAccessLogFileTool.warning.fileAlreadyExists', array('filePath' => $filePath)) . "\n");
174  return;
175  }
176 
177  $tmpFilePath = $tmpDir . DIRECTORY_SEPARATOR . $fileName;
178 
179  // Copy the file to a temporary directory.
180  if (!$fileMgr->copyFile($filePath, $tmpFilePath)) {
181  printf(__('admin.copyAccessLogFileTool.error.copyingFile', array('filePath' => $filePath, 'tmpFilePath' => $tmpFilePath)) . "\n");
182  exit(1);
183  }
184 
185  // Uncompress it, if needed.
186  $gunzipPath = $this->_gunzipPath;
187  if ($isCompressed) {
188  exec($gunzipPath . ' ' . $tmpFilePath);
189  $tmpFilePath = substr($tmpFilePath, 0, -3);
190  }
191 
192  // Filter only entries that contains context paths.
193  $egrepPath = $this->_egrepPath;
194  $destinationPath = $usageStatsDir . DIRECTORY_SEPARATOR .
195  FILE_LOADER_PATH_STAGING . DIRECTORY_SEPARATOR .
196  pathinfo($tmpFilePath, PATHINFO_BASENAME);
197  // Each context path is already escaped, see the constructor.
198  exec($egrepPath . " -i '" . $this->_contextPaths . "' " . escapeshellarg($tmpFilePath) . " > " . escapeshellarg($destinationPath));
199 
200  if (!$fileMgr->deleteFile($tmpFilePath)) {
201  printf(__('admin.copyAccessLogFileTool.error.deletingFile', array('tmpFilePath' => $tmpFilePath)) . "\n");
202  exit(1);
203  }
204 
205  printf(__('admin.copyAccessLogFileTool.success', array('filePath' => $filePath, 'destinationPath' => $destinationPath)) . "\n");
206  }
207 }
208 
209 $tool = new CopyAccessLogFileTool(isset($argv) ? $argv : array());
210 $tool->execute();
211 ?>
Initialization code for command-line scripts.
Definition: CliTool.inc.php:44
CLI tool to copy apache log files while filtering entries related only to the current instalation...
static requireComponents()
Class defining basic operations for file management.
static getVar($section, $key, $default=null)
Definition: Config.inc.php:35
static & getPlugin($category, $name)
CopyAccessLogFileTool($argv=array())
static getContextDAO()